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.
Files changed (333) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +50 -90
  3. package/THIRD-PARTY-LICENSES.txt +169 -11
  4. package/bin/dev.js +0 -0
  5. package/esm/adapters/fluidFramework.d.ts +13 -9
  6. package/esm/adapters/fluidFramework.d.ts.map +1 -1
  7. package/esm/adapters/fluidFramework.js +20 -43
  8. package/esm/adapters/fluidFramework.js.map +1 -1
  9. package/esm/api.d.ts +64 -1
  10. package/esm/api.d.ts.map +1 -1
  11. package/esm/api.js +17 -1
  12. package/esm/api.js.map +1 -1
  13. package/esm/baseCommand.d.ts.map +1 -1
  14. package/esm/baseCommand.js +2 -2
  15. package/esm/baseCommand.js.map +1 -1
  16. package/esm/commands/check-native.d.ts +3 -3
  17. package/esm/commands/check-native.d.ts.map +1 -1
  18. package/esm/commands/check-native.js +26 -7
  19. package/esm/commands/check-native.js.map +1 -1
  20. package/esm/commands/check.d.ts +6 -21
  21. package/esm/commands/check.d.ts.map +1 -1
  22. package/esm/commands/check.js +73 -153
  23. package/esm/commands/check.js.map +1 -1
  24. package/esm/commands/list.d.ts.map +1 -1
  25. package/esm/commands/list.js +2 -1
  26. package/esm/commands/list.js.map +1 -1
  27. package/esm/concurrency.d.ts +3 -0
  28. package/esm/concurrency.d.ts.map +1 -0
  29. package/esm/concurrency.js +8 -0
  30. package/esm/concurrency.js.map +1 -0
  31. package/esm/config.d.ts +5 -39
  32. package/esm/config.d.ts.map +1 -1
  33. package/esm/config.js +3 -7
  34. package/esm/config.js.map +1 -1
  35. package/esm/context.d.ts +8 -1
  36. package/esm/context.d.ts.map +1 -1
  37. package/esm/context.js +8 -1
  38. package/esm/context.js.map +1 -1
  39. package/esm/executionContractError.d.ts +4 -0
  40. package/esm/executionContractError.d.ts.map +1 -0
  41. package/esm/executionContractError.js +4 -0
  42. package/esm/executionContractError.js.map +1 -0
  43. package/esm/fileCache.d.ts +12 -0
  44. package/esm/fileCache.d.ts.map +1 -0
  45. package/esm/fileCache.js +37 -0
  46. package/esm/fileCache.js.map +1 -0
  47. package/esm/filePaths.d.ts +2 -0
  48. package/esm/filePaths.d.ts.map +1 -0
  49. package/esm/filePaths.js +9 -0
  50. package/esm/filePaths.js.map +1 -0
  51. package/esm/generators.d.ts +0 -20
  52. package/esm/generators.d.ts.map +1 -1
  53. package/esm/generators.js.map +1 -1
  54. package/esm/index.d.ts +3 -16
  55. package/esm/index.d.ts.map +1 -1
  56. package/esm/index.js +3 -17
  57. package/esm/index.js.map +1 -1
  58. package/esm/makePolicy.d.ts +20 -100
  59. package/esm/makePolicy.d.ts.map +1 -1
  60. package/esm/makePolicy.js +44 -132
  61. package/esm/makePolicy.js.map +1 -1
  62. package/esm/perf.d.ts +5 -2
  63. package/esm/perf.d.ts.map +1 -1
  64. package/esm/perf.js +10 -9
  65. package/esm/perf.js.map +1 -1
  66. package/esm/policies/CargoLicenceValidated.d.ts +4 -4
  67. package/esm/policies/CargoLicenceValidated.d.ts.map +1 -1
  68. package/esm/policies/CargoLicenceValidated.js +9 -7
  69. package/esm/policies/CargoLicenceValidated.js.map +1 -1
  70. package/esm/policies/CargoLintsConfigured.d.ts +4 -4
  71. package/esm/policies/CargoLintsConfigured.d.ts.map +1 -1
  72. package/esm/policies/CargoLintsConfigured.js +19 -15
  73. package/esm/policies/CargoLintsConfigured.js.map +1 -1
  74. package/esm/policies/CargoLockPolicy.d.ts +4 -4
  75. package/esm/policies/CargoLockPolicy.d.ts.map +1 -1
  76. package/esm/policies/CargoLockPolicy.js +15 -11
  77. package/esm/policies/CargoLockPolicy.js.map +1 -1
  78. package/esm/policies/CargoTomlRequired.d.ts +5 -5
  79. package/esm/policies/CargoTomlRequired.d.ts.map +1 -1
  80. package/esm/policies/CargoTomlRequired.js +7 -7
  81. package/esm/policies/CargoTomlRequired.js.map +1 -1
  82. package/esm/policies/CargoTomlSorted.d.ts +4 -4
  83. package/esm/policies/CargoTomlSorted.d.ts.map +1 -1
  84. package/esm/policies/CargoTomlSorted.js +21 -17
  85. package/esm/policies/CargoTomlSorted.js.map +1 -1
  86. package/esm/policies/ConditionalScripts.d.ts +10 -8
  87. package/esm/policies/ConditionalScripts.d.ts.map +1 -1
  88. package/esm/policies/ConditionalScripts.js +24 -22
  89. package/esm/policies/ConditionalScripts.js.map +1 -1
  90. package/esm/policies/ExactScripts.d.ts +8 -6
  91. package/esm/policies/ExactScripts.d.ts.map +1 -1
  92. package/esm/policies/ExactScripts.js +15 -18
  93. package/esm/policies/ExactScripts.js.map +1 -1
  94. package/esm/policies/GleamDepVersions.d.ts +5 -5
  95. package/esm/policies/GleamDepVersions.d.ts.map +1 -1
  96. package/esm/policies/GleamDepVersions.js +5 -5
  97. package/esm/policies/GleamDepVersions.js.map +1 -1
  98. package/esm/policies/GleamDocExists.d.ts +4 -4
  99. package/esm/policies/GleamDocExists.d.ts.map +1 -1
  100. package/esm/policies/GleamDocExists.js +6 -6
  101. package/esm/policies/GleamDocExists.js.map +1 -1
  102. package/esm/policies/GleamInternalModulesConfigured.d.ts +4 -4
  103. package/esm/policies/GleamInternalModulesConfigured.d.ts.map +1 -1
  104. package/esm/policies/GleamInternalModulesConfigured.js +8 -6
  105. package/esm/policies/GleamInternalModulesConfigured.js.map +1 -1
  106. package/esm/policies/GleamLicenceConfigured.d.ts +4 -4
  107. package/esm/policies/GleamLicenceConfigured.d.ts.map +1 -1
  108. package/esm/policies/GleamLicenceConfigured.js +8 -6
  109. package/esm/policies/GleamLicenceConfigured.js.map +1 -1
  110. package/esm/policies/GleamManifestCommitted.d.ts +10 -3
  111. package/esm/policies/GleamManifestCommitted.d.ts.map +1 -1
  112. package/esm/policies/GleamManifestCommitted.js +10 -9
  113. package/esm/policies/GleamManifestCommitted.js.map +1 -1
  114. package/esm/policies/GleamMonorepoConsistency.d.ts +13 -5
  115. package/esm/policies/GleamMonorepoConsistency.d.ts.map +1 -1
  116. package/esm/policies/GleamMonorepoConsistency.js +10 -10
  117. package/esm/policies/GleamMonorepoConsistency.js.map +1 -1
  118. package/esm/policies/GleamNameRestrictions.d.ts +4 -4
  119. package/esm/policies/GleamNameRestrictions.d.ts.map +1 -1
  120. package/esm/policies/GleamNameRestrictions.js +6 -6
  121. package/esm/policies/GleamNameRestrictions.js.map +1 -1
  122. package/esm/policies/GleamNoPathDepsInPublished.d.ts +4 -4
  123. package/esm/policies/GleamNoPathDepsInPublished.d.ts.map +1 -1
  124. package/esm/policies/GleamNoPathDepsInPublished.js +6 -6
  125. package/esm/policies/GleamNoPathDepsInPublished.js.map +1 -1
  126. package/esm/policies/GleamPathDepsValid.d.ts +3 -3
  127. package/esm/policies/GleamPathDepsValid.d.ts.map +1 -1
  128. package/esm/policies/GleamPathDepsValid.js +5 -5
  129. package/esm/policies/GleamPathDepsValid.js.map +1 -1
  130. package/esm/policies/GleamProjectStructure.d.ts +11 -4
  131. package/esm/policies/GleamProjectStructure.d.ts.map +1 -1
  132. package/esm/policies/GleamProjectStructure.js +7 -8
  133. package/esm/policies/GleamProjectStructure.js.map +1 -1
  134. package/esm/policies/GleamSharedDependencyVersions.d.ts +12 -4
  135. package/esm/policies/GleamSharedDependencyVersions.d.ts.map +1 -1
  136. package/esm/policies/GleamSharedDependencyVersions.js +10 -10
  137. package/esm/policies/GleamSharedDependencyVersions.js.map +1 -1
  138. package/esm/policies/GleamTomlRequired.d.ts +4 -4
  139. package/esm/policies/GleamTomlRequired.d.ts.map +1 -1
  140. package/esm/policies/GleamTomlRequired.js +5 -5
  141. package/esm/policies/GleamTomlRequired.js.map +1 -1
  142. package/esm/policies/GleamTomlSorted.d.ts +4 -4
  143. package/esm/policies/GleamTomlSorted.d.ts.map +1 -1
  144. package/esm/policies/GleamTomlSorted.js +21 -17
  145. package/esm/policies/GleamTomlSorted.js.map +1 -1
  146. package/esm/policies/GleamVersionConstraint.d.ts +4 -4
  147. package/esm/policies/GleamVersionConstraint.d.ts.map +1 -1
  148. package/esm/policies/GleamVersionConstraint.js +14 -10
  149. package/esm/policies/GleamVersionConstraint.js.map +1 -1
  150. package/esm/policies/HtmlFileHeaders.d.ts +4 -2
  151. package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
  152. package/esm/policies/HtmlFileHeaders.js +1 -1
  153. package/esm/policies/HtmlFileHeaders.js.map +1 -1
  154. package/esm/policies/JsTsFileHeaders.d.ts +4 -2
  155. package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
  156. package/esm/policies/JsTsFileHeaders.js +1 -1
  157. package/esm/policies/JsTsFileHeaders.js.map +1 -1
  158. package/esm/policies/LicenseFileExists.d.ts +10 -4
  159. package/esm/policies/LicenseFileExists.d.ts.map +1 -1
  160. package/esm/policies/LicenseFileExists.js +27 -20
  161. package/esm/policies/LicenseFileExists.js.map +1 -1
  162. package/esm/policies/MutuallyExclusiveScripts.d.ts +8 -6
  163. package/esm/policies/MutuallyExclusiveScripts.d.ts.map +1 -1
  164. package/esm/policies/MutuallyExclusiveScripts.js +9 -13
  165. package/esm/policies/MutuallyExclusiveScripts.js.map +1 -1
  166. package/esm/policies/NoBuildDirectory.d.ts +9 -3
  167. package/esm/policies/NoBuildDirectory.d.ts.map +1 -1
  168. package/esm/policies/NoBuildDirectory.js +8 -13
  169. package/esm/policies/NoBuildDirectory.js.map +1 -1
  170. package/esm/policies/NoJsFileExtensions.d.ts +9 -3
  171. package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
  172. package/esm/policies/NoJsFileExtensions.js +9 -14
  173. package/esm/policies/NoJsFileExtensions.js.map +1 -1
  174. package/esm/policies/NoLargeBinaryFiles.d.ts +9 -4
  175. package/esm/policies/NoLargeBinaryFiles.d.ts.map +1 -1
  176. package/esm/policies/NoLargeBinaryFiles.js +10 -16
  177. package/esm/policies/NoLargeBinaryFiles.js.map +1 -1
  178. package/esm/policies/NoPrivateWorkspaceDependencies.d.ts +10 -6
  179. package/esm/policies/NoPrivateWorkspaceDependencies.d.ts.map +1 -1
  180. package/esm/policies/NoPrivateWorkspaceDependencies.js +12 -14
  181. package/esm/policies/NoPrivateWorkspaceDependencies.js.map +1 -1
  182. package/esm/policies/NoTargetArtifacts.d.ts +9 -3
  183. package/esm/policies/NoTargetArtifacts.d.ts.map +1 -1
  184. package/esm/policies/NoTargetArtifacts.js +9 -14
  185. package/esm/policies/NoTargetArtifacts.js.map +1 -1
  186. package/esm/policies/NoUnsafeWithoutJustification.d.ts +11 -4
  187. package/esm/policies/NoUnsafeWithoutJustification.d.ts.map +1 -1
  188. package/esm/policies/NoUnsafeWithoutJustification.js +8 -9
  189. package/esm/policies/NoUnsafeWithoutJustification.js.map +1 -1
  190. package/esm/policies/NoWildcardDependencies.d.ts +5 -5
  191. package/esm/policies/NoWildcardDependencies.d.ts.map +1 -1
  192. package/esm/policies/NoWildcardDependencies.js +6 -6
  193. package/esm/policies/NoWildcardDependencies.js.map +1 -1
  194. package/esm/policies/PackageAllowedScopes.d.ts +9 -5
  195. package/esm/policies/PackageAllowedScopes.d.ts.map +1 -1
  196. package/esm/policies/PackageAllowedScopes.js +15 -16
  197. package/esm/policies/PackageAllowedScopes.js.map +1 -1
  198. package/esm/policies/PackageEsmType.d.ts +7 -5
  199. package/esm/policies/PackageEsmType.d.ts.map +1 -1
  200. package/esm/policies/PackageEsmType.js +31 -31
  201. package/esm/policies/PackageEsmType.js.map +1 -1
  202. package/esm/policies/PackageFolderName.d.ts +8 -6
  203. package/esm/policies/PackageFolderName.d.ts.map +1 -1
  204. package/esm/policies/PackageFolderName.js +13 -16
  205. package/esm/policies/PackageFolderName.js.map +1 -1
  206. package/esm/policies/PackageJsonProperties.d.ts +5 -3
  207. package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
  208. package/esm/policies/PackageJsonProperties.js +6 -17
  209. package/esm/policies/PackageJsonProperties.js.map +1 -1
  210. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +2 -7
  211. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
  212. package/esm/policies/PackageJsonRepoDirectoryProperty.js +28 -42
  213. package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
  214. package/esm/policies/PackageJsonSorted.d.ts +2 -2
  215. package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
  216. package/esm/policies/PackageJsonSorted.js +15 -30
  217. package/esm/policies/PackageJsonSorted.js.map +1 -1
  218. package/esm/policies/PackageLicense.d.ts +4 -4
  219. package/esm/policies/PackageLicense.d.ts.map +1 -1
  220. package/esm/policies/PackageLicense.js +31 -52
  221. package/esm/policies/PackageLicense.js.map +1 -1
  222. package/esm/policies/PackagePrivateField.d.ts +12 -8
  223. package/esm/policies/PackagePrivateField.d.ts.map +1 -1
  224. package/esm/policies/PackagePrivateField.js +31 -23
  225. package/esm/policies/PackagePrivateField.js.map +1 -1
  226. package/esm/policies/PackageReadme.d.ts +6 -5
  227. package/esm/policies/PackageReadme.d.ts.map +1 -1
  228. package/esm/policies/PackageReadme.js +22 -59
  229. package/esm/policies/PackageReadme.js.map +1 -1
  230. package/esm/policies/PackageScripts.d.ts +26 -22
  231. package/esm/policies/PackageScripts.d.ts.map +1 -1
  232. package/esm/policies/PackageScripts.js +39 -36
  233. package/esm/policies/PackageScripts.js.map +1 -1
  234. package/esm/policies/PackageTestScripts.d.ts +10 -6
  235. package/esm/policies/PackageTestScripts.d.ts.map +1 -1
  236. package/esm/policies/PackageTestScripts.js +14 -16
  237. package/esm/policies/PackageTestScripts.js.map +1 -1
  238. package/esm/policies/PublicApiDocumented.d.ts +4 -4
  239. package/esm/policies/PublicApiDocumented.d.ts.map +1 -1
  240. package/esm/policies/PublicApiDocumented.js +10 -8
  241. package/esm/policies/PublicApiDocumented.js.map +1 -1
  242. package/esm/policies/RequiredGitignorePatterns.d.ts +11 -4
  243. package/esm/policies/RequiredGitignorePatterns.d.ts.map +1 -1
  244. package/esm/policies/RequiredGitignorePatterns.js +29 -36
  245. package/esm/policies/RequiredGitignorePatterns.js.map +1 -1
  246. package/esm/policies/RequiredScripts.d.ts +9 -7
  247. package/esm/policies/RequiredScripts.d.ts.map +1 -1
  248. package/esm/policies/RequiredScripts.js +24 -24
  249. package/esm/policies/RequiredScripts.js.map +1 -1
  250. package/esm/policies/RustDocExists.d.ts +4 -4
  251. package/esm/policies/RustDocExists.d.ts.map +1 -1
  252. package/esm/policies/RustDocExists.js +6 -6
  253. package/esm/policies/RustDocExists.js.map +1 -1
  254. package/esm/policies/RustToolchainExists.d.ts +11 -4
  255. package/esm/policies/RustToolchainExists.d.ts.map +1 -1
  256. package/esm/policies/RustToolchainExists.js +10 -9
  257. package/esm/policies/RustToolchainExists.js.map +1 -1
  258. package/esm/policies/RustfmtConfigExists.d.ts +11 -4
  259. package/esm/policies/RustfmtConfigExists.d.ts.map +1 -1
  260. package/esm/policies/RustfmtConfigExists.js +10 -9
  261. package/esm/policies/RustfmtConfigExists.js.map +1 -1
  262. package/esm/policies/ScriptContains.d.ts +9 -7
  263. package/esm/policies/ScriptContains.d.ts.map +1 -1
  264. package/esm/policies/ScriptContains.js +9 -13
  265. package/esm/policies/ScriptContains.js.map +1 -1
  266. package/esm/policies/SharedDependencyVersions.d.ts +9 -4
  267. package/esm/policies/SharedDependencyVersions.d.ts.map +1 -1
  268. package/esm/policies/SharedDependencyVersions.js +28 -20
  269. package/esm/policies/SharedDependencyVersions.js.map +1 -1
  270. package/esm/policies/WorkspaceInheritance.d.ts +11 -4
  271. package/esm/policies/WorkspaceInheritance.d.ts.map +1 -1
  272. package/esm/policies/WorkspaceInheritance.js +10 -11
  273. package/esm/policies/WorkspaceInheritance.js.map +1 -1
  274. package/esm/policies/WorkspaceMembersValid.d.ts +11 -4
  275. package/esm/policies/WorkspaceMembersValid.d.ts.map +1 -1
  276. package/esm/policies/WorkspaceMembersValid.js +10 -11
  277. package/esm/policies/WorkspaceMembersValid.js.map +1 -1
  278. package/esm/policies/constants.d.ts.map +1 -1
  279. package/esm/policies/constants.js +1 -1
  280. package/esm/policies/constants.js.map +1 -1
  281. package/esm/policies.d.ts +13 -5
  282. package/esm/policies.d.ts.map +1 -1
  283. package/esm/policies.js +12 -5
  284. package/esm/policies.js.map +1 -1
  285. package/esm/policy.d.ts +61 -289
  286. package/esm/policy.d.ts.map +1 -1
  287. package/esm/policy.js +1 -122
  288. package/esm/policy.js.map +1 -1
  289. package/esm/policyDefiners/defineCargoPolicy.d.ts +25 -9
  290. package/esm/policyDefiners/defineCargoPolicy.d.ts.map +1 -1
  291. package/esm/policyDefiners/defineCargoPolicy.js +10 -28
  292. package/esm/policyDefiners/defineCargoPolicy.js.map +1 -1
  293. package/esm/policyDefiners/defineFileHeaderPolicy.d.ts +27 -14
  294. package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -1
  295. package/esm/policyDefiners/defineFileHeaderPolicy.js +16 -35
  296. package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -1
  297. package/esm/policyDefiners/defineGleamPolicy.d.ts +25 -9
  298. package/esm/policyDefiners/defineGleamPolicy.d.ts.map +1 -1
  299. package/esm/policyDefiners/defineGleamPolicy.js +10 -27
  300. package/esm/policyDefiners/defineGleamPolicy.js.map +1 -1
  301. package/esm/policyDefiners/definePackagePolicy.d.ts +24 -13
  302. package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -1
  303. package/esm/policyDefiners/definePackagePolicy.js +9 -32
  304. package/esm/policyDefiners/definePackagePolicy.js.map +1 -1
  305. package/esm/policyDefiners/spdxValidator.d.ts +4 -12
  306. package/esm/policyDefiners/spdxValidator.d.ts.map +1 -1
  307. package/esm/policyDefiners/spdxValidator.js +26 -14
  308. package/esm/policyDefiners/spdxValidator.js.map +1 -1
  309. package/esm/policyExecution.d.ts +19 -0
  310. package/esm/policyExecution.d.ts.map +1 -0
  311. package/esm/policyExecution.js +224 -0
  312. package/esm/policyExecution.js.map +1 -0
  313. package/esm/repositoryFiles.d.ts +4 -0
  314. package/esm/repositoryFiles.d.ts.map +1 -0
  315. package/esm/repositoryFiles.js +8 -0
  316. package/esm/repositoryFiles.js.map +1 -0
  317. package/esm/runner.d.ts +72 -47
  318. package/esm/runner.d.ts.map +1 -1
  319. package/esm/runner.js +153 -138
  320. package/esm/runner.js.map +1 -1
  321. package/esm/settlePolicyPromise.d.ts +4 -0
  322. package/esm/settlePolicyPromise.d.ts.map +1 -0
  323. package/esm/settlePolicyPromise.js +10 -0
  324. package/esm/settlePolicyPromise.js.map +1 -0
  325. package/esm/tsdoc-metadata.json +1 -1
  326. package/esm/utils/safePaths.d.ts +9 -0
  327. package/esm/utils/safePaths.d.ts.map +1 -0
  328. package/esm/utils/safePaths.js +40 -0
  329. package/esm/utils/safePaths.js.map +1 -0
  330. package/oclif.manifest.json +19 -2
  331. package/package.json +42 -27
  332. package/scripts/benchmark.mjs +341 -0
  333. package/sidecar/sidecar.mjs +348 -417
