ghost-github-portfolio 0.3.4 → 0.4.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/generator.js CHANGED
@@ -1,190 +1,146 @@
1
- function shieldsUrl(label, value, color, style, logo) {
2
- const encoded = `${encodeURIComponent(label)}-${encodeURIComponent(value)}-${color}`;
3
- let url = `https://img.shields.io/badge/${encoded}?style=${style}`;
4
- if (logo)
5
- url += `&logo=${logo}&logoColor=white`;
6
- return url;
1
+ export const MAX_DESCRIPTION_LENGTH = 140;
2
+ // Abbreviations that end in a period without ending the sentence.
3
+ const ABBREVIATION = /\b(?:e\.g|i\.e|etc|vs|approx|incl|inc|ltd|dr|mr|ms|st)$/i;
4
+ /**
5
+ * Turn a GitHub description into one short line: emoji and :shortcodes:
6
+ * removed, em and en dashes turned into commas, first sentence only,
7
+ * at most 140 characters.
8
+ */
9
+ export function cleanDescription(text, max = MAX_DESCRIPTION_LENGTH) {
10
+ let s = text
11
+ .replace(/:(?=[a-z0-9_+-]*[a-z])[a-z0-9_+-]+:/g, " ")
12
+ .replace(/(?![©®™])\p{Extended_Pictographic}/gu, " ")
13
+ .replace(/[\u{1F1E6}-\u{1F1FF}\u{1F3FB}-\u{1F3FF}‍️⃣]/gu, "")
14
+ .replace(/\s*[\u2013\u2014]\s*/g, ", ")
15
+ .replace(/\s+/g, " ")
16
+ .replace(/\s+([,.;:!?])/g, "$1")
17
+ .replace(/,(?=[,.;:!?])/g, "")
18
+ .replace(/^[\s,;:.-]+/, "")
19
+ .replace(/[\s,;:-]+$/, "")
20
+ .trim();
21
+ for (const m of s.matchAll(/[.!?](?=\s+["'(\p{Lu}\d])/gu)) {
22
+ const before = s.slice(0, m.index);
23
+ if (m[0] === "." && ABBREVIATION.test(before))
24
+ continue;
25
+ s = s.slice(0, m.index + 1);
26
+ break;
27
+ }
28
+ if (s.length > max) {
29
+ const cut = s.slice(0, max - 1);
30
+ const space = cut.lastIndexOf(" ");
31
+ s = (space > max / 2 ? cut.slice(0, space) : cut).replace(/[\s,;:.-]+$/, "") + "…";
32
+ }
33
+ else if (s && !/[.!?…]$/.test(s)) {
34
+ s += ".";
35
+ }
36
+ return s;
7
37
  }
8
- function buildBadges(repo, config) {
9
- const style = config.portfolio.badgeStyle;
10
- const overrides = config.portfolio.repos[repo.name];
11
- const badges = [];
12
- // Stars
13
- badges.push(`<img src="https://img.shields.io/github/stars/${repo.full_name}?style=${style}" alt="Stars">`);
14
- // Forks
15
- badges.push(`<img src="https://img.shields.io/github/forks/${repo.full_name}?style=${style}" alt="Forks">`);
16
- // License
17
- if (repo.license) {
18
- badges.push(`<img src="https://img.shields.io/github/license/${repo.full_name}?style=${style}" alt="License">`);
19
- }
20
- // Docker pulls (from config override)
21
- const dockerImage = overrides?.dockerImage;
22
- if (dockerImage) {
23
- badges.push(`<a href="https://hub.docker.com/r/${dockerImage}"><img src="https://img.shields.io/docker/pulls/${dockerImage}?style=${style}" alt="Docker Pulls"></a>`);
24
- }
25
- // Website badge (from GitHub homepage or config)
26
- const homepage = repo.homepage;
27
- if (homepage &&
28
- !homepage.includes("hub.docker.com") &&
29
- !homepage.includes("github.io")) {
30
- const domain = new URL(homepage).hostname;
31
- badges.push(`<a href="${homepage}"><img src="${shieldsUrl("website", domain, "blue", style)}" alt="Website"></a>`);
32
- }
33
- // Custom badges from config
34
- if (overrides?.badges) {
35
- for (const badge of overrides.badges) {
36
- badges.push(renderCustomBadge(badge, style));
37
- }
38
- }
39
- // Auto-detect awesome-list from topics
40
- if (repo.topics.includes("awesome-list") &&
41
- !overrides?.badges?.some((b) => b.type === "awesome-list")) {
42
- badges.push(`<img src="${shieldsUrl("awesome", "list", "fc60a8", style, "awesomelists")}" alt="Awesome List">`);
38
+ export function formatStars(count) {
39
+ return `${count.toLocaleString("en-US")} ${count === 1 ? "star" : "stars"}`;
40
+ }
41
+ /** The card's site link: the override, else the GitHub homepage unless it points at github.com. */
42
+ export function siteLink(repo, config) {
43
+ const override = config.portfolio.repos[repo.name];
44
+ const raw = (override?.homepage ?? repo.homepage ?? "").trim();
45
+ if (!raw)
46
+ return null;
47
+ let url;
48
+ try {
49
+ url = new URL(raw);
43
50
  }
44
- // Docs badge for GitHub Pages
45
- if (homepage?.includes("github.io") &&
46
- !overrides?.badges?.some((b) => b.type === "docs")) {
47
- badges.push(`<a href="${homepage}"><img src="${shieldsUrl("docs", "online", "blue", style)}" alt="Docs"></a>`);
51
+ catch {
52
+ return null;
48
53
  }
49
- return badges;
54
+ if (url.protocol !== "https:" && url.protocol !== "http:")
55
+ return null;
56
+ const host = url.hostname.toLowerCase();
57
+ if (host === "github.com" || host === "www.github.com")
58
+ return null;
59
+ return { url: raw, label: override?.siteLabel || "Site" };
50
60
  }
51
- function renderCustomBadge(badge, style) {
52
- switch (badge.type) {
53
- case "website":
54
- return `<a href="${badge.url}"><img src="${shieldsUrl("website", badge.label ?? new URL(badge.url).hostname, badge.color ?? "blue", style)}" alt="Website"></a>`;
55
- case "docker":
56
- return `<a href="https://hub.docker.com/r/${badge.label}"><img src="https://img.shields.io/docker/pulls/${badge.label}?style=${style}" alt="Docker Pulls"></a>`;
57
- case "awesome-list":
58
- return `<img src="${shieldsUrl("awesome", "list", badge.color ?? "fc60a8", style, "awesomelists")}" alt="Awesome List">`;
59
- case "platform":
60
- return `<img src="${shieldsUrl("platform", badge.label ?? "unknown", badge.color ?? "000", style, badge.logo)}" alt="Platform">`;
61
- case "docs":
62
- return `<a href="${badge.url}"><img src="${shieldsUrl("docs", badge.label ?? "online", badge.color ?? "blue", style)}" alt="Docs"></a>`;
63
- case "custom":
64
- return `<img src="${shieldsUrl(badge.label ?? "", badge.value ?? "", badge.color ?? "grey", style, badge.logo)}" alt="${badge.label}">`;
65
- }
61
+ export function repoDescription(repo, config) {
62
+ const override = config.portfolio.repos[repo.name]?.description;
63
+ if (override)
64
+ return override;
65
+ return repo.description ? cleanDescription(repo.description) : "";
66
66
  }
67
67
  export function generateCard(repo, bannerUrl, config) {
68
- const overrides = config.portfolio.repos[repo.name];
69
- const center = config.portfolio.centerContent;
70
- const align = center ? ' style="text-align:center;"' : "";
71
- const flexJustify = center ? " justify-content:center;" : "";
72
- const parts = [];
73
- // Banner
74
- if (bannerUrl) {
75
- parts.push(`<a href="${repo.html_url}" rel="noreferrer"${center ? ' style="display:block; text-align:center;"' : ""}>` +
76
- `<img src="${bannerUrl}" alt="${repo.name} banner" style="width:100%; max-width:900px; border-radius:8px; margin-bottom:12px; display:block;${center ? " margin-left:auto; margin-right:auto;" : ""}">` +
77
- `</a>`);
78
- }
79
- // Title
80
- parts.push(`<h2${align}><a href="${repo.html_url}" rel="noreferrer">${repo.name}</a></h2>`);
81
- // Badges
82
- const badges = buildBadges(repo, config);
83
- parts.push(`<div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;${flexJustify}">`, ` ${badges.join("\n ")}`, `</div>`);
84
- // Description
85
- const description = overrides?.description ?? repo.description;
86
- if (description) {
87
- parts.push(`<p style="font-size:1.1em;"><em>${escapeHtml(description)}</em></p>`);
88
- }
89
- // Personal note
90
- if (overrides?.personalNote) {
91
- parts.push(`<p>${escapeHtml(overrides.personalNote)}</p>`);
92
- }
93
- // Key features (from config only)
94
- if (overrides?.keyFeatures?.length) {
95
- parts.push(`<p><strong>Key Features:</strong></p>`);
96
- parts.push(`<ul>`);
97
- for (const feature of overrides.keyFeatures) {
98
- parts.push(`<li>${escapeHtml(feature)}</li>`);
99
- }
100
- parts.push(`</ul>`);
101
- }
102
- // Tech stack
103
- const techStack = overrides?.techStack ?? inferTechStack(repo);
104
- if (techStack) {
105
- parts.push(`<p><strong>Tech Stack:</strong>&nbsp;${escapeHtml(techStack)}</p>`);
106
- }
107
- // Separator
108
- parts.push(`<hr>`);
109
- return parts.join("\n");
68
+ const href = escapeHtml(repo.html_url);
69
+ const name = escapeHtml(repo.name);
70
+ const media = bannerUrl
71
+ ? `<a class="pf-media" href="${href}" tabindex="-1" aria-hidden="true"><img src="${escapeHtml(bannerUrl)}" alt="" loading="lazy"></a>`
72
+ : `<a class="pf-media pf-tile" href="${href}" tabindex="-1" aria-hidden="true"><span>${name}</span></a>`;
73
+ const description = repoDescription(repo, config);
74
+ const site = siteLink(repo, config);
75
+ const lineParts = [];
76
+ if (description)
77
+ lineParts.push(escapeHtml(description));
78
+ if (site) {
79
+ lineParts.push(`<a href="${escapeHtml(site.url)}">${escapeHtml(site.label)}</a>`);
80
+ }
81
+ const lines = [
82
+ `<li class="pf-card">`,
83
+ ` ${media}`,
84
+ ` <div class="pf-head"><h3 class="pf-name"><a href="${href}">${name}</a></h3><span class="pf-stars">${formatStars(repo.stargazers_count)}</span></div>`,
85
+ ];
86
+ if (lineParts.length > 0) {
87
+ lines.push(` <p class="pf-line">${lineParts.join(" ")}</p>`);
88
+ }
89
+ lines.push(`</li>`);
90
+ return lines.join("\n");
110
91
  }
111
- function inferTechStack(repo) {
112
- const languages = [];
113
- if (repo.language)
114
- languages.push(repo.language);
115
- // Add relevant topics as tech
116
- const techTopics = repo.topics.filter((t) => [
117
- "docker",
118
- "kubernetes",
119
- "helm",
120
- "nextjs",
121
- "react",
122
- "vue",
123
- "svelte",
124
- "fastapi",
125
- "flask",
126
- "express",
127
- "nestjs",
128
- "terraform",
129
- "ansible",
130
- "mcp",
131
- "jellyfin",
132
- "telegram",
133
- "swift",
134
- "macos",
135
- "nodejs",
136
- ].includes(t.toLowerCase()));
137
- const topicLabels = techTopics.map((t) => t.charAt(0).toUpperCase() + t.slice(1));
138
- const all = [...new Set([...languages, ...topicLabels])];
139
- return all.length > 0 ? all.join(", ") : null;
92
+ function portfolioStyle(columns) {
93
+ const tablet = Math.min(columns, 2);
94
+ const rules = [
95
+ `.pf { --pf-muted: #999; --pf-rule: #3a3f4b; --pf-tile: #21252c; }`,
96
+ `.pf .pf-intro, .pf .pf-more { max-width: 720px; margin-left: auto; margin-right: auto; }`,
97
+ `.pf .pf-intro { margin-top: 0; margin-bottom: 0; font-size: 1.1em; line-height: 1.6; }`,
98
+ `.pf .pf-grid { display: grid; grid-template-columns: repeat(${columns}, minmax(0, 1fr)); gap: 3.2rem 2.4rem; margin: 2.4em 0 0; padding: 0; list-style: none; }`,
99
+ `.pf .pf-card { margin: 0; padding: 0; display: flex; flex-direction: column; min-width: 0; }`,
100
+ `.pf .pf-media { display: block; border-radius: 8px; overflow: hidden; aspect-ratio: 9 / 2; text-decoration: none; }`,
101
+ `.pf .pf-media img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center; margin: 0; border-radius: 0; }`,
102
+ `.pf .pf-tile { display: flex; align-items: center; padding: 0 7%; background: var(--pf-tile); border: 1px solid var(--pf-rule); }`,
103
+ `.pf .pf-tile span { color: #fff; font-size: 1.45em; font-weight: 700; letter-spacing: -.02em; line-height: 1.1; overflow-wrap: anywhere; }`,
104
+ `.pf .pf-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1.2rem; margin: 1.2rem 0 0; }`,
105
+ `.pf .pf-name { margin: 0; min-width: 0; font-size: 1em; font-weight: 700; line-height: 1.3; letter-spacing: -.01em; overflow-wrap: anywhere; }`,
106
+ `.pf .pf-name a { color: #fff; text-decoration: none; }`,
107
+ `.pf .pf-name a:hover, .pf .pf-name a:focus-visible { text-decoration: underline; }`,
108
+ `.pf .pf-stars { flex: none; color: var(--pf-muted); font-size: .85em; font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }`,
109
+ `.pf .pf-line { margin: .4rem 0 0; font-size: .92em; line-height: 1.55; }`,
110
+ `.pf .pf-line a { white-space: nowrap; }`,
111
+ `.pf .pf-more { margin-top: 3.2em; margin-bottom: 0; color: var(--pf-muted); font-size: .95em; }`,
112
+ ];
113
+ if (tablet < columns) {
114
+ rules.push(`@media (max-width: 1024px) {`, ` .pf .pf-grid.pf-cols-${columns} { grid-template-columns: repeat(${tablet}, minmax(0, 1fr)); }`, `}`);
115
+ }
116
+ rules.push(`@media (max-width: 640px) {`, ` .pf .pf-grid.pf-cols-${columns} { grid-template-columns: 1fr; gap: 2.8rem; }`, `}`);
117
+ return `<style>\n${rules.join("\n")}\n</style>`;
140
118
  }
141
- export function generateFooter(allRepos, config) {
142
- if (!config.portfolio.footer.showStats && !config.portfolio.footer.showViewAll)
143
- return null;
144
- const parts = [];
145
- parts.push(`<h2>GitHub Stats</h2>`);
146
- if (config.portfolio.footer.showStats) {
147
- const totalStars = allRepos.reduce((s, r) => s + r.stargazers_count, 0);
148
- const totalRepos = allRepos.length;
149
- const languages = [
150
- ...new Set(allRepos.map((r) => r.language).filter(Boolean)),
151
- ];
152
- const focusAreas = [
153
- ...new Set(allRepos.flatMap((r) => r.topics).filter(Boolean)),
154
- ]
155
- .slice(0, 8)
156
- .map((t) => t.charAt(0).toUpperCase() + t.slice(1));
157
- const lines = [];
158
- lines.push(`<strong>Total Stars:</strong>&nbsp;${totalStars}+`);
159
- lines.push(`<strong>Public Repositories:</strong>&nbsp;${totalRepos}`);
160
- if (languages.length > 0) {
161
- lines.push(`<strong>Primary Languages:</strong>&nbsp;${languages.join(", ")}`);
162
- }
163
- if (focusAreas.length > 0) {
164
- lines.push(`<strong>Focus Areas:</strong>&nbsp;${focusAreas.join(", ")}`);
165
- }
166
- parts.push(`<p>${lines.join("<br>")}</p>`);
167
- }
168
- if (config.portfolio.footer.showViewAll) {
169
- parts.push(`<p><a href="https://github.com/${config.github.username}?tab=repositories"><strong>View All Repositories &rarr;</strong></a></p>`);
170
- }
119
+ /**
120
+ * The whole page as the HTML of one Ghost html card. The `kg-width-wide`
121
+ * class lets themes built on Ghost's content grid (Alto, Source, Casper)
122
+ * give the cards the wide column; the text stays at reading width.
123
+ */
124
+ export function generatePortfolioHtml(input, config) {
125
+ const { columns, intro } = config.portfolio;
126
+ const user = escapeHtml(config.github.username);
127
+ const profile = `<a href="https://github.com/${user}">github.com/${user}</a>`;
128
+ const others = input.totalRepos - input.cards.length;
129
+ const more = others > 0
130
+ ? `The other ${others.toLocaleString("en-US")} public ${others === 1 ? "repository is" : "repositories are"} on ${profile}.`
131
+ : `More on ${profile}.`;
132
+ const parts = [`<div class="pf kg-width-wide">`, portfolioStyle(columns)];
133
+ if (intro.trim()) {
134
+ parts.push(`<p class="pf-intro">${escapeHtml(intro.trim())}</p>`);
135
+ }
136
+ parts.push(`<ul class="pf-grid pf-cols-${columns}">`, ...input.cards, `</ul>`);
137
+ parts.push(`<p class="pf-more">${more}</p>`, `</div>`);
171
138
  return parts.join("\n");
172
139
  }
173
- export function buildLexical(cards, footer) {
174
- const children = [];
175
- // Opening separator
176
- children.push({ type: "horizontalrule", version: 1 });
177
- // Project cards
178
- for (const card of cards) {
179
- children.push({ type: "html", version: 1, html: card });
180
- }
181
- // Footer
182
- if (footer) {
183
- children.push({ type: "html", version: 1, html: footer });
184
- }
140
+ export function buildLexical(html) {
185
141
  return {
186
142
  root: {
187
- children,
143
+ children: [{ type: "html", version: 1, html }],
188
144
  direction: "ltr",
189
145
  format: "",
190
146
  indent: 0,
@@ -193,6 +149,56 @@ export function buildLexical(cards, footer) {
193
149
  },
194
150
  };
195
151
  }
152
+ /** The html card as Ghost renders it, with its begin and end markers. */
153
+ export function wrapHtmlCard(html) {
154
+ return `<!--kg-card-begin: html-->\n${html}\n<!--kg-card-end: html-->`;
155
+ }
156
+ /**
157
+ * A standalone dark page that approximates Ghost's Alto theme in dark mode
158
+ * (content grid, widths, the .gh-content rules that reach into an html
159
+ * card), for checking the output in a browser before syncing.
160
+ */
161
+ export function buildPreviewPage(html, title = "Portfolio") {
162
+ const t = escapeHtml(title);
163
+ return `<!doctype html>
164
+ <html lang="en">
165
+ <head>
166
+ <meta charset="utf-8">
167
+ <meta name="viewport" content="width=device-width, initial-scale=1">
168
+ <title>${t} (preview)</title>
169
+ <style>
170
+ :root { --ghost-accent-color: #FF1A75; --gap: 3.6rem; }
171
+ * { box-sizing: border-box; }
172
+ html { font-size: 62.5%; background: #282c35; }
173
+ body { margin: 0; background: #282c35; color: #ccc; font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; font-size: 1.6rem; line-height: 1.6; -webkit-font-smoothing: antialiased; }
174
+ .article-header { width: min(720px, 100% - var(--gap) * 2); margin: 60px auto 0; text-align: center; }
175
+ .post-title { margin: 0; color: #fff; font-size: 3.6rem; font-weight: 800; line-height: 1.15; letter-spacing: -.02em; }
176
+ .gh-canvas { --main: min(720px, 100% - var(--gap) * 2); --wide: minmax(0, calc((1200px - 720px) / 2)); --full: minmax(var(--gap), 1fr); display: grid; grid-template-columns: [full-start] var(--full) [wide-start] var(--wide) [main-start] var(--main) [main-end] var(--wide) [wide-end] var(--full) [full-end]; }
177
+ .gh-canvas > * { grid-column: main; }
178
+ .gh-canvas > .kg-width-wide { grid-column: wide; }
179
+ .gh-content { margin-top: 5.6rem; margin-bottom: 12rem; font-size: 1.7rem; word-break: break-word; }
180
+ .gh-content > * { margin-top: 0; margin-bottom: 0; }
181
+ .gh-content > * + * { margin-top: 1.6em; }
182
+ .gh-content h3 { font-size: 1.4em; }
183
+ .gh-content a { color: var(--ghost-accent-color); text-decoration: underline; word-break: break-word; }
184
+ .gh-content ul { padding-left: 2.8rem; }
185
+ .gh-content li + li { margin-top: .8rem; }
186
+ @media (max-width: 767px) { :root { --gap: 2rem; } .post-title { font-size: 3.2rem; } .article-header { margin-top: 40px; } .gh-content { margin-top: 4rem; } }
187
+ </style>
188
+ </head>
189
+ <body>
190
+ <main>
191
+ <article>
192
+ <header class="article-header"><h1 class="post-title">${t}</h1></header>
193
+ <div class="gh-content gh-canvas">
194
+ ${wrapHtmlCard(html)}
195
+ </div>
196
+ </article>
197
+ </main>
198
+ </body>
199
+ </html>
200
+ `;
201
+ }
196
202
  function escapeHtml(str) {
197
203
  return str
198
204
  .replace(/&/g, "&amp;")
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
package/dist/ghost.d.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import type { Config, LexicalDocument } from "./types.js";
2
2
  export declare function generateJwt(apiKey: string): string;
3
+ /**
4
+ * Where Admin API requests go. Normally the public Ghost URL. With
5
+ * ghost.originUrl set they go straight to the origin (for example past a WAF
6
+ * that rejects page bodies containing <img>), carrying the public Host and
7
+ * X-Forwarded-Proto: https so Ghost answers as it would for the public site.
8
+ * The JWT audience stays /admin/ either way.
9
+ */
10
+ export declare function adminUrl(config: Config, path: string): string;
3
11
  interface GhostPage {
4
12
  id: string;
5
13
  updated_at: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ghost.d.ts","sourceRoot":"","sources":["../src/ghost.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG1D,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA6BlD;AAUD,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAqBlE;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,SAAS,CAAC,CA0BpB"}
1
+ {"version":3,"file":"ghost.d.ts","sourceRoot":"","sources":["../src/ghost.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG1D,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA6BlD;AAgBD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7D;AAkBD,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAelE;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,SAAS,CAAC,CAwBpB"}
package/dist/ghost.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createHmac } from "node:crypto";
2
- import { fetchWithRetry } from "./http.js";
2
+ import { fetchWithRetry, rawRequest } from "./http.js";
3
3
  export function generateJwt(apiKey) {
4
4
  const [keyId, secretHex] = apiKey.split(":");
5
5
  if (!keyId || !secretHex) {
@@ -19,25 +19,43 @@ export function generateJwt(apiKey) {
19
19
  .replace(/=+$/, "");
20
20
  return `${header}.${payload}.${signature}`;
21
21
  }
22
- function ghostHeaders(apiKey) {
23
- return {
24
- Authorization: `Ghost ${generateJwt(apiKey)}`,
22
+ function ghostHeaders(config) {
23
+ const h = {
24
+ Authorization: `Ghost ${generateJwt(config.ghost.adminApiKey)}`,
25
25
  "Content-Type": "application/json",
26
26
  "User-Agent": "Mozilla/5.0 ghost-github-portfolio",
27
27
  };
28
+ if (config.ghost.originUrl) {
29
+ const publicUrl = new URL(config.ghost.url);
30
+ h.Host = config.ghost.hostHeader || publicUrl.host;
31
+ h["X-Forwarded-Proto"] = "https";
32
+ }
33
+ return h;
34
+ }
35
+ /**
36
+ * Where Admin API requests go. Normally the public Ghost URL. With
37
+ * ghost.originUrl set they go straight to the origin (for example past a WAF
38
+ * that rejects page bodies containing <img>), carrying the public Host and
39
+ * X-Forwarded-Proto: https so Ghost answers as it would for the public site.
40
+ * The JWT audience stays /admin/ either way.
41
+ */
42
+ export function adminUrl(config, path) {
43
+ const base = config.ghost.originUrl || config.ghost.url;
44
+ return `${base}/ghost/api/admin/${path}`;
45
+ }
46
+ /**
47
+ * Send an Admin API request. With originUrl set it goes through rawRequest,
48
+ * because the global fetch drops a custom Host header.
49
+ */
50
+ function send(config, url, init = {}) {
51
+ return fetchWithRetry(url, { ...init, headers: ghostHeaders(config) }, config.ghost.originUrl ? { fetchImpl: rawRequest } : undefined);
28
52
  }
29
53
  export async function fetchPage(config) {
30
- const { url, adminApiKey, pageId, pageSlug } = config.ghost;
31
- let endpoint;
32
- if (pageId) {
33
- endpoint = `${url}/ghost/api/admin/pages/${pageId}/`;
34
- }
35
- else {
36
- endpoint = `${url}/ghost/api/admin/pages/slug/${pageSlug}/`;
37
- }
38
- const res = await fetchWithRetry(endpoint, {
39
- headers: ghostHeaders(adminApiKey),
40
- });
54
+ const { pageId, pageSlug } = config.ghost;
55
+ const endpoint = pageId
56
+ ? adminUrl(config, `pages/${pageId}/`)
57
+ : adminUrl(config, `pages/slug/${pageSlug}/`);
58
+ const res = await send(config, endpoint);
41
59
  if (!res.ok) {
42
60
  const body = await res.text();
43
61
  throw new Error(`Ghost API error ${res.status}: ${body}`);
@@ -46,8 +64,7 @@ export async function fetchPage(config) {
46
64
  return data.pages[0];
47
65
  }
48
66
  export async function updatePage(config, pageId, updatedAt, lexical) {
49
- const { url, adminApiKey } = config.ghost;
50
- const endpoint = `${url}/ghost/api/admin/pages/${pageId}/`;
67
+ const endpoint = adminUrl(config, `pages/${pageId}/`);
51
68
  const body = {
52
69
  pages: [
53
70
  {
@@ -56,9 +73,8 @@ export async function updatePage(config, pageId, updatedAt, lexical) {
56
73
  },
57
74
  ],
58
75
  };
59
- const res = await fetchWithRetry(endpoint, {
76
+ const res = await send(config, endpoint, {
60
77
  method: "PUT",
61
- headers: ghostHeaders(adminApiKey),
62
78
  body: JSON.stringify(body),
63
79
  });
64
80
  if (!res.ok) {
package/dist/ghost.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ghost.js","sourceRoot":"","sources":["../src/ghost.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ghost.js","sourceRoot":"","sources":["../src/ghost.ts"],"names":[],"mappings":"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"}
package/dist/github.d.ts CHANGED
@@ -1,10 +1,29 @@
1
1
  import type { Config, GitHubRepo, RepoOverride } from "./types.js";
2
- import { type RateLimitInfo } from "./http.js";
3
- export interface FetchReposResult {
4
- repos: GitHubRepo[];
5
- rateLimit: RateLimitInfo | null;
2
+ /** Fetch every public repo the user owns, unfiltered. */
3
+ export declare function fetchAllRepos(config: Config, verbose?: boolean): Promise<GitHubRepo[]>;
4
+ export declare function isAwesomeList(repo: GitHubRepo): boolean;
5
+ /**
6
+ * Apply every filter, sort by stars and only then cut to maxRepos, so an
7
+ * excluded repo never takes a slot.
8
+ */
9
+ export declare function selectRepos(repos: GitHubRepo[], config: Config): GitHubRepo[];
10
+ export interface BannerResult {
11
+ /** URL to use in the card, or null to draw a name tile. */
12
+ url: string | null;
13
+ /** Why no banner is used, one entry per path tried. Empty when url is set or banners are off. */
14
+ problems: string[];
6
15
  }
7
- export declare function fetchRepos(config: Config, verbose?: boolean): Promise<GitHubRepo[]>;
8
- export declare function detectBanner(repo: GitHubRepo, config: Config): Promise<string | null>;
9
- export declare function fetchPortfolioConfig(repo: GitHubRepo, config: Config): Promise<RepoOverride | null>;
16
+ /**
17
+ * List every reference in an SVG that a browser would have to load from
18
+ * somewhere else. Inside an `<img>` those are never loaded, so the banner
19
+ * renders blank or broken. `#id` and `data:` references are fine.
20
+ */
21
+ export declare function findExternalRefs(svg: string): string[];
22
+ /**
23
+ * Pick the banner for a repo: the per-repo path first (repos.<name>.bannerPath
24
+ * or bannerPaths.<name>), then defaultBannerPath. A banner is used only when
25
+ * it answers 200 and, for SVG, loads nothing from outside itself.
26
+ */
27
+ export declare function resolveBanner(repo: GitHubRepo, config: Config): Promise<BannerResult>;
28
+ export declare function fetchPortfolioConfig(repo: GitHubRepo): Promise<RepoOverride | null>;
10
29
  //# sourceMappingURL=github.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAanB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,UAAQ,GACd,OAAO,CAAC,UAAU,EAAE,CAAC,CAwDvB;AAaD,wBAAsB,YAAY,CAChC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AAID,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA4B9B"}
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkBnE,yDAAyD;AACzD,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,UAAQ,GACd,OAAO,CAAC,UAAU,EAAE,CAAC,CA+CvB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAKvD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAsB7E;AAED,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,iGAAiG;IACjG,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CActD;AAgCD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CAuBvB;AAID,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAuB9B"}