@grove-dev/core 0.7.0 → 0.9.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/audit.d.ts +3 -3
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +25 -6
- package/dist/audit.js.map +1 -1
- package/dist/awesome-readme.d.ts.map +1 -1
- package/dist/awesome-readme.js +31 -31
- package/dist/awesome-readme.js.map +1 -1
- package/dist/build-data.d.ts +1 -1
- package/dist/build-data.d.ts.map +1 -1
- package/dist/build-data.js +110 -80
- package/dist/build-data.js.map +1 -1
- package/dist/candidate.d.ts +34 -0
- package/dist/candidate.d.ts.map +1 -0
- package/dist/candidate.js +128 -0
- package/dist/candidate.js.map +1 -0
- package/dist/collections-io.d.ts +1 -1
- package/dist/collections-io.js +8 -8
- package/dist/collections-io.js.map +1 -1
- package/dist/collections.d.ts +2 -2
- package/dist/collections.d.ts.map +1 -1
- package/dist/collections.js +8 -9
- package/dist/collections.js.map +1 -1
- package/dist/collector.d.ts +1 -1
- package/dist/collector.d.ts.map +1 -1
- package/dist/collector.js +2 -2
- package/dist/collector.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -4
- package/dist/config.js.map +1 -1
- package/dist/content-body.d.ts.map +1 -1
- package/dist/content-body.js +22 -22
- package/dist/content-body.js.map +1 -1
- package/dist/contributors.d.ts.map +1 -1
- package/dist/contributors.js +22 -23
- package/dist/contributors.js.map +1 -1
- package/dist/decisions.d.ts +1 -1
- package/dist/decisions.d.ts.map +1 -1
- package/dist/decisions.js +18 -20
- package/dist/decisions.js.map +1 -1
- package/dist/directory-client.d.ts +6 -4
- package/dist/directory-client.d.ts.map +1 -1
- package/dist/directory-client.js +9 -4
- package/dist/directory-client.js.map +1 -1
- package/dist/directory-facets.d.ts +1 -1
- package/dist/directory-facets.d.ts.map +1 -1
- package/dist/directory-facets.js +35 -17
- package/dist/directory-facets.js.map +1 -1
- package/dist/directory-filter-keys.d.ts +53 -0
- package/dist/directory-filter-keys.d.ts.map +1 -0
- package/dist/directory-filter-keys.js +66 -0
- package/dist/directory-filter-keys.js.map +1 -0
- package/dist/directory-format.d.ts.map +1 -1
- package/dist/directory-format.js +15 -15
- package/dist/directory-format.js.map +1 -1
- package/dist/directory-lenses.d.ts +1 -1
- package/dist/directory-lenses.d.ts.map +1 -1
- package/dist/directory-lenses.js +66 -61
- package/dist/directory-lenses.js.map +1 -1
- package/dist/directory-repo.js +2 -2
- package/dist/directory-scores.d.ts.map +1 -1
- package/dist/directory-scores.js +25 -25
- package/dist/directory-scores.js.map +1 -1
- package/dist/directory-search.d.ts +4 -4
- package/dist/directory-search.d.ts.map +1 -1
- package/dist/directory-search.js +129 -110
- package/dist/directory-search.js.map +1 -1
- package/dist/directory-taxonomy.d.ts +1 -1
- package/dist/directory-taxonomy.d.ts.map +1 -1
- package/dist/directory-taxonomy.js +2 -2
- package/dist/directory-taxonomy.js.map +1 -1
- package/dist/enrich.d.ts.map +1 -1
- package/dist/enrich.js +15 -12
- package/dist/enrich.js.map +1 -1
- package/dist/evidence.d.ts +33 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +181 -0
- package/dist/evidence.js.map +1 -0
- package/dist/github-client.js +6 -6
- package/dist/github.d.ts +9 -1
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +40 -13
- package/dist/github.js.map +1 -1
- package/dist/health.d.ts +1 -1
- package/dist/health.js +44 -44
- package/dist/host.js +2 -2
- package/dist/import-types.d.ts +24 -0
- package/dist/import-types.d.ts.map +1 -0
- package/dist/import-types.js +2 -0
- package/dist/import-types.js.map +1 -0
- package/dist/import-write.d.ts +12 -0
- package/dist/import-write.d.ts.map +1 -0
- package/dist/import-write.js +39 -0
- package/dist/import-write.js.map +1 -0
- package/dist/importer.d.ts +5 -3
- package/dist/importer.d.ts.map +1 -1
- package/dist/importer.js +4 -2
- package/dist/importer.js.map +1 -1
- package/dist/index.d.ts +74 -63
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -75
- package/dist/index.js.map +1 -1
- package/dist/io.js +8 -8
- package/dist/llms.d.ts +1 -1
- package/dist/llms.d.ts.map +1 -1
- package/dist/llms.js +65 -64
- package/dist/llms.js.map +1 -1
- package/dist/markdown.d.ts +3 -33
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +2 -39
- package/dist/markdown.js.map +1 -1
- package/dist/og-image.d.ts +8 -8
- package/dist/og-image.d.ts.map +1 -1
- package/dist/og-image.js +91 -84
- package/dist/og-image.js.map +1 -1
- package/dist/page-document.d.ts +8 -8
- package/dist/page-document.d.ts.map +1 -1
- package/dist/page-document.js +48 -54
- package/dist/page-document.js.map +1 -1
- package/dist/parseReadme.d.ts.map +1 -1
- package/dist/parseReadme.js +9 -11
- package/dist/parseReadme.js.map +1 -1
- package/dist/prepare.d.ts +5 -5
- package/dist/prepare.d.ts.map +1 -1
- package/dist/prepare.js +32 -38
- package/dist/prepare.js.map +1 -1
- package/dist/readme-health.d.ts +33 -0
- package/dist/readme-health.d.ts.map +1 -0
- package/dist/readme-health.js +88 -0
- package/dist/readme-health.js.map +1 -0
- package/dist/related.d.ts +1 -1
- package/dist/repository-health.d.ts +11 -0
- package/dist/repository-health.d.ts.map +1 -0
- package/dist/repository-health.js +94 -0
- package/dist/repository-health.js.map +1 -0
- package/dist/schema.d.ts +72 -30
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +156 -144
- package/dist/schema.js.map +1 -1
- package/dist/site-artifacts.js +1 -1
- package/dist/sitemap.d.ts +2 -2
- package/dist/sitemap.d.ts.map +1 -1
- package/dist/sitemap.js +39 -39
- package/dist/sitemap.js.map +1 -1
- package/dist/slug.js +4 -4
- package/dist/sync-icons.js +15 -15
- package/dist/taxonomy-inference.d.ts +27 -0
- package/dist/taxonomy-inference.d.ts.map +1 -0
- package/dist/taxonomy-inference.js +38 -0
- package/dist/taxonomy-inference.js.map +1 -0
- package/dist/validate.d.ts +3 -3
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +73 -62
- package/dist/validate.js.map +1 -1
- package/dist/yaml.d.ts +47 -0
- package/dist/yaml.d.ts.map +1 -0
- package/dist/yaml.js +56 -0
- package/dist/yaml.js.map +1 -0
- package/package.json +6 -1
package/dist/validate.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { access, readdir, readFile } from
|
|
2
|
-
import { basename, join, resolve } from
|
|
3
|
-
import { parse as parseYaml } from
|
|
4
|
-
import { ZodError } from
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { access, readdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import { basename, join, resolve } from 'node:path';
|
|
3
|
+
import { parse as parseYaml } from 'yaml';
|
|
4
|
+
import { ZodError } from 'zod';
|
|
5
|
+
import { readYamlFile } from './io.js';
|
|
6
|
+
import { blueprintKind, decisionsFileSchema, healthFileSchema, recordsFileSchema, unwrapDecisions, unwrapHealth, } from './schema.js';
|
|
7
7
|
async function exists(path) {
|
|
8
8
|
try {
|
|
9
9
|
await access(path);
|
|
@@ -15,14 +15,12 @@ async function exists(path) {
|
|
|
15
15
|
}
|
|
16
16
|
async function taxonomyIds(path) {
|
|
17
17
|
try {
|
|
18
|
-
const raw = parseYaml(await readFile(path,
|
|
18
|
+
const raw = parseYaml(await readFile(path, 'utf8'), { schema: 'core' });
|
|
19
19
|
if (!Array.isArray(raw))
|
|
20
20
|
return new Set();
|
|
21
21
|
return new Set(raw
|
|
22
|
-
.map((entry) => entry && typeof entry ===
|
|
23
|
-
|
|
24
|
-
: undefined)
|
|
25
|
-
.filter((id) => typeof id === "string"));
|
|
22
|
+
.map((entry) => entry && typeof entry === 'object' ? entry.id : undefined)
|
|
23
|
+
.filter((id) => typeof id === 'string'));
|
|
26
24
|
}
|
|
27
25
|
catch {
|
|
28
26
|
return new Set();
|
|
@@ -44,46 +42,46 @@ export async function validateProject(config, opts = {}) {
|
|
|
44
42
|
const recordsDir = resolve(process.cwd(), config.paths.recordsDir);
|
|
45
43
|
if (!(await exists(recordsDir))) {
|
|
46
44
|
errors.push({
|
|
47
|
-
code:
|
|
45
|
+
code: 'missing_records_dir',
|
|
48
46
|
message: `${config.paths.recordsDir} does not exist`,
|
|
49
|
-
severity:
|
|
47
|
+
severity: 'error',
|
|
50
48
|
});
|
|
51
49
|
return finalize(errors, warnings);
|
|
52
50
|
}
|
|
53
51
|
const expectedKind = blueprintKind[config.blueprint];
|
|
54
52
|
const entries = await readdir(recordsDir).catch(() => []);
|
|
55
|
-
const files = entries.filter((f) => f.endsWith(
|
|
53
|
+
const files = entries.filter((f) => f.endsWith('.yml')).sort();
|
|
56
54
|
const slugs = new Set();
|
|
57
55
|
/** Slugs that have a github link and therefore need a health entry. */
|
|
58
56
|
const slugsNeedingHealth = new Set();
|
|
59
|
-
const taxonomyDir = config.paths.taxonomyDir ??
|
|
57
|
+
const taxonomyDir = config.paths.taxonomyDir ?? 'data/taxonomy';
|
|
60
58
|
const taxonomy = {
|
|
61
|
-
categories: await taxonomyIds(resolve(process.cwd(), taxonomyDir,
|
|
62
|
-
stacks: await taxonomyIds(resolve(process.cwd(), taxonomyDir,
|
|
63
|
-
platforms: await taxonomyIds(resolve(process.cwd(), taxonomyDir,
|
|
59
|
+
categories: await taxonomyIds(resolve(process.cwd(), taxonomyDir, 'categories.yml')),
|
|
60
|
+
stacks: await taxonomyIds(resolve(process.cwd(), taxonomyDir, 'stacks.yml')),
|
|
61
|
+
platforms: await taxonomyIds(resolve(process.cwd(), taxonomyDir, 'platforms.yml')),
|
|
64
62
|
};
|
|
65
63
|
const warnUnknownTaxonomy = (fileSlug, field, value, ids, filename) => {
|
|
66
64
|
if (ids.size === 0 || ids.has(value))
|
|
67
65
|
return;
|
|
68
66
|
warnings.push({
|
|
69
|
-
code:
|
|
67
|
+
code: 'unknown_taxonomy_value',
|
|
70
68
|
message: `${fileSlug}: ${field} "${value}" is not defined in ${taxonomyDir}/${filename}`,
|
|
71
|
-
severity:
|
|
69
|
+
severity: 'warning',
|
|
72
70
|
});
|
|
73
71
|
};
|
|
74
72
|
for (const file of files) {
|
|
75
|
-
const fileSlug = basename(file,
|
|
76
|
-
const text = await readFile(join(recordsDir, file),
|
|
73
|
+
const fileSlug = basename(file, '.yml');
|
|
74
|
+
const text = await readFile(join(recordsDir, file), 'utf8');
|
|
77
75
|
// `schema: 'core'` disables custom-tag interpretation; a malicious
|
|
78
76
|
// record with `!!binary` / `!!js/function` would otherwise be parsed
|
|
79
77
|
// into a host object by the YAML package's default schema.
|
|
80
78
|
// Implementation-checklist.md #27.
|
|
81
|
-
const raw = parseYaml(text, { schema:
|
|
82
|
-
if (raw === null || typeof raw !==
|
|
79
|
+
const raw = parseYaml(text, { schema: 'core' });
|
|
80
|
+
if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
83
81
|
errors.push({
|
|
84
|
-
code:
|
|
82
|
+
code: 'schema_error',
|
|
85
83
|
message: `${fileSlug}: record file is empty or not a YAML mapping`,
|
|
86
|
-
severity:
|
|
84
|
+
severity: 'error',
|
|
87
85
|
});
|
|
88
86
|
slugs.add(fileSlug);
|
|
89
87
|
continue;
|
|
@@ -93,9 +91,9 @@ export async function validateProject(config, opts = {}) {
|
|
|
93
91
|
// still need to flag a duplicate filename as an error.
|
|
94
92
|
if (slugs.has(fileSlug)) {
|
|
95
93
|
errors.push({
|
|
96
|
-
code:
|
|
94
|
+
code: 'duplicate_slug',
|
|
97
95
|
message: `Duplicate record slug: ${fileSlug}`,
|
|
98
|
-
severity:
|
|
96
|
+
severity: 'error',
|
|
99
97
|
});
|
|
100
98
|
}
|
|
101
99
|
slugs.add(fileSlug);
|
|
@@ -113,19 +111,19 @@ export async function validateProject(config, opts = {}) {
|
|
|
113
111
|
catch (err) {
|
|
114
112
|
if (err instanceof ZodError) {
|
|
115
113
|
for (const issue of err.issues) {
|
|
116
|
-
const where = issue.path.length > 0 ? issue.path.join(
|
|
114
|
+
const where = issue.path.length > 0 ? issue.path.join('.') : '(root)';
|
|
117
115
|
errors.push({
|
|
118
|
-
code:
|
|
116
|
+
code: 'zod_error',
|
|
119
117
|
message: `${fileSlug}: ${where} ${issue.message}`,
|
|
120
|
-
severity:
|
|
118
|
+
severity: 'error',
|
|
121
119
|
});
|
|
122
120
|
}
|
|
123
121
|
}
|
|
124
122
|
else {
|
|
125
123
|
errors.push({
|
|
126
|
-
code:
|
|
124
|
+
code: 'schema_error',
|
|
127
125
|
message: `${fileSlug}: ${err.message}`,
|
|
128
|
-
severity:
|
|
126
|
+
severity: 'error',
|
|
129
127
|
});
|
|
130
128
|
}
|
|
131
129
|
continue;
|
|
@@ -135,28 +133,41 @@ export async function validateProject(config, opts = {}) {
|
|
|
135
133
|
// and record.slug must agree; mismatch is itself a warning.
|
|
136
134
|
if (parsed.slug !== fileSlug) {
|
|
137
135
|
warnings.push({
|
|
138
|
-
code:
|
|
136
|
+
code: 'slug_mismatch',
|
|
139
137
|
message: `${fileSlug}: record slug "${parsed.slug}" does not match filename`,
|
|
140
|
-
severity:
|
|
138
|
+
severity: 'warning',
|
|
141
139
|
});
|
|
142
140
|
}
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
// A record with no `addedAt` still builds — `recordAddedAt` falls
|
|
142
|
+
// back — but it can never sort correctly in `recently-added`, and
|
|
143
|
+
// nothing else in the pipeline will ever fill the field in. Say so
|
|
144
|
+
// once, at the point the record is read.
|
|
145
|
+
if (!parsed.addedAt) {
|
|
146
|
+
warnings.push({
|
|
147
|
+
code: 'missing_added_at',
|
|
148
|
+
message: `${fileSlug}: no addedAt — the recently-added sort will fall back to the review or repo date`,
|
|
149
|
+
severity: 'warning',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
warnUnknownTaxonomy(fileSlug, 'category', parsed.category, taxonomy.categories, 'categories.yml');
|
|
153
|
+
if (parsed.kind === 'project') {
|
|
145
154
|
// `stack` is the canonical browse taxonomy. `stacks` contains
|
|
146
155
|
// supporting technologies and is intentionally open-ended.
|
|
147
156
|
if (parsed.stack) {
|
|
148
|
-
warnUnknownTaxonomy(fileSlug,
|
|
157
|
+
warnUnknownTaxonomy(fileSlug, 'stack', parsed.stack, taxonomy.stacks, 'stacks.yml');
|
|
149
158
|
}
|
|
150
159
|
for (const platform of parsed.platforms) {
|
|
151
|
-
warnUnknownTaxonomy(fileSlug,
|
|
160
|
+
warnUnknownTaxonomy(fileSlug, 'platform', platform, taxonomy.platforms, 'platforms.yml');
|
|
152
161
|
}
|
|
153
162
|
}
|
|
154
|
-
// Records that link to a GitHub repo need a
|
|
155
|
-
//
|
|
156
|
-
//
|
|
163
|
+
// Records that link to a GitHub repo need a health entry — either
|
|
164
|
+
// inline on the record itself (what `sync github` now writes) or,
|
|
165
|
+
// for records synced before that change, in health.yml — so
|
|
166
|
+
// list/detail UIs can render staleness signals.
|
|
157
167
|
const repoUrl = parsed.repoUrl;
|
|
158
168
|
const linksGithub = parsed.links?.github;
|
|
159
|
-
|
|
169
|
+
const hasInlineHealth = parsed.kind === 'project' && Boolean(parsed.health);
|
|
170
|
+
if ((repoUrl || linksGithub) && !hasInlineHealth) {
|
|
160
171
|
slugsNeedingHealth.add(fileSlug);
|
|
161
172
|
}
|
|
162
173
|
}
|
|
@@ -167,9 +178,9 @@ export async function validateProject(config, opts = {}) {
|
|
|
167
178
|
}
|
|
168
179
|
catch (err) {
|
|
169
180
|
errors.push({
|
|
170
|
-
code:
|
|
181
|
+
code: 'health_file_invalid',
|
|
171
182
|
message: `${config.paths.health}: ${err.message}`,
|
|
172
|
-
severity:
|
|
183
|
+
severity: 'error',
|
|
173
184
|
});
|
|
174
185
|
}
|
|
175
186
|
const healthIds = new Set(health.map((entry) => entry.id));
|
|
@@ -177,9 +188,9 @@ export async function validateProject(config, opts = {}) {
|
|
|
177
188
|
if (healthIds.has(slug))
|
|
178
189
|
continue;
|
|
179
190
|
errors.push({
|
|
180
|
-
code:
|
|
191
|
+
code: 'missing_health',
|
|
181
192
|
message: `${slug} has a GitHub link but no health entry`,
|
|
182
|
-
severity:
|
|
193
|
+
severity: 'error',
|
|
183
194
|
});
|
|
184
195
|
}
|
|
185
196
|
}
|
|
@@ -188,9 +199,9 @@ export async function validateProject(config, opts = {}) {
|
|
|
188
199
|
// repo we expect a health file to exist (or `sync github` to
|
|
189
200
|
// produce one). Flag it as a warning so the operator knows.
|
|
190
201
|
warnings.push({
|
|
191
|
-
code:
|
|
202
|
+
code: 'missing_health_file',
|
|
192
203
|
message: `${config.paths.health} is missing but ${slugsNeedingHealth.size} record(s) link to GitHub repos`,
|
|
193
|
-
severity:
|
|
204
|
+
severity: 'warning',
|
|
194
205
|
});
|
|
195
206
|
}
|
|
196
207
|
if (await exists(resolve(process.cwd(), config.paths.decisions))) {
|
|
@@ -200,17 +211,17 @@ export async function validateProject(config, opts = {}) {
|
|
|
200
211
|
}
|
|
201
212
|
catch (err) {
|
|
202
213
|
errors.push({
|
|
203
|
-
code:
|
|
214
|
+
code: 'decisions_file_invalid',
|
|
204
215
|
message: `${config.paths.decisions}: ${err.message}`,
|
|
205
|
-
severity:
|
|
216
|
+
severity: 'error',
|
|
206
217
|
});
|
|
207
218
|
}
|
|
208
219
|
for (const decision of decisions) {
|
|
209
220
|
if (!slugs.has(decision.id)) {
|
|
210
221
|
errors.push({
|
|
211
|
-
code:
|
|
222
|
+
code: 'unknown_decision_record',
|
|
212
223
|
message: `Decision references unknown record: ${decision.id}`,
|
|
213
|
-
severity:
|
|
224
|
+
severity: 'error',
|
|
214
225
|
});
|
|
215
226
|
}
|
|
216
227
|
}
|
|
@@ -242,21 +253,21 @@ function finalize(errors, warnings, strict = false) {
|
|
|
242
253
|
* surface for surfacing failures with full error reporting.
|
|
243
254
|
*/
|
|
244
255
|
export async function loadRecords(config, opts = {}) {
|
|
245
|
-
const onError = opts.onError ??
|
|
256
|
+
const onError = opts.onError ?? 'skip';
|
|
246
257
|
const cwd = opts.cwd ?? process.cwd();
|
|
247
258
|
const recordsDir = resolve(cwd, config.paths.recordsDir);
|
|
248
259
|
const entries = await readdir(recordsDir).catch(() => []);
|
|
249
|
-
const files = entries.filter((f) => f.endsWith(
|
|
260
|
+
const files = entries.filter((f) => f.endsWith('.yml')).sort();
|
|
250
261
|
const expectedKind = blueprintKind[config.blueprint];
|
|
251
262
|
const out = [];
|
|
252
263
|
for (const file of files) {
|
|
253
|
-
const fileSlug = basename(file,
|
|
254
|
-
const text = await readFile(join(recordsDir, file),
|
|
264
|
+
const fileSlug = basename(file, '.yml');
|
|
265
|
+
const text = await readFile(join(recordsDir, file), 'utf8');
|
|
255
266
|
// `schema: 'core'` disables custom-tag interpretation. Same
|
|
256
267
|
// rationale as the `readRecords` block above.
|
|
257
|
-
const raw = parseYaml(text, { schema:
|
|
258
|
-
if (!raw || typeof raw !==
|
|
259
|
-
if (onError ===
|
|
268
|
+
const raw = parseYaml(text, { schema: 'core' });
|
|
269
|
+
if (!raw || typeof raw !== 'object') {
|
|
270
|
+
if (onError === 'throw') {
|
|
260
271
|
throw new Error(`${fileSlug}: record file is empty or not a YAML mapping`);
|
|
261
272
|
}
|
|
262
273
|
continue;
|
|
@@ -269,7 +280,7 @@ export async function loadRecords(config, opts = {}) {
|
|
|
269
280
|
out.push(parsed);
|
|
270
281
|
}
|
|
271
282
|
catch (err) {
|
|
272
|
-
if (onError ===
|
|
283
|
+
if (onError === 'throw')
|
|
273
284
|
throw err;
|
|
274
285
|
// skip — validation should have caught this
|
|
275
286
|
}
|
|
@@ -283,6 +294,6 @@ export async function loadRecords(config, opts = {}) {
|
|
|
283
294
|
* helper for previews and dev-time inspection.
|
|
284
295
|
*/
|
|
285
296
|
export function loadRecordsOrThrow(config, opts = {}) {
|
|
286
|
-
return loadRecords(config, { ...opts, onError:
|
|
297
|
+
return loadRecords(config, { ...opts, onError: 'throw' });
|
|
287
298
|
}
|
|
288
299
|
//# sourceMappingURL=validate.js.map
|
package/dist/validate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,mBAAmB,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/yaml.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure YAML string helpers used by the submit form (and any future
|
|
3
|
+
* surface that emits record YAML for hand-curated directories).
|
|
4
|
+
*
|
|
5
|
+
* The pre-v1 implementation lived inline inside
|
|
6
|
+
* `packages/astro/src/components/SubmissionClient.astro` (lines
|
|
7
|
+
* 64–73, 92–124). That broke §11 of `apps/docs/v1-architecture.md`:
|
|
8
|
+
* UI files must not contain serialization logic. This module is
|
|
9
|
+
* the canonical home.
|
|
10
|
+
*
|
|
11
|
+
* The helpers are deliberately tiny and dependency-free so they
|
|
12
|
+
* can run in both Node (during `grove submit` builds) and the
|
|
13
|
+
* browser (the live form's preview).
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Convert any input to a URL-safe, hyphen-separated slug.
|
|
17
|
+
*
|
|
18
|
+
* Returns the empty string for falsy input. Mirrors the inline
|
|
19
|
+
* behavior that shipped in v0.7 so existing form submissions stay
|
|
20
|
+
* byte-identical.
|
|
21
|
+
*/
|
|
22
|
+
export declare function recordSlugify(value: unknown): string;
|
|
23
|
+
/**
|
|
24
|
+
* Parse a GitHub repository URL into `{ owner, repo }`. Returns
|
|
25
|
+
* null if the input is not a recognized GitHub URL. The `.git`
|
|
26
|
+
* suffix is stripped so callers can compare against canonical
|
|
27
|
+
* GitHub names without a normalization step.
|
|
28
|
+
*/
|
|
29
|
+
export interface ParsedRepo {
|
|
30
|
+
owner: string;
|
|
31
|
+
repo: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function parseGithubRepo(value: unknown): ParsedRepo | null;
|
|
34
|
+
/**
|
|
35
|
+
* Quote a value for safe inclusion inside a YAML double-quoted
|
|
36
|
+
* scalar. Escapes backslashes and double quotes; leaves the rest
|
|
37
|
+
* alone. Matches the v0.7 inline behavior; if the value contains
|
|
38
|
+
* a newline the YAML consumer must use folded/block style instead.
|
|
39
|
+
*/
|
|
40
|
+
export declare function yamlQuote(value: unknown): string;
|
|
41
|
+
/**
|
|
42
|
+
* Render a YAML block sequence with a given indent. Produces
|
|
43
|
+
* `- a\n- b\n…` for the given input array. Empty arrays produce
|
|
44
|
+
* an empty string so the caller can choose to emit `[]` instead.
|
|
45
|
+
*/
|
|
46
|
+
export declare function yamlLines(values: readonly string[], indent?: number): string;
|
|
47
|
+
//# sourceMappingURL=yaml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AAEH;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKpD;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAMjE;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,SAAI,GAAG,MAAM,CAEvE"}
|
package/dist/yaml.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
/**
|
|
3
|
+
* Pure YAML string helpers used by the submit form (and any future
|
|
4
|
+
* surface that emits record YAML for hand-curated directories).
|
|
5
|
+
*
|
|
6
|
+
* The pre-v1 implementation lived inline inside
|
|
7
|
+
* `packages/astro/src/components/SubmissionClient.astro` (lines
|
|
8
|
+
* 64–73, 92–124). That broke §11 of `apps/docs/v1-architecture.md`:
|
|
9
|
+
* UI files must not contain serialization logic. This module is
|
|
10
|
+
* the canonical home.
|
|
11
|
+
*
|
|
12
|
+
* The helpers are deliberately tiny and dependency-free so they
|
|
13
|
+
* can run in both Node (during `grove submit` builds) and the
|
|
14
|
+
* browser (the live form's preview).
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Convert any input to a URL-safe, hyphen-separated slug.
|
|
18
|
+
*
|
|
19
|
+
* Returns the empty string for falsy input. Mirrors the inline
|
|
20
|
+
* behavior that shipped in v0.7 so existing form submissions stay
|
|
21
|
+
* byte-identical.
|
|
22
|
+
*/
|
|
23
|
+
export function recordSlugify(value) {
|
|
24
|
+
return String(value || '')
|
|
25
|
+
.toLowerCase()
|
|
26
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
27
|
+
.replace(/^-+|-+$/g, '');
|
|
28
|
+
}
|
|
29
|
+
export function parseGithubRepo(value) {
|
|
30
|
+
const match = String(value ?? '').match(/github\.com\/([^/]+)\/([^/?#]+)/);
|
|
31
|
+
if (!match)
|
|
32
|
+
return null;
|
|
33
|
+
const owner = match[1] ?? '';
|
|
34
|
+
const repo = (match[2] ?? '').replace(/\.git$/, '');
|
|
35
|
+
return { owner, repo };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Quote a value for safe inclusion inside a YAML double-quoted
|
|
39
|
+
* scalar. Escapes backslashes and double quotes; leaves the rest
|
|
40
|
+
* alone. Matches the v0.7 inline behavior; if the value contains
|
|
41
|
+
* a newline the YAML consumer must use folded/block style instead.
|
|
42
|
+
*/
|
|
43
|
+
export function yamlQuote(value) {
|
|
44
|
+
return `"${String(value ?? '')
|
|
45
|
+
.replace(/\\/g, '\\\\')
|
|
46
|
+
.replace(/"/g, '\\"')}"`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Render a YAML block sequence with a given indent. Produces
|
|
50
|
+
* `- a\n- b\n…` for the given input array. Empty arrays produce
|
|
51
|
+
* an empty string so the caller can choose to emit `[]` instead.
|
|
52
|
+
*/
|
|
53
|
+
export function yamlLines(values, indent = 2) {
|
|
54
|
+
return values.map((value) => `${' '.repeat(indent)}- ${value}`).join('\n');
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=yaml.js.map
|
package/dist/yaml.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.js","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B;;;;;;;;;;;;;GAaG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SACvB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAaD,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC3E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACpD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,IAAI,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,MAAyB,EAAE,MAAM,GAAG,CAAC;IAC7D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grove-dev/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Headless engine for Grove: resource schema, config, importers, validators, taxonomy, sitemap, llms.txt, and the data build pipeline.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,10 +48,15 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@resvg/resvg-js": "^2.6.2",
|
|
50
50
|
"jiti": "^2.6.1",
|
|
51
|
+
"mdast-util-from-markdown": "^2.0.3",
|
|
51
52
|
"satori": "^0.29.0",
|
|
53
|
+
"unist-util-visit": "^5.1.0",
|
|
52
54
|
"yaml": "^2.9.0",
|
|
53
55
|
"zod": "^4.4.3"
|
|
54
56
|
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/mdast": "^4.0.4"
|
|
59
|
+
},
|
|
55
60
|
"scripts": {
|
|
56
61
|
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
|
|
57
62
|
"check": "tsc -p tsconfig.json --noEmit",
|