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,127 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ /**
3
+ * Lazily load spdx-correct. It's an optional peer dependency.
4
+ *
5
+ * @returns The corrected identifier, `null` if unrecognized, or `undefined` if
6
+ * spdx-correct is not installed.
7
+ *
8
+ * @internal
9
+ */
10
+ export async function tryCorrectLicence(licence) {
11
+ try {
12
+ const mod = (await import("spdx-correct"));
13
+ const correct = mod.default ?? mod;
14
+ return correct(licence);
15
+ }
16
+ catch {
17
+ return undefined;
18
+ }
19
+ }
20
+ /**
21
+ * Validate an array of licence identifiers using spdx-correct.
22
+ *
23
+ * @internal
24
+ */
25
+ export async function validateWithSpdxCorrect(licences) {
26
+ const errors = [];
27
+ const corrections = new Map();
28
+ for (const licence of licences) {
29
+ const corrected = await tryCorrectLicence(licence);
30
+ if (corrected === undefined) {
31
+ errors.push(`Cannot validate "${licence}": spdx-correct is not installed. Install it with: pnpm add spdx-correct`);
32
+ break;
33
+ }
34
+ if (corrected === null) {
35
+ errors.push(`Licence "${licence}" is not a recognized SPDX identifier`);
36
+ }
37
+ else if (corrected !== licence) {
38
+ corrections.set(licence, corrected);
39
+ errors.push(`Licence "${licence}" should be "${corrected}"`);
40
+ }
41
+ }
42
+ return { errors, corrections };
43
+ }
44
+ /**
45
+ * Check that all licence identifiers are in the allowed list.
46
+ *
47
+ * @internal
48
+ */
49
+ export function validateAllowlist(licences, allowedLicences) {
50
+ const errors = [];
51
+ for (const licence of licences) {
52
+ if (!allowedLicences.includes(licence)) {
53
+ errors.push(`Licence "${licence}" is not in the allowed list: ${allowedLicences.join(", ")}`);
54
+ }
55
+ }
56
+ return errors;
57
+ }
58
+ /**
59
+ * Replace quoted licence strings in TOML/text content with their corrected forms.
60
+ *
61
+ * @internal
62
+ */
63
+ export function applyCorrections(content, corrections) {
64
+ let result = content;
65
+ for (const [original, corrected] of corrections) {
66
+ result = result.replace(`"${original}"`, `"${corrected}"`);
67
+ }
68
+ return result;
69
+ }
70
+ /**
71
+ * Read a file, apply licence corrections, and write it back.
72
+ *
73
+ * @internal
74
+ */
75
+ export async function tryAutoFix(filePath, corrections, errors) {
76
+ try {
77
+ const content = await readFile(filePath, "utf-8");
78
+ const fixed = applyCorrections(content, corrections);
79
+ await writeFile(filePath, fixed);
80
+ return { error: errors.join("; "), fixable: true, fixed: true };
81
+ }
82
+ catch {
83
+ return {
84
+ error: `${errors.join("; ")}. Auto-fix failed.`,
85
+ fixable: true,
86
+ fixed: false,
87
+ };
88
+ }
89
+ }
90
+ /**
91
+ * Validate licence identifiers and optionally auto-fix them.
92
+ *
93
+ * Combines spdx-correct validation with allowlist checking and auto-fix
94
+ * into a single helper used by both Cargo and Gleam licence policies.
95
+ *
96
+ * @returns `true` if valid, or a PolicyError-compatible object on failure.
97
+ * Returns `undefined` if no validation was requested (both allowlist and
98
+ * validateSpdx are empty/false).
99
+ *
100
+ * @internal
101
+ */
102
+ export async function validateLicenceField(options) {
103
+ const { licences, allowedLicences, validateSpdx, shouldResolve, filePath, manualFixMessage, } = options;
104
+ // Check allowlist first (takes priority)
105
+ if (allowedLicences) {
106
+ const errors = validateAllowlist(licences, allowedLicences);
107
+ if (errors.length > 0) {
108
+ return { error: errors.join("; "), manualFix: manualFixMessage };
109
+ }
110
+ }
111
+ // Validate with spdx-correct
112
+ if (validateSpdx) {
113
+ const { errors, corrections } = await validateWithSpdxCorrect(licences);
114
+ if (errors.length > 0) {
115
+ if (shouldResolve && corrections.size > 0) {
116
+ return tryAutoFix(filePath, corrections, errors);
117
+ }
118
+ return {
119
+ error: errors.join("; "),
120
+ fixable: corrections.size > 0,
121
+ manualFix: manualFixMessage,
122
+ };
123
+ }
124
+ }
125
+ return undefined;
126
+ }
127
+ //# sourceMappingURL=spdxValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spdxValidator.js","sourceRoot":"","sources":["../../src/policyDefiners/spdxValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\n\n/**\n * Lazily load spdx-correct. It's an optional peer dependency.\n *\n * @returns The corrected identifier, `null` if unrecognized, or `undefined` if\n * spdx-correct is not installed.\n *\n * @internal\n */\nexport async function tryCorrectLicence(\n\tlicence: string,\n): Promise<string | null | undefined> {\n\ttry {\n\t\tconst mod = (await import(\"spdx-correct\")) as {\n\t\t\tdefault?: (id: string) => string | null;\n\t\t};\n\t\tconst correct =\n\t\t\tmod.default ?? (mod as unknown as (id: string) => string | null);\n\t\treturn correct(licence);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Result of validating licence identifiers with spdx-correct.\n *\n * @internal\n */\nexport interface LicenceValidationResult {\n\t/** Human-readable error messages. */\n\terrors: string[];\n\t/** Map from original identifier to its corrected form. */\n\tcorrections: Map<string, string>;\n}\n\n/**\n * Validate an array of licence identifiers using spdx-correct.\n *\n * @internal\n */\nexport async function validateWithSpdxCorrect(\n\tlicences: string[],\n): Promise<LicenceValidationResult> {\n\tconst errors: string[] = [];\n\tconst corrections = new Map<string, string>();\n\n\tfor (const licence of licences) {\n\t\tconst corrected = await tryCorrectLicence(licence);\n\t\tif (corrected === undefined) {\n\t\t\terrors.push(\n\t\t\t\t`Cannot validate \"${licence}\": spdx-correct is not installed. Install it with: pnpm add spdx-correct`,\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tif (corrected === null) {\n\t\t\terrors.push(`Licence \"${licence}\" is not a recognized SPDX identifier`);\n\t\t} else if (corrected !== licence) {\n\t\t\tcorrections.set(licence, corrected);\n\t\t\terrors.push(`Licence \"${licence}\" should be \"${corrected}\"`);\n\t\t}\n\t}\n\n\treturn { errors, corrections };\n}\n\n/**\n * Check that all licence identifiers are in the allowed list.\n *\n * @internal\n */\nexport function validateAllowlist(\n\tlicences: string[],\n\tallowedLicences: string[],\n): string[] {\n\tconst errors: string[] = [];\n\tfor (const licence of licences) {\n\t\tif (!allowedLicences.includes(licence)) {\n\t\t\terrors.push(\n\t\t\t\t`Licence \"${licence}\" is not in the allowed list: ${allowedLicences.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn errors;\n}\n\n/**\n * Replace quoted licence strings in TOML/text content with their corrected forms.\n *\n * @internal\n */\nexport function applyCorrections(\n\tcontent: string,\n\tcorrections: Map<string, string>,\n): string {\n\tlet result = content;\n\tfor (const [original, corrected] of corrections) {\n\t\tresult = result.replace(`\"${original}\"`, `\"${corrected}\"`);\n\t}\n\treturn result;\n}\n\n/**\n * Read a file, apply licence corrections, and write it back.\n *\n * @internal\n */\nexport async function tryAutoFix(\n\tfilePath: string,\n\tcorrections: Map<string, string>,\n\terrors: string[],\n): Promise<{ error: string; fixable: boolean; fixed: boolean }> {\n\ttry {\n\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\tconst fixed = applyCorrections(content, corrections);\n\t\tawait writeFile(filePath, fixed);\n\t\treturn { error: errors.join(\"; \"), fixable: true, fixed: true };\n\t} catch {\n\t\treturn {\n\t\t\terror: `${errors.join(\"; \")}. Auto-fix failed.`,\n\t\t\tfixable: true,\n\t\t\tfixed: false,\n\t\t};\n\t}\n}\n\n/**\n * Validate licence identifiers and optionally auto-fix them.\n *\n * Combines spdx-correct validation with allowlist checking and auto-fix\n * into a single helper used by both Cargo and Gleam licence policies.\n *\n * @returns `true` if valid, or a PolicyError-compatible object on failure.\n * Returns `undefined` if no validation was requested (both allowlist and\n * validateSpdx are empty/false).\n *\n * @internal\n */\nexport async function validateLicenceField(options: {\n\tlicences: string[];\n\tallowedLicences?: string[];\n\tvalidateSpdx: boolean;\n\tshouldResolve: boolean;\n\tfilePath: string;\n\tmanualFixMessage: string;\n}): Promise<\n\t| true\n\t| { error: string; fixable?: boolean; fixed?: boolean; manualFix?: string }\n\t| undefined\n> {\n\tconst {\n\t\tlicences,\n\t\tallowedLicences,\n\t\tvalidateSpdx,\n\t\tshouldResolve,\n\t\tfilePath,\n\t\tmanualFixMessage,\n\t} = options;\n\n\t// Check allowlist first (takes priority)\n\tif (allowedLicences) {\n\t\tconst errors = validateAllowlist(licences, allowedLicences);\n\t\tif (errors.length > 0) {\n\t\t\treturn { error: errors.join(\"; \"), manualFix: manualFixMessage };\n\t\t}\n\t}\n\n\t// Validate with spdx-correct\n\tif (validateSpdx) {\n\t\tconst { errors, corrections } = await validateWithSpdxCorrect(licences);\n\t\tif (errors.length > 0) {\n\t\t\tif (shouldResolve && corrections.size > 0) {\n\t\t\t\treturn tryAutoFix(filePath, corrections, errors);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\tfixable: corrections.size > 0,\n\t\t\t\tmanualFix: manualFixMessage,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn undefined;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Lazily load smol-toml. It's an optional peer dependency, so we import
3
+ * dynamically and surface a clear error when it isn't installed.
4
+ *
5
+ * @internal
6
+ */
7
+ export declare function parseToml(content: string): Promise<Record<string, unknown>>;
8
+ //# sourceMappingURL=tomlParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tomlParser.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/tomlParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAsB,SAAS,CAC9B,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAUlC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Lazily load smol-toml. It's an optional peer dependency, so we import
3
+ * dynamically and surface a clear error when it isn't installed.
4
+ *
5
+ * @internal
6
+ */
7
+ export async function parseToml(content) {
8
+ try {
9
+ const { parse } = await import("smol-toml");
10
+ return parse(content);
11
+ }
12
+ catch {
13
+ throw new Error("smol-toml is required for TOML-based policies but is not installed. " +
14
+ "Install it with: pnpm add smol-toml");
15
+ }
16
+ }
17
+ //# sourceMappingURL=tomlParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tomlParser.js","sourceRoot":"","sources":["../../src/policyDefiners/tomlParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC9B,OAAe;IAEf,IAAI,CAAC;QACJ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5C,OAAO,KAAK,CAAC,OAAO,CAA4B,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CACd,sEAAsE;YACrE,qCAAqC,CACtC,CAAC;IACH,CAAC;AACF,CAAC","sourcesContent":["/**\n * Lazily load smol-toml. It's an optional peer dependency, so we import\n * dynamically and surface a clear error when it isn't installed.\n *\n * @internal\n */\nexport async function parseToml(\n\tcontent: string,\n): Promise<Record<string, unknown>> {\n\ttry {\n\t\tconst { parse } = await import(\"smol-toml\");\n\t\treturn parse(content) as Record<string, unknown>;\n\t} catch {\n\t\tthrow new Error(\n\t\t\t\"smol-toml is required for TOML-based policies but is not installed. \" +\n\t\t\t\t\"Install it with: pnpm add smol-toml\",\n\t\t);\n\t}\n}\n"]}
@@ -0,0 +1,60 @@
1
+ import type { Logger } from "@tylerbu/cli-api";
2
+ import { type Operation } from "effection";
3
+ import { type ExcludedPolicyFileMap } from "./context.js";
4
+ import { type PolicyHandlerPerfStats } from "./perf.js";
5
+ import type { PolicyFixResult, PolicyHandlerResult, PolicyInstance, PolicyInstanceId, PolicyName } from "./policy.js";
6
+ /**
7
+ * Result of running a single policy on a single file.
8
+ * @alpha
9
+ */
10
+ export interface PolicyFileResult {
11
+ file: string;
12
+ policy: PolicyName;
13
+ /** Stable identity of the configured policy instance */
14
+ policyId: PolicyInstanceId;
15
+ /** The raw result from the policy handler */
16
+ outcome: PolicyHandlerResult;
17
+ /** Set when a standalone resolver was attempted (legacy resolver path) */
18
+ resolution?: PolicyFixResult;
19
+ }
20
+ /**
21
+ * Aggregated results from a full policy run.
22
+ * @alpha
23
+ */
24
+ export interface PolicyRunResults {
25
+ results: PolicyFileResult[];
26
+ perfStats: PolicyHandlerPerfStats;
27
+ }
28
+ /**
29
+ * Options for configuring a {@link PolicyRunner}.
30
+ * @alpha
31
+ */
32
+ export interface PolicyRunnerOptions {
33
+ policies: PolicyInstance[];
34
+ excludeFromAll: RegExp[];
35
+ excludePoliciesForFiles: ExcludedPolicyFileMap;
36
+ gitRoot: string;
37
+ resolve: boolean;
38
+ logger?: Pick<Logger, "verbose">;
39
+ }
40
+ /**
41
+ * Runs configured policies against files and collects results.
42
+ * @alpha
43
+ */
44
+ export declare class PolicyRunner {
45
+ private readonly policies;
46
+ private readonly excludeFromAll;
47
+ private readonly excludePoliciesForFiles;
48
+ private readonly gitRoot;
49
+ private readonly resolve;
50
+ private readonly logger;
51
+ constructor(options: PolicyRunnerOptions);
52
+ run(filePaths: string[]): Operation<PolicyRunResults>;
53
+ private checkOrExcludeFile;
54
+ private routeToPolicies;
55
+ private runPolicyOnFile;
56
+ private isPolicyExcluded;
57
+ private executePolicyHandler;
58
+ private attemptResolution;
59
+ }
60
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAEN,KAAK,qBAAqB,EAC1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAEN,KAAK,sBAAsB,EAE3B,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAEX,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,UAAU,EAEV,MAAM,aAAa,CAAC;AA0BrB;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,wDAAwD;IACxD,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,6CAA6C;IAC7C,OAAO,EAAE,mBAAmB,CAAC;IAC7B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,SAAS,EAAE,sBAAsB,CAAC;CAClC;AAOD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,uBAAuB,EAAE,qBAAqB,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAW;IAC1C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAwB;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;gBAE1C,OAAO,EAAE,mBAAmB;IAYvC,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,gBAAgB,CAAC;IAgB7D,OAAO,CAAE,kBAAkB;IAc3B,OAAO,CAAE,eAAe;IA2BxB,OAAO,CAAE,eAAe;IAyDxB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAE,oBAAoB;IA2C7B,OAAO,CAAE,iBAAiB;CA4B1B"}
package/esm/runner.js ADDED
@@ -0,0 +1,174 @@
1
+ import { all, call } from "effection";
2
+ import { createExcludedPolicyFileMap, } from "./context.js";
3
+ import { identifyPolicyInstances } from "./makePolicy.js";
4
+ import { newPerfStats, runWithPerf, } from "./perf.js";
5
+ import { isPolicyError, isPolicyFixResult } from "./policy.js";
6
+ function isOperation(value) {
7
+ return (typeof value === "object" &&
8
+ value !== null &&
9
+ "next" in value &&
10
+ typeof value.next === "function");
11
+ }
12
+ function matches(regex, value) {
13
+ if (!(regex.global || regex.sticky)) {
14
+ return regex.test(value);
15
+ }
16
+ const savedLastIndex = regex.lastIndex;
17
+ try {
18
+ regex.lastIndex = 0;
19
+ return regex.test(value);
20
+ }
21
+ finally {
22
+ regex.lastIndex = savedLastIndex;
23
+ }
24
+ }
25
+ /**
26
+ * Runs configured policies against files and collects results.
27
+ * @alpha
28
+ */
29
+ export class PolicyRunner {
30
+ policies;
31
+ excludeFromAll;
32
+ excludePoliciesForFiles;
33
+ gitRoot;
34
+ resolve;
35
+ logger;
36
+ constructor(options) {
37
+ this.policies = identifyPolicyInstances(options.policies);
38
+ this.excludeFromAll = options.excludeFromAll;
39
+ this.excludePoliciesForFiles = createExcludedPolicyFileMap(this.policies);
40
+ for (const [instanceId, exclusions] of options.excludePoliciesForFiles) {
41
+ this.excludePoliciesForFiles.set(instanceId, exclusions);
42
+ }
43
+ this.gitRoot = options.gitRoot;
44
+ this.resolve = options.resolve;
45
+ this.logger = options.logger;
46
+ }
47
+ *run(filePaths) {
48
+ const state = {
49
+ results: [],
50
+ perfStats: newPerfStats(),
51
+ };
52
+ for (const filePath of filePaths) {
53
+ yield* this.checkOrExcludeFile(filePath, state);
54
+ }
55
+ return {
56
+ results: state.results,
57
+ perfStats: state.perfStats,
58
+ };
59
+ }
60
+ *checkOrExcludeFile(relPath, state) {
61
+ state.perfStats.count++;
62
+ try {
63
+ yield* this.routeToPolicies(relPath, state);
64
+ }
65
+ catch (error) {
66
+ throw new Error(`Error routing ${relPath} to handler: ${error}\nStack:\n${error.stack}`);
67
+ }
68
+ }
69
+ *routeToPolicies(relPath, state) {
70
+ if (this.excludeFromAll.some((regex) => matches(regex, relPath))) {
71
+ this.logger?.verbose(`Excluded all handlers: ${relPath}`);
72
+ return;
73
+ }
74
+ const matchingPolicies = this.policies.filter((policy) => matches(policy.match, relPath));
75
+ if (this.resolve) {
76
+ // Fixers can read and rewrite the same file.
77
+ for (const policy of matchingPolicies) {
78
+ yield* this.runPolicyOnFile(relPath, policy, state);
79
+ }
80
+ return;
81
+ }
82
+ yield* all(matchingPolicies.map((policy) => {
83
+ return this.runPolicyOnFile(relPath, policy, state);
84
+ }));
85
+ }
86
+ *runPolicyOnFile(relPath, policy, state) {
87
+ if (this.isPolicyExcluded(relPath, policy)) {
88
+ this.logger?.verbose(`Excluded from '${policy.instanceId}' policy: ${relPath}`);
89
+ return;
90
+ }
91
+ try {
92
+ const result = yield* this.executePolicyHandler(relPath, policy, state);
93
+ // Success — nothing to report
94
+ if (result === true) {
95
+ return;
96
+ }
97
+ const fileResult = {
98
+ file: relPath,
99
+ policy: policy.name,
100
+ policyId: policy.instanceId,
101
+ outcome: result,
102
+ };
103
+ // Check if resolution should be attempted: result is a failure that
104
+ // wasn't already fixed, resolve mode is on, and a standalone resolver exists.
105
+ const alreadyFixed = isPolicyFixResult(result) ||
106
+ (isPolicyError(result) && result.fixed !== undefined);
107
+ if (!alreadyFixed && this.resolve && policy.resolver) {
108
+ const resolution = yield* this.attemptResolution(relPath, policy, policy.resolver, state);
109
+ fileResult.resolution = resolution;
110
+ }
111
+ state.results.push(fileResult);
112
+ }
113
+ catch (error) {
114
+ const message = error instanceof Error ? error.message : String(error);
115
+ state.results.push({
116
+ file: relPath,
117
+ policy: policy.name,
118
+ policyId: policy.instanceId,
119
+ outcome: {
120
+ error: `System Error: Error executing policy '${policy.instanceId}' for file '${relPath}': ${message}`,
121
+ },
122
+ });
123
+ }
124
+ }
125
+ isPolicyExcluded(relPath, policy) {
126
+ return (this.excludePoliciesForFiles
127
+ .get(policy.instanceId)
128
+ ?.some((regex) => matches(regex, relPath)) ?? false);
129
+ }
130
+ *executePolicyHandler(relPath, policy, state) {
131
+ const { resolve, gitRoot } = this;
132
+ const result = yield* runWithPerf(policy.instanceId, "handle", state.perfStats, function* () {
133
+ const args = {
134
+ file: relPath,
135
+ root: gitRoot,
136
+ resolve,
137
+ config: policy.config,
138
+ };
139
+ if (policy._internalHandler) {
140
+ return yield* policy._internalHandler(args);
141
+ }
142
+ const handlerResult = policy.handler(args);
143
+ if (handlerResult instanceof Promise) {
144
+ return yield* call(() => handlerResult);
145
+ }
146
+ if (isOperation(handlerResult)) {
147
+ return yield* handlerResult;
148
+ }
149
+ throw new Error(`Unexpected handler result type: ${typeof handlerResult}`);
150
+ });
151
+ if (result === undefined) {
152
+ throw new Error("Policy result was undefined.");
153
+ }
154
+ return result;
155
+ }
156
+ *attemptResolution(relPath, policy, resolver, state) {
157
+ const { gitRoot } = this;
158
+ return yield* runWithPerf(policy.instanceId, "resolve", state.perfStats, function* () {
159
+ const result = resolver({
160
+ file: relPath,
161
+ root: gitRoot,
162
+ config: policy.config,
163
+ });
164
+ if (result instanceof Promise) {
165
+ return yield* call(() => result);
166
+ }
167
+ if (isOperation(result)) {
168
+ return yield* result;
169
+ }
170
+ throw new Error(`Unexpected resolver result type: ${typeof result}`);
171
+ });
172
+ }
173
+ }
174
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Logger } from \"@tylerbu/cli-api\";\nimport { all, call, type Operation } from \"effection\";\n\nimport {\n\tcreateExcludedPolicyFileMap,\n\ttype ExcludedPolicyFileMap,\n} from \"./context.js\";\nimport { identifyPolicyInstances } from \"./makePolicy.js\";\nimport {\n\tnewPerfStats,\n\ttype PolicyHandlerPerfStats,\n\trunWithPerf,\n} from \"./perf.js\";\nimport type {\n\tIdentifiedPolicy,\n\tPolicyFixResult,\n\tPolicyHandlerResult,\n\tPolicyInstance,\n\tPolicyInstanceId,\n\tPolicyName,\n\tPolicyStandaloneResolver,\n} from \"./policy.js\";\nimport { isPolicyError, isPolicyFixResult } from \"./policy.js\";\n\nfunction isOperation<T>(value: unknown): value is Operation<T> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"next\" in value &&\n\t\ttypeof (value as { next: unknown }).next === \"function\"\n\t);\n}\n\nfunction matches(regex: RegExp, value: string): boolean {\n\tif (!(regex.global || regex.sticky)) {\n\t\treturn regex.test(value);\n\t}\n\n\tconst savedLastIndex = regex.lastIndex;\n\ttry {\n\t\tregex.lastIndex = 0;\n\t\treturn regex.test(value);\n\t} finally {\n\t\tregex.lastIndex = savedLastIndex;\n\t}\n}\n\n/**\n * Result of running a single policy on a single file.\n * @alpha\n */\nexport interface PolicyFileResult {\n\tfile: string;\n\tpolicy: PolicyName;\n\t/** Stable identity of the configured policy instance */\n\tpolicyId: PolicyInstanceId;\n\t/** The raw result from the policy handler */\n\toutcome: PolicyHandlerResult;\n\t/** Set when a standalone resolver was attempted (legacy resolver path) */\n\tresolution?: PolicyFixResult;\n}\n\n/**\n * Aggregated results from a full policy run.\n * @alpha\n */\nexport interface PolicyRunResults {\n\tresults: PolicyFileResult[];\n\tperfStats: PolicyHandlerPerfStats;\n}\n\ninterface PolicyRunState {\n\tresults: PolicyFileResult[];\n\tperfStats: PolicyHandlerPerfStats;\n}\n\n/**\n * Options for configuring a {@link PolicyRunner}.\n * @alpha\n */\nexport interface PolicyRunnerOptions {\n\tpolicies: PolicyInstance[];\n\texcludeFromAll: RegExp[];\n\texcludePoliciesForFiles: ExcludedPolicyFileMap;\n\tgitRoot: string;\n\tresolve: boolean;\n\tlogger?: Pick<Logger, \"verbose\">;\n}\n\n/**\n * Runs configured policies against files and collects results.\n * @alpha\n */\nexport class PolicyRunner {\n\tprivate readonly policies: IdentifiedPolicy[];\n\tprivate readonly excludeFromAll: RegExp[];\n\tprivate readonly excludePoliciesForFiles: ExcludedPolicyFileMap;\n\tprivate readonly gitRoot: string;\n\tprivate readonly resolve: boolean;\n\tprivate readonly logger: Pick<Logger, \"verbose\"> | undefined;\n\n\tpublic constructor(options: PolicyRunnerOptions) {\n\t\tthis.policies = identifyPolicyInstances(options.policies);\n\t\tthis.excludeFromAll = options.excludeFromAll;\n\t\tthis.excludePoliciesForFiles = createExcludedPolicyFileMap(this.policies);\n\t\tfor (const [instanceId, exclusions] of options.excludePoliciesForFiles) {\n\t\t\tthis.excludePoliciesForFiles.set(instanceId, exclusions);\n\t\t}\n\t\tthis.gitRoot = options.gitRoot;\n\t\tthis.resolve = options.resolve;\n\t\tthis.logger = options.logger;\n\t}\n\n\tpublic *run(filePaths: string[]): Operation<PolicyRunResults> {\n\t\tconst state: PolicyRunState = {\n\t\t\tresults: [],\n\t\t\tperfStats: newPerfStats(),\n\t\t};\n\n\t\tfor (const filePath of filePaths) {\n\t\t\tyield* this.checkOrExcludeFile(filePath, state);\n\t\t}\n\n\t\treturn {\n\t\t\tresults: state.results,\n\t\t\tperfStats: state.perfStats,\n\t\t};\n\t}\n\n\tprivate *checkOrExcludeFile(\n\t\trelPath: string,\n\t\tstate: PolicyRunState,\n\t): Operation<void> {\n\t\tstate.perfStats.count++;\n\t\ttry {\n\t\t\tyield* this.routeToPolicies(relPath, state);\n\t\t} catch (error: unknown) {\n\t\t\tthrow new Error(\n\t\t\t\t`Error routing ${relPath} to handler: ${error}\\nStack:\\n${(error as Error).stack}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate *routeToPolicies(\n\t\trelPath: string,\n\t\tstate: PolicyRunState,\n\t): Operation<void> {\n\t\tif (this.excludeFromAll.some((regex) => matches(regex, relPath))) {\n\t\t\tthis.logger?.verbose(`Excluded all handlers: ${relPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst matchingPolicies = this.policies.filter((policy) =>\n\t\t\tmatches(policy.match, relPath),\n\t\t);\n\t\tif (this.resolve) {\n\t\t\t// Fixers can read and rewrite the same file.\n\t\t\tfor (const policy of matchingPolicies) {\n\t\t\t\tyield* this.runPolicyOnFile(relPath, policy, state);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tyield* all(\n\t\t\tmatchingPolicies.map((policy) => {\n\t\t\t\treturn this.runPolicyOnFile(relPath, policy, state);\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate *runPolicyOnFile(\n\t\trelPath: string,\n\t\tpolicy: IdentifiedPolicy,\n\t\tstate: PolicyRunState,\n\t): Operation<void> {\n\t\tif (this.isPolicyExcluded(relPath, policy)) {\n\t\t\tthis.logger?.verbose(\n\t\t\t\t`Excluded from '${policy.instanceId}' policy: ${relPath}`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = yield* this.executePolicyHandler(relPath, policy, state);\n\n\t\t\t// Success — nothing to report\n\t\t\tif (result === true) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst fileResult: PolicyFileResult = {\n\t\t\t\tfile: relPath,\n\t\t\t\tpolicy: policy.name,\n\t\t\t\tpolicyId: policy.instanceId,\n\t\t\t\toutcome: result,\n\t\t\t};\n\n\t\t\t// Check if resolution should be attempted: result is a failure that\n\t\t\t// wasn't already fixed, resolve mode is on, and a standalone resolver exists.\n\t\t\tconst alreadyFixed =\n\t\t\t\tisPolicyFixResult(result) ||\n\t\t\t\t(isPolicyError(result) && result.fixed !== undefined);\n\n\t\t\tif (!alreadyFixed && this.resolve && policy.resolver) {\n\t\t\t\tconst resolution = yield* this.attemptResolution(\n\t\t\t\t\trelPath,\n\t\t\t\t\tpolicy,\n\t\t\t\t\tpolicy.resolver,\n\t\t\t\t\tstate,\n\t\t\t\t);\n\t\t\t\tfileResult.resolution = resolution;\n\t\t\t}\n\n\t\t\tstate.results.push(fileResult);\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tstate.results.push({\n\t\t\t\tfile: relPath,\n\t\t\t\tpolicy: policy.name,\n\t\t\t\tpolicyId: policy.instanceId,\n\t\t\t\toutcome: {\n\t\t\t\t\terror: `System Error: Error executing policy '${policy.instanceId}' for file '${relPath}': ${message}`,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate isPolicyExcluded(relPath: string, policy: IdentifiedPolicy): boolean {\n\t\treturn (\n\t\t\tthis.excludePoliciesForFiles\n\t\t\t\t.get(policy.instanceId)\n\t\t\t\t?.some((regex) => matches(regex, relPath)) ?? false\n\t\t);\n\t}\n\n\tprivate *executePolicyHandler(\n\t\trelPath: string,\n\t\tpolicy: IdentifiedPolicy,\n\t\tstate: PolicyRunState,\n\t): Operation<PolicyHandlerResult> {\n\t\tconst { resolve, gitRoot } = this;\n\n\t\tconst result = yield* runWithPerf(\n\t\t\tpolicy.instanceId,\n\t\t\t\"handle\",\n\t\t\tstate.perfStats,\n\t\t\tfunction* () {\n\t\t\t\tconst args = {\n\t\t\t\t\tfile: relPath,\n\t\t\t\t\troot: gitRoot,\n\t\t\t\t\tresolve,\n\t\t\t\t\tconfig: policy.config,\n\t\t\t\t};\n\n\t\t\t\tif (policy._internalHandler) {\n\t\t\t\t\treturn yield* policy._internalHandler(args);\n\t\t\t\t}\n\n\t\t\t\tconst handlerResult = policy.handler(args);\n\t\t\t\tif (handlerResult instanceof Promise) {\n\t\t\t\t\treturn yield* call(() => handlerResult);\n\t\t\t\t}\n\t\t\t\tif (isOperation<PolicyHandlerResult>(handlerResult)) {\n\t\t\t\t\treturn yield* handlerResult;\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unexpected handler result type: ${typeof handlerResult}`,\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\n\t\tif (result === undefined) {\n\t\t\tthrow new Error(\"Policy result was undefined.\");\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate *attemptResolution(\n\t\trelPath: string,\n\t\tpolicy: IdentifiedPolicy,\n\t\tresolver: PolicyStandaloneResolver,\n\t\tstate: PolicyRunState,\n\t): Operation<PolicyFixResult> {\n\t\tconst { gitRoot } = this;\n\n\t\treturn yield* runWithPerf(\n\t\t\tpolicy.instanceId,\n\t\t\t\"resolve\",\n\t\t\tstate.perfStats,\n\t\t\tfunction* () {\n\t\t\t\tconst result = resolver({\n\t\t\t\t\tfile: relPath,\n\t\t\t\t\troot: gitRoot,\n\t\t\t\t\tconfig: policy.config,\n\t\t\t\t});\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\treturn yield* call(() => result);\n\t\t\t\t}\n\t\t\t\tif (isOperation<PolicyFixResult>(result)) {\n\t\t\t\t\treturn yield* result;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Unexpected resolver result type: ${typeof result}`);\n\t\t\t},\n\t\t);\n\t}\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.56.0"
8
+ "packageVersion": "7.58.11"
9
9
  }
