@cejel/cejel 0.1.1

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.
package/dist/index.js ADDED
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ formatExternalSourceLine,
4
+ renderWitanBadgeEndpoint,
5
+ renderWitanBadgeSvg,
6
+ renderWitanHtmlReport,
7
+ runCejelScan
8
+ } from "./chunk-H5T65GGS.js";
9
+
10
+ // src/index.ts
11
+ import { mkdirSync, realpathSync, writeFileSync } from "fs";
12
+ import { join, resolve } from "path";
13
+ import { pathToFileURL } from "url";
14
+
15
+ // src/terminal.ts
16
+ function renderTerminalCertificate(summary) {
17
+ const lines = summary.insufficientSourceReason ? [
18
+ `Cejel Trust Certificate \u2014 ${summary.productDisplayName}`,
19
+ "",
20
+ "Insufficient source to certify.",
21
+ ` ${summary.insufficientSourceReason}`,
22
+ ""
23
+ ] : [
24
+ `Cejel Trust Certificate \u2014 ${summary.productDisplayName}`,
25
+ "",
26
+ `Overall: ${formatScore(summary.overallScore)}/4.0 (${summary.verdict})`,
27
+ ` Code trust: ${formatScore(summary.codeTrustScore)}/4.0`,
28
+ ` Process trust: ${formatScore(summary.processTrustScore)}/4.0`,
29
+ ""
30
+ ];
31
+ if (summary.contributingSources.length > 0) {
32
+ lines.push(`Incorporates findings from: ${summary.contributingSources.join(", ")}`);
33
+ for (const source of summary.externalSources) {
34
+ lines.push(` ${formatExternalSourceLine(source)}`);
35
+ }
36
+ lines.push("");
37
+ }
38
+ if (summary.insufficientSourceReason) {
39
+ lines.push("See report.json / certificate.html for the full per-criterion detail.");
40
+ } else if (summary.topFindings.length === 0) {
41
+ lines.push("No evidence-backed findings.");
42
+ } else {
43
+ lines.push(`Top findings (${summary.findingCount} total):`);
44
+ for (const finding of summary.topFindings) {
45
+ lines.push(` [${finding.severity}] ${finding.criterionId}: ${finding.summary}`);
46
+ }
47
+ const remaining = summary.findingCount - summary.topFindings.length;
48
+ if (remaining > 0) {
49
+ lines.push(` ...and ${remaining} more \u2014 see the written report for the full list.`);
50
+ }
51
+ }
52
+ if (!summary.insufficientSourceReason && summary.externalFindingCount > 0) {
53
+ lines.push(
54
+ "",
55
+ `External findings (${summary.externalFindingCount} total, attributed to tool + criterion):`
56
+ );
57
+ for (const finding of summary.topExternalFindings) {
58
+ lines.push(
59
+ ` [${finding.severity}] ${finding.label} \u2192 ${finding.dimension}: ${finding.ruleId} \u2014 ${finding.message}${finding.location ? ` (${finding.location})` : ""}`
60
+ );
61
+ }
62
+ const remaining = summary.externalFindingCount - summary.topExternalFindings.length;
63
+ if (remaining > 0) {
64
+ lines.push(` ...and ${remaining} more \u2014 see report.json for the full list.`);
65
+ }
66
+ }
67
+ return `${lines.join("\n")}
68
+ `;
69
+ }
70
+ function formatScore(score) {
71
+ return score.toFixed(1);
72
+ }
73
+
74
+ // src/index.ts
75
+ var DEFAULT_OUT_DIR = ".cejel";
76
+ async function main() {
77
+ const exitCode = await runWitanFreeCli(process.argv.slice(2));
78
+ process.exitCode = exitCode;
79
+ }
80
+ async function runWitanFreeCli(args) {
81
+ const options = parseArgs(args);
82
+ const { report, summary } = runCejelScan({
83
+ repoPath: options.repoPath,
84
+ ingestPatterns: options.ingestPatterns,
85
+ warnOnEmptyIngestMatch: !options.quiet
86
+ });
87
+ mkdirSync(options.outDir, { recursive: true });
88
+ writeFileSync(join(options.outDir, "report.json"), JSON.stringify(report, null, 2), "utf8");
89
+ writeFileSync(join(options.outDir, "certificate.html"), renderWitanHtmlReport(report), "utf8");
90
+ writeFileSync(
91
+ join(options.outDir, "badge.json"),
92
+ JSON.stringify(renderWitanBadgeEndpoint(report), null, 2),
93
+ "utf8"
94
+ );
95
+ writeFileSync(join(options.outDir, "badge.svg"), renderWitanBadgeSvg(report), "utf8");
96
+ writeFileSync(join(options.outDir, "summary.json"), JSON.stringify(summary, null, 2), "utf8");
97
+ if (!options.quiet) {
98
+ process.stdout.write(renderTerminalCertificate(summary));
99
+ process.stdout.write(
100
+ `
101
+ Wrote:
102
+ ${options.outDir}/report.json
103
+ ${options.outDir}/certificate.html
104
+ ${options.outDir}/badge.json
105
+ ${options.outDir}/badge.svg
106
+ `
107
+ );
108
+ }
109
+ if (options.minScore != null && report.overallScore < options.minScore) {
110
+ process.stderr.write(
111
+ `Cejel: overall score ${report.overallScore.toFixed(1)}/4.0 is below the required minimum ${options.minScore.toFixed(1)}/4.0
112
+ `
113
+ );
114
+ return 1;
115
+ }
116
+ return 0;
117
+ }
118
+ function parseArgs(args) {
119
+ let repoPath;
120
+ let outDir = DEFAULT_OUT_DIR;
121
+ let minScore;
122
+ let quiet = false;
123
+ const ingestPatterns = [];
124
+ for (let index = 0; index < args.length; index += 1) {
125
+ const arg = args[index];
126
+ if (arg === "--" || arg === void 0) continue;
127
+ if (arg === "--quiet") {
128
+ quiet = true;
129
+ continue;
130
+ }
131
+ if (arg === "--out-dir") {
132
+ const value = args[index + 1];
133
+ if (!value) throw new Error("Missing value for --out-dir");
134
+ outDir = value;
135
+ index += 1;
136
+ continue;
137
+ }
138
+ if (arg === "--min-score") {
139
+ const value = args[index + 1];
140
+ if (!value) throw new Error("Missing value for --min-score");
141
+ const parsed = Number(value);
142
+ if (!Number.isFinite(parsed) || parsed < 0 || parsed > 4) {
143
+ throw new Error(`--min-score must be between 0 and 4, got: ${value}`);
144
+ }
145
+ minScore = parsed;
146
+ index += 1;
147
+ continue;
148
+ }
149
+ if (arg === "--ingest") {
150
+ const value = args[index + 1];
151
+ if (!value) throw new Error("Missing value for --ingest");
152
+ ingestPatterns.push(value);
153
+ index += 1;
154
+ continue;
155
+ }
156
+ if (arg.startsWith("--")) {
157
+ throw new Error(`Unknown Cejel CLI flag: ${arg}`);
158
+ }
159
+ if (repoPath === void 0) repoPath = arg;
160
+ }
161
+ return {
162
+ repoPath: resolve(repoPath ?? "."),
163
+ outDir,
164
+ ...minScore != null ? { minScore } : {},
165
+ quiet,
166
+ ingestPatterns
167
+ };
168
+ }
169
+ function isEntryPoint() {
170
+ const invokedPath = process.argv[1];
171
+ if (!invokedPath) return false;
172
+ let resolvedPath;
173
+ try {
174
+ resolvedPath = realpathSync(invokedPath);
175
+ } catch {
176
+ resolvedPath = invokedPath;
177
+ }
178
+ return import.meta.url === pathToFileURL(resolvedPath).href;
179
+ }
180
+ if (isEntryPoint()) {
181
+ main().catch((error) => {
182
+ const message = error instanceof Error ? error.message : "Unknown Cejel CLI error.";
183
+ process.stderr.write(`${message}
184
+ `);
185
+ process.exitCode = 1;
186
+ });
187
+ }
188
+ export {
189
+ parseArgs,
190
+ runWitanFreeCli
191
+ };