@fourteensystems/prodcheck 0.3.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 (239) hide show
  1. package/README.md +252 -0
  2. package/bin/prodcheck.mjs +2 -0
  3. package/dist/cli/commands/baseline.d.ts +7 -0
  4. package/dist/cli/commands/baseline.d.ts.map +1 -0
  5. package/dist/cli/commands/baseline.js +22 -0
  6. package/dist/cli/commands/baseline.js.map +1 -0
  7. package/dist/cli/commands/ci.d.ts +14 -0
  8. package/dist/cli/commands/ci.d.ts.map +1 -0
  9. package/dist/cli/commands/ci.js +104 -0
  10. package/dist/cli/commands/ci.js.map +1 -0
  11. package/dist/cli/commands/explain.d.ts +2 -0
  12. package/dist/cli/commands/explain.d.ts.map +1 -0
  13. package/dist/cli/commands/explain.js +20 -0
  14. package/dist/cli/commands/explain.js.map +1 -0
  15. package/dist/cli/commands/init.d.ts +7 -0
  16. package/dist/cli/commands/init.d.ts.map +1 -0
  17. package/dist/cli/commands/init.js +127 -0
  18. package/dist/cli/commands/init.js.map +1 -0
  19. package/dist/cli/commands/rules.d.ts +2 -0
  20. package/dist/cli/commands/rules.d.ts.map +1 -0
  21. package/dist/cli/commands/rules.js +13 -0
  22. package/dist/cli/commands/rules.js.map +1 -0
  23. package/dist/cli/commands/scan.d.ts +10 -0
  24. package/dist/cli/commands/scan.d.ts.map +1 -0
  25. package/dist/cli/commands/scan.js +65 -0
  26. package/dist/cli/commands/scan.js.map +1 -0
  27. package/dist/cli/commands/waive.d.ts +8 -0
  28. package/dist/cli/commands/waive.d.ts.map +1 -0
  29. package/dist/cli/commands/waive.js +34 -0
  30. package/dist/cli/commands/waive.js.map +1 -0
  31. package/dist/cli/index.d.ts +2 -0
  32. package/dist/cli/index.d.ts.map +1 -0
  33. package/dist/cli/index.js +64 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/engine/baseline.d.ts +11 -0
  36. package/dist/engine/baseline.d.ts.map +1 -0
  37. package/dist/engine/baseline.js +39 -0
  38. package/dist/engine/baseline.js.map +1 -0
  39. package/dist/engine/baseline.test.d.ts +2 -0
  40. package/dist/engine/baseline.test.d.ts.map +1 -0
  41. package/dist/engine/baseline.test.js +135 -0
  42. package/dist/engine/baseline.test.js.map +1 -0
  43. package/dist/engine/config.d.ts +8 -0
  44. package/dist/engine/config.d.ts.map +1 -0
  45. package/dist/engine/config.js +134 -0
  46. package/dist/engine/config.js.map +1 -0
  47. package/dist/engine/config.test.d.ts +2 -0
  48. package/dist/engine/config.test.d.ts.map +1 -0
  49. package/dist/engine/config.test.js +107 -0
  50. package/dist/engine/config.test.js.map +1 -0
  51. package/dist/engine/extensions/load.d.ts +11 -0
  52. package/dist/engine/extensions/load.d.ts.map +1 -0
  53. package/dist/engine/extensions/load.js +26 -0
  54. package/dist/engine/extensions/load.js.map +1 -0
  55. package/dist/engine/extensions/registry.d.ts +5 -0
  56. package/dist/engine/extensions/registry.d.ts.map +1 -0
  57. package/dist/engine/extensions/registry.js +11 -0
  58. package/dist/engine/extensions/registry.js.map +1 -0
  59. package/dist/engine/extensions/types.d.ts +51 -0
  60. package/dist/engine/extensions/types.d.ts.map +1 -0
  61. package/dist/engine/extensions/types.js +2 -0
  62. package/dist/engine/extensions/types.js.map +1 -0
  63. package/dist/engine/license.d.ts +40 -0
  64. package/dist/engine/license.d.ts.map +1 -0
  65. package/dist/engine/license.js +104 -0
  66. package/dist/engine/license.js.map +1 -0
  67. package/dist/engine/report.d.ts +5 -0
  68. package/dist/engine/report.d.ts.map +1 -0
  69. package/dist/engine/report.js +115 -0
  70. package/dist/engine/report.js.map +1 -0
  71. package/dist/engine/run.d.ts +11 -0
  72. package/dist/engine/run.d.ts.map +1 -0
  73. package/dist/engine/run.js +105 -0
  74. package/dist/engine/run.js.map +1 -0
  75. package/dist/engine/sarif.d.ts +3 -0
  76. package/dist/engine/sarif.d.ts.map +1 -0
  77. package/dist/engine/sarif.js +58 -0
  78. package/dist/engine/sarif.js.map +1 -0
  79. package/dist/engine/sarif.test.d.ts +2 -0
  80. package/dist/engine/sarif.test.d.ts.map +1 -0
  81. package/dist/engine/sarif.test.js +152 -0
  82. package/dist/engine/sarif.test.js.map +1 -0
  83. package/dist/engine/score.d.ts +13 -0
  84. package/dist/engine/score.d.ts.map +1 -0
  85. package/dist/engine/score.js +116 -0
  86. package/dist/engine/score.js.map +1 -0
  87. package/dist/engine/score.test.d.ts +2 -0
  88. package/dist/engine/score.test.d.ts.map +1 -0
  89. package/dist/engine/score.test.js +227 -0
  90. package/dist/engine/score.test.js.map +1 -0
  91. package/dist/engine/types.d.ts +123 -0
  92. package/dist/engine/types.d.ts.map +1 -0
  93. package/dist/engine/types.js +2 -0
  94. package/dist/engine/types.js.map +1 -0
  95. package/dist/engine/version.d.ts +5 -0
  96. package/dist/engine/version.d.ts.map +1 -0
  97. package/dist/engine/version.js +15 -0
  98. package/dist/engine/version.js.map +1 -0
  99. package/dist/engine/waivers.d.ts +9 -0
  100. package/dist/engine/waivers.d.ts.map +1 -0
  101. package/dist/engine/waivers.js +55 -0
  102. package/dist/engine/waivers.js.map +1 -0
  103. package/dist/engine/waivers.test.d.ts +2 -0
  104. package/dist/engine/waivers.test.d.ts.map +1 -0
  105. package/dist/engine/waivers.test.js +147 -0
  106. package/dist/engine/waivers.test.js.map +1 -0
  107. package/dist/index.d.ts +14 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +12 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/next/deps.d.ts +4 -0
  112. package/dist/next/deps.d.ts.map +1 -0
  113. package/dist/next/deps.js +118 -0
  114. package/dist/next/deps.js.map +1 -0
  115. package/dist/next/deps.test.d.ts +2 -0
  116. package/dist/next/deps.test.d.ts.map +1 -0
  117. package/dist/next/deps.test.js +249 -0
  118. package/dist/next/deps.test.js.map +1 -0
  119. package/dist/next/detect.d.ts +10 -0
  120. package/dist/next/detect.d.ts.map +1 -0
  121. package/dist/next/detect.js +57 -0
  122. package/dist/next/detect.js.map +1 -0
  123. package/dist/next/detect.test.d.ts +2 -0
  124. package/dist/next/detect.test.d.ts.map +1 -0
  125. package/dist/next/detect.test.js +74 -0
  126. package/dist/next/detect.test.js.map +1 -0
  127. package/dist/next/index.d.ts +5 -0
  128. package/dist/next/index.d.ts.map +1 -0
  129. package/dist/next/index.js +59 -0
  130. package/dist/next/index.js.map +1 -0
  131. package/dist/next/middleware.d.ts +3 -0
  132. package/dist/next/middleware.d.ts.map +1 -0
  133. package/dist/next/middleware.js +48 -0
  134. package/dist/next/middleware.js.map +1 -0
  135. package/dist/next/middleware.test.d.ts +2 -0
  136. package/dist/next/middleware.test.d.ts.map +1 -0
  137. package/dist/next/middleware.test.js +203 -0
  138. package/dist/next/middleware.test.js.map +1 -0
  139. package/dist/next/routes.d.ts +10 -0
  140. package/dist/next/routes.d.ts.map +1 -0
  141. package/dist/next/routes.js +172 -0
  142. package/dist/next/routes.js.map +1 -0
  143. package/dist/next/routes.test.d.ts +2 -0
  144. package/dist/next/routes.test.d.ts.map +1 -0
  145. package/dist/next/routes.test.js +175 -0
  146. package/dist/next/routes.test.js.map +1 -0
  147. package/dist/next/server-actions.d.ts +4 -0
  148. package/dist/next/server-actions.d.ts.map +1 -0
  149. package/dist/next/server-actions.js +107 -0
  150. package/dist/next/server-actions.js.map +1 -0
  151. package/dist/next/server-actions.test.d.ts +2 -0
  152. package/dist/next/server-actions.test.d.ts.map +1 -0
  153. package/dist/next/server-actions.test.js +138 -0
  154. package/dist/next/server-actions.test.js.map +1 -0
  155. package/dist/next/trpc.d.ts +3 -0
  156. package/dist/next/trpc.d.ts.map +1 -0
  157. package/dist/next/trpc.js +312 -0
  158. package/dist/next/trpc.js.map +1 -0
  159. package/dist/next/types.d.ts +144 -0
  160. package/dist/next/types.d.ts.map +1 -0
  161. package/dist/next/types.js +2 -0
  162. package/dist/next/types.js.map +1 -0
  163. package/dist/next/wrappers.d.ts +10 -0
  164. package/dist/next/wrappers.d.ts.map +1 -0
  165. package/dist/next/wrappers.js +536 -0
  166. package/dist/next/wrappers.js.map +1 -0
  167. package/dist/next/wrappers.test.d.ts +2 -0
  168. package/dist/next/wrappers.test.d.ts.map +1 -0
  169. package/dist/next/wrappers.test.js +361 -0
  170. package/dist/next/wrappers.test.js.map +1 -0
  171. package/dist/rules/auth-boundary-missing.d.ts +5 -0
  172. package/dist/rules/auth-boundary-missing.d.ts.map +1 -0
  173. package/dist/rules/auth-boundary-missing.js +463 -0
  174. package/dist/rules/auth-boundary-missing.js.map +1 -0
  175. package/dist/rules/auth-boundary-missing.test.d.ts +2 -0
  176. package/dist/rules/auth-boundary-missing.test.d.ts.map +1 -0
  177. package/dist/rules/auth-boundary-missing.test.js +492 -0
  178. package/dist/rules/auth-boundary-missing.test.js.map +1 -0
  179. package/dist/rules/index.d.ts +12 -0
  180. package/dist/rules/index.d.ts.map +1 -0
  181. package/dist/rules/index.js +95 -0
  182. package/dist/rules/index.js.map +1 -0
  183. package/dist/rules/input-validation-missing.d.ts +5 -0
  184. package/dist/rules/input-validation-missing.d.ts.map +1 -0
  185. package/dist/rules/input-validation-missing.js +272 -0
  186. package/dist/rules/input-validation-missing.js.map +1 -0
  187. package/dist/rules/input-validation-missing.test.d.ts +2 -0
  188. package/dist/rules/input-validation-missing.test.d.ts.map +1 -0
  189. package/dist/rules/input-validation-missing.test.js +449 -0
  190. package/dist/rules/input-validation-missing.test.js.map +1 -0
  191. package/dist/rules/rate-limit-missing.d.ts +5 -0
  192. package/dist/rules/rate-limit-missing.d.ts.map +1 -0
  193. package/dist/rules/rate-limit-missing.js +316 -0
  194. package/dist/rules/rate-limit-missing.js.map +1 -0
  195. package/dist/rules/rate-limit-missing.test.d.ts +2 -0
  196. package/dist/rules/rate-limit-missing.test.d.ts.map +1 -0
  197. package/dist/rules/rate-limit-missing.test.js +381 -0
  198. package/dist/rules/rate-limit-missing.test.js.map +1 -0
  199. package/dist/rules/tenancy-scope-missing.d.ts +5 -0
  200. package/dist/rules/tenancy-scope-missing.d.ts.map +1 -0
  201. package/dist/rules/tenancy-scope-missing.js +149 -0
  202. package/dist/rules/tenancy-scope-missing.js.map +1 -0
  203. package/dist/rules/wrapper-unrecognized.d.ts +5 -0
  204. package/dist/rules/wrapper-unrecognized.d.ts.map +1 -0
  205. package/dist/rules/wrapper-unrecognized.js +81 -0
  206. package/dist/rules/wrapper-unrecognized.js.map +1 -0
  207. package/dist/util/hof.d.ts +22 -0
  208. package/dist/util/hof.d.ts.map +1 -0
  209. package/dist/util/hof.js +99 -0
  210. package/dist/util/hof.js.map +1 -0
  211. package/dist/util/hof.test.d.ts +2 -0
  212. package/dist/util/hof.test.d.ts.map +1 -0
  213. package/dist/util/hof.test.js +79 -0
  214. package/dist/util/hof.test.js.map +1 -0
  215. package/dist/util/monorepo.d.ts +6 -0
  216. package/dist/util/monorepo.d.ts.map +1 -0
  217. package/dist/util/monorepo.js +29 -0
  218. package/dist/util/monorepo.js.map +1 -0
  219. package/dist/util/outbound-fetch.d.ts +14 -0
  220. package/dist/util/outbound-fetch.d.ts.map +1 -0
  221. package/dist/util/outbound-fetch.js +59 -0
  222. package/dist/util/outbound-fetch.js.map +1 -0
  223. package/dist/util/outbound-fetch.test.d.ts +2 -0
  224. package/dist/util/outbound-fetch.test.d.ts.map +1 -0
  225. package/dist/util/outbound-fetch.test.js +83 -0
  226. package/dist/util/outbound-fetch.test.js.map +1 -0
  227. package/dist/util/paths.d.ts +6 -0
  228. package/dist/util/paths.d.ts.map +1 -0
  229. package/dist/util/paths.js +18 -0
  230. package/dist/util/paths.js.map +1 -0
  231. package/dist/util/resolve.d.ts +30 -0
  232. package/dist/util/resolve.d.ts.map +1 -0
  233. package/dist/util/resolve.js +306 -0
  234. package/dist/util/resolve.js.map +1 -0
  235. package/dist/util/resolve.test.d.ts +2 -0
  236. package/dist/util/resolve.test.d.ts.map +1 -0
  237. package/dist/util/resolve.test.js +186 -0
  238. package/dist/util/resolve.test.js.map +1 -0
  239. package/package.json +56 -0
