@ox-content/vite-plugin 0.0.1-alpha.0 → 0.3.0-alpha.11

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/chunk.cjs ADDED
@@ -0,0 +1,74 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
9
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
10
+ var __exportAll = (all, symbols) => {
11
+ let target = {};
12
+ for (var name in all) {
13
+ __defProp(target, name, {
14
+ get: all[name],
15
+ enumerable: true
16
+ });
17
+ }
18
+ if (symbols) {
19
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
20
+ }
21
+ return target;
22
+ };
23
+ var __copyProps = (to, from, except, desc) => {
24
+ if (from && typeof from === "object" || typeof from === "function") {
25
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
26
+ key = keys[i];
27
+ if (!__hasOwnProp.call(to, key) && key !== except) {
28
+ __defProp(to, key, {
29
+ get: ((k) => from[k]).bind(null, key),
30
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
31
+ });
32
+ }
33
+ }
34
+ }
35
+ return to;
36
+ };
37
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
38
+ value: mod,
39
+ enumerable: true
40
+ }) : target, mod));
41
+ var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
42
+
43
+ //#endregion
44
+
45
+ Object.defineProperty(exports, '__commonJSMin', {
46
+ enumerable: true,
47
+ get: function () {
48
+ return __commonJSMin;
49
+ }
50
+ });
51
+ Object.defineProperty(exports, '__esmMin', {
52
+ enumerable: true,
53
+ get: function () {
54
+ return __esmMin;
55
+ }
56
+ });
57
+ Object.defineProperty(exports, '__exportAll', {
58
+ enumerable: true,
59
+ get: function () {
60
+ return __exportAll;
61
+ }
62
+ });
63
+ Object.defineProperty(exports, '__toCommonJS', {
64
+ enumerable: true,
65
+ get: function () {
66
+ return __toCommonJS;
67
+ }
68
+ });
69
+ Object.defineProperty(exports, '__toESM', {
70
+ enumerable: true,
71
+ get: function () {
72
+ return __toESM;
73
+ }
74
+ });
@@ -0,0 +1,4 @@
1
+ const require_chunk = require('./chunk.cjs');
2
+ const require_github = require('./github2.cjs');
3
+
4
+ exports.transformGitHub = require_github.transformGitHub;
package/dist/github.js ADDED
@@ -0,0 +1,3 @@
1
+ import { i as transformGitHub, n as fetchRepoData, r as prefetchGitHubRepos, t as collectGitHubRepos } from "./github2.js";
2
+
3
+ export { transformGitHub };
@@ -0,0 +1,313 @@
1
+ const require_chunk = require('./chunk.cjs');
2
+ let unified = require("unified");
3
+ let rehype_parse = require("rehype-parse");
4
+ rehype_parse = require_chunk.__toESM(rehype_parse);
5
+ let rehype_stringify = require("rehype-stringify");
6
+ rehype_stringify = require_chunk.__toESM(rehype_stringify);
7
+
8
+ //#region src/plugins/github.ts
9
+ /**
10
+ * GitHub Plugin - Repository card embedding
11
+ *
12
+ * Transforms <GitHub> components into static repository cards
13
+ * by fetching data from GitHub API at build time.
14
+ */
15
+ const defaultOptions = {
16
+ token: "",
17
+ cache: true,
18
+ cacheTTL: 36e5
19
+ };
20
+ const repoCache = /* @__PURE__ */ new Map();
21
+ /**
22
+ * Get element attribute value.
23
+ */
24
+ function getAttribute(el, name) {
25
+ const value = el.properties?.[name];
26
+ if (typeof value === "string") return value;
27
+ if (Array.isArray(value)) return value.join(" ");
28
+ }
29
+ /**
30
+ * Format number with K/M suffix.
31
+ */
32
+ function formatNumber(num) {
33
+ if (num >= 1e6) return `${(num / 1e6).toFixed(1)}M`;
34
+ if (num >= 1e3) return `${(num / 1e3).toFixed(1)}k`;
35
+ return String(num);
36
+ }
37
+ /**
38
+ * Fetch repository data from GitHub API.
39
+ */
40
+ async function fetchRepoData(repo, options) {
41
+ if (options.cache) {
42
+ const cached = repoCache.get(repo);
43
+ if (cached && Date.now() - cached.timestamp < options.cacheTTL) return cached.data;
44
+ }
45
+ try {
46
+ const headers = {
47
+ Accept: "application/vnd.github.v3+json",
48
+ "User-Agent": "ox-content-github-plugin"
49
+ };
50
+ if (options.token) headers.Authorization = `Bearer ${options.token}`;
51
+ const response = await fetch(`https://api.github.com/repos/${repo}`, { headers });
52
+ if (!response.ok) {
53
+ console.warn(`Failed to fetch GitHub repo ${repo}: ${response.status}`);
54
+ return null;
55
+ }
56
+ const data = await response.json();
57
+ if (options.cache) repoCache.set(repo, {
58
+ data,
59
+ timestamp: Date.now()
60
+ });
61
+ return data;
62
+ } catch (error) {
63
+ console.warn(`Error fetching GitHub repo ${repo}:`, error);
64
+ return null;
65
+ }
66
+ }
67
+ /**
68
+ * Create GitHub card element from repo data.
69
+ */
70
+ function createGitHubCard(repoData) {
71
+ const statsChildren = [];
72
+ if (repoData.language) statsChildren.push({
73
+ type: "element",
74
+ tagName: "span",
75
+ properties: { className: ["ox-github-language"] },
76
+ children: [{
77
+ type: "element",
78
+ tagName: "span",
79
+ properties: {
80
+ className: ["ox-github-language-color"],
81
+ "data-lang": repoData.language.toLowerCase()
82
+ },
83
+ children: []
84
+ }, {
85
+ type: "text",
86
+ value: repoData.language
87
+ }]
88
+ });
89
+ statsChildren.push({
90
+ type: "element",
91
+ tagName: "span",
92
+ properties: { className: ["ox-github-stat"] },
93
+ children: [{
94
+ type: "element",
95
+ tagName: "svg",
96
+ properties: {
97
+ viewBox: "0 0 16 16",
98
+ fill: "currentColor"
99
+ },
100
+ children: [{
101
+ type: "element",
102
+ tagName: "path",
103
+ properties: { d: "M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z" },
104
+ children: []
105
+ }]
106
+ }, {
107
+ type: "text",
108
+ value: formatNumber(repoData.stargazers_count)
109
+ }]
110
+ });
111
+ statsChildren.push({
112
+ type: "element",
113
+ tagName: "span",
114
+ properties: { className: ["ox-github-stat"] },
115
+ children: [{
116
+ type: "element",
117
+ tagName: "svg",
118
+ properties: {
119
+ viewBox: "0 0 16 16",
120
+ fill: "currentColor"
121
+ },
122
+ children: [{
123
+ type: "element",
124
+ tagName: "path",
125
+ properties: { d: "M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z" },
126
+ children: []
127
+ }]
128
+ }, {
129
+ type: "text",
130
+ value: formatNumber(repoData.forks_count)
131
+ }]
132
+ });
133
+ return {
134
+ type: "element",
135
+ tagName: "a",
136
+ properties: {
137
+ className: ["ox-github-card"],
138
+ href: repoData.html_url,
139
+ target: "_blank",
140
+ rel: "noopener noreferrer"
141
+ },
142
+ children: [
143
+ {
144
+ type: "element",
145
+ tagName: "div",
146
+ properties: { className: ["ox-github-header"] },
147
+ children: [{
148
+ type: "element",
149
+ tagName: "svg",
150
+ properties: {
151
+ className: ["ox-github-icon"],
152
+ viewBox: "0 0 16 16",
153
+ fill: "currentColor"
154
+ },
155
+ children: [{
156
+ type: "element",
157
+ tagName: "path",
158
+ properties: { d: "M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z" },
159
+ children: []
160
+ }]
161
+ }, {
162
+ type: "element",
163
+ tagName: "span",
164
+ properties: { className: ["ox-github-repo"] },
165
+ children: [{
166
+ type: "text",
167
+ value: repoData.full_name
168
+ }]
169
+ }]
170
+ },
171
+ ...repoData.description ? [{
172
+ type: "element",
173
+ tagName: "p",
174
+ properties: { className: ["ox-github-description"] },
175
+ children: [{
176
+ type: "text",
177
+ value: repoData.description
178
+ }]
179
+ }] : [],
180
+ {
181
+ type: "element",
182
+ tagName: "div",
183
+ properties: { className: ["ox-github-stats"] },
184
+ children: statsChildren
185
+ }
186
+ ]
187
+ };
188
+ }
189
+ /**
190
+ * Create fallback element when repo data is unavailable.
191
+ */
192
+ function createFallbackCard(repo) {
193
+ return {
194
+ type: "element",
195
+ tagName: "a",
196
+ properties: {
197
+ className: ["ox-github-card", "error"],
198
+ href: `https://github.com/${repo}`,
199
+ target: "_blank",
200
+ rel: "noopener noreferrer"
201
+ },
202
+ children: [{
203
+ type: "element",
204
+ tagName: "div",
205
+ properties: { className: ["ox-github-header"] },
206
+ children: [{
207
+ type: "element",
208
+ tagName: "svg",
209
+ properties: {
210
+ className: ["ox-github-icon"],
211
+ viewBox: "0 0 16 16",
212
+ fill: "currentColor"
213
+ },
214
+ children: [{
215
+ type: "element",
216
+ tagName: "path",
217
+ properties: { d: "M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z" },
218
+ children: []
219
+ }]
220
+ }, {
221
+ type: "element",
222
+ tagName: "span",
223
+ properties: { className: ["ox-github-repo"] },
224
+ children: [{
225
+ type: "text",
226
+ value: repo
227
+ }]
228
+ }]
229
+ }]
230
+ };
231
+ }
232
+ /**
233
+ * Collect all GitHub repos from HTML for pre-fetching.
234
+ */
235
+ async function collectGitHubRepos(html) {
236
+ const repos = [];
237
+ const repoPattern = /<github[^>]*\s+repo=["']([^"']+)["']/gi;
238
+ let match;
239
+ while ((match = repoPattern.exec(html)) !== null) repos.push(match[1]);
240
+ return repos;
241
+ }
242
+ /**
243
+ * Pre-fetch all GitHub repos data.
244
+ */
245
+ async function prefetchGitHubRepos(repos, options) {
246
+ const mergedOptions = {
247
+ ...defaultOptions,
248
+ ...options
249
+ };
250
+ const results = /* @__PURE__ */ new Map();
251
+ await Promise.all(repos.map(async (repo) => {
252
+ const data = await fetchRepoData(repo, mergedOptions);
253
+ results.set(repo, data);
254
+ }));
255
+ return results;
256
+ }
257
+ /**
258
+ * Rehype plugin to transform GitHub components.
259
+ */
260
+ function rehypeGitHub(repoDataMap) {
261
+ return (tree) => {
262
+ const visit = (node) => {
263
+ if ("children" in node) for (let i = 0; i < node.children.length; i++) {
264
+ const child = node.children[i];
265
+ if (child.type === "element") if (child.tagName.toLowerCase() === "github") {
266
+ const repo = getAttribute(child, "repo");
267
+ if (repo) {
268
+ const repoData = repoDataMap.get(repo);
269
+ const cardElement = repoData ? createGitHubCard(repoData) : createFallbackCard(repo);
270
+ node.children[i] = cardElement;
271
+ }
272
+ } else visit(child);
273
+ }
274
+ };
275
+ visit(tree);
276
+ };
277
+ }
278
+ /**
279
+ * Transform GitHub components in HTML.
280
+ */
281
+ async function transformGitHub(html, repoDataMap, options) {
282
+ let dataMap = repoDataMap;
283
+ if (!dataMap) dataMap = await prefetchGitHubRepos(await collectGitHubRepos(html), options);
284
+ const result = await (0, unified.unified)().use(rehype_parse.default, { fragment: true }).use(rehypeGitHub, dataMap).use(rehype_stringify.default).process(html);
285
+ return String(result);
286
+ }
287
+
288
+ //#endregion
289
+ Object.defineProperty(exports, 'collectGitHubRepos', {
290
+ enumerable: true,
291
+ get: function () {
292
+ return collectGitHubRepos;
293
+ }
294
+ });
295
+ Object.defineProperty(exports, 'fetchRepoData', {
296
+ enumerable: true,
297
+ get: function () {
298
+ return fetchRepoData;
299
+ }
300
+ });
301
+ Object.defineProperty(exports, 'prefetchGitHubRepos', {
302
+ enumerable: true,
303
+ get: function () {
304
+ return prefetchGitHubRepos;
305
+ }
306
+ });
307
+ Object.defineProperty(exports, 'transformGitHub', {
308
+ enumerable: true,
309
+ get: function () {
310
+ return transformGitHub;
311
+ }
312
+ });
313
+ //# sourceMappingURL=github2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github2.cjs","names":["rehypeParse","rehypeStringify"],"sources":["../src/plugins/github.ts"],"sourcesContent":["/**\n * GitHub Plugin - Repository card embedding\n *\n * Transforms <GitHub> components into static repository cards\n * by fetching data from GitHub API at build time.\n */\n\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeStringify from \"rehype-stringify\";\nimport type { Root, Element } from \"hast\";\n\nexport interface GitHubRepoData {\n name: string;\n full_name: string;\n description: string | null;\n html_url: string;\n stargazers_count: number;\n forks_count: number;\n language: string | null;\n owner: {\n login: string;\n avatar_url: string;\n };\n}\n\nexport interface GitHubOptions {\n /** GitHub API token for higher rate limits. */\n token?: string;\n /** Cache fetched data. Default: true */\n cache?: boolean;\n /** Cache TTL in milliseconds. Default: 3600000 (1 hour) */\n cacheTTL?: number;\n}\n\nconst defaultOptions: Required<GitHubOptions> = {\n token: \"\",\n cache: true,\n cacheTTL: 3600000,\n};\n\n// Simple in-memory cache\nconst repoCache = new Map<string, { data: GitHubRepoData; timestamp: number }>();\n\n/**\n * Get element attribute value.\n */\nfunction getAttribute(el: Element, name: string): string | undefined {\n const value = el.properties?.[name];\n if (typeof value === \"string\") return value;\n if (Array.isArray(value)) return value.join(\" \");\n return undefined;\n}\n\n/**\n * Format number with K/M suffix.\n */\nfunction formatNumber(num: number): string {\n if (num >= 1000000) {\n return `${(num / 1000000).toFixed(1)}M`;\n }\n if (num >= 1000) {\n return `${(num / 1000).toFixed(1)}k`;\n }\n return String(num);\n}\n\n/**\n * Fetch repository data from GitHub API.\n */\nexport async function fetchRepoData(repo: string, options: Required<GitHubOptions>): Promise<GitHubRepoData | null> {\n // Check cache\n if (options.cache) {\n const cached = repoCache.get(repo);\n if (cached && Date.now() - cached.timestamp < options.cacheTTL) {\n return cached.data;\n }\n }\n\n try {\n const headers: Record<string, string> = {\n Accept: \"application/vnd.github.v3+json\",\n \"User-Agent\": \"ox-content-github-plugin\",\n };\n\n if (options.token) {\n headers.Authorization = `Bearer ${options.token}`;\n }\n\n const response = await fetch(`https://api.github.com/repos/${repo}`, { headers });\n\n if (!response.ok) {\n console.warn(`Failed to fetch GitHub repo ${repo}: ${response.status}`);\n return null;\n }\n\n const data = (await response.json()) as GitHubRepoData;\n\n // Cache the result\n if (options.cache) {\n repoCache.set(repo, { data, timestamp: Date.now() });\n }\n\n return data;\n } catch (error) {\n console.warn(`Error fetching GitHub repo ${repo}:`, error);\n return null;\n }\n}\n\n/**\n * Create GitHub card element from repo data.\n */\nfunction createGitHubCard(repoData: GitHubRepoData): Element {\n const statsChildren: Element[\"children\"] = [];\n\n // Language\n if (repoData.language) {\n statsChildren.push({\n type: \"element\",\n tagName: \"span\",\n properties: { className: [\"ox-github-language\"] },\n children: [\n {\n type: \"element\",\n tagName: \"span\",\n properties: {\n className: [\"ox-github-language-color\"],\n \"data-lang\": repoData.language.toLowerCase(),\n },\n children: [],\n },\n { type: \"text\", value: repoData.language },\n ],\n });\n }\n\n // Stars\n statsChildren.push({\n type: \"element\",\n tagName: \"span\",\n properties: { className: [\"ox-github-stat\"] },\n children: [\n {\n type: \"element\",\n tagName: \"svg\",\n properties: {\n viewBox: \"0 0 16 16\",\n fill: \"currentColor\",\n },\n children: [\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z\",\n },\n children: [],\n },\n ],\n },\n { type: \"text\", value: formatNumber(repoData.stargazers_count) },\n ],\n });\n\n // Forks\n statsChildren.push({\n type: \"element\",\n tagName: \"span\",\n properties: { className: [\"ox-github-stat\"] },\n children: [\n {\n type: \"element\",\n tagName: \"svg\",\n properties: {\n viewBox: \"0 0 16 16\",\n fill: \"currentColor\",\n },\n children: [\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z\",\n },\n children: [],\n },\n ],\n },\n { type: \"text\", value: formatNumber(repoData.forks_count) },\n ],\n });\n\n return {\n type: \"element\",\n tagName: \"a\",\n properties: {\n className: [\"ox-github-card\"],\n href: repoData.html_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n children: [\n // Header\n {\n type: \"element\",\n tagName: \"div\",\n properties: { className: [\"ox-github-header\"] },\n children: [\n {\n type: \"element\",\n tagName: \"svg\",\n properties: {\n className: [\"ox-github-icon\"],\n viewBox: \"0 0 16 16\",\n fill: \"currentColor\",\n },\n children: [\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z\",\n },\n children: [],\n },\n ],\n },\n {\n type: \"element\",\n tagName: \"span\",\n properties: { className: [\"ox-github-repo\"] },\n children: [{ type: \"text\", value: repoData.full_name }],\n },\n ],\n },\n // Description\n ...(repoData.description\n ? [\n {\n type: \"element\" as const,\n tagName: \"p\",\n properties: { className: [\"ox-github-description\"] },\n children: [{ type: \"text\" as const, value: repoData.description }],\n },\n ]\n : []),\n // Stats\n {\n type: \"element\",\n tagName: \"div\",\n properties: { className: [\"ox-github-stats\"] },\n children: statsChildren,\n },\n ],\n };\n}\n\n/**\n * Create fallback element when repo data is unavailable.\n */\nfunction createFallbackCard(repo: string): Element {\n return {\n type: \"element\",\n tagName: \"a\",\n properties: {\n className: [\"ox-github-card\", \"error\"],\n href: `https://github.com/${repo}`,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n children: [\n {\n type: \"element\",\n tagName: \"div\",\n properties: { className: [\"ox-github-header\"] },\n children: [\n {\n type: \"element\",\n tagName: \"svg\",\n properties: {\n className: [\"ox-github-icon\"],\n viewBox: \"0 0 16 16\",\n fill: \"currentColor\",\n },\n children: [\n {\n type: \"element\",\n tagName: \"path\",\n properties: {\n d: \"M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z\",\n },\n children: [],\n },\n ],\n },\n {\n type: \"element\",\n tagName: \"span\",\n properties: { className: [\"ox-github-repo\"] },\n children: [{ type: \"text\", value: repo }],\n },\n ],\n },\n ],\n };\n}\n\n/**\n * Collect all GitHub repos from HTML for pre-fetching.\n */\nexport async function collectGitHubRepos(html: string): Promise<string[]> {\n const repos: string[] = [];\n const repoPattern = /<github[^>]*\\s+repo=[\"']([^\"']+)[\"']/gi;\n\n let match;\n while ((match = repoPattern.exec(html)) !== null) {\n repos.push(match[1]);\n }\n\n return repos;\n}\n\n/**\n * Pre-fetch all GitHub repos data.\n */\nexport async function prefetchGitHubRepos(\n repos: string[],\n options?: GitHubOptions,\n): Promise<Map<string, GitHubRepoData | null>> {\n const mergedOptions = { ...defaultOptions, ...options };\n const results = new Map<string, GitHubRepoData | null>();\n\n await Promise.all(\n repos.map(async (repo) => {\n const data = await fetchRepoData(repo, mergedOptions);\n results.set(repo, data);\n }),\n );\n\n return results;\n}\n\n/**\n * Rehype plugin to transform GitHub components.\n */\nfunction rehypeGitHub(repoDataMap: Map<string, GitHubRepoData | null>) {\n return (tree: Root) => {\n const visit = (node: Root | Element) => {\n if (\"children\" in node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n\n if (child.type === \"element\") {\n // Check for <GitHub> component\n if (child.tagName.toLowerCase() === \"github\") {\n const repo = getAttribute(child, \"repo\");\n\n if (repo) {\n const repoData = repoDataMap.get(repo);\n const cardElement = repoData ? createGitHubCard(repoData) : createFallbackCard(repo);\n node.children[i] = cardElement;\n }\n } else {\n visit(child);\n }\n }\n }\n }\n };\n\n visit(tree);\n };\n}\n\n/**\n * Transform GitHub components in HTML.\n */\nexport async function transformGitHub(\n html: string,\n repoDataMap?: Map<string, GitHubRepoData | null>,\n options?: GitHubOptions,\n): Promise<string> {\n // If no pre-fetched data, collect and fetch\n let dataMap = repoDataMap;\n if (!dataMap) {\n const repos = await collectGitHubRepos(html);\n dataMap = await prefetchGitHubRepos(repos, options);\n }\n\n const result = await unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeGitHub, dataMap)\n .use(rehypeStringify)\n .process(html);\n\n return String(result);\n}\n"],"mappings":"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"}