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
@@ -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 PublicApiDocumented policy.
4
4
  *
5
- * @alpha
5
+ * @public
6
6
  */
7
7
  export interface PublicApiDocumentedConfig {
8
8
  /**
@@ -15,7 +15,7 @@ export interface PublicApiDocumentedConfig {
15
15
  * A policy that ensures public API documentation is enforced in Rust crates
16
16
  * via the `missing_docs` lint configured in Cargo.toml.
17
17
  *
18
- * @alpha
18
+ * @public
19
19
  */
20
- export declare const PublicApiDocumented: PolicyShape<PublicApiDocumentedConfig>;
20
+ export declare const PublicApiDocumented: FilePolicyDefinition<PublicApiDocumentedConfig>;
21
21
  //# sourceMappingURL=PublicApiDocumented.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PublicApiDocumented.d.ts","sourceRoot":"","sources":["../../src/policies/PublicApiDocumented.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,yBAAyB,CAsCpE,CAAC"}
1
+ {"version":3,"file":"PublicApiDocumented.d.ts","sourceRoot":"","sources":["../../src/policies/PublicApiDocumented.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMzD;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,iDAoC4B,CAAC"}
@@ -3,7 +3,7 @@ import { defineCargoPolicy, } from "../policyDefiners/defineCargoPolicy.js";
3
3
  * A policy that ensures public API documentation is enforced in Rust crates
4
4
  * via the `missing_docs` lint configured in Cargo.toml.
5
5
  *
6
- * @alpha
6
+ * @public
7
7
  */
8
8
  export const PublicApiDocumented = defineCargoPolicy({
9
9
  name: "PublicApiDocumented",
@@ -11,7 +11,7 @@ export const PublicApiDocumented = defineCargoPolicy({
11
11
  handler: async (toml, { config }) => {
12
12
  // Skip workspace root
13
13
  if (toml.workspace !== undefined && toml.package === undefined) {
14
- return true;
14
+ return [];
15
15
  }
16
16
  const checkCargoLints = config?.checkCargoLints ?? true;
17
17
  if (checkCargoLints) {
@@ -22,15 +22,17 @@ export const PublicApiDocumented = defineCargoPolicy({
22
22
  if (missingDocs === "deny" ||
23
23
  missingDocs === "warn" ||
24
24
  missingDocs === "forbid") {
25
- return true;
25
+ return [];
26
26
  }
27
27
  }
28
- return {
29
- error: 'missing_docs lint is not configured. Set [lints.rust] missing_docs = "warn" or "deny" in Cargo.toml.',
30
- manualFix: 'Add to Cargo.toml:\n[lints.rust]\nmissing_docs = "warn"',
31
- };
28
+ return [
29
+ {
30
+ message: 'missing_docs lint is not configured. Set [lints.rust] missing_docs = "warn" or "deny" in Cargo.toml.',
31
+ manualFix: 'Add to Cargo.toml:\n[lints.rust]\nmissing_docs = "warn"',
32
+ },
33
+ ];
32
34
  }
33
- return true;
35
+ return [];
34
36
  },
35
37
  });
36
38
  //# sourceMappingURL=PublicApiDocumented.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PublicApiDocumented.js","sourceRoot":"","sources":["../../src/policies/PublicApiDocumented.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAehD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAC/B,iBAAiB,CAAC;IACjB,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EACV,gGAAgG;IACjG,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,sBAAsB;QACtB,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,EAAE,eAAe,IAAI,IAAI,CAAC;QAExD,IAAI,eAAe,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;YAChE,MAAM,SAAS,GAAG,KAAK,EAAE,IAA2C,CAAC;YAErE,IAAI,SAAS,EAAE,CAAC;gBACf,MAAM,WAAW,GAChB,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC;gBACrD,IACC,WAAW,KAAK,MAAM;oBACtB,WAAW,KAAK,MAAM;oBACtB,WAAW,KAAK,QAAQ,EACvB,CAAC;oBACF,OAAO,IAAI,CAAC;gBACb,CAAC;YACF,CAAC;YAED,OAAO;gBACN,KAAK,EACJ,sGAAsG;gBACvG,SAAS,EAAE,yDAAyD;aACpE,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 PublicApiDocumented policy.\n *\n * @alpha\n */\nexport interface PublicApiDocumentedConfig {\n\t/**\n\t * If true, check for `#![deny(missing_docs)]` directive via [lints.rust] in Cargo.toml.\n\t * @defaultValue true\n\t */\n\tcheckCargoLints?: boolean;\n}\n\n/**\n * A policy that ensures public API documentation is enforced in Rust crates\n * via the `missing_docs` lint configured in Cargo.toml.\n *\n * @alpha\n */\nexport const PublicApiDocumented: PolicyShape<PublicApiDocumentedConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"PublicApiDocumented\",\n\t\tdescription:\n\t\t\t\"Ensures the missing_docs lint is configured in Cargo.toml to enforce public API documentation.\",\n\t\thandler: async (toml: CargoToml, { config }) => {\n\t\t\t// Skip workspace root\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 checkCargoLints = config?.checkCargoLints ?? true;\n\n\t\t\tif (checkCargoLints) {\n\t\t\t\tconst lints = toml.lints as Record<string, unknown> | undefined;\n\t\t\t\tconst rustLints = lints?.rust as Record<string, unknown> | undefined;\n\n\t\t\t\tif (rustLints) {\n\t\t\t\t\tconst missingDocs =\n\t\t\t\t\t\trustLints.missing_docs ?? rustLints[\"missing-docs\"];\n\t\t\t\t\tif (\n\t\t\t\t\t\tmissingDocs === \"deny\" ||\n\t\t\t\t\t\tmissingDocs === \"warn\" ||\n\t\t\t\t\t\tmissingDocs === \"forbid\"\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\terror:\n\t\t\t\t\t\t'missing_docs lint is not configured. Set [lints.rust] missing_docs = \"warn\" or \"deny\" in Cargo.toml.',\n\t\t\t\t\tmanualFix: 'Add to Cargo.toml:\\n[lints.rust]\\nmissing_docs = \"warn\"',\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":"PublicApiDocumented.js","sourceRoot":"","sources":["../../src/policies/PublicApiDocumented.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,iBAAiB,GACjB,MAAM,wCAAwC,CAAC;AAehD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;IACpD,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EACV,gGAAgG;IACjG,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,sBAAsB;QACtB,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,EAAE,CAAC;QACX,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,EAAE,eAAe,IAAI,IAAI,CAAC;QAExD,IAAI,eAAe,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;YAChE,MAAM,SAAS,GAAG,KAAK,EAAE,IAA2C,CAAC;YAErE,IAAI,SAAS,EAAE,CAAC;gBACf,MAAM,WAAW,GAAG,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC;gBACxE,IACC,WAAW,KAAK,MAAM;oBACtB,WAAW,KAAK,MAAM;oBACtB,WAAW,KAAK,QAAQ,EACvB,CAAC;oBACF,OAAO,EAAE,CAAC;gBACX,CAAC;YACF,CAAC;YACD,OAAO;gBACN;oBACC,OAAO,EACN,sGAAsG;oBACvG,SAAS,EAAE,yDAAyD;iBACpE;aACD,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;CACD,CAA2D,CAAC","sourcesContent":["import type { FilePolicyDefinition } from \"../policy.js\";\nimport {\n\ttype CargoToml,\n\tdefineCargoPolicy,\n} from \"../policyDefiners/defineCargoPolicy.js\";\n\n/**\n * Configuration for the PublicApiDocumented policy.\n *\n * @public\n */\nexport interface PublicApiDocumentedConfig {\n\t/**\n\t * If true, check for `#![deny(missing_docs)]` directive via [lints.rust] in Cargo.toml.\n\t * @defaultValue true\n\t */\n\tcheckCargoLints?: boolean;\n}\n\n/**\n * A policy that ensures public API documentation is enforced in Rust crates\n * via the `missing_docs` lint configured in Cargo.toml.\n *\n * @public\n */\nexport const PublicApiDocumented = defineCargoPolicy({\n\tname: \"PublicApiDocumented\",\n\tdescription:\n\t\t\"Ensures the missing_docs lint is configured in Cargo.toml to enforce public API documentation.\",\n\thandler: async (toml: CargoToml, { config }) => {\n\t\t// Skip workspace root\n\t\tif (toml.workspace !== undefined && toml.package === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst checkCargoLints = config?.checkCargoLints ?? true;\n\n\t\tif (checkCargoLints) {\n\t\t\tconst lints = toml.lints as Record<string, unknown> | undefined;\n\t\t\tconst rustLints = lints?.rust as Record<string, unknown> | undefined;\n\n\t\t\tif (rustLints) {\n\t\t\t\tconst missingDocs = rustLints.missing_docs ?? rustLints[\"missing-docs\"];\n\t\t\t\tif (\n\t\t\t\t\tmissingDocs === \"deny\" ||\n\t\t\t\t\tmissingDocs === \"warn\" ||\n\t\t\t\t\tmissingDocs === \"forbid\"\n\t\t\t\t) {\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'missing_docs lint is not configured. Set [lints.rust] missing_docs = \"warn\" or \"deny\" in Cargo.toml.',\n\t\t\t\t\tmanualFix: 'Add to Cargo.toml:\\n[lints.rust]\\nmissing_docs = \"warn\"',\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\treturn [];\n\t},\n}) satisfies FilePolicyDefinition<PublicApiDocumentedConfig>;\n"]}
@@ -1,8 +1,8 @@
1
- import type { PolicyDefinition } from "../policy.js";
1
+ import type { PolicyFinding } from "../policy.js";
2
2
  /**
3
3
  * Policy settings for the RequiredGitignorePatterns repo policy.
4
4
  *
5
- * @alpha
5
+ * @public
6
6
  */
7
7
  export interface RequiredGitignorePatternsSettings {
8
8
  /**
@@ -10,7 +10,9 @@ export interface RequiredGitignorePatternsSettings {
10
10
  * Each pattern can be a string or an object with pattern and comment.
11
11
  */
12
12
  patterns: Array<string | {
13
+ /** Literal .gitignore entry to require. */
13
14
  pattern: string;
15
+ /** Comment inserted before the entry when fixing the file. */
14
16
  comment?: string;
15
17
  }>;
16
18
  }
@@ -18,7 +20,12 @@ export interface RequiredGitignorePatternsSettings {
18
20
  * A repo policy that ensures .gitignore contains required patterns to prevent
19
21
  * committing sensitive files, dependencies, and build artifacts.
20
22
  *
21
- * @alpha
23
+ * @public
22
24
  */
23
- export declare const RequiredGitignorePatterns: PolicyDefinition<RequiredGitignorePatternsSettings>;
25
+ export declare const RequiredGitignorePatterns: {
26
+ name: string;
27
+ description: string;
28
+ match: RegExp;
29
+ handler: ({ file, root, resolve, config }: import("../policy.js").PolicyArgs<RequiredGitignorePatternsSettings>) => Promise<PolicyFinding[]>;
30
+ };
24
31
  //# sourceMappingURL=RequiredGitignorePatterns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RequiredGitignorePatterns.d.ts","sourceRoot":"","sources":["../../src/policies/RequiredGitignorePatterns.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,gBAAgB,EAGhB,MAAM,cAAc,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,iCAAiC;IACjD;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChE;AAyMD;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,gBAAgB,CAAC,iCAAiC,CAgBvF,CAAC"}
1
+ {"version":3,"file":"RequiredGitignorePatterns.d.ts","sourceRoot":"","sources":["../../src/policies/RequiredGitignorePatterns.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAwB,aAAa,EAAE,MAAM,cAAc,CAAC;AACxE;;;;GAIG;AACH,MAAM,WAAW,iCAAiC;IACjD;;;OAGG;IACH,QAAQ,EAAE,KAAK,CACZ,MAAM,GACN;QACA,2CAA2C;QAC3C,OAAO,EAAE,MAAM,CAAC;QAChB,8DAA8D;QAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;KAChB,CACH,CAAC;CACF;AAgPD;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;CAe6B,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { readFile, writeFile } from "node:fs/promises";
2
2
  import path from "pathe";
3
- import { makePolicyDefinition } from "../makePolicy.js";
4
3
  /**
5
4
  * Default patterns that should typically be in .gitignore files.
6
5
  */
@@ -90,35 +89,30 @@ function createGitignoreContent(patterns) {
90
89
  /**
91
90
  * Handle the case when .gitignore exists.
92
91
  */
93
- async function handleExistingGitignore(filePath, patterns, file, resolve) {
92
+ async function handleExistingGitignore(filePath, patterns, _file, resolve) {
94
93
  const gitignoreContent = await readFile(filePath, "utf-8");
95
94
  const lines = gitignoreContent.split("\n");
96
95
  const missingPatterns = findMissingPatterns(patterns, lines);
97
96
  if (missingPatterns.length === 0) {
98
- return true;
97
+ return [];
99
98
  }
100
- const result = {
101
- name: RequiredGitignorePatterns.name,
102
- file,
103
- autoFixable: true,
104
- errorMessages: [
105
- `Missing required .gitignore patterns: ${missingPatterns.map((p) => (typeof p === "string" ? p : p.pattern)).join(", ")}`,
106
- ],
107
- };
99
+ const result = [
100
+ `Missing required .gitignore patterns: ${missingPatterns.map((p) => (typeof p === "string" ? p : p.pattern)).join(", ")}`,
101
+ ].map((message) => ({ message, fixStatus: "available" }));
108
102
  if (resolve) {
109
- const fixResult = {
110
- ...result,
111
- resolved: false,
112
- };
103
+ const fixResult = result.map((finding) => ({
104
+ ...finding,
105
+ fixStatus: "failed",
106
+ }));
113
107
  try {
114
108
  const newContent = addPatternsToContent(gitignoreContent, missingPatterns);
115
109
  await writeFile(filePath, newContent);
116
- fixResult.resolved = true;
110
+ for (const finding of fixResult) {
111
+ finding.fixStatus = "fixed";
112
+ }
117
113
  }
118
114
  catch (error) {
119
- fixResult.errorMessages = [
120
- `Failed to update .gitignore: ${error.message}`,
121
- ];
115
+ fixResult.splice(0, fixResult.length, ...[`Failed to update .gitignore: ${error.message}`].map((message) => ({ ...fixResult[0], message })));
122
116
  }
123
117
  return fixResult;
124
118
  }
@@ -127,27 +121,26 @@ async function handleExistingGitignore(filePath, patterns, file, resolve) {
127
121
  /**
128
122
  * Handle the case when .gitignore doesn't exist.
129
123
  */
130
- async function handleMissingGitignore(filePath, patterns, file, resolve) {
131
- const result = {
132
- name: RequiredGitignorePatterns.name,
133
- file,
134
- autoFixable: true,
135
- errorMessages: ["No .gitignore file found in repository root"],
136
- };
124
+ async function handleMissingGitignore(filePath, patterns, _file, resolve) {
125
+ const result = [
126
+ "No .gitignore file found in repository root",
127
+ ].map((message) => ({ message, fixStatus: "available" }));
137
128
  if (resolve) {
138
- const fixResult = {
139
- ...result,
140
- resolved: false,
141
- };
129
+ const fixResult = result.map((finding) => ({
130
+ ...finding,
131
+ fixStatus: "failed",
132
+ }));
142
133
  try {
143
134
  const content = createGitignoreContent(patterns);
144
135
  await writeFile(filePath, content);
145
- fixResult.resolved = true;
136
+ for (const finding of fixResult) {
137
+ finding.fixStatus = "fixed";
138
+ }
146
139
  }
147
140
  catch (writeError) {
148
- fixResult.errorMessages = [
141
+ fixResult.splice(0, fixResult.length, ...[
149
142
  `Failed to create .gitignore: ${writeError.message}`,
150
- ];
143
+ ].map((message) => ({ ...fixResult[0], message })));
151
144
  }
152
145
  return fixResult;
153
146
  }
@@ -157,9 +150,9 @@ async function handleMissingGitignore(filePath, patterns, file, resolve) {
157
150
  * A repo policy that ensures .gitignore contains required patterns to prevent
158
151
  * committing sensitive files, dependencies, and build artifacts.
159
152
  *
160
- * @alpha
153
+ * @public
161
154
  */
162
- export const RequiredGitignorePatterns = makePolicyDefinition({
155
+ export const RequiredGitignorePatterns = {
163
156
  name: "RequiredGitignorePatterns",
164
157
  description: "Ensures .gitignore contains required patterns to prevent committing sensitive files, dependencies, and build artifacts.",
165
158
  match: /^\.gitignore$/,
@@ -173,5 +166,5 @@ export const RequiredGitignorePatterns = makePolicyDefinition({
173
166
  return await handleMissingGitignore(filePath, patterns, file, resolve);
174
167
  }
175
168
  },
176
- });
169
+ };
177
170
  //# sourceMappingURL=RequiredGitignorePatterns.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RequiredGitignorePatterns.js","sourceRoot":"","sources":["../../src/policies/RequiredGitignorePatterns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,IAAI,MAAM,OAAO,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAoBxD;;GAEG;AACH,MAAM,gBAAgB,GAAG;IACxB,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE;IACrD,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE;IACjD,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,EAAE;IACnD,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,wBAAwB,EAAE;IAC/D,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE;IAC7C,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE;IAC9C,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,oBAAoB,EAAE;IACvD,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,EAAE;CACzD,CAAC;AAEF;;;GAGG;AACH,SAAS,aAAa,CAAC,KAAe,EAAE,OAAe;IACtD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,iEAAiE;QACjE,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC3D,OAAO,CACN,cAAc,KAAK,OAAO;YAC1B,OAAO,KAAK,OAAO;YACnB,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC;YACjC,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,IAAI,CAAC,CAClC,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC3B,QAA+D,EAC/D,KAAe;IAEf,MAAM,eAAe,GACpB,EAAE,CAAC;IAEJ,KAAK,MAAM,aAAa,IAAI,QAAQ,EAAE,CAAC;QACtC,MAAM,OAAO,GACZ,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC;QAE3E,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;YACpC,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;IAED,OAAO,eAAe,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC5B,OAAe,EACf,eAAsE;IAEtE,IAAI,UAAU,GAAG,OAAO,CAAC;IAEzB,gCAAgC;IAChC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,UAAU,IAAI,IAAI,CAAC;IACpB,CAAC;IAED,gDAAgD;IAChD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,UAAU,IAAI,wDAAwD,CAAC;IACxE,CAAC;IAED,2BAA2B;IAC3B,KAAK,MAAM,aAAa,IAAI,eAAe,EAAE,CAAC;QAC7C,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;YACvC,UAAU,IAAI,GAAG,aAAa,IAAI,CAAC;QACpC,CAAC;aAAM,CAAC;YACP,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;gBAC3B,UAAU,IAAI,KAAK,aAAa,CAAC,OAAO,IAAI,CAAC;YAC9C,CAAC;YACD,UAAU,IAAI,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC;QAC5C,CAAC;IACF,CAAC;IAED,OAAO,UAAU,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAC9B,QAA+D;IAE/D,IAAI,OAAO,GAAG,4DAA4D,CAAC;IAE3E,KAAK,MAAM,aAAa,IAAI,QAAQ,EAAE,CAAC;QACtC,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;YACvC,OAAO,IAAI,GAAG,aAAa,IAAI,CAAC;QACjC,CAAC;aAAM,CAAC;YACP,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;gBAC3B,OAAO,IAAI,KAAK,aAAa,CAAC,OAAO,IAAI,CAAC;YAC3C,CAAC;YACD,OAAO,IAAI,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC;QACzC,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,uBAAuB,CACrC,QAAgB,EAChB,QAA+D,EAC/D,IAAY,EACZ,OAAgB;IAEhB,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,eAAe,GAAG,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE7D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAkB;QAC7B,IAAI,EAAE,yBAAyB,CAAC,IAAI;QACpC,IAAI;QACJ,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE;YACd,yCAAyC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACzH;KACD,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,SAAS,GAAoB;YAClC,GAAG,MAAM;YACT,QAAQ,EAAE,KAAK;SACf,CAAC;QAEF,IAAI,CAAC;YACJ,MAAM,UAAU,GAAG,oBAAoB,CACtC,gBAAgB,EAChB,eAAe,CACf,CAAC;YACF,MAAM,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACtC,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACzB,SAAS,CAAC,aAAa,GAAG;gBACzB,gCAAiC,KAAe,CAAC,OAAO,EAAE;aAC1D,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,sBAAsB,CACpC,QAAgB,EAChB,QAA+D,EAC/D,IAAY,EACZ,OAAgB;IAEhB,MAAM,MAAM,GAAkB;QAC7B,IAAI,EAAE,yBAAyB,CAAC,IAAI;QACpC,IAAI;QACJ,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE,CAAC,6CAA6C,CAAC;KAC9D,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,SAAS,GAAoB;YAClC,GAAG,MAAM;YACT,QAAQ,EAAE,KAAK;SACf,CAAC;QAEF,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnC,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC3B,CAAC;QAAC,OAAO,UAAmB,EAAE,CAAC;YAC9B,SAAS,CAAC,aAAa,GAAG;gBACzB,gCAAiC,UAAoB,CAAC,OAAO,EAAE;aAC/D,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACrC,oBAAoB,CAAC;IACpB,IAAI,EAAE,2BAA2B;IACjC,WAAW,EACV,yHAAyH;IAC1H,KAAK,EAAE,eAAe;IACtB,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAClD,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC;YACJ,OAAO,MAAM,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,MAAe,EAAE,CAAC;YAC1B,OAAO,MAAM,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACxE,CAAC;IACF,CAAC;CACD,CAAC,CAAC","sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"pathe\";\nimport { makePolicyDefinition } from \"../makePolicy.js\";\nimport type {\n\tPolicyDefinition,\n\tPolicyFailure,\n\tPolicyFixResult,\n} from \"../policy.js\";\n\n/**\n * Policy settings for the RequiredGitignorePatterns repo policy.\n *\n * @alpha\n */\nexport interface RequiredGitignorePatternsSettings {\n\t/**\n\t * Array of patterns that must be present in .gitignore.\n\t * Each pattern can be a string or an object with pattern and comment.\n\t */\n\tpatterns: Array<string | { pattern: string; comment?: string }>;\n}\n\n/**\n * Default patterns that should typically be in .gitignore files.\n */\nconst DEFAULT_PATTERNS = [\n\t{ pattern: \"node_modules/\", comment: \"Dependencies\" },\n\t{ pattern: \".env\", comment: \"Environment files\" },\n\t{ pattern: \".env.*\", comment: \"Environment files\" },\n\t{ pattern: \"!.env.example\", comment: \"Allow example env file\" },\n\t{ pattern: \"dist/\", comment: \"Build output\" },\n\t{ pattern: \"build/\", comment: \"Build output\" },\n\t{ pattern: \".DS_Store\", comment: \"macOS system files\" },\n\t{ pattern: \"Thumbs.db\", comment: \"Windows system files\" },\n];\n\n/**\n * Check if a pattern exists in gitignore content.\n * Handles patterns with inline comments (e.g., \"node_modules/ # comment\").\n */\nfunction patternExists(lines: string[], pattern: string): boolean {\n\treturn lines.some((line) => {\n\t\tconst trimmed = line.trim();\n\t\t// Remove inline comments (everything after # that's not escaped)\n\t\tconst withoutComment = trimmed.split(\"#\")[0]?.trim() ?? \"\";\n\t\treturn (\n\t\t\twithoutComment === pattern ||\n\t\t\ttrimmed === pattern ||\n\t\t\ttrimmed.startsWith(`${pattern} `) ||\n\t\t\ttrimmed.startsWith(`${pattern}\\t`)\n\t\t);\n\t});\n}\n\n/**\n * Find missing patterns in gitignore content.\n */\nfunction findMissingPatterns(\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n\tlines: string[],\n): Array<string | { pattern: string; comment?: string }> {\n\tconst missingPatterns: Array<string | { pattern: string; comment?: string }> =\n\t\t[];\n\n\tfor (const patternConfig of patterns) {\n\t\tconst pattern =\n\t\t\ttypeof patternConfig === \"string\" ? patternConfig : patternConfig.pattern;\n\n\t\tif (!patternExists(lines, pattern)) {\n\t\t\tmissingPatterns.push(patternConfig);\n\t\t}\n\t}\n\n\treturn missingPatterns;\n}\n\n/**\n * Add patterns to gitignore content.\n */\nfunction addPatternsToContent(\n\tcontent: string,\n\tmissingPatterns: Array<string | { pattern: string; comment?: string }>,\n): string {\n\tlet newContent = content;\n\n\t// Ensure file ends with newline\n\tif (!newContent.endsWith(\"\\n\")) {\n\t\tnewContent += \"\\n\";\n\t}\n\n\t// Add a section header if we're adding patterns\n\tif (missingPatterns.length > 0) {\n\t\tnewContent += \"\\n# Added by repopo RequiredGitignorePatterns policy\\n\";\n\t}\n\n\t// Add each missing pattern\n\tfor (const patternConfig of missingPatterns) {\n\t\tif (typeof patternConfig === \"string\") {\n\t\t\tnewContent += `${patternConfig}\\n`;\n\t\t} else {\n\t\t\tif (patternConfig.comment) {\n\t\t\t\tnewContent += `# ${patternConfig.comment}\\n`;\n\t\t\t}\n\t\t\tnewContent += `${patternConfig.pattern}\\n`;\n\t\t}\n\t}\n\n\treturn newContent;\n}\n\n/**\n * Create gitignore content from scratch.\n */\nfunction createGitignoreContent(\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n): string {\n\tlet content = \"# Generated by repopo RequiredGitignorePatterns policy\\n\\n\";\n\n\tfor (const patternConfig of patterns) {\n\t\tif (typeof patternConfig === \"string\") {\n\t\t\tcontent += `${patternConfig}\\n`;\n\t\t} else {\n\t\t\tif (patternConfig.comment) {\n\t\t\t\tcontent += `# ${patternConfig.comment}\\n`;\n\t\t\t}\n\t\t\tcontent += `${patternConfig.pattern}\\n`;\n\t\t}\n\t}\n\n\treturn content;\n}\n\n/**\n * Handle the case when .gitignore exists.\n */\nasync function handleExistingGitignore(\n\tfilePath: string,\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n\tfile: string,\n\tresolve: boolean,\n): Promise<true | PolicyFailure | PolicyFixResult> {\n\tconst gitignoreContent = await readFile(filePath, \"utf-8\");\n\tconst lines = gitignoreContent.split(\"\\n\");\n\tconst missingPatterns = findMissingPatterns(patterns, lines);\n\n\tif (missingPatterns.length === 0) {\n\t\treturn true;\n\t}\n\n\tconst result: PolicyFailure = {\n\t\tname: RequiredGitignorePatterns.name,\n\t\tfile,\n\t\tautoFixable: true,\n\t\terrorMessages: [\n\t\t\t`Missing required .gitignore patterns: ${missingPatterns.map((p) => (typeof p === \"string\" ? p : p.pattern)).join(\", \")}`,\n\t\t],\n\t};\n\n\tif (resolve) {\n\t\tconst fixResult: PolicyFixResult = {\n\t\t\t...result,\n\t\t\tresolved: false,\n\t\t};\n\n\t\ttry {\n\t\t\tconst newContent = addPatternsToContent(\n\t\t\t\tgitignoreContent,\n\t\t\t\tmissingPatterns,\n\t\t\t);\n\t\t\tawait writeFile(filePath, newContent);\n\t\t\tfixResult.resolved = true;\n\t\t} catch (error: unknown) {\n\t\t\tfixResult.errorMessages = [\n\t\t\t\t`Failed to update .gitignore: ${(error as Error).message}`,\n\t\t\t];\n\t\t}\n\n\t\treturn fixResult;\n\t}\n\n\treturn result;\n}\n\n/**\n * Handle the case when .gitignore doesn't exist.\n */\nasync function handleMissingGitignore(\n\tfilePath: string,\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n\tfile: string,\n\tresolve: boolean,\n): Promise<PolicyFailure | PolicyFixResult> {\n\tconst result: PolicyFailure = {\n\t\tname: RequiredGitignorePatterns.name,\n\t\tfile,\n\t\tautoFixable: true,\n\t\terrorMessages: [\"No .gitignore file found in repository root\"],\n\t};\n\n\tif (resolve) {\n\t\tconst fixResult: PolicyFixResult = {\n\t\t\t...result,\n\t\t\tresolved: false,\n\t\t};\n\n\t\ttry {\n\t\t\tconst content = createGitignoreContent(patterns);\n\t\t\tawait writeFile(filePath, content);\n\t\t\tfixResult.resolved = true;\n\t\t} catch (writeError: unknown) {\n\t\t\tfixResult.errorMessages = [\n\t\t\t\t`Failed to create .gitignore: ${(writeError as Error).message}`,\n\t\t\t];\n\t\t}\n\n\t\treturn fixResult;\n\t}\n\n\treturn result;\n}\n\n/**\n * A repo policy that ensures .gitignore contains required patterns to prevent\n * committing sensitive files, dependencies, and build artifacts.\n *\n * @alpha\n */\nexport const RequiredGitignorePatterns: PolicyDefinition<RequiredGitignorePatternsSettings> =\n\tmakePolicyDefinition({\n\t\tname: \"RequiredGitignorePatterns\",\n\t\tdescription:\n\t\t\t\"Ensures .gitignore contains required patterns to prevent committing sensitive files, dependencies, and build artifacts.\",\n\t\tmatch: /^\\.gitignore$/,\n\t\thandler: async ({ file, root, resolve, config }) => {\n\t\t\tconst patterns = config?.patterns ?? DEFAULT_PATTERNS;\n\t\t\tconst filePath = path.join(root, file);\n\n\t\t\ttry {\n\t\t\t\treturn await handleExistingGitignore(filePath, patterns, file, resolve);\n\t\t\t} catch (_error: unknown) {\n\t\t\t\treturn await handleMissingGitignore(filePath, patterns, file, resolve);\n\t\t\t}\n\t\t},\n\t});\n"]}
1
+ {"version":3,"file":"RequiredGitignorePatterns.js","sourceRoot":"","sources":["../../src/policies/RequiredGitignorePatterns.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"pathe\";\nimport type { FilePolicyDefinition, PolicyFinding } from \"../policy.js\";\n/**\n * Policy settings for the RequiredGitignorePatterns repo policy.\n *\n * @public\n */\nexport interface RequiredGitignorePatternsSettings {\n\t/**\n\t * Array of patterns that must be present in .gitignore.\n\t * Each pattern can be a string or an object with pattern and comment.\n\t */\n\tpatterns: Array<\n\t\t| string\n\t\t| {\n\t\t\t\t/** Literal .gitignore entry to require. */\n\t\t\t\tpattern: string;\n\t\t\t\t/** Comment inserted before the entry when fixing the file. */\n\t\t\t\tcomment?: string;\n\t\t }\n\t>;\n}\n\n/**\n * Default patterns that should typically be in .gitignore files.\n */\nconst DEFAULT_PATTERNS = [\n\t{ pattern: \"node_modules/\", comment: \"Dependencies\" },\n\t{ pattern: \".env\", comment: \"Environment files\" },\n\t{ pattern: \".env.*\", comment: \"Environment files\" },\n\t{ pattern: \"!.env.example\", comment: \"Allow example env file\" },\n\t{ pattern: \"dist/\", comment: \"Build output\" },\n\t{ pattern: \"build/\", comment: \"Build output\" },\n\t{ pattern: \".DS_Store\", comment: \"macOS system files\" },\n\t{ pattern: \"Thumbs.db\", comment: \"Windows system files\" },\n];\n\n/**\n * Check if a pattern exists in gitignore content.\n * Handles patterns with inline comments (e.g., \"node_modules/ # comment\").\n */\nfunction patternExists(lines: string[], pattern: string): boolean {\n\treturn lines.some((line) => {\n\t\tconst trimmed = line.trim();\n\t\t// Remove inline comments (everything after # that's not escaped)\n\t\tconst withoutComment = trimmed.split(\"#\")[0]?.trim() ?? \"\";\n\t\treturn (\n\t\t\twithoutComment === pattern ||\n\t\t\ttrimmed === pattern ||\n\t\t\ttrimmed.startsWith(`${pattern} `) ||\n\t\t\ttrimmed.startsWith(`${pattern}\\t`)\n\t\t);\n\t});\n}\n\n/**\n * Find missing patterns in gitignore content.\n */\nfunction findMissingPatterns(\n\tpatterns: Array<\n\t\t| string\n\t\t| {\n\t\t\t\tpattern: string;\n\t\t\t\tcomment?: string;\n\t\t }\n\t>,\n\tlines: string[],\n): Array<\n\t| string\n\t| {\n\t\t\tpattern: string;\n\t\t\tcomment?: string;\n\t }\n> {\n\tconst missingPatterns: Array<\n\t\t| string\n\t\t| {\n\t\t\t\tpattern: string;\n\t\t\t\tcomment?: string;\n\t\t }\n\t> = [];\n\tfor (const patternConfig of patterns) {\n\t\tconst pattern =\n\t\t\ttypeof patternConfig === \"string\" ? patternConfig : patternConfig.pattern;\n\n\t\tif (!patternExists(lines, pattern)) {\n\t\t\tmissingPatterns.push(patternConfig);\n\t\t}\n\t}\n\n\treturn missingPatterns;\n}\n\n/**\n * Add patterns to gitignore content.\n */\nfunction addPatternsToContent(\n\tcontent: string,\n\tmissingPatterns: Array<\n\t\t| string\n\t\t| {\n\t\t\t\tpattern: string;\n\t\t\t\tcomment?: string;\n\t\t }\n\t>,\n): string {\n\tlet newContent = content;\n\n\t// Ensure file ends with newline\n\tif (!newContent.endsWith(\"\\n\")) {\n\t\tnewContent += \"\\n\";\n\t}\n\n\t// Add a section header if we're adding patterns\n\tif (missingPatterns.length > 0) {\n\t\tnewContent += \"\\n# Added by repopo RequiredGitignorePatterns policy\\n\";\n\t}\n\n\t// Add each missing pattern\n\tfor (const patternConfig of missingPatterns) {\n\t\tif (typeof patternConfig === \"string\") {\n\t\t\tnewContent += `${patternConfig}\\n`;\n\t\t} else {\n\t\t\tif (patternConfig.comment) {\n\t\t\t\tnewContent += `# ${patternConfig.comment}\\n`;\n\t\t\t}\n\t\t\tnewContent += `${patternConfig.pattern}\\n`;\n\t\t}\n\t}\n\n\treturn newContent;\n}\n\n/**\n * Create gitignore content from scratch.\n */\nfunction createGitignoreContent(\n\tpatterns: Array<\n\t\t| string\n\t\t| {\n\t\t\t\tpattern: string;\n\t\t\t\tcomment?: string;\n\t\t }\n\t>,\n): string {\n\tlet content = \"# Generated by repopo RequiredGitignorePatterns policy\\n\\n\";\n\n\tfor (const patternConfig of patterns) {\n\t\tif (typeof patternConfig === \"string\") {\n\t\t\tcontent += `${patternConfig}\\n`;\n\t\t} else {\n\t\t\tif (patternConfig.comment) {\n\t\t\t\tcontent += `# ${patternConfig.comment}\\n`;\n\t\t\t}\n\t\t\tcontent += `${patternConfig.pattern}\\n`;\n\t\t}\n\t}\n\n\treturn content;\n}\n\n/**\n * Handle the case when .gitignore exists.\n */\nasync function handleExistingGitignore(\n\tfilePath: string,\n\tpatterns: Array<\n\t\t| string\n\t\t| {\n\t\t\t\tpattern: string;\n\t\t\t\tcomment?: string;\n\t\t }\n\t>,\n\t_file: string,\n\tresolve: boolean,\n): Promise<PolicyFinding[]> {\n\tconst gitignoreContent = await readFile(filePath, \"utf-8\");\n\tconst lines = gitignoreContent.split(\"\\n\");\n\tconst missingPatterns = findMissingPatterns(patterns, lines);\n\n\tif (missingPatterns.length === 0) {\n\t\treturn [];\n\t}\n\tconst result: PolicyFinding[] = [\n\t\t`Missing required .gitignore patterns: ${missingPatterns.map((p) => (typeof p === \"string\" ? p : p.pattern)).join(\", \")}`,\n\t].map((message) => ({ message, fixStatus: \"available\" }));\n\tif (resolve) {\n\t\tconst fixResult: PolicyFinding[] = result.map((finding) => ({\n\t\t\t...finding,\n\t\t\tfixStatus: \"failed\",\n\t\t}));\n\t\ttry {\n\t\t\tconst newContent = addPatternsToContent(\n\t\t\t\tgitignoreContent,\n\t\t\t\tmissingPatterns,\n\t\t\t);\n\t\t\tawait writeFile(filePath, newContent);\n\t\t\tfor (const finding of fixResult) {\n\t\t\t\tfinding.fixStatus = \"fixed\";\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tfixResult.splice(\n\t\t\t\t0,\n\t\t\t\tfixResult.length,\n\t\t\t\t...[`Failed to update .gitignore: ${(error as Error).message}`].map(\n\t\t\t\t\t(message) => ({ ...fixResult[0], message }),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\treturn fixResult;\n\t}\n\n\treturn result;\n}\n\n/**\n * Handle the case when .gitignore doesn't exist.\n */\nasync function handleMissingGitignore(\n\tfilePath: string,\n\tpatterns: Array<\n\t\t| string\n\t\t| {\n\t\t\t\tpattern: string;\n\t\t\t\tcomment?: string;\n\t\t }\n\t>,\n\t_file: string,\n\tresolve: boolean,\n): Promise<PolicyFinding[]> {\n\tconst result: PolicyFinding[] = [\n\t\t\"No .gitignore file found in repository root\",\n\t].map((message) => ({ message, fixStatus: \"available\" }));\n\tif (resolve) {\n\t\tconst fixResult: PolicyFinding[] = result.map((finding) => ({\n\t\t\t...finding,\n\t\t\tfixStatus: \"failed\",\n\t\t}));\n\t\ttry {\n\t\t\tconst content = createGitignoreContent(patterns);\n\t\t\tawait writeFile(filePath, content);\n\t\t\tfor (const finding of fixResult) {\n\t\t\t\tfinding.fixStatus = \"fixed\";\n\t\t\t}\n\t\t} catch (writeError: unknown) {\n\t\t\tfixResult.splice(\n\t\t\t\t0,\n\t\t\t\tfixResult.length,\n\t\t\t\t...[\n\t\t\t\t\t`Failed to create .gitignore: ${(writeError as Error).message}`,\n\t\t\t\t].map((message) => ({ ...fixResult[0], message })),\n\t\t\t);\n\t\t}\n\n\t\treturn fixResult;\n\t}\n\n\treturn result;\n}\n\n/**\n * A repo policy that ensures .gitignore contains required patterns to prevent\n * committing sensitive files, dependencies, and build artifacts.\n *\n * @public\n */\nexport const RequiredGitignorePatterns = {\n\tname: \"RequiredGitignorePatterns\",\n\tdescription:\n\t\t\"Ensures .gitignore contains required patterns to prevent committing sensitive files, dependencies, and build artifacts.\",\n\tmatch: /^\\.gitignore$/,\n\thandler: async ({ file, root, resolve, config }) => {\n\t\tconst patterns = config?.patterns ?? DEFAULT_PATTERNS;\n\t\tconst filePath = path.join(root, file);\n\n\t\ttry {\n\t\t\treturn await handleExistingGitignore(filePath, patterns, file, resolve);\n\t\t} catch (_error: unknown) {\n\t\t\treturn await handleMissingGitignore(filePath, patterns, file, resolve);\n\t\t}\n\t},\n} satisfies FilePolicyDefinition<RequiredGitignorePatternsSettings>;\n"]}
@@ -12,13 +12,13 @@
12
12
  * { lint: "biome lint ." }
13
13
  * ```
14
14
  *
15
- * @alpha
15
+ * @public
16
16
  */
17
17
  export type RequiredScriptEntry = string | Record<string, string>;
18
18
  /**
19
19
  * Configuration for the RequiredScripts policy.
20
20
  *
21
- * @alpha
21
+ * @public
22
22
  */
23
23
  export interface RequiredScriptsConfig {
24
24
  /**
@@ -53,19 +53,21 @@ export interface RequiredScriptsConfig {
53
53
  *
54
54
  * @example
55
55
  * ```typescript
56
- * import { policy } from "repopo";
56
+ * import { makePolicy } from "repopo";
57
57
  * import { RequiredScripts } from "repopo/policies";
58
58
  *
59
- * policy(RequiredScripts, {
59
+ * makePolicy(RequiredScripts, { config: {
60
60
  * scripts: [
61
61
  * "test", // Must exist, no auto-fix
62
62
  * { lint: "biome lint ." }, // Must exist, auto-fix adds default if missing
63
63
  * { clean: "rimraf dist esm" }, // Must exist, auto-fix adds default if missing
64
64
  * ],
65
- * })
65
+ * } })
66
66
  * ```
67
67
  *
68
- * @alpha
68
+ * @public
69
69
  */
70
- export declare const RequiredScripts: import("../policy.js").PolicyShape<RequiredScriptsConfig | undefined>;
70
+ export declare const RequiredScripts: import("../policy.js").FilePolicyDefinition<RequiredScriptsConfig | undefined> & {
71
+ requiresConfig: true;
72
+ };
71
73
  //# sourceMappingURL=RequiredScripts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RequiredScripts.d.ts","sourceRoot":"","sources":["../../src/policies/RequiredScripts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAC/B;AAoFD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,eAAe,uEA2D1B,CAAC"}
1
+ {"version":3,"file":"RequiredScripts.d.ts","sourceRoot":"","sources":["../../src/policies/RequiredScripts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAC/B;AA4FD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,eAAe;;CA0D1B,CAAC"}
@@ -61,31 +61,32 @@ async function fixMissingScripts(json, file, missingWithDefaults, existingScript
61
61
  *
62
62
  * @example
63
63
  * ```typescript
64
- * import { policy } from "repopo";
64
+ * import { makePolicy } from "repopo";
65
65
  * import { RequiredScripts } from "repopo/policies";
66
66
  *
67
- * policy(RequiredScripts, {
67
+ * makePolicy(RequiredScripts, { config: {
68
68
  * scripts: [
69
69
  * "test", // Must exist, no auto-fix
70
70
  * { lint: "biome lint ." }, // Must exist, auto-fix adds default if missing
71
71
  * { clean: "rimraf dist esm" }, // Must exist, auto-fix adds default if missing
72
72
  * ],
73
- * })
73
+ * } })
74
74
  * ```
75
75
  *
76
- * @alpha
76
+ * @public
77
77
  */
78
78
  export const RequiredScripts = definePackagePolicy({
79
+ requiresConfig: true,
79
80
  name: POLICY_NAME,
80
81
  description: "Validates that required scripts exist in package.json.",
81
82
  handler: async (json, { file, root, resolve, config }) => {
82
83
  if (config === undefined || config.scripts.length === 0) {
83
- return true;
84
+ return [];
84
85
  }
85
86
  const scripts = json.scripts ?? {};
86
87
  const validation = validateRequiredScripts(scripts, config.scripts);
87
88
  if (validation.missingScripts.length === 0) {
88
- return true;
89
+ return [];
89
90
  }
90
91
  const hasAutoFixableErrors = validation.missingWithDefaults.length > 0;
91
92
  if (resolve && hasAutoFixableErrors) {
@@ -93,29 +94,28 @@ export const RequiredScripts = definePackagePolicy({
93
94
  const fixedScripts = await fixMissingScripts(json, resolvePath(root, file), validation.missingWithDefaults, scripts);
94
95
  // Check if there are still missing scripts (those without defaults)
95
96
  const stillMissing = validation.missingScripts.filter((name) => !fixedScripts.includes(name));
96
- return {
97
- name: POLICY_NAME,
98
- file,
99
- resolved: stillMissing.length === 0,
100
- errorMessages: stillMissing.length > 0
101
- ? [
102
- `Fixed scripts: ${fixedScripts.join(", ")}. Still missing: ${stillMissing.join(", ")}`,
103
- ]
104
- : [`Fixed scripts: ${fixedScripts.join(", ")}`],
105
- };
97
+ return [
98
+ ...fixedScripts.map((name) => ({
99
+ message: `Fixed scripts: ${name}`,
100
+ fixStatus: "fixed",
101
+ })),
102
+ ...stillMissing.map((name) => ({
103
+ message: `Still missing: ${name}`,
104
+ })),
105
+ ];
106
106
  }
107
107
  catch {
108
108
  // Fall through to return regular failure
109
109
  }
110
110
  }
111
- return {
112
- name: POLICY_NAME,
113
- file,
114
- autoFixable: hasAutoFixableErrors,
115
- errorMessages: [
116
- `Missing required scripts:\n\t${validation.missingScripts.join("\n\t")}`,
117
- ],
118
- };
111
+ return validation.missingScripts.map((name) => ({
112
+ message: `Missing required scripts:\n\t${name}`,
113
+ fixStatus: validation.missingWithDefaults.some((entry) => entry.name === name)
114
+ ? resolve
115
+ ? "failed"
116
+ : "available"
117
+ : undefined,
118
+ }));
119
119
  },
120
120
  });
121
121
  //# sourceMappingURL=RequiredScripts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RequiredScripts.js","sourceRoot":"","sources":["../../src/policies/RequiredScripts.ts"],"names":[],"mappings":"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","sourcesContent":["import jsonfile from \"jsonfile\";\nimport { resolve as resolvePath } from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * A required script entry. Can be either:\n * - A string (script name only, no default value)\n * - An object with a single key-value pair (script name → default value for auto-fix)\n *\n * @example\n * ```typescript\n * // Script must exist, no auto-fix available\n * \"test\"\n *\n * // Script must exist, auto-fix will add this value if missing\n * { lint: \"biome lint .\" }\n * ```\n *\n * @alpha\n */\nexport type RequiredScriptEntry = string | Record<string, string>;\n\n/**\n * Configuration for the RequiredScripts policy.\n *\n * @alpha\n */\nexport interface RequiredScriptsConfig {\n\t/**\n\t * Scripts that must be present in package.json.\n\t *\n\t * @remarks\n\t * Each entry can be:\n\t * - A string: Script must exist, no auto-fix available, content not validated\n\t * - An object `{ scriptName: \"default value\" }`: Script must exist, auto-fix adds the\n\t * default value if missing, but existing scripts with different content still pass\n\t *\n\t * @example\n\t * ```typescript\n\t * scripts: [\n\t * \"test\", // Must exist, no auto-fix\n\t * { lint: \"biome lint .\" }, // Must exist, auto-fix available\n\t * { clean: \"rimraf dist esm\" }, // Must exist, auto-fix available\n\t * ]\n\t * ```\n\t */\n\tscripts: RequiredScriptEntry[];\n}\n\nconst POLICY_NAME = \"RequiredScripts\";\n\ninterface ParsedEntry {\n\tname: string;\n\tdefaultValue?: string;\n}\n\n/**\n * Extracts script name and optional default value from a RequiredScriptEntry.\n */\nfunction parseRequiredEntry(entry: RequiredScriptEntry): ParsedEntry {\n\tif (typeof entry === \"string\") {\n\t\treturn { name: entry };\n\t}\n\tconst keys = Object.keys(entry);\n\tif (keys.length !== 1) {\n\t\tthrow new Error(\n\t\t\t`Invalid required script entry: expected single key-value pair, got ${keys.length} keys`,\n\t\t);\n\t}\n\t// biome-ignore lint/style/noNonNullAssertion: we verified length is 1\n\tconst name = keys[0]!;\n\tconst defaultValue = entry[name];\n\treturn defaultValue !== undefined ? { name, defaultValue } : { name };\n}\n\ninterface ValidationResult {\n\tmissingScripts: string[];\n\tmissingWithDefaults: Array<{ name: string; defaultValue: string }>;\n}\n\nfunction validateRequiredScripts(\n\tscripts: Record<string, string | undefined>,\n\trequiredEntries: RequiredScriptEntry[],\n): ValidationResult {\n\tconst missingScripts: string[] = [];\n\tconst missingWithDefaults: Array<{ name: string; defaultValue: string }> = [];\n\n\tfor (const entry of requiredEntries) {\n\t\tconst { name, defaultValue } = parseRequiredEntry(entry);\n\t\tif (!Object.hasOwn(scripts, name)) {\n\t\t\tmissingScripts.push(name);\n\t\t\tif (defaultValue !== undefined) {\n\t\t\t\tmissingWithDefaults.push({ name, defaultValue });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { missingScripts, missingWithDefaults };\n}\n\nasync function fixMissingScripts(\n\tjson: PackageJson,\n\tfile: string,\n\tmissingWithDefaults: Array<{ name: string; defaultValue: string }>,\n\texistingScripts: Record<string, string | undefined>,\n): Promise<string[]> {\n\tconst updatedScripts: Record<string, string> = {};\n\n\t// Copy existing scripts\n\tfor (const [key, value] of Object.entries(existingScripts)) {\n\t\tif (value !== undefined) {\n\t\t\tupdatedScripts[key] = value;\n\t\t}\n\t}\n\n\t// Add missing scripts with defaults\n\tconst fixedScripts: string[] = [];\n\tfor (const { name, defaultValue } of missingWithDefaults) {\n\t\tupdatedScripts[name] = defaultValue;\n\t\tfixedScripts.push(name);\n\t}\n\n\tawait jsonfile.writeFile(\n\t\tfile,\n\t\t{ ...json, scripts: updatedScripts },\n\t\t{ spaces: 2 },\n\t);\n\n\treturn fixedScripts;\n}\n\n/**\n * A policy that validates required scripts exist in package.json.\n *\n * @remarks\n * Use this policy when you want to ensure specific scripts are present.\n * Scripts can be specified with optional default values that enable auto-fix.\n *\n * Note: This policy only checks for script presence. It does NOT validate\n * the script's content. Use ExactScripts for content validation.\n *\n * @example\n * ```typescript\n * import { policy } from \"repopo\";\n * import { RequiredScripts } from \"repopo/policies\";\n *\n * policy(RequiredScripts, {\n * scripts: [\n * \"test\", // Must exist, no auto-fix\n * { lint: \"biome lint .\" }, // Must exist, auto-fix adds default if missing\n * { clean: \"rimraf dist esm\" }, // Must exist, auto-fix adds default if missing\n * ],\n * })\n * ```\n *\n * @alpha\n */\nexport const RequiredScripts = definePackagePolicy<\n\tPackageJson,\n\tRequiredScriptsConfig | undefined\n>({\n\tname: POLICY_NAME,\n\tdescription: \"Validates that required scripts exist in package.json.\",\n\thandler: async (json, { file, root, resolve, config }) => {\n\t\tif (config === undefined || config.scripts.length === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst scripts = json.scripts ?? {};\n\t\tconst validation = validateRequiredScripts(scripts, config.scripts);\n\n\t\tif (validation.missingScripts.length === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst hasAutoFixableErrors = validation.missingWithDefaults.length > 0;\n\n\t\tif (resolve && hasAutoFixableErrors) {\n\t\t\ttry {\n\t\t\t\tconst fixedScripts = await fixMissingScripts(\n\t\t\t\t\tjson,\n\t\t\t\t\tresolvePath(root, file),\n\t\t\t\t\tvalidation.missingWithDefaults,\n\t\t\t\t\tscripts,\n\t\t\t\t);\n\n\t\t\t\t// Check if there are still missing scripts (those without defaults)\n\t\t\t\tconst stillMissing = validation.missingScripts.filter(\n\t\t\t\t\t(name) => !fixedScripts.includes(name),\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\tname: POLICY_NAME,\n\t\t\t\t\tfile,\n\t\t\t\t\tresolved: stillMissing.length === 0,\n\t\t\t\t\terrorMessages:\n\t\t\t\t\t\tstillMissing.length > 0\n\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t`Fixed scripts: ${fixedScripts.join(\", \")}. Still missing: ${stillMissing.join(\", \")}`,\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t: [`Fixed scripts: ${fixedScripts.join(\", \")}`],\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\t// Fall through to return regular failure\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tname: POLICY_NAME,\n\t\t\tfile,\n\t\t\tautoFixable: hasAutoFixableErrors,\n\t\t\terrorMessages: [\n\t\t\t\t`Missing required scripts:\\n\\t${validation.missingScripts.join(\"\\n\\t\")}`,\n\t\t\t],\n\t\t};\n\t},\n});\n"]}
1
+ {"version":3,"file":"RequiredScripts.js","sourceRoot":"","sources":["../../src/policies/RequiredScripts.ts"],"names":[],"mappings":"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","sourcesContent":["import jsonfile from \"jsonfile\";\nimport { resolve as resolvePath } from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * A required script entry. Can be either:\n * - A string (script name only, no default value)\n * - An object with a single key-value pair (script name → default value for auto-fix)\n *\n * @example\n * ```typescript\n * // Script must exist, no auto-fix available\n * \"test\"\n *\n * // Script must exist, auto-fix will add this value if missing\n * { lint: \"biome lint .\" }\n * ```\n *\n * @public\n */\nexport type RequiredScriptEntry = string | Record<string, string>;\n\n/**\n * Configuration for the RequiredScripts policy.\n *\n * @public\n */\nexport interface RequiredScriptsConfig {\n\t/**\n\t * Scripts that must be present in package.json.\n\t *\n\t * @remarks\n\t * Each entry can be:\n\t * - A string: Script must exist, no auto-fix available, content not validated\n\t * - An object `{ scriptName: \"default value\" }`: Script must exist, auto-fix adds the\n\t * default value if missing, but existing scripts with different content still pass\n\t *\n\t * @example\n\t * ```typescript\n\t * scripts: [\n\t * \"test\", // Must exist, no auto-fix\n\t * { lint: \"biome lint .\" }, // Must exist, auto-fix available\n\t * { clean: \"rimraf dist esm\" }, // Must exist, auto-fix available\n\t * ]\n\t * ```\n\t */\n\tscripts: RequiredScriptEntry[];\n}\n\nconst POLICY_NAME = \"RequiredScripts\";\n\ninterface ParsedEntry {\n\tname: string;\n\tdefaultValue?: string;\n}\n\n/**\n * Extracts script name and optional default value from a RequiredScriptEntry.\n */\nfunction parseRequiredEntry(entry: RequiredScriptEntry): ParsedEntry {\n\tif (typeof entry === \"string\") {\n\t\treturn { name: entry };\n\t}\n\tconst keys = Object.keys(entry);\n\tif (keys.length !== 1) {\n\t\tthrow new Error(\n\t\t\t`Invalid required script entry: expected single key-value pair, got ${keys.length} keys`,\n\t\t);\n\t}\n\t// biome-ignore lint/style/noNonNullAssertion: we verified length is 1\n\tconst name = keys[0]!;\n\tconst defaultValue = entry[name];\n\treturn defaultValue !== undefined ? { name, defaultValue } : { name };\n}\n\ninterface ValidationResult {\n\tmissingScripts: string[];\n\tmissingWithDefaults: Array<{\n\t\tname: string;\n\t\tdefaultValue: string;\n\t}>;\n}\n\nfunction validateRequiredScripts(\n\tscripts: Record<string, string | undefined>,\n\trequiredEntries: RequiredScriptEntry[],\n): ValidationResult {\n\tconst missingScripts: string[] = [];\n\tconst missingWithDefaults: Array<{\n\t\tname: string;\n\t\tdefaultValue: string;\n\t}> = [];\n\tfor (const entry of requiredEntries) {\n\t\tconst { name, defaultValue } = parseRequiredEntry(entry);\n\t\tif (!Object.hasOwn(scripts, name)) {\n\t\t\tmissingScripts.push(name);\n\t\t\tif (defaultValue !== undefined) {\n\t\t\t\tmissingWithDefaults.push({ name, defaultValue });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { missingScripts, missingWithDefaults };\n}\n\nasync function fixMissingScripts(\n\tjson: PackageJson,\n\tfile: string,\n\tmissingWithDefaults: Array<{\n\t\tname: string;\n\t\tdefaultValue: string;\n\t}>,\n\texistingScripts: Record<string, string | undefined>,\n): Promise<string[]> {\n\tconst updatedScripts: Record<string, string> = {};\n\n\t// Copy existing scripts\n\tfor (const [key, value] of Object.entries(existingScripts)) {\n\t\tif (value !== undefined) {\n\t\t\tupdatedScripts[key] = value;\n\t\t}\n\t}\n\n\t// Add missing scripts with defaults\n\tconst fixedScripts: string[] = [];\n\tfor (const { name, defaultValue } of missingWithDefaults) {\n\t\tupdatedScripts[name] = defaultValue;\n\t\tfixedScripts.push(name);\n\t}\n\n\tawait jsonfile.writeFile(\n\t\tfile,\n\t\t{ ...json, scripts: updatedScripts },\n\t\t{ spaces: 2 },\n\t);\n\n\treturn fixedScripts;\n}\n\n/**\n * A policy that validates required scripts exist in package.json.\n *\n * @remarks\n * Use this policy when you want to ensure specific scripts are present.\n * Scripts can be specified with optional default values that enable auto-fix.\n *\n * Note: This policy only checks for script presence. It does NOT validate\n * the script's content. Use ExactScripts for content validation.\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { RequiredScripts } from \"repopo/policies\";\n *\n * makePolicy(RequiredScripts, { config: {\n * scripts: [\n * \"test\", // Must exist, no auto-fix\n * { lint: \"biome lint .\" }, // Must exist, auto-fix adds default if missing\n * { clean: \"rimraf dist esm\" }, // Must exist, auto-fix adds default if missing\n * ],\n * } })\n * ```\n *\n * @public\n */\nexport const RequiredScripts = definePackagePolicy<\n\tPackageJson,\n\tRequiredScriptsConfig | undefined\n>({\n\trequiresConfig: true,\n\tname: POLICY_NAME,\n\tdescription: \"Validates that required scripts exist in package.json.\",\n\thandler: async (json, { file, root, resolve, config }) => {\n\t\tif (config === undefined || config.scripts.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst scripts = json.scripts ?? {};\n\t\tconst validation = validateRequiredScripts(scripts, config.scripts);\n\n\t\tif (validation.missingScripts.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst hasAutoFixableErrors = validation.missingWithDefaults.length > 0;\n\n\t\tif (resolve && hasAutoFixableErrors) {\n\t\t\ttry {\n\t\t\t\tconst fixedScripts = await fixMissingScripts(\n\t\t\t\t\tjson,\n\t\t\t\t\tresolvePath(root, file),\n\t\t\t\t\tvalidation.missingWithDefaults,\n\t\t\t\t\tscripts,\n\t\t\t\t);\n\n\t\t\t\t// Check if there are still missing scripts (those without defaults)\n\t\t\t\tconst stillMissing = validation.missingScripts.filter(\n\t\t\t\t\t(name) => !fixedScripts.includes(name),\n\t\t\t\t);\n\t\t\t\treturn [\n\t\t\t\t\t...fixedScripts.map((name) => ({\n\t\t\t\t\t\tmessage: `Fixed scripts: ${name}`,\n\t\t\t\t\t\tfixStatus: \"fixed\" as const,\n\t\t\t\t\t})),\n\t\t\t\t\t...stillMissing.map((name) => ({\n\t\t\t\t\t\tmessage: `Still missing: ${name}`,\n\t\t\t\t\t})),\n\t\t\t\t];\n\t\t\t} catch {\n\t\t\t\t// Fall through to return regular failure\n\t\t\t}\n\t\t}\n\t\treturn validation.missingScripts.map((name) => ({\n\t\t\tmessage: `Missing required scripts:\\n\\t${name}`,\n\t\t\tfixStatus: validation.missingWithDefaults.some(\n\t\t\t\t(entry) => entry.name === name,\n\t\t\t)\n\t\t\t\t? resolve\n\t\t\t\t\t? \"failed\"\n\t\t\t\t\t: \"available\"\n\t\t\t\t: undefined,\n\t\t}));\n\t},\n});\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 RustDocExists policy.
4
4
  *
5
- * @alpha
5
+ * @public
6
6
  */
7
7
  export interface RustDocExistsConfig {
8
8
  /**
@@ -18,7 +18,7 @@ export interface RustDocExistsConfig {
18
18
  /**
19
19
  * A policy that validates documentation files exist for Rust crates.
20
20
  *
21
- * @alpha
21
+ * @public
22
22
  */
23
- export declare const RustDocExists: PolicyShape<RustDocExistsConfig>;
23
+ export declare const RustDocExists: FilePolicyDefinition<RustDocExistsConfig>;
24
24
  //# sourceMappingURL=RustDocExists.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RustDocExists.d.ts","sourceRoot":"","sources":["../../src/policies/RustDocExists.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAID;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,mBAAmB,CAoDxD,CAAC"}
1
+ {"version":3,"file":"RustDocExists.d.ts","sourceRoot":"","sources":["../../src/policies/RustDocExists.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMzD;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAID;;;;GAIG;AACH,eAAO,MAAM,aAAa,2CAkD4B,CAAC"}
@@ -5,7 +5,7 @@ const DEFAULT_REQUIRED = ["README.md"];
5
5
  /**
6
6
  * A policy that validates documentation files exist for Rust crates.
7
7
  *
8
- * @alpha
8
+ * @public
9
9
  */
10
10
  export const RustDocExists = defineCargoPolicy({
11
11
  name: "RustDocExists",
@@ -13,7 +13,7 @@ export const RustDocExists = defineCargoPolicy({
13
13
  handler: async (toml, { file, root, config }) => {
14
14
  // Skip workspace root
15
15
  if (toml.workspace !== undefined && toml.package === undefined) {
16
- return true;
16
+ return [];
17
17
  }
18
18
  const dir = path.dirname(path.resolve(root, file));
19
19
  const required = config?.required ?? DEFAULT_REQUIRED;
@@ -38,12 +38,12 @@ export const RustDocExists = defineCargoPolicy({
38
38
  errors.push(`Missing recommended documentation: ${missingRecommended.join(", ")}`);
39
39
  }
40
40
  if (errors.length > 0) {
41
- return {
42
- error: errors.join("; "),
41
+ return errors.map((message) => ({
42
+ message,
43
43
  manualFix: "Create the missing documentation files alongside Cargo.toml.",
44
- };
44
+ }));
45
45
  }
46
- return true;
46
+ return [];
47
47
  },
48
48
  });
49
49
  //# sourceMappingURL=RustDocExists.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RustDocExists.js","sourceRoot":"","sources":["../../src/policies/RustDocExists.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;AAoBhD,MAAM,gBAAgB,GAAG,CAAC,WAAW,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GACzB,iBAAiB,CAAC;IACjB,IAAI,EAAE,eAAe;IACrB,WAAW,EACV,6EAA6E;IAC9E,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1D,sBAAsB;QACtB,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,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,CAAC;QACtD,MAAM,WAAW,GAAG,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC;QAE9C,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,kBAAkB,GAAa,EAAE,CAAC;QAExC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAC3C,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;QACF,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,WAAW,EAAE,CAAC;YACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAC3C,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,CAAC;QACF,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CACV,mCAAmC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;QACH,CAAC;QACD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CACV,sCAAsC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrE,CAAC;QACH,CAAC;QAED,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 { 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 RustDocExists policy.\n *\n * @alpha\n */\nexport interface RustDocExistsConfig {\n\t/**\n\t * Files that must exist alongside the Cargo.toml.\n\t * @defaultValue [\"README.md\"]\n\t */\n\trequired?: string[];\n\n\t/**\n\t * Files that are recommended but not required. Missing ones produce warnings.\n\t */\n\trecommended?: string[];\n}\n\nconst DEFAULT_REQUIRED = [\"README.md\"];\n\n/**\n * A policy that validates documentation files exist for Rust crates.\n *\n * @alpha\n */\nexport const RustDocExists: PolicyShape<RustDocExistsConfig> =\n\tdefineCargoPolicy({\n\t\tname: \"RustDocExists\",\n\t\tdescription:\n\t\t\t\"Validates that documentation files (README.md, etc.) exist for Rust crates.\",\n\t\thandler: async (toml: CargoToml, { file, root, config }) => {\n\t\t\t// Skip workspace root\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 required = config?.required ?? DEFAULT_REQUIRED;\n\t\t\tconst recommended = config?.recommended ?? [];\n\n\t\t\tconst missingRequired: string[] = [];\n\t\t\tconst missingRecommended: string[] = [];\n\n\t\t\tfor (const fileName of required) {\n\t\t\t\tif (!existsSync(path.join(dir, fileName))) {\n\t\t\t\t\tmissingRequired.push(fileName);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const fileName of recommended) {\n\t\t\t\tif (!existsSync(path.join(dir, fileName))) {\n\t\t\t\t\tmissingRecommended.push(fileName);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst errors: string[] = [];\n\t\t\tif (missingRequired.length > 0) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`Missing required documentation: ${missingRequired.join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (missingRecommended.length > 0) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`Missing recommended documentation: ${missingRecommended.join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\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\"Create the missing documentation files alongside Cargo.toml.\",\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":"RustDocExists.js","sourceRoot":"","sources":["../../src/policies/RustDocExists.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;AAoBhD,MAAM,gBAAgB,GAAG,CAAC,WAAW,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;IAC9C,IAAI,EAAE,eAAe;IACrB,WAAW,EACV,6EAA6E;IAC9E,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1D,sBAAsB;QACtB,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,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,CAAC;QACtD,MAAM,WAAW,GAAG,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC;QAE9C,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,kBAAkB,GAAa,EAAE,CAAC;QAExC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAC3C,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;QACF,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,WAAW,EAAE,CAAC;YACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAC3C,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,CAAC;QACF,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CACV,mCAAmC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;QACH,CAAC;QACD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CACV,sCAAsC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrE,CAAC;QACH,CAAC;QAED,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,8DAA8D;aAC/D,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;CACD,CAAqD,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 RustDocExists policy.\n *\n * @public\n */\nexport interface RustDocExistsConfig {\n\t/**\n\t * Files that must exist alongside the Cargo.toml.\n\t * @defaultValue [\"README.md\"]\n\t */\n\trequired?: string[];\n\n\t/**\n\t * Files that are recommended but not required. Missing ones produce warnings.\n\t */\n\trecommended?: string[];\n}\n\nconst DEFAULT_REQUIRED = [\"README.md\"];\n\n/**\n * A policy that validates documentation files exist for Rust crates.\n *\n * @public\n */\nexport const RustDocExists = defineCargoPolicy({\n\tname: \"RustDocExists\",\n\tdescription:\n\t\t\"Validates that documentation files (README.md, etc.) exist for Rust crates.\",\n\thandler: async (toml: CargoToml, { file, root, config }) => {\n\t\t// Skip workspace root\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 required = config?.required ?? DEFAULT_REQUIRED;\n\t\tconst recommended = config?.recommended ?? [];\n\n\t\tconst missingRequired: string[] = [];\n\t\tconst missingRecommended: string[] = [];\n\n\t\tfor (const fileName of required) {\n\t\t\tif (!existsSync(path.join(dir, fileName))) {\n\t\t\t\tmissingRequired.push(fileName);\n\t\t\t}\n\t\t}\n\n\t\tfor (const fileName of recommended) {\n\t\t\tif (!existsSync(path.join(dir, fileName))) {\n\t\t\t\tmissingRecommended.push(fileName);\n\t\t\t}\n\t\t}\n\n\t\tconst errors: string[] = [];\n\t\tif (missingRequired.length > 0) {\n\t\t\terrors.push(\n\t\t\t\t`Missing required documentation: ${missingRequired.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t\tif (missingRecommended.length > 0) {\n\t\t\terrors.push(\n\t\t\t\t`Missing recommended documentation: ${missingRecommended.join(\", \")}`,\n\t\t\t);\n\t\t}\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\"Create the missing documentation files alongside Cargo.toml.\",\n\t\t\t}));\n\t\t}\n\t\treturn [];\n\t},\n}) satisfies FilePolicyDefinition<RustDocExistsConfig>;\n"]}
@@ -1,8 +1,7 @@
1
- import type { PolicyDefinition } from "../policy.js";
2
1
  /**
3
2
  * Configuration for the RustToolchainExists policy.
4
3
  *
5
- * @alpha
4
+ * @public
6
5
  */
7
6
  export interface RustToolchainExistsConfig {
8
7
  /**
@@ -14,7 +13,15 @@ export interface RustToolchainExistsConfig {
14
13
  /**
15
14
  * A policy that requires a rust-toolchain.toml file for reproducible Rust builds.
16
15
  *
17
- * @alpha
16
+ * @public
18
17
  */
19
- export declare const RustToolchainExists: PolicyDefinition<RustToolchainExistsConfig>;
18
+ export declare const RustToolchainExists: {
19
+ name: string;
20
+ description: string;
21
+ match: RegExp;
22
+ handler: ({ root, config }: import("../policy.js").PolicyArgs<RustToolchainExistsConfig>) => Promise<{
23
+ message: string;
24
+ manualFix: string;
25
+ }[]>;
26
+ };
20
27
  //# sourceMappingURL=RustToolchainExists.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RustToolchainExists.d.ts","sourceRoot":"","sources":["../../src/policies/RustToolchainExists.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAID;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,gBAAgB,CAAC,yBAAyB,CAuBzE,CAAC"}
1
+ {"version":3,"file":"RustToolchainExists.d.ts","sourceRoot":"","sources":["../../src/policies/RustToolchainExists.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAID;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;CAuB2B,CAAC"}