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
package/esm/index.js
CHANGED
|
@@ -10,7 +10,15 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export { run } from "@oclif/core";
|
|
12
12
|
export { fromFluidHandlers, } from "./adapters/fluidFramework.js";
|
|
13
|
-
export { makePolicy, makePolicyDefinition, } from "./makePolicy.js";
|
|
13
|
+
export { makePolicy, makePolicyDefinition, policy, } from "./makePolicy.js";
|
|
14
|
+
export {
|
|
15
|
+
// Type guards
|
|
16
|
+
isPolicyError, isPolicyFailure, isPolicyFixResult,
|
|
17
|
+
// New types
|
|
18
|
+
Policy, } from "./policy.js";
|
|
19
|
+
export { defineCargoPolicy, } from "./policyDefiners/defineCargoPolicy.js";
|
|
14
20
|
export { defineFileHeaderPolicy, } from "./policyDefiners/defineFileHeaderPolicy.js";
|
|
21
|
+
export { defineGleamPolicy, } from "./policyDefiners/defineGleamPolicy.js";
|
|
15
22
|
export { definePackagePolicy as generatePackagePolicy, } from "./policyDefiners/definePackagePolicy.js";
|
|
23
|
+
export { PolicyRunner, } from "./runner.js";
|
|
16
24
|
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAGN,iBAAiB,GACjB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAGN,iBAAiB,GACjB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EACN,UAAU,EACV,oBAAoB,EAGpB,MAAM,GACN,MAAM,iBAAiB,CAAC;AAEzB,OAAO;AAGN,cAAc;AACd,aAAa,EACb,eAAe,EACf,iBAAiB;AACjB,YAAY;AACZ,MAAM,GAkBN,MAAM,aAAa,CAAC;AACrB,OAAO,EAIN,iBAAiB,GACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAEN,sBAAsB,GAGtB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAEN,iBAAiB,GAGjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAEN,mBAAmB,IAAI,qBAAqB,GAE5C,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAEN,YAAY,GAGZ,MAAM,aAAa,CAAC","sourcesContent":["/**\n * A tool for enforcing repository policies and standards across codebases.\n *\n * @remarks\n * Repopo provides a framework for defining and enforcing policies across repositories,\n * such as file headers, package.json consistency, and other code standards.\n * It can be used as a CLI tool or integrated into CI/CD pipelines.\n *\n * @packageDocumentation\n */\n\nexport { run } from \"@oclif/core\";\nexport {\n\ttype FluidAdapterOptions,\n\ttype FluidHandler,\n\tfromFluidHandlers,\n} from \"./adapters/fluidFramework.js\";\nexport type {\n\t// PolicyList,\n\tRepopoConfig,\n} from \"./config.js\";\nexport type { ExcludedPolicyFileMap } from \"./context.js\";\nexport {\n\tmakePolicy,\n\tmakePolicyDefinition,\n\ttype PolicyDefinitionInput,\n\ttype PolicyOptions,\n\tpolicy,\n} from \"./makePolicy.js\";\nexport type { PolicyAction, PolicyHandlerPerfStats } from \"./perf.js\";\nexport {\n\ttype ConfiguredPolicy,\n\ttype IdentifiedPolicy,\n\t// Type guards\n\tisPolicyError,\n\tisPolicyFailure,\n\tisPolicyFixResult,\n\t// New types\n\tPolicy,\n\ttype PolicyArgs,\n\t// Legacy types (for backward compatibility)\n\ttype PolicyDefinition,\n\ttype PolicyError,\n\ttype PolicyFailure,\n\ttype PolicyFixResult,\n\ttype PolicyFunctionArguments,\n\ttype PolicyHandler,\n\ttype PolicyHandlerResult,\n\ttype PolicyInstance,\n\ttype PolicyInstanceId,\n\ttype PolicyInstanceSettings,\n\ttype PolicyName,\n\ttype PolicyResolver,\n\ttype PolicyResult,\n\ttype PolicyShape,\n\ttype PolicyStandaloneResolver,\n} from \"./policy.js\";\nexport {\n\ttype CargoToml,\n\ttype CargoTomlHandler,\n\ttype DefineCargoPolicyArgs,\n\tdefineCargoPolicy,\n} from \"./policyDefiners/defineCargoPolicy.js\";\nexport {\n\ttype DefineFileHeaderPolicyArgs,\n\tdefineFileHeaderPolicy,\n\ttype FileHeaderGeneratorConfig,\n\ttype FileHeaderPolicyConfig,\n} from \"./policyDefiners/defineFileHeaderPolicy.js\";\nexport {\n\ttype DefineGleamPolicyArgs,\n\tdefineGleamPolicy,\n\ttype GleamToml,\n\ttype GleamTomlHandler,\n} from \"./policyDefiners/defineGleamPolicy.js\";\nexport {\n\ttype DefinePackagePolicyArgs,\n\tdefinePackagePolicy as generatePackagePolicy,\n\ttype PackageJsonHandler,\n} from \"./policyDefiners/definePackagePolicy.js\";\nexport {\n\ttype PolicyFileResult,\n\tPolicyRunner,\n\ttype PolicyRunnerOptions,\n\ttype PolicyRunResults,\n} from \"./runner.js\";\n"]}
|
package/esm/makePolicy.d.ts
CHANGED
|
@@ -1,10 +1,74 @@
|
|
|
1
|
-
import type { PolicyDefinition, PolicyInstance, PolicyInstanceSettings } from "./policy.js";
|
|
1
|
+
import type { ConfiguredPolicy, PolicyDefinition, PolicyInstance, PolicyInstanceId, PolicyInstanceSettings, PolicyName, PolicyShape } from "./policy.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Options for configuring a policy instance.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface PolicyOptions {
|
|
8
|
+
/**
|
|
9
|
+
* A stable identifier for this configured policy instance.
|
|
10
|
+
*
|
|
11
|
+
* This is required when the same policy definition is configured more than once.
|
|
12
|
+
*/
|
|
13
|
+
instanceId?: PolicyInstanceId;
|
|
14
|
+
/**
|
|
15
|
+
* File paths matching these patterns will be excluded from this policy.
|
|
16
|
+
* Patterns are matched against repo-relative paths.
|
|
17
|
+
*/
|
|
18
|
+
exclude?: (string | RegExp)[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Configure a policy for use in repopo.
|
|
4
22
|
*
|
|
5
23
|
* @remarks
|
|
6
|
-
* This
|
|
7
|
-
*
|
|
24
|
+
* This function takes a policy definition and returns a configured policy instance
|
|
25
|
+
* that can be added to the `policies` array in `repopo.config.ts`.
|
|
26
|
+
*
|
|
27
|
+
* Handlers are automatically normalized: async functions are wrapped for Effection
|
|
28
|
+
* compatibility, while generator functions are used directly.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* // Policy with no config, just options
|
|
33
|
+
* policy(NoJsFileExtensions, { exclude: ["bin/*"] })
|
|
34
|
+
*
|
|
35
|
+
* // Policy with config
|
|
36
|
+
* policy(PackageJsonProperties, { verbatim: { license: "MIT" } })
|
|
37
|
+
*
|
|
38
|
+
* // Policy with config and options
|
|
39
|
+
* policy(PackageJsonProperties, { verbatim: { license: "MIT" } }, { exclude: ["vendor/*"] })
|
|
40
|
+
*
|
|
41
|
+
* // Duplicate policies need stable instance IDs
|
|
42
|
+
* policy(PackageJsonProperties, sourceConfig, { instanceId: "source-packages" })
|
|
43
|
+
* policy(PackageJsonProperties, testConfig, { instanceId: "test-packages" })
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @alpha
|
|
47
|
+
*/
|
|
48
|
+
export declare function policy<C = void>(policyDef: PolicyShape<C>, options?: PolicyOptions & {
|
|
49
|
+
exclude: (string | RegExp)[];
|
|
50
|
+
}): ConfiguredPolicy<C>;
|
|
51
|
+
/** @alpha */
|
|
52
|
+
export declare function policy<C>(policyDef: PolicyShape<C>, config: C, options?: PolicyOptions): ConfiguredPolicy<C>;
|
|
53
|
+
/**
|
|
54
|
+
* Assigns stable identities to configured policy instances.
|
|
55
|
+
*
|
|
56
|
+
* Single instances retain the policy name for compatibility. Duplicate instances
|
|
57
|
+
* must declare explicit identities so their identities remain stable across config
|
|
58
|
+
* reordering and policy renames.
|
|
59
|
+
*
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export declare function identifyPolicyInstances<T extends {
|
|
63
|
+
name: PolicyName;
|
|
64
|
+
instanceId?: PolicyInstanceId | undefined;
|
|
65
|
+
}>(policies: readonly T[]): (T & {
|
|
66
|
+
instanceId: PolicyInstanceId;
|
|
67
|
+
})[];
|
|
68
|
+
/**
|
|
69
|
+
* Input arguments for creating a policy definition.
|
|
70
|
+
*
|
|
71
|
+
* @deprecated Use {@link PolicyShape} directly instead.
|
|
8
72
|
*
|
|
9
73
|
* @alpha
|
|
10
74
|
*/
|
|
@@ -12,9 +76,7 @@ export type PolicyDefinitionInput<C = undefined> = PolicyDefinition<C>;
|
|
|
12
76
|
/**
|
|
13
77
|
* Creates a {@link PolicyDefinition} from the provided arguments.
|
|
14
78
|
*
|
|
15
|
-
* @
|
|
16
|
-
* This function accepts an object with all policy properties, making it easier
|
|
17
|
-
* to add new optional properties in the future without breaking changes.
|
|
79
|
+
* @deprecated Define policies as object literals satisfying {@link PolicyShape} instead.
|
|
18
80
|
*
|
|
19
81
|
* @example
|
|
20
82
|
* ```typescript
|
|
@@ -30,7 +92,14 @@ export type PolicyDefinitionInput<C = undefined> = PolicyDefinition<C>;
|
|
|
30
92
|
*/
|
|
31
93
|
export declare function makePolicyDefinition<C = undefined>(args: PolicyDefinitionInput<C>): PolicyDefinition<C>;
|
|
32
94
|
/**
|
|
33
|
-
* Combine a {@link PolicyDefinition} with a policy-specific config and other settings
|
|
95
|
+
* Combine a {@link PolicyDefinition} with a policy-specific config and other settings.
|
|
96
|
+
*
|
|
97
|
+
* @deprecated Use the `policy` function instead, which has a simpler API.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* makePolicy(NoJsFileExtensions, undefined, { excludeFiles: ["bin/*"] })
|
|
102
|
+
* ```
|
|
34
103
|
*
|
|
35
104
|
* @alpha
|
|
36
105
|
*/
|
package/esm/makePolicy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makePolicy.d.ts","sourceRoot":"","sources":["../src/makePolicy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"makePolicy.d.ts","sourceRoot":"","sources":["../src/makePolicy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,gBAAgB,EAEhB,gBAAgB,EAGhB,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,WAAW,EACX,MAAM,aAAa,CAAC;AAMrB;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CAC9B;AAuBD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,IAAI,EAC9B,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CAAE,GACxD,gBAAgB,CAAC,CAAC,CAAC,CAAC;AACvB,aAAa;AACb,wBAAgB,MAAM,CAAC,CAAC,EACvB,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,EACzB,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,aAAa,GACrB,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAmDvB;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACtC,CAAC,SAAS;IACT,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC1C,EACA,QAAQ,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG;IAAE,UAAU,EAAE,gBAAgB,CAAA;CAAE,CAAC,EAAE,CAgDlE;AAMD;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,GAAG,SAAS,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAEvE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,GAAG,SAAS,EACjD,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAC5B,gBAAgB,CAAC,CAAC,CAAC,CASrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC3B,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,MAAM,CAAC,EAAE,CAAC,EACV,QAAQ,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAClC,cAAc,CAAC,CAAC,CAAC,CAMnB"}
|
package/esm/makePolicy.js
CHANGED
|
@@ -1,9 +1,106 @@
|
|
|
1
|
+
import { call } from "effection";
|
|
2
|
+
import { isGeneratorFunction } from "./generators.js";
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes a handler to always return an Effection Operation.
|
|
5
|
+
* Detection happens once at registration time, not per-invocation.
|
|
6
|
+
*/
|
|
7
|
+
function normalizeHandler(handler) {
|
|
8
|
+
if (isGeneratorFunction(handler)) {
|
|
9
|
+
// Already a generator, return as-is
|
|
10
|
+
return handler;
|
|
11
|
+
}
|
|
12
|
+
// Async function - wrap with call()
|
|
13
|
+
return function* (args) {
|
|
14
|
+
const asyncHandler = handler;
|
|
15
|
+
return yield* call(() => asyncHandler(args));
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** @alpha */
|
|
19
|
+
export function policy(policyDef, configOrOptions, maybeOptions) {
|
|
20
|
+
// Determine if the second argument is config or options
|
|
21
|
+
let config;
|
|
22
|
+
let options;
|
|
23
|
+
if (maybeOptions !== undefined) {
|
|
24
|
+
// Three-argument form: policy(def, config, options)
|
|
25
|
+
config = configOrOptions;
|
|
26
|
+
options = maybeOptions;
|
|
27
|
+
}
|
|
28
|
+
else if (configOrOptions !== undefined) {
|
|
29
|
+
// Two-argument form: need to determine if it's config or options
|
|
30
|
+
// PolicyOptions has a specific shape with 'exclude' property
|
|
31
|
+
if (typeof configOrOptions === "object" &&
|
|
32
|
+
configOrOptions !== null &&
|
|
33
|
+
"exclude" in configOrOptions &&
|
|
34
|
+
!("name" in configOrOptions) &&
|
|
35
|
+
Object.keys(configOrOptions).every((k) => k === "exclude" || k === "instanceId")) {
|
|
36
|
+
// It's options (has 'exclude' and only option keys)
|
|
37
|
+
options = configOrOptions;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// It's config
|
|
41
|
+
config = configOrOptions;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Merge with default config if available
|
|
45
|
+
const effectiveConfig = config ?? policyDef.defaultConfig;
|
|
46
|
+
// Support both 'exclude' and 'excludeFiles' for backward compatibility
|
|
47
|
+
const excludePatterns = options?.exclude;
|
|
48
|
+
return {
|
|
49
|
+
...policyDef,
|
|
50
|
+
config: effectiveConfig,
|
|
51
|
+
exclude: excludePatterns,
|
|
52
|
+
excludeFiles: excludePatterns,
|
|
53
|
+
instanceId: options?.instanceId,
|
|
54
|
+
_internalHandler: normalizeHandler(policyDef.handler),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Assigns stable identities to configured policy instances.
|
|
59
|
+
*
|
|
60
|
+
* Single instances retain the policy name for compatibility. Duplicate instances
|
|
61
|
+
* must declare explicit identities so their identities remain stable across config
|
|
62
|
+
* reordering and policy renames.
|
|
63
|
+
*
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
export function identifyPolicyInstances(policies) {
|
|
67
|
+
const explicitIds = new Set();
|
|
68
|
+
const nameCounts = new Map();
|
|
69
|
+
for (const configuredPolicy of policies) {
|
|
70
|
+
nameCounts.set(configuredPolicy.name, (nameCounts.get(configuredPolicy.name) ?? 0) + 1);
|
|
71
|
+
if (configuredPolicy.instanceId !== undefined) {
|
|
72
|
+
if (explicitIds.has(configuredPolicy.instanceId)) {
|
|
73
|
+
throw new Error(`Duplicate policy instance ID: ${configuredPolicy.instanceId}`);
|
|
74
|
+
}
|
|
75
|
+
explicitIds.add(configuredPolicy.instanceId);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const usedIds = new Set(explicitIds);
|
|
79
|
+
return policies.map((configuredPolicy) => {
|
|
80
|
+
if (configuredPolicy.instanceId !== undefined) {
|
|
81
|
+
return {
|
|
82
|
+
...configuredPolicy,
|
|
83
|
+
instanceId: configuredPolicy.instanceId,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if ((nameCounts.get(configuredPolicy.name) ?? 0) > 1) {
|
|
87
|
+
throw new Error(`Policy '${configuredPolicy.name}' is configured multiple times. Set a unique instanceId for each instance.`);
|
|
88
|
+
}
|
|
89
|
+
const instanceId = configuredPolicy.name;
|
|
90
|
+
if (usedIds.has(instanceId)) {
|
|
91
|
+
throw new Error(`Policy instance ID '${instanceId}' conflicts with another configured policy. Set an explicit unique instanceId.`);
|
|
92
|
+
}
|
|
93
|
+
usedIds.add(instanceId);
|
|
94
|
+
return {
|
|
95
|
+
...configuredPolicy,
|
|
96
|
+
instanceId,
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
}
|
|
1
100
|
/**
|
|
2
101
|
* Creates a {@link PolicyDefinition} from the provided arguments.
|
|
3
102
|
*
|
|
4
|
-
* @
|
|
5
|
-
* This function accepts an object with all policy properties, making it easier
|
|
6
|
-
* to add new optional properties in the future without breaking changes.
|
|
103
|
+
* @deprecated Define policies as object literals satisfying {@link PolicyShape} instead.
|
|
7
104
|
*
|
|
8
105
|
* @example
|
|
9
106
|
* ```typescript
|
|
@@ -28,7 +125,14 @@ export function makePolicyDefinition(args) {
|
|
|
28
125
|
};
|
|
29
126
|
}
|
|
30
127
|
/**
|
|
31
|
-
* Combine a {@link PolicyDefinition} with a policy-specific config and other settings
|
|
128
|
+
* Combine a {@link PolicyDefinition} with a policy-specific config and other settings.
|
|
129
|
+
*
|
|
130
|
+
* @deprecated Use the `policy` function instead, which has a simpler API.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* makePolicy(NoJsFileExtensions, undefined, { excludeFiles: ["bin/*"] })
|
|
135
|
+
* ```
|
|
32
136
|
*
|
|
33
137
|
* @alpha
|
|
34
138
|
*/
|
package/esm/makePolicy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makePolicy.js","sourceRoot":"","sources":["../src/makePolicy.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,oBAAoB,CACnC,IAA8B;IAE9B,OAAO;QACN,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACvB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACzB,UAA+B,EAC/B,MAAU,EACV,QAAoC;IAEpC,OAAO;QACN,GAAG,UAAU;QACb,GAAG,QAAQ;QACX,MAAM;KACsB,CAAC;AAC/B,CAAC","sourcesContent":["import type {\n\tPolicyDefinition,\n\tPolicyInstance,\n\tPolicyInstanceSettings,\n} from \"./policy.js\";\n\n/**\n * Input arguments for creating a policy definition.\n *\n * @remarks\n * This type is identical to {@link PolicyDefinition} but is used as the input type\n * for {@link makePolicyDefinition} to make the API more explicit.\n *\n * @alpha\n */\nexport type PolicyDefinitionInput<C = undefined> = PolicyDefinition<C>;\n\n/**\n * Creates a {@link PolicyDefinition} from the provided arguments.\n *\n * @remarks\n * This function accepts an object with all policy properties, making it easier\n * to add new optional properties in the future without breaking changes.\n *\n * @example\n * ```typescript\n * const MyPolicy = makePolicyDefinition({\n * name: \"MyPolicy\",\n * description: \"Ensures files follow conventions\",\n * match: /\\.ts$/,\n * handler: async ({ file }) => true,\n * });\n * ```\n *\n * @alpha\n */\nexport function makePolicyDefinition<C = undefined>(\n\targs: PolicyDefinitionInput<C>,\n): PolicyDefinition<C> {\n\treturn {\n\t\tname: args.name,\n\t\tdescription: args.description,\n\t\tmatch: args.match,\n\t\thandler: args.handler,\n\t\tdefaultConfig: args.defaultConfig,\n\t\tresolver: args.resolver,\n\t};\n}\n\n/**\n * Combine a {@link PolicyDefinition} with a policy-specific config and other settings to produce a {@link PolicyInstance}.\n *\n * @alpha\n */\nexport function makePolicy<C>(\n\tdefinition: PolicyDefinition<C>,\n\tconfig?: C,\n\tsettings?: PolicyInstanceSettings<C>,\n): PolicyInstance<C> {\n\treturn {\n\t\t...definition,\n\t\t...settings,\n\t\tconfig,\n\t} satisfies PolicyInstance<C>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"makePolicy.js","sourceRoot":"","sources":["../src/makePolicy.ts"],"names":[],"mappings":"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","sourcesContent":["import { call, type Operation } from \"effection\";\nimport { isGeneratorFunction } from \"./generators.js\";\nimport type {\n\tConfiguredPolicy,\n\tPolicyArgs,\n\tPolicyDefinition,\n\tPolicyHandler,\n\tPolicyHandlerResult,\n\tPolicyInstance,\n\tPolicyInstanceId,\n\tPolicyInstanceSettings,\n\tPolicyName,\n\tPolicyShape,\n} from \"./policy.js\";\n\n// ============================================================================\n// New API: policy() function\n// ============================================================================\n\n/**\n * Options for configuring a policy instance.\n *\n * @alpha\n */\nexport interface PolicyOptions {\n\t/**\n\t * A stable identifier for this configured policy instance.\n\t *\n\t * This is required when the same policy definition is configured more than once.\n\t */\n\tinstanceId?: PolicyInstanceId;\n\n\t/**\n\t * File paths matching these patterns will be excluded from this policy.\n\t * Patterns are matched against repo-relative paths.\n\t */\n\texclude?: (string | RegExp)[];\n}\n\n/**\n * Normalizes a handler to always return an Effection Operation.\n * Detection happens once at registration time, not per-invocation.\n */\nfunction normalizeHandler<C>(\n\thandler: PolicyHandler<C>,\n): (args: PolicyArgs<C>) => Operation<PolicyHandlerResult> {\n\tif (isGeneratorFunction(handler)) {\n\t\t// Already a generator, return as-is\n\t\treturn handler as (args: PolicyArgs<C>) => Operation<PolicyHandlerResult>;\n\t}\n\n\t// Async function - wrap with call()\n\treturn function* (args: PolicyArgs<C>): Operation<PolicyHandlerResult> {\n\t\tconst asyncHandler = handler as (\n\t\t\tpolicyArgs: PolicyArgs<C>,\n\t\t) => Promise<PolicyHandlerResult>;\n\t\treturn yield* call(() => asyncHandler(args));\n\t};\n}\n\n/**\n * Configure a policy for use in repopo.\n *\n * @remarks\n * This function takes a policy definition and returns a configured policy instance\n * that can be added to the `policies` array in `repopo.config.ts`.\n *\n * Handlers are automatically normalized: async functions are wrapped for Effection\n * compatibility, while generator functions are used directly.\n *\n * @example\n * ```typescript\n * // Policy with no config, just options\n * policy(NoJsFileExtensions, { exclude: [\"bin/*\"] })\n *\n * // Policy with config\n * policy(PackageJsonProperties, { verbatim: { license: \"MIT\" } })\n *\n * // Policy with config and options\n * policy(PackageJsonProperties, { verbatim: { license: \"MIT\" } }, { exclude: [\"vendor/*\"] })\n *\n * // Duplicate policies need stable instance IDs\n * policy(PackageJsonProperties, sourceConfig, { instanceId: \"source-packages\" })\n * policy(PackageJsonProperties, testConfig, { instanceId: \"test-packages\" })\n * ```\n *\n * @alpha\n */\nexport function policy<C = void>(\n\tpolicyDef: PolicyShape<C>,\n\toptions?: PolicyOptions & { exclude: (string | RegExp)[] },\n): ConfiguredPolicy<C>;\n/** @alpha */\nexport function policy<C>(\n\tpolicyDef: PolicyShape<C>,\n\tconfig: C,\n\toptions?: PolicyOptions,\n): ConfiguredPolicy<C>;\n/** @alpha */\nexport function policy<C>(\n\tpolicyDef: PolicyShape<C>,\n\tconfigOrOptions?: C | PolicyOptions,\n\tmaybeOptions?: PolicyOptions,\n): ConfiguredPolicy<C> {\n\t// Determine if the second argument is config or options\n\tlet config: C | undefined;\n\tlet options: PolicyOptions | undefined;\n\n\tif (maybeOptions !== undefined) {\n\t\t// Three-argument form: policy(def, config, options)\n\t\tconfig = configOrOptions as C;\n\t\toptions = maybeOptions;\n\t} else if (configOrOptions !== undefined) {\n\t\t// Two-argument form: need to determine if it's config or options\n\t\t// PolicyOptions has a specific shape with 'exclude' property\n\t\tif (\n\t\t\ttypeof configOrOptions === \"object\" &&\n\t\t\tconfigOrOptions !== null &&\n\t\t\t\"exclude\" in configOrOptions &&\n\t\t\t!(\"name\" in configOrOptions) &&\n\t\t\tObject.keys(configOrOptions).every(\n\t\t\t\t(k) => k === \"exclude\" || k === \"instanceId\",\n\t\t\t)\n\t\t) {\n\t\t\t// It's options (has 'exclude' and only option keys)\n\t\t\toptions = configOrOptions as PolicyOptions;\n\t\t} else {\n\t\t\t// It's config\n\t\t\tconfig = configOrOptions as C;\n\t\t}\n\t}\n\n\t// Merge with default config if available\n\tconst effectiveConfig = config ?? (policyDef.defaultConfig as C | undefined);\n\n\t// Support both 'exclude' and 'excludeFiles' for backward compatibility\n\tconst excludePatterns = options?.exclude;\n\n\treturn {\n\t\t...policyDef,\n\t\tconfig: effectiveConfig,\n\t\texclude: excludePatterns,\n\t\texcludeFiles: excludePatterns,\n\t\tinstanceId: options?.instanceId,\n\t\t_internalHandler: normalizeHandler(policyDef.handler),\n\t};\n}\n\n/**\n * Assigns stable identities to configured policy instances.\n *\n * Single instances retain the policy name for compatibility. Duplicate instances\n * must declare explicit identities so their identities remain stable across config\n * reordering and policy renames.\n *\n * @internal\n */\nexport function identifyPolicyInstances<\n\tT extends {\n\t\tname: PolicyName;\n\t\tinstanceId?: PolicyInstanceId | undefined;\n\t},\n>(policies: readonly T[]): (T & { instanceId: PolicyInstanceId })[] {\n\tconst explicitIds = new Set<PolicyInstanceId>();\n\tconst nameCounts = new Map<PolicyName, number>();\n\n\tfor (const configuredPolicy of policies) {\n\t\tnameCounts.set(\n\t\t\tconfiguredPolicy.name,\n\t\t\t(nameCounts.get(configuredPolicy.name) ?? 0) + 1,\n\t\t);\n\t\tif (configuredPolicy.instanceId !== undefined) {\n\t\t\tif (explicitIds.has(configuredPolicy.instanceId)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Duplicate policy instance ID: ${configuredPolicy.instanceId}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\texplicitIds.add(configuredPolicy.instanceId);\n\t\t}\n\t}\n\n\tconst usedIds = new Set(explicitIds);\n\n\treturn policies.map((configuredPolicy) => {\n\t\tif (configuredPolicy.instanceId !== undefined) {\n\t\t\treturn {\n\t\t\t\t...configuredPolicy,\n\t\t\t\tinstanceId: configuredPolicy.instanceId,\n\t\t\t};\n\t\t}\n\n\t\tif ((nameCounts.get(configuredPolicy.name) ?? 0) > 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Policy '${configuredPolicy.name}' is configured multiple times. Set a unique instanceId for each instance.`,\n\t\t\t);\n\t\t}\n\n\t\tconst instanceId = configuredPolicy.name;\n\t\tif (usedIds.has(instanceId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Policy instance ID '${instanceId}' conflicts with another configured policy. Set an explicit unique instanceId.`,\n\t\t\t);\n\t\t}\n\t\tusedIds.add(instanceId);\n\n\t\treturn {\n\t\t\t...configuredPolicy,\n\t\t\tinstanceId,\n\t\t};\n\t});\n}\n\n// ============================================================================\n// Legacy API (Still supported for backward compatibility)\n// ============================================================================\n\n/**\n * Input arguments for creating a policy definition.\n *\n * @deprecated Use {@link PolicyShape} directly instead.\n *\n * @alpha\n */\nexport type PolicyDefinitionInput<C = undefined> = PolicyDefinition<C>;\n\n/**\n * Creates a {@link PolicyDefinition} from the provided arguments.\n *\n * @deprecated Define policies as object literals satisfying {@link PolicyShape} instead.\n *\n * @example\n * ```typescript\n * const MyPolicy = makePolicyDefinition({\n * name: \"MyPolicy\",\n * description: \"Ensures files follow conventions\",\n * match: /\\.ts$/,\n * handler: async ({ file }) => true,\n * });\n * ```\n *\n * @alpha\n */\nexport function makePolicyDefinition<C = undefined>(\n\targs: PolicyDefinitionInput<C>,\n): PolicyDefinition<C> {\n\treturn {\n\t\tname: args.name,\n\t\tdescription: args.description,\n\t\tmatch: args.match,\n\t\thandler: args.handler,\n\t\tdefaultConfig: args.defaultConfig,\n\t\tresolver: args.resolver,\n\t};\n}\n\n/**\n * Combine a {@link PolicyDefinition} with a policy-specific config and other settings.\n *\n * @deprecated Use the `policy` function instead, which has a simpler API.\n *\n * @example\n * ```typescript\n * makePolicy(NoJsFileExtensions, undefined, { excludeFiles: [\"bin/*\"] })\n * ```\n *\n * @alpha\n */\nexport function makePolicy<C>(\n\tdefinition: PolicyDefinition<C>,\n\tconfig?: C,\n\tsettings?: PolicyInstanceSettings<C>,\n): PolicyInstance<C> {\n\treturn {\n\t\t...definition,\n\t\t...settings,\n\t\tconfig,\n\t} satisfies PolicyInstance<C>;\n}\n"]}
|
package/esm/perf.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import type { Logger } from "@tylerbu/cli-api";
|
|
2
2
|
import type { Operation } from "effection";
|
|
3
|
-
import type {
|
|
3
|
+
import type { PolicyInstanceId } from "./policy.js";
|
|
4
|
+
/**
|
|
5
|
+
* The type of action a policy can perform.
|
|
6
|
+
* @alpha
|
|
7
|
+
*/
|
|
4
8
|
export type PolicyAction = "check" | "resolve" | "handle";
|
|
5
9
|
/**
|
|
6
10
|
* Stores performance data for each handler. Used to collect and display performance stats.
|
|
11
|
+
* @alpha
|
|
7
12
|
*/
|
|
8
13
|
export interface PolicyHandlerPerfStats {
|
|
9
14
|
count: number;
|
|
10
15
|
processed: number;
|
|
11
|
-
data: Map<PolicyAction, Map<
|
|
16
|
+
data: Map<PolicyAction, Map<PolicyInstanceId, number>>;
|
|
12
17
|
}
|
|
13
18
|
export declare function newPerfStats(): PolicyHandlerPerfStats;
|
|
14
19
|
export declare function runWithPerf<T>(name: string, action: PolicyAction, stats: PolicyHandlerPerfStats, run: () => Operation<T>): Operation<T>;
|
package/esm/perf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;CACvD;AAED,wBAAgB,YAAY,IAAI,sBAAsB,CAMrD;AAED,wBAAiB,WAAW,CAAC,CAAC,EAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,sBAAsB,EAC7B,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,GACrB,SAAS,CAAC,CAAC,CAAC,CAWd;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAWzE"}
|
package/esm/perf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,YAAY;IAC3B,OAAO;QACN,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,CAAC;QACZ,IAAI,EAAE,IAAI,GAAG,EAA+C;KAC5D,CAAC;AACH,CAAC;AAED,MAAM,SAAS,CAAC,CAAC,WAAW,CAC3B,IAAY,EACZ,MAAoB,EACpB,KAA6B,EAC7B,GAAuB;IAEvB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;IACtE,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;IAC5B,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAE1B,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAA6B,EAAE,GAAW;IAClE,GAAG,CAAC,GAAG,CACN,eAAe,KAAK,CAAC,SAAS,oBAAoB;QACjD,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,SAAS,cAAc,KAAK,CAAC,KAAK,QAAQ,CAClE,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1D,GAAG,CAAC,GAAG,CAAC,oBAAoB,MAAM,IAAI,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,OAAO,OAAO,KAAK,GAAG,IAAI,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["import type { Logger } from \"@tylerbu/cli-api\";\nimport type { Operation } from \"effection\";\nimport type { PolicyInstanceId } from \"./policy.js\";\n\n/**\n * The type of action a policy can perform.\n * @alpha\n */\nexport type PolicyAction = \"check\" | \"resolve\" | \"handle\";\n\n/**\n * Stores performance data for each handler. Used to collect and display performance stats.\n * @alpha\n */\nexport interface PolicyHandlerPerfStats {\n\tcount: number;\n\tprocessed: number;\n\tdata: Map<PolicyAction, Map<PolicyInstanceId, number>>;\n}\n\nexport function newPerfStats(): PolicyHandlerPerfStats {\n\treturn {\n\t\tcount: 0,\n\t\tprocessed: 0,\n\t\tdata: new Map<PolicyAction, Map<PolicyInstanceId, number>>(),\n\t};\n}\n\nexport function* runWithPerf<T>(\n\tname: string,\n\taction: PolicyAction,\n\tstats: PolicyHandlerPerfStats,\n\trun: () => Operation<T>,\n): Operation<T> {\n\tconst actionMap = stats.data.get(action) ?? new Map<string, number>();\n\tlet dur = actionMap.get(name) ?? 0;\n\n\tconst start = Date.now();\n\tconst result = yield* run();\n\tdur += Date.now() - start;\n\n\tactionMap.set(name, dur);\n\tstats.data.set(action, actionMap);\n\treturn result;\n}\n\nexport function logStats(stats: PolicyHandlerPerfStats, log: Logger): void {\n\tlog.log(\n\t\t`Statistics: ${stats.processed} files processed, ` +\n\t\t\t`${stats.count - stats.processed} excluded, ${stats.count} total`,\n\t);\n\tfor (const [action, handlerPerf] of stats.data.entries()) {\n\t\tlog.log(`Performance for \"${action}\":`);\n\t\tfor (const [handler, dur] of handlerPerf.entries()) {\n\t\t\tlog.log(` ${handler}: ${dur}ms`);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { PolicyShape } from "../policy.js";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for the CargoLicenceValidated policy.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface CargoLicenceValidatedConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Allowed SPDX licence identifiers. If set, only these are accepted.
|
|
10
|
+
*/
|
|
11
|
+
allowedLicences?: string[];
|
|
12
|
+
/**
|
|
13
|
+
* If true, validate the licence value against the SPDX licence list
|
|
14
|
+
* using `spdx-correct`. When enabled, typos like "MIIT" are detected
|
|
15
|
+
* and can be auto-fixed to the correct identifier ("MIT").
|
|
16
|
+
*
|
|
17
|
+
* Requires the optional peer dependency `spdx-correct` to be installed.
|
|
18
|
+
*
|
|
19
|
+
* @defaultValue true
|
|
20
|
+
*/
|
|
21
|
+
validateSpdx?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* If true, skip workspace-only Cargo.toml files (those without a [package] section).
|
|
24
|
+
*
|
|
25
|
+
* @defaultValue true
|
|
26
|
+
*/
|
|
27
|
+
skipWorkspace?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A policy that validates the `license` field in Cargo.toml against the SPDX
|
|
31
|
+
* licence list. Supports auto-fixing correctable identifiers.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Cargo.toml uses a single `license` string field (not an array like Gleam's
|
|
35
|
+
* `licences`). This policy validates that the value is a recognized SPDX
|
|
36
|
+
* identifier and can auto-fix common mistakes like wrong casing.
|
|
37
|
+
*
|
|
38
|
+
* @alpha
|
|
39
|
+
*/
|
|
40
|
+
export declare const CargoLicenceValidated: PolicyShape<CargoLicenceValidatedConfig>;
|
|
41
|
+
//# sourceMappingURL=CargoLicenceValidated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CargoLicenceValidated.d.ts","sourceRoot":"","sources":["../../src/policies/CargoLicenceValidated.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOhD;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC3C;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAKD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,2BAA2B,CAuCxE,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { resolve } from "pathe";
|
|
2
|
+
import { defineCargoPolicy, } from "../policyDefiners/defineCargoPolicy.js";
|
|
3
|
+
import { validateLicenceField } from "../policyDefiners/spdxValidator.js";
|
|
4
|
+
const MANUAL_FIX = "Use a valid SPDX licence identifier (e.g., MIT, Apache-2.0, MPL-2.0).";
|
|
5
|
+
/**
|
|
6
|
+
* A policy that validates the `license` field in Cargo.toml against the SPDX
|
|
7
|
+
* licence list. Supports auto-fixing correctable identifiers.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Cargo.toml uses a single `license` string field (not an array like Gleam's
|
|
11
|
+
* `licences`). This policy validates that the value is a recognized SPDX
|
|
12
|
+
* identifier and can auto-fix common mistakes like wrong casing.
|
|
13
|
+
*
|
|
14
|
+
* @alpha
|
|
15
|
+
*/
|
|
16
|
+
export const CargoLicenceValidated = defineCargoPolicy({
|
|
17
|
+
name: "CargoLicenceValidated",
|
|
18
|
+
description: "Validates that Cargo.toml has a valid SPDX licence identifier.",
|
|
19
|
+
handler: async (toml, { file, root, resolve: shouldResolve, config }) => {
|
|
20
|
+
const skipWorkspace = config?.skipWorkspace ?? true;
|
|
21
|
+
const pkg = toml.package;
|
|
22
|
+
if (!pkg && skipWorkspace) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
const licence = pkg?.license;
|
|
26
|
+
if (!licence || licence.trim() === "") {
|
|
27
|
+
return {
|
|
28
|
+
error: "Missing or empty license field in [package] section.",
|
|
29
|
+
manualFix: 'Add license = "MIT" (or appropriate SPDX identifier) to [package] in Cargo.toml.',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const result = await validateLicenceField({
|
|
33
|
+
licences: [licence],
|
|
34
|
+
...(config?.allowedLicences !== undefined && {
|
|
35
|
+
allowedLicences: config.allowedLicences,
|
|
36
|
+
}),
|
|
37
|
+
validateSpdx: config?.validateSpdx ?? true,
|
|
38
|
+
shouldResolve,
|
|
39
|
+
filePath: resolve(root, file),
|
|
40
|
+
manualFixMessage: MANUAL_FIX,
|
|
41
|
+
});
|
|
42
|
+
return result ?? true;
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=CargoLicenceValidated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CargoLicenceValidated.js","sourceRoot":"","sources":["../../src/policies/CargoLicenceValidated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAgC1E,MAAM,UAAU,GACf,uEAAuE,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GACjC,iBAAiB,CAAC;IACjB,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACV,gEAAgE;IACjE,OAAO,EAAE,KAAK,EACb,IAAe,EACf,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAC7C,EAAE;QACH,MAAM,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,IAAI,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,OAA8C,CAAC;QAEhE,IAAI,CAAC,GAAG,IAAI,aAAa,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,EAAE,OAA6B,CAAC;QAEnD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvC,OAAO;gBACN,KAAK,EAAE,sDAAsD;gBAC7D,SAAS,EACR,kFAAkF;aACnF,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;YACzC,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,SAAS,IAAI;gBAC5C,eAAe,EAAE,MAAM,CAAC,eAAe;aACvC,CAAC;YACF,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,IAAI;YAC1C,aAAa;YACb,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC;YAC7B,gBAAgB,EAAE,UAAU;SAC5B,CAAC,CAAC;QAEH,OAAO,MAAM,IAAI,IAAI,CAAC;IACvB,CAAC;CACD,CAAC,CAAC","sourcesContent":["import { resolve } from \"pathe\";\nimport type { PolicyShape } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\nimport { validateLicenceField } from \"../policyDefiners/spdxValidator.js\";\n\n/**\n * Configuration for the CargoLicenceValidated policy.\n *\n * @alpha\n */\nexport interface CargoLicenceValidatedConfig {\n\t/**\n\t * Allowed SPDX licence identifiers. If set, only these are accepted.\n\t */\n\tallowedLicences?: string[];\n\n\t/**\n\t * If true, validate the licence value against the SPDX licence list\n\t * using `spdx-correct`. When enabled, typos like \"MIIT\" are detected\n\t * and can be auto-fixed to the correct identifier (\"MIT\").\n\t *\n\t * Requires the optional peer dependency `spdx-correct` to be installed.\n\t *\n\t * @defaultValue true\n\t */\n\tvalidateSpdx?: boolean;\n\n\t/**\n\t * If true, skip workspace-only Cargo.toml files (those without a [package] section).\n\t *\n\t * @defaultValue true\n\t */\n\tskipWorkspace?: boolean;\n}\n\nconst MANUAL_FIX =\n\t\"Use a valid SPDX licence identifier (e.g., MIT, Apache-2.0, MPL-2.0).\";\n\n/**\n * A policy that validates the `license` field in Cargo.toml against the SPDX\n * licence list. Supports auto-fixing correctable identifiers.\n *\n * @remarks\n * Cargo.toml uses a single `license` string field (not an array like Gleam's\n * `licences`). This policy validates that the value is a recognized SPDX\n * identifier and can auto-fix common mistakes like wrong casing.\n *\n * @alpha\n */\nexport const CargoLicenceValidated: PolicyShape<CargoLicenceValidatedConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"CargoLicenceValidated\",\n\t\tdescription:\n\t\t\t\"Validates that Cargo.toml has a valid SPDX licence identifier.\",\n\t\thandler: async (\n\t\t\ttoml: CargoToml,\n\t\t\t{ file, root, resolve: shouldResolve, config },\n\t\t) => {\n\t\t\tconst skipWorkspace = config?.skipWorkspace ?? true;\n\t\t\tconst pkg = toml.package as Record<string, unknown> | undefined;\n\n\t\t\tif (!pkg && skipWorkspace) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst licence = pkg?.license as string | undefined;\n\n\t\t\tif (!licence || licence.trim() === \"\") {\n\t\t\t\treturn {\n\t\t\t\t\terror: \"Missing or empty license field in [package] section.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t'Add license = \"MIT\" (or appropriate SPDX identifier) to [package] in Cargo.toml.',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst result = await validateLicenceField({\n\t\t\t\tlicences: [licence],\n\t\t\t\t...(config?.allowedLicences !== undefined && {\n\t\t\t\t\tallowedLicences: config.allowedLicences,\n\t\t\t\t}),\n\t\t\t\tvalidateSpdx: config?.validateSpdx ?? true,\n\t\t\t\tshouldResolve,\n\t\t\t\tfilePath: resolve(root, file),\n\t\t\t\tmanualFixMessage: MANUAL_FIX,\n\t\t\t});\n\n\t\t\treturn result ?? true;\n\t\t},\n\t});\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PolicyShape } from "../policy.js";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for the CargoLintsConfigured policy.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface CargoLintsConfiguredConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Required clippy lint levels. Keys are lint names (without the `clippy::` prefix),
|
|
10
|
+
* values are the minimum level ("warn" or "deny").
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* { pedantic: "warn", nursery: "warn" }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
required?: Record<string, string>;
|
|
18
|
+
/**
|
|
19
|
+
* If true, just require that a [lints.clippy] section exists (without checking specific lints).
|
|
20
|
+
* @defaultValue true
|
|
21
|
+
*/
|
|
22
|
+
requireSection?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A policy that ensures Cargo.toml has a [lints.clippy] section configured.
|
|
26
|
+
*
|
|
27
|
+
* @alpha
|
|
28
|
+
*/
|
|
29
|
+
export declare const CargoLintsConfigured: PolicyShape<CargoLintsConfiguredConfig>;
|
|
30
|
+
//# sourceMappingURL=CargoLintsConfigured.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CargoLintsConfigured.d.ts","sourceRoot":"","sources":["../../src/policies/CargoLintsConfigured.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,WAAW,EAAE,MAAM,cAAc,CAAC;AAMrE;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAgED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,0BAA0B,CAatE,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { defineCargoPolicy, } from "../policyDefiners/defineCargoPolicy.js";
|
|
2
|
+
function checkClippyLints(clippy, required) {
|
|
3
|
+
const errors = [];
|
|
4
|
+
for (const [lint, expectedLevel] of Object.entries(required)) {
|
|
5
|
+
const actual = clippy[lint];
|
|
6
|
+
if (actual === undefined) {
|
|
7
|
+
errors.push(`Missing clippy lint: ${lint} (expected level: "${expectedLevel}")`);
|
|
8
|
+
}
|
|
9
|
+
else if (String(actual) !== expectedLevel) {
|
|
10
|
+
errors.push(`Clippy lint ${lint} = "${String(actual)}", expected "${expectedLevel}"`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return errors;
|
|
14
|
+
}
|
|
15
|
+
function checkLintsSection(toml, config) {
|
|
16
|
+
const lints = toml.lints;
|
|
17
|
+
const requireSection = config?.requireSection ?? true;
|
|
18
|
+
if (requireSection && lints === undefined) {
|
|
19
|
+
return {
|
|
20
|
+
error: "Missing [lints] section in Cargo.toml.",
|
|
21
|
+
manualFix: 'Add a [lints.clippy] section, e.g.:\n[lints.clippy]\npedantic = "warn"',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (lints === undefined) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
const clippy = lints.clippy;
|
|
28
|
+
if (requireSection && clippy === undefined) {
|
|
29
|
+
return {
|
|
30
|
+
error: "Missing [lints.clippy] section in Cargo.toml.",
|
|
31
|
+
manualFix: 'Add a [lints.clippy] section, e.g.:\n[lints.clippy]\npedantic = "warn"',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (config?.required && clippy) {
|
|
35
|
+
const errors = checkClippyLints(clippy, config.required);
|
|
36
|
+
if (errors.length > 0) {
|
|
37
|
+
return {
|
|
38
|
+
error: errors.join("; "),
|
|
39
|
+
manualFix: "Update the [lints.clippy] section with the required lint levels.",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A policy that ensures Cargo.toml has a [lints.clippy] section configured.
|
|
47
|
+
*
|
|
48
|
+
* @alpha
|
|
49
|
+
*/
|
|
50
|
+
export const CargoLintsConfigured = defineCargoPolicy({
|
|
51
|
+
name: "CargoLintsConfigured",
|
|
52
|
+
description: "Ensures Cargo.toml has clippy lints configured in the [lints] section.",
|
|
53
|
+
handler: async (toml, { config }) => {
|
|
54
|
+
// Skip workspace root Cargo.toml files
|
|
55
|
+
if (toml.workspace !== undefined && toml.package === undefined) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return checkLintsSection(toml, config);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=CargoLintsConfigured.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CargoLintsConfigured.js","sourceRoot":"","sources":["../../src/policies/CargoLintsConfigured.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AA0BhD,SAAS,gBAAgB,CACxB,MAA+B,EAC/B,QAAgC;IAEhC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CACV,wBAAwB,IAAI,sBAAsB,aAAa,IAAI,CACnE,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,aAAa,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CACV,eAAe,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,aAAa,GAAG,CACxE,CAAC;QACH,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CACzB,IAAe,EACf,MAA8C;IAE9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;IAChE,MAAM,cAAc,GAAG,MAAM,EAAE,cAAc,IAAI,IAAI,CAAC;IAEtD,IAAI,cAAc,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO;YACN,KAAK,EAAE,wCAAwC;YAC/C,SAAS,EACR,wEAAwE;SACzE,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAA6C,CAAC;IACnE,IAAI,cAAc,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5C,OAAO;YACN,KAAK,EAAE,+CAA+C;YACtD,SAAS,EACR,wEAAwE;SACzE,CAAC;IACH,CAAC;IAED,IAAI,MAAM,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO;gBACN,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxB,SAAS,EACR,kEAAkE;aACnE,CAAC;QACH,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAChC,iBAAiB,CAAC;IACjB,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACV,wEAAwE;IACzE,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,uCAAuC;QACvC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;CACD,CAAC,CAAC","sourcesContent":["import type { PolicyHandlerResult, PolicyShape } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoLintsConfigured policy.\n *\n * @alpha\n */\nexport interface CargoLintsConfiguredConfig {\n\t/**\n\t * Required clippy lint levels. Keys are lint names (without the `clippy::` prefix),\n\t * values are the minimum level (\"warn\" or \"deny\").\n\t *\n\t * @example\n\t * ```typescript\n\t * { pedantic: \"warn\", nursery: \"warn\" }\n\t * ```\n\t */\n\trequired?: Record<string, string>;\n\n\t/**\n\t * If true, just require that a [lints.clippy] section exists (without checking specific lints).\n\t * @defaultValue true\n\t */\n\trequireSection?: boolean;\n}\n\nfunction checkClippyLints(\n\tclippy: Record<string, unknown>,\n\trequired: Record<string, string>,\n): string[] {\n\tconst errors: string[] = [];\n\tfor (const [lint, expectedLevel] of Object.entries(required)) {\n\t\tconst actual = clippy[lint];\n\t\tif (actual === undefined) {\n\t\t\terrors.push(\n\t\t\t\t`Missing clippy lint: ${lint} (expected level: \"${expectedLevel}\")`,\n\t\t\t);\n\t\t} else if (String(actual) !== expectedLevel) {\n\t\t\terrors.push(\n\t\t\t\t`Clippy lint ${lint} = \"${String(actual)}\", expected \"${expectedLevel}\"`,\n\t\t\t);\n\t\t}\n\t}\n\treturn errors;\n}\n\nfunction checkLintsSection(\n\ttoml: CargoToml,\n\tconfig: CargoLintsConfiguredConfig | undefined,\n): PolicyHandlerResult {\n\tconst lints = toml.lints as Record<string, unknown> | undefined;\n\tconst requireSection = config?.requireSection ?? true;\n\n\tif (requireSection && lints === undefined) {\n\t\treturn {\n\t\t\terror: \"Missing [lints] section in Cargo.toml.\",\n\t\t\tmanualFix:\n\t\t\t\t'Add a [lints.clippy] section, e.g.:\\n[lints.clippy]\\npedantic = \"warn\"',\n\t\t};\n\t}\n\n\tif (lints === undefined) {\n\t\treturn true;\n\t}\n\n\tconst clippy = lints.clippy as Record<string, unknown> | undefined;\n\tif (requireSection && clippy === undefined) {\n\t\treturn {\n\t\t\terror: \"Missing [lints.clippy] section in Cargo.toml.\",\n\t\t\tmanualFix:\n\t\t\t\t'Add a [lints.clippy] section, e.g.:\\n[lints.clippy]\\npedantic = \"warn\"',\n\t\t};\n\t}\n\n\tif (config?.required && clippy) {\n\t\tconst errors = checkClippyLints(clippy, config.required);\n\t\tif (errors.length > 0) {\n\t\t\treturn {\n\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\tmanualFix:\n\t\t\t\t\t\"Update the [lints.clippy] section with the required lint levels.\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * A policy that ensures Cargo.toml has a [lints.clippy] section configured.\n *\n * @alpha\n */\nexport const CargoLintsConfigured: PolicyShape<CargoLintsConfiguredConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"CargoLintsConfigured\",\n\t\tdescription:\n\t\t\t\"Ensures Cargo.toml has clippy lints configured in the [lints] section.\",\n\t\thandler: async (toml: CargoToml, { config }) => {\n\t\t\t// Skip workspace root Cargo.toml files\n\t\t\tif (toml.workspace !== undefined && toml.package === undefined) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn checkLintsSection(toml, config);\n\t\t},\n\t});\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { PolicyShape } from "../policy.js";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for the CargoLockPolicy.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface CargoLockPolicyConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Policy for binary crates.
|
|
10
|
+
* - "require": Cargo.lock must be committed (default for binaries)
|
|
11
|
+
* - "warn": Emit a warning if missing
|
|
12
|
+
* - "ignore": Skip check
|
|
13
|
+
*
|
|
14
|
+
* @defaultValue "require"
|
|
15
|
+
*/
|
|
16
|
+
binaries?: "require" | "warn" | "ignore";
|
|
17
|
+
/**
|
|
18
|
+
* Policy for library crates.
|
|
19
|
+
* - "require": Cargo.lock must be committed
|
|
20
|
+
* - "warn": Emit a warning if committed (default for libraries)
|
|
21
|
+
* - "ignore": Skip check
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue "ignore"
|
|
24
|
+
*/
|
|
25
|
+
libraries?: "require" | "warn" | "ignore";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A context-aware policy for Cargo.lock files.
|
|
29
|
+
* Binary crates should commit Cargo.lock; library crates typically shouldn't.
|
|
30
|
+
*
|
|
31
|
+
* @alpha
|
|
32
|
+
*/
|
|
33
|
+
export declare const CargoLockPolicy: PolicyShape<CargoLockPolicyConfig>;
|
|
34
|
+
//# sourceMappingURL=CargoLockPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CargoLockPolicy.d.ts","sourceRoot":"","sources":["../../src/policies/CargoLockPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IAEzC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;CAC1C;AAsBD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,qBAAqB,CAuC5D,CAAC"}
|