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
@@ -1 +1 @@
1
- {"version":3,"file":"PackageLicense.js","sourceRoot":"","sources":["../../src/policies/PackageLicense.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { copyFile, readFile } from \"node:fs/promises\";\nimport path from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFixResult } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * Policy settings for the PackageLicense repo policy.\n *\n * @alpha\n */\nexport interface PackageLicenseSettings {\n\t/**\n\t * Whether to skip validation for private packages.\n\t *\n\t * @defaultValue true\n\t *\n\t * @remarks\n\t *\n\t * Private packages (those with `private: true` in package.json) are typically\n\t * not published and may not need a LICENSE file. Set to `false` to require\n\t * LICENSE files for all packages.\n\t */\n\tskipPrivate?: boolean;\n\n\t/**\n\t * The name of the LICENSE file to look for and sync.\n\t *\n\t * @defaultValue \"LICENSE\"\n\t */\n\tlicenseFileName?: string;\n}\n\nconst DEFAULT_LICENSE_FILE_NAME = \"LICENSE\";\nconst POLICY_NAME = \"PackageLicense\";\n\n/**\n * Copies the root LICENSE file to the package directory.\n * @returns A PolicyFixResult indicating success or failure.\n */\nasync function copyLicenseFile(\n\trootLicensePath: string,\n\tpackageLicensePath: string,\n\tpolicyName: string,\n\tfile: string,\n\tpackageName: string,\n\tlicenseFileName: string,\n\tisCreate: boolean,\n): Promise<PolicyFixResult> {\n\ttry {\n\t\tawait copyFile(rootLicensePath, packageLicensePath);\n\t\treturn {\n\t\t\tname: policyName,\n\t\t\tfile,\n\t\t\tresolved: true,\n\t\t\tautoFixable: true,\n\t\t\terrorMessages: [\n\t\t\t\tisCreate\n\t\t\t\t\t? `Created ${licenseFileName} file for package \"${packageName}\"`\n\t\t\t\t\t: `Updated ${licenseFileName} file for package \"${packageName}\" to match root`,\n\t\t\t],\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tname: policyName,\n\t\t\tfile,\n\t\t\tresolved: false,\n\t\t\tautoFixable: true,\n\t\t\terrorMessages: [\n\t\t\t\tisCreate\n\t\t\t\t\t? `Failed to copy ${licenseFileName} to package \"${packageName}\"`\n\t\t\t\t\t: `Failed to update ${licenseFileName} for package \"${packageName}\"`,\n\t\t\t],\n\t\t};\n\t}\n}\n\n/**\n * A repo policy that ensures each package has a LICENSE file that matches the root LICENSE.\n *\n * @remarks\n *\n * This policy is essential for monorepos where individual packages are published\n * to npm. Each published package should include a LICENSE file, and it should\n * match the root repository's LICENSE to ensure consistent licensing.\n *\n * The policy:\n * 1. Checks if a LICENSE file exists in the package directory\n * 2. Compares it with the root LICENSE file\n * 3. Can auto-fix by copying the root LICENSE to the package directory\n *\n * By default, private packages are skipped since they're not published.\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { PackageLicense } from \"repopo/policies\";\n *\n * const config: RepopoConfig = {\n * policies: [\n * // Use defaults (skip private, look for LICENSE)\n * makePolicy(PackageLicense),\n *\n * // Or require LICENSE for all packages including private\n * makePolicy(PackageLicense, { skipPrivate: false }),\n * ],\n * };\n * ```\n *\n * @alpha\n */\nexport const PackageLicense = definePackagePolicy<\n\tPackageJson,\n\tPackageLicenseSettings | undefined\n>({\n\tname: \"PackageLicense\",\n\tdescription:\n\t\t\"Ensures each package has a LICENSE file that matches the root repository LICENSE.\",\n\thandler: async (json, { file, root, resolve, config }) => {\n\t\tconst skipPrivate = config?.skipPrivate ?? true;\n\t\tconst licenseFileName =\n\t\t\tconfig?.licenseFileName ?? DEFAULT_LICENSE_FILE_NAME;\n\n\t\t// Skip private packages if configured to do so\n\t\tif (skipPrivate && json.private === true) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst packageName = json.name ?? \"unknown\";\n\t\t// file is an absolute path, get the directory containing package.json\n\t\tconst packageDir = path.dirname(file);\n\t\tconst packageLicensePath = path.join(packageDir, licenseFileName);\n\t\tconst rootLicensePath = path.join(root, licenseFileName);\n\n\t\t// Check if root LICENSE exists\n\t\tif (!existsSync(rootLicensePath)) {\n\t\t\treturn {\n\t\t\t\tname: POLICY_NAME,\n\t\t\t\tfile,\n\t\t\t\tautoFixable: false,\n\t\t\t\terrorMessages: [\n\t\t\t\t\t`Cannot validate package LICENSE: root ${licenseFileName} file not found`,\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\n\t\t// Check if package LICENSE exists\n\t\tif (!existsSync(packageLicensePath)) {\n\t\t\tif (resolve) {\n\t\t\t\treturn await copyLicenseFile(\n\t\t\t\t\trootLicensePath,\n\t\t\t\t\tpackageLicensePath,\n\t\t\t\t\tPOLICY_NAME,\n\t\t\t\t\tfile,\n\t\t\t\t\tpackageName,\n\t\t\t\t\tlicenseFileName,\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tname: POLICY_NAME,\n\t\t\t\tfile,\n\t\t\t\tautoFixable: true,\n\t\t\t\terrorMessages: [\n\t\t\t\t\t`${licenseFileName} file missing for package \"${packageName}\"`,\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\n\t\t// Compare package LICENSE with root LICENSE\n\t\tconst [packageLicenseContent, rootLicenseContent] = await Promise.all([\n\t\t\treadFile(packageLicensePath, \"utf-8\"),\n\t\t\treadFile(rootLicensePath, \"utf-8\"),\n\t\t]);\n\n\t\tif (packageLicenseContent !== rootLicenseContent) {\n\t\t\tif (resolve) {\n\t\t\t\treturn await copyLicenseFile(\n\t\t\t\t\trootLicensePath,\n\t\t\t\t\tpackageLicensePath,\n\t\t\t\t\tPOLICY_NAME,\n\t\t\t\t\tfile,\n\t\t\t\t\tpackageName,\n\t\t\t\t\tlicenseFileName,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tname: POLICY_NAME,\n\t\t\t\tfile,\n\t\t\t\tautoFixable: true,\n\t\t\t\terrorMessages: [\n\t\t\t\t\t`${licenseFileName} file in package \"${packageName}\" doesn't match root ${licenseFileName}`,\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\n\t\treturn true;\n\t},\n});\n"]}
1
+ {"version":3,"file":"PackageLicense.js","sourceRoot":"","sources":["../../src/policies/PackageLicense.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { copyFile, readFile } from \"node:fs/promises\";\nimport path from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFinding } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * Policy settings for the PackageLicense repo policy.\n *\n * @public\n */\nexport interface PackageLicenseSettings {\n\t/**\n\t * Whether to skip validation for private packages.\n\t *\n\t * @defaultValue true\n\t *\n\t * @remarks\n\t *\n\t * Private packages (those with `private: true` in package.json) are typically\n\t * not published and may not need a LICENSE file. Set to `false` to require\n\t * LICENSE files for all packages.\n\t */\n\tskipPrivate?: boolean;\n\n\t/**\n\t * The name of the LICENSE file to look for and sync.\n\t *\n\t * @defaultValue \"LICENSE\"\n\t */\n\tlicenseFileName?: string;\n}\n\nconst DEFAULT_LICENSE_FILE_NAME = \"LICENSE\";\nconst POLICY_NAME = \"PackageLicense\";\n\n/**\n * Copies the root LICENSE file to the package directory.\n * @returns Findings that record whether the license was fixed.\n */\nasync function copyLicenseFile(\n\trootLicensePath: string,\n\tpackageLicensePath: string,\n\t_policyName: string,\n\t_file: string,\n\tpackageName: string,\n\tlicenseFileName: string,\n\tisCreate: boolean,\n): Promise<PolicyFinding[]> {\n\ttry {\n\t\tawait copyFile(rootLicensePath, packageLicensePath);\n\t\treturn [\n\t\t\tisCreate\n\t\t\t\t? `Created ${licenseFileName} file for package \"${packageName}\"`\n\t\t\t\t: `Updated ${licenseFileName} file for package \"${packageName}\" to match root`,\n\t\t].map((message) => ({ message, fixStatus: \"fixed\" }));\n\t} catch {\n\t\treturn [\n\t\t\tisCreate\n\t\t\t\t? `Failed to copy ${licenseFileName} to package \"${packageName}\"`\n\t\t\t\t: `Failed to update ${licenseFileName} for package \"${packageName}\"`,\n\t\t].map((message) => ({ message, fixStatus: \"failed\" }));\n\t}\n}\n\n/**\n * A repo policy that ensures each package has a LICENSE file that matches the root LICENSE.\n *\n * @remarks\n *\n * This policy is essential for monorepos where individual packages are published\n * to npm. Each published package should include a LICENSE file, and it should\n * match the root repository's LICENSE to ensure consistent licensing.\n *\n * The policy:\n * 1. Checks if a LICENSE file exists in the package directory\n * 2. Compares it with the root LICENSE file\n * 3. Can auto-fix by copying the root LICENSE to the package directory\n *\n * By default, private packages are skipped since they're not published.\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { PackageLicense } from \"repopo/policies\";\n *\n * const config: RepopoConfig = {\n * policies: [\n * // Use defaults (skip private, look for LICENSE)\n * makePolicy(PackageLicense),\n *\n * // Or require LICENSE for all packages including private\n * // makePolicy(PackageLicense, { config: { skipPrivate: false } }),\n * ],\n * };\n * ```\n *\n * @public\n */\nexport const PackageLicense = definePackagePolicy<\n\tPackageJson,\n\tPackageLicenseSettings | undefined\n>({\n\tname: \"PackageLicense\",\n\tdescription:\n\t\t\"Ensures each package has a LICENSE file that matches the root repository LICENSE.\",\n\thandler: async (json, { file, root, resolve, config }) => {\n\t\tconst skipPrivate = config?.skipPrivate ?? true;\n\t\tconst licenseFileName =\n\t\t\tconfig?.licenseFileName ?? DEFAULT_LICENSE_FILE_NAME;\n\n\t\t// Skip private packages if configured to do so\n\t\tif (skipPrivate && json.private === true) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst packageName = json.name ?? \"unknown\";\n\t\tconst packageDir = path.dirname(path.resolve(root, file));\n\t\tconst packageLicensePath = path.join(packageDir, licenseFileName);\n\t\tconst rootLicensePath = path.join(root, licenseFileName);\n\n\t\t// Check if root LICENSE exists\n\t\tif (!existsSync(rootLicensePath)) {\n\t\t\treturn [\n\t\t\t\t`Cannot validate package LICENSE: root ${licenseFileName} file not found`,\n\t\t\t].map((message) => ({ message }));\n\t\t}\n\n\t\t// Check if package LICENSE exists\n\t\tif (!existsSync(packageLicensePath)) {\n\t\t\tif (resolve) {\n\t\t\t\treturn await copyLicenseFile(\n\t\t\t\t\trootLicensePath,\n\t\t\t\t\tpackageLicensePath,\n\t\t\t\t\tPOLICY_NAME,\n\t\t\t\t\tfile,\n\t\t\t\t\tpackageName,\n\t\t\t\t\tlicenseFileName,\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t`${licenseFileName} file missing for package \"${packageName}\"`,\n\t\t\t].map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\tfixStatus: \"available\",\n\t\t\t}));\n\t\t}\n\n\t\t// Compare package LICENSE with root LICENSE\n\t\tconst [packageLicenseContent, rootLicenseContent] = await Promise.all([\n\t\t\treadFile(packageLicensePath, \"utf-8\"),\n\t\t\treadFile(rootLicensePath, \"utf-8\"),\n\t\t]);\n\n\t\tif (packageLicenseContent !== rootLicenseContent) {\n\t\t\tif (resolve) {\n\t\t\t\treturn await copyLicenseFile(\n\t\t\t\t\trootLicensePath,\n\t\t\t\t\tpackageLicensePath,\n\t\t\t\t\tPOLICY_NAME,\n\t\t\t\t\tfile,\n\t\t\t\t\tpackageName,\n\t\t\t\t\tlicenseFileName,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t`${licenseFileName} file in package \"${packageName}\" doesn't match root ${licenseFileName}`,\n\t\t\t].map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\tfixStatus: \"available\",\n\t\t\t}));\n\t\t}\n\t\treturn [];\n\t},\n});\n"]}
@@ -19,7 +19,7 @@
19
19
  * };
