repopo 0.10.0 → 0.12.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 (229) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +41 -2
  3. package/THIRD-PARTY-LICENSES.txt +71 -11
  4. package/bin/dev.js +5 -1
  5. package/esm/baseCommand.d.ts +1 -1
  6. package/esm/baseCommand.d.ts.map +1 -1
  7. package/esm/baseCommand.js +6 -9
  8. package/esm/baseCommand.js.map +1 -1
  9. package/esm/commands/check-native.d.ts +25 -0
  10. package/esm/commands/check-native.d.ts.map +1 -0
  11. package/esm/commands/check-native.js +137 -0
  12. package/esm/commands/check-native.js.map +1 -0
  13. package/esm/commands/check.d.ts +8 -20
  14. package/esm/commands/check.d.ts.map +1 -1
  15. package/esm/commands/check.js +77 -186
  16. package/esm/commands/check.js.map +1 -1
  17. package/esm/commands/list.d.ts.map +1 -1
  18. package/esm/commands/list.js +5 -6
  19. package/esm/commands/list.js.map +1 -1
  20. package/esm/context.d.ts +13 -3
  21. package/esm/context.d.ts.map +1 -1
  22. package/esm/context.js +11 -1
  23. package/esm/context.js.map +1 -1
  24. package/esm/index.d.ts +6 -1
  25. package/esm/index.d.ts.map +1 -1
  26. package/esm/index.js +3 -0
  27. package/esm/index.js.map +1 -1
  28. package/esm/makePolicy.d.ts +29 -2
  29. package/esm/makePolicy.d.ts.map +1 -1
  30. package/esm/makePolicy.js +46 -2
  31. package/esm/makePolicy.js.map +1 -1
  32. package/esm/perf.d.ts +7 -2
  33. package/esm/perf.d.ts.map +1 -1
  34. package/esm/perf.js.map +1 -1
  35. package/esm/policies/CargoLicenceValidated.d.ts +41 -0
  36. package/esm/policies/CargoLicenceValidated.d.ts.map +1 -0
  37. package/esm/policies/CargoLicenceValidated.js +45 -0
  38. package/esm/policies/CargoLicenceValidated.js.map +1 -0
  39. package/esm/policies/CargoLintsConfigured.d.ts +30 -0
  40. package/esm/policies/CargoLintsConfigured.d.ts.map +1 -0
  41. package/esm/policies/CargoLintsConfigured.js +61 -0
  42. package/esm/policies/CargoLintsConfigured.js.map +1 -0
  43. package/esm/policies/CargoLockPolicy.d.ts +34 -0
  44. package/esm/policies/CargoLockPolicy.d.ts.map +1 -0
  45. package/esm/policies/CargoLockPolicy.js +57 -0
  46. package/esm/policies/CargoLockPolicy.js.map +1 -0
  47. package/esm/policies/CargoTomlRequired.d.ts +34 -0
  48. package/esm/policies/CargoTomlRequired.d.ts.map +1 -0
  49. package/esm/policies/CargoTomlRequired.js +77 -0
  50. package/esm/policies/CargoTomlRequired.js.map +1 -0
  51. package/esm/policies/CargoTomlSorted.d.ts +20 -0
  52. package/esm/policies/CargoTomlSorted.d.ts.map +1 -0
  53. package/esm/policies/CargoTomlSorted.js +164 -0
  54. package/esm/policies/CargoTomlSorted.js.map +1 -0
  55. package/esm/policies/ConditionalScripts.d.ts.map +1 -1
  56. package/esm/policies/ConditionalScripts.js +3 -2
  57. package/esm/policies/ConditionalScripts.js.map +1 -1
  58. package/esm/policies/ExactScripts.d.ts.map +1 -1
  59. package/esm/policies/ExactScripts.js +3 -2
  60. package/esm/policies/ExactScripts.js.map +1 -1
  61. package/esm/policies/GleamDepVersions.d.ts +25 -0
  62. package/esm/policies/GleamDepVersions.d.ts.map +1 -0
  63. package/esm/policies/GleamDepVersions.js +67 -0
  64. package/esm/policies/GleamDepVersions.js.map +1 -0
  65. package/esm/policies/GleamDocExists.d.ts +24 -0
  66. package/esm/policies/GleamDocExists.d.ts.map +1 -0
  67. package/esm/policies/GleamDocExists.js +39 -0
  68. package/esm/policies/GleamDocExists.js.map +1 -0
  69. package/esm/policies/GleamInternalModulesConfigured.d.ts +21 -0
  70. package/esm/policies/GleamInternalModulesConfigured.d.ts.map +1 -0
  71. package/esm/policies/GleamInternalModulesConfigured.js +30 -0
  72. package/esm/policies/GleamInternalModulesConfigured.js.map +1 -0
  73. package/esm/policies/GleamLicenceConfigured.d.ts +29 -0
  74. package/esm/policies/GleamLicenceConfigured.d.ts.map +1 -0
  75. package/esm/policies/GleamLicenceConfigured.js +34 -0
  76. package/esm/policies/GleamLicenceConfigured.js.map +1 -0
  77. package/esm/policies/GleamManifestCommitted.d.ts +9 -0
  78. package/esm/policies/GleamManifestCommitted.d.ts.map +1 -0
  79. package/esm/policies/GleamManifestCommitted.js +26 -0
  80. package/esm/policies/GleamManifestCommitted.js.map +1 -0
  81. package/esm/policies/GleamMonorepoConsistency.d.ts +30 -0
  82. package/esm/policies/GleamMonorepoConsistency.d.ts.map +1 -0
  83. package/esm/policies/GleamMonorepoConsistency.js +74 -0
  84. package/esm/policies/GleamMonorepoConsistency.js.map +1 -0
  85. package/esm/policies/GleamNameRestrictions.d.ts +25 -0
  86. package/esm/policies/GleamNameRestrictions.d.ts.map +1 -0
  87. package/esm/policies/GleamNameRestrictions.js +44 -0
  88. package/esm/policies/GleamNameRestrictions.js.map +1 -0
  89. package/esm/policies/GleamNoPathDepsInPublished.d.ts +22 -0
  90. package/esm/policies/GleamNoPathDepsInPublished.d.ts.map +1 -0
  91. package/esm/policies/GleamNoPathDepsInPublished.js +43 -0
  92. package/esm/policies/GleamNoPathDepsInPublished.js.map +1 -0
  93. package/esm/policies/GleamPathDepsValid.d.ts +9 -0
  94. package/esm/policies/GleamPathDepsValid.d.ts.map +1 -0
  95. package/esm/policies/GleamPathDepsValid.js +59 -0
  96. package/esm/policies/GleamPathDepsValid.js.map +1 -0
  97. package/esm/policies/GleamProjectStructure.d.ts +25 -0
  98. package/esm/policies/GleamProjectStructure.d.ts.map +1 -0
  99. package/esm/policies/GleamProjectStructure.js +33 -0
  100. package/esm/policies/GleamProjectStructure.js.map +1 -0
  101. package/esm/policies/GleamSharedDependencyVersions.d.ts +29 -0
  102. package/esm/policies/GleamSharedDependencyVersions.d.ts.map +1 -0
  103. package/esm/policies/GleamSharedDependencyVersions.js +101 -0
  104. package/esm/policies/GleamSharedDependencyVersions.js.map +1 -0
  105. package/esm/policies/GleamTomlRequired.d.ts +30 -0
  106. package/esm/policies/GleamTomlRequired.d.ts.map +1 -0
  107. package/esm/policies/GleamTomlRequired.js +37 -0
  108. package/esm/policies/GleamTomlRequired.js.map +1 -0
  109. package/esm/policies/GleamTomlSorted.d.ts +20 -0
  110. package/esm/policies/GleamTomlSorted.d.ts.map +1 -0
  111. package/esm/policies/GleamTomlSorted.js +153 -0
  112. package/esm/policies/GleamTomlSorted.js.map +1 -0
  113. package/esm/policies/GleamVersionConstraint.d.ts +20 -0
  114. package/esm/policies/GleamVersionConstraint.d.ts.map +1 -0
  115. package/esm/policies/GleamVersionConstraint.js +64 -0
  116. package/esm/policies/GleamVersionConstraint.js.map +1 -0
  117. package/esm/policies/HtmlFileHeaders.js +1 -1
  118. package/esm/policies/HtmlFileHeaders.js.map +1 -1
  119. package/esm/policies/NoBuildDirectory.d.ts +9 -0
  120. package/esm/policies/NoBuildDirectory.d.ts.map +1 -0
  121. package/esm/policies/NoBuildDirectory.js +29 -0
  122. package/esm/policies/NoBuildDirectory.js.map +1 -0
  123. package/esm/policies/NoTargetArtifacts.d.ts +8 -0
  124. package/esm/policies/NoTargetArtifacts.d.ts.map +1 -0
  125. package/esm/policies/NoTargetArtifacts.js +42 -0
  126. package/esm/policies/NoTargetArtifacts.js.map +1 -0
  127. package/esm/policies/NoUnsafeWithoutJustification.d.ts +24 -0
  128. package/esm/policies/NoUnsafeWithoutJustification.d.ts.map +1 -0
  129. package/esm/policies/NoUnsafeWithoutJustification.js +80 -0
  130. package/esm/policies/NoUnsafeWithoutJustification.js.map +1 -0
  131. package/esm/policies/NoWildcardDependencies.d.ts +30 -0
  132. package/esm/policies/NoWildcardDependencies.d.ts.map +1 -0
  133. package/esm/policies/NoWildcardDependencies.js +83 -0
  134. package/esm/policies/NoWildcardDependencies.js.map +1 -0
  135. package/esm/policies/PackageEsmType.d.ts.map +1 -1
  136. package/esm/policies/PackageEsmType.js +7 -5
  137. package/esm/policies/PackageEsmType.js.map +1 -1
  138. package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
  139. package/esm/policies/PackageJsonProperties.js +12 -4
  140. package/esm/policies/PackageJsonProperties.js.map +1 -1
  141. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
  142. package/esm/policies/PackageJsonRepoDirectoryProperty.js +3 -2
  143. package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
  144. package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
  145. package/esm/policies/PackageJsonSorted.js +42 -7
  146. package/esm/policies/PackageJsonSorted.js.map +1 -1
  147. package/esm/policies/PackageLicense.d.ts.map +1 -1
  148. package/esm/policies/PackageLicense.js +1 -2
  149. package/esm/policies/PackageLicense.js.map +1 -1
  150. package/esm/policies/PackagePrivateField.d.ts.map +1 -1
  151. package/esm/policies/PackagePrivateField.js +3 -2
  152. package/esm/policies/PackagePrivateField.js.map +1 -1
  153. package/esm/policies/PackageReadme.js +2 -2
  154. package/esm/policies/PackageReadme.js.map +1 -1
  155. package/esm/policies/PackageScripts.d.ts.map +1 -1
  156. package/esm/policies/PackageScripts.js +3 -2
  157. package/esm/policies/PackageScripts.js.map +1 -1
  158. package/esm/policies/PackageTestScripts.js +3 -3
  159. package/esm/policies/PackageTestScripts.js.map +1 -1
  160. package/esm/policies/PublicApiDocumented.d.ts +21 -0
  161. package/esm/policies/PublicApiDocumented.d.ts.map +1 -0
  162. package/esm/policies/PublicApiDocumented.js +36 -0
  163. package/esm/policies/PublicApiDocumented.js.map +1 -0
  164. package/esm/policies/RequiredScripts.d.ts.map +1 -1
  165. package/esm/policies/RequiredScripts.js +3 -2
  166. package/esm/policies/RequiredScripts.js.map +1 -1
  167. package/esm/policies/RustDocExists.d.ts +24 -0
  168. package/esm/policies/RustDocExists.d.ts.map +1 -0
  169. package/esm/policies/RustDocExists.js +49 -0
  170. package/esm/policies/RustDocExists.js.map +1 -0
  171. package/esm/policies/RustToolchainExists.d.ts +20 -0
  172. package/esm/policies/RustToolchainExists.d.ts.map +1 -0
  173. package/esm/policies/RustToolchainExists.js +27 -0
  174. package/esm/policies/RustToolchainExists.js.map +1 -0
  175. package/esm/policies/RustfmtConfigExists.d.ts +20 -0
  176. package/esm/policies/RustfmtConfigExists.d.ts.map +1 -0
  177. package/esm/policies/RustfmtConfigExists.js +27 -0
  178. package/esm/policies/RustfmtConfigExists.js.map +1 -0
  179. package/esm/policies/SharedDependencyVersions.d.ts +24 -0
  180. package/esm/policies/SharedDependencyVersions.d.ts.map +1 -0
  181. package/esm/policies/SharedDependencyVersions.js +135 -0
  182. package/esm/policies/SharedDependencyVersions.js.map +1 -0
  183. package/esm/policies/WorkspaceInheritance.d.ts +24 -0
  184. package/esm/policies/WorkspaceInheritance.d.ts.map +1 -0
  185. package/esm/policies/WorkspaceInheritance.js +94 -0
  186. package/esm/policies/WorkspaceInheritance.js.map +1 -0
  187. package/esm/policies/WorkspaceMembersValid.d.ts +20 -0
  188. package/esm/policies/WorkspaceMembersValid.d.ts.map +1 -0
  189. package/esm/policies/WorkspaceMembersValid.js +88 -0
  190. package/esm/policies/WorkspaceMembersValid.js.map +1 -0
  191. package/esm/policies/constants.d.ts +8 -0
  192. package/esm/policies/constants.d.ts.map +1 -1
  193. package/esm/policies/constants.js +8 -0
  194. package/esm/policies/constants.js.map +1 -1
  195. package/esm/policies.d.ts +30 -0
  196. package/esm/policies.d.ts.map +1 -1
  197. package/esm/policies.js +51 -1
  198. package/esm/policies.js.map +1 -1
  199. package/esm/policy.d.ts +24 -0
  200. package/esm/policy.d.ts.map +1 -1
  201. package/esm/policy.js.map +1 -1
  202. package/esm/policyDefiners/defineCargoPolicy.d.ts +66 -0
  203. package/esm/policyDefiners/defineCargoPolicy.d.ts.map +1 -0
  204. package/esm/policyDefiners/defineCargoPolicy.js +60 -0
  205. package/esm/policyDefiners/defineCargoPolicy.js.map +1 -0
  206. package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -1
  207. package/esm/policyDefiners/defineFileHeaderPolicy.js +6 -7
  208. package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -1
  209. package/esm/policyDefiners/defineGleamPolicy.d.ts +65 -0
  210. package/esm/policyDefiners/defineGleamPolicy.d.ts.map +1 -0
  211. package/esm/policyDefiners/defineGleamPolicy.js +59 -0
  212. package/esm/policyDefiners/defineGleamPolicy.js.map +1 -0
  213. package/esm/policyDefiners/spdxValidator.d.ts +74 -0
  214. package/esm/policyDefiners/spdxValidator.d.ts.map +1 -0
  215. package/esm/policyDefiners/spdxValidator.js +127 -0
  216. package/esm/policyDefiners/spdxValidator.js.map +1 -0
  217. package/esm/policyDefiners/tomlParser.d.ts +8 -0
  218. package/esm/policyDefiners/tomlParser.d.ts.map +1 -0
  219. package/esm/policyDefiners/tomlParser.js +17 -0
  220. package/esm/policyDefiners/tomlParser.js.map +1 -0
  221. package/esm/runner.d.ts +60 -0
  222. package/esm/runner.d.ts.map +1 -0
  223. package/esm/runner.js +174 -0
  224. package/esm/runner.js.map +1 -0
  225. package/esm/tsdoc-metadata.json +1 -1
  226. package/oclif.manifest.json +100 -3
  227. package/package.json +46 -31
  228. package/scripts/postinstall.mjs +154 -0
  229. package/sidecar/sidecar.mjs +468 -0
