repopo 0.10.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 (340) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/README.md +76 -77
  3. package/THIRD-PARTY-LICENSES.txt +232 -14
  4. package/bin/dev.js +5 -1
  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 +1 -1
  14. package/esm/baseCommand.d.ts.map +1 -1
  15. package/esm/baseCommand.js +7 -10
  16. package/esm/baseCommand.js.map +1 -1
  17. package/esm/commands/check-native.d.ts +25 -0
  18. package/esm/commands/check-native.d.ts.map +1 -0
  19. package/esm/commands/check-native.js +156 -0
  20. package/esm/commands/check-native.js.map +1 -0
  21. package/esm/commands/check.d.ts +7 -34
  22. package/esm/commands/check.d.ts.map +1 -1
  23. package/esm/commands/check.js +76 -265
  24. package/esm/commands/check.js.map +1 -1
  25. package/esm/commands/list.d.ts.map +1 -1
  26. package/esm/commands/list.js +6 -6
  27. package/esm/commands/list.js.map +1 -1
  28. package/esm/concurrency.d.ts +3 -0
  29. package/esm/concurrency.d.ts.map +1 -0
  30. package/esm/concurrency.js +8 -0
  31. package/esm/concurrency.js.map +1 -0
  32. package/esm/config.d.ts +5 -39
  33. package/esm/config.d.ts.map +1 -1
  34. package/esm/config.js +3 -7
  35. package/esm/config.js.map +1 -1
  36. package/esm/context.d.ts +20 -3
  37. package/esm/context.d.ts.map +1 -1
  38. package/esm/context.js +18 -1
  39. package/esm/context.js.map +1 -1
  40. package/esm/executionContractError.d.ts +4 -0
  41. package/esm/executionContractError.d.ts.map +1 -0
  42. package/esm/executionContractError.js +4 -0
  43. package/esm/executionContractError.js.map +1 -0
  44. package/esm/fileCache.d.ts +12 -0
  45. package/esm/fileCache.d.ts.map +1 -0
  46. package/esm/fileCache.js +37 -0
  47. package/esm/fileCache.js.map +1 -0
  48. package/esm/filePaths.d.ts +2 -0
  49. package/esm/filePaths.d.ts.map +1 -0
  50. package/esm/filePaths.js +9 -0
  51. package/esm/filePaths.js.map +1 -0
  52. package/esm/generators.d.ts +0 -20
  53. package/esm/generators.d.ts.map +1 -1
  54. package/esm/generators.js.map +1 -1
  55. package/esm/index.d.ts +3 -11
  56. package/esm/index.d.ts.map +1 -1
  57. package/esm/index.js +3 -14
  58. package/esm/index.js.map +1 -1
  59. package/esm/makePolicy.d.ts +26 -79
  60. package/esm/makePolicy.d.ts.map +1 -1
  61. package/esm/makePolicy.js +51 -95
  62. package/esm/makePolicy.js.map +1 -1
  63. package/esm/perf.d.ts +10 -2
  64. package/esm/perf.d.ts.map +1 -1
  65. package/esm/perf.js +10 -9
  66. package/esm/perf.js.map +1 -1
  67. package/esm/policies/CargoLicenceValidated.d.ts +41 -0
  68. package/esm/policies/CargoLicenceValidated.d.ts.map +1 -0
  69. package/esm/policies/CargoLicenceValidated.js +47 -0
  70. package/esm/policies/CargoLicenceValidated.js.map +1 -0
  71. package/esm/policies/CargoLintsConfigured.d.ts +30 -0
  72. package/esm/policies/CargoLintsConfigured.d.ts.map +1 -0
  73. package/esm/policies/CargoLintsConfigured.js +65 -0
  74. package/esm/policies/CargoLintsConfigured.js.map +1 -0
  75. package/esm/policies/CargoLockPolicy.d.ts +34 -0
  76. package/esm/policies/CargoLockPolicy.d.ts.map +1 -0
  77. package/esm/policies/CargoLockPolicy.js +61 -0
  78. package/esm/policies/CargoLockPolicy.js.map +1 -0
  79. package/esm/policies/CargoTomlRequired.d.ts +34 -0
  80. package/esm/policies/CargoTomlRequired.d.ts.map +1 -0
  81. package/esm/policies/CargoTomlRequired.js +77 -0
  82. package/esm/policies/CargoTomlRequired.js.map +1 -0
  83. package/esm/policies/CargoTomlSorted.d.ts +20 -0
  84. package/esm/policies/CargoTomlSorted.d.ts.map +1 -0
  85. package/esm/policies/CargoTomlSorted.js +168 -0
  86. package/esm/policies/CargoTomlSorted.js.map +1 -0
  87. package/esm/policies/ConditionalScripts.d.ts +10 -8
  88. package/esm/policies/ConditionalScripts.d.ts.map +1 -1
  89. package/esm/policies/ConditionalScripts.js +27 -24
  90. package/esm/policies/ConditionalScripts.js.map +1 -1
  91. package/esm/policies/ExactScripts.d.ts +8 -6
  92. package/esm/policies/ExactScripts.d.ts.map +1 -1
  93. package/esm/policies/ExactScripts.js +18 -20
  94. package/esm/policies/ExactScripts.js.map +1 -1
  95. package/esm/policies/GleamDepVersions.d.ts +25 -0
  96. package/esm/policies/GleamDepVersions.d.ts.map +1 -0
  97. package/esm/policies/GleamDepVersions.js +67 -0
  98. package/esm/policies/GleamDepVersions.js.map +1 -0
  99. package/esm/policies/GleamDocExists.d.ts +24 -0
  100. package/esm/policies/GleamDocExists.d.ts.map +1 -0
  101. package/esm/policies/GleamDocExists.js +39 -0
  102. package/esm/policies/GleamDocExists.js.map +1 -0
  103. package/esm/policies/GleamInternalModulesConfigured.d.ts +21 -0
  104. package/esm/policies/GleamInternalModulesConfigured.d.ts.map +1 -0
  105. package/esm/policies/GleamInternalModulesConfigured.js +32 -0
  106. package/esm/policies/GleamInternalModulesConfigured.js.map +1 -0
  107. package/esm/policies/GleamLicenceConfigured.d.ts +29 -0
  108. package/esm/policies/GleamLicenceConfigured.d.ts.map +1 -0
  109. package/esm/policies/GleamLicenceConfigured.js +36 -0
  110. package/esm/policies/GleamLicenceConfigured.js.map +1 -0
  111. package/esm/policies/GleamManifestCommitted.d.ts +16 -0
  112. package/esm/policies/GleamManifestCommitted.d.ts.map +1 -0
  113. package/esm/policies/GleamManifestCommitted.js +27 -0
  114. package/esm/policies/GleamManifestCommitted.js.map +1 -0
  115. package/esm/policies/GleamMonorepoConsistency.d.ts +38 -0
  116. package/esm/policies/GleamMonorepoConsistency.d.ts.map +1 -0
  117. package/esm/policies/GleamMonorepoConsistency.js +74 -0
  118. package/esm/policies/GleamMonorepoConsistency.js.map +1 -0
  119. package/esm/policies/GleamNameRestrictions.d.ts +25 -0
  120. package/esm/policies/GleamNameRestrictions.d.ts.map +1 -0
  121. package/esm/policies/GleamNameRestrictions.js +44 -0
  122. package/esm/policies/GleamNameRestrictions.js.map +1 -0
  123. package/esm/policies/GleamNoPathDepsInPublished.d.ts +22 -0
  124. package/esm/policies/GleamNoPathDepsInPublished.d.ts.map +1 -0
  125. package/esm/policies/GleamNoPathDepsInPublished.js +43 -0
  126. package/esm/policies/GleamNoPathDepsInPublished.js.map +1 -0
  127. package/esm/policies/GleamPathDepsValid.d.ts +9 -0
  128. package/esm/policies/GleamPathDepsValid.d.ts.map +1 -0
  129. package/esm/policies/GleamPathDepsValid.js +59 -0
  130. package/esm/policies/GleamPathDepsValid.js.map +1 -0
  131. package/esm/policies/GleamProjectStructure.d.ts +32 -0
  132. package/esm/policies/GleamProjectStructure.d.ts.map +1 -0
  133. package/esm/policies/GleamProjectStructure.js +32 -0
  134. package/esm/policies/GleamProjectStructure.js.map +1 -0
  135. package/esm/policies/GleamSharedDependencyVersions.d.ts +37 -0
  136. package/esm/policies/GleamSharedDependencyVersions.d.ts.map +1 -0
  137. package/esm/policies/GleamSharedDependencyVersions.js +101 -0
  138. package/esm/policies/GleamSharedDependencyVersions.js.map +1 -0
  139. package/esm/policies/GleamTomlRequired.d.ts +30 -0
  140. package/esm/policies/GleamTomlRequired.d.ts.map +1 -0
  141. package/esm/policies/GleamTomlRequired.js +37 -0
  142. package/esm/policies/GleamTomlRequired.js.map +1 -0
  143. package/esm/policies/GleamTomlSorted.d.ts +20 -0
  144. package/esm/policies/GleamTomlSorted.d.ts.map +1 -0
  145. package/esm/policies/GleamTomlSorted.js +157 -0
  146. package/esm/policies/GleamTomlSorted.js.map +1 -0
  147. package/esm/policies/GleamVersionConstraint.d.ts +20 -0
  148. package/esm/policies/GleamVersionConstraint.d.ts.map +1 -0
  149. package/esm/policies/GleamVersionConstraint.js +68 -0
  150. package/esm/policies/GleamVersionConstraint.js.map +1 -0
  151. package/esm/policies/HtmlFileHeaders.d.ts +4 -2
  152. package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
  153. package/esm/policies/HtmlFileHeaders.js +2 -2
  154. package/esm/policies/HtmlFileHeaders.js.map +1 -1
  155. package/esm/policies/JsTsFileHeaders.d.ts +4 -2
  156. package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
  157. package/esm/policies/JsTsFileHeaders.js +1 -1
  158. package/esm/policies/JsTsFileHeaders.js.map +1 -1
  159. package/esm/policies/LicenseFileExists.d.ts +10 -4
  160. package/esm/policies/LicenseFileExists.d.ts.map +1 -1
  161. package/esm/policies/LicenseFileExists.js +27 -20
  162. package/esm/policies/LicenseFileExists.js.map +1 -1
  163. package/esm/policies/MutuallyExclusiveScripts.d.ts +8 -6
  164. package/esm/policies/MutuallyExclusiveScripts.d.ts.map +1 -1
  165. package/esm/policies/MutuallyExclusiveScripts.js +9 -13
  166. package/esm/policies/MutuallyExclusiveScripts.js.map +1 -1
  167. package/esm/policies/NoBuildDirectory.d.ts +15 -0
  168. package/esm/policies/NoBuildDirectory.d.ts.map +1 -0
  169. package/esm/policies/NoBuildDirectory.js +24 -0
  170. package/esm/policies/NoBuildDirectory.js.map +1 -0
  171. package/esm/policies/NoJsFileExtensions.d.ts +9 -3
  172. package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
  173. package/esm/policies/NoJsFileExtensions.js +9 -14
  174. package/esm/policies/NoJsFileExtensions.js.map +1 -1
  175. package/esm/policies/NoLargeBinaryFiles.d.ts +9 -4
  176. package/esm/policies/NoLargeBinaryFiles.d.ts.map +1 -1
  177. package/esm/policies/NoLargeBinaryFiles.js +10 -16
  178. package/esm/policies/NoLargeBinaryFiles.js.map +1 -1
  179. package/esm/policies/NoPrivateWorkspaceDependencies.d.ts +10 -6
  180. package/esm/policies/NoPrivateWorkspaceDependencies.d.ts.map +1 -1
  181. package/esm/policies/NoPrivateWorkspaceDependencies.js +12 -14
  182. package/esm/policies/NoPrivateWorkspaceDependencies.js.map +1 -1
  183. package/esm/policies/NoTargetArtifacts.d.ts +14 -0
  184. package/esm/policies/NoTargetArtifacts.d.ts.map +1 -0
  185. package/esm/policies/NoTargetArtifacts.js +37 -0
  186. package/esm/policies/NoTargetArtifacts.js.map +1 -0
  187. package/esm/policies/NoUnsafeWithoutJustification.d.ts +31 -0
  188. package/esm/policies/NoUnsafeWithoutJustification.d.ts.map +1 -0
  189. package/esm/policies/NoUnsafeWithoutJustification.js +79 -0
  190. package/esm/policies/NoUnsafeWithoutJustification.js.map +1 -0
  191. package/esm/policies/NoWildcardDependencies.d.ts +30 -0
  192. package/esm/policies/NoWildcardDependencies.d.ts.map +1 -0
  193. package/esm/policies/NoWildcardDependencies.js +83 -0
  194. package/esm/policies/NoWildcardDependencies.js.map +1 -0
  195. package/esm/policies/PackageAllowedScopes.d.ts +9 -5
  196. package/esm/policies/PackageAllowedScopes.d.ts.map +1 -1
  197. package/esm/policies/PackageAllowedScopes.js +15 -16
  198. package/esm/policies/PackageAllowedScopes.js.map +1 -1
  199. package/esm/policies/PackageEsmType.d.ts +7 -5
  200. package/esm/policies/PackageEsmType.d.ts.map +1 -1
  201. package/esm/policies/PackageEsmType.js +38 -36
  202. package/esm/policies/PackageEsmType.js.map +1 -1
  203. package/esm/policies/PackageFolderName.d.ts +8 -6
  204. package/esm/policies/PackageFolderName.d.ts.map +1 -1
  205. package/esm/policies/PackageFolderName.js +13 -16
  206. package/esm/policies/PackageFolderName.js.map +1 -1
  207. package/esm/policies/PackageJsonProperties.d.ts +5 -3
  208. package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
  209. package/esm/policies/PackageJsonProperties.js +18 -21
  210. package/esm/policies/PackageJsonProperties.js.map +1 -1
  211. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +2 -7
  212. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
  213. package/esm/policies/PackageJsonRepoDirectoryProperty.js +29 -42
  214. package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
  215. package/esm/policies/PackageJsonSorted.d.ts +2 -2
  216. package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
  217. package/esm/policies/PackageJsonSorted.js +51 -31
  218. package/esm/policies/PackageJsonSorted.js.map +1 -1
  219. package/esm/policies/PackageLicense.d.ts +4 -4
  220. package/esm/policies/PackageLicense.d.ts.map +1 -1
  221. package/esm/policies/PackageLicense.js +32 -54
  222. package/esm/policies/PackageLicense.js.map +1 -1
  223. package/esm/policies/PackagePrivateField.d.ts +12 -8
  224. package/esm/policies/PackagePrivateField.d.ts.map +1 -1
  225. package/esm/policies/PackagePrivateField.js +34 -25
  226. package/esm/policies/PackagePrivateField.js.map +1 -1
  227. package/esm/policies/PackageReadme.d.ts +6 -5
  228. package/esm/policies/PackageReadme.d.ts.map +1 -1
  229. package/esm/policies/PackageReadme.js +24 -61
  230. package/esm/policies/PackageReadme.js.map +1 -1
  231. package/esm/policies/PackageScripts.d.ts +26 -22
  232. package/esm/policies/PackageScripts.d.ts.map +1 -1
  233. package/esm/policies/PackageScripts.js +42 -38
  234. package/esm/policies/PackageScripts.js.map +1 -1
  235. package/esm/policies/PackageTestScripts.d.ts +10 -6
  236. package/esm/policies/PackageTestScripts.d.ts.map +1 -1
  237. package/esm/policies/PackageTestScripts.js +17 -19
  238. package/esm/policies/PackageTestScripts.js.map +1 -1
  239. package/esm/policies/PublicApiDocumented.d.ts +21 -0
  240. package/esm/policies/PublicApiDocumented.d.ts.map +1 -0
  241. package/esm/policies/PublicApiDocumented.js +38 -0
  242. package/esm/policies/PublicApiDocumented.js.map +1 -0
  243. package/esm/policies/RequiredGitignorePatterns.d.ts +11 -4
  244. package/esm/policies/RequiredGitignorePatterns.d.ts.map +1 -1
  245. package/esm/policies/RequiredGitignorePatterns.js +29 -36
  246. package/esm/policies/RequiredGitignorePatterns.js.map +1 -1
  247. package/esm/policies/RequiredScripts.d.ts +9 -7
  248. package/esm/policies/RequiredScripts.d.ts.map +1 -1
  249. package/esm/policies/RequiredScripts.js +27 -26
  250. package/esm/policies/RequiredScripts.js.map +1 -1
  251. package/esm/policies/RustDocExists.d.ts +24 -0
  252. package/esm/policies/RustDocExists.d.ts.map +1 -0
  253. package/esm/policies/RustDocExists.js +49 -0
  254. package/esm/policies/RustDocExists.js.map +1 -0
  255. package/esm/policies/RustToolchainExists.d.ts +27 -0
  256. package/esm/policies/RustToolchainExists.d.ts.map +1 -0
  257. package/esm/policies/RustToolchainExists.js +28 -0
  258. package/esm/policies/RustToolchainExists.js.map +1 -0
  259. package/esm/policies/RustfmtConfigExists.d.ts +27 -0
  260. package/esm/policies/RustfmtConfigExists.d.ts.map +1 -0
  261. package/esm/policies/RustfmtConfigExists.js +28 -0
  262. package/esm/policies/RustfmtConfigExists.js.map +1 -0
  263. package/esm/policies/ScriptContains.d.ts +9 -7
  264. package/esm/policies/ScriptContains.d.ts.map +1 -1
  265. package/esm/policies/ScriptContains.js +9 -13
  266. package/esm/policies/ScriptContains.js.map +1 -1
  267. package/esm/policies/SharedDependencyVersions.d.ts +29 -0
  268. package/esm/policies/SharedDependencyVersions.d.ts.map +1 -0
  269. package/esm/policies/SharedDependencyVersions.js +143 -0
  270. package/esm/policies/SharedDependencyVersions.js.map +1 -0
  271. package/esm/policies/WorkspaceInheritance.d.ts +31 -0
  272. package/esm/policies/WorkspaceInheritance.d.ts.map +1 -0
  273. package/esm/policies/WorkspaceInheritance.js +93 -0
  274. package/esm/policies/WorkspaceInheritance.js.map +1 -0
  275. package/esm/policies/WorkspaceMembersValid.d.ts +27 -0
  276. package/esm/policies/WorkspaceMembersValid.d.ts.map +1 -0
  277. package/esm/policies/WorkspaceMembersValid.js +87 -0
  278. package/esm/policies/WorkspaceMembersValid.js.map +1 -0
  279. package/esm/policies/constants.d.ts +8 -0
  280. package/esm/policies/constants.d.ts.map +1 -1
  281. package/esm/policies/constants.js +9 -1
  282. package/esm/policies/constants.js.map +1 -1
  283. package/esm/policies.d.ts +43 -5
  284. package/esm/policies.d.ts.map +1 -1
  285. package/esm/policies.js +63 -6
  286. package/esm/policies.js.map +1 -1
  287. package/esm/policy.d.ts +65 -269
  288. package/esm/policy.d.ts.map +1 -1
  289. package/esm/policy.js +1 -122
  290. package/esm/policy.js.map +1 -1
  291. package/esm/policyDefiners/defineCargoPolicy.d.ts +82 -0
  292. package/esm/policyDefiners/defineCargoPolicy.d.ts.map +1 -0
  293. package/esm/policyDefiners/defineCargoPolicy.js +42 -0
  294. package/esm/policyDefiners/defineCargoPolicy.js.map +1 -0
  295. package/esm/policyDefiners/defineFileHeaderPolicy.d.ts +27 -14
  296. package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -1
  297. package/esm/policyDefiners/defineFileHeaderPolicy.js +19 -39
  298. package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -1
  299. package/esm/policyDefiners/defineGleamPolicy.d.ts +81 -0
  300. package/esm/policyDefiners/defineGleamPolicy.d.ts.map +1 -0
  301. package/esm/policyDefiners/defineGleamPolicy.js +42 -0
  302. package/esm/policyDefiners/defineGleamPolicy.js.map +1 -0
  303. package/esm/policyDefiners/definePackagePolicy.d.ts +24 -13
  304. package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -1
  305. package/esm/policyDefiners/definePackagePolicy.js +9 -32
  306. package/esm/policyDefiners/definePackagePolicy.js.map +1 -1
  307. package/esm/policyDefiners/spdxValidator.d.ts +66 -0
  308. package/esm/policyDefiners/spdxValidator.d.ts.map +1 -0
  309. package/esm/policyDefiners/spdxValidator.js +139 -0
  310. package/esm/policyDefiners/spdxValidator.js.map +1 -0
  311. package/esm/policyDefiners/tomlParser.d.ts +8 -0
  312. package/esm/policyDefiners/tomlParser.d.ts.map +1 -0
  313. package/esm/policyDefiners/tomlParser.js +17 -0
  314. package/esm/policyDefiners/tomlParser.js.map +1 -0
  315. package/esm/policyExecution.d.ts +19 -0
  316. package/esm/policyExecution.d.ts.map +1 -0
  317. package/esm/policyExecution.js +224 -0
  318. package/esm/policyExecution.js.map +1 -0
  319. package/esm/repositoryFiles.d.ts +4 -0
  320. package/esm/repositoryFiles.d.ts.map +1 -0
  321. package/esm/repositoryFiles.js +8 -0
  322. package/esm/repositoryFiles.js.map +1 -0
  323. package/esm/runner.d.ts +85 -0
  324. package/esm/runner.d.ts.map +1 -0
  325. package/esm/runner.js +189 -0
  326. package/esm/runner.js.map +1 -0
  327. package/esm/settlePolicyPromise.d.ts +4 -0
  328. package/esm/settlePolicyPromise.d.ts.map +1 -0
  329. package/esm/settlePolicyPromise.js +10 -0
  330. package/esm/settlePolicyPromise.js.map +1 -0
  331. package/esm/tsdoc-metadata.json +1 -1
  332. package/esm/utils/safePaths.d.ts +9 -0
  333. package/esm/utils/safePaths.d.ts.map +1 -0
  334. package/esm/utils/safePaths.js +40 -0
  335. package/esm/utils/safePaths.js.map +1 -0
  336. package/oclif.manifest.json +117 -3
  337. package/package.json +66 -36
  338. package/scripts/benchmark.mjs +341 -0
  339. package/scripts/postinstall.mjs +154 -0
  340. package/sidecar/sidecar.mjs +399 -0
