@geoql/doctor-core 1.0.1 → 1.1.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.
package/dist/index.d.ts CHANGED
@@ -485,5 +485,72 @@ interface ListRulesFilter {
485
485
  }
486
486
  declare function listRules(filter?: ListRulesFilter): RegisteredRule[];
487
487
  //#endregion
488
- export { type ApplyInlineDisablesOptions, type AuditConfig, type AuditReport, type AuditTimings, BUILT_IN_RECOMMENDED, type Capability, type CliOverrides, ConfigCycleError, ConfigFileNotFoundError, type ConfigSource, DOCTOR_REPORT_SCHEMA_VERSION, DeadCodeImportFailed, DeadCodeTimeoutError, type Diagnostic, type DiagnosticSource, type DirectiveLine, type DirectiveRange, type DirectiveSet, type DoctorReport, type DoctorUserConfig, type Framework, type GitScopeMode, type InitConfigFormat, type InitFileWrite, type InitOptions, type InitPlan, type InitPreset, InvalidConfigError, type ListRulesFilter, type LoadRuleDocOptions, type MonorepoKind, type MonorepoResult, OxlintOutputTooLarge, OxlintSpawnFailed, type ProjectInfo, type ProjectInfoLite, RULE_REGISTRY, type RawInitAnswers, type RegisteredRule, type ReporterFormat, type ReporterInput, type ReporterOptions, type ResolvedDoctorConfig, type ResolvedInitAnswers, type RuleCategory, type RuleDoc, type RuleSource, type ScoreBreakdownEntry, type ScoreConfig, type ScoreResult, type Severity, type VerboseTraceOptions, type WorkspacePackage, agentReport, applyInlineDisables, audit, buildDoctorReport, checkBuildQuality, checkDeadCode, checkDeps, checkNuxtProject, dedupeDeadCodeAgainstLint, defineConfig, detectProject, detectSummary, docsUrl, encodeAnnotation, encodeAnnotations, findMonorepoRoot, format, isNuxtLayoutFile, isNuxtPageFile, isNuxtServerFile, jsonCompactReport, jsonReport, listChangedFiles, listRules, listWorkspacePackages, loadAllRuleDocs, loadDoctorConfig, loadRuleDoc, mergeCliOverrides, normalizeInitAnswers, parseDirectives, parseExcludeList, planInit, prCommentReport, prettyReport, renderDetectSummary, renderVerboseTrace, runCrossFilePass, sarifReport, scoreDiagnostics, validateConfig };
488
+ //#region src/push.d.ts
489
+ /**
490
+ * The 6 fields the SaaS receives for each finding.
491
+ * Everything else (message, codeSnippet, recommendation, etc.) is privacy-sensitive
492
+ * and MUST be stripped before transmission.
493
+ */
494
+ interface PushedFinding {
495
+ file: string;
496
+ line: number;
497
+ col: number;
498
+ ruleId: string;
499
+ severity: Severity;
500
+ category: string;
501
+ }
502
+ interface PushPayloadInput {
503
+ project: string;
504
+ score: number;
505
+ errorCount: number;
506
+ warnCount: number;
507
+ infoCount: number;
508
+ findings: PushedFinding[];
509
+ }
510
+ interface PushPayload extends PushPayloadInput {
511
+ commitSha?: string;
512
+ branch?: string;
513
+ prNumber?: number;
514
+ }
515
+ interface PushOptions {
516
+ project: string;
517
+ score: number;
518
+ errorCount: number;
519
+ warnCount: number;
520
+ infoCount: number;
521
+ diagnostics: Diagnostic[];
522
+ url: string;
523
+ apiKey: string;
524
+ fetchImpl?: typeof fetch;
525
+ /** Overrides for the request timeout (ms). Defaults to 5000. Test-only. */
526
+ timeoutMs?: number;
527
+ }
528
+ type PushResult = {
529
+ ok: true;
530
+ status?: number;
531
+ error?: undefined;
532
+ } | {
533
+ ok: false;
534
+ status?: number;
535
+ error: string;
536
+ };
537
+ /**
538
+ * Strip a list of Diagnostics down to the 6 allowed push fields.
539
+ * Privacy boundary: this function is the single point of enforcement.
540
+ * If you add a new privacy-sensitive field to Diagnostic, add it to the deny list here.
541
+ */
542
+ declare function stripFindings(diagnostics: Diagnostic[]): PushedFinding[];
543
+ /**
544
+ * Build the top-level POST body. CI fields (commitSha, branch, prNumber) are
545
+ * included ONLY when the matching GITHUB_* env var is set.
546
+ */
547
+ declare function buildPushPayload(input: PushPayloadInput): PushPayload;
548
+ /**
549
+ * Strip + POST findings to a SaaS endpoint. Never throws — returns
550
+ * `{ ok: false, error }` on any HTTP / network failure so the audit's
551
+ * exit code is not affected by SaaS downtime.
552
+ */
553
+ declare function pushFindings(opts: PushOptions): Promise<PushResult>;
554
+ //#endregion
555
+ export { type ApplyInlineDisablesOptions, type AuditConfig, type AuditReport, type AuditTimings, BUILT_IN_RECOMMENDED, type Capability, type CliOverrides, ConfigCycleError, ConfigFileNotFoundError, type ConfigSource, DOCTOR_REPORT_SCHEMA_VERSION, DeadCodeImportFailed, DeadCodeTimeoutError, type Diagnostic, type DiagnosticSource, type DirectiveLine, type DirectiveRange, type DirectiveSet, type DoctorReport, type DoctorUserConfig, type Framework, type GitScopeMode, type InitConfigFormat, type InitFileWrite, type InitOptions, type InitPlan, type InitPreset, InvalidConfigError, type ListRulesFilter, type LoadRuleDocOptions, type MonorepoKind, type MonorepoResult, OxlintOutputTooLarge, OxlintSpawnFailed, type ProjectInfo, type ProjectInfoLite, type PushOptions, type PushPayload, type PushPayloadInput, type PushResult, type PushedFinding, RULE_REGISTRY, type RawInitAnswers, type RegisteredRule, type ReporterFormat, type ReporterInput, type ReporterOptions, type ResolvedDoctorConfig, type ResolvedInitAnswers, type RuleCategory, type RuleDoc, type RuleSource, type ScoreBreakdownEntry, type ScoreConfig, type ScoreResult, type Severity, type VerboseTraceOptions, type WorkspacePackage, agentReport, applyInlineDisables, audit, buildDoctorReport, buildPushPayload, checkBuildQuality, checkDeadCode, checkDeps, checkNuxtProject, dedupeDeadCodeAgainstLint, defineConfig, detectProject, detectSummary, docsUrl, encodeAnnotation, encodeAnnotations, findMonorepoRoot, format, isNuxtLayoutFile, isNuxtPageFile, isNuxtServerFile, jsonCompactReport, jsonReport, listChangedFiles, listRules, listWorkspacePackages, loadAllRuleDocs, loadDoctorConfig, loadRuleDoc, mergeCliOverrides, normalizeInitAnswers, parseDirectives, parseExcludeList, planInit, prCommentReport, prettyReport, pushFindings, renderDetectSummary, renderVerboseTrace, runCrossFilePass, sarifReport, scoreDiagnostics, stripFindings, validateConfig };
489
556
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -3474,6 +3474,112 @@ function format(input, kind = "agent", options) {
3474
3474
  return agentReport(input, options);
3475
3475
  }