@@ -0,0 +1,25 @@
1
+ import type { PolicyDefinition } from "../policy.js";
2
+ /**
3
+ * Configuration for the GleamProjectStructure policy.
4
+ *
5
+ * @alpha
6
+ */
7
+ export interface GleamProjectStructureConfig {
8
+ /**
9
+ * If true, require the src/ directory to exist.
10
+ * @defaultValue true
11
+ */
12
+ requireSrcDir?: boolean;
13
+ /**
14
+ * If true, require the test/ directory to exist.
15
+ * @defaultValue false
16
+ */
17
+ requireTestDir?: boolean;
18
+ }
19
+ /**
20
+ * A policy that validates standard Gleam project structure.
21
+ *
22
+ * @alpha
23
+ */
24
+ export declare const GleamProjectStructure: PolicyDefinition<GleamProjectStructureConfig>;
25
+ //# sourceMappingURL=GleamProjectStructure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamProjectStructure.d.ts","sourceRoot":"","sources":["../../src/policies/GleamProjectStructure.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC3C;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,2BAA2B,CA+B7E,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "pathe";
3
+ import { makePolicyDefinition } from "../makePolicy.js";
4
+ /**
5
+ * A policy that validates standard Gleam project structure.
6
+ *
7
+ * @alpha
8
+ */
9
+ export const GleamProjectStructure = makePolicyDefinition({
10
+ name: "GleamProjectStructure",
11
+ description: "Validates that Gleam projects have the standard directory structure (src/, test/).",
12
+ match: /gleam\.toml$/,
13
+ handler: async ({ file, root, config }) => {
14
+ const dir = path.dirname(path.resolve(root, file));
15
+ const requireSrc = config?.requireSrcDir ?? true;
16
+ const requireTest = config?.requireTestDir ?? false;
17
+ const errors = [];
18
+ if (requireSrc && !existsSync(path.join(dir, "src"))) {
19
+ errors.push("Missing src/ directory. Gleam projects require a src/ directory for source modules.");
20
+ }
21
+ if (requireTest && !existsSync(path.join(dir, "test"))) {
22
+ errors.push("Missing test/ directory.");
23
+ }
24
+ if (errors.length > 0) {
25
+ return {
26
+ error: errors.join("; "),
27
+ manualFix: "Create the missing directories in your Gleam project.",
28
+ };
29
+ }
30
+ return true;
31
+ },
32
+ });
33
+ //# sourceMappingURL=GleamProjectStructure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamProjectStructure.js","sourceRoot":"","sources":["../../src/policies/GleamProjectStructure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,OAAO,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAsBxD;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GACjC,oBAAoB,CAAC;IACpB,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACV,oFAAoF;IACrF,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,MAAM,EAAE,aAAa,IAAI,IAAI,CAAC;QACjD,MAAM,WAAW,GAAG,MAAM,EAAE,cAAc,IAAI,KAAK,CAAC;QACpD,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,IAAI,CACV,qFAAqF,CACrF,CAAC;QACH,CAAC;QAED,IAAI,WAAW,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YACxD,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO;gBACN,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxB,SAAS,EAAE,uDAAuD;aAClE,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC,CAAC","sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"pathe\";\nimport { makePolicyDefinition } from \"../makePolicy.js\";\nimport type { PolicyDefinition } from \"../policy.js\";\n\n/**\n * Configuration for the GleamProjectStructure policy.\n *\n * @alpha\n */\nexport interface GleamProjectStructureConfig {\n\t/**\n\t * If true, require the src/ directory to exist.\n\t * @defaultValue true\n\t */\n\trequireSrcDir?: boolean;\n\n\t/**\n\t * If true, require the test/ directory to exist.\n\t * @defaultValue false\n\t */\n\trequireTestDir?: boolean;\n}\n\n/**\n * A policy that validates standard Gleam project structure.\n *\n * @alpha\n */\nexport const GleamProjectStructure: PolicyDefinition<GleamProjectStructureConfig> =\n\tmakePolicyDefinition({\n\t\tname: \"GleamProjectStructure\",\n\t\tdescription:\n\t\t\t\"Validates that Gleam projects have the standard directory structure (src/, test/).\",\n\t\tmatch: /gleam\\.toml$/,\n\t\thandler: async ({ file, root, config }) => {\n\t\t\tconst dir = path.dirname(path.resolve(root, file));\n\t\t\tconst requireSrc = config?.requireSrcDir ?? true;\n\t\t\tconst requireTest = config?.requireTestDir ?? false;\n\t\t\tconst errors: string[] = [];\n\n\t\t\tif (requireSrc && !existsSync(path.join(dir, \"src\"))) {\n\t\t\t\terrors.push(\n\t\t\t\t\t\"Missing src/ directory. Gleam projects require a src/ directory for source modules.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (requireTest && !existsSync(path.join(dir, \"test\"))) {\n\t\t\t\terrors.push(\"Missing test/ directory.\");\n\t\t\t}\n\n\t\t\tif (errors.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\t\tmanualFix: \"Create the missing directories in your Gleam project.\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t});\n"]}
@@ -0,0 +1,29 @@
1
+ import type { PolicyDefinition } from "../policy.js";
2
+ /**
3
+ * Configuration for the GleamSharedDependencyVersions policy.
4
+ *
5
+ * @alpha
6
+ */
7
+ export interface GleamSharedDependencyVersionsConfig {
8
+ /**
9
+ * If true, detect version mismatches across packages.
10
+ * @defaultValue true
11
+ */
12
+ detectMismatches?: boolean;
13
+ /**
14
+ * If true, also check dev-dependencies for mismatches.
15
+ * @defaultValue false
16
+ */
17
+ includeDev?: boolean;
18
+ /**
19
+ * Paths to gleam.toml files to compare (relative to repo root).
20
+ */
21
+ packages?: string[];
22
+ }
23
+ /**
24
+ * A policy that detects dependency version mismatches across Gleam packages in a monorepo.
25
+ *
26
+ * @alpha
27
+ */
28
+ export declare const GleamSharedDependencyVersions: PolicyDefinition<GleamSharedDependencyVersionsConfig>;
29
+ //# sourceMappingURL=GleamSharedDependencyVersions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamSharedDependencyVersions.d.ts","sourceRoot":"","sources":["../../src/policies/GleamSharedDependencyVersions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD;;;;GAIG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AA2DD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,gBAAgB,CAAC,mCAAmC,CAsD7F,CAAC"}
@@ -0,0 +1,101 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "pathe";
3
+ import { makePolicyDefinition } from "../makePolicy.js";
4
+ import { parseToml } from "../policyDefiners/tomlParser.js";
5
+ function extractVersion(dep) {
6
+ if (typeof dep === "string") {
7
+ return dep;
8
+ }
9
+ if (typeof dep === "object" && dep !== null) {
10
+ const record = dep;
11
+ if (typeof record.version === "string") {
12
+ return record.version;
13
+ }
14
+ }
15
+ return undefined;
16
+ }
17
+ function collectDeps(toml, includeDev) {
18
+ const deps = new Map();
19
+ const sections = ["dependencies"];
20
+ if (includeDev) {
21
+ sections.push("dev-dependencies");
22
+ }
23
+ for (const section of sections) {
24
+ const sectionDeps = toml[section];
25
+ if (!sectionDeps) {
26
+ continue;
27
+ }
28
+ for (const [name, value] of Object.entries(sectionDeps)) {
29
+ const version = extractVersion(value);
30
+ if (version) {
31
+ deps.set(name, version);
32
+ }
33
+ }
34
+ }
35
+ return deps;
36
+ }
37
+ function recordDependency(allDeps, depName, version, pkgPath) {
38
+ if (!allDeps.has(depName)) {
39
+ allDeps.set(depName, new Map());
40
+ }
41
+ const versionMap = allDeps.get(depName);
42
+ if (versionMap === undefined) {
43
+ return;
44
+ }
45
+ if (!versionMap.has(version)) {
46
+ versionMap.set(version, []);
47
+ }
48
+ versionMap.get(version)?.push(pkgPath);
49
+ }
50
+ /**
51
+ * A policy that detects dependency version mismatches across Gleam packages in a monorepo.
52
+ *
53
+ * @alpha
54
+ */
55
+ export const GleamSharedDependencyVersions = makePolicyDefinition({
56
+ name: "GleamSharedDependencyVersions",
57
+ description: "Detects dependency version mismatches across Gleam packages in a monorepo.",
58
+ match: /^gleam\.toml$/,
59
+ handler: async ({ root, config }) => {
60
+ const packagePaths = config?.packages;
61
+ if (!packagePaths || packagePaths.length < 2) {
62
+ return true;
63
+ }
64
+ const detectMismatches = config?.detectMismatches ?? true;
65
+ if (!detectMismatches) {
66
+ return true;
67
+ }
68
+ const includeDev = config?.includeDev ?? false;
69
+ const allDeps = new Map();
70
+ for (const pkgPath of packagePaths) {
71
+ try {
72
+ const content = await readFile(path.resolve(root, pkgPath), "utf-8");
73
+ const toml = await parseToml(content);
74
+ const deps = collectDeps(toml, includeDev);
75
+ for (const [name, version] of deps) {
76
+ recordDependency(allDeps, name, version, pkgPath);
77
+ }
78
+ }
79
+ catch {
80
+ // Package might not exist
81
+ }
82
+ }
83
+ const errors = [];
84
+ for (const [dep, versionMap] of allDeps) {
85
+ if (versionMap.size > 1) {
86
+ const details = [...versionMap.entries()]
87
+ .map(([ver, pkgs]) => `"${ver}" in ${pkgs.join(", ")}`)
88
+ .join("; ");
89
+ errors.push(`Version mismatch for "${dep}": ${details}`);
90
+ }
91
+ }
92
+ if (errors.length > 0) {
93
+ return {
94
+ error: errors.join("; "),
95
+ manualFix: "Align dependency versions across all Gleam packages in the monorepo.",
96
+ };
97
+ }
98
+ return true;
99
+ },
100
+ });
101
+ //# sourceMappingURL=GleamSharedDependencyVersions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamSharedDependencyVersions.js","sourceRoot":"","sources":["../../src/policies/GleamSharedDependencyVersions.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport path from \"pathe\";\nimport { makePolicyDefinition } from \"../makePolicy.js\";\nimport type { PolicyDefinition } from \"../policy.js\";\nimport { parseToml } from \"../policyDefiners/tomlParser.js\";\n\n/**\n * Configuration for the GleamSharedDependencyVersions policy.\n *\n * @alpha\n */\nexport interface GleamSharedDependencyVersionsConfig {\n\t/**\n\t * If true, detect version mismatches across packages.\n\t * @defaultValue true\n\t */\n\tdetectMismatches?: boolean;\n\n\t/**\n\t * If true, also check dev-dependencies for mismatches.\n\t * @defaultValue false\n\t */\n\tincludeDev?: boolean;\n\n\t/**\n\t * Paths to gleam.toml files to compare (relative to repo root).\n\t */\n\tpackages?: string[];\n}\n\nfunction extractVersion(dep: unknown): string | undefined {\n\tif (typeof dep === \"string\") {\n\t\treturn dep;\n\t}\n\tif (typeof dep === \"object\" && dep !== null) {\n\t\tconst record = dep as Record<string, unknown>;\n\t\tif (typeof record.version === \"string\") {\n\t\t\treturn record.version;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction collectDeps(\n\ttoml: Record<string, unknown>,\n\tincludeDev: boolean,\n): Map<string, string> {\n\tconst deps = new Map<string, string>();\n\tconst sections = [\"dependencies\"];\n\tif (includeDev) {\n\t\tsections.push(\"dev-dependencies\");\n\t}\n\n\tfor (const section of sections) {\n\t\tconst sectionDeps = toml[section] as Record<string, unknown> | undefined;\n\t\tif (!sectionDeps) {\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const [name, value] of Object.entries(sectionDeps)) {\n\t\t\tconst version = extractVersion(value);\n\t\t\tif (version) {\n\t\t\t\tdeps.set(name, version);\n\t\t\t}\n\t\t}\n\t}\n\treturn deps;\n}\n\nfunction recordDependency(\n\tallDeps: Map<string, Map<string, string[]>>,\n\tdepName: string,\n\tversion: string,\n\tpkgPath: string,\n): void {\n\tif (!allDeps.has(depName)) {\n\t\tallDeps.set(depName, new Map());\n\t}\n\tconst versionMap = allDeps.get(depName);\n\tif (versionMap === undefined) {\n\t\treturn;\n\t}\n\tif (!versionMap.has(version)) {\n\t\tversionMap.set(version, []);\n\t}\n\tversionMap.get(version)?.push(pkgPath);\n}\n\n/**\n * A policy that detects dependency version mismatches across Gleam packages in a monorepo.\n *\n * @alpha\n */\nexport const GleamSharedDependencyVersions: PolicyDefinition<GleamSharedDependencyVersionsConfig> =\n\tmakePolicyDefinition({\n\t\tname: \"GleamSharedDependencyVersions\",\n\t\tdescription:\n\t\t\t\"Detects dependency version mismatches across Gleam packages in a monorepo.\",\n\t\tmatch: /^gleam\\.toml$/,\n\t\thandler: async ({ root, config }) => {\n\t\t\tconst packagePaths = config?.packages;\n\t\t\tif (!packagePaths || packagePaths.length < 2) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst detectMismatches = config?.detectMismatches ?? true;\n\t\t\tif (!detectMismatches) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst includeDev = config?.includeDev ?? false;\n\t\t\tconst allDeps = new Map<string, Map<string, string[]>>();\n\n\t\t\tfor (const pkgPath of packagePaths) {\n\t\t\t\ttry {\n\t\t\t\t\tconst content = await readFile(path.resolve(root, pkgPath), \"utf-8\");\n\t\t\t\t\tconst toml = await parseToml(content);\n\t\t\t\t\tconst deps = collectDeps(toml, includeDev);\n\n\t\t\t\t\tfor (const [name, version] of deps) {\n\t\t\t\t\t\trecordDependency(allDeps, name, version, pkgPath);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Package might not exist\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst errors: string[] = [];\n\t\t\tfor (const [dep, versionMap] of allDeps) {\n\t\t\t\tif (versionMap.size > 1) {\n\t\t\t\t\tconst details = [...versionMap.entries()]\n\t\t\t\t\t\t.map(([ver, pkgs]) => `\"${ver}\" in ${pkgs.join(\", \")}`)\n\t\t\t\t\t\t.join(\"; \");\n\t\t\t\t\terrors.push(`Version mismatch for \"${dep}\": ${details}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (errors.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t\"Align dependency versions across all Gleam packages in the monorepo.\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t});\n"]}
@@ -0,0 +1,30 @@
1
+ import type { PolicyShape } from "../policy.js";
2
+ /**
3
+ * Configuration for the GleamTomlRequired policy.
4
+ *
5
+ * @alpha
6
+ */
7
+ export interface GleamTomlRequiredConfig {
8
+ /**
9
+ * Top-level fields that must exist in gleam.toml.
10
+ * @defaultValue ["name", "version"]
11
+ */
12
+ required?: string[];
13
+ /**
14
+ * If true, require the `gleam` compiler version constraint.
15
+ * @defaultValue false
16
+ */
17
+ requireGleamVersion?: boolean;
18
+ /**
19
+ * If true, require the `[repository]` section.
20
+ * @defaultValue false
21
+ */
22
+ requireRepository?: boolean;
23
+ }
24
+ /**
25
+ * A policy that enforces required fields exist in gleam.toml.
26
+ *
27
+ * @alpha
28
+ */
29
+ export declare const GleamTomlRequired: PolicyShape<GleamTomlRequiredConfig>;
30
+ //# sourceMappingURL=GleamTomlRequired.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamTomlRequired.d.ts","sourceRoot":"","sources":["../../src/policies/GleamTomlRequired.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAcD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,uBAAuB,CA8BhE,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { defineGleamPolicy, } from "../policyDefiners/defineGleamPolicy.js";
2
+ const DEFAULT_REQUIRED_FIELDS = ["name", "version"];
3
+ function checkRequiredFields(toml, fields) {
4
+ const errors = [];
5
+ for (const field of fields) {
6
+ if (toml[field] === undefined || toml[field] === "") {
7
+ errors.push(`Missing required field: ${field}`);
8
+ }
9
+ }
10
+ return errors;
11
+ }
12
+ /**
13
+ * A policy that enforces required fields exist in gleam.toml.
14
+ *
15
+ * @alpha
16
+ */
17
+ export const GleamTomlRequired = defineGleamPolicy({
18
+ name: "GleamTomlRequired",
19
+ description: "Ensures gleam.toml files contain required fields for proper project configuration.",
20
+ handler: async (toml, { config }) => {
21
+ const errors = checkRequiredFields(toml, config?.required ?? DEFAULT_REQUIRED_FIELDS);
22
+ if (config?.requireGleamVersion && toml.gleam === undefined) {
23
+ errors.push('Missing gleam version constraint. Add gleam = ">= x.y.z" to gleam.toml.');
24
+ }
25
+ if (config?.requireRepository && toml.repository === undefined) {
26
+ errors.push("Missing [repository] section in gleam.toml.");
27
+ }
28
+ if (errors.length > 0) {
29
+ return {
30
+ error: errors.join("; "),
31
+ manualFix: "Add the missing fields to your gleam.toml file.",
32
+ };
33
+ }
34
+ return true;
35
+ },
36
+ });
37
+ //# sourceMappingURL=GleamTomlRequired.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamTomlRequired.js","sourceRoot":"","sources":["../../src/policies/GleamTomlRequired.ts"],"names":[],"mappings":"AACA,OAAO,EACN,iBAAiB,GAEjB,MAAM,wCAAwC,CAAC;AA2BhD,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEpD,SAAS,mBAAmB,CAAC,IAAe,EAAE,MAAgB;IAC7D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;QACjD,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAC7B,iBAAiB,CAAC;IACjB,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACV,oFAAoF;IACrF,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,mBAAmB,CACjC,IAAI,EACJ,MAAM,EAAE,QAAQ,IAAI,uBAAuB,CAC3C,CAAC;QAEF,IAAI,MAAM,EAAE,mBAAmB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7D,MAAM,CAAC,IAAI,CACV,yEAAyE,CACzE,CAAC;QACH,CAAC;QAED,IAAI,MAAM,EAAE,iBAAiB,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO;gBACN,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxB,SAAS,EAAE,iDAAiD;aAC5D,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC,CAAC","sourcesContent":["import type { PolicyShape } from \"../policy.js\";\nimport {\n\tdefineGleamPolicy,\n\ttype GleamToml,\n} from \"../policyDefiners/defineGleamPolicy.js\";\n\n/**\n * Configuration for the GleamTomlRequired policy.\n *\n * @alpha\n */\nexport interface GleamTomlRequiredConfig {\n\t/**\n\t * Top-level fields that must exist in gleam.toml.\n\t * @defaultValue [\"name\", \"version\"]\n\t */\n\trequired?: string[];\n\n\t/**\n\t * If true, require the `gleam` compiler version constraint.\n\t * @defaultValue false\n\t */\n\trequireGleamVersion?: boolean;\n\n\t/**\n\t * If true, require the `[repository]` section.\n\t * @defaultValue false\n\t */\n\trequireRepository?: boolean;\n}\n\nconst DEFAULT_REQUIRED_FIELDS = [\"name\", \"version\"];\n\nfunction checkRequiredFields(toml: GleamToml, fields: string[]): string[] {\n\tconst errors: string[] = [];\n\tfor (const field of fields) {\n\t\tif (toml[field] === undefined || toml[field] === \"\") {\n\t\t\terrors.push(`Missing required field: ${field}`);\n\t\t}\n\t}\n\treturn errors;\n}\n\n/**\n * A policy that enforces required fields exist in gleam.toml.\n *\n * @alpha\n */\nexport const GleamTomlRequired: PolicyShape<GleamTomlRequiredConfig> =\n\tdefineGleamPolicy({\n\t\tname: \"GleamTomlRequired\",\n\t\tdescription:\n\t\t\t\"Ensures gleam.toml files contain required fields for proper project configuration.\",\n\t\thandler: async (toml: GleamToml, { config }) => {\n\t\t\tconst errors = checkRequiredFields(\n\t\t\t\ttoml,\n\t\t\t\tconfig?.required ?? DEFAULT_REQUIRED_FIELDS,\n\t\t\t);\n\n\t\t\tif (config?.requireGleamVersion && toml.gleam === undefined) {\n\t\t\t\terrors.push(\n\t\t\t\t\t'Missing gleam version constraint. Add gleam = \">= x.y.z\" to gleam.toml.',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (config?.requireRepository && toml.repository === undefined) {\n\t\t\t\terrors.push(\"Missing [repository] section in gleam.toml.\");\n\t\t\t}\n\n\t\t\tif (errors.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\t\tmanualFix: \"Add the missing fields to your gleam.toml file.\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t});\n"]}
@@ -0,0 +1,20 @@
1
+ import type { PolicyShape } from "../policy.js";
2
+ /**
3
+ * Configuration for the GleamTomlSorted policy.
4
+ *
5
+ * @alpha
6
+ */
7
+ export interface GleamTomlSortedConfig {
8
+ /**
9
+ * Sections whose keys should be sorted alphabetically.
10
+ * @defaultValue ["dependencies", "dev-dependencies"]
11
+ */
12
+ sections?: string[];
13
+ }
14
+ /**
15
+ * A policy that ensures dependency sections in gleam.toml are sorted alphabetically.
16
+ *
17
+ * @alpha
18
+ */
19
+ export declare const GleamTomlSorted: PolicyShape<GleamTomlSortedConfig>;
20
+ //# sourceMappingURL=GleamTomlSorted.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamTomlSorted.d.ts","sourceRoot":"","sources":["../../src/policies/GleamTomlSorted.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAwID;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,qBAAqB,CAoD5D,CAAC"}
@@ -0,0 +1,153 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { resolve } from "pathe";
3
+ import { defineGleamPolicy, } from "../policyDefiners/defineGleamPolicy.js";
4
+ const DEFAULT_SORTED_SECTIONS = ["dependencies", "dev-dependencies"];
5
+ const SECTION_HEADER_REGEX = /^\[([^\]]+)\]\s*$/;
6
+ const KEY_VALUE_REGEX = /^(\S+)\s*=/;
7
+ function isSorted(keys) {
8
+ for (let i = 1; i < keys.length; i++) {
9
+ const prev = keys[i - 1];
10
+ const curr = keys[i];
11
+ if (prev !== undefined && curr !== undefined && curr < prev) {
12
+ return false;
13
+ }
14
+ }
15
+ return true;
16
+ }
17
+ function classifyLine(line) {
18
+ if (SECTION_HEADER_REGEX.test(line)) {
19
+ return "section";
20
+ }
21
+ if (line.trim() === "") {
22
+ return "blank";
23
+ }
24
+ if (line.trim().startsWith("#")) {
25
+ return "comment";
26
+ }
27
+ if (KEY_VALUE_REGEX.test(line)) {
28
+ return "key";
29
+ }
30
+ return "continuation";
31
+ }
32
+ function handleCommentLine(entryLine, currentEntry) {
33
+ if (currentEntry) {
34
+ currentEntry.lines.push(entryLine);
35
+ return currentEntry;
36
+ }
37
+ return { key: "", lines: [entryLine] };
38
+ }
39
+ function processKeyLine(entryLine, currentEntry, entries) {
40
+ if (currentEntry) {
41
+ entries.push(currentEntry);
42
+ }
43
+ const keyMatch = entryLine.match(KEY_VALUE_REGEX);
44
+ return { key: keyMatch?.[1] ?? "", lines: [entryLine] };
45
+ }
46
+ function collectSectionEntries(lines, startIndex) {
47
+ const entries = [];
48
+ let currentEntry;
49
+ let i = startIndex;
50
+ while (i < lines.length) {
51
+ const entryLine = lines[i] ?? "";
52
+ const kind = classifyLine(entryLine);
53
+ if (kind === "section") {
54
+ break;
55
+ }
56
+ switch (kind) {
57
+ case "blank": {
58
+ break;
59
+ }
60
+ case "comment": {
61
+ currentEntry = handleCommentLine(entryLine, currentEntry);
62
+ break;
63
+ }
64
+ case "key": {
65
+ currentEntry = processKeyLine(entryLine, currentEntry, entries);
66
+ break;
67
+ }
68
+ case "continuation": {
69
+ currentEntry?.lines.push(entryLine);
70
+ break;
71
+ }
72
+ default: {
73
+ break;
74
+ }
75
+ }
76
+ i++;
77
+ }
78
+ if (currentEntry) {
79
+ entries.push(currentEntry);
80
+ }
81
+ return { entries, endIndex: i };
82
+ }
83
+ function sortTomlSections(content, sectionsToSort) {
84
+ const lines = content.split("\n");
85
+ const result = [];
86
+ let i = 0;
87
+ while (i < lines.length) {
88
+ const line = lines[i] ?? "";
89
+ const sectionMatch = line.match(SECTION_HEADER_REGEX);
90
+ if (sectionMatch && sectionsToSort.includes(sectionMatch[1] ?? "")) {
91
+ result.push(line);
92
+ i++;
93
+ const { entries, endIndex } = collectSectionEntries(lines, i);
94
+ entries.sort((a, b) => a.key.localeCompare(b.key));
95
+ for (const entry of entries) {
96
+ result.push(...entry.lines);
97
+ }
98
+ i = endIndex;
99
+ continue;
100
+ }
101
+ result.push(line);
102
+ i++;
103
+ }
104
+ return result.join("\n");
105
+ }
106
+ /**
107
+ * A policy that ensures dependency sections in gleam.toml are sorted alphabetically.
108
+ *
109
+ * @alpha
110
+ */
111
+ export const GleamTomlSorted = defineGleamPolicy({
112
+ name: "GleamTomlSorted",
113
+ description: "Ensures dependency sections in gleam.toml are sorted alphabetically.",
114
+ handler: async (toml, { file, root, resolve: shouldResolve, config }) => {
115
+ const sections = config?.sections ?? DEFAULT_SORTED_SECTIONS;
116
+ const unsortedSections = [];
117
+ for (const section of sections) {
118
+ const sectionData = toml[section];
119
+ if (sectionData !== undefined && !isSorted(Object.keys(sectionData))) {
120
+ unsortedSections.push(section);
121
+ }
122
+ }
123
+ if (unsortedSections.length === 0) {
124
+ return true;
125
+ }
126
+ if (shouldResolve) {
127
+ try {
128
+ const filePath = resolve(root, file);
129
+ const content = await readFile(filePath, "utf-8");
130
+ const sorted = sortTomlSections(content, unsortedSections);
131
+ await writeFile(filePath, sorted);
132
+ return {
133
+ error: `Unsorted sections: [${unsortedSections.join("], [")}]`,
134
+ fixable: true,
135
+ fixed: true,
136
+ };
137
+ }
138
+ catch {
139
+ return {
140
+ error: `Unsorted sections: [${unsortedSections.join("], [")}]. Auto-fix failed.`,
141
+ fixable: true,
142
+ fixed: false,
143
+ };
144
+ }
145
+ }
146
+ return {
147
+ error: `Unsorted sections: [${unsortedSections.join("], [")}]`,
148
+ fixable: true,
149
+ manualFix: "Sort the dependency keys alphabetically in the listed sections.",
150
+ };
151
+ },
152
+ });
153
+ //# sourceMappingURL=GleamTomlSorted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamTomlSorted.js","sourceRoot":"","sources":["../../src/policies/GleamTomlSorted.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"pathe\";\nimport type { PolicyShape } from \"../policy.js\";\nimport {\n\tdefineGleamPolicy,\n\ttype GleamToml,\n} from \"../policyDefiners/defineGleamPolicy.js\";\n\n/**\n * Configuration for the GleamTomlSorted policy.\n *\n * @alpha\n */\nexport interface GleamTomlSortedConfig {\n\t/**\n\t * Sections whose keys should be sorted alphabetically.\n\t * @defaultValue [\"dependencies\", \"dev-dependencies\"]\n\t */\n\tsections?: string[];\n}\n\nconst DEFAULT_SORTED_SECTIONS = [\"dependencies\", \"dev-dependencies\"];\n\nconst SECTION_HEADER_REGEX = /^\\[([^\\]]+)\\]\\s*$/;\nconst KEY_VALUE_REGEX = /^(\\S+)\\s*=/;\n\nfunction isSorted(keys: string[]): boolean {\n\tfor (let i = 1; i < keys.length; i++) {\n\t\tconst prev = keys[i - 1];\n\t\tconst curr = keys[i];\n\t\tif (prev !== undefined && curr !== undefined && curr < prev) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\ninterface TomlEntry {\n\tkey: string;\n\tlines: string[];\n}\n\nfunction classifyLine(\n\tline: string,\n): \"section\" | \"blank\" | \"comment\" | \"key\" | \"continuation\" {\n\tif (SECTION_HEADER_REGEX.test(line)) {\n\t\treturn \"section\";\n\t}\n\tif (line.trim() === \"\") {\n\t\treturn \"blank\";\n\t}\n\tif (line.trim().startsWith(\"#\")) {\n\t\treturn \"comment\";\n\t}\n\tif (KEY_VALUE_REGEX.test(line)) {\n\t\treturn \"key\";\n\t}\n\treturn \"continuation\";\n}\n\nfunction handleCommentLine(\n\tentryLine: string,\n\tcurrentEntry: TomlEntry | undefined,\n): TomlEntry {\n\tif (currentEntry) {\n\t\tcurrentEntry.lines.push(entryLine);\n\t\treturn currentEntry;\n\t}\n\treturn { key: \"\", lines: [entryLine] };\n}\n\nfunction processKeyLine(\n\tentryLine: string,\n\tcurrentEntry: TomlEntry | undefined,\n\tentries: TomlEntry[],\n): TomlEntry {\n\tif (currentEntry) {\n\t\tentries.push(currentEntry);\n\t}\n\tconst keyMatch = entryLine.match(KEY_VALUE_REGEX);\n\treturn { key: keyMatch?.[1] ?? \"\", lines: [entryLine] };\n}\n\nfunction collectSectionEntries(\n\tlines: string[],\n\tstartIndex: number,\n): { entries: TomlEntry[]; endIndex: number } {\n\tconst entries: TomlEntry[] = [];\n\tlet currentEntry: TomlEntry | undefined;\n\tlet i = startIndex;\n\n\twhile (i < lines.length) {\n\t\tconst entryLine = lines[i] ?? \"\";\n\t\tconst kind = classifyLine(entryLine);\n\n\t\tif (kind === \"section\") {\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch (kind) {\n\t\t\tcase \"blank\": {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"comment\": {\n\t\t\t\tcurrentEntry = handleCommentLine(entryLine, currentEntry);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"key\": {\n\t\t\t\tcurrentEntry = processKeyLine(entryLine, currentEntry, entries);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"continuation\": {\n\t\t\t\tcurrentEntry?.lines.push(entryLine);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\tif (currentEntry) {\n\t\tentries.push(currentEntry);\n\t}\n\treturn { entries, endIndex: i };\n}\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\tconst sectionMatch = line.match(SECTION_HEADER_REGEX);\n\n\t\tif (sectionMatch && sectionsToSort.includes(sectionMatch[1] ?? \"\")) {\n\t\t\tresult.push(line);\n\t\t\ti++;\n\t\t\tconst { entries, endIndex } = collectSectionEntries(lines, i);\n\t\t\tentries.sort((a, b) => a.key.localeCompare(b.key));\n\t\t\tfor (const entry of entries) {\n\t\t\t\tresult.push(...entry.lines);\n\t\t\t}\n\t\t\ti = endIndex;\n\t\t\tcontinue;\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 gleam.toml are sorted alphabetically.\n *\n * @alpha\n */\nexport const GleamTomlSorted: PolicyShape<GleamTomlSortedConfig> =\n\tdefineGleamPolicy({\n\t\tname: \"GleamTomlSorted\",\n\t\tdescription:\n\t\t\t\"Ensures dependency sections in gleam.toml are sorted alphabetically.\",\n\t\thandler: async (\n\t\t\ttoml: GleamToml,\n\t\t\t{ file, root, resolve: shouldResolve, config },\n\t\t) => {\n\t\t\tconst sections = config?.sections ?? DEFAULT_SORTED_SECTIONS;\n\t\t\tconst unsortedSections: string[] = [];\n\n\t\t\tfor (const section of sections) {\n\t\t\t\tconst sectionData = toml[section] as\n\t\t\t\t\t| Record<string, unknown>\n\t\t\t\t\t| undefined;\n\t\t\t\tif (sectionData !== undefined && !isSorted(Object.keys(sectionData))) {\n\t\t\t\t\tunsortedSections.push(section);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unsortedSections.length === 0) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (shouldResolve) {\n\t\t\t\ttry {\n\t\t\t\t\tconst filePath = resolve(root, file);\n\t\t\t\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\t\t\t\tconst sorted = sortTomlSections(content, unsortedSections);\n\t\t\t\t\tawait writeFile(filePath, sorted);\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: `Unsorted sections: [${unsortedSections.join(\"], [\")}]`,\n\t\t\t\t\t\tfixable: true,\n\t\t\t\t\t\tfixed: true,\n\t\t\t\t\t};\n\t\t\t\t} catch {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: `Unsorted sections: [${unsortedSections.join(\"], [\")}]. Auto-fix failed.`,\n\t\t\t\t\t\tfixable: true,\n\t\t\t\t\t\tfixed: false,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\terror: `Unsorted sections: [${unsortedSections.join(\"], [\")}]`,\n\t\t\t\tfixable: true,\n\t\t\t\tmanualFix:\n\t\t\t\t\t\"Sort the dependency keys alphabetically in the listed sections.\",\n\t\t\t};\n\t\t},\n\t});\n"]}
@@ -0,0 +1,20 @@
1
+ import type { PolicyShape } from "../policy.js";
2
+ /**
3
+ * Configuration for the GleamVersionConstraint policy.
4
+ *
5
+ * @alpha
6
+ */
7
+ export interface GleamVersionConstraintConfig {
8
+ /**
9
+ * Minimum Gleam compiler version to require (e.g., "1.0.0").
10
+ * If set, the constraint must specify at least this version.
11
+ */
12
+ minimumVersion?: string;
13
+ }
14
+ /**
15
+ * A policy that ensures the Gleam compiler version constraint is set in gleam.toml.
16
+ *
17
+ * @alpha
18
+ */
19
+ export declare const GleamVersionConstraint: PolicyShape<GleamVersionConstraintConfig>;
20
+ //# sourceMappingURL=GleamVersionConstraint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamVersionConstraint.d.ts","sourceRoot":"","sources":["../../src/policies/GleamVersionConstraint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC5C;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAyCD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,4BAA4B,CA4B1E,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { defineGleamPolicy, } from "../policyDefiners/defineGleamPolicy.js";
2
+ const SEMVER_PREFIX_REGEX = /^[><=~^!\s]+/;
3
+ /**
4
+ * Parse a simple semver string into comparable parts.
5
+ */
6
+ function parseSemver(version) {
7
+ const cleaned = version.replace(SEMVER_PREFIX_REGEX, "").trim();
8
+ const parts = cleaned.split(".");
9
+ if (parts.length < 2) {
10
+ return undefined;
11
+ }
12
+ const major = Number.parseInt(parts[0] ?? "0", 10);
13
+ const minor = Number.parseInt(parts[1] ?? "0", 10);
14
+ const patch = Number.parseInt(parts[2] ?? "0", 10);
15
+ if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch)) {
16
+ return undefined;
17
+ }
18
+ return [major, minor, patch];
19
+ }
20
+ function isVersionAtLeast(constraint, minimum) {
21
+ const constraintParts = parseSemver(constraint);
22
+ const minimumParts = parseSemver(minimum);
23
+ if (!(constraintParts && minimumParts)) {
24
+ return false;
25
+ }
26
+ for (let i = 0; i < 3; i++) {
27
+ const c = constraintParts[i] ?? 0;
28
+ const m = minimumParts[i] ?? 0;
29
+ if (c > m) {
30
+ return true;
31
+ }
32
+ if (c < m) {
33
+ return false;
34
+ }
35
+ }
36
+ return true;
37
+ }
38
+ /**
39
+ * A policy that ensures the Gleam compiler version constraint is set in gleam.toml.
40
+ *
41
+ * @alpha
42
+ */
43
+ export const GleamVersionConstraint = defineGleamPolicy({
44
+ name: "GleamVersionConstraint",
45
+ description: "Ensures gleam.toml has a Gleam compiler version constraint to prevent incompatible builds.",
46
+ handler: async (toml, { config }) => {
47
+ const gleamVersion = toml.gleam;
48
+ if (gleamVersion === undefined || gleamVersion === "") {
49
+ return {
50
+ error: "Missing gleam version constraint in gleam.toml.",
51
+ manualFix: 'Add gleam = ">= 1.0.0" (or appropriate version) to gleam.toml.',
52
+ };
53
+ }
54
+ if (config?.minimumVersion &&
55
+ !isVersionAtLeast(gleamVersion, config.minimumVersion)) {
56
+ return {
57
+ error: `Gleam version constraint "${gleamVersion}" is below minimum "${config.minimumVersion}".`,
58
+ manualFix: `Update to gleam = ">= ${config.minimumVersion}" or higher.`,
59
+ };
60
+ }
61
+ return true;
62
+ },
63
+ });
64
+ //# sourceMappingURL=GleamVersionConstraint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GleamVersionConstraint.js","sourceRoot":"","sources":["../../src/policies/GleamVersionConstraint.ts"],"names":[],"mappings":"AACA,OAAO,EACN,iBAAiB,GAEjB,MAAM,wCAAwC,CAAC;AAehD,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAE3C;;GAEG;AACH,SAAS,WAAW,CAAC,OAAe;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,gBAAgB,CAAC,UAAkB,EAAE,OAAe;IAC5D,MAAM,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,eAAe,IAAI,YAAY,CAAC,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAClC,iBAAiB,CAAC;IACjB,IAAI,EAAE,wBAAwB;IAC9B,WAAW,EACV,4FAA4F;IAC7F,OAAO,EAAE,KAAK,EAAE,IAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,KAA2B,CAAC;QAEtD,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;YACvD,OAAO;gBACN,KAAK,EAAE,iDAAiD;gBACxD,SAAS,EACR,gEAAgE;aACjE,CAAC;QACH,CAAC;QAED,IACC,MAAM,EAAE,cAAc;YACtB,CAAC,gBAAgB,CAAC,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,EACrD,CAAC;YACF,OAAO;gBACN,KAAK,EAAE,6BAA6B,YAAY,uBAAuB,MAAM,CAAC,cAAc,IAAI;gBAChG,SAAS,EAAE,yBAAyB,MAAM,CAAC,cAAc,cAAc;aACvE,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC,CAAC","sourcesContent":["import type { PolicyShape } from \"../policy.js\";\nimport {\n\tdefineGleamPolicy,\n\ttype GleamToml,\n} from \"../policyDefiners/defineGleamPolicy.js\";\n\n/**\n * Configuration for the GleamVersionConstraint policy.\n *\n * @alpha\n */\nexport interface GleamVersionConstraintConfig {\n\t/**\n\t * Minimum Gleam compiler version to require (e.g., \"1.0.0\").\n\t * If set, the constraint must specify at least this version.\n\t */\n\tminimumVersion?: string;\n}\n\nconst SEMVER_PREFIX_REGEX = /^[><=~^!\\s]+/;\n\n/**\n * Parse a simple semver string into comparable parts.\n */\nfunction parseSemver(version: string): [number, number, number] | undefined {\n\tconst cleaned = version.replace(SEMVER_PREFIX_REGEX, \"\").trim();\n\tconst parts = cleaned.split(\".\");\n\tif (parts.length < 2) {\n\t\treturn undefined;\n\t}\n\tconst major = Number.parseInt(parts[0] ?? \"0\", 10);\n\tconst minor = Number.parseInt(parts[1] ?? \"0\", 10);\n\tconst patch = Number.parseInt(parts[2] ?? \"0\", 10);\n\tif (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch)) {\n\t\treturn undefined;\n\t}\n\treturn [major, minor, patch];\n}\n\nfunction isVersionAtLeast(constraint: string, minimum: string): boolean {\n\tconst constraintParts = parseSemver(constraint);\n\tconst minimumParts = parseSemver(minimum);\n\tif (!(constraintParts && minimumParts)) {\n\t\treturn false;\n\t}\n\tfor (let i = 0; i < 3; i++) {\n\t\tconst c = constraintParts[i] ?? 0;\n\t\tconst m = minimumParts[i] ?? 0;\n\t\tif (c > m) {\n\t\t\treturn true;\n\t\t}\n\t\tif (c < m) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * A policy that ensures the Gleam compiler version constraint is set in gleam.toml.\n *\n * @alpha\n */\nexport const GleamVersionConstraint: PolicyShape<GleamVersionConstraintConfig> =\n\tdefineGleamPolicy({\n\t\tname: \"GleamVersionConstraint\",\n\t\tdescription:\n\t\t\t\"Ensures gleam.toml has a Gleam compiler version constraint to prevent incompatible builds.\",\n\t\thandler: async (toml: GleamToml, { config }) => {\n\t\t\tconst gleamVersion = toml.gleam as string | undefined;\n\n\t\t\tif (gleamVersion === undefined || gleamVersion === \"\") {\n\t\t\t\treturn {\n\t\t\t\t\terror: \"Missing gleam version constraint in gleam.toml.\",\n\t\t\t\t\tmanualFix:\n\t\t\t\t\t\t'Add gleam = \">= 1.0.0\" (or appropriate version) to gleam.toml.',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tconfig?.minimumVersion &&\n\t\t\t\t!isVersionAtLeast(gleamVersion, config.minimumVersion)\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\terror: `Gleam version constraint \"${gleamVersion}\" is below minimum \"${config.minimumVersion}\".`,\n\t\t\t\t\tmanualFix: `Update to gleam = \">= ${config.minimumVersion}\" or higher.`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t});\n"]}
@@ -9,7 +9,7 @@ export const HtmlFileHeaders = defineFileHeaderPolicy({
9
9
  name: "HtmlFileHeaders",
10
10
  description: "Ensures HTML files have the configured header comment.",
11
11
  config: {
12
- match: /(^|\/)[^/]+\.[mc]?[jt]sx?$/i,
12
+ match: /(^|\/)[^/]+\.html?$/i,
13
13
  lineStart: /<!-- /, // Lines begin with '<!-- '
14
14
  lineEnd: / -->\r?\n/, // Lines end with ' -->' followed by CRLF or LF
15
15
  replacer: (content, { headerText }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"HtmlFileHeaders.js","sourceRoot":"","sources":["../../src/policies/HtmlFileHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EACN,sBAAsB,GAEtB,MAAM,6CAA6C,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC;IACrD,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,wDAAwD;IACrE,MAAM,EAAE;QACP,KAAK,EAAE,6BAA6B;QACpC,SAAS,EAAE,OAAO,EAAE,2BAA2B;QAC/C,OAAO,EAAE,WAAW,EAAE,+CAA+C;QACrE,QAAQ,EAAE,CACT,OAAe,EACf,EAAE,UAAU,EAA0B,EAC7B,EAAE;YACX,MAAM,UAAU,GAAG,QAAQ,UAAU,CAAC,OAAO,CAC5C,OAAO,EACP,OAAO,OAAO,OAAO,CACrB,OAAO,OAAO,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;YACtC,OAAO,UAAU,CAAC;QACnB,CAAC;KACD;CACD,CAAC,CAAC","sourcesContent":["import { EOL as newline } from \"node:os\";\nimport {\n\tdefineFileHeaderPolicy,\n\ttype FileHeaderPolicyConfig,\n} from \"../policyDefiners/defineFileHeaderPolicy.js\";\n\n/**\n * A RepoPolicy that checks that HTML files have the configured header comment.\n *\n * @alpha\n */\nexport const HtmlFileHeaders = defineFileHeaderPolicy({\n\tname: \"HtmlFileHeaders\",\n\tdescription: \"Ensures HTML files have the configured header comment.\",\n\tconfig: {\n\t\tmatch: /(^|\\/)[^/]+\\.[mc]?[jt]sx?$/i,\n\t\tlineStart: /<!-- /, // Lines begin with '<!-- '\n\t\tlineEnd: / -->\\r?\\n/, // Lines end with ' -->' followed by CRLF or LF\n\t\treplacer: (\n\t\t\tcontent: string,\n\t\t\t{ headerText }: FileHeaderPolicyConfig,\n\t\t): string => {\n\t\t\tconst newContent = `<!-- ${headerText.replace(\n\t\t\t\tnewline,\n\t\t\t\t` -->${newline}<!-- `,\n\t\t\t)} -->${newline}${newline}${content}`;\n\t\t\treturn newContent;\n\t\t},\n\t},\n});\n"]}
1
+ {"version":3,"file":"HtmlFileHeaders.js","sourceRoot":"","sources":["../../src/policies/HtmlFileHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EACN,sBAAsB,GAEtB,MAAM,6CAA6C,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC;IACrD,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,wDAAwD;IACrE,MAAM,EAAE;QACP,KAAK,EAAE,sBAAsB;QAC7B,SAAS,EAAE,OAAO,EAAE,2BAA2B;QAC/C,OAAO,EAAE,WAAW,EAAE,+CAA+C;QACrE,QAAQ,EAAE,CACT,OAAe,EACf,EAAE,UAAU,EAA0B,EAC7B,EAAE;YACX,MAAM,UAAU,GAAG,QAAQ,UAAU,CAAC,OAAO,CAC5C,OAAO,EACP,OAAO,OAAO,OAAO,CACrB,OAAO,OAAO,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;YACtC,OAAO,UAAU,CAAC;QACnB,CAAC;KACD;CACD,CAAC,CAAC","sourcesContent":["import { EOL as newline } from \"node:os\";\nimport {\n\tdefineFileHeaderPolicy,\n\ttype FileHeaderPolicyConfig,\n} from \"../policyDefiners/defineFileHeaderPolicy.js\";\n\n/**\n * A RepoPolicy that checks that HTML files have the configured header comment.\n *\n * @alpha\n */\nexport const HtmlFileHeaders = defineFileHeaderPolicy({\n\tname: \"HtmlFileHeaders\",\n\tdescription: \"Ensures HTML files have the configured header comment.\",\n\tconfig: {\n\t\tmatch: /(^|\\/)[^/]+\\.html?$/i,\n\t\tlineStart: /<!-- /, // Lines begin with '<!-- '\n\t\tlineEnd: / -->\\r?\\n/, // Lines end with ' -->' followed by CRLF or LF\n\t\treplacer: (\n\t\t\tcontent: string,\n\t\t\t{ headerText }: FileHeaderPolicyConfig,\n\t\t): string => {\n\t\t\tconst newContent = `<!-- ${headerText.replace(\n\t\t\t\tnewline,\n\t\t\t\t` -->${newline}<!-- `,\n\t\t\t)} -->${newline}${newline}${content}`;\n\t\t\treturn newContent;\n\t\t},\n\t},\n});\n"]}
@@ -0,0 +1,9 @@
1
+ import type { PolicyDefinition } from "../policy.js";
2
+ /**
3
+ * A policy that prevents accidental commits of build directory contents.
4
+ * Applies to Gleam's `build/` output directory.
5
+ *
6
+ * @alpha
7
+ */
8
+ export declare const NoBuildDirectory: PolicyDefinition;
9
+ //# sourceMappingURL=NoBuildDirectory.d.ts.map