@@ -11,7 +11,7 @@ const MANUAL_FIX = "Use a valid SPDX licence identifier (e.g., MIT, Apache-2.0,
11
11
  * `licences`). This policy validates that the value is a recognized SPDX
12
12
  * identifier and can auto-fix common mistakes like wrong casing.
13
13
  *
14
- * @alpha
14
+ * @public
15
15
  */
16
16
  export const CargoLicenceValidated = defineCargoPolicy({
17
17
  name: "CargoLicenceValidated",
@@ -20,14 +20,16 @@ export const CargoLicenceValidated = defineCargoPolicy({
20
20
  const skipWorkspace = config?.skipWorkspace ?? true;
21
21
  const pkg = toml.package;
22
22
  if (!pkg && skipWorkspace) {
23
- return true;
23
+ return [];
24
24
  }
25
25
  const licence = pkg?.license;
26
26
  if (!licence || licence.trim() === "") {
27
- return {
28
- error: "Missing or empty license field in [package] section.",
29
- manualFix: 'Add license = "MIT" (or appropriate SPDX identifier) to [package] in Cargo.toml.',
30
- };
27
+ return [
28
+ {
29
+ message: "Missing or empty license field in [package] section.",
30
+ manualFix: 'Add license = "MIT" (or appropriate SPDX identifier) to [package] in Cargo.toml.',
31
+ },
32
+ ];
31
33
  }
32
34
  const result = await validateLicenceField({
33
35
  licences: [licence],
@@ -39,7 +41,7 @@ export const CargoLicenceValidated = defineCargoPolicy({
39
41
  filePath: resolve(root, file),
40
42
  manualFixMessage: MANUAL_FIX,
41
43
  });
42
- return result ?? true;
44
+ return result;
43
45
  },
44
46
  });
45
47
  //# sourceMappingURL=CargoLicenceValidated.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoLicenceValidated.js","sourceRoot":"","sources":["../../src/policies/CargoLicenceValidated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAgC1E,MAAM,UAAU,GACf,uEAAuE,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GACjC,iBAAiB,CAAC;IACjB,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACV,gEAAgE;IACjE,OAAO,EAAE,KAAK,EACb,IAAe,EACf,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAC7C,EAAE;QACH,MAAM,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,IAAI,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,OAA8C,CAAC;QAEhE,IAAI,CAAC,GAAG,IAAI,aAAa,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,EAAE,OAA6B,CAAC;QAEnD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvC,OAAO;gBACN,KAAK,EAAE,sDAAsD;gBAC7D,SAAS,EACR,kFAAkF;aACnF,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;YACzC,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,SAAS,IAAI;gBAC5C,eAAe,EAAE,MAAM,CAAC,eAAe;aACvC,CAAC;YACF,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,IAAI;YAC1C,aAAa;YACb,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC;YAC7B,gBAAgB,EAAE,UAAU;SAC5B,CAAC,CAAC;QAEH,OAAO,MAAM,IAAI,IAAI,CAAC;IACvB,CAAC;CACD,CAAC,CAAC","sourcesContent":["import { resolve } from \"pathe\";\nimport type { PolicyShape } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\nimport { validateLicenceField } from \"../policyDefiners/spdxValidator.js\";\n\n/**\n * Configuration for the CargoLicenceValidated policy.\n *\n * @alpha\n */\nexport interface CargoLicenceValidatedConfig {\n\t/**\n\t * Allowed SPDX licence identifiers. If set, only these are accepted.\n\t */\n\tallowedLicences?: string[];\n\n\t/**\n\t * If true, validate the licence value against the SPDX licence list\n\t * using `spdx-correct`. When enabled, typos like \"MIIT\" are detected\n\t * and can be auto-fixed to the correct identifier (\"MIT\").\n\t *\n\t * Requires the optional peer dependency `spdx-correct` to be installed.\n\t *\n\t * @defaultValue true\n\t */\n\tvalidateSpdx?: boolean;\n\n\t/**\n\t * If true, skip workspace-only Cargo.toml files (those without a [package] section).\n\t *\n\t * @defaultValue true\n\t */\n\tskipWorkspace?: boolean;\n}\n\nconst MANUAL_FIX =\n\t\"Use a valid SPDX licence identifier (e.g., MIT, Apache-2.0, MPL-2.0).\";\n\n/**\n * A policy that validates the `license` field in Cargo.toml against the SPDX\n * licence list. Supports auto-fixing correctable identifiers.\n *\n * @remarks\n * Cargo.toml uses a single `license` string field (not an array like Gleam's\n * `licences`). This policy validates that the value is a recognized SPDX\n * identifier and can auto-fix common mistakes like wrong casing.\n *\n * @alpha\n */\nexport const CargoLicenceValidated: PolicyShape<CargoLicenceValidatedConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"CargoLicenceValidated\",\n\t\tdescription:\n\t\t\t\"Validates that Cargo.toml has a valid SPDX licence identifier.\",\n\t\thandler: async (\n\t\t\ttoml: CargoToml,\n\t\t\t{ file, root, resolve: shouldResolve, config },\n\t\t) => {\n\t\t\tconst skipWorkspace = config?.skipWorkspace ?? true;\n\t\t\tconst pkg = toml.package as Record<string, unknown> | undefined;\n\n\t\t\tif (!pkg && skipWorkspace) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst licence = pkg?.license as string | undefined;\n\n\t\t\tif (!licence || licence.trim() === \"\") {\n\t\t\t\treturn {\n\t\t\t\t\terror: \"Missing or empty license field in [package] section.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t'Add license = \"MIT\" (or appropriate SPDX identifier) to [package] in Cargo.toml.',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst result = await validateLicenceField({\n\t\t\t\tlicences: [licence],\n\t\t\t\t...(config?.allowedLicences !== undefined && {\n\t\t\t\t\tallowedLicences: config.allowedLicences,\n\t\t\t\t}),\n\t\t\t\tvalidateSpdx: config?.validateSpdx ?? true,\n\t\t\t\tshouldResolve,\n\t\t\t\tfilePath: resolve(root, file),\n\t\t\t\tmanualFixMessage: MANUAL_FIX,\n\t\t\t});\n\n\t\t\treturn result ?? true;\n\t\t},\n\t});\n"]}
1
+ {"version":3,"file":"CargoLicenceValidated.js","sourceRoot":"","sources":["../../src/policies/CargoLicenceValidated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAgC1E,MAAM,UAAU,GACf,uEAAuE,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;IACtD,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EAAE,gEAAgE;IAC7E,OAAO,EAAE,KAAK,EACb,IAAe,EACf,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAC7C,EAAE;QACH,MAAM,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,IAAI,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,OAA8C,CAAC;QAEhE,IAAI,CAAC,GAAG,IAAI,aAAa,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC;QACX,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,EAAE,OAA6B,CAAC;QAEnD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvC,OAAO;gBACN;oBACC,OAAO,EAAE,sDAAsD;oBAC/D,SAAS,EACR,kFAAkF;iBACnF;aACD,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;YACzC,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,SAAS,IAAI;gBAC5C,eAAe,EAAE,MAAM,CAAC,eAAe;aACvC,CAAC;YACF,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,IAAI;YAC1C,aAAa;YACb,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC;YAC7B,gBAAgB,EAAE,UAAU;SAC5B,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IACf,CAAC;CACD,CAA6D,CAAC","sourcesContent":["import { resolve } from \"pathe\";\nimport type { FilePolicyDefinition } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\nimport { validateLicenceField } from \"../policyDefiners/spdxValidator.js\";\n\n/**\n * Configuration for the CargoLicenceValidated policy.\n *\n * @public\n */\nexport interface CargoLicenceValidatedConfig {\n\t/**\n\t * Allowed SPDX licence identifiers. If set, only these are accepted.\n\t */\n\tallowedLicences?: string[];\n\n\t/**\n\t * If true, validate the licence value against the SPDX licence list\n\t * using `spdx-correct`. When enabled, typos like \"MIIT\" are detected\n\t * and can be auto-fixed to the correct identifier (\"MIT\").\n\t *\n\t * Requires the optional peer dependency `spdx-correct` to be installed.\n\t *\n\t * @defaultValue true\n\t */\n\tvalidateSpdx?: boolean;\n\n\t/**\n\t * If true, skip workspace-only Cargo.toml files (those without a [package] section).\n\t *\n\t * @defaultValue true\n\t */\n\tskipWorkspace?: boolean;\n}\n\nconst MANUAL_FIX =\n\t\"Use a valid SPDX licence identifier (e.g., MIT, Apache-2.0, MPL-2.0).\";\n\n/**\n * A policy that validates the `license` field in Cargo.toml against the SPDX\n * licence list. Supports auto-fixing correctable identifiers.\n *\n * @remarks\n * Cargo.toml uses a single `license` string field (not an array like Gleam's\n * `licences`). This policy validates that the value is a recognized SPDX\n * identifier and can auto-fix common mistakes like wrong casing.\n *\n * @public\n */\nexport const CargoLicenceValidated = defineCargoPolicy({\n\tname: \"CargoLicenceValidated\",\n\tdescription: \"Validates that Cargo.toml has a valid SPDX licence identifier.\",\n\thandler: async (\n\t\ttoml: CargoToml,\n\t\t{ file, root, resolve: shouldResolve, config },\n\t) => {\n\t\tconst skipWorkspace = config?.skipWorkspace ?? true;\n\t\tconst pkg = toml.package as Record<string, unknown> | undefined;\n\n\t\tif (!pkg && skipWorkspace) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst licence = pkg?.license as string | undefined;\n\n\t\tif (!licence || licence.trim() === \"\") {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tmessage: \"Missing or empty license field in [package] section.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t'Add license = \"MIT\" (or appropriate SPDX identifier) to [package] in Cargo.toml.',\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\tconst result = await validateLicenceField({\n\t\t\tlicences: [licence],\n\t\t\t...(config?.allowedLicences !== undefined && {\n\t\t\t\tallowedLicences: config.allowedLicences,\n\t\t\t}),\n\t\t\tvalidateSpdx: config?.validateSpdx ?? true,\n\t\t\tshouldResolve,\n\t\t\tfilePath: resolve(root, file),\n\t\t\tmanualFixMessage: MANUAL_FIX,\n\t\t});\n\t\treturn result;\n\t},\n}) satisfies FilePolicyDefinition<CargoLicenceValidatedConfig>;\n"]}
@@ -1,8 +1,8 @@
1
- import type { PolicyShape } from "../policy.js";
1
+ import type { FilePolicyDefinition } from "../policy.js";
2
2
  /**
3
3
  * Configuration for the CargoLintsConfigured policy.
4
4
  *
5
- * @alpha
5
+ * @public
6
6
  */
7
7
  export interface CargoLintsConfiguredConfig {
8
8
  /**
@@ -24,7 +24,7 @@ export interface CargoLintsConfiguredConfig {
24
24
  /**
25
25
  * A policy that ensures Cargo.toml has a [lints.clippy] section configured.
26
26
  *
27
- * @alpha
27
+ * @public
28
28
  */
29
- export declare const CargoLintsConfigured: PolicyShape<CargoLintsConfiguredConfig>;
29
+ export declare const CargoLintsConfigured: FilePolicyDefinition<CargoLintsConfiguredConfig>;
30
30
  //# sourceMappingURL=CargoLintsConfigured.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoLintsConfigured.d.ts","sourceRoot":"","sources":["../../src/policies/CargoLintsConfigured.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,WAAW,EAAE,MAAM,cAAc,CAAC;AAMrE;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAgED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,0BAA0B,CAatE,CAAC"}
1
+ {"version":3,"file":"CargoLintsConfigured.d.ts","sourceRoot":"","sources":["../../src/policies/CargoLintsConfigured.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAgB,MAAM,cAAc,CAAC;AAMvE;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAmED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,kDAY4B,CAAC"}
@@ -16,36 +16,40 @@ function checkLintsSection(toml, config) {
16
16
  const lints = toml.lints;
17
17
  const requireSection = config?.requireSection ?? true;
18
18
  if (requireSection && lints === undefined) {
19
- return {
20
- error: "Missing [lints] section in Cargo.toml.",
21
- manualFix: 'Add a [lints.clippy] section, e.g.:\n[lints.clippy]\npedantic = "warn"',
22
- };
19
+ return [
20
+ {
21
+ message: "Missing [lints] section in Cargo.toml.",
22
+ manualFix: 'Add a [lints.clippy] section, e.g.:\n[lints.clippy]\npedantic = "warn"',
23
+ },
24
+ ];
23
25
  }
24
26
  if (lints === undefined) {
25
- return true;
27
+ return [];
26
28
  }
27
29
  const clippy = lints.clippy;
28
30
  if (requireSection && clippy === undefined) {
29
- return {
30
- error: "Missing [lints.clippy] section in Cargo.toml.",
31
- manualFix: 'Add a [lints.clippy] section, e.g.:\n[lints.clippy]\npedantic = "warn"',
32
- };
31
+ return [
32
+ {
33
+ message: "Missing [lints.clippy] section in Cargo.toml.",
34
+ manualFix: 'Add a [lints.clippy] section, e.g.:\n[lints.clippy]\npedantic = "warn"',
35
+ },
36
+ ];
33
37
  }
34
38
  if (config?.required && clippy) {
35
39
  const errors = checkClippyLints(clippy, config.required);
36
40
  if (errors.length > 0) {
37
- return {
38
- error: errors.join("; "),
41
+ return errors.map((message) => ({
42
+ message,
39
43
  manualFix: "Update the [lints.clippy] section with the required lint levels.",
40
- };
44
+ }));
41
45
  }
42
46
  }
43
- return true;
47
+ return [];
44
48
  }
45
49
  /**
46
50
  * A policy that ensures Cargo.toml has a [lints.clippy] section configured.
47
51
  *
48
- * @alpha
52
+ * @public
49
53
  */
50
54
  export const CargoLintsConfigured = defineCargoPolicy({
51
55
  name: "CargoLintsConfigured",
@@ -53,7 +57,7 @@ export const CargoLintsConfigured = defineCargoPolicy({
53
57
  handler: async (toml, { config }) => {
54
58
  // Skip workspace root Cargo.toml files
55
59
  if (toml.workspace !== undefined && toml.package === undefined) {
56
- return true;
60
+ return [];
57
61
  }
58
62
  return checkLintsSection(toml, config);
59
63
  },
@@ -1 +1 @@
1
- {"version":3,"file":"CargoLintsConfigured.js","sourceRoot":"","sources":["../../src/policies/CargoLintsConfigured.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AA0BhD,SAAS,gBAAgB,CACxB,MAA+B,EAC/B,QAAgC;IAEhC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CACV,wBAAwB,IAAI,sBAAsB,aAAa,IAAI,CACnE,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,aAAa,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CACV,eAAe,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,aAAa,GAAG,CACxE,CAAC;QACH,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CACzB,IAAe,EACf,MAA8C;IAE9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;IAChE,MAAM,cAAc,GAAG,MAAM,EAAE,cAAc,IAAI,IAAI,CAAC;IAEtD,IAAI,cAAc,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO;YACN,KAAK,EAAE,wCAAwC;YAC/C,SAAS,EACR,wEAAwE;SACzE,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAA6C,CAAC;IACnE,IAAI,cAAc,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5C,OAAO;YACN,KAAK,EAAE,+CAA+C;YACtD,SAAS,EACR,wEAAwE;SACzE,CAAC;IACH,CAAC;IAED,IAAI,MAAM,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO;gBACN,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxB,SAAS,EACR,kEAAkE;aACnE,CAAC;QACH,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAChC,iBAAiB,CAAC;IACjB,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACV,wEAAwE;IACzE,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,uCAAuC;QACvC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;CACD,CAAC,CAAC","sourcesContent":["import type { PolicyHandlerResult, PolicyShape } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoLintsConfigured policy.\n *\n * @alpha\n */\nexport interface CargoLintsConfiguredConfig {\n\t/**\n\t * Required clippy lint levels. Keys are lint names (without the `clippy::` prefix),\n\t * values are the minimum level (\"warn\" or \"deny\").\n\t *\n\t * @example\n\t * ```typescript\n\t * { pedantic: \"warn\", nursery: \"warn\" }\n\t * ```\n\t */\n\trequired?: Record<string, string>;\n\n\t/**\n\t * If true, just require that a [lints.clippy] section exists (without checking specific lints).\n\t * @defaultValue true\n\t */\n\trequireSection?: boolean;\n}\n\nfunction checkClippyLints(\n\tclippy: Record<string, unknown>,\n\trequired: Record<string, string>,\n): string[] {\n\tconst errors: string[] = [];\n\tfor (const [lint, expectedLevel] of Object.entries(required)) {\n\t\tconst actual = clippy[lint];\n\t\tif (actual === undefined) {\n\t\t\terrors.push(\n\t\t\t\t`Missing clippy lint: ${lint} (expected level: \"${expectedLevel}\")`,\n\t\t\t);\n\t\t} else if (String(actual) !== expectedLevel) {\n\t\t\terrors.push(\n\t\t\t\t`Clippy lint ${lint} = \"${String(actual)}\", expected \"${expectedLevel}\"`,\n\t\t\t);\n\t\t}\n\t}\n\treturn errors;\n}\n\nfunction checkLintsSection(\n\ttoml: CargoToml,\n\tconfig: CargoLintsConfiguredConfig | undefined,\n): PolicyHandlerResult {\n\tconst lints = toml.lints as Record<string, unknown> | undefined;\n\tconst requireSection = config?.requireSection ?? true;\n\n\tif (requireSection && lints === undefined) {\n\t\treturn {\n\t\t\terror: \"Missing [lints] section in Cargo.toml.\",\n\t\t\tmanualFix:\n\t\t\t\t'Add a [lints.clippy] section, e.g.:\\n[lints.clippy]\\npedantic = \"warn\"',\n\t\t};\n\t}\n\n\tif (lints === undefined) {\n\t\treturn true;\n\t}\n\n\tconst clippy = lints.clippy as Record<string, unknown> | undefined;\n\tif (requireSection && clippy === undefined) {\n\t\treturn {\n\t\t\terror: \"Missing [lints.clippy] section in Cargo.toml.\",\n\t\t\tmanualFix:\n\t\t\t\t'Add a [lints.clippy] section, e.g.:\\n[lints.clippy]\\npedantic = \"warn\"',\n\t\t};\n\t}\n\n\tif (config?.required && clippy) {\n\t\tconst errors = checkClippyLints(clippy, config.required);\n\t\tif (errors.length > 0) {\n\t\t\treturn {\n\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\tmanualFix:\n\t\t\t\t\t\"Update the [lints.clippy] section with the required lint levels.\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * A policy that ensures Cargo.toml has a [lints.clippy] section configured.\n *\n * @alpha\n */\nexport const CargoLintsConfigured: PolicyShape<CargoLintsConfiguredConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"CargoLintsConfigured\",\n\t\tdescription:\n\t\t\t\"Ensures Cargo.toml has clippy lints configured in the [lints] section.\",\n\t\thandler: async (toml: CargoToml, { config }) => {\n\t\t\t// Skip workspace root Cargo.toml files\n\t\t\tif (toml.workspace !== undefined && toml.package === undefined) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn checkLintsSection(toml, config);\n\t\t},\n\t});\n"]}
1
+ {"version":3,"file":"CargoLintsConfigured.js","sourceRoot":"","sources":["../../src/policies/CargoLintsConfigured.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AA0BhD,SAAS,gBAAgB,CACxB,MAA+B,EAC/B,QAAgC;IAEhC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CACV,wBAAwB,IAAI,sBAAsB,aAAa,IAAI,CACnE,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,aAAa,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CACV,eAAe,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,aAAa,GAAG,CACxE,CAAC;QACH,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CACzB,IAAe,EACf,MAA8C;IAE9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;IAChE,MAAM,cAAc,GAAG,MAAM,EAAE,cAAc,IAAI,IAAI,CAAC;IAEtD,IAAI,cAAc,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO;YACN;gBACC,OAAO,EAAE,wCAAwC;gBACjD,SAAS,EACR,wEAAwE;aACzE;SACD,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAA6C,CAAC;IACnE,IAAI,cAAc,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5C,OAAO;YACN;gBACC,OAAO,EAAE,+CAA+C;gBACxD,SAAS,EACR,wEAAwE;aACzE;SACD,CAAC;IACH,CAAC;IAED,IAAI,MAAM,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC/B,OAAO;gBACP,SAAS,EACR,kEAAkE;aACnE,CAAC,CAAC,CAAC;QACL,CAAC;IACF,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;IACrD,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACV,wEAAwE;IACzE,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,uCAAuC;QACvC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;CACD,CAA4D,CAAC","sourcesContent":["import type { FilePolicyDefinition, PolicyResult } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoLintsConfigured policy.\n *\n * @public\n */\nexport interface CargoLintsConfiguredConfig {\n\t/**\n\t * Required clippy lint levels. Keys are lint names (without the `clippy::` prefix),\n\t * values are the minimum level (\"warn\" or \"deny\").\n\t *\n\t * @example\n\t * ```typescript\n\t * { pedantic: \"warn\", nursery: \"warn\" }\n\t * ```\n\t */\n\trequired?: Record<string, string>;\n\n\t/**\n\t * If true, just require that a [lints.clippy] section exists (without checking specific lints).\n\t * @defaultValue true\n\t */\n\trequireSection?: boolean;\n}\n\nfunction checkClippyLints(\n\tclippy: Record<string, unknown>,\n\trequired: Record<string, string>,\n): string[] {\n\tconst errors: string[] = [];\n\tfor (const [lint, expectedLevel] of Object.entries(required)) {\n\t\tconst actual = clippy[lint];\n\t\tif (actual === undefined) {\n\t\t\terrors.push(\n\t\t\t\t`Missing clippy lint: ${lint} (expected level: \"${expectedLevel}\")`,\n\t\t\t);\n\t\t} else if (String(actual) !== expectedLevel) {\n\t\t\terrors.push(\n\t\t\t\t`Clippy lint ${lint} = \"${String(actual)}\", expected \"${expectedLevel}\"`,\n\t\t\t);\n\t\t}\n\t}\n\treturn errors;\n}\n\nfunction checkLintsSection(\n\ttoml: CargoToml,\n\tconfig: CargoLintsConfiguredConfig | undefined,\n): PolicyResult {\n\tconst lints = toml.lints as Record<string, unknown> | undefined;\n\tconst requireSection = config?.requireSection ?? true;\n\n\tif (requireSection && lints === undefined) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tmessage: \"Missing [lints] section in Cargo.toml.\",\n\t\t\t\tmanualFix:\n\t\t\t\t\t'Add a [lints.clippy] section, e.g.:\\n[lints.clippy]\\npedantic = \"warn\"',\n\t\t\t},\n\t\t];\n\t}\n\n\tif (lints === undefined) {\n\t\treturn [];\n\t}\n\n\tconst clippy = lints.clippy as Record<string, unknown> | undefined;\n\tif (requireSection && clippy === undefined) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tmessage: \"Missing [lints.clippy] section in Cargo.toml.\",\n\t\t\t\tmanualFix:\n\t\t\t\t\t'Add a [lints.clippy] section, e.g.:\\n[lints.clippy]\\npedantic = \"warn\"',\n\t\t\t},\n\t\t];\n\t}\n\n\tif (config?.required && clippy) {\n\t\tconst errors = checkClippyLints(clippy, config.required);\n\t\tif (errors.length > 0) {\n\t\t\treturn errors.map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\tmanualFix:\n\t\t\t\t\t\"Update the [lints.clippy] section with the required lint levels.\",\n\t\t\t}));\n\t\t}\n\t}\n\treturn [];\n}\n\n/**\n * A policy that ensures Cargo.toml has a [lints.clippy] section configured.\n *\n * @public\n */\nexport const CargoLintsConfigured = defineCargoPolicy({\n\tname: \"CargoLintsConfigured\",\n\tdescription:\n\t\t\"Ensures Cargo.toml has clippy lints configured in the [lints] section.\",\n\thandler: async (toml: CargoToml, { config }) => {\n\t\t// Skip workspace root Cargo.toml files\n\t\tif (toml.workspace !== undefined && toml.package === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn checkLintsSection(toml, config);\n\t},\n}) satisfies FilePolicyDefinition<CargoLintsConfiguredConfig>;\n"]}
@@ -1,8 +1,8 @@
1
- import type { PolicyShape } from "../policy.js";
1
+ import type { FilePolicyDefinition } from "../policy.js";
2
2
  /**
3
3
  * Configuration for the CargoLockPolicy.
4
4
  *
5
- * @alpha
5
+ * @public
6
6
  */
7
7
  export interface CargoLockPolicyConfig {
8
8
  /**
@@ -28,7 +28,7 @@ export interface CargoLockPolicyConfig {
28
28
  * A context-aware policy for Cargo.lock files.
29
29
  * Binary crates should commit Cargo.lock; library crates typically shouldn't.
30
30
  *
31
- * @alpha
31
+ * @public
32
32
  */
33
- export declare const CargoLockPolicy: PolicyShape<CargoLockPolicyConfig>;
33
+ export declare const CargoLockPolicy: FilePolicyDefinition<CargoLockPolicyConfig>;
34
34
  //# sourceMappingURL=CargoLockPolicy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoLockPolicy.d.ts","sourceRoot":"","sources":["../../src/policies/CargoLockPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IAEzC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;CAC1C;AAsBD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,qBAAqB,CAuC5D,CAAC"}
1
+ {"version":3,"file":"CargoLockPolicy.d.ts","sourceRoot":"","sources":["../../src/policies/CargoLockPolicy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMzD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IAEzC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;CAC1C;AAsBD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,6CAyC4B,CAAC"}
@@ -23,7 +23,7 @@ function isLibraryCrate(toml) {
23
23
  * A context-aware policy for Cargo.lock files.
24
24
  * Binary crates should commit Cargo.lock; library crates typically shouldn't.
25
25
  *
26
- * @alpha
26
+ * @public
27
27
  */
28
28
  export const CargoLockPolicy = defineCargoPolicy({
29
29
  name: "CargoLockPolicy",
@@ -31,7 +31,7 @@ export const CargoLockPolicy = defineCargoPolicy({
31
31
  handler: async (toml, { root, file, config }) => {
32
32
  // Skip workspace root Cargo.toml
33
33
  if (toml.workspace !== undefined && toml.package === undefined) {
34
- return true;
34
+ return [];
35
35
  }
36
36
  const dir = path.dirname(path.resolve(root, file));
37
37
  const lockExists = existsSync(path.join(dir, "Cargo.lock"));
@@ -40,18 +40,22 @@ export const CargoLockPolicy = defineCargoPolicy({
40
40
  const binaryPolicy = config?.binaries ?? "require";
41
41
  const libraryPolicy = config?.libraries ?? "ignore";
42
42
  if (isBinary && binaryPolicy === "require" && !lockExists) {
43
- return {
44
- error: "Binary crate is missing Cargo.lock. Binary crates should commit their lockfile for reproducible builds.",
45
- manualFix: "Run `cargo generate-lockfile` and commit the Cargo.lock file.",
46
- };
43
+ return [
44
+ {
45
+ message: "Binary crate is missing Cargo.lock. Binary crates should commit their lockfile for reproducible builds.",
46
+ manualFix: "Run `cargo generate-lockfile` and commit the Cargo.lock file.",
47
+ },
48
+ ];
47
49
  }
48
50
  if (isLib && !isBinary && libraryPolicy === "warn" && lockExists) {
49
- return {
50
- error: "Library crate has Cargo.lock committed. Library crates typically should not commit their lockfile.",
51
- manualFix: "Consider adding Cargo.lock to .gitignore for library crates.",
52
- };
51
+ return [
52
+ {
53
+ message: "Library crate has Cargo.lock committed. Library crates typically should not commit their lockfile.",
54
+ manualFix: "Consider adding Cargo.lock to .gitignore for library crates.",
55
+ },
56
+ ];
53
57
  }
54
- return true;
58
+ return [];
55
59
  },
56
60
  });
57
61
  //# sourceMappingURL=CargoLockPolicy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoLockPolicy.js","sourceRoot":"","sources":["../../src/policies/CargoLockPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,OAAO,CAAC;AAEzB,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AA6BhD,SAAS,aAAa,CAAC,IAAe;IACrC,sBAAsB;IACtB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,oEAAoE;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,OAA8C,CAAC;IAChE,IAAI,GAAG,EAAE,CAAC;QACT,0EAA0E;QAC1E,6DAA6D;QAC7D,qEAAqE;QACrE,OAAO,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,IAAe;IACtC,OAAO,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAC3B,iBAAiB,CAAC;IACjB,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACV,iGAAiG;IAClG,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1D,iCAAiC;QACjC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAEnC,MAAM,YAAY,GAAG,MAAM,EAAE,QAAQ,IAAI,SAAS,CAAC;QACnD,MAAM,aAAa,GAAG,MAAM,EAAE,SAAS,IAAI,QAAQ,CAAC;QAEpD,IAAI,QAAQ,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3D,OAAO;gBACN,KAAK,EACJ,yGAAyG;gBAC1G,SAAS,EACR,+DAA+D;aAChE,CAAC;QACH,CAAC;QAED,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,aAAa,KAAK,MAAM,IAAI,UAAU,EAAE,CAAC;YAClE,OAAO;gBACN,KAAK,EACJ,oGAAoG;gBACrG,SAAS,EACR,8DAA8D;aAC/D,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC,CAAC","sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"pathe\";\nimport type { PolicyShape } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoLockPolicy.\n *\n * @alpha\n */\nexport interface CargoLockPolicyConfig {\n\t/**\n\t * Policy for binary crates.\n\t * - \"require\": Cargo.lock must be committed (default for binaries)\n\t * - \"warn\": Emit a warning if missing\n\t * - \"ignore\": Skip check\n\t *\n\t * @defaultValue \"require\"\n\t */\n\tbinaries?: \"require\" | \"warn\" | \"ignore\";\n\n\t/**\n\t * Policy for library crates.\n\t * - \"require\": Cargo.lock must be committed\n\t * - \"warn\": Emit a warning if committed (default for libraries)\n\t * - \"ignore\": Skip check\n\t *\n\t * @defaultValue \"ignore\"\n\t */\n\tlibraries?: \"require\" | \"warn\" | \"ignore\";\n}\n\nfunction isBinaryCrate(toml: CargoToml): boolean {\n\t// Has [[bin]] entries\n\tif (Array.isArray(toml.bin) && toml.bin.length > 0) {\n\t\treturn true;\n\t}\n\t// Has a default binary (src/main.rs is handled by Cargo implicitly)\n\tconst pkg = toml.package as Record<string, unknown> | undefined;\n\tif (pkg) {\n\t\t// If there's no explicit lib section and no [[bin]], Cargo assumes binary\n\t\t// if src/main.rs exists, but we can't check filesystem here.\n\t\t// Best heuristic: if there's no [lib] section, it could be a binary.\n\t\treturn toml.lib === undefined;\n\t}\n\treturn false;\n}\n\nfunction isLibraryCrate(toml: CargoToml): boolean {\n\treturn toml.lib !== undefined;\n}\n\n/**\n * A context-aware policy for Cargo.lock files.\n * Binary crates should commit Cargo.lock; library crates typically shouldn't.\n *\n * @alpha\n */\nexport const CargoLockPolicy: PolicyShape<CargoLockPolicyConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"CargoLockPolicy\",\n\t\tdescription:\n\t\t\t\"Context-aware Cargo.lock validation: binaries should commit it, libraries typically should not.\",\n\t\thandler: async (toml: CargoToml, { root, file, config }) => {\n\t\t\t// Skip workspace root Cargo.toml\n\t\t\tif (toml.workspace !== undefined && toml.package === undefined) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst dir = path.dirname(path.resolve(root, file));\n\t\t\tconst lockExists = existsSync(path.join(dir, \"Cargo.lock\"));\n\t\t\tconst isBinary = isBinaryCrate(toml);\n\t\t\tconst isLib = isLibraryCrate(toml);\n\n\t\t\tconst binaryPolicy = config?.binaries ?? \"require\";\n\t\t\tconst libraryPolicy = config?.libraries ?? \"ignore\";\n\n\t\t\tif (isBinary && binaryPolicy === \"require\" && !lockExists) {\n\t\t\t\treturn {\n\t\t\t\t\terror:\n\t\t\t\t\t\t\"Binary crate is missing Cargo.lock. Binary crates should commit their lockfile for reproducible builds.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t\"Run `cargo generate-lockfile` and commit the Cargo.lock file.\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (isLib && !isBinary && libraryPolicy === \"warn\" && lockExists) {\n\t\t\t\treturn {\n\t\t\t\t\terror:\n\t\t\t\t\t\t\"Library crate has Cargo.lock committed. Library crates typically should not commit their lockfile.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t\"Consider adding Cargo.lock to .gitignore for library crates.\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t});\n"]}
1
+ {"version":3,"file":"CargoLockPolicy.js","sourceRoot":"","sources":["../../src/policies/CargoLockPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,OAAO,CAAC;AAEzB,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AA6BhD,SAAS,aAAa,CAAC,IAAe;IACrC,sBAAsB;IACtB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,oEAAoE;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,OAA8C,CAAC;IAChE,IAAI,GAAG,EAAE,CAAC;QACT,0EAA0E;QAC1E,6DAA6D;QAC7D,qEAAqE;QACrE,OAAO,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,IAAe;IACtC,OAAO,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC;IAChD,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACV,iGAAiG;IAClG,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1D,iCAAiC;QACjC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,EAAE,CAAC;QACX,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAEnC,MAAM,YAAY,GAAG,MAAM,EAAE,QAAQ,IAAI,SAAS,CAAC;QACnD,MAAM,aAAa,GAAG,MAAM,EAAE,SAAS,IAAI,QAAQ,CAAC;QAEpD,IAAI,QAAQ,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3D,OAAO;gBACN;oBACC,OAAO,EACN,yGAAyG;oBAC1G,SAAS,EACR,+DAA+D;iBAChE;aACD,CAAC;QACH,CAAC;QAED,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,aAAa,KAAK,MAAM,IAAI,UAAU,EAAE,CAAC;YAClE,OAAO;gBACN;oBACC,OAAO,EACN,oGAAoG;oBACrG,SAAS,EACR,8DAA8D;iBAC/D;aACD,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;CACD,CAAuD,CAAC","sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"pathe\";\nimport type { FilePolicyDefinition } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoLockPolicy.\n *\n * @public\n */\nexport interface CargoLockPolicyConfig {\n\t/**\n\t * Policy for binary crates.\n\t * - \"require\": Cargo.lock must be committed (default for binaries)\n\t * - \"warn\": Emit a warning if missing\n\t * - \"ignore\": Skip check\n\t *\n\t * @defaultValue \"require\"\n\t */\n\tbinaries?: \"require\" | \"warn\" | \"ignore\";\n\n\t/**\n\t * Policy for library crates.\n\t * - \"require\": Cargo.lock must be committed\n\t * - \"warn\": Emit a warning if committed (default for libraries)\n\t * - \"ignore\": Skip check\n\t *\n\t * @defaultValue \"ignore\"\n\t */\n\tlibraries?: \"require\" | \"warn\" | \"ignore\";\n}\n\nfunction isBinaryCrate(toml: CargoToml): boolean {\n\t// Has [[bin]] entries\n\tif (Array.isArray(toml.bin) && toml.bin.length > 0) {\n\t\treturn true;\n\t}\n\t// Has a default binary (src/main.rs is handled by Cargo implicitly)\n\tconst pkg = toml.package as Record<string, unknown> | undefined;\n\tif (pkg) {\n\t\t// If there's no explicit lib section and no [[bin]], Cargo assumes binary\n\t\t// if src/main.rs exists, but we can't check filesystem here.\n\t\t// Best heuristic: if there's no [lib] section, it could be a binary.\n\t\treturn toml.lib === undefined;\n\t}\n\treturn false;\n}\n\nfunction isLibraryCrate(toml: CargoToml): boolean {\n\treturn toml.lib !== undefined;\n}\n\n/**\n * A context-aware policy for Cargo.lock files.\n * Binary crates should commit Cargo.lock; library crates typically shouldn't.\n *\n * @public\n */\nexport const CargoLockPolicy = defineCargoPolicy({\n\tname: \"CargoLockPolicy\",\n\tdescription:\n\t\t\"Context-aware Cargo.lock validation: binaries should commit it, libraries typically should not.\",\n\thandler: async (toml: CargoToml, { root, file, config }) => {\n\t\t// Skip workspace root Cargo.toml\n\t\tif (toml.workspace !== undefined && toml.package === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst dir = path.dirname(path.resolve(root, file));\n\t\tconst lockExists = existsSync(path.join(dir, \"Cargo.lock\"));\n\t\tconst isBinary = isBinaryCrate(toml);\n\t\tconst isLib = isLibraryCrate(toml);\n\n\t\tconst binaryPolicy = config?.binaries ?? \"require\";\n\t\tconst libraryPolicy = config?.libraries ?? \"ignore\";\n\n\t\tif (isBinary && binaryPolicy === \"require\" && !lockExists) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"Binary crate is missing Cargo.lock. Binary crates should commit their lockfile for reproducible builds.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t\"Run `cargo generate-lockfile` and commit the Cargo.lock file.\",\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\tif (isLib && !isBinary && libraryPolicy === \"warn\" && lockExists) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"Library crate has Cargo.lock committed. Library crates typically should not commit their lockfile.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t\"Consider adding Cargo.lock to .gitignore for library crates.\",\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t},\n}) satisfies FilePolicyDefinition<CargoLockPolicyConfig>;\n"]}
@@ -1,8 +1,8 @@
1
- import type { PolicyShape } from "../policy.js";
1
+ import type { FilePolicyDefinition } from "../policy.js";
2
2
  /**
3
3
  * Configuration for the CargoTomlRequired policy.
4
4
  *
5
- * @alpha
5
+ * @public
6
6
  */
7
7
  export interface CargoTomlRequiredConfig {
8
8
  /**
@@ -12,7 +12,7 @@ export interface CargoTomlRequiredConfig {
12
12
  required?: string[];
13
13
  /**
14
14
  * Minimum Rust edition to require (e.g., "2021").
15
- * If set, the `edition` field must exist and be >= this value.
15
+ * If set, the `edition` field must exist and be at least this value.
16
16
  */
17
17
  minimumEdition?: string;
18
18
  /**
@@ -28,7 +28,7 @@ export interface CargoTomlRequiredConfig {
28
28
  /**
29
29
  * A policy that enforces required fields exist in Cargo.toml [package] section.
30
30
  *
31
- * @alpha
31
+ * @public
32
32
  */
33
- export declare const CargoTomlRequired: PolicyShape<CargoTomlRequiredConfig>;
33
+ export declare const CargoTomlRequired: FilePolicyDefinition<CargoTomlRequiredConfig>;
34
34
  //# sourceMappingURL=CargoTomlRequired.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoTomlRequired.d.ts","sourceRoot":"","sources":["../../src/policies/CargoTomlRequired.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAwED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,uBAAuB,CA+BhE,CAAC"}
1
+ {"version":3,"file":"CargoTomlRequired.d.ts","sourceRoot":"","sources":["../../src/policies/CargoTomlRequired.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMzD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAwED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,+CA6B4B,CAAC"}
@@ -46,7 +46,7 @@ function checkMinimumEdition(pkg, config, errors) {
46
46
  /**
47
47
  * A policy that enforces required fields exist in Cargo.toml [package] section.
48
48
  *
49
- * @alpha
49
+ * @public
50
50
  */
51
51
  export const CargoTomlRequired = defineCargoPolicy({
52
52
  name: "CargoTomlRequired",
@@ -56,9 +56,9 @@ export const CargoTomlRequired = defineCargoPolicy({
56
56
  if (!pkg) {
57
57
  // Workspace root Cargo.toml may not have [package]
58
58
  if (toml.workspace !== undefined) {
59
- return true;
59
+ return [];
60
60
  }
61
- return { error: "Missing [package] section in Cargo.toml" };
61
+ return [{ message: "Missing [package] section in Cargo.toml" }];
62
62
  }
63
63
  const errors = [];
64
64
  checkRequiredFields(pkg, config, errors);
@@ -66,12 +66,12 @@ export const CargoTomlRequired = defineCargoPolicy({
66
66
  checkRustVersion(pkg, config, errors);
67
67
  checkMinimumEdition(pkg, config, errors);
68
68
  if (errors.length > 0) {
69
- return {
70
- error: errors.join("; "),
69
+ return errors.map((message) => ({
70
+ message,
71
71
  manualFix: "Add the missing fields to your Cargo.toml [package] section.",
72
- };
72
+ }));
73
73
  }
74
- return true;
74
+ return [];
75
75
  },
76
76
  });
77
77
  //# sourceMappingURL=CargoTomlRequired.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoTomlRequired.js","sourceRoot":"","sources":["../../src/policies/CargoTomlRequired.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAgChD,MAAM,uBAAuB,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAC3D,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAExD,SAAS,mBAAmB,CAC3B,GAA4B,EAC5B,MAA2C,EAC3C,MAAgB;IAEhB,MAAM,cAAc,GAAG,MAAM,EAAE,QAAQ,IAAI,uBAAuB,CAAC;IACnE,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB,CAC3B,GAA4B,EAC5B,MAA2C,EAC3C,MAAgB;IAEhB,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;QAC7B,OAAO;IACR,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QACvE,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CACV,oBAAoB,KAAK,OAAO,QAAQ,WAAW,MAAM,CAAC,MAAM,CAAC,GAAG,CACpE,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CACxB,GAA4B,EAC5B,MAA2C,EAC3C,MAAgB;IAEhB,IAAI,MAAM,EAAE,kBAAkB,IAAI,GAAG,CAAC,cAAc,CAAC,KAAK,SAAS,EAAE,CAAC;QACrE,MAAM,CAAC,IAAI,CACV,8EAA8E,CAC9E,CAAC;IACH,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB,CAC3B,GAA4B,EAC5B,MAA2C,EAC3C,MAAgB;IAEhB,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;QAC7B,OAAO;IACR,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,OAA6B,CAAC;IAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAC/C,CAAC;SAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CACV,oBAAoB,OAAO,sBAAsB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5E,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CACV,YAAY,OAAO,uBAAuB,MAAM,CAAC,cAAc,IAAI,CACnE,CAAC;IACH,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAC7B,iBAAiB,CAAC;IACjB,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACV,4EAA4E;IAC7E,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAA8C,CAAC;QAChE,IAAI,CAAC,GAAG,EAAE,CAAC;YACV,mDAAmD;YACnD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC;YACb,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC;QAC7D,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAEzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO;gBACN,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxB,SAAS,EACR,8DAA8D;aAC/D,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC,CAAC","sourcesContent":["import type { PolicyShape } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoTomlRequired policy.\n *\n * @alpha\n */\nexport interface CargoTomlRequiredConfig {\n\t/**\n\t * Fields that must exist in the [package] section.\n\t * @defaultValue [\"license\", \"description\"]\n\t */\n\trequired?: string[];\n\n\t/**\n\t * Minimum Rust edition to require (e.g., \"2021\").\n\t * If set, the `edition` field must exist and be >= this value.\n\t */\n\tminimumEdition?: string;\n\n\t/**\n\t * If true, require the `rust-version` field (MSRV) to be set.\n\t * @defaultValue false\n\t */\n\trequireRustVersion?: boolean;\n\n\t/**\n\t * Specific field values to enforce. Keys are field names, values are expected values.\n\t */\n\texpectedValues?: Record<string, string>;\n}\n\nconst DEFAULT_REQUIRED_FIELDS = [\"license\", \"description\"];\nconst VALID_EDITIONS = [\"2015\", \"2018\", \"2021\", \"2024\"];\n\nfunction checkRequiredFields(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tconst requiredFields = config?.required ?? DEFAULT_REQUIRED_FIELDS;\n\tfor (const field of requiredFields) {\n\t\tif (pkg[field] === undefined) {\n\t\t\terrors.push(`Missing required field: package.${field}`);\n\t\t}\n\t}\n}\n\nfunction checkExpectedValues(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tif (!config?.expectedValues) {\n\t\treturn;\n\t}\n\tfor (const [field, expected] of Object.entries(config.expectedValues)) {\n\t\tconst actual = pkg[field];\n\t\tif (actual === undefined) {\n\t\t\terrors.push(`Missing required field: package.${field}`);\n\t\t} else if (String(actual) !== expected) {\n\t\t\terrors.push(\n\t\t\t\t`Expected package.${field} = \"${expected}\", got \"${String(actual)}\"`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction checkRustVersion(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tif (config?.requireRustVersion && pkg[\"rust-version\"] === undefined) {\n\t\terrors.push(\n\t\t\t\"Missing package.rust-version (MSRV). Set the minimum supported Rust version.\",\n\t\t);\n\t}\n}\n\nfunction checkMinimumEdition(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tif (!config?.minimumEdition) {\n\t\treturn;\n\t}\n\tconst edition = pkg.edition as string | undefined;\n\tif (edition === undefined) {\n\t\terrors.push(\"Missing package.edition field.\");\n\t} else if (!VALID_EDITIONS.includes(edition)) {\n\t\terrors.push(\n\t\t\t`Invalid edition \"${edition}\". Must be one of: ${VALID_EDITIONS.join(\", \")}`,\n\t\t);\n\t} else if (edition < config.minimumEdition) {\n\t\terrors.push(\n\t\t\t`Edition \"${edition}\" is below minimum \"${config.minimumEdition}\".`,\n\t\t);\n\t}\n}\n\n/**\n * A policy that enforces required fields exist in Cargo.toml [package] section.\n *\n * @alpha\n */\nexport const CargoTomlRequired: PolicyShape<CargoTomlRequiredConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"CargoTomlRequired\",\n\t\tdescription:\n\t\t\t\"Ensures Cargo.toml files contain required fields in the [package] section.\",\n\t\thandler: async (toml: CargoToml, { config }) => {\n\t\t\tconst pkg = toml.package as Record<string, unknown> | undefined;\n\t\t\tif (!pkg) {\n\t\t\t\t// Workspace root Cargo.toml may not have [package]\n\t\t\t\tif (toml.workspace !== undefined) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn { error: \"Missing [package] section in Cargo.toml\" };\n\t\t\t}\n\n\t\t\tconst errors: string[] = [];\n\t\t\tcheckRequiredFields(pkg, config, errors);\n\t\t\tcheckExpectedValues(pkg, config, errors);\n\t\t\tcheckRustVersion(pkg, config, errors);\n\t\t\tcheckMinimumEdition(pkg, config, errors);\n\n\t\t\tif (errors.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t\"Add the missing fields to your Cargo.toml [package] section.\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t});\n"]}
1
+ {"version":3,"file":"CargoTomlRequired.js","sourceRoot":"","sources":["../../src/policies/CargoTomlRequired.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FilePolicyDefinition } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoTomlRequired policy.\n *\n * @public\n */\nexport interface CargoTomlRequiredConfig {\n\t/**\n\t * Fields that must exist in the [package] section.\n\t * @defaultValue [\"license\", \"description\"]\n\t */\n\trequired?: string[];\n\n\t/**\n\t * Minimum Rust edition to require (e.g., \"2021\").\n\t * If set, the `edition` field must exist and be at least this value.\n\t */\n\tminimumEdition?: string;\n\n\t/**\n\t * If true, require the `rust-version` field (MSRV) to be set.\n\t * @defaultValue false\n\t */\n\trequireRustVersion?: boolean;\n\n\t/**\n\t * Specific field values to enforce. Keys are field names, values are expected values.\n\t */\n\texpectedValues?: Record<string, string>;\n}\n\nconst DEFAULT_REQUIRED_FIELDS = [\"license\", \"description\"];\nconst VALID_EDITIONS = [\"2015\", \"2018\", \"2021\", \"2024\"];\n\nfunction checkRequiredFields(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tconst requiredFields = config?.required ?? DEFAULT_REQUIRED_FIELDS;\n\tfor (const field of requiredFields) {\n\t\tif (pkg[field] === undefined) {\n\t\t\terrors.push(`Missing required field: package.${field}`);\n\t\t}\n\t}\n}\n\nfunction checkExpectedValues(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tif (!config?.expectedValues) {\n\t\treturn;\n\t}\n\tfor (const [field, expected] of Object.entries(config.expectedValues)) {\n\t\tconst actual = pkg[field];\n\t\tif (actual === undefined) {\n\t\t\terrors.push(`Missing required field: package.${field}`);\n\t\t} else if (String(actual) !== expected) {\n\t\t\terrors.push(\n\t\t\t\t`Expected package.${field} = \"${expected}\", got \"${String(actual)}\"`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction checkRustVersion(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tif (config?.requireRustVersion && pkg[\"rust-version\"] === undefined) {\n\t\terrors.push(\n\t\t\t\"Missing package.rust-version (MSRV). Set the minimum supported Rust version.\",\n\t\t);\n\t}\n}\n\nfunction checkMinimumEdition(\n\tpkg: Record<string, unknown>,\n\tconfig: CargoTomlRequiredConfig | undefined,\n\terrors: string[],\n): void {\n\tif (!config?.minimumEdition) {\n\t\treturn;\n\t}\n\tconst edition = pkg.edition as string | undefined;\n\tif (edition === undefined) {\n\t\terrors.push(\"Missing package.edition field.\");\n\t} else if (!VALID_EDITIONS.includes(edition)) {\n\t\terrors.push(\n\t\t\t`Invalid edition \"${edition}\". Must be one of: ${VALID_EDITIONS.join(\", \")}`,\n\t\t);\n\t} else if (edition < config.minimumEdition) {\n\t\terrors.push(\n\t\t\t`Edition \"${edition}\" is below minimum \"${config.minimumEdition}\".`,\n\t\t);\n\t}\n}\n\n/**\n * A policy that enforces required fields exist in Cargo.toml [package] section.\n *\n * @public\n */\nexport const CargoTomlRequired = defineCargoPolicy({\n\tname: \"CargoTomlRequired\",\n\tdescription:\n\t\t\"Ensures Cargo.toml files contain required fields in the [package] section.\",\n\thandler: async (toml: CargoToml, { config }) => {\n\t\tconst pkg = toml.package as Record<string, unknown> | undefined;\n\t\tif (!pkg) {\n\t\t\t// Workspace root Cargo.toml may not have [package]\n\t\t\tif (toml.workspace !== undefined) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn [{ message: \"Missing [package] section in Cargo.toml\" }];\n\t\t}\n\n\t\tconst errors: string[] = [];\n\t\tcheckRequiredFields(pkg, config, errors);\n\t\tcheckExpectedValues(pkg, config, errors);\n\t\tcheckRustVersion(pkg, config, errors);\n\t\tcheckMinimumEdition(pkg, config, errors);\n\n\t\tif (errors.length > 0) {\n\t\t\treturn errors.map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\tmanualFix:\n\t\t\t\t\t\"Add the missing fields to your Cargo.toml [package] section.\",\n\t\t\t}));\n\t\t}\n\t\treturn [];\n\t},\n}) satisfies FilePolicyDefinition<CargoTomlRequiredConfig>;\n"]}
@@ -1,8 +1,8 @@
1
- import type { PolicyShape } from "../policy.js";
1
+ import type { FilePolicyDefinition } from "../policy.js";
2
2
  /**
3
3
  * Configuration for the CargoTomlSorted policy.
4
4
  *
5
- * @alpha
5
+ * @public
6
6
  */
7
7
  export interface CargoTomlSortedConfig {
8
8
  /**
@@ -14,7 +14,7 @@ export interface CargoTomlSortedConfig {
14
14
  /**
15
15
  * A policy that ensures dependency sections in Cargo.toml are sorted alphabetically.
16
16
  *
17
- * @alpha
17
+ * @public
18
18
  */
19
- export declare const CargoTomlSorted: PolicyShape<CargoTomlSortedConfig>;
19
+ export declare const CargoTomlSorted: FilePolicyDefinition<CargoTomlSortedConfig>;
20
20
  //# sourceMappingURL=CargoTomlSorted.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoTomlSorted.d.ts","sourceRoot":"","sources":["../../src/policies/CargoTomlSorted.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAmID;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,qBAAqB,CAwD5D,CAAC"}
1
+ {"version":3,"file":"CargoTomlSorted.d.ts","sourceRoot":"","sources":["../../src/policies/CargoTomlSorted.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMzD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AA8JD;;;;GAIG;AACH,eAAO,MAAM,eAAe,6CAwD4B,CAAC"}
@@ -113,7 +113,7 @@ function sortTomlSections(content, sectionsToSort) {
113
113
  /**
114
114
  * A policy that ensures dependency sections in Cargo.toml are sorted alphabetically.
115
115
  *
116
- * @alpha
116
+ * @public
117
117
  */
118
118
  export const CargoTomlSorted = defineCargoPolicy({
119
119
  name: "CargoTomlSorted",
@@ -131,7 +131,7 @@ export const CargoTomlSorted = defineCargoPolicy({
131
131
  }
132
132
  }
133
133
  if (unsortedSections.length === 0) {
134
- return true;
134
+ return [];
135
135
  }
136
136
  if (shouldResolve) {
137
137
  try {
@@ -140,25 +140,29 @@ export const CargoTomlSorted = defineCargoPolicy({
140
140
  const content = await readFile(filePath, "utf-8");
141
141
  const sorted = sortTomlSections(content, unsortedSections);
142
142
  await writeFile(filePath, sorted);
143
- return {
144
- error: `Unsorted sections: [${unsortedSections.join("], [")}]`,
145
- fixable: true,
146
- fixed: true,
147
- };
143
+ return [
144
+ {
145
+ message: `Unsorted sections: [${unsortedSections.join("], [")}]`,
146
+ fixStatus: "fixed",
147
+ },
148
+ ];
148
149
  }
149
150
  catch {
150
- return {
151
- error: `Unsorted sections: [${unsortedSections.join("], [")}]. Auto-fix failed.`,
152
- fixable: true,
153
- fixed: false,
154
- };
151
+ return [
152
+ {
153
+ message: `Unsorted sections: [${unsortedSections.join("], [")}]. Auto-fix failed.`,
154
+ fixStatus: "failed",
155
+ },
156
+ ];
155
157
  }
156
158
  }
157
- return {
158
- error: `Unsorted sections: [${unsortedSections.join("], [")}]`,
159
- fixable: true,
160
- manualFix: "Sort the dependency keys alphabetically in the listed sections.",
161
- };
159
+ return [
160
+ {
161
+ message: `Unsorted sections: [${unsortedSections.join("], [")}]`,
162
+ fixStatus: "available",
163
+ manualFix: "Sort the dependency keys alphabetically in the listed sections.",
164
+ },
165
+ ];
162
166
  },
163
167
  });
164
168
  //# sourceMappingURL=CargoTomlSorted.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CargoTomlSorted.js","sourceRoot":"","sources":["../../src/policies/CargoTomlSorted.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAehD,MAAM,uBAAuB,GAAG;IAC/B,cAAc;IACd,kBAAkB;IAClB,oBAAoB;CACpB,CAAC;AAEF,SAAS,QAAQ,CAAC,IAAc;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7B,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,GAAG,QAAQ,EAAE,CAAC;YAC3E,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACjD,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,eAAe,GAAG,YAAY,CAAC;AAErC;;GAEG;AACH,SAAS,gBAAgB,CACxB,SAAiB,EACjB,OAA2C,EAC3C,YAA0D;IAE1D,sCAAsC;IACtC,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,IAAI,YAAY,EAAE,CAAC;YAClB,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACP,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,YAAY,CAAC;IACrB,CAAC;IACD,mBAAmB;IACnB,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAClD,IAAI,QAAQ,EAAE,CAAC;QACd,IAAI,YAAY,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QAClB,sCAAsC;QACtC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,YAAY,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAC7B,KAAe,EACf,UAAkB;IAElB,MAAM,OAAO,GAAuC,EAAE,CAAC;IACvD,IAAI,YAA0D,CAAC;IAC/D,IAAI,CAAC,GAAG,UAAU,CAAC;IAEnB,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM;QACP,CAAC;QACD,uBAAuB;QACvB,IAAI,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACxC,MAAM;QACP,CAAC;QACD,wCAAwC;QACxC,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC7B,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,YAAY,GAAG,gBAAgB,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAClE,CAAC,EAAE,CAAC;IACL,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAe,EAAE,cAAwB;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM;QACP,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAEtD,IAAI,YAAY,EAAE,CAAC;YAClB,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClB,CAAC,EAAE,CAAC;gBAEJ,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,qBAAqB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC7B,CAAC;gBACD,CAAC,GAAG,SAAS,CAAC;gBACd,SAAS;YACV,CAAC;QACF,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC,EAAE,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAC3B,iBAAiB,CAAC;IACjB,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACV,sEAAsE;IACvE,OAAO,EAAE,KAAK,EACb,IAAe,EACf,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAC7C,EAAE;QACH,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,uBAAuB,CAAC;QAC7D,MAAM,gBAAgB,GAAa,EAAE,CAAC;QAEtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAEpB,CAAC;YACb,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrB,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;YACF,CAAC;QACF,CAAC;QAED,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACb,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC;gBACJ,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;gBACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACrC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAClD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;gBAC3D,MAAM,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAClC,OAAO;oBACN,KAAK,EAAE,uBAAuB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;oBAC9D,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,IAAI;iBACX,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO;oBACN,KAAK,EAAE,uBAAuB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB;oBAChF,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,KAAK;iBACZ,CAAC;YACH,CAAC;QACF,CAAC;QAED,OAAO;YACN,KAAK,EAAE,uBAAuB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;YAC9D,OAAO,EAAE,IAAI;YACb,SAAS,EACR,iEAAiE;SAClE,CAAC;IACH,CAAC;CACD,CAAC,CAAC","sourcesContent":["import { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"pathe\";\nimport type { PolicyShape } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoTomlSorted policy.\n *\n * @alpha\n */\nexport interface CargoTomlSortedConfig {\n\t/**\n\t * Sections whose keys should be sorted alphabetically.\n\t * @defaultValue [\"dependencies\", \"dev-dependencies\", \"build-dependencies\"]\n\t */\n\tsections?: string[];\n}\n\nconst DEFAULT_SORTED_SECTIONS = [\n\t\"dependencies\",\n\t\"dev-dependencies\",\n\t\"build-dependencies\",\n];\n\nfunction isSorted(keys: string[]): boolean {\n\tfor (let i = 1; i < keys.length; i++) {\n\t\tconst current = keys[i];\n\t\tconst previous = keys[i - 1];\n\t\tif (current !== undefined && previous !== undefined && current < previous) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nconst SECTION_HEADER_REGEX = /^\\[([^\\]]+)\\]\\s*$/;\nconst NEXT_SECTION_REGEX = /^\\[/;\nconst KEY_VALUE_REGEX = /^(\\S+)\\s*=/;\n\n/**\n * Process a single line in a dependency section, updating entries and current state.\n */\nfunction processEntryLine(\n\tentryLine: string,\n\tentries: { key: string; lines: string[] }[],\n\tcurrentEntry: { key: string; lines: string[] } | undefined,\n): { key: string; lines: string[] } | undefined {\n\t// Comment line - attach to next entry\n\tif (entryLine.trim().startsWith(\"#\")) {\n\t\tif (currentEntry) {\n\t\t\tcurrentEntry.lines.push(entryLine);\n\t\t} else {\n\t\t\treturn { key: \"\", lines: [entryLine] };\n\t\t}\n\t\treturn currentEntry;\n\t}\n\t// Key = value line\n\tconst keyMatch = entryLine.match(KEY_VALUE_REGEX);\n\tif (keyMatch) {\n\t\tif (currentEntry) {\n\t\t\tentries.push(currentEntry);\n\t\t}\n\t\tconst key = keyMatch[1] ?? \"\";\n\t\treturn { key, lines: [entryLine] };\n\t}\n\tif (currentEntry) {\n\t\t// Continuation line (multiline value)\n\t\tcurrentEntry.lines.push(entryLine);\n\t}\n\treturn currentEntry;\n}\n\n/**\n * Collect sorted entries from a TOML dependency section.\n */\nfunction collectAndSortEntries(\n\tlines: string[],\n\tstartIndex: number,\n): { entries: { key: string; lines: string[] }[]; nextIndex: number } {\n\tconst entries: { key: string; lines: string[] }[] = [];\n\tlet currentEntry: { key: string; lines: string[] } | undefined;\n\tlet i = startIndex;\n\n\twhile (i < lines.length) {\n\t\tconst entryLine = lines[i];\n\t\tif (entryLine === undefined) {\n\t\t\tbreak;\n\t\t}\n\t\t// Stop at next section\n\t\tif (NEXT_SECTION_REGEX.test(entryLine)) {\n\t\t\tbreak;\n\t\t}\n\t\t// Skip pure blank lines between entries\n\t\tif (entryLine.trim() === \"\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrentEntry = processEntryLine(entryLine, entries, currentEntry);\n\t\ti++;\n\t}\n\tif (currentEntry) {\n\t\tentries.push(currentEntry);\n\t}\n\n\tentries.sort((a, b) => a.key.localeCompare(b.key));\n\treturn { entries, nextIndex: i };\n}\n\n/**\n * Rebuild TOML content with sorted dependency sections.\n * Uses line-based manipulation to preserve formatting and comments.\n */\nfunction sortTomlSections(content: string, sectionsToSort: string[]): string {\n\tconst lines = content.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet i = 0;\n\n\twhile (i < lines.length) {\n\t\tconst line = lines[i];\n\t\tif (line === undefined) {\n\t\t\tbreak;\n\t\t}\n\t\tconst sectionMatch = line.match(SECTION_HEADER_REGEX);\n\n\t\tif (sectionMatch) {\n\t\t\tconst sectionName = sectionMatch[1] ?? \"\";\n\t\t\tif (sectionsToSort.includes(sectionName)) {\n\t\t\t\tresult.push(line);\n\t\t\t\ti++;\n\n\t\t\t\tconst { entries, nextIndex } = collectAndSortEntries(lines, i);\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tresult.push(...entry.lines);\n\t\t\t\t}\n\t\t\t\ti = nextIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tresult.push(line);\n\t\ti++;\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * A policy that ensures dependency sections in Cargo.toml are sorted alphabetically.\n *\n * @alpha\n */\nexport const CargoTomlSorted: PolicyShape<CargoTomlSortedConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"CargoTomlSorted\",\n\t\tdescription:\n\t\t\t\"Ensures dependency sections in Cargo.toml are sorted alphabetically.\",\n\t\thandler: async (\n\t\t\ttoml: CargoToml,\n\t\t\t{ file, root, resolve: shouldResolve, config },\n\t\t) => {\n\t\t\tconst sections = config?.sections ?? DEFAULT_SORTED_SECTIONS;\n\t\t\tconst unsortedSections: string[] = [];\n\n\t\t\tfor (const section of sections) {\n\t\t\t\tconst sectionData = toml[section] as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined;\n\t\t\t\tif (sectionData !== undefined) {\n\t\t\t\t\tconst keys = Object.keys(sectionData);\n\t\t\t\t\tif (!isSorted(keys)) {\n\t\t\t\t\t\tunsortedSections.push(section);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unsortedSections.length === 0) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (shouldResolve) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { readFile } = await import(\"node:fs/promises\");\n\t\t\t\t\tconst filePath = resolve(root, file);\n\t\t\t\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\t\t\t\tconst sorted = sortTomlSections(content, unsortedSections);\n\t\t\t\t\tawait writeFile(filePath, sorted);\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: `Unsorted sections: [${unsortedSections.join(\"], [\")}]`,\n\t\t\t\t\t\tfixable: true,\n\t\t\t\t\t\tfixed: true,\n\t\t\t\t\t};\n\t\t\t\t} catch {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: `Unsorted sections: [${unsortedSections.join(\"], [\")}]. Auto-fix failed.`,\n\t\t\t\t\t\tfixable: true,\n\t\t\t\t\t\tfixed: false,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\terror: `Unsorted sections: [${unsortedSections.join(\"], [\")}]`,\n\t\t\t\tfixable: true,\n\t\t\t\tmanualFix:\n\t\t\t\t\t\"Sort the dependency keys alphabetically in the listed sections.\",\n\t\t\t};\n\t\t},\n\t});\n"]}
1
+ {"version":3,"file":"CargoTomlSorted.js","sourceRoot":"","sources":["../../src/policies/CargoTomlSorted.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAehD,MAAM,uBAAuB,GAAG;IAC/B,cAAc;IACd,kBAAkB;IAClB,oBAAoB;CACpB,CAAC;AAEF,SAAS,QAAQ,CAAC,IAAc;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7B,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,GAAG,QAAQ,EAAE,CAAC;YAC3E,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACjD,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,eAAe,GAAG,YAAY,CAAC;AAErC;;GAEG;AACH,SAAS,gBAAgB,CACxB,SAAiB,EACjB,OAGG,EACH,YAKY;IAOZ,sCAAsC;IACtC,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,IAAI,YAAY,EAAE,CAAC;YAClB,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACP,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,YAAY,CAAC;IACrB,CAAC;IACD,mBAAmB;IACnB,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAClD,IAAI,QAAQ,EAAE,CAAC;QACd,IAAI,YAAY,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QAClB,sCAAsC;QACtC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,YAAY,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAC7B,KAAe,EACf,UAAkB;IAQlB,MAAM,OAAO,GAGP,EAAE,CAAC;IACT,IAAI,YAKQ,CAAC;IACb,IAAI,CAAC,GAAG,UAAU,CAAC;IAEnB,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM;QACP,CAAC;QACD,uBAAuB;QACvB,IAAI,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACxC,MAAM;QACP,CAAC;QACD,wCAAwC;QACxC,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC7B,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,YAAY,GAAG,gBAAgB,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAClE,CAAC,EAAE,CAAC;IACL,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAe,EAAE,cAAwB;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM;QACP,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAEtD,IAAI,YAAY,EAAE,CAAC;YAClB,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClB,CAAC,EAAE,CAAC;gBAEJ,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,qBAAqB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC7B,CAAC;gBACD,CAAC,GAAG,SAAS,CAAC;gBACd,SAAS;YACV,CAAC;QACF,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC,EAAE,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC;IAChD,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACV,sEAAsE;IACvE,OAAO,EAAE,KAAK,EACb,IAAe,EACf,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAC7C,EAAE;QACH,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,uBAAuB,CAAC;QAC7D,MAAM,gBAAgB,GAAa,EAAE,CAAC;QAEtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAwC,CAAC;YACzE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrB,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;YACF,CAAC;QACF,CAAC;QAED,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC;QACX,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC;gBACJ,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;gBACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACrC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAClD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;gBAC3D,MAAM,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAClC,OAAO;oBACN;wBACC,OAAO,EAAE,uBAAuB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;wBAChE,SAAS,EAAE,OAAO;qBAClB;iBACD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO;oBACN;wBACC,OAAO,EAAE,uBAAuB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB;wBAClF,SAAS,EAAE,QAAQ;qBACnB;iBACD,CAAC;YACH,CAAC;QACF,CAAC;QACD,OAAO;YACN;gBACC,OAAO,EAAE,uBAAuB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;gBAChE,SAAS,EAAE,WAAW;gBACtB,SAAS,EACR,iEAAiE;aAClE;SACD,CAAC;IACH,CAAC;CACD,CAAuD,CAAC","sourcesContent":["import { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"pathe\";\nimport type { FilePolicyDefinition } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the CargoTomlSorted policy.\n *\n * @public\n */\nexport interface CargoTomlSortedConfig {\n\t/**\n\t * Sections whose keys should be sorted alphabetically.\n\t * @defaultValue [\"dependencies\", \"dev-dependencies\", \"build-dependencies\"]\n\t */\n\tsections?: string[];\n}\n\nconst DEFAULT_SORTED_SECTIONS = [\n\t\"dependencies\",\n\t\"dev-dependencies\",\n\t\"build-dependencies\",\n];\n\nfunction isSorted(keys: string[]): boolean {\n\tfor (let i = 1; i < keys.length; i++) {\n\t\tconst current = keys[i];\n\t\tconst previous = keys[i - 1];\n\t\tif (current !== undefined && previous !== undefined && current < previous) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nconst SECTION_HEADER_REGEX = /^\\[([^\\]]+)\\]\\s*$/;\nconst NEXT_SECTION_REGEX = /^\\[/;\nconst KEY_VALUE_REGEX = /^(\\S+)\\s*=/;\n\n/**\n * Process a single line in a dependency section, updating entries and current state.\n */\nfunction processEntryLine(\n\tentryLine: string,\n\tentries: {\n\t\tkey: string;\n\t\tlines: string[];\n\t}[],\n\tcurrentEntry:\n\t\t| {\n\t\t\t\tkey: string;\n\t\t\t\tlines: string[];\n\t\t }\n\t\t| undefined,\n):\n\t| {\n\t\t\tkey: string;\n\t\t\tlines: string[];\n\t }\n\t| undefined {\n\t// Comment line - attach to next entry\n\tif (entryLine.trim().startsWith(\"#\")) {\n\t\tif (currentEntry) {\n\t\t\tcurrentEntry.lines.push(entryLine);\n\t\t} else {\n\t\t\treturn { key: \"\", lines: [entryLine] };\n\t\t}\n\t\treturn currentEntry;\n\t}\n\t// Key = value line\n\tconst keyMatch = entryLine.match(KEY_VALUE_REGEX);\n\tif (keyMatch) {\n\t\tif (currentEntry) {\n\t\t\tentries.push(currentEntry);\n\t\t}\n\t\tconst key = keyMatch[1] ?? \"\";\n\t\treturn { key, lines: [entryLine] };\n\t}\n\tif (currentEntry) {\n\t\t// Continuation line (multiline value)\n\t\tcurrentEntry.lines.push(entryLine);\n\t}\n\treturn currentEntry;\n}\n\n/**\n * Collect sorted entries from a TOML dependency section.\n */\nfunction collectAndSortEntries(\n\tlines: string[],\n\tstartIndex: number,\n): {\n\tentries: {\n\t\tkey: string;\n\t\tlines: string[];\n\t}[];\n\tnextIndex: number;\n} {\n\tconst entries: {\n\t\tkey: string;\n\t\tlines: string[];\n\t}[] = [];\n\tlet currentEntry:\n\t\t| {\n\t\t\t\tkey: string;\n\t\t\t\tlines: string[];\n\t\t }\n\t\t| undefined;\n\tlet i = startIndex;\n\n\twhile (i < lines.length) {\n\t\tconst entryLine = lines[i];\n\t\tif (entryLine === undefined) {\n\t\t\tbreak;\n\t\t}\n\t\t// Stop at next section\n\t\tif (NEXT_SECTION_REGEX.test(entryLine)) {\n\t\t\tbreak;\n\t\t}\n\t\t// Skip pure blank lines between entries\n\t\tif (entryLine.trim() === \"\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrentEntry = processEntryLine(entryLine, entries, currentEntry);\n\t\ti++;\n\t}\n\tif (currentEntry) {\n\t\tentries.push(currentEntry);\n\t}\n\n\tentries.sort((a, b) => a.key.localeCompare(b.key));\n\treturn { entries, nextIndex: i };\n}\n\n/**\n * Rebuild TOML content with sorted dependency sections.\n * Uses line-based manipulation to preserve formatting and comments.\n */\nfunction sortTomlSections(content: string, sectionsToSort: string[]): string {\n\tconst lines = content.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet i = 0;\n\n\twhile (i < lines.length) {\n\t\tconst line = lines[i];\n\t\tif (line === undefined) {\n\t\t\tbreak;\n\t\t}\n\t\tconst sectionMatch = line.match(SECTION_HEADER_REGEX);\n\n\t\tif (sectionMatch) {\n\t\t\tconst sectionName = sectionMatch[1] ?? \"\";\n\t\t\tif (sectionsToSort.includes(sectionName)) {\n\t\t\t\tresult.push(line);\n\t\t\t\ti++;\n\n\t\t\t\tconst { entries, nextIndex } = collectAndSortEntries(lines, i);\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tresult.push(...entry.lines);\n\t\t\t\t}\n\t\t\t\ti = nextIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tresult.push(line);\n\t\ti++;\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * A policy that ensures dependency sections in Cargo.toml are sorted alphabetically.\n *\n * @public\n */\nexport const CargoTomlSorted = defineCargoPolicy({\n\tname: \"CargoTomlSorted\",\n\tdescription:\n\t\t\"Ensures dependency sections in Cargo.toml are sorted alphabetically.\",\n\thandler: async (\n\t\ttoml: CargoToml,\n\t\t{ file, root, resolve: shouldResolve, config },\n\t) => {\n\t\tconst sections = config?.sections ?? DEFAULT_SORTED_SECTIONS;\n\t\tconst unsortedSections: string[] = [];\n\n\t\tfor (const section of sections) {\n\t\t\tconst sectionData = toml[section] as Record<string, unknown> | undefined;\n\t\t\tif (sectionData !== undefined) {\n\t\t\t\tconst keys = Object.keys(sectionData);\n\t\t\t\tif (!isSorted(keys)) {\n\t\t\t\t\tunsortedSections.push(section);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (unsortedSections.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (shouldResolve) {\n\t\t\ttry {\n\t\t\t\tconst { readFile } = await import(\"node:fs/promises\");\n\t\t\t\tconst filePath = resolve(root, file);\n\t\t\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\t\t\tconst sorted = sortTomlSections(content, unsortedSections);\n\t\t\t\tawait writeFile(filePath, sorted);\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage: `Unsorted sections: [${unsortedSections.join(\"], [\")}]`,\n\t\t\t\t\t\tfixStatus: \"fixed\",\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t} catch {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage: `Unsorted sections: [${unsortedSections.join(\"], [\")}]. Auto-fix failed.`,\n\t\t\t\t\t\tfixStatus: \"failed\",\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\t\treturn [\n\t\t\t{\n\t\t\t\tmessage: `Unsorted sections: [${unsortedSections.join(\"], [\")}]`,\n\t\t\t\tfixStatus: \"available\",\n\t\t\t\tmanualFix:\n\t\t\t\t\t\"Sort the dependency keys alphabetically in the listed sections.\",\n\t\t\t},\n\t\t];\n\t},\n}) satisfies FilePolicyDefinition<CargoTomlSortedConfig>;\n"]}
@@ -12,13 +12,13 @@
12
12
  * { clean: "rimraf dist" }
13
13
  * ```
14
14
  *
15
- * @alpha
15
+ * @public
16
16
  */
17
17
  export type ConditionalScriptEntry = string | Record<string, string>;
18
18
  /**
19
19
  * Configuration for a conditional script requirement.
20
20
  *
21
- * @alpha
21
+ * @public
22
22
  */
23
23
  export interface ConditionalScriptRule {
24
24
  /**
@@ -45,7 +45,7 @@ export interface ConditionalScriptRule {
45
45
  /**
46
46
  * Configuration for the ConditionalScripts policy.
47
47
  *
48
- * @alpha
48
+ * @public
49
49
  */
50
50
  export interface ConditionalScriptsConfig {
51
51
  /**
@@ -75,20 +75,22 @@ export interface ConditionalScriptsConfig {
75
75
  *
76
76
  * @example
77
77
  * ```typescript
78
- * import { policy } from "repopo";
78
+ * import { makePolicy } from "repopo";
79
79
  * import { ConditionalScripts } from "repopo/policies";
80
80
  *
81
- * policy(ConditionalScripts, {
81
+ * makePolicy(ConditionalScripts, { config: {
82
82
  * rules: [
83
83
  * // If "build" exists, "clean" must also exist (with auto-fix default)
84
84
  * { ifPresent: "build", requires: [{ clean: "rimraf dist" }] },
85
85
  * // If "test" exists, "test:coverage" must also exist (no auto-fix)
86
86
  * { ifPresent: "test", requires: ["test:coverage"] },
87
87
  * ],
88
- * })
88
+ * } })
89
89
  * ```
90
90
  *
91
- * @alpha
91
+ * @public
92
92
  */
93
- export declare const ConditionalScripts: import("../policy.js").PolicyShape<ConditionalScriptsConfig | undefined>;
93
+ export declare const ConditionalScripts: import("../policy.js").FilePolicyDefinition<ConditionalScriptsConfig | undefined> & {
94
+ requiresConfig: true;
95
+ };
94
96
  //# sourceMappingURL=ConditionalScripts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConditionalScripts.d.ts","sourceRoot":"","sources":["../../src/policies/ConditionalScripts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;;;;;;;;;;;;OAcG;IACH,KAAK,EAAE,qBAAqB,EAAE,CAAC;CAC/B;AAiHD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,kBAAkB,0EAuE7B,CAAC"}
1
+ {"version":3,"file":"ConditionalScripts.d.ts","sourceRoot":"","sources":["../../src/policies/ConditionalScripts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;;;;;;;;;;;;OAcG;IACH,KAAK,EAAE,qBAAqB,EAAE,CAAC;CAC/B;AA0HD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,kBAAkB;;CAsE7B,CAAC"}