20
20
  * ```
21
21
  *
22
- * @alpha
22
+ * @public
23
23
  */
24
24
  export interface PackagePrivateFieldConfig {
25
25
  /**
@@ -30,7 +30,7 @@ export interface PackagePrivateFieldConfig {
30
30
  *
31
31
  * @remarks
32
32
  *
33
- * Uses glob patterns via picomatch. Use "@scope/*" to match all packages in a scope,
33
+ * Uses glob patterns via picomatch. Use `@scope/*` to match all packages in a scope,
34
34
  * or use exact package names.
35
35
  *
36
36
  * @example
@@ -109,16 +109,20 @@ export interface PackagePrivateFieldConfig {
109
109
  * const config: RepopoConfig = {
110
110
  * policies: [
111
111
  * makePolicy(PackagePrivateField, {
112
- * mustPublish: ["@myorg/*"],
113
- * mustBePrivate: ["@internal/*"],
114
- * mayPublish: ["@experimental/*"],
115
- * unmatchedPackages: "private",
112
+ * config: {
113
+ * mustPublish: ["@myorg/*"],
114
+ * mustBePrivate: ["@internal/*"],
115
+ * mayPublish: ["@experimental/*"],
116
+ * unmatchedPackages: "private",
117
+ * },
116
118
  * }),
117
119
  * ],
118
120
  * };
119
121
  * ```
120
122
  *
121
- * @alpha
123
+ * @public
122
124
  */
123
- export declare const PackagePrivateField: import("../policy.js").PolicyShape<PackagePrivateFieldConfig | undefined>;
125
+ export declare const PackagePrivateField: import("../policy.js").FilePolicyDefinition<PackagePrivateFieldConfig | undefined> & {
126
+ requiresConfig: true;
127
+ };
124
128
  //# sourceMappingURL=PackagePrivateField.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PackagePrivateField.d.ts","sourceRoot":"","sources":["../../src/policies/PackagePrivateField.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACpD;AA+DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,mBAAmB,2EA+E9B,CAAC"}
