repopo 0.12.0 → 0.14.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 +70 -0
- package/README.md +57 -90
- package/THIRD-PARTY-LICENSES.txt +169 -11
- package/bin/dev.js +0 -0
- package/esm/adapters/fluidFramework.d.ts +13 -9
- package/esm/adapters/fluidFramework.d.ts.map +1 -1
- package/esm/adapters/fluidFramework.js +20 -43
- package/esm/adapters/fluidFramework.js.map +1 -1
- package/esm/api.d.ts +66 -1
- package/esm/api.d.ts.map +1 -1
- package/esm/api.js +18 -1
- package/esm/api.js.map +1 -1
- package/esm/baseCommand.d.ts.map +1 -1
- package/esm/baseCommand.js +2 -2
- package/esm/baseCommand.js.map +1 -1
- package/esm/commands/check-native.d.ts +5 -3
- package/esm/commands/check-native.d.ts.map +1 -1
- package/esm/commands/check-native.js +35 -7
- package/esm/commands/check-native.js.map +1 -1
- package/esm/commands/check.d.ts +8 -21
- package/esm/commands/check.d.ts.map +1 -1
- package/esm/commands/check.js +98 -154
- package/esm/commands/check.js.map +1 -1
- package/esm/commands/list.d.ts.map +1 -1
- package/esm/commands/list.js +1 -0
- package/esm/commands/list.js.map +1 -1
- package/esm/concurrency.d.ts +3 -0
- package/esm/concurrency.d.ts.map +1 -0
- package/esm/concurrency.js +8 -0
- package/esm/concurrency.js.map +1 -0
- package/esm/config.d.ts +10 -39
- package/esm/config.d.ts.map +1 -1
- package/esm/config.js +3 -7
- package/esm/config.js.map +1 -1
- package/esm/context.d.ts +10 -1
- package/esm/context.d.ts.map +1 -1
- package/esm/context.js +19 -1
- package/esm/context.js.map +1 -1
- package/esm/executionContractError.d.ts +4 -0
- package/esm/executionContractError.d.ts.map +1 -0
- package/esm/executionContractError.js +4 -0
- package/esm/executionContractError.js.map +1 -0
- package/esm/fileCache.d.ts +12 -0
- package/esm/fileCache.d.ts.map +1 -0
- package/esm/fileCache.js +37 -0
- package/esm/fileCache.js.map +1 -0
- package/esm/filePaths.d.ts +2 -0
- package/esm/filePaths.d.ts.map +1 -0
- package/esm/filePaths.js +9 -0
- package/esm/filePaths.js.map +1 -0
- package/esm/generators.d.ts +0 -20
- package/esm/generators.d.ts.map +1 -1
- package/esm/generators.js.map +1 -1
- package/esm/index.d.ts +3 -16
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -17
- package/esm/index.js.map +1 -1
- package/esm/makePolicy.d.ts +20 -100
- package/esm/makePolicy.d.ts.map +1 -1
- package/esm/makePolicy.js +46 -132
- package/esm/makePolicy.js.map +1 -1
- package/esm/perf.d.ts +5 -2
- package/esm/perf.d.ts.map +1 -1
- package/esm/perf.js +10 -9
- package/esm/perf.js.map +1 -1
- package/esm/policies/CargoLicenceValidated.d.ts +4 -4
- package/esm/policies/CargoLicenceValidated.d.ts.map +1 -1
- package/esm/policies/CargoLicenceValidated.js +9 -7
- package/esm/policies/CargoLicenceValidated.js.map +1 -1
- package/esm/policies/CargoLintsConfigured.d.ts +4 -4
- package/esm/policies/CargoLintsConfigured.d.ts.map +1 -1
- package/esm/policies/CargoLintsConfigured.js +19 -15
- package/esm/policies/CargoLintsConfigured.js.map +1 -1
- package/esm/policies/CargoLockPolicy.d.ts +4 -4
- package/esm/policies/CargoLockPolicy.d.ts.map +1 -1
- package/esm/policies/CargoLockPolicy.js +15 -11
- package/esm/policies/CargoLockPolicy.js.map +1 -1
- package/esm/policies/CargoTomlRequired.d.ts +5 -5
- package/esm/policies/CargoTomlRequired.d.ts.map +1 -1
- package/esm/policies/CargoTomlRequired.js +7 -7
- package/esm/policies/CargoTomlRequired.js.map +1 -1
- package/esm/policies/CargoTomlSorted.d.ts +4 -4
- package/esm/policies/CargoTomlSorted.d.ts.map +1 -1
- package/esm/policies/CargoTomlSorted.js +21 -17
- package/esm/policies/CargoTomlSorted.js.map +1 -1
- package/esm/policies/ConditionalScripts.d.ts +10 -8
- package/esm/policies/ConditionalScripts.d.ts.map +1 -1
- package/esm/policies/ConditionalScripts.js +24 -22
- package/esm/policies/ConditionalScripts.js.map +1 -1
- package/esm/policies/ExactScripts.d.ts +8 -6
- package/esm/policies/ExactScripts.d.ts.map +1 -1
- package/esm/policies/ExactScripts.js +15 -18
- package/esm/policies/ExactScripts.js.map +1 -1
- package/esm/policies/GleamDepVersions.d.ts +5 -5
- package/esm/policies/GleamDepVersions.d.ts.map +1 -1
- package/esm/policies/GleamDepVersions.js +5 -5
- package/esm/policies/GleamDepVersions.js.map +1 -1
- package/esm/policies/GleamDocExists.d.ts +4 -4
- package/esm/policies/GleamDocExists.d.ts.map +1 -1
- package/esm/policies/GleamDocExists.js +6 -6
- package/esm/policies/GleamDocExists.js.map +1 -1
- package/esm/policies/GleamInternalModulesConfigured.d.ts +4 -4
- package/esm/policies/GleamInternalModulesConfigured.d.ts.map +1 -1
- package/esm/policies/GleamInternalModulesConfigured.js +8 -6
- package/esm/policies/GleamInternalModulesConfigured.js.map +1 -1
- package/esm/policies/GleamLicenceConfigured.d.ts +4 -4
- package/esm/policies/GleamLicenceConfigured.d.ts.map +1 -1
- package/esm/policies/GleamLicenceConfigured.js +8 -6
- package/esm/policies/GleamLicenceConfigured.js.map +1 -1
- package/esm/policies/GleamManifestCommitted.d.ts +10 -3
- package/esm/policies/GleamManifestCommitted.d.ts.map +1 -1
- package/esm/policies/GleamManifestCommitted.js +10 -9
- package/esm/policies/GleamManifestCommitted.js.map +1 -1
- package/esm/policies/GleamMonorepoConsistency.d.ts +13 -5
- package/esm/policies/GleamMonorepoConsistency.d.ts.map +1 -1
- package/esm/policies/GleamMonorepoConsistency.js +10 -10
- package/esm/policies/GleamMonorepoConsistency.js.map +1 -1
- package/esm/policies/GleamNameRestrictions.d.ts +4 -4
- package/esm/policies/GleamNameRestrictions.d.ts.map +1 -1
- package/esm/policies/GleamNameRestrictions.js +6 -6
- package/esm/policies/GleamNameRestrictions.js.map +1 -1
- package/esm/policies/GleamNoPathDepsInPublished.d.ts +4 -4
- package/esm/policies/GleamNoPathDepsInPublished.d.ts.map +1 -1
- package/esm/policies/GleamNoPathDepsInPublished.js +6 -6
- package/esm/policies/GleamNoPathDepsInPublished.js.map +1 -1
- package/esm/policies/GleamPathDepsValid.d.ts +3 -3
- package/esm/policies/GleamPathDepsValid.d.ts.map +1 -1
- package/esm/policies/GleamPathDepsValid.js +5 -5
- package/esm/policies/GleamPathDepsValid.js.map +1 -1
- package/esm/policies/GleamProjectStructure.d.ts +11 -4
- package/esm/policies/GleamProjectStructure.d.ts.map +1 -1
- package/esm/policies/GleamProjectStructure.js +7 -8
- package/esm/policies/GleamProjectStructure.js.map +1 -1
- package/esm/policies/GleamSharedDependencyVersions.d.ts +12 -4
- package/esm/policies/GleamSharedDependencyVersions.d.ts.map +1 -1
- package/esm/policies/GleamSharedDependencyVersions.js +10 -10
- package/esm/policies/GleamSharedDependencyVersions.js.map +1 -1
- package/esm/policies/GleamTomlRequired.d.ts +4 -4
- package/esm/policies/GleamTomlRequired.d.ts.map +1 -1
- package/esm/policies/GleamTomlRequired.js +5 -5
- package/esm/policies/GleamTomlRequired.js.map +1 -1
- package/esm/policies/GleamTomlSorted.d.ts +4 -4
- package/esm/policies/GleamTomlSorted.d.ts.map +1 -1
- package/esm/policies/GleamTomlSorted.js +21 -17
- package/esm/policies/GleamTomlSorted.js.map +1 -1
- package/esm/policies/GleamVersionConstraint.d.ts +4 -4
- package/esm/policies/GleamVersionConstraint.d.ts.map +1 -1
- package/esm/policies/GleamVersionConstraint.js +14 -10
- package/esm/policies/GleamVersionConstraint.js.map +1 -1
- package/esm/policies/HtmlFileHeaders.d.ts +4 -2
- 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 +4 -2
- package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
- package/esm/policies/JsTsFileHeaders.js +1 -1
- package/esm/policies/JsTsFileHeaders.js.map +1 -1
- package/esm/policies/LicenseFileExists.d.ts +10 -4
- package/esm/policies/LicenseFileExists.d.ts.map +1 -1
- package/esm/policies/LicenseFileExists.js +27 -20
- package/esm/policies/LicenseFileExists.js.map +1 -1
- package/esm/policies/MaxChangedFiles.d.ts +17 -0
- package/esm/policies/MaxChangedFiles.d.ts.map +1 -0
- package/esm/policies/MaxChangedFiles.js +22 -0
- package/esm/policies/MaxChangedFiles.js.map +1 -0
- package/esm/policies/MutuallyExclusiveScripts.d.ts +8 -6
- package/esm/policies/MutuallyExclusiveScripts.d.ts.map +1 -1
- package/esm/policies/MutuallyExclusiveScripts.js +9 -13
- package/esm/policies/MutuallyExclusiveScripts.js.map +1 -1
- package/esm/policies/NoBuildDirectory.d.ts +9 -3
- package/esm/policies/NoBuildDirectory.d.ts.map +1 -1
- package/esm/policies/NoBuildDirectory.js +8 -13
- package/esm/policies/NoBuildDirectory.js.map +1 -1
- package/esm/policies/NoJsFileExtensions.d.ts +9 -3
- package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
- package/esm/policies/NoJsFileExtensions.js +9 -14
- package/esm/policies/NoJsFileExtensions.js.map +1 -1
- package/esm/policies/NoLargeBinaryFiles.d.ts +9 -4
- package/esm/policies/NoLargeBinaryFiles.d.ts.map +1 -1
- package/esm/policies/NoLargeBinaryFiles.js +10 -16
- package/esm/policies/NoLargeBinaryFiles.js.map +1 -1
- package/esm/policies/NoPrivateWorkspaceDependencies.d.ts +10 -6
- package/esm/policies/NoPrivateWorkspaceDependencies.d.ts.map +1 -1
- package/esm/policies/NoPrivateWorkspaceDependencies.js +12 -14
- package/esm/policies/NoPrivateWorkspaceDependencies.js.map +1 -1
- package/esm/policies/NoTargetArtifacts.d.ts +9 -3
- package/esm/policies/NoTargetArtifacts.d.ts.map +1 -1
- package/esm/policies/NoTargetArtifacts.js +9 -14
- package/esm/policies/NoTargetArtifacts.js.map +1 -1
- package/esm/policies/NoUnsafeWithoutJustification.d.ts +11 -4
- package/esm/policies/NoUnsafeWithoutJustification.d.ts.map +1 -1
- package/esm/policies/NoUnsafeWithoutJustification.js +8 -9
- package/esm/policies/NoUnsafeWithoutJustification.js.map +1 -1
- package/esm/policies/NoWildcardDependencies.d.ts +5 -5
- package/esm/policies/NoWildcardDependencies.d.ts.map +1 -1
- package/esm/policies/NoWildcardDependencies.js +6 -6
- package/esm/policies/NoWildcardDependencies.js.map +1 -1
- package/esm/policies/PackageAllowedScopes.d.ts +9 -5
- package/esm/policies/PackageAllowedScopes.d.ts.map +1 -1
- package/esm/policies/PackageAllowedScopes.js +15 -16
- package/esm/policies/PackageAllowedScopes.js.map +1 -1
- package/esm/policies/PackageEsmType.d.ts +7 -5
- package/esm/policies/PackageEsmType.d.ts.map +1 -1
- package/esm/policies/PackageEsmType.js +31 -31
- package/esm/policies/PackageEsmType.js.map +1 -1
- package/esm/policies/PackageFolderName.d.ts +8 -6
- package/esm/policies/PackageFolderName.d.ts.map +1 -1
- package/esm/policies/PackageFolderName.js +13 -16
- package/esm/policies/PackageFolderName.js.map +1 -1
- package/esm/policies/PackageJsonProperties.d.ts +5 -3
- package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
- package/esm/policies/PackageJsonProperties.js +6 -17
- package/esm/policies/PackageJsonProperties.js.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +2 -7
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.js +28 -42
- package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
- package/esm/policies/PackageJsonSorted.d.ts +2 -2
- package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
- package/esm/policies/PackageJsonSorted.js +15 -30
- package/esm/policies/PackageJsonSorted.js.map +1 -1
- package/esm/policies/PackageLicense.d.ts +4 -4
- package/esm/policies/PackageLicense.d.ts.map +1 -1
- package/esm/policies/PackageLicense.js +31 -52
- package/esm/policies/PackageLicense.js.map +1 -1
- package/esm/policies/PackagePrivateField.d.ts +12 -8
- package/esm/policies/PackagePrivateField.d.ts.map +1 -1
- package/esm/policies/PackagePrivateField.js +31 -23
- package/esm/policies/PackagePrivateField.js.map +1 -1
- package/esm/policies/PackageReadme.d.ts +6 -5
- package/esm/policies/PackageReadme.d.ts.map +1 -1
- package/esm/policies/PackageReadme.js +22 -59
- package/esm/policies/PackageReadme.js.map +1 -1
- package/esm/policies/PackageScripts.d.ts +26 -22
- package/esm/policies/PackageScripts.d.ts.map +1 -1
- package/esm/policies/PackageScripts.js +39 -36
- package/esm/policies/PackageScripts.js.map +1 -1
- package/esm/policies/PackageTestScripts.d.ts +10 -6
- package/esm/policies/PackageTestScripts.d.ts.map +1 -1
- package/esm/policies/PackageTestScripts.js +14 -16
- package/esm/policies/PackageTestScripts.js.map +1 -1
- package/esm/policies/PublicApiDocumented.d.ts +4 -4
- package/esm/policies/PublicApiDocumented.d.ts.map +1 -1
- package/esm/policies/PublicApiDocumented.js +10 -8
- package/esm/policies/PublicApiDocumented.js.map +1 -1
- package/esm/policies/RequireCompanionChanges.d.ts +16 -0
- package/esm/policies/RequireCompanionChanges.d.ts.map +1 -0
- package/esm/policies/RequireCompanionChanges.js +42 -0
- package/esm/policies/RequireCompanionChanges.js.map +1 -0
- package/esm/policies/RequiredGitignorePatterns.d.ts +11 -4
- package/esm/policies/RequiredGitignorePatterns.d.ts.map +1 -1
- package/esm/policies/RequiredGitignorePatterns.js +29 -36
- package/esm/policies/RequiredGitignorePatterns.js.map +1 -1
- package/esm/policies/RequiredScripts.d.ts +9 -7
- package/esm/policies/RequiredScripts.d.ts.map +1 -1
- package/esm/policies/RequiredScripts.js +24 -24
- package/esm/policies/RequiredScripts.js.map +1 -1
- package/esm/policies/RustDocExists.d.ts +4 -4
- package/esm/policies/RustDocExists.d.ts.map +1 -1
- package/esm/policies/RustDocExists.js +6 -6
- package/esm/policies/RustDocExists.js.map +1 -1
- package/esm/policies/RustToolchainExists.d.ts +11 -4
- package/esm/policies/RustToolchainExists.d.ts.map +1 -1
- package/esm/policies/RustToolchainExists.js +10 -9
- package/esm/policies/RustToolchainExists.js.map +1 -1
- package/esm/policies/RustfmtConfigExists.d.ts +11 -4
- package/esm/policies/RustfmtConfigExists.d.ts.map +1 -1
- package/esm/policies/RustfmtConfigExists.js +10 -9
- package/esm/policies/RustfmtConfigExists.js.map +1 -1
- package/esm/policies/ScriptContains.d.ts +9 -7
- package/esm/policies/ScriptContains.d.ts.map +1 -1
- package/esm/policies/ScriptContains.js +9 -13
- package/esm/policies/ScriptContains.js.map +1 -1
- package/esm/policies/SharedDependencyVersions.d.ts +9 -4
- package/esm/policies/SharedDependencyVersions.d.ts.map +1 -1
- package/esm/policies/SharedDependencyVersions.js +28 -20
- package/esm/policies/SharedDependencyVersions.js.map +1 -1
- package/esm/policies/WorkspaceInheritance.d.ts +11 -4
- package/esm/policies/WorkspaceInheritance.d.ts.map +1 -1
- package/esm/policies/WorkspaceInheritance.js +10 -11
- package/esm/policies/WorkspaceInheritance.js.map +1 -1
- package/esm/policies/WorkspaceMembersValid.d.ts +11 -4
- package/esm/policies/WorkspaceMembersValid.d.ts.map +1 -1
- package/esm/policies/WorkspaceMembersValid.js +10 -11
- package/esm/policies/WorkspaceMembersValid.js.map +1 -1
- package/esm/policies/constants.d.ts.map +1 -1
- package/esm/policies/constants.js +1 -1
- package/esm/policies/constants.js.map +1 -1
- package/esm/policies.d.ts +15 -5
- package/esm/policies.d.ts.map +1 -1
- package/esm/policies.js +14 -5
- package/esm/policies.js.map +1 -1
- package/esm/policy.d.ts +67 -289
- package/esm/policy.d.ts.map +1 -1
- package/esm/policy.js +1 -122
- package/esm/policy.js.map +1 -1
- package/esm/policyDefiners/defineCargoPolicy.d.ts +25 -9
- package/esm/policyDefiners/defineCargoPolicy.d.ts.map +1 -1
- package/esm/policyDefiners/defineCargoPolicy.js +10 -28
- package/esm/policyDefiners/defineCargoPolicy.js.map +1 -1
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts +27 -14
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -1
- package/esm/policyDefiners/defineFileHeaderPolicy.js +16 -35
- package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -1
- package/esm/policyDefiners/defineGleamPolicy.d.ts +25 -9
- package/esm/policyDefiners/defineGleamPolicy.d.ts.map +1 -1
- package/esm/policyDefiners/defineGleamPolicy.js +10 -27
- package/esm/policyDefiners/defineGleamPolicy.js.map +1 -1
- package/esm/policyDefiners/definePackagePolicy.d.ts +24 -13
- package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -1
- package/esm/policyDefiners/definePackagePolicy.js +9 -32
- package/esm/policyDefiners/definePackagePolicy.js.map +1 -1
- package/esm/policyDefiners/spdxValidator.d.ts +4 -12
- package/esm/policyDefiners/spdxValidator.d.ts.map +1 -1
- package/esm/policyDefiners/spdxValidator.js +26 -14
- package/esm/policyDefiners/spdxValidator.js.map +1 -1
- package/esm/policyExecution.d.ts +20 -0
- package/esm/policyExecution.d.ts.map +1 -0
- package/esm/policyExecution.js +234 -0
- package/esm/policyExecution.js.map +1 -0
- package/esm/repositoryChanges.d.ts +26 -0
- package/esm/repositoryChanges.d.ts.map +1 -0
- package/esm/repositoryChanges.js +172 -0
- package/esm/repositoryChanges.js.map +1 -0
- package/esm/repositoryFiles.d.ts +6 -0
- package/esm/repositoryFiles.d.ts.map +1 -0
- package/esm/repositoryFiles.js +11 -0
- package/esm/repositoryFiles.js.map +1 -0
- package/esm/runner.d.ts +73 -47
- package/esm/runner.d.ts.map +1 -1
- package/esm/runner.js +158 -144
- package/esm/runner.js.map +1 -1
- package/esm/settlePolicyPromise.d.ts +4 -0
- package/esm/settlePolicyPromise.d.ts.map +1 -0
- package/esm/settlePolicyPromise.js +10 -0
- package/esm/settlePolicyPromise.js.map +1 -0
- package/esm/tsdoc-metadata.json +1 -1
- package/esm/utils/safePaths.d.ts +9 -0
- package/esm/utils/safePaths.d.ts.map +1 -0
- package/esm/utils/safePaths.js +40 -0
- package/esm/utils/safePaths.js.map +1 -0
- package/oclif.manifest.json +57 -2
- package/package.json +42 -27
- package/scripts/benchmark.mjs +341 -0
- package/sidecar/sidecar.mjs +388 -417
|
@@ -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 { DefinedConfig, FilePolicyDefinition, PolicyArgs, PolicyResult } from "../policy.js";
|
|
4
4
|
/**
|
|
5
5
|
* A policy handler especially for policies that target package.json.
|
|
6
6
|
*
|
|
@@ -11,13 +11,13 @@ import type { PolicyArgs, PolicyHandlerResult, PolicyShape } from "../policy.js"
|
|
|
11
11
|
*
|
|
12
12
|
* Both styles are supported to allow gradual migration and flexibility.
|
|
13
13
|
*
|
|
14
|
-
* @
|
|
14
|
+
* @public
|
|
15
15
|
*/
|
|
16
|
-
export type PackageJsonHandler<J, C> = (json: J, args: PolicyArgs<C>) => Operation<
|
|
16
|
+
export type PackageJsonHandler<J, C> = (json: J, args: PolicyArgs<C>) => Operation<PolicyResult> | Promise<PolicyResult>;
|
|
17
17
|
/**
|
|
18
18
|
* Input arguments for defining a package.json policy.
|
|
19
19
|
*
|
|
20
|
-
* @
|
|
20
|
+
* @public
|
|
21
21
|
*/
|
|
22
22
|
export interface DefinePackagePolicyArgs<J, C> {
|
|
23
23
|
/**
|
|
@@ -36,6 +36,7 @@ export interface DefinePackagePolicyArgs<J, C> {
|
|
|
36
36
|
* Optional default configuration for the policy.
|
|
37
37
|
*/
|
|
38
38
|
defaultConfig?: C;
|
|
39
|
+
requiresConfig?: boolean;
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
42
|
* Define a repo policy for package.json files.
|
|
@@ -44,6 +45,9 @@ export interface DefinePackagePolicyArgs<J, C> {
|
|
|
44
45
|
* This is a helper function that creates a policy pre-configured to match
|
|
45
46
|
* package.json files. The handler receives the parsed JSON content.
|
|
46
47
|
*
|
|
48
|
+
* @param args - Policy metadata, parsed-JSON handler, and optional defaults.
|
|
49
|
+
* @returns A file policy that reads and parses matching package.json files.
|
|
50
|
+
*
|
|
47
51
|
* @example
|
|
48
52
|
* ```typescript
|
|
49
53
|
* const MyPackagePolicy = definePackagePolicy({
|
|
@@ -51,19 +55,26 @@ export interface DefinePackagePolicyArgs<J, C> {
|
|
|
51
55
|
* description: "Ensures package.json has required fields",
|
|
52
56
|
* handler: async (json, { file }) => {
|
|
53
57
|
* if (!json.name) {
|
|
54
|
-
* return {
|
|
58
|
+
* return [{ message: "Missing name" }];
|
|
55
59
|
* }
|
|
56
|
-
* return
|
|
60
|
+
* return [];
|
|
57
61
|
* },
|
|
58
62
|
* });
|
|
59
63
|
* ```
|
|
60
64
|
*
|
|
61
|
-
* @
|
|
62
|
-
*/
|
|
63
|
-
export declare function definePackagePolicy<J = PackageJson, C = undefined>(args: DefinePackagePolicyArgs<J, C>): PolicyShape<C>;
|
|
64
|
-
/**
|
|
65
|
-
* Alias for definePackagePolicy.
|
|
66
|
-
* @alpha
|
|
65
|
+
* @public
|
|
67
66
|
*/
|
|
68
|
-
export declare
|
|
67
|
+
export declare function definePackagePolicy<J = PackageJson, C = void>(args: DefinePackagePolicyArgs<J, C> & {
|
|
68
|
+
defaultConfig: DefinedConfig<C>;
|
|
69
|
+
}): FilePolicyDefinition<C> & {
|
|
70
|
+
defaultConfig: DefinedConfig<C>;
|
|
71
|
+
};
|
|
72
|
+
/** Define a package policy that requires explicit configuration. @public */
|
|
73
|
+
export declare function definePackagePolicy<J = PackageJson, C = void>(args: DefinePackagePolicyArgs<J, C> & {
|
|
74
|
+
requiresConfig: true;
|
|
75
|
+
}): FilePolicyDefinition<C> & {
|
|
76
|
+
requiresConfig: true;
|
|
77
|
+
};
|
|
78
|
+
/** Define a package policy with optional configuration. @public */
|
|
79
|
+
export declare function definePackagePolicy<J = PackageJson, C = void>(args: DefinePackagePolicyArgs<J, C>): FilePolicyDefinition<C>;
|
|
69
80
|
//# 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;
|
|
1
|
+
{"version":3,"file":"definePackagePolicy.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/definePackagePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,OAAO,KAAK,EACX,aAAa,EACb,oBAAoB,EACpB,UAAU,EACV,YAAY,EACZ,MAAM,cAAc,CAAC;AAMtB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI,CACtC,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KACf,SAAS,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAcrD;;;;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;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC,GAAG,IAAI,EAC5D,IAAI,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;CAAE,GACvE,oBAAoB,CAAC,CAAC,CAAC,GAAG;IAAE,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;AACjE,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC,GAAG,IAAI,EAC5D,IAAI,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,cAAc,EAAE,IAAI,CAAA;CAAE,GAC5D,oBAAoB,CAAC,CAAC,CAAC,GAAG;IAAE,cAAc,EAAE,IAAI,CAAA;CAAE,CAAC;AACtD,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC,GAAG,IAAI,EAC5D,IAAI,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GACjC,oBAAoB,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { call } from "effection";
|
|
2
2
|
import jsonfile from "jsonfile";
|
|
3
|
-
import {
|
|
3
|
+
import { ExecutionContractError } from "../executionContractError.js";
|
|
4
|
+
import { readParsedFile } from "../fileCache.js";
|
|
4
5
|
import { PackageJsonRegexMatch } from "../policies/constants.js";
|
|
6
|
+
import { settlePolicyPromise } from "../settlePolicyPromise.js";
|
|
7
|
+
import { resolveRepoFilePath } from "../utils/safePaths.js";
|
|
5
8
|
const { readFile: readJson } = jsonfile;
|
|
6
9
|
/**
|
|
7
10
|
* Type guard to check if a value is an Effection Operation (generator).
|
|
@@ -12,29 +15,6 @@ function isOperation(value) {
|
|
|
12
15
|
"next" in value &&
|
|
13
16
|
typeof value.next === "function");
|
|
14
17
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Define a repo policy for package.json files.
|
|
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
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```typescript
|
|
24
|
-
* const MyPackagePolicy = definePackagePolicy({
|
|
25
|
-
* name: "MyPackagePolicy",
|
|
26
|
-
* description: "Ensures package.json has required fields",
|
|
27
|
-
* handler: async (json, { file }) => {
|
|
28
|
-
* if (!json.name) {
|
|
29
|
-
* return { error: "Missing name", fixable: false };
|
|
30
|
-
* }
|
|
31
|
-
* return true;
|
|
32
|
-
* },
|
|
33
|
-
* });
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* @alpha
|
|
37
|
-
*/
|
|
38
18
|
export function definePackagePolicy(args) {
|
|
39
19
|
const { name, description, handler: packageHandler, defaultConfig } = args;
|
|
40
20
|
return {
|
|
@@ -42,25 +22,22 @@ export function definePackagePolicy(args) {
|
|
|
42
22
|
description,
|
|
43
23
|
match: PackageJsonRegexMatch,
|
|
44
24
|
defaultConfig,
|
|
25
|
+
requiresConfig: args.requiresConfig,
|
|
45
26
|
handler: function* (innerArgs) {
|
|
46
|
-
const
|
|
27
|
+
const filePath = resolveRepoFilePath(innerArgs.root, innerArgs.file);
|
|
28
|
+
const json = yield* call(() => readParsedFile(innerArgs, "json", () => readJson(filePath)));
|
|
47
29
|
const result = packageHandler(json, innerArgs);
|
|
48
30
|
// Handle both Operation (generator) and Promise return types
|
|
49
31
|
if (result instanceof Promise) {
|
|
50
|
-
return yield*
|
|
32
|
+
return yield* settlePolicyPromise(result);
|
|
51
33
|
}
|
|
52
34
|
// Check if it's an Effection Operation (generator)
|
|
53
35
|
if (isOperation(result)) {
|
|
54
36
|
return yield* result;
|
|
55
37
|
}
|
|
56
38
|
// This should never happen with proper handler typing
|
|
57
|
-
throw new
|
|
39
|
+
throw new ExecutionContractError(`Unexpected handler result type: ${typeof result}`);
|
|
58
40
|
},
|
|
59
41
|
};
|
|
60
42
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Alias for definePackagePolicy.
|
|
63
|
-
* @alpha
|
|
64
|
-
*/
|
|
65
|
-
export const packagePolicy = definePackagePolicy;
|
|
66
43
|
//# 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;
|
|
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;AAEhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAOjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,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;AAmED,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,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS;YAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YACrE,MAAM,IAAI,GAAM,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAChC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAC3D,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,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC;YACD,mDAAmD;YACnD,IAAI,WAAW,CAAe,MAAM,CAAC,EAAE,CAAC;gBACvC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC;YACtB,CAAC;YACD,sDAAsD;YACtD,MAAM,IAAI,sBAAsB,CAC/B,mCAAmC,OAAO,MAAM,EAAE,CAClD,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import { call, type Operation } from \"effection\";\nimport jsonfile from \"jsonfile\";\nimport type { PackageJson } from \"type-fest\";\nimport { ExecutionContractError } from \"../executionContractError.js\";\nimport { readParsedFile } from \"../fileCache.js\";\nimport { PackageJsonRegexMatch } from \"../policies/constants.js\";\nimport type {\n\tDefinedConfig,\n\tFilePolicyDefinition,\n\tPolicyArgs,\n\tPolicyResult,\n} from \"../policy.js\";\nimport { settlePolicyPromise } from \"../settlePolicyPromise.js\";\nimport { resolveRepoFilePath } from \"../utils/safePaths.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 * @public\n */\nexport type PackageJsonHandler<J, C> = (\n\tjson: J,\n\targs: PolicyArgs<C>,\n) => Operation<PolicyResult> | Promise<PolicyResult>;\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 * @public\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\trequiresConfig?: boolean;\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 * @param args - Policy metadata, parsed-JSON handler, and optional defaults.\n * @returns A file policy that reads and parses matching package.json files.\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 [{ message: \"Missing name\" }];\n * }\n * return [];\n * },\n * });\n * ```\n *\n * @public\n */\nexport function definePackagePolicy<J = PackageJson, C = void>(\n\targs: DefinePackagePolicyArgs<J, C> & { defaultConfig: DefinedConfig<C> },\n): FilePolicyDefinition<C> & { defaultConfig: DefinedConfig<C> };\n/** Define a package policy that requires explicit configuration. @public */\nexport function definePackagePolicy<J = PackageJson, C = void>(\n\targs: DefinePackagePolicyArgs<J, C> & { requiresConfig: true },\n): FilePolicyDefinition<C> & { requiresConfig: true };\n/** Define a package policy with optional configuration. @public */\nexport function definePackagePolicy<J = PackageJson, C = void>(\n\targs: DefinePackagePolicyArgs<J, C>,\n): FilePolicyDefinition<C>;\nexport function definePackagePolicy<J = PackageJson, C = void>(\n\targs: DefinePackagePolicyArgs<J, C>,\n): FilePolicyDefinition<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\trequiresConfig: args.requiresConfig,\n\t\thandler: function* (innerArgs) {\n\t\t\tconst filePath = resolveRepoFilePath(innerArgs.root, innerArgs.file);\n\t\t\tconst json: J = yield* call(() =>\n\t\t\t\treadParsedFile(innerArgs, \"json\", () => readJson(filePath)),\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* settlePolicyPromise(result);\n\t\t\t}\n\t\t\t// Check if it's an Effection Operation (generator)\n\t\t\tif (isOperation<PolicyResult>(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 ExecutionContractError(\n\t\t\t\t`Unexpected handler result type: ${typeof result}`,\n\t\t\t);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PolicyResult } from "../policy.js";
|
|
1
2
|
/**
|
|
2
3
|
* Lazily load spdx-correct. It's an optional peer dependency.
|
|
3
4
|
*
|
|
@@ -41,18 +42,14 @@ export declare function applyCorrections(content: string, corrections: Map<strin
|
|
|
41
42
|
*
|
|
42
43
|
* @internal
|
|
43
44
|
*/
|
|
44
|
-
export declare function tryAutoFix(filePath: string, corrections: Map<string, string>, errors: string[]): Promise<
|
|
45
|
-
error: string;
|
|
46
|
-
fixable: boolean;
|
|
47
|
-
fixed: boolean;
|
|
48
|
-
}>;
|
|
45
|
+
export declare function tryAutoFix(filePath: string, corrections: Map<string, string>, errors: string[]): Promise<PolicyResult>;
|
|
49
46
|
/**
|
|
50
47
|
* Validate licence identifiers and optionally auto-fix them.
|
|
51
48
|
*
|
|
52
49
|
* Combines spdx-correct validation with allowlist checking and auto-fix
|
|
53
50
|
* into a single helper used by both Cargo and Gleam licence policies.
|
|
54
51
|
*
|
|
55
|
-
* @returns
|
|
52
|
+
* @returns An empty array if valid, or findings that describe invalid expressions.
|
|
56
53
|
* Returns `undefined` if no validation was requested (both allowlist and
|
|
57
54
|
* validateSpdx are empty/false).
|
|
58
55
|
*
|
|
@@ -65,10 +62,5 @@ export declare function validateLicenceField(options: {
|
|
|
65
62
|
shouldResolve: boolean;
|
|
66
63
|
filePath: string;
|
|
67
64
|
manualFixMessage: string;
|
|
68
|
-
}): Promise<
|
|
69
|
-
error: string;
|
|
70
|
-
fixable?: boolean;
|
|
71
|
-
fixed?: boolean;
|
|
72
|
-
manualFix?: string;
|
|
73
|
-
} | undefined>;
|
|
65
|
+
}): Promise<PolicyResult>;
|
|
74
66
|
//# sourceMappingURL=spdxValidator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spdxValidator.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/spdxValidator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spdxValidator.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/spdxValidator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;;;;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,YAAY,CAAC,CAqBvB;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,CAAC,YAAY,CAAC,CA8CxB"}
|
|
@@ -77,14 +77,17 @@ export async function tryAutoFix(filePath, corrections, errors) {
|
|
|
77
77
|
const content = await readFile(filePath, "utf-8");
|
|
78
78
|
const fixed = applyCorrections(content, corrections);
|
|
79
79
|
await writeFile(filePath, fixed);
|
|
80
|
-
|
|
80
|
+
const correctedMessages = new Set([...corrections].map(([original, corrected]) => `Licence "${original}" should be "${corrected}"`));
|
|
81
|
+
return errors.map((message) => ({
|
|
82
|
+
message,
|
|
83
|
+
fixStatus: correctedMessages.has(message) ? "fixed" : undefined,
|
|
84
|
+
}));
|
|
81
85
|
}
|
|
82
86
|
catch {
|
|
83
|
-
return {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
};
|
|
87
|
+
return errors.map((message) => ({
|
|
88
|
+
message: `${message}. Auto-fix failed.`,
|
|
89
|
+
fixStatus: "failed",
|
|
90
|
+
}));
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
/**
|
|
@@ -93,7 +96,7 @@ export async function tryAutoFix(filePath, corrections, errors) {
|
|
|
93
96
|
* Combines spdx-correct validation with allowlist checking and auto-fix
|
|
94
97
|
* into a single helper used by both Cargo and Gleam licence policies.
|
|
95
98
|
*
|
|
96
|
-
* @returns
|
|
99
|
+
* @returns An empty array if valid, or findings that describe invalid expressions.
|
|
97
100
|
* Returns `undefined` if no validation was requested (both allowlist and
|
|
98
101
|
* validateSpdx are empty/false).
|
|
99
102
|
*
|
|
@@ -105,7 +108,10 @@ export async function validateLicenceField(options) {
|
|
|
105
108
|
if (allowedLicences) {
|
|
106
109
|
const errors = validateAllowlist(licences, allowedLicences);
|
|
107
110
|
if (errors.length > 0) {
|
|
108
|
-
return
|
|
111
|
+
return errors.map((message) => ({
|
|
112
|
+
message,
|
|
113
|
+
manualFix: manualFixMessage,
|
|
114
|
+
}));
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
117
|
// Validate with spdx-correct
|
|
@@ -113,15 +119,21 @@ export async function validateLicenceField(options) {
|
|
|
113
119
|
const { errors, corrections } = await validateWithSpdxCorrect(licences);
|
|
114
120
|
if (errors.length > 0) {
|
|
115
121
|
if (shouldResolve && corrections.size > 0) {
|
|
116
|
-
|
|
122
|
+
const findings = await tryAutoFix(filePath, corrections, errors);
|
|
123
|
+
return findings.map((finding) => ({
|
|
124
|
+
...finding,
|
|
125
|
+
manualFix: manualFixMessage,
|
|
126
|
+
}));
|
|
117
127
|
}
|
|
118
|
-
return {
|
|
119
|
-
|
|
120
|
-
|
|
128
|
+
return errors.map((message) => ({
|
|
129
|
+
message,
|
|
130
|
+
fixStatus: [...corrections].some(([original, corrected]) => message === `Licence "${original}" should be "${corrected}"`)
|
|
131
|
+
? "available"
|
|
132
|
+
: undefined,
|
|
121
133
|
manualFix: manualFixMessage,
|
|
122
|
-
};
|
|
134
|
+
}));
|
|
123
135
|
}
|
|
124
136
|
}
|
|
125
|
-
return
|
|
137
|
+
return [];
|
|
126
138
|
}
|
|
127
139
|
//# sourceMappingURL=spdxValidator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spdxValidator.js","sourceRoot":"","sources":["../../src/policyDefiners/spdxValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
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\";\nimport type { PolicyResult } from \"../policy.js\";\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<PolicyResult> {\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\tconst correctedMessages = new Set(\n\t\t\t[...corrections].map(\n\t\t\t\t([original, corrected]) =>\n\t\t\t\t\t`Licence \"${original}\" should be \"${corrected}\"`,\n\t\t\t),\n\t\t);\n\t\treturn errors.map((message) => ({\n\t\t\tmessage,\n\t\t\tfixStatus: correctedMessages.has(message) ? \"fixed\" : undefined,\n\t\t}));\n\t} catch {\n\t\treturn errors.map((message) => ({\n\t\t\tmessage: `${message}. Auto-fix failed.`,\n\t\t\tfixStatus: \"failed\",\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 An empty array if valid, or findings that describe invalid expressions.\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<PolicyResult> {\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 errors.map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\tmanualFix: manualFixMessage,\n\t\t\t}));\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\tconst findings = await tryAutoFix(filePath, corrections, errors);\n\t\t\t\treturn findings.map((finding) => ({\n\t\t\t\t\t...finding,\n\t\t\t\t\tmanualFix: manualFixMessage,\n\t\t\t\t}));\n\t\t\t}\n\t\t\treturn errors.map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\tfixStatus: [...corrections].some(\n\t\t\t\t\t([original, corrected]) =>\n\t\t\t\t\t\tmessage === `Licence \"${original}\" should be \"${corrected}\"`,\n\t\t\t\t)\n\t\t\t\t\t? \"available\"\n\t\t\t\t\t: undefined,\n\t\t\t\tmanualFix: manualFixMessage,\n\t\t\t}));\n\t\t}\n\t}\n\n\treturn [];\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Operation } from "effection";
|
|
2
|
+
import { type ParsedFileCache } from "./fileCache.js";
|
|
3
|
+
import type { IdentifiedPolicy } from "./policy.js";
|
|
4
|
+
import { type RepositoryFile } from "./repositoryChanges.js";
|
|
5
|
+
import type { PolicyRunResults } from "./runner.js";
|
|
6
|
+
/** Describe thrown values without allowing hostile coercion to discard a run. */
|
|
7
|
+
export declare function executionMessage(cause: unknown): string;
|
|
8
|
+
/** Internal single-policy execution; engines own matching and scheduling. */
|
|
9
|
+
export declare class PolicyExecutor {
|
|
10
|
+
private readonly root;
|
|
11
|
+
private readonly fix;
|
|
12
|
+
constructor(root: string, fix: boolean);
|
|
13
|
+
repository(policy: Extract<IdentifiedPolicy, {
|
|
14
|
+
scope: "repository" | "changes";
|
|
15
|
+
}>, entries: readonly RepositoryFile[], output: PolicyRunResults): Operation<boolean>;
|
|
16
|
+
file(file: string, policy: Exclude<IdentifiedPolicy, {
|
|
17
|
+
scope: "repository" | "changes";
|
|
18
|
+
}>, output: PolicyRunResults, cache: ParsedFileCache | undefined): Operation<boolean>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=policyExecution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policyExecution.d.ts","sourceRoot":"","sources":["../src/policyExecution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,aAAa,CAAC;AAClE,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAsHpD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgBvD;AAuBD,6EAA6E;AAC7E,qBAAa,cAAc;IAEzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO;IAGtB,UAAU,CACjB,MAAM,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;KAAE,CAAC,EACtE,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,MAAM,EAAE,gBAAgB,GACtB,SAAS,CAAC,OAAO,CAAC;IAoDb,IAAI,CACX,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;KAAE,CAAC,EACtE,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,eAAe,GAAG,SAAS,GAChC,SAAS,CAAC,OAAO,CAAC;CA0ErB"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { types } from "node:util";
|
|
2
|
+
import { matchesPath } from "./context.js";
|
|
3
|
+
import { ExecutionContractError } from "./executionContractError.js";
|
|
4
|
+
import { fileCache } from "./fileCache.js";
|
|
5
|
+
import { runWithPerf } from "./perf.js";
|
|
6
|
+
import { inventoryPaths } from "./repositoryChanges.js";
|
|
7
|
+
import { settlePolicyPromise } from "./settlePolicyPromise.js";
|
|
8
|
+
const windowsAbsolutePath = /^[A-Za-z]:/;
|
|
9
|
+
function* execute(handler) {
|
|
10
|
+
const execution = handler();
|
|
11
|
+
if (execution instanceof Promise) {
|
|
12
|
+
return yield* settlePolicyPromise(execution);
|
|
13
|
+
}
|
|
14
|
+
if (typeof execution === "object" &&
|
|
15
|
+
execution !== null &&
|
|
16
|
+
Symbol.iterator in execution &&
|
|
17
|
+
!Array.isArray(execution)) {
|
|
18
|
+
return yield* execution;
|
|
19
|
+
}
|
|
20
|
+
throw new ExecutionContractError("Handlers and resolvers must be async functions or Effection generators.");
|
|
21
|
+
}
|
|
22
|
+
function validPath(path) {
|
|
23
|
+
return (typeof path === "string" &&
|
|
24
|
+
path.length > 0 &&
|
|
25
|
+
!path.includes("\\") &&
|
|
26
|
+
!path.includes("\0") &&
|
|
27
|
+
!path.startsWith("/") &&
|
|
28
|
+
!windowsAbsolutePath.test(path) &&
|
|
29
|
+
path
|
|
30
|
+
.split("/")
|
|
31
|
+
.every((part) => part !== "" && part !== "." && part !== ".."));
|
|
32
|
+
}
|
|
33
|
+
function validateResult(result, repository, fix) {
|
|
34
|
+
const invalid = () => new ExecutionContractError("Policy handlers and resolvers must return readonly PolicyFinding[] with message, optional manualFix, fixStatus and repository-only files; legacy results are not supported.");
|
|
35
|
+
if (!Array.isArray(result)) {
|
|
36
|
+
throw invalid();
|
|
37
|
+
}
|
|
38
|
+
for (const finding of result) {
|
|
39
|
+
if (typeof finding !== "object" ||
|
|
40
|
+
finding === null ||
|
|
41
|
+
Array.isArray(finding) ||
|
|
42
|
+
Reflect.ownKeys(finding).some((key) => typeof key !== "string" ||
|
|
43
|
+
!["message", "manualFix", "fixStatus", "files"].includes(key)) ||
|
|
44
|
+
!("message" in finding) ||
|
|
45
|
+
typeof finding.message !== "string" ||
|
|
46
|
+
finding.message.length === 0 ||
|
|
47
|
+
("manualFix" in finding &&
|
|
48
|
+
finding.manualFix !== undefined &&
|
|
49
|
+
typeof finding.manualFix !== "string") ||
|
|
50
|
+
("fixStatus" in finding &&
|
|
51
|
+
finding.fixStatus !== undefined &&
|
|
52
|
+
!["available", "fixed", "failed"].includes(finding.fixStatus)) ||
|
|
53
|
+
(!fix &&
|
|
54
|
+
(finding.fixStatus === "fixed" || finding.fixStatus === "failed")) ||
|
|
55
|
+
("files" in finding &&
|
|
56
|
+
!(repository &&
|
|
57
|
+
(finding.files === undefined ||
|
|
58
|
+
(Array.isArray(finding.files) && finding.files.every(validPath)))))) {
|
|
59
|
+
throw invalid();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function mergeFindings(checked, resolved) {
|
|
64
|
+
// Omission is not resolution; messages identify independent findings.
|
|
65
|
+
const merged = [...checked];
|
|
66
|
+
const used = new Set();
|
|
67
|
+
for (const finding of resolved) {
|
|
68
|
+
const index = checked.findIndex((previous, candidateIndex) => !used.has(candidateIndex) && previous.message === finding.message);
|
|
69
|
+
if (index === -1) {
|
|
70
|
+
merged.push(finding);
|
|
71
|
+
}
|
|
72
|
+
else if (merged[index]?.fixStatus !== "fixed") {
|
|
73
|
+
merged[index] = { ...merged[index], ...finding };
|
|
74
|
+
used.add(index);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return merged;
|
|
78
|
+
}
|
|
79
|
+
function nativeErrorMessage(cause) {
|
|
80
|
+
let current = cause;
|
|
81
|
+
while (current && !types.isProxy(current)) {
|
|
82
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, "message");
|
|
83
|
+
if (descriptor) {
|
|
84
|
+
return "value" in descriptor && typeof descriptor.value === "string"
|
|
85
|
+
? descriptor.value
|
|
86
|
+
: undefined;
|
|
87
|
+
}
|
|
88
|
+
current = Object.getPrototypeOf(current);
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
/** Describe thrown values without allowing hostile coercion to discard a run. */
|
|
93
|
+
export function executionMessage(cause) {
|
|
94
|
+
try {
|
|
95
|
+
if (cause === null ||
|
|
96
|
+
(typeof cause !== "object" && typeof cause !== "function")) {
|
|
97
|
+
return String(cause);
|
|
98
|
+
}
|
|
99
|
+
const message = !types.isProxy(cause) && types.isNativeError(cause)
|
|
100
|
+
? nativeErrorMessage(cause)
|
|
101
|
+
: undefined;
|
|
102
|
+
return message ?? "Policy threw a non-Error or uninspectable value.";
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return "Policy threw a value that cannot be inspected.";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function errorKind(cause) {
|
|
109
|
+
try {
|
|
110
|
+
if (cause === null ||
|
|
111
|
+
(typeof cause !== "object" && typeof cause !== "function")) {
|
|
112
|
+
return "exception";
|
|
113
|
+
}
|
|
114
|
+
let current = cause;
|
|
115
|
+
while (current && !types.isProxy(current)) {
|
|
116
|
+
if (current === ExecutionContractError.prototype) {
|
|
117
|
+
return "contract";
|
|
118
|
+
}
|
|
119
|
+
current = Object.getPrototypeOf(current);
|
|
120
|
+
}
|
|
121
|
+
return "exception";
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return "exception";
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Internal single-policy execution; engines own matching and scheduling. */
|
|
128
|
+
export class PolicyExecutor {
|
|
129
|
+
root;
|
|
130
|
+
fix;
|
|
131
|
+
constructor(root, fix) {
|
|
132
|
+
this.root = root;
|
|
133
|
+
this.fix = fix;
|
|
134
|
+
}
|
|
135
|
+
*repository(policy, entries, output) {
|
|
136
|
+
const { match } = policy;
|
|
137
|
+
const matching = match
|
|
138
|
+
? entries.filter((entry) => matchesPath(match, entry.path) ||
|
|
139
|
+
(entry.status === "renamed" &&
|
|
140
|
+
matchesPath(match, entry.previousPath)))
|
|
141
|
+
: entries;
|
|
142
|
+
const eligible = inventoryPaths(matching);
|
|
143
|
+
try {
|
|
144
|
+
const findings = yield* runWithPerf(policy.instanceId, "handle", output.perfStats, () => execute(() => policy.handler({
|
|
145
|
+
files: eligible,
|
|
146
|
+
entries: matching,
|
|
147
|
+
root: this.root,
|
|
148
|
+
resolve: this.fix,
|
|
149
|
+
config: policy.config,
|
|
150
|
+
})));
|
|
151
|
+
validateResult(findings, true, this.fix);
|
|
152
|
+
for (const finding of findings) {
|
|
153
|
+
output.findings.push({
|
|
154
|
+
...finding,
|
|
155
|
+
scope: policy.scope,
|
|
156
|
+
policy: policy.name,
|
|
157
|
+
policyId: policy.instanceId,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (cause) {
|
|
162
|
+
output.errors.push({
|
|
163
|
+
scope: policy.scope,
|
|
164
|
+
files: eligible,
|
|
165
|
+
policy: policy.name,
|
|
166
|
+
policyId: policy.instanceId,
|
|
167
|
+
phase: "handle",
|
|
168
|
+
kind: errorKind(cause),
|
|
169
|
+
message: executionMessage(cause),
|
|
170
|
+
cause,
|
|
171
|
+
});
|
|
172
|
+
return this.fix;
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
*file(file, policy, output, cache) {
|
|
177
|
+
let stopped = false;
|
|
178
|
+
let phase = "handle";
|
|
179
|
+
let checked = [];
|
|
180
|
+
try {
|
|
181
|
+
const args = {
|
|
182
|
+
file,
|
|
183
|
+
root: this.root,
|
|
184
|
+
resolve: this.fix,
|
|
185
|
+
config: policy.config,
|
|
186
|
+
[fileCache]: cache,
|
|
187
|
+
};
|
|
188
|
+
checked = yield* runWithPerf(policy.instanceId, "handle", output.perfStats, () => execute(() => policy.handler(args)));
|
|
189
|
+
validateResult(checked, false, this.fix);
|
|
190
|
+
if (this.fix &&
|
|
191
|
+
checked.length > 0 &&
|
|
192
|
+
policy.resolver &&
|
|
193
|
+
!checked.some((finding) => finding.fixStatus === "fixed" || finding.fixStatus === "failed")) {
|
|
194
|
+
phase = "resolve";
|
|
195
|
+
const resolver = policy.resolver;
|
|
196
|
+
const resolved = yield* runWithPerf(policy.instanceId, "resolve", output.perfStats, () => execute(() => resolver({
|
|
197
|
+
file,
|
|
198
|
+
root: args.root,
|
|
199
|
+
config: args.config,
|
|
200
|
+
findings: checked.map((finding) => ({ ...finding })),
|
|
201
|
+
})));
|
|
202
|
+
validateResult(resolved, false, true);
|
|
203
|
+
checked = mergeFindings(checked, resolved);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (cause) {
|
|
207
|
+
output.errors.push({
|
|
208
|
+
scope: "file",
|
|
209
|
+
file,
|
|
210
|
+
policy: policy.name,
|
|
211
|
+
policyId: policy.instanceId,
|
|
212
|
+
phase,
|
|
213
|
+
kind: errorKind(cause),
|
|
214
|
+
message: executionMessage(cause),
|
|
215
|
+
cause,
|
|
216
|
+
});
|
|
217
|
+
stopped = this.fix;
|
|
218
|
+
if (phase === "handle") {
|
|
219
|
+
checked = [];
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
for (const { files: _files, ...finding } of checked) {
|
|
223
|
+
output.findings.push({
|
|
224
|
+
...finding,
|
|
225
|
+
scope: "file",
|
|
226
|
+
file,
|
|
227
|
+
policy: policy.name,
|
|
228
|
+
policyId: policy.instanceId,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return stopped;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=policyExecution.js.map
|