repopo 0.12.0 → 0.13.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 +53 -0
- package/README.md +50 -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 +64 -1
- package/esm/api.d.ts.map +1 -1
- package/esm/api.js +17 -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 +3 -3
- package/esm/commands/check-native.d.ts.map +1 -1
- package/esm/commands/check-native.js +26 -7
- package/esm/commands/check-native.js.map +1 -1
- package/esm/commands/check.d.ts +6 -21
- package/esm/commands/check.d.ts.map +1 -1
- package/esm/commands/check.js +73 -153
- package/esm/commands/check.js.map +1 -1
- package/esm/commands/list.d.ts.map +1 -1
- package/esm/commands/list.js +2 -1
- 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 +5 -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 +8 -1
- package/esm/context.d.ts.map +1 -1
- package/esm/context.js +8 -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 +44 -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/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/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 +13 -5
- package/esm/policies.d.ts.map +1 -1
- package/esm/policies.js +12 -5
- package/esm/policies.js.map +1 -1
- package/esm/policy.d.ts +61 -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 +19 -0
- package/esm/policyExecution.d.ts.map +1 -0
- package/esm/policyExecution.js +224 -0
- package/esm/policyExecution.js.map +1 -0
- package/esm/repositoryFiles.d.ts +4 -0
- package/esm/repositoryFiles.d.ts.map +1 -0
- package/esm/repositoryFiles.js +8 -0
- package/esm/repositoryFiles.js.map +1 -0
- package/esm/runner.d.ts +72 -47
- package/esm/runner.d.ts.map +1 -1
- package/esm/runner.js +153 -138
- 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 +19 -2
- package/package.json +42 -27
- package/scripts/benchmark.mjs +341 -0
- package/sidecar/sidecar.mjs +348 -417
package/sidecar/sidecar.mjs
CHANGED
|
@@ -1,468 +1,399 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Newline-delimited JSON bridge for the native CLI.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* policy
|
|
6
|
-
* happens over stdin/stdout using newline-delimited JSON.
|
|
7
|
-
*
|
|
8
|
-
* Protocol:
|
|
9
|
-
* Rust -> Node: JSON request (one per line)
|
|
10
|
-
* Node -> Rust: JSON response (one per line)
|
|
11
|
-
*
|
|
12
|
-
* Request format:
|
|
13
|
-
* { "method": "load_config", "params": { "configPath": "...", "gitRoot": "..." } }
|
|
14
|
-
* { "method": "run_handler", "params": { "policyName": "...", "file": "...", "root": "...", "resolve": false } }
|
|
15
|
-
* { "method": "run_resolver", "params": { "policyName": "...", "file": "...", "root": "..." } }
|
|
16
|
-
* { "method": "run_handler_batch", "params": { "policyName": "...", "files": [...], "root": "...", "resolve": false } }
|
|
17
|
-
* { "method": "run_resolver_batch", "params": { "policyName": "...", "files": [...], "root": "..." } }
|
|
18
|
-
* { "method": "shutdown" }
|
|
19
|
-
*
|
|
20
|
-
* Response format:
|
|
21
|
-
* { "ok": true, "data": ... }
|
|
22
|
-
* { "ok": false, "error": "message" }
|
|
4
|
+
* Rust owns matching and scheduling. This bridge executes only explicitly
|
|
5
|
+
* selected policy units, sharing contracts and reconciliation with `check`.
|
|
23
6
|
*/
|
|
24
|
-
|
|
7
|
+
import { Console } from "node:console";
|
|
25
8
|
import { stat } from "node:fs/promises";
|
|
26
9
|
import { createInterface } from "node:readline";
|
|
10
|
+
import { types } from "node:util";
|
|
27
11
|
import { TypeScriptLoader } from "@tylerbu/lilconfig-loader-ts";
|
|
28
|
-
import { run } from "effection";
|
|
12
|
+
import { all, run } from "effection";
|
|
29
13
|
import { lilconfig } from "lilconfig";
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
14
|
+
import { DefaultPolicyConfig } from "../esm/config.js";
|
|
15
|
+
import { createExcludedPolicyFileMap, exclusionRegex } from "../esm/context.js";
|
|
16
|
+
import { ParsedFileCache } from "../esm/fileCache.js";
|
|
17
|
+
import { identifyPolicyInstances, makePolicy } from "../esm/makePolicy.js";
|
|
18
|
+
import { newPerfStats } from "../esm/perf.js";
|
|
19
|
+
import { executionMessage, PolicyExecutor } from "../esm/policyExecution.js";
|
|
20
|
+
|
|
21
|
+
// Policy logging must not corrupt the JSON response stream.
|
|
22
|
+
globalThis.console = new Console(process.stderr);
|
|
23
|
+
const nativeStackGetter = Object.getOwnPropertyDescriptor(
|
|
24
|
+
new Error(),
|
|
25
|
+
"stack",
|
|
26
|
+
)?.get;
|
|
27
|
+
const nativePrepareStackTrace = Object.getOwnPropertyDescriptor(
|
|
28
|
+
Error,
|
|
29
|
+
"prepareStackTrace",
|
|
30
|
+
)?.value;
|
|
31
|
+
|
|
32
|
+
let registration;
|
|
33
|
+
let active;
|
|
34
|
+
let session;
|
|
35
|
+
let interrupted = false;
|
|
36
|
+
let closeInput;
|
|
37
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
38
|
+
process.on(signal, () => {
|
|
39
|
+
interrupted = true;
|
|
40
|
+
active?.abort(new Error(`Sidecar received ${signal}`));
|
|
41
|
+
closeInput?.();
|
|
42
|
+
});
|
|
50
43
|
}
|
|
51
44
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
source: regex.source,
|
|
60
|
-
flags: regex.flags,
|
|
61
|
-
};
|
|
45
|
+
async function respond(response) {
|
|
46
|
+
await new Promise((resolve, reject) => {
|
|
47
|
+
process.stdout.write(`${JSON.stringify(response)}\n`, (error) =>
|
|
48
|
+
error ? reject(error) : resolve(),
|
|
49
|
+
);
|
|
50
|
+
});
|
|
62
51
|
}
|
|
63
52
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
* Strips out functions and sends only what Rust needs for matching.
|
|
67
|
-
* @param {import("../src/policy.js").ConfiguredPolicy} policy
|
|
68
|
-
* @returns {object}
|
|
69
|
-
*/
|
|
70
|
-
function serializePolicy(policy) {
|
|
71
|
-
const match = serializeRegex(policy.match);
|
|
72
|
-
|
|
73
|
-
// Convert excludeFiles to regex pattern strings
|
|
74
|
-
const excludeFiles = (policy.excludeFiles ?? policy.exclude ?? []).map(
|
|
75
|
-
(e) => {
|
|
76
|
-
if (e instanceof RegExp) {
|
|
77
|
-
return e.source;
|
|
78
|
-
}
|
|
79
|
-
return String(e);
|
|
80
|
-
},
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
name: policy.name,
|
|
85
|
-
description: policy.description,
|
|
86
|
-
matchPattern: match.source,
|
|
87
|
-
matchFlags: match.flags,
|
|
88
|
-
hasResolver: typeof policy.resolver === "function",
|
|
89
|
-
excludeFiles,
|
|
90
|
-
};
|
|
53
|
+
function serializeRegex(regex) {
|
|
54
|
+
return { source: regex.source, flags: regex.flags };
|
|
91
55
|
}
|
|
92
56
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
* @param {unknown} value
|
|
96
|
-
* @returns {boolean}
|
|
97
|
-
*/
|
|
98
|
-
function isOperation(value) {
|
|
99
|
-
return (
|
|
100
|
-
typeof value === "object" &&
|
|
101
|
-
value !== null &&
|
|
102
|
-
"next" in value &&
|
|
103
|
-
typeof value.next === "function"
|
|
104
|
-
);
|
|
57
|
+
function serializeExclusion(pattern) {
|
|
58
|
+
return pattern instanceof RegExp ? serializeRegex(pattern) : pattern;
|
|
105
59
|
}
|
|
106
60
|
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
* @param {import("../src/policy.js").PolicyHandler} handler
|
|
110
|
-
* @param {import("../src/policy.js").PolicyArgs} args
|
|
111
|
-
* @returns {Promise<import("../src/policy.js").PolicyHandlerResult>}
|
|
112
|
-
*/
|
|
113
|
-
async function executeHandler(handler, args) {
|
|
114
|
-
const result = handler(args);
|
|
115
|
-
|
|
116
|
-
if (result instanceof Promise) {
|
|
117
|
-
return result;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (isOperation(result)) {
|
|
121
|
-
// Run the generator through Effection
|
|
122
|
-
return run(function* () {
|
|
123
|
-
return yield* result;
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Shouldn't happen, but handle it
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Handle a load_config request.
|
|
133
|
-
* @param {object} params
|
|
134
|
-
*/
|
|
135
|
-
async function handleLoadConfig(params) {
|
|
61
|
+
/** Preserve Error's non-enumerable details and safely encode non-JSON causes. */
|
|
62
|
+
function serializeCause(value, seen = new WeakSet(), depth = 0) {
|
|
136
63
|
try {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const configLoader = lilconfig("repopo", {
|
|
141
|
-
searchPlaces: [
|
|
142
|
-
"repopo.config.ts",
|
|
143
|
-
"repopo.config.mjs",
|
|
144
|
-
"repopo.config.cjs",
|
|
145
|
-
],
|
|
146
|
-
loaders: {
|
|
147
|
-
".ts": TypeScriptLoader,
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
const pathStats = await stat(searchPath);
|
|
152
|
-
const maybeConfig = pathStats.isDirectory()
|
|
153
|
-
? await configLoader.search(searchPath)
|
|
154
|
-
: await configLoader.load(searchPath);
|
|
155
|
-
|
|
156
|
-
if (maybeConfig !== null) {
|
|
157
|
-
loadedConfig = maybeConfig.config?.default ?? maybeConfig.config;
|
|
158
|
-
} else {
|
|
159
|
-
// Use default config
|
|
160
|
-
const { DefaultPolicyConfig } = await import("../esm/config.js");
|
|
161
|
-
loadedConfig = DefaultPolicyConfig;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Store git root for reuse in batch calls
|
|
165
|
-
storedGitRoot = params.gitRoot ?? process.cwd();
|
|
166
|
-
|
|
167
|
-
// Build the policy map and index array
|
|
168
|
-
policiesByName.clear();
|
|
169
|
-
policiesByIndex = [];
|
|
170
|
-
const policies =
|
|
171
|
-
loadedConfig?.policies ??
|
|
172
|
-
(await import("../esm/config.js")).DefaultPolicyConfig.policies;
|
|
173
|
-
for (const p of policies) {
|
|
174
|
-
policiesByName.set(p.name, p);
|
|
175
|
-
policiesByIndex.push(p);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Serialize for Rust
|
|
179
|
-
const serializedPolicies = policies.map(serializePolicy);
|
|
180
|
-
const excludeFiles = (loadedConfig?.excludeFiles ?? []).map((e) => {
|
|
181
|
-
if (e instanceof RegExp) {
|
|
182
|
-
return e.source;
|
|
183
|
-
}
|
|
184
|
-
return String(e);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
respond({
|
|
188
|
-
ok: true,
|
|
189
|
-
data: {
|
|
190
|
-
policies: serializedPolicies,
|
|
191
|
-
excludeFiles,
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
} catch (err) {
|
|
195
|
-
respond({
|
|
196
|
-
ok: false,
|
|
197
|
-
error: `Failed to load config: ${err.message}`,
|
|
198
|
-
});
|
|
64
|
+
return serializeValue(value, seen, depth);
|
|
65
|
+
} catch {
|
|
66
|
+
return { type: "uninspectable" };
|
|
199
67
|
}
|
|
200
68
|
}
|
|
201
69
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
async function handleRunHandler(params) {
|
|
207
|
-
try {
|
|
208
|
-
const policy = policiesByName.get(params.policyName);
|
|
209
|
-
if (!policy) {
|
|
210
|
-
respond({
|
|
211
|
-
ok: false,
|
|
212
|
-
error: `Unknown policy: ${params.policyName}`,
|
|
213
|
-
});
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const handler = policy._internalHandler ?? policy.handler;
|
|
218
|
-
const args = {
|
|
219
|
-
file: params.file,
|
|
220
|
-
root: params.root,
|
|
221
|
-
resolve: params.resolve ?? false,
|
|
222
|
-
config: policy.config,
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const result = await executeHandler(handler, args);
|
|
226
|
-
|
|
227
|
-
// Serialize the result — `true` passes through as-is,
|
|
228
|
-
// objects (PolicyError/PolicyFailure) are serialized.
|
|
229
|
-
respond({ ok: true, data: result });
|
|
230
|
-
} catch (err) {
|
|
231
|
-
respond({
|
|
232
|
-
ok: false,
|
|
233
|
-
error: `Handler error for ${params.policyName}: ${err.message}`,
|
|
234
|
-
});
|
|
70
|
+
function serializeValue(value, seen, depth) {
|
|
71
|
+
if (value === undefined) return { type: "undefined" };
|
|
72
|
+
if (typeof value === "bigint" || typeof value === "symbol") {
|
|
73
|
+
return { type: typeof value, value: String(value) };
|
|
235
74
|
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
75
|
+
if (typeof value === "function") return { type: "function" };
|
|
76
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
77
|
+
return { type: "number", value: String(value) };
|
|
78
|
+
}
|
|
79
|
+
if (value === null || typeof value !== "object") return value;
|
|
80
|
+
// Proxy traps are arbitrary code, including during descriptor inspection.
|
|
81
|
+
if (types.isProxy(value)) return { type: "proxy" };
|
|
82
|
+
if (seen.has(value)) return { type: "circular" };
|
|
83
|
+
if (depth >= 20) return { type: "truncated" };
|
|
84
|
+
seen.add(value);
|
|
245
85
|
try {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
86
|
+
if (Array.isArray(value)) {
|
|
87
|
+
const length = Object.getOwnPropertyDescriptor(value, "length").value;
|
|
88
|
+
const array = Array.from(
|
|
89
|
+
{ length: Math.min(length, 10000) },
|
|
90
|
+
(_, index) => {
|
|
91
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
92
|
+
value,
|
|
93
|
+
String(index),
|
|
94
|
+
);
|
|
95
|
+
return descriptor && "value" in descriptor
|
|
96
|
+
? serializeCause(descriptor.value, seen, depth + 1)
|
|
97
|
+
: { type: descriptor ? "accessor" : "hole" };
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
if (length > array.length) array.push({ type: "truncated" });
|
|
101
|
+
return array;
|
|
253
102
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
pass.push(file);
|
|
273
|
-
} else {
|
|
274
|
-
fail.push({
|
|
275
|
-
file,
|
|
276
|
-
error: result.error,
|
|
277
|
-
errorMessages: result.errorMessages,
|
|
278
|
-
fixable: result.fixable ?? result.autoFixable,
|
|
279
|
-
fixed: result.fixed ?? result.resolved,
|
|
280
|
-
manualFix: result.manualFix,
|
|
281
|
-
});
|
|
103
|
+
const entries = [];
|
|
104
|
+
if (types.isNativeError(value)) {
|
|
105
|
+
for (const key of ["name", "message"]) {
|
|
106
|
+
let current = value;
|
|
107
|
+
let found = false;
|
|
108
|
+
while (current && !types.isProxy(current)) {
|
|
109
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, key);
|
|
110
|
+
if (descriptor) {
|
|
111
|
+
found = true;
|
|
112
|
+
entries.push([
|
|
113
|
+
key,
|
|
114
|
+
"value" in descriptor
|
|
115
|
+
? serializeCause(descriptor.value, seen, depth + 1)
|
|
116
|
+
: { type: "accessor" },
|
|
117
|
+
]);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
current = Object.getPrototypeOf(current);
|
|
282
121
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
122
|
+
if (!found && current) entries.push([key, { type: "proxy" }]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
for (const key of Object.getOwnPropertyNames(value)) {
|
|
126
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
127
|
+
// V8 lazily exposes native Error stacks via a native accessor.
|
|
128
|
+
// Never call a user getter or Error.prepareStackTrace hook.
|
|
129
|
+
if (key === "stack" && types.isNativeError(value) && descriptor?.get) {
|
|
130
|
+
const prepare = Object.getOwnPropertyDescriptor(
|
|
131
|
+
Error,
|
|
132
|
+
"prepareStackTrace",
|
|
133
|
+
);
|
|
134
|
+
const plain = ["name", "message"].every((field) => {
|
|
135
|
+
const entry = entries.find(([name]) => name === field)?.[1];
|
|
136
|
+
return entry === undefined || typeof entry === "string";
|
|
288
137
|
});
|
|
138
|
+
if (
|
|
139
|
+
descriptor.get === nativeStackGetter &&
|
|
140
|
+
(!prepare ||
|
|
141
|
+
("value" in prepare &&
|
|
142
|
+
prepare.value === nativePrepareStackTrace)) &&
|
|
143
|
+
plain
|
|
144
|
+
) {
|
|
145
|
+
const stack = descriptor.get.call(value);
|
|
146
|
+
entries.push([
|
|
147
|
+
key,
|
|
148
|
+
typeof stack === "string" ? stack : { type: "uninspectable" },
|
|
149
|
+
]);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
289
152
|
}
|
|
153
|
+
entries.push([
|
|
154
|
+
key,
|
|
155
|
+
descriptor && "value" in descriptor
|
|
156
|
+
? serializeCause(descriptor.value, seen, depth + 1)
|
|
157
|
+
: { type: "accessor" },
|
|
158
|
+
]);
|
|
290
159
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
respond({
|
|
295
|
-
ok: false,
|
|
296
|
-
error: `Batch handler error for policy index ${params.policyId}: ${err.message}`,
|
|
297
|
-
});
|
|
160
|
+
return Object.fromEntries(entries);
|
|
161
|
+
} finally {
|
|
162
|
+
seen.delete(value);
|
|
298
163
|
}
|
|
299
164
|
}
|
|
300
165
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
166
|
+
function serializeRun(result) {
|
|
167
|
+
return {
|
|
168
|
+
...result,
|
|
169
|
+
errors: result.errors.map((error) => ({
|
|
170
|
+
...error,
|
|
171
|
+
cause: serializeCause(error.cause),
|
|
172
|
+
})),
|
|
173
|
+
perfStats: {
|
|
174
|
+
...result.perfStats,
|
|
175
|
+
data: Object.fromEntries(
|
|
176
|
+
[...result.perfStats.data].map(([action, timings]) => [
|
|
177
|
+
action,
|
|
178
|
+
Object.fromEntries(timings),
|
|
179
|
+
]),
|
|
180
|
+
),
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
}
|
|
315
184
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
185
|
+
async function loadConfig(params) {
|
|
186
|
+
registration = undefined;
|
|
187
|
+
session?.cache?.clear();
|
|
188
|
+
session = undefined;
|
|
189
|
+
const searchPath = params.configPath ?? process.cwd();
|
|
190
|
+
const loader = lilconfig("repopo", {
|
|
191
|
+
searchPlaces: [
|
|
192
|
+
"repopo.config.ts",
|
|
193
|
+
"repopo.config.mjs",
|
|
194
|
+
"repopo.config.cjs",
|
|
195
|
+
],
|
|
196
|
+
loaders: { ".ts": TypeScriptLoader },
|
|
197
|
+
});
|
|
198
|
+
const pathStats = await stat(searchPath);
|
|
199
|
+
const loaded = pathStats.isDirectory()
|
|
200
|
+
? await loader.search(searchPath)
|
|
201
|
+
: await loader.load(searchPath);
|
|
202
|
+
const config =
|
|
203
|
+
loaded?.config?.default ?? loaded?.config ?? DefaultPolicyConfig;
|
|
204
|
+
const policies = identifyPolicyInstances(
|
|
205
|
+
(config.policies ?? DefaultPolicyConfig.policies).map((policy) => {
|
|
206
|
+
if ("excludeFiles" in policy) {
|
|
207
|
+
throw new TypeError(
|
|
208
|
+
"Per-instance excludeFiles is retired; use exclude.",
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return makePolicy(policy, {
|
|
212
|
+
config: policy.config,
|
|
213
|
+
exclude: policy.exclude,
|
|
214
|
+
instanceId: policy.instanceId,
|
|
320
215
|
});
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
216
|
+
}),
|
|
217
|
+
);
|
|
218
|
+
const options = {
|
|
219
|
+
policies,
|
|
220
|
+
root: params.gitRoot ?? process.cwd(),
|
|
221
|
+
exclude: config.excludeFiles ?? [],
|
|
222
|
+
};
|
|
223
|
+
options.exclude.forEach(exclusionRegex);
|
|
224
|
+
createExcludedPolicyFileMap(policies);
|
|
225
|
+
const metadata = {
|
|
226
|
+
policies: policies.map((policy) => ({
|
|
227
|
+
name: policy.name,
|
|
228
|
+
instanceId: policy.instanceId,
|
|
229
|
+
description: policy.description,
|
|
230
|
+
scope: policy.scope ?? "file",
|
|
231
|
+
...(policy.scope === "repository"
|
|
232
|
+
? {}
|
|
233
|
+
: { match: serializeRegex(policy.match) }),
|
|
234
|
+
hasResolver: typeof policy.resolver === "function",
|
|
235
|
+
exclude: (policy.exclude ?? []).map(serializeExclusion),
|
|
236
|
+
})),
|
|
237
|
+
excludeFiles: options.exclude.map(serializeExclusion),
|
|
238
|
+
};
|
|
239
|
+
registration = options;
|
|
240
|
+
return metadata;
|
|
241
|
+
}
|
|
329
242
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
243
|
+
function beginRun(params) {
|
|
244
|
+
if (!registration)
|
|
245
|
+
throw new Error("Load configuration before running policies.");
|
|
246
|
+
session?.cache?.clear();
|
|
247
|
+
session = {
|
|
248
|
+
executor: new PolicyExecutor(registration.root, params.fix ?? false),
|
|
249
|
+
cache: params.fix ? undefined : new ParsedFileCache(),
|
|
250
|
+
};
|
|
251
|
+
return {};
|
|
338
252
|
}
|
|
339
253
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
254
|
+
async function executeUnits(params) {
|
|
255
|
+
if (!registration || !session)
|
|
256
|
+
throw new Error(
|
|
257
|
+
"Load configuration and begin a run before executing units.",
|
|
258
|
+
);
|
|
259
|
+
active = new AbortController();
|
|
260
|
+
const task = run(function* () {
|
|
261
|
+
return yield* all(
|
|
262
|
+
params.units.map((unit) =>
|
|
263
|
+
(function* () {
|
|
264
|
+
const policy = registration.policies.find(
|
|
265
|
+
(entry) => entry.instanceId === unit.policyId,
|
|
266
|
+
);
|
|
267
|
+
if (!policy)
|
|
268
|
+
throw new Error(`Unknown policy instance: ${unit.policyId}`);
|
|
269
|
+
const result = {
|
|
270
|
+
findings: [],
|
|
271
|
+
errors: [],
|
|
272
|
+
skipped: [],
|
|
273
|
+
perfStats: newPerfStats(),
|
|
274
|
+
};
|
|
275
|
+
if (policy.scope === "repository") {
|
|
276
|
+
if (!Array.isArray(unit.files))
|
|
277
|
+
throw new Error("Repository units require explicit inventory.");
|
|
278
|
+
yield* session.executor.repository(policy, unit.files, result);
|
|
279
|
+
} else {
|
|
280
|
+
if (typeof unit.file !== "string")
|
|
281
|
+
throw new Error("File units require a file.");
|
|
282
|
+
yield* session.executor.file(
|
|
283
|
+
unit.file,
|
|
284
|
+
policy,
|
|
285
|
+
result,
|
|
286
|
+
session.cache,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
return serializeRun(result);
|
|
290
|
+
})(),
|
|
291
|
+
),
|
|
292
|
+
);
|
|
293
|
+
});
|
|
294
|
+
const abort = () => {
|
|
295
|
+
task.halt().catch(() => undefined);
|
|
296
|
+
};
|
|
297
|
+
active.signal.addEventListener("abort", abort, { once: true });
|
|
347
298
|
try {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if (typeof policy.resolver !== "function") {
|
|
358
|
-
respond({
|
|
359
|
-
ok: false,
|
|
360
|
-
error: `Policy index ${params.policyId} has no resolver`,
|
|
361
|
-
});
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
299
|
+
return await task;
|
|
300
|
+
} finally {
|
|
301
|
+
active.signal.removeEventListener("abort", abort);
|
|
302
|
+
active = undefined;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
364
305
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
306
|
+
function matchFiles(params) {
|
|
307
|
+
const regex =
|
|
308
|
+
typeof params.pattern === "string"
|
|
309
|
+
? exclusionRegex(params.pattern)
|
|
310
|
+
: new RegExp(params.pattern.source, params.pattern.flags);
|
|
311
|
+
return params.files.map((file) => {
|
|
312
|
+
regex.lastIndex = 0;
|
|
313
|
+
return regex.test(file);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
369
316
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
fixed: result.fixed ?? result.resolved,
|
|
387
|
-
manualFix: result.manualFix,
|
|
388
|
-
});
|
|
317
|
+
async function main() {
|
|
318
|
+
const rl = createInterface({ input: process.stdin, terminal: false });
|
|
319
|
+
closeInput = () => rl.close();
|
|
320
|
+
let closing = false;
|
|
321
|
+
let shutdownRequested = false;
|
|
322
|
+
let pendingWork = 0;
|
|
323
|
+
rl.on("line", (line) => {
|
|
324
|
+
try {
|
|
325
|
+
const { method } = JSON.parse(line);
|
|
326
|
+
if (method === "execute_units") pendingWork++;
|
|
327
|
+
if (method === "shutdown") {
|
|
328
|
+
closing = true;
|
|
329
|
+
shutdownRequested = true;
|
|
330
|
+
if (active || pendingWork > 0) {
|
|
331
|
+
interrupted = true;
|
|
332
|
+
active?.abort(new Error("Native parent requested shutdown"));
|
|
389
333
|
}
|
|
390
|
-
} catch (err) {
|
|
391
|
-
fail.push({
|
|
392
|
-
file,
|
|
393
|
-
error: `Resolver error: ${err.message}`,
|
|
394
|
-
fixable: false,
|
|
395
|
-
fixed: false,
|
|
396
|
-
});
|
|
397
334
|
}
|
|
335
|
+
} catch {
|
|
336
|
+
// The request loop reports malformed JSON.
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
// A dead native parent closes the pipe. Halt owned operations before exit.
|
|
340
|
+
rl.on("close", () => {
|
|
341
|
+
if (!closing) {
|
|
342
|
+
interrupted = true;
|
|
343
|
+
active?.abort(new Error("Native parent closed the request stream"));
|
|
398
344
|
}
|
|
399
|
-
|
|
400
|
-
respond({ ok: true, data: { pass, fail } });
|
|
401
|
-
} catch (err) {
|
|
402
|
-
respond({
|
|
403
|
-
ok: false,
|
|
404
|
-
error: `Batch resolver error for policy index ${params.policyId}: ${err.message}`,
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Main loop: read JSON requests from stdin, dispatch, respond on stdout.
|
|
411
|
-
*/
|
|
412
|
-
async function main() {
|
|
413
|
-
const rl = createInterface({
|
|
414
|
-
input: process.stdin,
|
|
415
|
-
terminal: false,
|
|
416
345
|
});
|
|
417
|
-
|
|
418
346
|
for await (const line of rl) {
|
|
347
|
+
if (interrupted || shutdownRequested) break;
|
|
419
348
|
if (!line.trim()) continue;
|
|
420
|
-
|
|
421
|
-
let request;
|
|
422
349
|
try {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
const { method, params } = request;
|
|
430
|
-
|
|
431
|
-
switch (method) {
|
|
432
|
-
case "load_config":
|
|
433
|
-
await handleLoadConfig(params ?? {});
|
|
434
|
-
break;
|
|
435
|
-
|
|
436
|
-
case "run_handler":
|
|
437
|
-
await handleRunHandler(params ?? {});
|
|
438
|
-
break;
|
|
439
|
-
|
|
440
|
-
case "run_resolver":
|
|
441
|
-
await handleRunResolver(params ?? {});
|
|
442
|
-
break;
|
|
443
|
-
|
|
444
|
-
case "run_handler_batch":
|
|
445
|
-
await handleRunHandlerBatch(params ?? {});
|
|
446
|
-
break;
|
|
447
|
-
|
|
448
|
-
case "run_resolver_batch":
|
|
449
|
-
await handleRunResolverBatch(params ?? {});
|
|
450
|
-
break;
|
|
451
|
-
|
|
452
|
-
case "shutdown":
|
|
453
|
-
process.exit(0);
|
|
350
|
+
const { method, params = {} } = JSON.parse(line);
|
|
351
|
+
if (method === "shutdown") {
|
|
352
|
+
closing = true;
|
|
454
353
|
break;
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
354
|
+
}
|
|
355
|
+
let data;
|
|
356
|
+
switch (method) {
|
|
357
|
+
case "load_config":
|
|
358
|
+
data = await loadConfig(params);
|
|
359
|
+
break;
|
|
360
|
+
case "begin_run":
|
|
361
|
+
data = beginRun(params);
|
|
362
|
+
break;
|
|
363
|
+
case "execute_units":
|
|
364
|
+
try {
|
|
365
|
+
data = await executeUnits(params);
|
|
366
|
+
} finally {
|
|
367
|
+
pendingWork--;
|
|
368
|
+
}
|
|
369
|
+
break;
|
|
370
|
+
case "match_files":
|
|
371
|
+
if (!registration)
|
|
372
|
+
throw new Error("Load configuration before matching.");
|
|
373
|
+
data = matchFiles(params);
|
|
374
|
+
break;
|
|
375
|
+
default:
|
|
376
|
+
throw new Error(`Unknown method: ${method}`);
|
|
377
|
+
}
|
|
378
|
+
if (interrupted) break;
|
|
379
|
+
await respond({ ok: true, data });
|
|
380
|
+
} catch (error) {
|
|
381
|
+
if (interrupted) break;
|
|
382
|
+
await respond({
|
|
383
|
+
ok: false,
|
|
384
|
+
error: executionMessage(error),
|
|
385
|
+
cause: serializeCause(error),
|
|
386
|
+
});
|
|
458
387
|
}
|
|
388
|
+
if (interrupted) break;
|
|
459
389
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
390
|
+
closing = true;
|
|
391
|
+
session?.cache?.clear();
|
|
392
|
+
rl.close();
|
|
393
|
+
process.exit(interrupted ? 130 : 0);
|
|
463
394
|
}
|
|
464
395
|
|
|
465
|
-
main().catch((
|
|
466
|
-
process.stderr.write(`Sidecar fatal error: ${
|
|
396
|
+
main().catch((error) => {
|
|
397
|
+
process.stderr.write(`Sidecar fatal error: ${error.message}\n`);
|
|
467
398
|
process.exit(1);
|
|
468
399
|
});
|