1
+ {"version":3,"file":"PackagePrivateField.d.ts","sourceRoot":"","sources":["../../src/policies/PackagePrivateField.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACpD;AA+DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,mBAAmB;;CAsF9B,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import jsonfile from "jsonfile";
2
+ import { resolve as resolvePath } from "pathe";
2
3
  import picomatch from "picomatch";
3
4
  import { definePackagePolicy } from "../policyDefiners/definePackagePolicy.js";
4
5
  const { writeFile: writeJson } = jsonfile;
@@ -82,59 +83,60 @@ function getRequiredPrivateState(packageName, config) {
82
83
  * const config: RepopoConfig = {
83
84
  * policies: [
84
85
  * makePolicy(PackagePrivateField, {
85
- * mustPublish: ["@myorg/*"],
86
- * mustBePrivate: ["@internal/*"],
87
- * mayPublish: ["@experimental/*"],
88
- * unmatchedPackages: "private",
86
+ * config: {
87
+ * mustPublish: ["@myorg/*"],
88
+ * mustBePrivate: ["@internal/*"],
89
+ * mayPublish: ["@experimental/*"],
90
+ * unmatchedPackages: "private",
91
+ * },
89
92
  * }),
90
93
  * ],
91
94
  * };
92
95
  * ```
93
96
  *
94
- * @alpha
97
+ * @public
95
98
  */
96
99
  export const PackagePrivateField = definePackagePolicy({
97
100
  name: "PackagePrivateField",
101
+ requiresConfig: true,
98
102
  description: "Enforces the private field in package.json based on package scope or name patterns.",
99
- handler: async (json, { file, config, resolve }) => {
103
+ handler: async (json, { file, root, config, resolve }) => {
100
104
  // If no config provided, skip validation
101
105
  if (config === undefined) {
102
- return true;
106
+ return [];
103
107
  }
104
108
  const packageName = json.name;
105
109
  // Skip packages without a name (shouldn't happen in practice)
106
110
  if (packageName === undefined) {
107
- return true;
111
+ return [];
108
112
  }
109
113
  // Skip the root package (typically named "root" in monorepos)
110
114
  if (packageName === "root") {
111
- return true;
115
+ return [];
112
116
  }
113
117
  const requiredState = getRequiredPrivateState(packageName, config);
114
118
  // If "ignore", the package can be either private or public
115
119
  if (requiredState === IGNORE_PRIVATE_STATE) {
116
- return true;
120
+ return [];
117
121
  }
118
122
  const currentlyPrivate = json.private === true;
119
123
  // Check if the current state matches the required state
120
124
  if (requiredState === currentlyPrivate) {
121
- return true;
125
+ return [];
122
126
  }
123
127
  // State mismatch - build error message
124
128
  const errorMessage = requiredState === true
125
129
  ? `Package "${packageName}" must be marked private. Add "private": true to package.json.`
126
130
  : `Package "${packageName}" must not be marked private. Remove "private": true from package.json to allow publishing.`;
127
- const failResult = {
128
- name: PackagePrivateField.name,
129
- file,
130
- autoFixable: true,
131
- errorMessages: [errorMessage],
132
- };
131
+ const failResult = [errorMessage].map((message) => ({
132
+ message,
133
+ fixStatus: "available",
134
+ }));
133
135
  if (resolve) {
134
- const fixResult = {
135
- ...failResult,
136
- resolved: false,
137
- };
136
+ const fixResult = failResult.map((finding) => ({
137
+ ...finding,
138
+ fixStatus: "failed",
139
+ }));
138
140
  try {
139
141
  if (requiredState === true) {
140
142
  // Add private: true
@@ -144,12 +146,19 @@ export const PackagePrivateField = definePackagePolicy({
144
146
  // Remove private field
145
147
  delete json.private;
146
148
  }
147
- await writeJson(file, json, { spaces: "\t" });
148
- fixResult.resolved = true;
149
+ await writeJson(resolvePath(root, file), json, { spaces: "\t" });
150
+ for (const finding of fixResult) {
151
+ finding.fixStatus = "fixed";
152
+ }
149
153
  }
150
154
  catch {
151
- fixResult.resolved = false;
152
- fixResult.errorMessages = [`Failed to update ${file}`];
155
+ for (const finding of fixResult) {
156
+ finding.fixStatus = "failed";
157
+ }
158
+ fixResult.splice(0, fixResult.length, ...[`Failed to update ${file}`].map((message) => ({
159
+ ...fixResult[0],
160
+ message,
161
+ })));
153
162
  }
154
163
  return fixResult;
155
164
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PackagePrivateField.js","sourceRoot":"","sources":["../../src/policies/PackagePrivateField.ts"],"names":[],"mappings":"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","sourcesContent":["import jsonfile from \"jsonfile\";\nimport picomatch from \"picomatch\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFailure, PolicyFixResult } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\nconst { writeFile: writeJson } = jsonfile;\n\n/**\n * Sentinel value indicating that the package's private status should not be enforced.\n * This is more explicit than using `undefined` to represent \"ignore\".\n */\nconst IGNORE_PRIVATE_STATE = \"ignore\" as const;\n\n/**\n * The required private state for a package.\n * - `true`: Package must have `private: true`\n * - `false`: Package must NOT have `private: true`\n * - `\"ignore\"`: No enforcement - package can be either private or public\n */\ntype RequiredPrivateState = boolean | typeof IGNORE_PRIVATE_STATE;\n\n/**\n * Configuration for the PackagePrivateField policy.\n *\n * This policy enforces that packages are correctly marked as private or public based on\n * their scope or name. This is essential for monorepos where some packages should be\n * published to npm while others should remain internal.\n *\n * All pattern matching uses glob patterns via picomatch.\n *\n * @example\n * ```typescript\n * const config: PackagePrivateFieldConfig = {\n * // Packages in myorg scope must be published (private: false or absent)\n * mustPublish: [\"@myorg/*\"],\n * // Packages in internal scope must be private\n * mustBePrivate: [\"@internal/*\"],\n * // Packages in experimental scope can choose\n * mayPublish: [\"@experimental/*\"],\n * };\n * ```\n *\n * @alpha\n */\nexport interface PackagePrivateFieldConfig {\n\t/**\n\t * A list of glob patterns for packages that must be published.\n\t *\n\t * Packages matching these patterns must NOT have `private: true` in their package.json.\n\t * If they do, the policy will fail and can auto-fix by removing the private field.\n\t *\n\t * @remarks\n\t *\n\t * Uses glob patterns via picomatch. Use \"@scope/*\" to match all packages in a scope,\n\t * or use exact package names.\n\t *\n\t * @example\n\t * ```typescript\n\t * mustPublish: [\"@fluidframework/*\", \"@fluid-tools/*\", \"tinylicious\"]\n\t * ```\n\t */\n\tmustPublish?: string[];\n\n\t/**\n\t * A list of glob patterns for packages that must be private.\n\t *\n\t * Packages matching these patterns must have `private: true` in their package.json.\n\t * If they don't, the policy will fail and can auto-fix by adding `private: true`.\n\t *\n\t * @remarks\n\t *\n\t * Uses glob patterns via picomatch (see mustPublish for pattern examples).\n\t *\n\t * @example\n\t * ```typescript\n\t * mustBePrivate: [\"@fluid-internal/*\", \"@fluid-private/*\"]\n\t * ```\n\t */\n\tmustBePrivate?: string[];\n\n\t/**\n\t * A list of glob patterns for packages that may optionally be published.\n\t *\n\t * Packages matching these patterns can choose whether to be private or public.\n\t * The policy will not enforce either state for these packages.\n\t *\n\t * @remarks\n\t *\n\t * Uses glob patterns via picomatch (see mustPublish for pattern examples).\n\t * Packages not matching any list default to requiring `private: true`.\n\t *\n\t * @example\n\t * ```typescript\n\t * mayPublish: [\"@fluid-experimental/*\"]\n\t * ```\n\t */\n\tmayPublish?: string[];\n\n\t/**\n\t * Default behavior for packages that don't match any of the above lists.\n\t *\n\t * - `\"private\"` (default): Unmatched packages must have `private: true`\n\t * - `\"public\"`: Unmatched packages must NOT have `private: true`\n\t * - `\"ignore\"`: No enforcement for unmatched packages\n\t *\n\t * @defaultValue \"private\"\n\t */\n\tunmatchedPackages?: \"private\" | \"public\" | \"ignore\";\n}\n\n/**\n * Check if a package name matches any pattern in the list.\n *\n * Supports glob patterns via picomatch. Use patterns like:\n * - \"@myorg/\\*\" - matches all packages in the myorg scope\n * - \"my-package\" - exact match\n * - \"my-*\" - matches my-foo, my-bar, etc.\n *\n * @param packageName - The package name to check (e.g., `@myorg/foo`)\n * @param patterns - List of glob patterns or exact package names\n * @returns `true` if the package matches any pattern\n */\nfunction matchesAnyPattern(\n\tpackageName: string,\n\tpatterns: string[] | undefined,\n): boolean {\n\tif (patterns === undefined || patterns.length === 0) {\n\t\treturn false;\n\t}\n\n\treturn picomatch.isMatch(packageName, patterns);\n}\n\n/**\n * Determine what the private field should be for a package.\n *\n * @returns `true` if package must be private, `false` if must be public, `\"ignore\"` if either is ok\n */\nfunction getRequiredPrivateState(\n\tpackageName: string,\n\tconfig: PackagePrivateFieldConfig,\n): RequiredPrivateState {\n\t// Check mustPublish first - these packages must NOT be private\n\tif (matchesAnyPattern(packageName, config.mustPublish)) {\n\t\treturn false;\n\t}\n\n\t// Check mustBePrivate - these packages MUST be private\n\tif (matchesAnyPattern(packageName, config.mustBePrivate)) {\n\t\treturn true;\n\t}\n\n\t// Check mayPublish - these packages can be either\n\tif (matchesAnyPattern(packageName, config.mayPublish)) {\n\t\treturn IGNORE_PRIVATE_STATE;\n\t}\n\n\t// Default behavior for unmatched packages\n\tconst unmatchedBehavior = config.unmatchedPackages ?? \"private\";\n\tswitch (unmatchedBehavior) {\n\t\tcase \"private\":\n\t\t\treturn true;\n\t\tcase \"public\":\n\t\t\treturn false;\n\t\tcase \"ignore\":\n\t\t\treturn IGNORE_PRIVATE_STATE;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown unmatchedPackages value: ${unmatchedBehavior}`);\n\t}\n}\n\n/**\n * A policy that enforces the `private` field in package.json based on package scope or name.\n *\n * This policy is essential for monorepos where publishing control is important:\n *\n * - Prevent accidental publishing of internal packages\n * - Ensure public packages don't have `private: true` blocking publishing\n * - Allow experimental packages to choose their own publishing status\n *\n * @remarks\n *\n * The policy evaluates packages in the following order:\n *\n * 1. If the package matches `mustPublish`, it must NOT have `private: true`\n * 2. If the package matches `mustBePrivate`, it MUST have `private: true`\n * 3. If the package matches `mayPublish`, no enforcement is applied\n * 4. Otherwise, the `unmatchedPackages` setting determines behavior (defaults to requiring private)\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { PackagePrivateField } from \"repopo/policies\";\n *\n * const config: RepopoConfig = {\n * policies: [\n * makePolicy(PackagePrivateField, {\n * mustPublish: [\"@myorg/*\"],\n * mustBePrivate: [\"@internal/*\"],\n * mayPublish: [\"@experimental/*\"],\n * unmatchedPackages: \"private\",\n * }),\n * ],\n * };\n * ```\n *\n * @alpha\n */\nexport const PackagePrivateField = definePackagePolicy<\n\tPackageJson,\n\tPackagePrivateFieldConfig | undefined\n>({\n\tname: \"PackagePrivateField\",\n\tdescription:\n\t\t\"Enforces the private field in package.json based on package scope or name patterns.\",\n\thandler: async (json, { file, config, resolve }) => {\n\t\t// If no config provided, skip validation\n\t\tif (config === undefined) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst packageName = json.name;\n\n\t\t// Skip packages without a name (shouldn't happen in practice)\n\t\tif (packageName === undefined) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Skip the root package (typically named \"root\" in monorepos)\n\t\tif (packageName === \"root\") {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst requiredState = getRequiredPrivateState(packageName, config);\n\n\t\t// If \"ignore\", the package can be either private or public\n\t\tif (requiredState === IGNORE_PRIVATE_STATE) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst currentlyPrivate = json.private === true;\n\n\t\t// Check if the current state matches the required state\n\t\tif (requiredState === currentlyPrivate) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// State mismatch - build error message\n\t\tconst errorMessage =\n\t\t\trequiredState === true\n\t\t\t\t? `Package \"${packageName}\" must be marked private. Add \"private\": true to package.json.`\n\t\t\t\t: `Package \"${packageName}\" must not be marked private. Remove \"private\": true from package.json to allow publishing.`;\n\n\t\tconst failResult: PolicyFailure = {\n\t\t\tname: PackagePrivateField.name,\n\t\t\tfile,\n\t\t\tautoFixable: true,\n\t\t\terrorMessages: [errorMessage],\n\t\t};\n\n\t\tif (resolve) {\n\t\t\tconst fixResult: PolicyFixResult = {\n\t\t\t\t...failResult,\n\t\t\t\tresolved: false,\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tif (requiredState === true) {\n\t\t\t\t\t// Add private: true\n\t\t\t\t\tjson.private = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Remove private field\n\t\t\t\t\tdelete json.private;\n\t\t\t\t}\n\n\t\t\t\tawait writeJson(file, json, { spaces: \"\\t\" });\n\t\t\t\tfixResult.resolved = true;\n\t\t\t} catch {\n\t\t\t\tfixResult.resolved = false;\n\t\t\t\tfixResult.errorMessages = [`Failed to update ${file}`];\n\t\t\t}\n\n\t\t\treturn fixResult;\n\t\t}\n\n\t\treturn failResult;\n\t},\n});\n"]}
1
+ {"version":3,"file":"PackagePrivateField.js","sourceRoot":"","sources":["../../src/policies/PackagePrivateField.ts"],"names":[],"mappings":"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","sourcesContent":["import jsonfile from \"jsonfile\";\nimport { resolve as resolvePath } from \"pathe\";\nimport picomatch from \"picomatch\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFinding } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\nconst { writeFile: writeJson } = jsonfile;\n\n/**\n * Sentinel value indicating that the package's private status should not be enforced.\n * This is more explicit than using `undefined` to represent \"ignore\".\n */\nconst IGNORE_PRIVATE_STATE = \"ignore\" as const;\n\n/**\n * The required private state for a package.\n * - `true`: Package must have `private: true`\n * - `false`: Package must NOT have `private: true`\n * - `\"ignore\"`: No enforcement - package can be either private or public\n */\ntype RequiredPrivateState = boolean | typeof IGNORE_PRIVATE_STATE;\n\n/**\n * Configuration for the PackagePrivateField policy.\n *\n * This policy enforces that packages are correctly marked as private or public based on\n * their scope or name. This is essential for monorepos where some packages should be\n * published to npm while others should remain internal.\n *\n * All pattern matching uses glob patterns via picomatch.\n *\n * @example\n * ```typescript\n * const config: PackagePrivateFieldConfig = {\n * // Packages in myorg scope must be published (private: false or absent)\n * mustPublish: [\"@myorg/*\"],\n * // Packages in internal scope must be private\n * mustBePrivate: [\"@internal/*\"],\n * // Packages in experimental scope can choose\n * mayPublish: [\"@experimental/*\"],\n * };\n * ```\n *\n * @public\n */\nexport interface PackagePrivateFieldConfig {\n\t/**\n\t * A list of glob patterns for packages that must be published.\n\t *\n\t * Packages matching these patterns must NOT have `private: true` in their package.json.\n\t * If they do, the policy will fail and can auto-fix by removing the private field.\n\t *\n\t * @remarks\n\t *\n\t * Uses glob patterns via picomatch. Use `@scope/*` to match all packages in a scope,\n\t * or use exact package names.\n\t *\n\t * @example\n\t * ```typescript\n\t * mustPublish: [\"@fluidframework/*\", \"@fluid-tools/*\", \"tinylicious\"]\n\t * ```\n\t */\n\tmustPublish?: string[];\n\n\t/**\n\t * A list of glob patterns for packages that must be private.\n\t *\n\t * Packages matching these patterns must have `private: true` in their package.json.\n\t * If they don't, the policy will fail and can auto-fix by adding `private: true`.\n\t *\n\t * @remarks\n\t *\n\t * Uses glob patterns via picomatch (see mustPublish for pattern examples).\n\t *\n\t * @example\n\t * ```typescript\n\t * mustBePrivate: [\"@fluid-internal/*\", \"@fluid-private/*\"]\n\t * ```\n\t */\n\tmustBePrivate?: string[];\n\n\t/**\n\t * A list of glob patterns for packages that may optionally be published.\n\t *\n\t * Packages matching these patterns can choose whether to be private or public.\n\t * The policy will not enforce either state for these packages.\n\t *\n\t * @remarks\n\t *\n\t * Uses glob patterns via picomatch (see mustPublish for pattern examples).\n\t * Packages not matching any list default to requiring `private: true`.\n\t *\n\t * @example\n\t * ```typescript\n\t * mayPublish: [\"@fluid-experimental/*\"]\n\t * ```\n\t */\n\tmayPublish?: string[];\n\n\t/**\n\t * Default behavior for packages that don't match any of the above lists.\n\t *\n\t * - `\"private\"` (default): Unmatched packages must have `private: true`\n\t * - `\"public\"`: Unmatched packages must NOT have `private: true`\n\t * - `\"ignore\"`: No enforcement for unmatched packages\n\t *\n\t * @defaultValue \"private\"\n\t */\n\tunmatchedPackages?: \"private\" | \"public\" | \"ignore\";\n}\n\n/**\n * Check if a package name matches any pattern in the list.\n *\n * Supports glob patterns via picomatch. Use patterns like:\n * - \"@myorg/\\*\" - matches all packages in the myorg scope\n * - \"my-package\" - exact match\n * - \"my-*\" - matches my-foo, my-bar, etc.\n *\n * @param packageName - The package name to check (e.g., `@myorg/foo`)\n * @param patterns - List of glob patterns or exact package names\n * @returns `true` if the package matches any pattern\n */\nfunction matchesAnyPattern(\n\tpackageName: string,\n\tpatterns: string[] | undefined,\n): boolean {\n\tif (patterns === undefined || patterns.length === 0) {\n\t\treturn false;\n\t}\n\n\treturn picomatch.isMatch(packageName, patterns);\n}\n\n/**\n * Determine what the private field should be for a package.\n *\n * @returns `true` if package must be private, `false` if must be public, `\"ignore\"` if either is ok\n */\nfunction getRequiredPrivateState(\n\tpackageName: string,\n\tconfig: PackagePrivateFieldConfig,\n): RequiredPrivateState {\n\t// Check mustPublish first - these packages must NOT be private\n\tif (matchesAnyPattern(packageName, config.mustPublish)) {\n\t\treturn false;\n\t}\n\n\t// Check mustBePrivate - these packages MUST be private\n\tif (matchesAnyPattern(packageName, config.mustBePrivate)) {\n\t\treturn true;\n\t}\n\n\t// Check mayPublish - these packages can be either\n\tif (matchesAnyPattern(packageName, config.mayPublish)) {\n\t\treturn IGNORE_PRIVATE_STATE;\n\t}\n\n\t// Default behavior for unmatched packages\n\tconst unmatchedBehavior = config.unmatchedPackages ?? \"private\";\n\tswitch (unmatchedBehavior) {\n\t\tcase \"private\":\n\t\t\treturn true;\n\t\tcase \"public\":\n\t\t\treturn false;\n\t\tcase \"ignore\":\n\t\t\treturn IGNORE_PRIVATE_STATE;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown unmatchedPackages value: ${unmatchedBehavior}`);\n\t}\n}\n\n/**\n * A policy that enforces the `private` field in package.json based on package scope or name.\n *\n * This policy is essential for monorepos where publishing control is important:\n *\n * - Prevent accidental publishing of internal packages\n * - Ensure public packages don't have `private: true` blocking publishing\n * - Allow experimental packages to choose their own publishing status\n *\n * @remarks\n *\n * The policy evaluates packages in the following order:\n *\n * 1. If the package matches `mustPublish`, it must NOT have `private: true`\n * 2. If the package matches `mustBePrivate`, it MUST have `private: true`\n * 3. If the package matches `mayPublish`, no enforcement is applied\n * 4. Otherwise, the `unmatchedPackages` setting determines behavior (defaults to requiring private)\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { PackagePrivateField } from \"repopo/policies\";\n *\n * const config: RepopoConfig = {\n * policies: [\n * makePolicy(PackagePrivateField, {\n * config: {\n * mustPublish: [\"@myorg/*\"],\n * mustBePrivate: [\"@internal/*\"],\n * mayPublish: [\"@experimental/*\"],\n * unmatchedPackages: \"private\",\n * },\n * }),\n * ],\n * };\n * ```\n *\n * @public\n */\nexport const PackagePrivateField = definePackagePolicy<\n\tPackageJson,\n\tPackagePrivateFieldConfig | undefined\n>({\n\tname: \"PackagePrivateField\",\n\trequiresConfig: true,\n\tdescription:\n\t\t\"Enforces the private field in package.json based on package scope or name patterns.\",\n\thandler: async (json, { file, root, config, resolve }) => {\n\t\t// If no config provided, skip validation\n\t\tif (config === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst packageName = json.name;\n\n\t\t// Skip packages without a name (shouldn't happen in practice)\n\t\tif (packageName === undefined) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Skip the root package (typically named \"root\" in monorepos)\n\t\tif (packageName === \"root\") {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst requiredState = getRequiredPrivateState(packageName, config);\n\n\t\t// If \"ignore\", the package can be either private or public\n\t\tif (requiredState === IGNORE_PRIVATE_STATE) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst currentlyPrivate = json.private === true;\n\n\t\t// Check if the current state matches the required state\n\t\tif (requiredState === currentlyPrivate) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// State mismatch - build error message\n\t\tconst errorMessage =\n\t\t\trequiredState === true\n\t\t\t\t? `Package \"${packageName}\" must be marked private. Add \"private\": true to package.json.`\n\t\t\t\t: `Package \"${packageName}\" must not be marked private. Remove \"private\": true from package.json to allow publishing.`;\n\t\tconst failResult: PolicyFinding[] = [errorMessage].map((message) => ({\n\t\t\tmessage,\n\t\t\tfixStatus: \"available\",\n\t\t}));\n\t\tif (resolve) {\n\t\t\tconst fixResult: PolicyFinding[] = failResult.map((finding) => ({\n\t\t\t\t...finding,\n\t\t\t\tfixStatus: \"failed\",\n\t\t\t}));\n\t\t\ttry {\n\t\t\t\tif (requiredState === true) {\n\t\t\t\t\t// Add private: true\n\t\t\t\t\tjson.private = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Remove private field\n\t\t\t\t\tdelete json.private;\n\t\t\t\t}\n\n\t\t\t\tawait writeJson(resolvePath(root, file), json, { spaces: \"\\t\" });\n\t\t\t\tfor (const finding of fixResult) {\n\t\t\t\t\tfinding.fixStatus = \"fixed\";\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tfor (const finding of fixResult) {\n\t\t\t\t\tfinding.fixStatus = \"failed\";\n\t\t\t\t}\n\t\t\t\tfixResult.splice(\n\t\t\t\t\t0,\n\t\t\t\t\tfixResult.length,\n\t\t\t\t\t...[`Failed to update ${file}`].map((message) => ({\n\t\t\t\t\t\t...fixResult[0],\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn fixResult;\n\t\t}\n\n\t\treturn failResult;\n\t},\n});\n"]}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Policy settings for the PackageReadme repo policy.
3
3
  *
4
- * @alpha
4
+ * @public
5
5
  */
6
6
  export interface PackageReadmeSettings {
7
7
  /**
@@ -61,17 +61,18 @@ export interface PackageReadmeSettings {
61
61
  * const config: RepopoConfig = {
62
62
  * policies: [
63
63
  * // Basic README validation
64
- * makePolicy(PackageReadme),
64
+ * makePolicy(PackageReadme, { instanceId: "readme" }),
65
65
  *
66
66
  * // Require trademark notice in all READMEs
67
67
  * makePolicy(PackageReadme, {
68
- * requiredContent: "## Trademark",
68
+ * instanceId: "readme-trademark",
69
+ * config: { requiredContent: "## Trademark" },
69
70
  * }),
70
71
  * ],
71
72
  * };
72
73
  * ```
73
74
  *
74
- * @alpha
75
+ * @public
75
76
  */
76
- export declare const PackageReadme: import("../policy.js").PolicyShape<PackageReadmeSettings | undefined>;
77
+ export declare const PackageReadme: import("../policy.js").FilePolicyDefinition<PackageReadmeSettings | undefined>;
77
78
  //# sourceMappingURL=PackageReadme.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PackageReadme.d.ts","sourceRoot":"","sources":["../../src/policies/PackageReadme.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;;;;;;;;OAYG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAkMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,aAAa,uEA4CxB,CAAC"}
1
+ {"version":3,"file":"PackageReadme.d.ts","sourceRoot":"","sources":["../../src/policies/PackageReadme.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;;;;;;;;OAYG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AA0JD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,aAAa,gFA4CxB,CAAC"}
@@ -34,36 +34,20 @@ function createReadmeContent(packageName, requiredContent) {
34
34
  /**
35
35
  * Handle case when README is missing.
36
36
  */
37
- async function handleMissingReadme(readmePath, packageName, file, resolve, requiredContent) {
37
+ async function handleMissingReadme(readmePath, packageName, _file, resolve, requiredContent) {
38
38
  if (resolve) {
39
39
  try {
40
40
  await writeFile(readmePath, createReadmeContent(packageName, requiredContent));
41
- return {
42
- name: "PackageReadme",
43
- file,
44
- resolved: true,
45
- autoFixable: true,
46
- errorMessages: [`Created README.md for package "${packageName}"`],
47
- };
41
+ return [`Created README.md for package "${packageName}"`].map((message) => ({ message, fixStatus: "fixed" }));
48
42
  }
49
43
  catch {
50
- return {
51
- name: "PackageReadme",
52
- file,
53
- resolved: false,
54
- autoFixable: true,
55
- errorMessages: [
56
- `Failed to create README.md for package "${packageName}"`,
57
- ],
58
- };
44
+ return [`Failed to create README.md for package "${packageName}"`].map((message) => ({ message, fixStatus: "failed" }));
59
45
  }
60
46
  }
61
- return {
62
- name: "PackageReadme",
63
- file,
64
- autoFixable: true,
65
- errorMessages: [`README.md missing for package "${packageName}"`],
66
- };
47
+ return [`README.md missing for package "${packageName}"`].map((message) => ({
48
+ message,
49
+ fixStatus: "available",
50
+ }));
67
51
  }
68
52
  /**
69
53
  * Validate README title against package name.
@@ -82,7 +66,7 @@ function validateTitle(readmeContent, packageName) {
82
66
  */
83
67
  async function handleRequiredContent(readmePath, readmeContent, requiredContent, resolve) {
84
68
  if (readmeContent.includes(requiredContent)) {
85
- return { fixed: false };
69
+ return undefined;
86
70
  }
87
71
  if (resolve) {
88
72
  try {
@@ -91,8 +75,8 @@ async function handleRequiredContent(readmePath, readmeContent, requiredContent,
91
75
  : `${readmeContent}\n${requiredContent}\n`;
92
76
  await writeFile(readmePath, newContent);
93
77
  return {
94
- error: `README missing required content: "${requiredContent}"`,
95
- fixed: true,
78
+ message: `README missing required content: "${requiredContent}"`,
79
+ fixStatus: "fixed",
96
80
  };
97
81
  }
98
82
  catch {
@@ -100,52 +84,30 @@ async function handleRequiredContent(readmePath, readmeContent, requiredContent,
100
84
  }
101
85
  }
102
86
  return {
103
- error: `README missing required content: "${requiredContent}"`,
104
- fixed: false,
87
+ message: `README missing required content: "${requiredContent}"`,
88
+ fixStatus: resolve ? "failed" : "available",
105
89
  };
106
90
  }
107
91
  /**
108
92
  * Validate existing README content.
109
93
  */
110
94
  async function validateExistingReadme(ctx) {
111
- const errors = [];
112
- let wasFixed = false;
95
+ const findings = [];
113
96
  // Check title matches package name
114
97
  if (ctx.requireMatchingTitle) {
115
98
  const titleResult = validateTitle(ctx.readmeContent, ctx.packageName);
116
99
  if (titleResult !== true) {
117
- errors.push(titleResult);
100
+ findings.push({ message: titleResult });
118
101
  }
119
102
  }
120
103
  // Check required content
121
104
  if (ctx.requiredContent) {
122
105
  const contentResult = await handleRequiredContent(ctx.readmePath, ctx.readmeContent, ctx.requiredContent, ctx.resolve);
123
- if (contentResult.error) {
124
- errors.push(contentResult.error);
106
+ if (contentResult) {
107
+ findings.push(contentResult);
125
108
  }
126
- if (contentResult.fixed) {
127
- wasFixed = true;
128
- }
129
- }
130
- if (errors.length === 0) {
131
- return true;
132
- }
133
- if (wasFixed) {
134
- return {
135
- name: "PackageReadme",
136
- file: ctx.file,
137
- resolved: true,
138
- autoFixable: true,
139
- errorMessages: [errors.join("; ")],
140
- };
141
109
  }
142
- return {
143
- name: "PackageReadme",
144
- file: ctx.file,
145
- autoFixable: ctx.requiredContent !== undefined &&
146
- !ctx.readmeContent.includes(ctx.requiredContent),
147
- errorMessages: [errors.join("; ")],
148
- };
110
+ return findings;
149
111
  }
150
112
  /**
151
113
  * A repo policy that ensures each package has a README.md file with proper content.
@@ -167,31 +129,32 @@ async function validateExistingReadme(ctx) {
167
129
  * const config: RepopoConfig = {
168
130
  * policies: [
169
131
  * // Basic README validation
170
- * makePolicy(PackageReadme),
132
+ * makePolicy(PackageReadme, { instanceId: "readme" }),
171
133
  *
172
134
  * // Require trademark notice in all READMEs
173
135
  * makePolicy(PackageReadme, {
174
- * requiredContent: "## Trademark",
136
+ * instanceId: "readme-trademark",
137
+ * config: { requiredContent: "## Trademark" },
175
138
  * }),
176
139
  * ],
177
140
  * };
178
141
  * ```
179
142
  *
180
- * @alpha
143
+ * @public
181
144
  */
182
145
  export const PackageReadme = definePackagePolicy({
183
146
  name: "PackageReadme",
184
147
  description: "Ensures each package has a README.md file with proper title and required content.",
185
- handler: async (json, { file, resolve, config }) => {
148
+ handler: async (json, { file, root, resolve, config }) => {
186
149
  const skipPrivate = config?.skipPrivate ?? true;
187
150
  const requireMatchingTitle = config?.requireMatchingTitle ?? true;
188
151
  const requiredContent = config?.requiredContent;
189
152
  // Skip private packages if configured to do so
190
153
  if (skipPrivate && json.private === true) {
191
- return true;
154
+ return [];
192
155
  }
193
156
  const packageName = json.name ?? "unknown";
194
- const packageDir = path.dirname(file);
157
+ const packageDir = path.dirname(path.resolve(root, file));
195
158
  const readmePath = path.join(packageDir, "README.md");
196
159
  // Check if README exists
197
160
  if (!existsSync(readmePath)) {
@@ -1 +1 @@
1
- {"version":3,"file":"PackageReadme.js","sourceRoot":"","sources":["../../src/policies/PackageReadme.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFailure, PolicyFixResult } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n// Pre-compiled regex for performance\nconst LINE_SPLIT_REGEX = /\\r?\\n/;\nconst HEADING_REGEX = /^#\\s+(.+)$/;\n\n/**\n * Policy settings for the PackageReadme repo policy.\n *\n * @alpha\n */\nexport interface PackageReadmeSettings {\n\t/**\n\t * Whether to skip validation for private packages.\n\t *\n\t * @defaultValue true\n\t *\n\t * @remarks\n\t *\n\t * Private packages are typically not published and may not need a README file.\n\t * Set to `false` to require README files for all packages.\n\t */\n\tskipPrivate?: boolean;\n\n\t/**\n\t * Whether to require the README title to match the package name.\n\t *\n\t * @defaultValue true\n\t *\n\t * @remarks\n\t *\n\t * When enabled, the first line of the README must be `# package-name`.\n\t * This ensures consistency and helps users identify the package.\n\t */\n\trequireMatchingTitle?: boolean;\n\n\t/**\n\t * A string that must appear in the README content.\n\t *\n\t * @remarks\n\t *\n\t * Useful for ensuring all READMEs include required content like trademark\n\t * notices, disclaimers, or standard documentation sections.\n\t *\n\t * @example\n\t * ```typescript\n\t * requiredContent: \"## Trademark\"\n\t * ```\n\t */\n\trequiredContent?: string;\n}\n\n/**\n * Extract the title from a README file (first markdown H1 heading).\n *\n * @param content - The README content\n * @returns The title text (without the `# ` prefix) or `undefined` if not found\n */\nfunction extractReadmeTitle(content: string): string | undefined {\n\tconst lines = content.split(LINE_SPLIT_REGEX);\n\tfor (const line of lines) {\n\t\tconst match = HEADING_REGEX.exec(line);\n\t\tif (match?.[1]) {\n\t\t\treturn match[1].trim();\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Create a basic README content with package name as title.\n */\nfunction createReadmeContent(\n\tpackageName: string,\n\trequiredContent?: string,\n): string {\n\tlet content = `# ${packageName}\\n`;\n\tif (requiredContent) {\n\t\tcontent += `\\n${requiredContent}\\n`;\n\t}\n\treturn content;\n}\n\n/**\n * Handle case when README is missing.\n */\nasync function handleMissingReadme(\n\treadmePath: string,\n\tpackageName: string,\n\tfile: string,\n\tresolve: boolean,\n\trequiredContent?: string,\n): Promise<PolicyFailure | PolicyFixResult> {\n\tif (resolve) {\n\t\ttry {\n\t\t\tawait writeFile(\n\t\t\t\treadmePath,\n\t\t\t\tcreateReadmeContent(packageName, requiredContent),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tname: \"PackageReadme\",\n\t\t\t\tfile,\n\t\t\t\tresolved: true,\n\t\t\t\tautoFixable: true,\n\t\t\t\terrorMessages: [`Created README.md for package \"${packageName}\"`],\n\t\t\t};\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tname: \"PackageReadme\",\n\t\t\t\tfile,\n\t\t\t\tresolved: false,\n\t\t\t\tautoFixable: true,\n\t\t\t\terrorMessages: [\n\t\t\t\t\t`Failed to create README.md for package \"${packageName}\"`,\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tname: \"PackageReadme\",\n\t\tfile,\n\t\tautoFixable: true,\n\t\terrorMessages: [`README.md missing for package \"${packageName}\"`],\n\t};\n}\n\n/**\n * Validate README title against package name.\n *\n * @returns `true` if valid, or an error message string if invalid\n */\nfunction validateTitle(\n\treadmeContent: string,\n\tpackageName: string,\n): true | string {\n\tconst title = extractReadmeTitle(readmeContent);\n\tif (title !== packageName) {\n\t\treturn `README title \"${title ?? \"(none)\"}\" doesn't match package name \"${packageName}\"`;\n\t}\n\treturn true;\n}\n\n/**\n * Handle required content validation and auto-fix.\n */\nasync function handleRequiredContent(\n\treadmePath: string,\n\treadmeContent: string,\n\trequiredContent: string,\n\tresolve: boolean,\n): Promise<{ error?: string; fixed: boolean }> {\n\tif (readmeContent.includes(requiredContent)) {\n\t\treturn { fixed: false };\n\t}\n\n\tif (resolve) {\n\t\ttry {\n\t\t\tconst newContent = readmeContent.endsWith(\"\\n\")\n\t\t\t\t? `${readmeContent}${requiredContent}\\n`\n\t\t\t\t: `${readmeContent}\\n${requiredContent}\\n`;\n\t\t\tawait writeFile(readmePath, newContent);\n\t\t\treturn {\n\t\t\t\terror: `README missing required content: \"${requiredContent}\"`,\n\t\t\t\tfixed: true,\n\t\t\t};\n\t\t} catch {\n\t\t\t// Fall through to report error\n\t\t}\n\t}\n\n\treturn {\n\t\terror: `README missing required content: \"${requiredContent}\"`,\n\t\tfixed: false,\n\t};\n}\n\ninterface ValidationContext {\n\treadmePath: string;\n\treadmeContent: string;\n\tpackageName: string;\n\tfile: string;\n\tresolve: boolean;\n\trequireMatchingTitle: boolean;\n\trequiredContent: string | undefined;\n}\n\n/**\n * Validate existing README content.\n */\nasync function validateExistingReadme(\n\tctx: ValidationContext,\n): Promise<true | PolicyFailure | PolicyFixResult> {\n\tconst errors: string[] = [];\n\tlet wasFixed = false;\n\n\t// Check title matches package name\n\tif (ctx.requireMatchingTitle) {\n\t\tconst titleResult = validateTitle(ctx.readmeContent, ctx.packageName);\n\t\tif (titleResult !== true) {\n\t\t\terrors.push(titleResult);\n\t\t}\n\t}\n\n\t// Check required content\n\tif (ctx.requiredContent) {\n\t\tconst contentResult = await handleRequiredContent(\n\t\t\tctx.readmePath,\n\t\t\tctx.readmeContent,\n\t\t\tctx.requiredContent,\n\t\t\tctx.resolve,\n\t\t);\n\t\tif (contentResult.error) {\n\t\t\terrors.push(contentResult.error);\n\t\t}\n\t\tif (contentResult.fixed) {\n\t\t\twasFixed = true;\n\t\t}\n\t}\n\n\tif (errors.length === 0) {\n\t\treturn true;\n\t}\n\n\tif (wasFixed) {\n\t\treturn {\n\t\t\tname: \"PackageReadme\",\n\t\t\tfile: ctx.file,\n\t\t\tresolved: true,\n\t\t\tautoFixable: true,\n\t\t\terrorMessages: [errors.join(\"; \")],\n\t\t};\n\t}\n\n\treturn {\n\t\tname: \"PackageReadme\",\n\t\tfile: ctx.file,\n\t\tautoFixable:\n\t\t\tctx.requiredContent !== undefined &&\n\t\t\t!ctx.readmeContent.includes(ctx.requiredContent),\n\t\terrorMessages: [errors.join(\"; \")],\n\t};\n}\n\n/**\n * A repo policy that ensures each package has a README.md file with proper content.\n *\n * @remarks\n *\n * This policy validates that packages have documentation and can enforce:\n * 1. README.md file exists\n * 2. README title matches the package name\n * 3. README contains required content (e.g., trademark notices)\n *\n * The policy supports auto-fixing by creating a basic README with the package name as title.\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { PackageReadme } from \"repopo/policies\";\n *\n * const config: RepopoConfig = {\n * policies: [\n * // Basic README validation\n * makePolicy(PackageReadme),\n *\n * // Require trademark notice in all READMEs\n * makePolicy(PackageReadme, {\n * requiredContent: \"## Trademark\",\n * }),\n * ],\n * };\n * ```\n *\n * @alpha\n */\nexport const PackageReadme = definePackagePolicy<\n\tPackageJson,\n\tPackageReadmeSettings | undefined\n>({\n\tname: \"PackageReadme\",\n\tdescription:\n\t\t\"Ensures each package has a README.md file with proper title and required content.\",\n\thandler: async (json, { file, resolve, config }) => {\n\t\tconst skipPrivate = config?.skipPrivate ?? true;\n\t\tconst requireMatchingTitle = config?.requireMatchingTitle ?? true;\n\t\tconst requiredContent = config?.requiredContent;\n\n\t\t// Skip private packages if configured to do so\n\t\tif (skipPrivate && json.private === true) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst packageName = json.name ?? \"unknown\";\n\t\tconst packageDir = path.dirname(file);\n\t\tconst readmePath = path.join(packageDir, \"README.md\");\n\n\t\t// Check if README exists\n\t\tif (!existsSync(readmePath)) {\n\t\t\treturn await handleMissingReadme(\n\t\t\t\treadmePath,\n\t\t\t\tpackageName,\n\t\t\t\tfile,\n\t\t\t\tresolve,\n\t\t\t\trequiredContent,\n\t\t\t);\n\t\t}\n\n\t\t// README exists, validate content\n\t\tconst readmeContent = await readFile(readmePath, \"utf-8\");\n\t\treturn await validateExistingReadme({\n\t\t\treadmePath,\n\t\t\treadmeContent,\n\t\t\tpackageName,\n\t\t\tfile,\n\t\t\tresolve,\n\t\t\trequireMatchingTitle,\n\t\t\trequiredContent,\n\t\t});\n\t},\n});\n"]}
1
+ {"version":3,"file":"PackageReadme.js","sourceRoot":"","sources":["../../src/policies/PackageReadme.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFinding } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n// Pre-compiled regex for performance\nconst LINE_SPLIT_REGEX = /\\r?\\n/;\nconst HEADING_REGEX = /^#\\s+(.+)$/;\n\n/**\n * Policy settings for the PackageReadme repo policy.\n *\n * @public\n */\nexport interface PackageReadmeSettings {\n\t/**\n\t * Whether to skip validation for private packages.\n\t *\n\t * @defaultValue true\n\t *\n\t * @remarks\n\t *\n\t * Private packages are typically not published and may not need a README file.\n\t * Set to `false` to require README files for all packages.\n\t */\n\tskipPrivate?: boolean;\n\n\t/**\n\t * Whether to require the README title to match the package name.\n\t *\n\t * @defaultValue true\n\t *\n\t * @remarks\n\t *\n\t * When enabled, the first line of the README must be `# package-name`.\n\t * This ensures consistency and helps users identify the package.\n\t */\n\trequireMatchingTitle?: boolean;\n\n\t/**\n\t * A string that must appear in the README content.\n\t *\n\t * @remarks\n\t *\n\t * Useful for ensuring all READMEs include required content like trademark\n\t * notices, disclaimers, or standard documentation sections.\n\t *\n\t * @example\n\t * ```typescript\n\t * requiredContent: \"## Trademark\"\n\t * ```\n\t */\n\trequiredContent?: string;\n}\n\n/**\n * Extract the title from a README file (first markdown H1 heading).\n *\n * @param content - The README content\n * @returns The title text (without the `# ` prefix) or `undefined` if not found\n */\nfunction extractReadmeTitle(content: string): string | undefined {\n\tconst lines = content.split(LINE_SPLIT_REGEX);\n\tfor (const line of lines) {\n\t\tconst match = HEADING_REGEX.exec(line);\n\t\tif (match?.[1]) {\n\t\t\treturn match[1].trim();\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Create a basic README content with package name as title.\n */\nfunction createReadmeContent(\n\tpackageName: string,\n\trequiredContent?: string,\n): string {\n\tlet content = `# ${packageName}\\n`;\n\tif (requiredContent) {\n\t\tcontent += `\\n${requiredContent}\\n`;\n\t}\n\treturn content;\n}\n\n/**\n * Handle case when README is missing.\n */\nasync function handleMissingReadme(\n\treadmePath: string,\n\tpackageName: string,\n\t_file: string,\n\tresolve: boolean,\n\trequiredContent?: string,\n): Promise<PolicyFinding[]> {\n\tif (resolve) {\n\t\ttry {\n\t\t\tawait writeFile(\n\t\t\t\treadmePath,\n\t\t\t\tcreateReadmeContent(packageName, requiredContent),\n\t\t\t);\n\t\t\treturn [`Created README.md for package \"${packageName}\"`].map(\n\t\t\t\t(message) => ({ message, fixStatus: \"fixed\" }),\n\t\t\t);\n\t\t} catch {\n\t\t\treturn [`Failed to create README.md for package \"${packageName}\"`].map(\n\t\t\t\t(message) => ({ message, fixStatus: \"failed\" }),\n\t\t\t);\n\t\t}\n\t}\n\treturn [`README.md missing for package \"${packageName}\"`].map((message) => ({\n\t\tmessage,\n\t\tfixStatus: \"available\",\n\t}));\n}\n\n/**\n * Validate README title against package name.\n *\n * @returns `true` if valid, or an error message string if invalid\n */\nfunction validateTitle(\n\treadmeContent: string,\n\tpackageName: string,\n): true | string {\n\tconst title = extractReadmeTitle(readmeContent);\n\tif (title !== packageName) {\n\t\treturn `README title \"${title ?? \"(none)\"}\" doesn't match package name \"${packageName}\"`;\n\t}\n\treturn true;\n}\n\n/**\n * Handle required content validation and auto-fix.\n */\nasync function handleRequiredContent(\n\treadmePath: string,\n\treadmeContent: string,\n\trequiredContent: string,\n\tresolve: boolean,\n): Promise<PolicyFinding | undefined> {\n\tif (readmeContent.includes(requiredContent)) {\n\t\treturn undefined;\n\t}\n\n\tif (resolve) {\n\t\ttry {\n\t\t\tconst newContent = readmeContent.endsWith(\"\\n\")\n\t\t\t\t? `${readmeContent}${requiredContent}\\n`\n\t\t\t\t: `${readmeContent}\\n${requiredContent}\\n`;\n\t\t\tawait writeFile(readmePath, newContent);\n\t\t\treturn {\n\t\t\t\tmessage: `README missing required content: \"${requiredContent}\"`,\n\t\t\t\tfixStatus: \"fixed\",\n\t\t\t};\n\t\t} catch {\n\t\t\t// Fall through to report error\n\t\t}\n\t}\n\n\treturn {\n\t\tmessage: `README missing required content: \"${requiredContent}\"`,\n\t\tfixStatus: resolve ? \"failed\" : \"available\",\n\t};\n}\n\ninterface ValidationContext {\n\treadmePath: string;\n\treadmeContent: string;\n\tpackageName: string;\n\tfile: string;\n\tresolve: boolean;\n\trequireMatchingTitle: boolean;\n\trequiredContent: string | undefined;\n}\n\n/**\n * Validate existing README content.\n */\nasync function validateExistingReadme(\n\tctx: ValidationContext,\n): Promise<PolicyFinding[]> {\n\tconst findings: PolicyFinding[] = [];\n\t// Check title matches package name\n\tif (ctx.requireMatchingTitle) {\n\t\tconst titleResult = validateTitle(ctx.readmeContent, ctx.packageName);\n\t\tif (titleResult !== true) {\n\t\t\tfindings.push({ message: titleResult });\n\t\t}\n\t}\n\n\t// Check required content\n\tif (ctx.requiredContent) {\n\t\tconst contentResult = await handleRequiredContent(\n\t\t\tctx.readmePath,\n\t\t\tctx.readmeContent,\n\t\t\tctx.requiredContent,\n\t\t\tctx.resolve,\n\t\t);\n\t\tif (contentResult) {\n\t\t\tfindings.push(contentResult);\n\t\t}\n\t}\n\treturn findings;\n}\n\n/**\n * A repo policy that ensures each package has a README.md file with proper content.\n *\n * @remarks\n *\n * This policy validates that packages have documentation and can enforce:\n * 1. README.md file exists\n * 2. README title matches the package name\n * 3. README contains required content (e.g., trademark notices)\n *\n * The policy supports auto-fixing by creating a basic README with the package name as title.\n *\n * @example\n * ```typescript\n * import { makePolicy } from \"repopo\";\n * import { PackageReadme } from \"repopo/policies\";\n *\n * const config: RepopoConfig = {\n * policies: [\n * // Basic README validation\n * makePolicy(PackageReadme, { instanceId: \"readme\" }),\n *\n * // Require trademark notice in all READMEs\n * makePolicy(PackageReadme, {\n * instanceId: \"readme-trademark\",\n * config: { requiredContent: \"## Trademark\" },\n * }),\n * ],\n * };\n * ```\n *\n * @public\n */\nexport const PackageReadme = definePackagePolicy<\n\tPackageJson,\n\tPackageReadmeSettings | undefined\n>({\n\tname: \"PackageReadme\",\n\tdescription:\n\t\t\"Ensures each package has a README.md file with proper title and required content.\",\n\thandler: async (json, { file, root, resolve, config }) => {\n\t\tconst skipPrivate = config?.skipPrivate ?? true;\n\t\tconst requireMatchingTitle = config?.requireMatchingTitle ?? true;\n\t\tconst requiredContent = config?.requiredContent;\n\n\t\t// Skip private packages if configured to do so\n\t\tif (skipPrivate && json.private === true) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst packageName = json.name ?? \"unknown\";\n\t\tconst packageDir = path.dirname(path.resolve(root, file));\n\t\tconst readmePath = path.join(packageDir, \"README.md\");\n\n\t\t// Check if README exists\n\t\tif (!existsSync(readmePath)) {\n\t\t\treturn await handleMissingReadme(\n\t\t\t\treadmePath,\n\t\t\t\tpackageName,\n\t\t\t\tfile,\n\t\t\t\tresolve,\n\t\t\t\trequiredContent,\n\t\t\t);\n\t\t}\n\n\t\t// README exists, validate content\n\t\tconst readmeContent = await readFile(readmePath, \"utf-8\");\n\t\treturn await validateExistingReadme({\n\t\t\treadmePath,\n\t\t\treadmeContent,\n\t\t\tpackageName,\n\t\t\tfile,\n\t\t\tresolve,\n\t\t\trequireMatchingTitle,\n\t\t\trequiredContent,\n\t\t});\n\t},\n});\n"]}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Configuration for validating that a script's body contains required substrings.
3
3
  *
4
- * @alpha
4
+ * @public
5
5
  */
6
6
  export interface ScriptMustContainRule {
7
7
  /**
@@ -17,7 +17,7 @@ export interface ScriptMustContainRule {
17
17
  /**
18
18
  * Configuration for conditional script requirements.
19
19
  *
20
- * @alpha
20
+ * @public
21
21
  */
22
22
  export interface ConditionalScriptRule {
23
23
  /**
@@ -56,13 +56,13 @@ export interface ConditionalScriptRule {
56
56
  * { lint: "biome lint ." }
57
57
  * ```
58
58
  *
59
- * @alpha
59
+ * @public
60
60
  */
61
61
  export type RequiredScriptEntry = string | Record<string, string>;
62
62
  /**
63
63
  * Policy settings for the PackageScripts repo policy.
64
64
  *
65
- * @alpha
65
+ * @public
66
66
  */
67
67
  export interface PackageScriptsSettings {
68
68
  /**
@@ -180,29 +180,33 @@ export interface PackageScriptsSettings {
180
180
  * const config: RepopoConfig = {
181
181
  * policies: [
182
182
  * makePolicy(PackageScripts, {
183
- * // Scripts that must exist
184
- * must: [
185
- * "test", // Must exist, no auto-fix
186
- * { build: "tsc" }, // Must exist, auto-fix available
187
- * { lint: "biome lint ." }, // Must exist, auto-fix available
188
- * ],
189
- * // Scripts that must exist AND match exactly
190
- * exact: {
191
- * clean: "rimraf dist esm",
192
- * format: "biome format --write .",
183
+ * config: {
184
+ * // Scripts that must exist
185
+ * must: [
186
+ * "test", // Must exist, no auto-fix
187
+ * { build: "tsc" }, // Must exist, auto-fix available
188
+ * { lint: "biome lint ." }, // Must exist, auto-fix available
189
+ * ],
190
+ * // Scripts that must exist AND match exactly
191
+ * exact: {
192
+ * clean: "rimraf dist esm",
193
+ * format: "biome format --write .",
194
+ * },
195
+ * // If "build" exists, "clean" must also exist (with inline auto-fix default)
196
+ * conditionalRequired: [{ ifPresent: "build", requires: [{ clean: "rimraf dist" }] }],
197
+ * // Script body must contain these substrings
198
+ * scriptMustContain: [{ script: "build", mustContain: ["tsc"] }],
199
+ * // Only one of these can exist
200
+ * mutuallyExclusive: [["lint:eslint", "lint:biome"]],
193
201
  * },
194
- * // If "build" exists, "clean" must also exist (with inline auto-fix default)
195
- * conditionalRequired: [{ ifPresent: "build", requires: [{ clean: "rimraf dist" }] }],
196
- * // Script body must contain these substrings
197
- * scriptMustContain: [{ script: "build", mustContain: ["tsc"] }],
198
- * // Only one of these can exist
199
- * mutuallyExclusive: [["lint:eslint", "lint:biome"]],
200
202
  * }),
201
203
  * ],
202
204
  * };
203
205
  * ```
204
206
  *
205
- * @alpha
207
+ * @public
206
208
  */
207
- export declare const PackageScripts: import("../policy.js").PolicyShape<PackageScriptsSettings | undefined>;
209
+ export declare const PackageScripts: import("../policy.js").FilePolicyDefinition<PackageScriptsSettings | undefined> & {
210
+ requiresConfig: true;
211
+ };
208
212
  //# sourceMappingURL=PackageScripts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PackageScripts.d.ts","sourceRoot":"","sources":["../../src/policies/PackageScripts.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAE7B;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/B;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAE/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,mBAAmB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAE9C;;;;;;;;;;;;;;;;;;OAkBG;IACH,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC5C;AAseD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,cAAc,wEAgEzB,CAAC"}
1
+ {"version":3,"file":"PackageScripts.d.ts","sourceRoot":"","sources":["../../src/policies/PackageScripts.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAE7B;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/B;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAE/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,mBAAmB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAE9C;;;;;;;;;;;;;;;;;;OAkBG;IACH,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC5C;AAseD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,cAAc;;CA+DzB,CAAC"}