@repodeckhz/core 0.6.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/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # @repodeckhz/core
2
+
3
+ > Framework-free core for **repodeck**: fetch, parse, and build GitHub repo card data. Zero DOM, zero dependencies.
4
+
5
+ This is the headless heart of the repodeck package. It talks to the GitHub REST API, parses the response, and returns a normalized `CardData` object. No UI, no framework: use it in Node, Deno, Bun, the browser, or any server-side template engine.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @repodeckhz/core
11
+ # or
12
+ bun add @repodeckhz/core
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```ts
18
+ import { buildCardData } from '@repodeckhz/core';
19
+
20
+ const card = await buildCardData('repodeck', 'taskflow', {
21
+ include: { readme: true, resume: true, screenshots: true },
22
+ branch: 'main',
23
+ configPath: 'config-repodeck',
24
+ });
25
+
26
+ // card.resume → { text, truncated } | { error: RepoDeckError }
27
+ // card.readme → { html, raw, frontmatter? } | { error: RepoDeckError }
28
+ // card.screenshots → Screenshot[] | { error: RepoDeckError }
29
+ ```
30
+
31
+ The target repo must contain a `config-repodeck/` folder (configurable
32
+ via `options.configPath`):
33
+
34
+ ```
35
+ config-repodeck/
36
+ ├── README.md # expanded content (shown in the modal)
37
+ ├── RESUME.txt # short plain-text summary (shown on the card)
38
+ └── screenshots/ # project images, sorted alphabetically
39
+ ├── 01-home.png
40
+ └── 02-dashboard.png
41
+ ```
42
+
43
+ ## Public API
44
+
45
+ ### `buildCardData(owner, repo, options?) → Promise<CardData>`
46
+
47
+ The orchestrator. Fires only the fetches you asked for (via `options.include`) in parallel, and assembles a single `CardData` object.
48
+
49
+ **Per-field error model** (closed decision, never all-or-nothing): if `RESUME.txt` is missing but `README.md` exists, the card still builds; `resume` carries its own `RepoDeckError`. You always know exactly which file failed.
50
+
51
+ ```ts
52
+ interface CardData {
53
+ meta: { owner, repo, url, branch, configPath, fetchedAt };
54
+ resume: FieldResult<ResumeData> | null;
55
+ readme: FieldResult<ReadmeData> | null;
56
+ screenshots: FieldResult<Screenshot[]> | null;
57
+ stats?: FieldResult<RepoStats> | null;
58
+ }
59
+ ```
60
+
61
+ `FieldResult<T>` is either `T` or `{ error: RepoDeckError }`.
62
+
63
+ ### `FetchOptions`
64
+
65
+ ```ts
66
+ interface FetchOptions {
67
+ token?: string; // GitHub PAT - bumps rate limit from 60 to 5000 req/h
68
+ branch?: string; // default "main"
69
+ timeoutMs?: number; // per-request timeout
70
+ retries?: number; // retries on 5xx/network (never on 404/401)
71
+ }
72
+ ```
73
+
74
+ ### `BuildOptions`
75
+
76
+ ```ts
77
+ interface BuildOptions extends FetchOptions {
78
+ include?: {
79
+ readme?: boolean;
80
+ resume?: boolean;
81
+ screenshots?: boolean;
82
+ stats?: boolean; // fetches /repos/{owner}/{repo} for stars/forks
83
+ };
84
+ configPath?: string; // default "config-repodeck"
85
+ resumeMaxChars?: number; // default 280
86
+ locale?: string; // tries RESUME.<locale>.txt before RESUME.txt
87
+ debug?: boolean; // verbose [repodeck:…] console logs (or REPODECK_DEBUG=1 env)
88
+ }
89
+ ```
90
+
91
+ ### GitHub client functions
92
+
93
+ ```ts
94
+ fetchFileContent(owner, repo, path, options?) // 404 → null (not an error)
95
+ fetchDirectoryListing(owner, repo, path, options?) // 404 → []
96
+ fetchRepoStats(owner, repo, options?) // stars, forks, watchers
97
+ checkRateLimit(options?) // { remaining, limit, resetAt }
98
+ buildRawUrl(owner, repo, branch, path) // raw.githubusercontent.com URL
99
+ ```
100
+
101
+ ### Parsers
102
+
103
+ ```ts
104
+ parseResume(rawText, { maxChars? }) // → { text, truncated, locale? }
105
+ parseReadme(rawMarkdown) // → { html, raw, frontmatter? } (sanitized)
106
+ parseReadmeFrontmatter(rawMarkdown) // → { metadata, content }
107
+ resolveScreenshots(entries, owner, repo, branch) // → Screenshot[]
108
+ ```
109
+
110
+ ### Presets
111
+
112
+ ```ts
113
+ import { defaultPresets, registerPreset, getPreset, mergePresetWithUserConfig } from '@repodeckhz/core';
114
+
115
+ defaultPresets.minimal // title + 1 cover
116
+ defaultPresets.standard // title + resume + screenshot cover
117
+ defaultPresets.detailed // everything + README preview line
118
+
119
+ registerPreset('my-preset', { include: {...}, readmePreview: true, ... });
120
+ ```
121
+
122
+ ### Layout & radius helpers
123
+
124
+ ```ts
125
+ resolveScreenshotLayout(screenshots, context, options?) // → { mode, items, total, hidden }
126
+ assignBentoSpans(count) // deterministic bento spans
127
+ resolveRadiusTokens('soft') // → { card, button, modal }
128
+ ```
129
+
130
+ ### `RepoDeckError`
131
+
132
+ ```ts
133
+ class RepoDeckError extends Error {
134
+ code: 'NOT_FOUND' | 'RATE_LIMITED' | 'UNAUTHORIZED' | 'NETWORK_ERROR' | 'INVALID_CONFIG';
135
+ status?: number;
136
+ field?: string;
137
+ toJSON(): { name, code, message, status, field };
138
+ }
139
+ ```
140
+
141
+ Also exported as `repodeckError` for backwards compatibility (same class).
142
+
143
+ ## Frontmatter (README.md)
144
+
145
+ Add YAML-like frontmatter to the top of `README.md` for per-project customization:
146
+
147
+ ```markdown
148
+ ---
149
+ title: My Project
150
+ accent: "#0891b2"
151
+ order: 2
152
+ tags: library, charts
153
+ ---
154
+ # My Project
155
+ ...
156
+ ```
157
+
158
+ Supported fields: `title`, `accent` (hex color), `order` (number), `description`, `tags`, `author`.
159
+
160
+ ## Localized RESUME
161
+
162
+ Pass `locale: 'pt'` and the builder tries `RESUME.pt.txt` before `RESUME.txt`, returning `{ text, truncated, locale: 'pt' }`.
163
+
164
+ ## Caching
165
+
166
+ In-memory singleton cache (Map) with TTL (5 min default):
167
+
168
+ ```ts
169
+ import { getCached, setCached, clearCache, buildCacheKey } from '@repodeckhz/core';
170
+ ```
171
+
172
+ ## License
173
+
174
+ MIT