@grove-dev/core 0.13.0 → 0.15.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/awesome-readme.d.ts +8 -0
- package/dist/awesome-readme.d.ts.map +1 -1
- package/dist/awesome-readme.js +28 -0
- package/dist/awesome-readme.js.map +1 -1
- package/dist/build-data.d.ts.map +1 -1
- package/dist/build-data.js +12 -145
- package/dist/build-data.js.map +1 -1
- package/dist/decisions.d.ts +4 -4
- package/dist/decisions.d.ts.map +1 -1
- package/dist/decisions.js +15 -31
- package/dist/decisions.js.map +1 -1
- package/dist/github-cache.d.ts +44 -1
- package/dist/github-cache.d.ts.map +1 -1
- package/dist/github-cache.js +94 -2
- package/dist/github-cache.js.map +1 -1
- package/dist/health-thresholds.d.ts +39 -0
- package/dist/health-thresholds.d.ts.map +1 -0
- package/dist/health-thresholds.js +68 -0
- package/dist/health-thresholds.js.map +1 -0
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +18 -34
- package/dist/health.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/normalize-records.d.ts +131 -0
- package/dist/normalize-records.d.ts.map +1 -0
- package/dist/normalize-records.js +199 -0
- package/dist/normalize-records.js.map +1 -0
- package/dist/repository-health.d.ts.map +1 -1
- package/dist/repository-health.js +9 -18
- package/dist/repository-health.js.map +1 -1
- package/dist/schema.d.ts +60 -46
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +34 -5
- package/dist/schema.js.map +1 -1
- package/dist/validate.d.ts +17 -15
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +70 -123
- package/dist/validate.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The record normalizer: the one place that turns the three record
|
|
3
|
+
* layers into the record every output is built from.
|
|
4
|
+
*
|
|
5
|
+
* 1. Human source — `paths.recordsDir/<slug>.yml`, patched by
|
|
6
|
+
* `paths.overrides`.
|
|
7
|
+
* 2. Generated cache — `paths.githubCache/<slug>.json` (GitHub
|
|
8
|
+
* metadata and health, written by
|
|
9
|
+
* `grove sync github`), with a legacy inline
|
|
10
|
+
* `github` / `health` block and `paths.health`
|
|
11
|
+
* as fallbacks. Health from a stale sync resolves
|
|
12
|
+
* as `status: unknown` (`sync.github.maxAgeDays`).
|
|
13
|
+
* 3. Decisions — `paths.decisions`, which has the final say on
|
|
14
|
+
* visibility.
|
|
15
|
+
*
|
|
16
|
+
* `generate()` (browse, collections, SEO, sitemap, llms), `grove check`,
|
|
17
|
+
* `grove cleanup` and `grove readme generate` all read records through
|
|
18
|
+
* {@link loadNormalizedRecords}, so they cannot disagree about a
|
|
19
|
+
* record's fields or whether it is visible.
|
|
20
|
+
*/
|
|
21
|
+
import { type GithubCache, type GithubFieldSource } from './github-cache.js';
|
|
22
|
+
import { type DecisionVisibility, type GroveConfig, type Resource } from './schema.js';
|
|
23
|
+
/** Where a normalized record's `health` block came from. */
|
|
24
|
+
export type RecordHealthSource =
|
|
25
|
+
/** `paths.githubCache/<slug>.json`. */
|
|
26
|
+
'cache'
|
|
27
|
+
/** A legacy `health` block written inline on the record. */
|
|
28
|
+
| 'inline'
|
|
29
|
+
/** A `paths.overrides` patch. */
|
|
30
|
+
| 'override'
|
|
31
|
+
/** The record's entry in `paths.health`. */
|
|
32
|
+
| 'file'
|
|
33
|
+
/** Fabricated as "unknown" so a decision has a block to carry its visibility. */
|
|
34
|
+
| 'decision' | 'none';
|
|
35
|
+
/** A problem found while normalizing one record file. */
|
|
36
|
+
export interface RecordIssue {
|
|
37
|
+
code: 'schema_error' | 'zod_error' | 'github_cache_mismatch';
|
|
38
|
+
severity: 'error' | 'warning';
|
|
39
|
+
/** Record slug (the file name without its extension). */
|
|
40
|
+
slug: string;
|
|
41
|
+
/** Record file, relative to `cwd`. */
|
|
42
|
+
file: string;
|
|
43
|
+
/** Human-readable message, already prefixed with the slug. */
|
|
44
|
+
message: string;
|
|
45
|
+
}
|
|
46
|
+
export interface NormalizedRecord {
|
|
47
|
+
/** Canonical slug: always the file name without its extension. */
|
|
48
|
+
slug: string;
|
|
49
|
+
/** Record file, relative to `cwd`. */
|
|
50
|
+
file: string;
|
|
51
|
+
/**
|
|
52
|
+
* The record after every layer: source, GitHub cache (or legacy
|
|
53
|
+
* inline copy), overrides, `paths.health` and decisions. This is
|
|
54
|
+
* what the build serializes and every output renders.
|
|
55
|
+
*/
|
|
56
|
+
record: Resource;
|
|
57
|
+
/**
|
|
58
|
+
* The record before `paths.health` and decisions are applied:
|
|
59
|
+
* source + GitHub cache + overrides, schema-parsed, slug from the
|
|
60
|
+
* file name. `grove check` compares this against `paths.health`.
|
|
61
|
+
*/
|
|
62
|
+
base: Resource;
|
|
63
|
+
/** Effective visibility: decision, then health, then the record's own field. */
|
|
64
|
+
visibility: DecisionVisibility;
|
|
65
|
+
/** The `slug` value written in the file, which the file name overrides. */
|
|
66
|
+
declaredSlug: unknown;
|
|
67
|
+
provenance: {
|
|
68
|
+
github: GithubFieldSource;
|
|
69
|
+
health: RecordHealthSource;
|
|
70
|
+
/** True when `paths.decisions` has an entry for this record. */
|
|
71
|
+
decision: boolean;
|
|
72
|
+
/** True when `paths.overrides` has a patch for this record. */
|
|
73
|
+
override: boolean;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** One record file in discovery order, whether or not it normalized. */
|
|
77
|
+
export interface RecordEntry {
|
|
78
|
+
slug: string;
|
|
79
|
+
file: string;
|
|
80
|
+
/** Problems with this file; an `error` means `record` is absent. */
|
|
81
|
+
issues: RecordIssue[];
|
|
82
|
+
/**
|
|
83
|
+
* True when the record's cached health came from a stale sync and
|
|
84
|
+
* resolved as `status: unknown` (see `githubSyncFreshness`).
|
|
85
|
+
*/
|
|
86
|
+
syncStale: boolean;
|
|
87
|
+
/** Absent when the file failed to parse or validate. */
|
|
88
|
+
record?: NormalizedRecord;
|
|
89
|
+
}
|
|
90
|
+
export interface NormalizedRecords {
|
|
91
|
+
/** Records that normalized, sorted by file name. */
|
|
92
|
+
records: NormalizedRecord[];
|
|
93
|
+
/** Every record file, sorted by file name, with its issues. */
|
|
94
|
+
entries: RecordEntry[];
|
|
95
|
+
/** All issues from `entries`, flattened in the same order. */
|
|
96
|
+
issues: RecordIssue[];
|
|
97
|
+
/** The GitHub sync cache the records were resolved against. */
|
|
98
|
+
githubCache: GithubCache;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Apply a `paths.decisions` visibility to a record. For project records
|
|
102
|
+
* the decision overwrites `health.visibility`; a project with no health
|
|
103
|
+
* block gets a fabricated "unknown" one from {@link classifyHealth},
|
|
104
|
+
* because list and index payloads read visibility from `health`. For
|
|
105
|
+
* resource-hub and ecosystem-map records (no `health` block) it sets the
|
|
106
|
+
* top-level `visibility`.
|
|
107
|
+
*/
|
|
108
|
+
export declare function applyDecisionVisibility(record: Resource, visibility: DecisionVisibility | undefined): Resource;
|
|
109
|
+
/**
|
|
110
|
+
* Discover, parse and merge every record under `config.paths.recordsDir`.
|
|
111
|
+
*
|
|
112
|
+
* Per record, lowest to highest precedence:
|
|
113
|
+
*
|
|
114
|
+
* 1. the record file (`paths.recordsDir/<slug>.yml`)
|
|
115
|
+
* 2. the GitHub sync cache, which supplies `github` / `health` over a
|
|
116
|
+
* legacy inline copy ({@link resolveRecordGithub})
|
|
117
|
+
* 3. the `paths.overrides` patch (shallow, top-level fields)
|
|
118
|
+
* 4. schema parse (`recordsFileSchema`); the slug is the file name
|
|
119
|
+
* 5. the `paths.health` entry, for a project record nothing above
|
|
120
|
+
* gave a health block
|
|
121
|
+
* 6. the `paths.decisions` visibility
|
|
122
|
+
*
|
|
123
|
+
* Effective visibility is then decision > health > the record's own
|
|
124
|
+
* `visibility` field ({@link recordVisibility}).
|
|
125
|
+
*
|
|
126
|
+
* Never throws for a bad record: a file that cannot be parsed or fails
|
|
127
|
+
* the schema is reported in `issues` and left out of `records`. Missing
|
|
128
|
+
* or invalid side files are treated as empty; `grove check` reports them.
|
|
129
|
+
*/
|
|
130
|
+
export declare function loadNormalizedRecords(config: GroveConfig, cwd?: string): Promise<NormalizedRecords>;
|
|
131
|
+
//# sourceMappingURL=normalize-records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-records.d.ts","sourceRoot":"","sources":["../src/normalize-records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAIvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EAIhB,KAAK,QAAQ,EAMd,MAAM,aAAa,CAAC;AAErB,4DAA4D;AAC5D,MAAM,MAAM,kBAAkB;AAC5B,uCAAuC;AACrC,OAAO;AACT,4DAA4D;GAC1D,QAAQ;AACV,iCAAiC;GAC/B,UAAU;AACZ,4CAA4C;GAC1C,MAAM;AACR,iFAAiF;GAC/E,UAAU,GACV,MAAM,CAAC;AAEX,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,GAAG,WAAW,GAAG,uBAAuB,CAAC;IAC7D,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,EAAE,QAAQ,CAAC;IACjB;;;;OAIG;IACH,IAAI,EAAE,QAAQ,CAAC;IACf,gFAAgF;IAChF,UAAU,EAAE,kBAAkB,CAAC;IAC/B,2EAA2E;IAC3E,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE;QACV,MAAM,EAAE,iBAAiB,CAAC;QAC1B,MAAM,EAAE,kBAAkB,CAAC;QAC3B,gEAAgE;QAChE,QAAQ,EAAE,OAAO,CAAC;QAClB,+DAA+D;QAC/D,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,+DAA+D;IAC/D,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,8DAA8D;IAC9D,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,+DAA+D;IAC/D,WAAW,EAAE,WAAW,CAAC;CAC1B;AAqDD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,QAAQ,EAChB,UAAU,EAAE,kBAAkB,GAAG,SAAS,GACzC,QAAQ,CAOV;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,GAAG,SAAgB,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAmH5B"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The record normalizer: the one place that turns the three record
|
|
3
|
+
* layers into the record every output is built from.
|
|
4
|
+
*
|
|
5
|
+
* 1. Human source — `paths.recordsDir/<slug>.yml`, patched by
|
|
6
|
+
* `paths.overrides`.
|
|
7
|
+
* 2. Generated cache — `paths.githubCache/<slug>.json` (GitHub
|
|
8
|
+
* metadata and health, written by
|
|
9
|
+
* `grove sync github`), with a legacy inline
|
|
10
|
+
* `github` / `health` block and `paths.health`
|
|
11
|
+
* as fallbacks. Health from a stale sync resolves
|
|
12
|
+
* as `status: unknown` (`sync.github.maxAgeDays`).
|
|
13
|
+
* 3. Decisions — `paths.decisions`, which has the final say on
|
|
14
|
+
* visibility.
|
|
15
|
+
*
|
|
16
|
+
* `generate()` (browse, collections, SEO, sitemap, llms), `grove check`,
|
|
17
|
+
* `grove cleanup` and `grove readme generate` all read records through
|
|
18
|
+
* {@link loadNormalizedRecords}, so they cannot disagree about a
|
|
19
|
+
* record's fields or whether it is visible.
|
|
20
|
+
*/
|
|
21
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
22
|
+
import { basename, join, relative, resolve } from 'node:path';
|
|
23
|
+
import { parse as parseYaml } from 'yaml';
|
|
24
|
+
import { ZodError } from 'zod';
|
|
25
|
+
import { githubSyncFreshnessOptions, loadGithubCache, resolveRecordGithub, } from './github-cache.js';
|
|
26
|
+
import { classifyHealth } from './health.js';
|
|
27
|
+
import { blueprintKind, decisionsFileSchema, healthFileSchema, overridesFileSchema, recordsFileSchema, recordVisibility, unwrapDecisions, unwrapHealth, unwrapOverrides, } from './schema.js';
|
|
28
|
+
/** Read an optional side file; a missing or invalid file yields `fallback`. */
|
|
29
|
+
async function readSideFile(path, cwd, parse, fallback) {
|
|
30
|
+
try {
|
|
31
|
+
const raw = await readFile(resolve(cwd, path), 'utf8');
|
|
32
|
+
return parse(parseYaml(raw, { schema: 'core' }) ?? {});
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return fallback;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function loadDecisionVisibility(config, cwd) {
|
|
39
|
+
return readSideFile(config.paths.decisions, cwd, (raw) => new Map(unwrapDecisions(decisionsFileSchema.parse(raw)).map((d) => [d.id, d.decision.visibility])), new Map());
|
|
40
|
+
}
|
|
41
|
+
function loadHealthEntries(config, cwd) {
|
|
42
|
+
return readSideFile(config.paths.health, cwd, (raw) => new Map(unwrapHealth(healthFileSchema.parse(raw)).map((entry) => [entry.id, entry.health])), new Map());
|
|
43
|
+
}
|
|
44
|
+
function loadOverridePatches(config, cwd) {
|
|
45
|
+
return readSideFile(config.paths.overrides, cwd, (raw) => new Map(unwrapOverrides(overridesFileSchema.parse(raw)).map((entry) => [entry.id, entry.patch])), new Map());
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Apply a `paths.decisions` visibility to a record. For project records
|
|
49
|
+
* the decision overwrites `health.visibility`; a project with no health
|
|
50
|
+
* block gets a fabricated "unknown" one from {@link classifyHealth},
|
|
51
|
+
* because list and index payloads read visibility from `health`. For
|
|
52
|
+
* resource-hub and ecosystem-map records (no `health` block) it sets the
|
|
53
|
+
* top-level `visibility`.
|
|
54
|
+
*/
|
|
55
|
+
export function applyDecisionVisibility(record, visibility) {
|
|
56
|
+
if (!visibility)
|
|
57
|
+
return record;
|
|
58
|
+
if (record.kind === 'project') {
|
|
59
|
+
const health = record.health ?? classifyHealth(record.slug).health;
|
|
60
|
+
return { ...record, health: { ...health, visibility } };
|
|
61
|
+
}
|
|
62
|
+
return { ...record, visibility };
|
|
63
|
+
}
|
|
64
|
+
function isMapping(value) {
|
|
65
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Discover, parse and merge every record under `config.paths.recordsDir`.
|
|
69
|
+
*
|
|
70
|
+
* Per record, lowest to highest precedence:
|
|
71
|
+
*
|
|
72
|
+
* 1. the record file (`paths.recordsDir/<slug>.yml`)
|
|
73
|
+
* 2. the GitHub sync cache, which supplies `github` / `health` over a
|
|
74
|
+
* legacy inline copy ({@link resolveRecordGithub})
|
|
75
|
+
* 3. the `paths.overrides` patch (shallow, top-level fields)
|
|
76
|
+
* 4. schema parse (`recordsFileSchema`); the slug is the file name
|
|
77
|
+
* 5. the `paths.health` entry, for a project record nothing above
|
|
78
|
+
* gave a health block
|
|
79
|
+
* 6. the `paths.decisions` visibility
|
|
80
|
+
*
|
|
81
|
+
* Effective visibility is then decision > health > the record's own
|
|
82
|
+
* `visibility` field ({@link recordVisibility}).
|
|
83
|
+
*
|
|
84
|
+
* Never throws for a bad record: a file that cannot be parsed or fails
|
|
85
|
+
* the schema is reported in `issues` and left out of `records`. Missing
|
|
86
|
+
* or invalid side files are treated as empty; `grove check` reports them.
|
|
87
|
+
*/
|
|
88
|
+
export async function loadNormalizedRecords(config, cwd = process.cwd()) {
|
|
89
|
+
const recordsDir = resolve(cwd, config.paths.recordsDir);
|
|
90
|
+
const expectedKind = blueprintKind[config.blueprint];
|
|
91
|
+
const files = (await readdir(recordsDir).catch(() => []))
|
|
92
|
+
.filter((file) => file.endsWith('.yml'))
|
|
93
|
+
.sort();
|
|
94
|
+
const [githubCache, decisions, healthBySlug, patches] = await Promise.all([
|
|
95
|
+
loadGithubCache(config, cwd),
|
|
96
|
+
loadDecisionVisibility(config, cwd),
|
|
97
|
+
loadHealthEntries(config, cwd),
|
|
98
|
+
loadOverridePatches(config, cwd),
|
|
99
|
+
]);
|
|
100
|
+
const cachePath = relative(cwd, githubCache.dir) || '.';
|
|
101
|
+
// A stale sync resolves as `status: unknown` rather than old values.
|
|
102
|
+
const freshness = githubSyncFreshnessOptions(config);
|
|
103
|
+
const entries = [];
|
|
104
|
+
for (const name of files) {
|
|
105
|
+
const slug = basename(name, '.yml');
|
|
106
|
+
const path = join(recordsDir, name);
|
|
107
|
+
const file = relative(cwd, path);
|
|
108
|
+
const entry = { slug, file, issues: [], syncStale: false };
|
|
109
|
+
entries.push(entry);
|
|
110
|
+
const fail = (code, message) => entry.issues.push({ code, severity: 'error', slug, file, message: `${slug}: ${message}` });
|
|
111
|
+
// `schema: 'core'` disables custom-tag interpretation: a record with
|
|
112
|
+
// `!!binary` / `!!js/function` must not become a host object.
|
|
113
|
+
let raw;
|
|
114
|
+
try {
|
|
115
|
+
raw = parseYaml(await readFile(path, 'utf8'), { schema: 'core' });
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
fail('schema_error', err.message);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (!isMapping(raw)) {
|
|
122
|
+
fail('schema_error', 'record file is empty or not a YAML mapping');
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
// Cache wins over a legacy inline copy; a disagreement is a second
|
|
126
|
+
// source of truth, so name the fields.
|
|
127
|
+
const resolved = resolveRecordGithub(raw, githubCache.entries.get(slug), freshness);
|
|
128
|
+
entry.syncStale = resolved.syncStale !== undefined;
|
|
129
|
+
if (resolved.conflicts.length > 0) {
|
|
130
|
+
entry.issues.push({
|
|
131
|
+
code: 'github_cache_mismatch',
|
|
132
|
+
severity: 'warning',
|
|
133
|
+
slug,
|
|
134
|
+
file,
|
|
135
|
+
message: `${slug}: inline github/health disagrees with ${cachePath}/${slug}.json — ${resolved.conflicts.join(', ')}. The cache wins; run \`grove migrate github-cache\` to drop the inline copy.`,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const merged = resolved.record;
|
|
139
|
+
if (!merged.kind)
|
|
140
|
+
merged.kind = expectedKind;
|
|
141
|
+
const patch = patches.get(slug);
|
|
142
|
+
let base;
|
|
143
|
+
try {
|
|
144
|
+
base = recordsFileSchema.parse(patch ? { ...merged, ...patch } : merged);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
if (err instanceof ZodError) {
|
|
148
|
+
for (const issue of err.issues) {
|
|
149
|
+
const where = issue.path.length > 0 ? issue.path.join('.') : '(root)';
|
|
150
|
+
fail('zod_error', `${where} ${issue.message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
fail('schema_error', err.message);
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
base.slug = slug;
|
|
159
|
+
let healthSource = patch && 'health' in patch
|
|
160
|
+
? 'override'
|
|
161
|
+
: resolved.health === 'none'
|
|
162
|
+
? 'none'
|
|
163
|
+
: resolved.health;
|
|
164
|
+
let record = base;
|
|
165
|
+
if (record.kind === 'project' && !record.health) {
|
|
166
|
+
healthSource = 'none';
|
|
167
|
+
const fromFile = healthBySlug.get(slug);
|
|
168
|
+
if (fromFile) {
|
|
169
|
+
record = { ...record, health: fromFile };
|
|
170
|
+
healthSource = 'file';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const decision = decisions.get(slug);
|
|
174
|
+
if (decision && record.kind === 'project' && !record.health)
|
|
175
|
+
healthSource = 'decision';
|
|
176
|
+
record = applyDecisionVisibility(record, decision);
|
|
177
|
+
entry.record = {
|
|
178
|
+
slug,
|
|
179
|
+
file,
|
|
180
|
+
record,
|
|
181
|
+
base,
|
|
182
|
+
visibility: recordVisibility(record),
|
|
183
|
+
declaredSlug: raw.slug,
|
|
184
|
+
provenance: {
|
|
185
|
+
github: resolved.github,
|
|
186
|
+
health: healthSource,
|
|
187
|
+
decision: decision !== undefined,
|
|
188
|
+
override: patch !== undefined,
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
records: entries.flatMap((entry) => (entry.record ? [entry.record] : [])),
|
|
194
|
+
entries,
|
|
195
|
+
issues: entries.flatMap((entry) => entry.issues),
|
|
196
|
+
githubCache,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=normalize-records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-records.js","sourceRoot":"","sources":["../src/normalize-records.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-health.d.ts","sourceRoot":"","sources":["../src/repository-health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"repository-health.d.ts","sourceRoot":"","sources":["../src/repository-health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAQxD,MAAM,MAAM,sBAAsB,GAC9B,QAAQ,GACR,YAAY,GACZ,QAAQ,GACR,cAAc,GACd,UAAU,GACV,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,0BAA0B,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,UAAU,EAAE,0BAA0B,CAAC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAeD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,sBAAsB,CAgF7F"}
|
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
if (!value)
|
|
3
|
-
return Infinity;
|
|
4
|
-
const date = new Date(value);
|
|
5
|
-
if (Number.isNaN(date.valueOf()))
|
|
6
|
-
return Infinity;
|
|
7
|
-
return (Date.now() - date.valueOf()) / 86_400_000;
|
|
8
|
-
}
|
|
1
|
+
import { daysSince, POPULAR_STARS, PUSH_AGE_MAX_DAYS, RECENT_RELEASE_WITHIN_DAYS, } from './health-thresholds.js';
|
|
9
2
|
function unknown(reason) {
|
|
10
3
|
return { status: 'unknown', confidence: 'low', evidence: [reason], counterEvidence: [] };
|
|
11
4
|
}
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
const ACTIVE_WITHIN_DAYS =
|
|
18
|
-
const STABLE_WITHIN_DAYS =
|
|
19
|
-
const CONFIDENT_STALE_WITHIN_DAYS =
|
|
20
|
-
const RECENT_RELEASE_WITHIN_DAYS = 365;
|
|
21
|
-
const POPULAR_STARS = 500;
|
|
5
|
+
// The push-age bands come from the shared table in health-thresholds.ts,
|
|
6
|
+
// so a README link and a directory record read the same cutoffs. This
|
|
7
|
+
// classifier keeps its own vocabulary: the `stale` band (6–18 months)
|
|
8
|
+
// reads as `stable` here, and both later bands as `likely-stale` — with
|
|
9
|
+
// medium confidence up to 24 months and low confidence beyond.
|
|
10
|
+
const ACTIVE_WITHIN_DAYS = PUSH_AGE_MAX_DAYS.active;
|
|
11
|
+
const STABLE_WITHIN_DAYS = PUSH_AGE_MAX_DAYS.stale;
|
|
12
|
+
const CONFIDENT_STALE_WITHIN_DAYS = PUSH_AGE_MAX_DAYS.needs_review;
|
|
22
13
|
export function classifyRepositoryHealth(evidence) {
|
|
23
14
|
if (evidence.status === 'not-found') {
|
|
24
15
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-health.js","sourceRoot":"","sources":["../src/repository-health.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"repository-health.js","sourceRoot":"","sources":["../src/repository-health.ts"],"names":[],"mappings":"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"}
|