10
10
  ]
11
11
  }
@@ -1,5 +1,102 @@
1
1
  {
2
2
  "commands": {
3
+ "check-native": {
4
+ "aliases": [],
5
+ "args": {},
6
+ "description": "Runs the Rust-based repopo-core engine with the Node.js sidecar. This provides the same policy checking as 'check' but with Rust-based file enumeration, regex matching, and orchestration for better performance.",
7
+ "flags": {
8
+ "fix": {
9
+ "aliases": [
10
+ "resolve"
11
+ ],
12
+ "char": "f",
13
+ "description": "Fix errors if possible.",
14
+ "name": "fix",
15
+ "required": false,
16
+ "allowNo": false,
17
+ "type": "boolean"
18
+ },
19
+ "stdin": {
20
+ "description": "Read list of files from stdin.",
21
+ "name": "stdin",
22
+ "required": false,
23
+ "allowNo": false,
24
+ "type": "boolean"
25
+ },
26
+ "verbose": {
27
+ "char": "v",
28
+ "description": "Show verbose output including per-policy timing.",
29
+ "name": "verbose",
30
+ "required": false,
31
+ "allowNo": false,
32
+ "type": "boolean"
33
+ },
34
+ "quiet": {
35
+ "char": "q",
36
+ "description": "Suppress all output except errors.",
37
+ "name": "quiet",
38
+ "required": false,
39
+ "allowNo": false,
40
+ "type": "boolean"
41
+ },
42
+ "config": {
43
+ "char": "c",
44
+ "description": "Path to the config file.",
45
+ "name": "config",
46
+ "required": false,
47
+ "hasDynamicHelp": false,
48
+ "multiple": false,
49
+ "type": "option"
50
+ },
51
+ "sidecar-path": {
52
+ "description": "Path to the Node.js sidecar script.",
53
+ "env": "REPOPO_SIDECAR_PATH",
54
+ "name": "sidecar-path",
55
+ "required": false,
56
+ "hasDynamicHelp": false,
57
+ "multiple": false,
58
+ "type": "option"
59
+ },
60
+ "binary-path": {
61
+ "description": "Path to the repopo-core Rust binary.",
62
+ "env": "REPOPO_CORE_PATH",
63
+ "name": "binary-path",
64
+ "required": false,
65
+ "hasDynamicHelp": false,
66
+ "multiple": false,
67
+ "type": "option"
68
+ },
69
+ "runtime": {
70
+ "description": "JS runtime for the sidecar process (auto, node, bun).",
71
+ "env": "REPOPO_RUNTIME",
72
+ "name": "runtime",
73
+ "required": false,
74
+ "hasDynamicHelp": false,
75
+ "multiple": false,
76
+ "options": [
77
+ "auto",
78
+ "node",
79
+ "bun"
80
+ ],
81
+ "type": "option"
82
+ }
83
+ },
84
+ "hasDynamicHelp": false,
85
+ "hiddenAliases": [],
86
+ "id": "check-native",
87
+ "pluginAlias": "repopo",
88
+ "pluginName": "repopo",
89
+ "pluginType": "core",
90
+ "strict": true,
91
+ "summary": "Checks and applies policies using the Rust engine.",
92
+ "enableJsonFlag": false,
93
+ "isESM": true,
94
+ "relativePath": [
95
+ "esm",
96
+ "commands",
97
+ "check-native.js"
98
+ ]
99
+ },
3
100
  "check": {
4
101
  "aliases": [],
5
102
  "args": {},
@@ -46,7 +143,7 @@
46
143
  "type": "boolean"
47
144
  },
48
145
  "config": {
49
- "description": "The path to a configuration file.",
146
+ "description": "Path to configuration file.",
50
147
  "helpGroup": "CONFIGURATION",
51
148
  "hidden": true,
52
149
  "name": "config",
@@ -99,7 +196,7 @@
99
196
  "type": "boolean"
100
197
  },
101
198
  "config": {
102
- "description": "The path to a configuration file.",
199
+ "description": "Path to configuration file.",
103
200
  "helpGroup": "CONFIGURATION",
104
201
  "hidden": true,
105
202
  "name": "config",
@@ -125,5 +222,5 @@
125
222
  ]
126
223
  }
127
224
  },
128
- "version": "0.10.0"
225
+ "version": "0.12.0"
129
226
  }