@@ -0,0 +1,107 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdtempSync, rmSync, writeFileSync, existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import os from "node:os";
5
+ import { findConfigFile, loadConfigIfExists, writeDefaultConfig, DEFAULT_CONFIG } from "./config.js";
6
+ describe("findConfigFile", () => {
7
+ let tmpDir;
8
+ beforeEach(() => {
9
+ tmpDir = mkdtempSync(path.join(os.tmpdir(), "prodcheck-config-"));
10
+ });
11
+ afterEach(() => {
12
+ rmSync(tmpDir, { recursive: true, force: true });
13
+ });
14
+ it("returns undefined when no config exists", () => {
15
+ expect(findConfigFile(tmpDir)).toBeUndefined();
16
+ });
17
+ it("finds prodcheck.config.json", () => {
18
+ writeFileSync(path.join(tmpDir, "prodcheck.config.json"), "{}");
19
+ expect(findConfigFile(tmpDir)).toBe(path.join(tmpDir, "prodcheck.config.json"));
20
+ });
21
+ it("finds prodcheck.config.ts", () => {
22
+ writeFileSync(path.join(tmpDir, "prodcheck.config.ts"), "export default {}");
23
+ expect(findConfigFile(tmpDir)).toBe(path.join(tmpDir, "prodcheck.config.ts"));
24
+ });
25
+ it("prefers ts over json", () => {
26
+ writeFileSync(path.join(tmpDir, "prodcheck.config.ts"), "export default {}");
27
+ writeFileSync(path.join(tmpDir, "prodcheck.config.json"), "{}");
28
+ expect(findConfigFile(tmpDir)).toBe(path.join(tmpDir, "prodcheck.config.ts"));
29
+ });
30
+ });
31
+ describe("loadConfigIfExists", () => {
32
+ let tmpDir;
33
+ beforeEach(() => {
34
+ tmpDir = mkdtempSync(path.join(os.tmpdir(), "prodcheck-config-"));
35
+ });
36
+ afterEach(() => {
37
+ rmSync(tmpDir, { recursive: true, force: true });
38
+ });
39
+ it("returns undefined when no config exists", () => {
40
+ expect(loadConfigIfExists(tmpDir)).toBeUndefined();
41
+ });
42
+ it("loads JSON config", () => {
43
+ const config = { framework: "next-app-router", include: ["app/**"] };
44
+ writeFileSync(path.join(tmpDir, "prodcheck.config.json"), JSON.stringify(config));
45
+ const loaded = loadConfigIfExists(tmpDir);
46
+ expect(loaded).toBeDefined();
47
+ expect(loaded.framework).toBe("next-app-router");
48
+ });
49
+ it("throws on malformed JSON", () => {
50
+ writeFileSync(path.join(tmpDir, "prodcheck.config.json"), "not json");
51
+ expect(() => loadConfigIfExists(tmpDir)).toThrow("Failed to parse");
52
+ });
53
+ it("returns undefined for TS config (not yet supported)", () => {
54
+ writeFileSync(path.join(tmpDir, "prodcheck.config.ts"), "export default {}");
55
+ expect(loadConfigIfExists(tmpDir)).toBeUndefined();
56
+ });
57
+ });
58
+ describe("writeDefaultConfig", () => {
59
+ let tmpDir;
60
+ beforeEach(() => {
61
+ tmpDir = mkdtempSync(path.join(os.tmpdir(), "prodcheck-config-"));
62
+ });
63
+ afterEach(() => {
64
+ rmSync(tmpDir, { recursive: true, force: true });
65
+ });
66
+ it("writes config file", () => {
67
+ writeDefaultConfig(tmpDir, {});
68
+ expect(existsSync(path.join(tmpDir, "prodcheck.config.json"))).toBe(true);
69
+ });
70
+ it("does not overwrite existing without force", () => {
71
+ writeFileSync(path.join(tmpDir, "prodcheck.config.json"), '{"custom": true}');
72
+ writeDefaultConfig(tmpDir, {});
73
+ const content = JSON.parse(require("node:fs").readFileSync(path.join(tmpDir, "prodcheck.config.json"), "utf8"));
74
+ expect(content.custom).toBe(true);
75
+ });
76
+ it("overwrites existing with force", () => {
77
+ writeFileSync(path.join(tmpDir, "prodcheck.config.json"), '{"custom": true}');
78
+ writeDefaultConfig(tmpDir, { force: true });
79
+ const content = JSON.parse(require("node:fs").readFileSync(path.join(tmpDir, "prodcheck.config.json"), "utf8"));
80
+ expect(content.custom).toBeUndefined();
81
+ expect(content.framework).toBe("next-app-router");
82
+ });
83
+ });
84
+ describe("DEFAULT_CONFIG", () => {
85
+ it("has expected structure", () => {
86
+ expect(DEFAULT_CONFIG.framework).toBe("next-app-router");
87
+ expect(DEFAULT_CONFIG.scoring.start).toBe(100);
88
+ expect(DEFAULT_CONFIG.scoring.penalties.critical).toBe(15);
89
+ expect(DEFAULT_CONFIG.rules["AUTH-BOUNDARY-MISSING"]).toBeDefined();
90
+ expect(DEFAULT_CONFIG.rules["RATE-LIMIT-MISSING"]).toBeDefined();
91
+ expect(DEFAULT_CONFIG.rules["TENANCY-SCOPE-MISSING"]).toBeDefined();
92
+ });
93
+ it("has auth hint functions", () => {
94
+ expect(DEFAULT_CONFIG.hints.auth.functions.length).toBeGreaterThan(0);
95
+ expect(DEFAULT_CONFIG.hints.auth.functions).toContain("auth");
96
+ expect(DEFAULT_CONFIG.hints.auth.functions).toContain("getServerSession");
97
+ });
98
+ it("has rate limit wrappers", () => {
99
+ expect(DEFAULT_CONFIG.hints.rateLimit.wrappers.length).toBeGreaterThan(0);
100
+ expect(DEFAULT_CONFIG.hints.rateLimit.wrappers).toContain("rateLimit");
101
+ });
102
+ it("has tenancy field names", () => {
103
+ expect(DEFAULT_CONFIG.hints.tenancy.orgFieldNames).toContain("orgId");
104
+ expect(DEFAULT_CONFIG.hints.tenancy.orgFieldNames).toContain("tenantId");
105
+ });
106
+ });
107
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/engine/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ShipguardConfig } from "../types.js";
2
+ /**
3
+ * Attempts to load the governance module if a license key is present.
4
+ * Soft-fails: OSS core runs fine without governance installed.
5
+ *
6
+ * NOTE: Not wired into run.ts yet. Will be integrated when governance
7
+ * module is built. The extension types and registry are reserved now
8
+ * so the boundary is defined.
9
+ */
10
+ export declare function loadGovernanceIfPresent(config: ShipguardConfig): Promise<void>;
11
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/engine/extensions/load.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAcpF"}
@@ -0,0 +1,26 @@
1
+ import { registerExtension } from "./registry.js";
2
+ /**
3
+ * Attempts to load the governance module if a license key is present.
4
+ * Soft-fails: OSS core runs fine without governance installed.
5
+ *
6
+ * NOTE: Not wired into run.ts yet. Will be integrated when governance
7
+ * module is built. The extension types and registry are reserved now
8
+ * so the boundary is defined.
9
+ */
10
+ export async function loadGovernanceIfPresent(config) {
11
+ if (!config.license?.key)
12
+ return;
13
+ try {
14
+ // @ts-expect-error — governance module is optional; not installed in OSS
15
+ const mod = await import("@shipguard/governance");
16
+ if (typeof mod.registerGovernance === "function") {
17
+ mod.registerGovernance({
18
+ registerExtension,
19
+ });
20
+ }
21
+ }
22
+ catch {
23
+ // Governance not installed — this is fine for OSS usage.
24
+ }
25
+ }
26
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/engine/extensions/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAAuB;IACnE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG;QAAE,OAAO;IAEjC,IAAI,CAAC;QACH,yEAAyE;QACzE,MAAM,GAAG,GAA4B,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAC3E,IAAI,OAAO,GAAG,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YAChD,GAAG,CAAC,kBAAqF,CAAC;gBACzF,iBAAiB;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ShipguardExtension } from "./types.js";
2
+ export declare function registerExtension(ext: ShipguardExtension): void;
3
+ export declare function getExtensions(): readonly ShipguardExtension[];
4
+ export declare function clearExtensions(): void;
5
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/engine/extensions/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAE/D;AAED,wBAAgB,aAAa,IAAI,SAAS,kBAAkB,EAAE,CAE7D;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,11 @@
1
+ const extensions = [];
2
+ export function registerExtension(ext) {
3
+ extensions.push(ext);
4
+ }
5
+ export function getExtensions() {
6
+ return extensions;
7
+ }
8
+ export function clearExtensions() {
9
+ extensions.length = 0;
10
+ }
11
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/engine/extensions/registry.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAyB,EAAE,CAAC;AAE5C,MAAM,UAAU,iBAAiB,CAAC,GAAuB;IACvD,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { Finding, ScanResult, ShipguardConfig } from "../types.js";
2
+ export type ExtensionId = string;
3
+ export type GateResult = {
4
+ ok: true;
5
+ } | {
6
+ ok: false;
7
+ exitCode: number;
8
+ message: string;
9
+ details?: unknown;
10
+ };
11
+ export interface RunContext {
12
+ rootDir: string;
13
+ mode: "scan" | "ci" | "init";
14
+ }
15
+ export interface ExtensionHooks {
16
+ /** Called after config is loaded. Can validate config or gate. */
17
+ onConfigLoaded?: (args: {
18
+ config: ShipguardConfig;
19
+ ctx: RunContext;
20
+ }) => GateResult | void;
21
+ /** Called after analysis, before scoring. Can mutate findings or gate. */
22
+ onFindings?: (args: {
23
+ config: ShipguardConfig;
24
+ ctx: RunContext;
25
+ findings: Finding[];
26
+ }) => GateResult | void;
27
+ /** Called after scoring. Useful for policy gates. */
28
+ onScored?: (args: {
29
+ config: ShipguardConfig;
30
+ ctx: RunContext;
31
+ score: number;
32
+ findings: Finding[];
33
+ }) => GateResult | void;
34
+ /** Called before writing outputs. Can attach extra report sections. */
35
+ onReport?: (args: {
36
+ config: ShipguardConfig;
37
+ ctx: RunContext;
38
+ result: ScanResult;
39
+ }) => GateResult | void;
40
+ /** Called during `shipguard init`. Can add setup messages. */
41
+ onInit?: (args: {
42
+ config: ShipguardConfig;
43
+ ctx: RunContext;
44
+ messages: string[];
45
+ }) => void;
46
+ }
47
+ export interface ShipguardExtension {
48
+ id: ExtensionId;
49
+ hooks: ExtensionHooks;
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/engine/extensions/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAExE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC,MAAM,MAAM,UAAU,GAClB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAExE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QACtB,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,EAAE,UAAU,CAAC;KACjB,KAAK,UAAU,GAAG,IAAI,CAAC;IAExB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,EAAE,UAAU,CAAC;QAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;KACrB,KAAK,UAAU,GAAG,IAAI,CAAC;IAExB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,EAAE,UAAU,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,OAAO,EAAE,CAAC;KACrB,KAAK,UAAU,GAAG,IAAI,CAAC;IAExB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,EAAE,UAAU,CAAC;QAChB,MAAM,EAAE,UAAU,CAAC;KACpB,KAAK,UAAU,GAAG,IAAI,CAAC;IAExB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QACd,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,EAAE,UAAU,CAAC;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,KAAK,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,cAAc,CAAC;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/engine/extensions/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ export interface LicensePayload {
2
+ /** Customer identifier (email or user ID) */
3
+ sub: string;
4
+ /** Optional org/team scope */
5
+ org?: string;
6
+ /** License tier */
7
+ tier: "pro";
8
+ /** Issuer */
9
+ iss: "fourteensystems.com";
10
+ /** Issued at (unix seconds) */
11
+ iat: number;
12
+ /** Expiry (unix seconds) */
13
+ exp: number;
14
+ }
15
+ export interface LicenseResult {
16
+ valid: true;
17
+ payload: LicensePayload;
18
+ }
19
+ export interface LicenseError {
20
+ valid: false;
21
+ reason: string;
22
+ }
23
+ export type LicenseCheck = LicenseResult | LicenseError;
24
+ /**
25
+ * Resolve a license key from (in priority order):
26
+ * 1. PRODCHECK_PRO_KEY env var
27
+ * 2. config.license.key
28
+ */
29
+ export declare function resolveLicenseKey(configKey?: string): string | undefined;
30
+ /**
31
+ * Validate and decode a Prodcheck Pro license key.
32
+ * Fully offline — uses Ed25519 signature verification.
33
+ */
34
+ export declare function validateLicense(key: string): LicenseCheck;
35
+ /**
36
+ * Require a valid Pro license or exit with a helpful message.
37
+ * Used at the top of Pro-gated commands.
38
+ */
39
+ export declare function requireProLicense(configKey?: string): LicensePayload;
40
+ //# sourceMappingURL=license.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../../src/engine/license.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,IAAI,EAAE,KAAK,CAAC;IACZ,aAAa;IACb,GAAG,EAAE,qBAAqB,CAAC;IAC3B,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;AAIxD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAgDzD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAepE"}
@@ -0,0 +1,104 @@
1
+ import { verify, createPublicKey } from "node:crypto";
2
+ /**
3
+ * Prodcheck Pro license verification.
4
+ *
5
+ * Key format: pc_pro_<base64url(payload)>.<base64url(signature)>
6
+ * Payload: JSON { sub, org?, tier, iss, iat, exp }
7
+ * Signature: Ed25519 over the raw payload bytes
8
+ *
9
+ * Verification is fully offline — no network calls.
10
+ */
11
+ // Ed25519 public key for verifying license signatures.
12
+ // The corresponding private key is held offline for key generation.
13
+ const PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
14
+ MCowBQYDK2VwAyEAfISU4mB83G7joDkEkwQ8MrgflJAhdLbg8yzxZhcDwbU=
15
+ -----END PUBLIC KEY-----`;
16
+ const PREFIX = "pc_pro_";
17
+ /**
18
+ * Resolve a license key from (in priority order):
19
+ * 1. PRODCHECK_PRO_KEY env var
20
+ * 2. config.license.key
21
+ */
22
+ export function resolveLicenseKey(configKey) {
23
+ return process.env.PRODCHECK_PRO_KEY || configKey || undefined;
24
+ }
25
+ /**
26
+ * Validate and decode a Prodcheck Pro license key.
27
+ * Fully offline — uses Ed25519 signature verification.
28
+ */
29
+ export function validateLicense(key) {
30
+ if (!key.startsWith(PREFIX)) {
31
+ return { valid: false, reason: "Invalid key format" };
32
+ }
33
+ const rest = key.slice(PREFIX.length);
34
+ const dotIndex = rest.indexOf(".");
35
+ if (dotIndex === -1) {
36
+ return { valid: false, reason: "Invalid key format" };
37
+ }
38
+ const payloadB64 = rest.slice(0, dotIndex);
39
+ const signatureB64 = rest.slice(dotIndex + 1);
40
+ // Decode payload
41
+ let payloadBytes;
42
+ let payload;
43
+ try {
44
+ payloadBytes = Buffer.from(payloadB64, "base64url");
45
+ payload = JSON.parse(payloadBytes.toString("utf8"));
46
+ }
47
+ catch {
48
+ return { valid: false, reason: "Invalid key format" };
49
+ }
50
+ // Verify Ed25519 signature
51
+ try {
52
+ const sigBytes = Buffer.from(signatureB64, "base64url");
53
+ const pubKey = createPublicKey(PUBLIC_KEY_PEM);
54
+ const valid = verify(null, payloadBytes, pubKey, sigBytes);
55
+ if (!valid) {
56
+ return { valid: false, reason: "Invalid license signature" };
57
+ }
58
+ }
59
+ catch {
60
+ return { valid: false, reason: "Signature verification failed" };
61
+ }
62
+ // Check required fields
63
+ if (payload.tier !== "pro" || payload.iss !== "fourteensystems.com") {
64
+ return { valid: false, reason: "Invalid license payload" };
65
+ }
66
+ // Check expiry
67
+ const nowSec = Math.floor(Date.now() / 1000);
68
+ if (payload.exp && nowSec > payload.exp) {
69
+ return { valid: false, reason: "License expired" };
70
+ }
71
+ return { valid: true, payload };
72
+ }
73
+ /**
74
+ * Require a valid Pro license or exit with a helpful message.
75
+ * Used at the top of Pro-gated commands.
76
+ */
77
+ export function requireProLicense(configKey) {
78
+ const key = resolveLicenseKey(configKey);
79
+ if (!key) {
80
+ printUpgradeMessage("No Prodcheck Pro license key found.");
81
+ process.exit(1);
82
+ }
83
+ const result = validateLicense(key);
84
+ if (!result.valid) {
85
+ printUpgradeMessage(result.reason);
86
+ process.exit(1);
87
+ }
88
+ return result.payload;
89
+ }
90
+ function printUpgradeMessage(reason) {
91
+ console.error("");
92
+ console.error(` ${reason}`);
93
+ console.error("");
94
+ console.error(" This command requires Prodcheck Pro.");
95
+ console.error("");
96
+ console.error(" Set your key via:");
97
+ console.error(" export PRODCHECK_PRO_KEY=pc_pro_...");
98
+ console.error(" or in prodcheck.config.json:");
99
+ console.error(' { "license": { "key": "pc_pro_..." } }');
100
+ console.error("");
101
+ console.error(" Get Pro → https://fourteensystems.com/prodcheck#pricing");
102
+ console.error("");
103
+ }
104
+ //# sourceMappingURL=license.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.js","sourceRoot":"","sources":["../../src/engine/license.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ScanResult } from "./types.js";
2
+ import type { BaselineDiff } from "./baseline.js";
3
+ export declare function formatPretty(result: ScanResult, diff?: BaselineDiff): string;
4
+ export declare function formatJson(result: ScanResult): string;
5
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/engine/report.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM,CAsG5E;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAErD"}
@@ -0,0 +1,115 @@
1
+ import pc from "picocolors";
2
+ import { scoreStatus, buildDetectedList } from "./score.js";
3
+ export function formatPretty(result, diff) {
4
+ const lines = [];
5
+ const { score, findings, waivedFindings, summary } = result;
6
+ // Header with detected stack
7
+ const detected = buildDetectedList(result);
8
+ const status = scoreStatus(score);
9
+ const scoreColor = status === "PASS" ? pc.green : status === "WARN" ? pc.yellow : pc.red;
10
+ lines.push("");
11
+ lines.push(` ${pc.bold("Prodcheck")} ${pc.dim(result.prodcheckVersion)}`);
12
+ lines.push(` ${pc.dim("Detected:")} ${detected.join(" · ")}`);
13
+ // Score line with inline severity counts
14
+ if (findings.length === 0) {
15
+ lines.push(` ${pc.dim("Score:")} ${scoreColor(String(score))} ${scoreColor(status)}`);
16
+ }
17
+ else {
18
+ const parts = [];
19
+ if (summary.critical > 0)
20
+ parts.push(pc.red(`${summary.critical} critical`));
21
+ if (summary.high > 0)
22
+ parts.push(pc.yellow(`${summary.high} high`));
23
+ if (summary.med > 0)
24
+ parts.push(`${summary.med} med`);
25
+ if (summary.low > 0)
26
+ parts.push(pc.dim(`${summary.low} low`));
27
+ lines.push(` ${pc.dim("Score:")} ${scoreColor(String(score))} ${scoreColor(status)} ${pc.dim("·")} ${parts.join(pc.dim(" · "))}`);
28
+ }
29
+ // Banner: no auth provider detected
30
+ const d = result.detected.deps;
31
+ const hasAnyAuth = d.hasNextAuth || d.hasClerk || d.hasSupabase || d.hasKinde ||
32
+ d.hasWorkOS || d.hasBetterAuth || d.hasLucia || d.hasAuth0 || d.hasIronSession ||
33
+ d.hasFirebaseAuth;
34
+ if (!hasAnyAuth && !result.detected.middleware) {
35
+ lines.push("");
36
+ lines.push(` ${pc.yellow("⚠")} ${pc.yellow("No auth provider detected.")} Public mutation endpoints will be treated as high risk.`);
37
+ }
38
+ if (diff) {
39
+ const deltaStr = diff.scoreDelta >= 0 ? `+${diff.scoreDelta}` : `${diff.scoreDelta}`;
40
+ lines.push(` Delta from baseline: ${diff.scoreDelta >= 0 ? pc.green(deltaStr) : pc.red(deltaStr)}`);
41
+ if (diff.newFindings.length > 0) {
42
+ lines.push(` New findings: ${pc.red(String(diff.newFindings.length))}`);
43
+ }
44
+ if (diff.resolvedKeys.length > 0) {
45
+ lines.push(` Resolved: ${pc.green(String(diff.resolvedKeys.length))}`);
46
+ }
47
+ }
48
+ lines.push("");
49
+ // Group by severity
50
+ const grouped = groupBySeverity(findings);
51
+ for (const [severity, items] of Object.entries(grouped)) {
52
+ if (items.length === 0)
53
+ continue;
54
+ const color = severity === "critical" ? pc.red : severity === "high" ? pc.yellow : pc.dim;
55
+ lines.push(` ${color(severity.toUpperCase())} (${items.length})`);
56
+ for (const f of items) {
57
+ const loc = f.line ? `:${f.line}` : "";
58
+ const conf = pc.dim(`(${f.confidence} confidence)`);
59
+ lines.push(` ${f.ruleId} ${conf}`);
60
+ lines.push(` ${pc.dim(f.file + loc)}`);
61
+ if (f.evidence.length > 0) {
62
+ for (const e of f.evidence) {
63
+ lines.push(` - ${e}`);
64
+ }
65
+ }
66
+ lines.push(` ${pc.dim(`Why ${f.confidence}: ${f.confidenceRationale}`)}`);
67
+ if (f.remediation.length > 0) {
68
+ lines.push(` ${pc.cyan("Fix:")} ${f.remediation[0]}`);
69
+ }
70
+ }
71
+ lines.push("");
72
+ }
73
+ // Remediation
74
+ const remediations = new Map();
75
+ for (const f of findings) {
76
+ if (!remediations.has(f.ruleId)) {
77
+ remediations.set(f.ruleId, f.remediation);
78
+ }
79
+ }
80
+ if (remediations.size > 0) {
81
+ lines.push(" Suggested fixes:");
82
+ for (const [ruleId, fixes] of remediations) {
83
+ for (const fix of fixes) {
84
+ lines.push(` - ${fix}`);
85
+ }
86
+ }
87
+ lines.push("");
88
+ }
89
+ // Waivers
90
+ if (waivedFindings.length > 0) {
91
+ lines.push(` ${pc.dim(`Waived: ${waivedFindings.length} finding(s)`)}`);
92
+ lines.push("");
93
+ }
94
+ // Tip
95
+ lines.push(pc.dim(" Tip: Use `prodcheck waive <RULE> --file <path> --reason \"...\"` to waive known exceptions."));
96
+ lines.push(pc.dim(" Tip: Configure hints in prodcheck.config.json to reduce false positives."));
97
+ lines.push("");
98
+ return lines.join("\n");
99
+ }
100
+ export function formatJson(result) {
101
+ return JSON.stringify(result, null, 2);
102
+ }
103
+ function groupBySeverity(findings) {
104
+ const groups = {
105
+ critical: [],
106
+ high: [],
107
+ med: [],
108
+ low: [],
109
+ };
110
+ for (const f of findings) {
111
+ groups[f.severity]?.push(f);
112
+ }
113
+ return groups;
114
+ }
115
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/engine/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ProdcheckConfig, ScanResult } from "./types.js";
2
+ export interface RunOptions {
3
+ rootDir: string;
4
+ configOverrides?: Partial<ProdcheckConfig>;
5
+ /** Additional exclude globs appended to config excludes (not replacing) */
6
+ additionalExclude?: string[];
7
+ /** Called with a short status string at each scan phase */
8
+ onProgress?: (step: string) => void;
9
+ }
10
+ export declare function runScan(opts: RunOptions): Promise<ScanResult>;
11
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/engine/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAW,MAAM,YAAY,CAAC;AAQvE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAyFnE"}