@@ -0,0 +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,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"]}
@@ -0,0 +1,34 @@
1
+ import type { FilePolicyDefinition } from "../policy.js";
2
+ /**
3
+ * Configuration for the CargoTomlRequired policy.
4
+ *
5
+ * @public
6
+ */
7
+ export interface CargoTomlRequiredConfig {
8
+ /**
9
+ * Fields that must exist in the [package] section.
10
+ * @defaultValue ["license", "description"]
11
+ */
12
+ required?: string[];
13
+ /**
14
+ * Minimum Rust edition to require (e.g., "2021").
15
+ * If set, the `edition` field must exist and be at least this value.
16
+ */
17
+ minimumEdition?: string;
18
+ /**
19
+ * If true, require the `rust-version` field (MSRV) to be set.
20
+ * @defaultValue false
21
+ */
22
+ requireRustVersion?: boolean;
23
+ /**
24
+ * Specific field values to enforce. Keys are field names, values are expected values.
25
+ */
26
+ expectedValues?: Record<string, string>;
27
+ }
28
+ /**
29
+ * A policy that enforces required fields exist in Cargo.toml [package] section.
30
+ *
31
+ * @public
32
+ */
33
+ export declare const CargoTomlRequired: FilePolicyDefinition<CargoTomlRequiredConfig>;
34
+ //# sourceMappingURL=CargoTomlRequired.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,77 @@
1
+ import { defineCargoPolicy, } from "../policyDefiners/defineCargoPolicy.js";
2
+ const DEFAULT_REQUIRED_FIELDS = ["license", "description"];
3
+ const VALID_EDITIONS = ["2015", "2018", "2021", "2024"];
4
+ function checkRequiredFields(pkg, config, errors) {
5
+ const requiredFields = config?.required ?? DEFAULT_REQUIRED_FIELDS;
6
+ for (const field of requiredFields) {
7
+ if (pkg[field] === undefined) {
8
+ errors.push(`Missing required field: package.${field}`);
9
+ }
10
+ }
11
+ }
12
+ function checkExpectedValues(pkg, config, errors) {
13
+ if (!config?.expectedValues) {
14
+ return;
15
+ }
16
+ for (const [field, expected] of Object.entries(config.expectedValues)) {
17
+ const actual = pkg[field];
18
+ if (actual === undefined) {
19
+ errors.push(`Missing required field: package.${field}`);
20
+ }
21
+ else if (String(actual) !== expected) {
22
+ errors.push(`Expected package.${field} = "${expected}", got "${String(actual)}"`);
23
+ }
24
+ }
25
+ }
26
+ function checkRustVersion(pkg, config, errors) {
27
+ if (config?.requireRustVersion && pkg["rust-version"] === undefined) {
28
+ errors.push("Missing package.rust-version (MSRV). Set the minimum supported Rust version.");
29
+ }
30
+ }
31
+ function checkMinimumEdition(pkg, config, errors) {
32
+ if (!config?.minimumEdition) {
33
+ return;
34
+ }
35
+ const edition = pkg.edition;
36
+ if (edition === undefined) {
37
+ errors.push("Missing package.edition field.");
38
+ }
39
+ else if (!VALID_EDITIONS.includes(edition)) {
40
+ errors.push(`Invalid edition "${edition}". Must be one of: ${VALID_EDITIONS.join(", ")}`);
41
+ }
42
+ else if (edition < config.minimumEdition) {
43
+ errors.push(`Edition "${edition}" is below minimum "${config.minimumEdition}".`);
44
+ }
45
+ }
46
+ /**
47
+ * A policy that enforces required fields exist in Cargo.toml [package] section.
48
+ *
49
+ * @public
50
+ */
51
+ export const CargoTomlRequired = defineCargoPolicy({
52
+ name: "CargoTomlRequired",
53
+ description: "Ensures Cargo.toml files contain required fields in the [package] section.",
54
+ handler: async (toml, { config }) => {
55
+ const pkg = toml.package;
56
+ if (!pkg) {
57
+ // Workspace root Cargo.toml may not have [package]
58
+ if (toml.workspace !== undefined) {
59
+ return [];
60
+ }
61
+ return [{ message: "Missing [package] section in Cargo.toml" }];
62
+ }
63
+ const errors = [];
64
+ checkRequiredFields(pkg, config, errors);
65
+ checkExpectedValues(pkg, config, errors);
66
+ checkRustVersion(pkg, config, errors);
67
+ checkMinimumEdition(pkg, config, errors);
68
+ if (errors.length > 0) {
69
+ return errors.map((message) => ({
70
+ message,
71
+ manualFix: "Add the missing fields to your Cargo.toml [package] section.",
72
+ }));
73
+ }
74
+ return [];
75
+ },
76
+ });
77
+ //# sourceMappingURL=CargoTomlRequired.js.map
@@ -0,0 +1 @@
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"]}
@@ -0,0 +1,20 @@
1
+ import type { FilePolicyDefinition } from "../policy.js";
2
+ /**
3
+ * Configuration for the CargoTomlSorted policy.
4
+ *
5
+ * @public
6
+ */
7
+ export interface CargoTomlSortedConfig {
8
+ /**
9
+ * Sections whose keys should be sorted alphabetically.
10
+ * @defaultValue ["dependencies", "dev-dependencies", "build-dependencies"]
11
+ */
12
+ sections?: string[];
13
+ }
14
+ /**
15
+ * A policy that ensures dependency sections in Cargo.toml are sorted alphabetically.
16
+ *
17
+ * @public
18
+ */
19
+ export declare const CargoTomlSorted: FilePolicyDefinition<CargoTomlSortedConfig>;
20
+ //# sourceMappingURL=CargoTomlSorted.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,168 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import { resolve } from "pathe";
3
+ import { defineCargoPolicy, } from "../policyDefiners/defineCargoPolicy.js";
4
+ const DEFAULT_SORTED_SECTIONS = [
5
+ "dependencies",
6
+ "dev-dependencies",
7
+ "build-dependencies",
8
+ ];
9
+ function isSorted(keys) {
10
+ for (let i = 1; i < keys.length; i++) {
11
+ const current = keys[i];
12
+ const previous = keys[i - 1];
13
+ if (current !== undefined && previous !== undefined && current < previous) {
14
+ return false;
15
+ }
16
+ }
17
+ return true;
18
+ }
19
+ const SECTION_HEADER_REGEX = /^\[([^\]]+)\]\s*$/;
20
+ const NEXT_SECTION_REGEX = /^\[/;
21
+ const KEY_VALUE_REGEX = /^(\S+)\s*=/;
22
+ /**
23
+ * Process a single line in a dependency section, updating entries and current state.
24
+ */
25
+ function processEntryLine(entryLine, entries, currentEntry) {
26
+ // Comment line - attach to next entry
27
+ if (entryLine.trim().startsWith("#")) {
28
+ if (currentEntry) {
29
+ currentEntry.lines.push(entryLine);
30
+ }
31
+ else {
32
+ return { key: "", lines: [entryLine] };
33
+ }
34
+ return currentEntry;
35
+ }
36
+ // Key = value line
37
+ const keyMatch = entryLine.match(KEY_VALUE_REGEX);
38
+ if (keyMatch) {
39
+ if (currentEntry) {
40
+ entries.push(currentEntry);
41
+ }
42
+ const key = keyMatch[1] ?? "";
43
+ return { key, lines: [entryLine] };
44
+ }
45
+ if (currentEntry) {
46
+ // Continuation line (multiline value)
47
+ currentEntry.lines.push(entryLine);
48
+ }
49
+ return currentEntry;
50
+ }
51
+ /**
52
+ * Collect sorted entries from a TOML dependency section.
53
+ */
54
+ function collectAndSortEntries(lines, startIndex) {
55
+ const entries = [];
56
+ let currentEntry;
57
+ let i = startIndex;
58
+ while (i < lines.length) {
59
+ const entryLine = lines[i];
60
+ if (entryLine === undefined) {
61
+ break;
62
+ }
63
+ // Stop at next section
64
+ if (NEXT_SECTION_REGEX.test(entryLine)) {
65
+ break;
66
+ }
67
+ // Skip pure blank lines between entries
68
+ if (entryLine.trim() === "") {
69
+ i++;
70
+ continue;
71
+ }
72
+ currentEntry = processEntryLine(entryLine, entries, currentEntry);
73
+ i++;
74
+ }
75
+ if (currentEntry) {
76
+ entries.push(currentEntry);
77
+ }
78
+ entries.sort((a, b) => a.key.localeCompare(b.key));
79
+ return { entries, nextIndex: i };
80
+ }
81
+ /**
82
+ * Rebuild TOML content with sorted dependency sections.
83
+ * Uses line-based manipulation to preserve formatting and comments.
84
+ */
85
+ function sortTomlSections(content, sectionsToSort) {
86
+ const lines = content.split("\n");
87
+ const result = [];
88
+ let i = 0;
89
+ while (i < lines.length) {
90
+ const line = lines[i];
91
+ if (line === undefined) {
92
+ break;
93
+ }
94
+ const sectionMatch = line.match(SECTION_HEADER_REGEX);
95
+ if (sectionMatch) {
96
+ const sectionName = sectionMatch[1] ?? "";
97
+ if (sectionsToSort.includes(sectionName)) {
98
+ result.push(line);
99
+ i++;
100
+ const { entries, nextIndex } = collectAndSortEntries(lines, i);
101
+ for (const entry of entries) {
102
+ result.push(...entry.lines);
103
+ }
104
+ i = nextIndex;
105
+ continue;
106
+ }
107
+ }
108
+ result.push(line);
109
+ i++;
110
+ }
111
+ return result.join("\n");
112
+ }
113
+ /**
114
+ * A policy that ensures dependency sections in Cargo.toml are sorted alphabetically.
115
+ *
116
+ * @public
117
+ */
118
+ export const CargoTomlSorted = defineCargoPolicy({
119
+ name: "CargoTomlSorted",
120
+ description: "Ensures dependency sections in Cargo.toml are sorted alphabetically.",
121
+ handler: async (toml, { file, root, resolve: shouldResolve, config }) => {
122
+ const sections = config?.sections ?? DEFAULT_SORTED_SECTIONS;
123
+ const unsortedSections = [];
124
+ for (const section of sections) {
125
+ const sectionData = toml[section];
126
+ if (sectionData !== undefined) {
127
+ const keys = Object.keys(sectionData);
128
+ if (!isSorted(keys)) {
129
+ unsortedSections.push(section);
130
+ }
131
+ }
132
+ }
133
+ if (unsortedSections.length === 0) {
134
+ return [];
135
+ }
136
+ if (shouldResolve) {
137
+ try {
138
+ const { readFile } = await import("node:fs/promises");
139
+ const filePath = resolve(root, file);
140
+ const content = await readFile(filePath, "utf-8");
141
+ const sorted = sortTomlSections(content, unsortedSections);
142
+ await writeFile(filePath, sorted);
143
+ return [
144
+ {
145
+ message: `Unsorted sections: [${unsortedSections.join("], [")}]`,
146
+ fixStatus: "fixed",
147
+ },
148
+ ];
149
+ }
150
+ catch {
151
+ return [
152
+ {
153
+ message: `Unsorted sections: [${unsortedSections.join("], [")}]. Auto-fix failed.`,
154
+ fixStatus: "failed",
155
+ },
156
+ ];
157
+ }
158
+ }
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
+ ];
166
+ },
167
+ });
168
+ //# sourceMappingURL=CargoTomlSorted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CargoTomlSorted.js","sourceRoot":"","sources":["../../src/policies/CargoTomlSorted.ts"],"names":[],"mappings":"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","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":"AAIA;;;;;;;;;;;;;;;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"}
@@ -1,4 +1,5 @@
1
1
  import jsonfile from "jsonfile";