3476
3476
  //#endregion
3477
- export { BUILT_IN_RECOMMENDED, ConfigCycleError, ConfigFileNotFoundError, DOCTOR_REPORT_SCHEMA_VERSION, DeadCodeImportFailed, DeadCodeTimeoutError, InvalidConfigError, OxlintOutputTooLarge, OxlintSpawnFailed, RULE_REGISTRY, agentReport, applyInlineDisables, audit, buildDoctorReport, checkBuildQuality, checkDeadCode, checkDeps, checkNuxtProject, dedupeDeadCodeAgainstLint, defineConfig, detectProject, detectSummary, docsUrl, encodeAnnotation, encodeAnnotations, findMonorepoRoot, format, isNuxtLayoutFile, isNuxtPageFile, isNuxtServerFile, jsonCompactReport, jsonReport, listChangedFiles, listRules, listWorkspacePackages, loadAllRuleDocs, loadDoctorConfig, loadRuleDoc, mergeCliOverrides, normalizeInitAnswers, parseDirectives, parseExcludeList, planInit, prCommentReport, prettyReport, renderDetectSummary, renderVerboseTrace, runCrossFilePass, sarifReport, scoreDiagnostics, validateConfig };
3477
+ //#region src/push.ts
3478
+ const PUSH_TIMEOUT_MS = 5e3;
3479
+ const categoryByRuleId = new Map(RULE_REGISTRY.map((r) => [r.id, r.category]));
3480
+ function lookupCategory(ruleId) {
3481
+ return categoryByRuleId.get(ruleId) ?? "unknown";
3482
+ }
3483
+ /**
3484
+ * Strip a list of Diagnostics down to the 6 allowed push fields.
3485
+ * Privacy boundary: this function is the single point of enforcement.
3486
+ * If you add a new privacy-sensitive field to Diagnostic, add it to the deny list here.
3487
+ */
3488
+ function stripFindings(diagnostics) {
3489
+ const out = new Array(diagnostics.length);
3490
+ for (let i = 0; i < diagnostics.length; i++) {
3491
+ const d = diagnostics[i];
3492
+ out[i] = {
3493
+ file: d.file,
3494
+ line: d.line,
3495
+ col: d.column,
3496
+ ruleId: d.ruleId,
3497
+ severity: d.severity,
3498
+ category: lookupCategory(d.ruleId)
3499
+ };
3500
+ }
3501
+ return out;
3502
+ }
3503
+ function readOptionalEnv(name) {
3504
+ const v = process.env[name];
3505
+ return v === void 0 || v === "" ? void 0 : v;
3506
+ }
3507
+ function readPrNumber() {
3508
+ const raw = readOptionalEnv("GITHUB_PR_NUMBER");
3509
+ if (raw === void 0) return void 0;
3510
+ const n = Number(raw);
3511
+ return Number.isFinite(n) ? n : void 0;
3512
+ }
3513
+ /**
3514
+ * Build the top-level POST body. CI fields (commitSha, branch, prNumber) are
3515
+ * included ONLY when the matching GITHUB_* env var is set.
3516
+ */
3517
+ function buildPushPayload(input) {
3518
+ const payload = {
3519
+ project: input.project,
3520
+ score: input.score,
3521
+ errorCount: input.errorCount,
3522
+ warnCount: input.warnCount,
3523
+ infoCount: input.infoCount,
3524
+ findings: input.findings
3525
+ };
3526
+ const commitSha = readOptionalEnv("GITHUB_SHA");
3527
+ const branch = readOptionalEnv("GITHUB_REF_NAME");
3528
+ const prNumber = readPrNumber();
3529
+ if (commitSha !== void 0) payload.commitSha = commitSha;
3530
+ if (branch !== void 0) payload.branch = branch;
3531
+ if (prNumber !== void 0) payload.prNumber = prNumber;
3532
+ return payload;
3533
+ }
3534
+ /**
3535
+ * Strip + POST findings to a SaaS endpoint. Never throws — returns
3536
+ * `{ ok: false, error }` on any HTTP / network failure so the audit's
3537
+ * exit code is not affected by SaaS downtime.
3538
+ */
3539
+ async function pushFindings(opts) {
3540
+ const findings = stripFindings(opts.diagnostics);
3541
+ const payload = buildPushPayload({
3542
+ project: opts.project,
3543
+ score: opts.score,
3544
+ errorCount: opts.errorCount,
3545
+ warnCount: opts.warnCount,
3546
+ infoCount: opts.infoCount,
3547
+ findings
3548
+ });
3549
+ const fetchImpl = opts.fetchImpl ?? fetch;
3550
+ const controller = new AbortController();
3551
+ const timeoutMs = opts.timeoutMs ?? PUSH_TIMEOUT_MS;
3552
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
3553
+ timer.unref?.();
3554
+ try {
3555
+ const res = await fetchImpl(opts.url, {
3556
+ method: "POST",
3557
+ headers: {
3558
+ "Content-Type": "application/json",
3559
+ "x-api-key": opts.apiKey
3560
+ },
3561
+ body: JSON.stringify(payload),
3562
+ signal: controller.signal
3563
+ });
3564
+ clearTimeout(timer);
3565
+ if (res.ok) return {
3566
+ ok: true,
3567
+ status: res.status
3568
+ };
3569
+ return {
3570
+ ok: false,
3571
+ status: res.status,
3572
+ error: `HTTP ${res.status} ${res.statusText}`.trim()
3573
+ };
3574
+ } catch (err) {
3575
+ clearTimeout(timer);
3576
+ return {
3577
+ ok: false,
3578
+ error: err instanceof Error ? err.message : String(err)
3579
+ };
3580
+ }
3581
+ }
3582
+ //#endregion
3583
+ export { BUILT_IN_RECOMMENDED, ConfigCycleError, ConfigFileNotFoundError, DOCTOR_REPORT_SCHEMA_VERSION, DeadCodeImportFailed, DeadCodeTimeoutError, InvalidConfigError, OxlintOutputTooLarge, OxlintSpawnFailed, RULE_REGISTRY, agentReport, applyInlineDisables, audit, buildDoctorReport, buildPushPayload, checkBuildQuality, checkDeadCode, checkDeps, checkNuxtProject, dedupeDeadCodeAgainstLint, defineConfig, detectProject, detectSummary, docsUrl, encodeAnnotation, encodeAnnotations, findMonorepoRoot, format, isNuxtLayoutFile, isNuxtPageFile, isNuxtServerFile, jsonCompactReport, jsonReport, listChangedFiles, listRules, listWorkspacePackages, loadAllRuleDocs, loadDoctorConfig, loadRuleDoc, mergeCliOverrides, normalizeInitAnswers, parseDirectives, parseExcludeList, planInit, prCommentReport, prettyReport, pushFindings, renderDetectSummary, renderVerboseTrace, runCrossFilePass, sarifReport, scoreDiagnostics, stripFindings, validateConfig };
3478
3584
 
3479
3585
  //# sourceMappingURL=index.js.map