@grove-dev/core 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/README.md +89 -0
- package/dist/build-data.d.ts +55 -0
- package/dist/build-data.d.ts.map +1 -0
- package/dist/build-data.js +115 -0
- package/dist/build-data.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +14 -0
- package/dist/config.js.map +1 -0
- package/dist/decisions.d.ts +28 -0
- package/dist/decisions.d.ts.map +1 -0
- package/dist/decisions.js +57 -0
- package/dist/decisions.js.map +1 -0
- package/dist/enrich.d.ts +26 -0
- package/dist/enrich.d.ts.map +1 -0
- package/dist/enrich.js +121 -0
- package/dist/enrich.js.map +1 -0
- package/dist/github-client.d.ts +28 -0
- package/dist/github-client.d.ts.map +1 -0
- package/dist/github-client.js +91 -0
- package/dist/github-client.js.map +1 -0
- package/dist/github.d.ts +8 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +62 -0
- package/dist/github.js.map +1 -0
- package/dist/health.d.ts +3 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +103 -0
- package/dist/health.js.map +1 -0
- package/dist/importer.d.ts +3 -0
- package/dist/importer.d.ts.map +1 -0
- package/dist/importer.js +24 -0
- package/dist/importer.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/io.d.ts +4 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +21 -0
- package/dist/io.js.map +1 -0
- package/dist/llms.d.ts +34 -0
- package/dist/llms.d.ts.map +1 -0
- package/dist/llms.js +99 -0
- package/dist/llms.js.map +1 -0
- package/dist/markdown.d.ts +18 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +182 -0
- package/dist/markdown.js.map +1 -0
- package/dist/parseReadme.d.ts +25 -0
- package/dist/parseReadme.d.ts.map +1 -0
- package/dist/parseReadme.js +100 -0
- package/dist/parseReadme.js.map +1 -0
- package/dist/schema.d.ts +988 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +729 -0
- package/dist/schema.js.map +1 -0
- package/dist/sitemap.d.ts +38 -0
- package/dist/sitemap.d.ts.map +1 -0
- package/dist/sitemap.js +73 -0
- package/dist/sitemap.js.map +1 -0
- package/dist/slug.d.ts +3 -0
- package/dist/slug.d.ts.map +1 -0
- package/dist/slug.js +15 -0
- package/dist/slug.js.map +1 -0
- package/dist/validate.d.ts +11 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +58 -0
- package/dist/validate.js.map +1 -0
- package/package.json +50 -0
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { uniqueSlug } from "./slug.js";
|
|
2
|
+
const markdownLinkPattern = /\[([^\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
|
|
3
|
+
const TOC_TITLES = new Set([
|
|
4
|
+
"contents",
|
|
5
|
+
"table of contents",
|
|
6
|
+
"contributing",
|
|
7
|
+
"contribution",
|
|
8
|
+
"license",
|
|
9
|
+
"contributors",
|
|
10
|
+
]);
|
|
11
|
+
function stripAnchor(name) {
|
|
12
|
+
return name
|
|
13
|
+
.replace(/<a\s+name="[^"]+"><\/a>/gi, "")
|
|
14
|
+
.replace(/🔗/g, "")
|
|
15
|
+
.replace(/🚀|🎨|📐|👨💻|🤖|🖥️|💬|🗣️|🔑|👤|🗄️|📊|💻|🔒|🧮|📟|🎓|🛒|🌳|📂|💰|🎮|🏠|🧠|⚖️|🗺️|🎯|📋|🏠|🔬|🔎|🌐|🔮|🏃|🎧|🌎|🎙️|🚆|🔄|🏢|🛠️/g, "")
|
|
16
|
+
.replace(/\s+/g, " ")
|
|
17
|
+
.trim();
|
|
18
|
+
}
|
|
19
|
+
export function detectGithubRepo(url) {
|
|
20
|
+
const match = url.match(/^https?:\/\/github\.com\/([^/\s]+)\/([^/#?\s]+)(?:[/?#].*)?$/i);
|
|
21
|
+
if (!match)
|
|
22
|
+
return undefined;
|
|
23
|
+
const repo = match[2].replace(/\.git$/, "");
|
|
24
|
+
if (!repo || ["issues", "pulls", "stargazers", "network"].includes(repo))
|
|
25
|
+
return undefined;
|
|
26
|
+
return `https://github.com/${match[1]}/${repo}`;
|
|
27
|
+
}
|
|
28
|
+
function isAnchorLink(url) {
|
|
29
|
+
return url.startsWith("#") || url.startsWith("./#") || url.startsWith("../#");
|
|
30
|
+
}
|
|
31
|
+
function isExternalUrl(url) {
|
|
32
|
+
return /^https?:\/\//.test(url) || /^[a-z][a-z0-9+.-]*:/i.test(url);
|
|
33
|
+
}
|
|
34
|
+
function extractDescription(body) {
|
|
35
|
+
return body
|
|
36
|
+
.replace(markdownLinkPattern, "")
|
|
37
|
+
.trim()
|
|
38
|
+
.replace(/^[-:—–]\s*/, "")
|
|
39
|
+
.replace(/\s+/g, " ")
|
|
40
|
+
.trim();
|
|
41
|
+
}
|
|
42
|
+
function headingDepth(line) {
|
|
43
|
+
const match = line.match(/^(#{2,6})\s+(.+?)\s*$/);
|
|
44
|
+
return match?.[1]?.length;
|
|
45
|
+
}
|
|
46
|
+
function headingText(line) {
|
|
47
|
+
return stripAnchor(line.match(/^#{2,6}\s+(.+?)\s*$/)?.[1]?.trim() ?? "");
|
|
48
|
+
}
|
|
49
|
+
export function parseAwesomeMarkdown(text, options = {}) {
|
|
50
|
+
const lines = text.split(/\r?\n/);
|
|
51
|
+
const seen = new Map();
|
|
52
|
+
const categories = new Set();
|
|
53
|
+
const items = [];
|
|
54
|
+
let currentCategory = "uncategorized";
|
|
55
|
+
let categoryDepth = 2;
|
|
56
|
+
let skipped = 0;
|
|
57
|
+
let duplicateSlugs = 0;
|
|
58
|
+
let tocSkipped = 0;
|
|
59
|
+
let anchorLinksSkipped = 0;
|
|
60
|
+
let inTocBlock = false;
|
|
61
|
+
let consecutiveBlankLines = 0;
|
|
62
|
+
for (let index = 0; index < lines.length; index++) {
|
|
63
|
+
const line = lines[index] ?? "";
|
|
64
|
+
const depth = headingDepth(line);
|
|
65
|
+
if (depth) {
|
|
66
|
+
const title = headingText(line) ?? "";
|
|
67
|
+
inTocBlock = TOC_TITLES.has(title.toLowerCase());
|
|
68
|
+
if (title && !inTocBlock) {
|
|
69
|
+
currentCategory = title;
|
|
70
|
+
categoryDepth = depth;
|
|
71
|
+
categories.add(currentCategory);
|
|
72
|
+
}
|
|
73
|
+
consecutiveBlankLines = 0;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (inTocBlock) {
|
|
77
|
+
// TOC blocks: skip list items entirely. Exit when we see a non-list, non-blank line.
|
|
78
|
+
if (!line.trim()) {
|
|
79
|
+
consecutiveBlankLines++;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (/^\s*[-*+]\s+/.test(line) || /^\s*\d+\.\s+/.test(line)) {
|
|
83
|
+
tocSkipped++;
|
|
84
|
+
consecutiveBlankLines = 0;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
// First non-list, non-blank line ends the TOC block.
|
|
88
|
+
inTocBlock = false;
|
|
89
|
+
}
|
|
90
|
+
if (!/^\s*[-*+]\s+/.test(line)) {
|
|
91
|
+
consecutiveBlankLines = line.trim() ? 0 : consecutiveBlankLines + 1;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
consecutiveBlankLines = 0;
|
|
95
|
+
const body = line.replace(/^\s*[-*+]\s+/, "").trim();
|
|
96
|
+
const parsedLinks = [...body.matchAll(markdownLinkPattern)].map((match) => ({
|
|
97
|
+
label: match[1].trim(),
|
|
98
|
+
url: match[2].trim(),
|
|
99
|
+
}));
|
|
100
|
+
if (parsedLinks.length === 0) {
|
|
101
|
+
skipped++;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Filter out items whose primary link is an in-page anchor (TOC-style leftover).
|
|
105
|
+
const primary = parsedLinks[0];
|
|
106
|
+
if (!primary) {
|
|
107
|
+
skipped++;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (isAnchorLink(primary.url)) {
|
|
111
|
+
anchorLinksSkipped++;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
// Only keep items that have at least one external URL (HTTP/HTTPS or protocol-relative).
|
|
115
|
+
// Project directories need a real link, not just text + bare words.
|
|
116
|
+
const hasExternal = parsedLinks.some((link) => isExternalUrl(link.url) && !isAnchorLink(link.url));
|
|
117
|
+
if (!hasExternal) {
|
|
118
|
+
skipped++;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Prefer the first external link as the primary, ignoring any leading anchor links.
|
|
122
|
+
const primaryExternal = parsedLinks.find((link) => isExternalUrl(link.url) && !isAnchorLink(link.url));
|
|
123
|
+
if (!primaryExternal) {
|
|
124
|
+
skipped++;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const github = parsedLinks.map((link) => detectGithubRepo(link.url)).find(Boolean);
|
|
128
|
+
const id = uniqueSlug(primaryExternal.label, seen);
|
|
129
|
+
if (id !==
|
|
130
|
+
(primaryExternal.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "item")) {
|
|
131
|
+
duplicateSlugs++;
|
|
132
|
+
}
|
|
133
|
+
const description = extractDescription(body);
|
|
134
|
+
const links = {
|
|
135
|
+
...(github ? { github } : {}),
|
|
136
|
+
...(!github ? { website: primaryExternal.url } : {}),
|
|
137
|
+
...(options.sourceUrl ? { source: options.sourceUrl } : {}),
|
|
138
|
+
};
|
|
139
|
+
items.push({
|
|
140
|
+
id,
|
|
141
|
+
name: primaryExternal.label,
|
|
142
|
+
description: description || primaryExternal.label,
|
|
143
|
+
links,
|
|
144
|
+
source: {
|
|
145
|
+
type: "markdown",
|
|
146
|
+
file: options.file,
|
|
147
|
+
line: index + 1,
|
|
148
|
+
url: options.sourceUrl,
|
|
149
|
+
},
|
|
150
|
+
taxonomy: {
|
|
151
|
+
category: currentCategory,
|
|
152
|
+
tags: [],
|
|
153
|
+
stacks: [],
|
|
154
|
+
platforms: [],
|
|
155
|
+
},
|
|
156
|
+
labels: [],
|
|
157
|
+
lenses: [],
|
|
158
|
+
distribution: {
|
|
159
|
+
channels: [],
|
|
160
|
+
},
|
|
161
|
+
curation: {
|
|
162
|
+
bestFor: [],
|
|
163
|
+
whyListed: [],
|
|
164
|
+
caveats: [],
|
|
165
|
+
launchAsk: [],
|
|
166
|
+
scores: {},
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
items,
|
|
172
|
+
report: {
|
|
173
|
+
imported: items.length,
|
|
174
|
+
skipped,
|
|
175
|
+
categories: [...categories].filter((c) => c && c !== "uncategorized"),
|
|
176
|
+
duplicateSlugs,
|
|
177
|
+
tocSkipped,
|
|
178
|
+
anchorLinksSkipped,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a legacy awesome-list README into structured entries.
|
|
3
|
+
*
|
|
4
|
+
* Legacy format: `- [Name](repoUrl) - description` (or em-dash),
|
|
5
|
+
* grouped under `### Category` headings. Used by `grove import`
|
|
6
|
+
* when the source is a flat awesome list rather than a schema-v1
|
|
7
|
+
* per-app directory.
|
|
8
|
+
*/
|
|
9
|
+
export interface ParsedEntry {
|
|
10
|
+
name: string;
|
|
11
|
+
repoUrl: string;
|
|
12
|
+
description: string;
|
|
13
|
+
author: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse one `- [Name](repoUrl) - desc` line.
|
|
17
|
+
* Returns null on miss (no link, non-github URL, etc).
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseEntry(line: string): ParsedEntry | null;
|
|
20
|
+
export interface ParsedSection {
|
|
21
|
+
category: string;
|
|
22
|
+
lines: string[];
|
|
23
|
+
}
|
|
24
|
+
export declare function parseSections(text: string): ParsedSection[];
|
|
25
|
+
//# sourceMappingURL=parseReadme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseReadme.d.ts","sourceRoot":"","sources":["../src/parseReadme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAcD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CA0D3D;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAgB3D"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a legacy awesome-list README into structured entries.
|
|
3
|
+
*
|
|
4
|
+
* Legacy format: `- [Name](repoUrl) - description` (or em-dash),
|
|
5
|
+
* grouped under `### Category` headings. Used by `grove import`
|
|
6
|
+
* when the source is a flat awesome list rather than a schema-v1
|
|
7
|
+
* per-app directory.
|
|
8
|
+
*/
|
|
9
|
+
const markdownLinkRe = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
10
|
+
function extractLinks(text) {
|
|
11
|
+
const out = [];
|
|
12
|
+
let m;
|
|
13
|
+
markdownLinkRe.lastIndex = 0;
|
|
14
|
+
while ((m = markdownLinkRe.exec(text)) !== null) {
|
|
15
|
+
out.push({ label: m[1], href: m[2] });
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse one `- [Name](repoUrl) - desc` line.
|
|
21
|
+
* Returns null on miss (no link, non-github URL, etc).
|
|
22
|
+
*/
|
|
23
|
+
export function parseEntry(line) {
|
|
24
|
+
const body = line.replace(/^\s*-\s+/, "").trim();
|
|
25
|
+
if (!body)
|
|
26
|
+
return null;
|
|
27
|
+
const links = extractLinks(body);
|
|
28
|
+
if (links.length === 0)
|
|
29
|
+
return null;
|
|
30
|
+
const app = links[0];
|
|
31
|
+
if (!app)
|
|
32
|
+
return null;
|
|
33
|
+
if (!/^https?:\/\/(github|gitlab)\.com\//i.test(app.href))
|
|
34
|
+
return null;
|
|
35
|
+
let afterApp = body
|
|
36
|
+
.replace(/^\s*\[[^\]]+\]\([^)]+\)\s*/, "")
|
|
37
|
+
.replace(/^[-—–]\s*/, "")
|
|
38
|
+
.trim();
|
|
39
|
+
while (/\s*\([^)]*\)\s*$/.test(afterApp)) {
|
|
40
|
+
let depth = 0;
|
|
41
|
+
let i = afterApp.length;
|
|
42
|
+
for (; i > 0; i--) {
|
|
43
|
+
const c = afterApp[i - 1];
|
|
44
|
+
if (c === ")")
|
|
45
|
+
depth++;
|
|
46
|
+
else if (c === "(") {
|
|
47
|
+
depth--;
|
|
48
|
+
if (depth === 0)
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (i <= 0)
|
|
53
|
+
break;
|
|
54
|
+
afterApp = afterApp.slice(0, i).trim();
|
|
55
|
+
}
|
|
56
|
+
let description = afterApp;
|
|
57
|
+
let author = null;
|
|
58
|
+
const byLinkIdx = afterApp.lastIndexOf(" by [");
|
|
59
|
+
if (byLinkIdx >= 0) {
|
|
60
|
+
description = afterApp.slice(0, byLinkIdx).trim();
|
|
61
|
+
const close = afterApp.indexOf("]", byLinkIdx);
|
|
62
|
+
if (close > 0) {
|
|
63
|
+
author = afterApp.slice(byLinkIdx + 5, close).trim();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const byPlain = afterApp.match(/^(.*?)\s+by\s+([A-Z][\w .'-]+?)\s*$/);
|
|
68
|
+
if (byPlain && byPlain[1] && byPlain[2]) {
|
|
69
|
+
description = byPlain[1].trim();
|
|
70
|
+
author = byPlain[2].trim();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
description = description.replace(/[.\s]+$/, "").trim();
|
|
74
|
+
if (!description)
|
|
75
|
+
description = app.label;
|
|
76
|
+
return {
|
|
77
|
+
name: app.label,
|
|
78
|
+
repoUrl: app.href,
|
|
79
|
+
description,
|
|
80
|
+
author,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export function parseSections(text) {
|
|
84
|
+
const lines = text.split(/\r?\n/);
|
|
85
|
+
const out = [];
|
|
86
|
+
let current = null;
|
|
87
|
+
for (const line of lines) {
|
|
88
|
+
const m = line.match(/^###\s+(.+?)\s*$/);
|
|
89
|
+
if (m && m[1]) {
|
|
90
|
+
current = { category: m[1].trim(), lines: [] };
|
|
91
|
+
out.push(current);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (current && /^\s*-\s/.test(line)) {
|
|
95
|
+
current.lines.push(line);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=parseReadme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseReadme.js","sourceRoot":"","sources":["../src/parseReadme.ts"],"names":[],"mappings":"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"}
|