2
+ import { resolve as resolvePath } from "pathe";
2
3
  import { definePackagePolicy } from "../policyDefiners/definePackagePolicy.js";
3
4
  const POLICY_NAME = "ConditionalScripts";
4
5
  /**
@@ -76,38 +77,39 @@ async function fixMissingScripts(json, file, missingWithDefaults, existingScript
76
77
  *
77
78
  * @example
78
79
  * ```typescript
79
- * import { policy } from "repopo";
80
+ * import { makePolicy } from "repopo";
80
81
  * import { ConditionalScripts } from "repopo/policies";
81
82
  *
82
- * policy(ConditionalScripts, {
83
+ * makePolicy(ConditionalScripts, { config: {
83
84
  * rules: [
84
85
  * // If "build" exists, "clean" must also exist (with auto-fix default)
85
86
  * { ifPresent: "build", requires: [{ clean: "rimraf dist" }] },
86
87
  * // If "test" exists, "test:coverage" must also exist (no auto-fix)
87
88
  * { ifPresent: "test", requires: ["test:coverage"] },
88
89
  * ],
89
- * })
90
+ * } })
90
91
  * ```
91
92
  *
92
- * @alpha
93
+ * @public
93
94
  */
94
95
  export const ConditionalScripts = definePackagePolicy({
96
+ requiresConfig: true,
95
97
  name: POLICY_NAME,
96
98
  description: "Validates that if certain scripts exist, other required scripts must also exist.",
97
- handler: async (json, { file, resolve, config }) => {
99
+ handler: async (json, { file, root, resolve, config }) => {
98
100
  if (config === undefined || config.rules.length === 0) {
99
- return true;
101
+ return [];
100
102
  }
101
103
  const scripts = json.scripts ?? {};
102
104
  const validation = validateConditionalRules(scripts, config.rules);
103
105
  if (validation.violations.length === 0) {
104
- return true;
106
+ return [];
105
107
  }
106
108
  const errors = formatViolationErrors(validation.violations);
107
109
  const hasAutoFixableErrors = validation.missingWithDefaults.length > 0;
108
110
  if (resolve && hasAutoFixableErrors) {
109
111
  try {
110
- const fixedScripts = await fixMissingScripts(json, file, validation.missingWithDefaults, scripts);
112
+ const fixedScripts = await fixMissingScripts(json, resolvePath(root, file), validation.missingWithDefaults, scripts);
111
113
  // Re-validate after fix to check for remaining errors
112
114
  const updatedScripts = { ...scripts };
113
115
  for (const name of fixedScripts) {
@@ -118,27 +120,28 @@ export const ConditionalScripts = definePackagePolicy({
118
120
  }
119
121
  const revalidation = validateConditionalRules(updatedScripts, config.rules);
120
122
  const remainingErrors = formatViolationErrors(revalidation.violations);
121
- return {
122
- name: POLICY_NAME,
123
- file,
124
- resolved: remainingErrors.length === 0,
125
- errorMessages: remainingErrors.length > 0
126
- ? [
127
- `Fixed scripts: ${fixedScripts.join(", ")}. Remaining errors:\n${remainingErrors.join("\n")}`,
128
- ]
129
- : [`Fixed scripts: ${fixedScripts.join(", ")}`],
130
- };
123
+ return [
124
+ ...fixedScripts.map((name) => ({
125
+ message: `Fixed scripts: ${name}`,
126
+ fixStatus: "fixed",
127
+ })),
128
+ ...remainingErrors.map((message) => ({
129
+ message: `Remaining errors:\n${message}`,
130
+ })),
131
+ ];
131
132
  }
132
133
  catch {
133
134
  // Fall through to return regular failure
134
135
  }
135
136
  }
136
- return {
137
- name: POLICY_NAME,
138
- file,
139
- autoFixable: hasAutoFixableErrors,
140
- errorMessages: errors,
141
- };
137
+ return errors.map((message) => ({
138
+ message,
139
+ fixStatus: hasAutoFixableErrors
140
+ ? resolve
141
+ ? "failed"
142
+ : "available"
143
+ : undefined,
144
+ }));
142
145
  },
143
146
  });
144
147
  //# sourceMappingURL=ConditionalScripts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConditionalScripts.js","sourceRoot":"","sources":["../../src/policies/ConditionalScripts.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAyE/E,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAOzC;;GAEG;AACH,SAAS,UAAU,CAAC,KAA6B;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACd,yEAAyE,IAAI,CAAC,MAAM,OAAO,CAC3F,CAAC;IACH,CAAC;IACD,sEAAsE;IACtE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IACtB,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC;AAYD,SAAS,wBAAwB,CAChC,OAA2C,EAC3C,KAA8B;IAE9B,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,MAAM,mBAAmB,GAAkD,EAAE,CAAC;IAC9E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,8CAA8C;QAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7C,SAAS;QACV,CAAC;QAED,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;gBACnC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1D,mBAAmB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;oBACjD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACvB,CAAC;YACF,CAAC;QACF,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC;gBACf,aAAa,EAAE,IAAI,CAAC,SAAS;gBAC7B,cAAc;aACd,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,qBAAqB,CAAC,UAA2B;IACzD,OAAO,UAAU,CAAC,GAAG,CACpB,CAAC,CAAC,EAAE,EAAE,CACL,WAAW,CAAC,CAAC,aAAa,2DAA2D,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC/B,IAAiB,EACjB,IAAY,EACZ,mBAAkE,EAClE,eAAmD;IAEnD,MAAM,cAAc,GAA2B,EAAE,CAAC;IAElD,wBAAwB;IACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,cAAc,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,oCAAoC;IACpC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,mBAAmB,EAAE,CAAC;QAC1D,cAAc,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC;QACpC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,QAAQ,CAAC,SAAS,CACvB,IAAI,EACJ,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,EACpC,EAAE,MAAM,EAAE,CAAC,EAAE,CACb,CAAC;IAEF,OAAO,YAAY,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAGnD;IACD,IAAI,EAAE,WAAW;IACjB,WAAW,EACV,kFAAkF;IACnF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAClD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QACnC,MAAM,UAAU,GAAG,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnE,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5D,MAAM,oBAAoB,GAAG,UAAU,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;QAEvE,IAAI,OAAO,IAAI,oBAAoB,EAAE,CAAC;YACrC,IAAI,CAAC;gBACJ,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAC3C,IAAI,EACJ,IAAI,EACJ,UAAU,CAAC,mBAAmB,EAC9B,OAAO,CACP,CAAC;gBAEF,sDAAsD;gBACtD,MAAM,cAAc,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;gBACtC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;oBACjC,MAAM,KAAK,GAAG,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CACtB,CAAC;oBACF,IAAI,KAAK,EAAE,CAAC;wBACX,cAAc,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC;oBAC3C,CAAC;gBACF,CAAC;gBAED,MAAM,YAAY,GAAG,wBAAwB,CAC5C,cAAc,EACd,MAAM,CAAC,KAAK,CACZ,CAAC;gBACF,MAAM,eAAe,GAAG,qBAAqB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;gBAEvE,OAAO;oBACN,IAAI,EAAE,WAAW;oBACjB,IAAI;oBACJ,QAAQ,EAAE,eAAe,CAAC,MAAM,KAAK,CAAC;oBACtC,aAAa,EACZ,eAAe,CAAC,MAAM,GAAG,CAAC;wBACzB,CAAC,CAAC;4BACA,kBAAkB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;yBAC7F;wBACF,CAAC,CAAC,CAAC,kBAAkB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;iBACjD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACR,yCAAyC;YAC1C,CAAC;QACF,CAAC;QAED,OAAO;YACN,IAAI,EAAE,WAAW;YACjB,IAAI;YACJ,WAAW,EAAE,oBAAoB;YACjC,aAAa,EAAE,MAAM;SACrB,CAAC;IACH,CAAC;CACD,CAAC,CAAC","sourcesContent":["import jsonfile from \"jsonfile\";\nimport type { PackageJson } from \"type-fest\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * A required script entry for conditional requirements. 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 * { clean: \"rimraf dist\" }\n * ```\n *\n * @alpha\n */\nexport type ConditionalScriptEntry = string | Record<string, string>;\n\n/**\n * Configuration for a conditional script requirement.\n *\n * @alpha\n */\nexport interface ConditionalScriptRule {\n\t/**\n\t * The script that triggers the requirement.\n\t * If this script exists, then `requires` must also exist.\n\t */\n\tifPresent: string;\n\n\t/**\n\t * Scripts that must be present if `ifPresent` script exists.\n\t *\n\t * @remarks\n\t * Each entry can be:\n\t * - A string: Script must exist, no auto-fix available\n\t * - An object `{ scriptName: \"default value\" }`: Script must exist, auto-fix adds the\n\t * default value if missing\n\t *\n\t * @example\n\t * ```typescript\n\t * requires: [\"test\", { clean: \"rimraf dist\" }]\n\t * ```\n\t */\n\trequires: ConditionalScriptEntry[];\n}\n\n/**\n * Configuration for the ConditionalScripts policy.\n *\n * @alpha\n */\nexport interface ConditionalScriptsConfig {\n\t/**\n\t * Conditional script requirements. If a script is present, other scripts must also exist.\n\t *\n\t * @remarks\n\t * This is useful for enforcing that packages with a \"build\" script also have a \"clean\" script,\n\t * or packages with \"test\" also have \"test:coverage\".\n\t *\n\t * @example\n\t * ```typescript\n\t * rules: [\n\t * { ifPresent: \"build\", requires: [{ clean: \"rimraf dist\" }] },\n\t * { ifPresent: \"test\", requires: [\"test:coverage\"] },\n\t * ]\n\t * ```\n\t */\n\trules: ConditionalScriptRule[];\n}\n\nconst POLICY_NAME = \"ConditionalScripts\";\n\ninterface ParsedEntry {\n\tname: string;\n\tdefaultValue?: string;\n}\n\n/**\n * Extracts script name and optional default value from a ConditionalScriptEntry.\n */\nfunction parseEntry(entry: ConditionalScriptEntry): 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 conditional 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 RuleViolation {\n\ttriggerScript: string;\n\tmissingScripts: string[];\n}\n\ninterface ValidationResult {\n\tviolations: RuleViolation[];\n\tmissingWithDefaults: Array<{ name: string; defaultValue: string }>;\n}\n\nfunction validateConditionalRules(\n\tscripts: Record<string, string | undefined>,\n\trules: ConditionalScriptRule[],\n): ValidationResult {\n\tconst violations: RuleViolation[] = [];\n\tconst missingWithDefaults: Array<{ name: string; defaultValue: string }> = [];\n\tconst seenMissing = new Set<string>();\n\n\tfor (const rule of rules) {\n\t\t// Skip if the triggering script doesn't exist\n\t\tif (!Object.hasOwn(scripts, rule.ifPresent)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst missingScripts: string[] = [];\n\t\tfor (const entry of rule.requires) {\n\t\t\tconst { name, defaultValue } = parseEntry(entry);\n\t\t\tif (!Object.hasOwn(scripts, name)) {\n\t\t\t\tmissingScripts.push(name);\n\t\t\t\tif (defaultValue !== undefined && !seenMissing.has(name)) {\n\t\t\t\t\tmissingWithDefaults.push({ name, defaultValue });\n\t\t\t\t\tseenMissing.add(name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (missingScripts.length > 0) {\n\t\t\tviolations.push({\n\t\t\t\ttriggerScript: rule.ifPresent,\n\t\t\t\tmissingScripts,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { violations, missingWithDefaults };\n}\n\nfunction formatViolationErrors(violations: RuleViolation[]): string[] {\n\treturn violations.map(\n\t\t(v) =>\n\t\t\t`Script \"${v.triggerScript}\" is present, but required companion script(s) missing: ${v.missingScripts.join(\", \")}`,\n\t);\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 conditional script requirements in package.json.\n *\n * @remarks\n * Use this policy when you want to enforce that the presence of one script\n * requires other scripts to also exist. For example, if \"build\" exists,\n * then \"clean\" must also exist.\n *\n * @example\n * ```typescript\n * import { policy } from \"repopo\";\n * import { ConditionalScripts } from \"repopo/policies\";\n *\n * policy(ConditionalScripts, {\n * rules: [\n * // If \"build\" exists, \"clean\" must also exist (with auto-fix default)\n * { ifPresent: \"build\", requires: [{ clean: \"rimraf dist\" }] },\n * // If \"test\" exists, \"test:coverage\" must also exist (no auto-fix)\n * { ifPresent: \"test\", requires: [\"test:coverage\"] },\n * ],\n * })\n * ```\n *\n * @alpha\n */\nexport const ConditionalScripts = definePackagePolicy<\n\tPackageJson,\n\tConditionalScriptsConfig | undefined\n>({\n\tname: POLICY_NAME,\n\tdescription:\n\t\t\"Validates that if certain scripts exist, other required scripts must also exist.\",\n\thandler: async (json, { file, resolve, config }) => {\n\t\tif (config === undefined || config.rules.length === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst scripts = json.scripts ?? {};\n\t\tconst validation = validateConditionalRules(scripts, config.rules);\n\n\t\tif (validation.violations.length === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst errors = formatViolationErrors(validation.violations);\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\tfile,\n\t\t\t\t\tvalidation.missingWithDefaults,\n\t\t\t\t\tscripts,\n\t\t\t\t);\n\n\t\t\t\t// Re-validate after fix to check for remaining errors\n\t\t\t\tconst updatedScripts = { ...scripts };\n\t\t\t\tfor (const name of fixedScripts) {\n\t\t\t\t\tconst entry = validation.missingWithDefaults.find(\n\t\t\t\t\t\t(m) => m.name === name,\n\t\t\t\t\t);\n\t\t\t\t\tif (entry) {\n\t\t\t\t\t\tupdatedScripts[name] = entry.defaultValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst revalidation = validateConditionalRules(\n\t\t\t\t\tupdatedScripts,\n\t\t\t\t\tconfig.rules,\n\t\t\t\t);\n\t\t\t\tconst remainingErrors = formatViolationErrors(revalidation.violations);\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: remainingErrors.length === 0,\n\t\t\t\t\terrorMessages:\n\t\t\t\t\t\tremainingErrors.length > 0\n\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t`Fixed scripts: ${fixedScripts.join(\", \")}. Remaining errors:\\n${remainingErrors.join(\"\\n\")}`,\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: errors,\n\t\t};\n\t},\n});\n"]}
1
+ {"version":3,"file":"ConditionalScripts.js","sourceRoot":"","sources":["../../src/policies/ConditionalScripts.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 for conditional requirements. 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 * { clean: \"rimraf dist\" }\n * ```\n *\n * @public\n */\nexport type ConditionalScriptEntry = string | Record<string, string>;\n\n/**\n * Configuration for a conditional script requirement.\n *\n * @public\n */\nexport interface ConditionalScriptRule {\n\t/**\n\t * The script that triggers the requirement.\n\t * If this script exists, then `requires` must also exist.\n\t */\n\tifPresent: string;\n\n\t/**\n\t * Scripts that must be present if `ifPresent` script exists.\n\t *\n\t * @remarks\n\t * Each entry can be:\n\t * - A string: Script must exist, no auto-fix available\n\t * - An object `{ scriptName: \"default value\" }`: Script must exist, auto-fix adds the\n\t * default value if missing\n\t *\n\t * @example\n\t * ```typescript\n\t * requires: [\"test\", { clean: \"rimraf dist\" }]\n\t * ```\n\t */\n\trequires: ConditionalScriptEntry[];\n}\n\n/**\n * Configuration for the ConditionalScripts policy.\n *\n * @public\n */\nexport interface ConditionalScriptsConfig {\n\t/**\n\t * Conditional script requirements. If a script is present, other scripts must also exist.\n\t *\n\t * @remarks\n\t * This is useful for enforcing that packages with a \"build\" script also have a \"clean\" script,\n\t * or packages with \"test\" also have \"test:coverage\".\n\t *\n\t * @example\n\t * ```typescript\n\t * rules: [\n\t * { ifPresent: \"build\", requires: [{ clean: \"rimraf dist\" }] },\n\t * { ifPresent: \"test\", requires: [\"test:coverage\"] },\n\t * ]\n\t * ```\n\t */\n\trules: ConditionalScriptRule[];\n}\n\nconst POLICY_NAME = \"ConditionalScripts\";\n\ninterface ParsedEntry {\n\tname: string;\n\tdefaultValue?: string;\n}\n\n/**\n * Extracts script name and optional default value from a ConditionalScriptEntry.\n */\nfunction parseEntry(entry: ConditionalScriptEntry): 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 conditional 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 RuleViolation {\n\ttriggerScript: string;\n\tmissingScripts: string[];\n}\n\ninterface ValidationResult {\n\tviolations: RuleViolation[];\n\tmissingWithDefaults: Array<{\n\t\tname: string;\n\t\tdefaultValue: string;\n\t}>;\n}\n\nfunction validateConditionalRules(\n\tscripts: Record<string, string | undefined>,\n\trules: ConditionalScriptRule[],\n): ValidationResult {\n\tconst violations: RuleViolation[] = [];\n\tconst missingWithDefaults: Array<{\n\t\tname: string;\n\t\tdefaultValue: string;\n\t}> = [];\n\tconst seenMissing = new Set<string>();\n\n\tfor (const rule of rules) {\n\t\t// Skip if the triggering script doesn't exist\n\t\tif (!Object.hasOwn(scripts, rule.ifPresent)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst missingScripts: string[] = [];\n\t\tfor (const entry of rule.requires) {\n\t\t\tconst { name, defaultValue } = parseEntry(entry);\n\t\t\tif (!Object.hasOwn(scripts, name)) {\n\t\t\t\tmissingScripts.push(name);\n\t\t\t\tif (defaultValue !== undefined && !seenMissing.has(name)) {\n\t\t\t\t\tmissingWithDefaults.push({ name, defaultValue });\n\t\t\t\t\tseenMissing.add(name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (missingScripts.length > 0) {\n\t\t\tviolations.push({\n\t\t\t\ttriggerScript: rule.ifPresent,\n\t\t\t\tmissingScripts,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { violations, missingWithDefaults };\n}\n\nfunction formatViolationErrors(violations: RuleViolation[]): string[] {\n\treturn violations.map(\n\t\t(v) =>\n\t\t\t`Script \"${v.triggerScript}\" is present, but required companion script(s) missing: ${v.missingScripts.join(\", \")}`,\n\t);\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 conditional script requirements in package.json.\n *\n * @remarks\n * Use this policy when you want to enforce that the presence of one script\n * requires other scripts to also exist. For example, if \"build\" exists,\n * then \"clean\" must also exist.\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { ConditionalScripts } from \"repopo/policies\";\n *\n * makePolicy(ConditionalScripts, { config: {\n * rules: [\n * // If \"build\" exists, \"clean\" must also exist (with auto-fix default)\n * { ifPresent: \"build\", requires: [{ clean: \"rimraf dist\" }] },\n * // If \"test\" exists, \"test:coverage\" must also exist (no auto-fix)\n * { ifPresent: \"test\", requires: [\"test:coverage\"] },\n * ],\n * } })\n * ```\n *\n * @public\n */\nexport const ConditionalScripts = definePackagePolicy<\n\tPackageJson,\n\tConditionalScriptsConfig | undefined\n>({\n\trequiresConfig: true,\n\tname: POLICY_NAME,\n\tdescription:\n\t\t\"Validates that if certain scripts exist, other required scripts must also exist.\",\n\thandler: async (json, { file, root, resolve, config }) => {\n\t\tif (config === undefined || config.rules.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst scripts = json.scripts ?? {};\n\t\tconst validation = validateConditionalRules(scripts, config.rules);\n\n\t\tif (validation.violations.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst errors = formatViolationErrors(validation.violations);\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// Re-validate after fix to check for remaining errors\n\t\t\t\tconst updatedScripts = { ...scripts };\n\t\t\t\tfor (const name of fixedScripts) {\n\t\t\t\t\tconst entry = validation.missingWithDefaults.find(\n\t\t\t\t\t\t(m) => m.name === name,\n\t\t\t\t\t);\n\t\t\t\t\tif (entry) {\n\t\t\t\t\t\tupdatedScripts[name] = entry.defaultValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst revalidation = validateConditionalRules(\n\t\t\t\t\tupdatedScripts,\n\t\t\t\t\tconfig.rules,\n\t\t\t\t);\n\t\t\t\tconst remainingErrors = formatViolationErrors(revalidation.violations);\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...remainingErrors.map((message) => ({\n\t\t\t\t\t\tmessage: `Remaining errors:\\n${message}`,\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 errors.map((message) => ({\n\t\t\tmessage,\n\t\t\tfixStatus: hasAutoFixableErrors\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,7 +1,7 @@
1
1
  /**
2
2
  * Configuration for the ExactScripts policy.
3
3
  *
4
- * @alpha
4
+ * @public
5
5
  */
6
6
  export interface ExactScriptsConfig {
7
7
  /**
@@ -33,19 +33,21 @@ export interface ExactScriptsConfig {
33
33
  *
34
34
  * @example
35
35
  * ```typescript
36
- * import { policy } from "repopo";
36
+ * import { makePolicy } from "repopo";
37
37
  * import { ExactScripts } from "repopo/policies";
38
38
  *
39
- * policy(ExactScripts, {
39
+ * makePolicy(ExactScripts, { config: {
40
40
  * scripts: {
41
41
  * clean: "rimraf dist esm",
42
42
  * format: "biome format --write .",
43
43
  * lint: "biome lint .",
44
44
  * },
45
- * })
45
+ * } })
46
46
  * ```
47
47
  *
48
- * @alpha
48
+ * @public
49
49
  */
50
- export declare const ExactScripts: import("../policy.js").PolicyShape<ExactScriptsConfig | undefined>;
50
+ export declare const ExactScripts: import("../policy.js").FilePolicyDefinition<ExactScriptsConfig | undefined> & {
51
+ requiresConfig: true;
52
+ };
51
53
  //# sourceMappingURL=ExactScripts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExactScripts.d.ts","sourceRoot":"","sources":["../../src/policies/ExactScripts.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAuED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,YAAY,oEAqDvB,CAAC"}
1
+ {"version":3,"file":"ExactScripts.d.ts","sourceRoot":"","sources":["../../src/policies/ExactScripts.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAuED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,YAAY;;CAgDvB,CAAC"}