@rmdes/indiekit-endpoint-github 1.0.4 → 1.0.6

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/assets/styles.css CHANGED
@@ -1,14 +1,6 @@
1
1
  /* GitHub endpoint styles */
2
2
 
3
- /* Section spacing */
4
- .github-section {
5
- margin-block-end: var(--space-xl);
6
- }
7
-
8
- .github-section h2 {
9
- margin-block-end: var(--space-m);
10
- }
11
-
3
+ /* Profile */
12
4
  .github-profile {
13
5
  align-items: center;
14
6
  display: flex;
@@ -36,7 +28,7 @@
36
28
  font-size: var(--step--1);
37
29
  }
38
30
 
39
- /* GitHub list */
31
+ /* List */
40
32
  .github-list {
41
33
  display: flex;
42
34
  flex-direction: column;
@@ -63,7 +55,7 @@
63
55
  gap: var(--space-xs);
64
56
  }
65
57
 
66
- /* Activity styles */
58
+ /* Activity */
67
59
  .github-activity {
68
60
  align-items: center;
69
61
  }
@@ -83,20 +75,20 @@
83
75
  color: var(--color-text-secondary);
84
76
  }
85
77
 
86
- /* Commit styles (in main list) */
78
+ /* Commit message (in main list) */
87
79
  .github-commit__message {
88
80
  flex: 1;
89
81
  min-inline-size: 200px;
90
82
  }
91
83
 
92
- /* Commit list styles (inside featured repos) */
84
+ /* Commit list (inside featured repos) */
93
85
  .github-commit-list {
94
86
  display: flex;
95
87
  flex-direction: column;
96
88
  font-size: var(--step--1);
97
89
  gap: var(--space-xs);
98
90
  list-style: none;
99
- margin: var(--space-s) 0 0;
91
+ margin: 0;
100
92
  padding: 0;
101
93
  }
102
94
 
@@ -116,24 +108,11 @@
116
108
  color: var(--color-text-secondary);
117
109
  }
118
110
 
119
- /* Featured repos styles */
111
+ /* Featured repos */
120
112
  .github-featured {
121
113
  display: grid;
122
114
  gap: var(--space-l);
123
115
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
124
- margin-block-end: var(--space-xl);
125
- }
126
-
127
- .github-featured__commits {
128
- border-block-start: 1px solid var(--color-border);
129
- margin-block-start: var(--space-s);
130
- padding-block-start: var(--space-s);
131
- }
132
-
133
- .github-featured__commits summary {
134
- color: var(--color-text-secondary);
135
- cursor: pointer;
136
- font-size: var(--step--1);
137
116
  }
138
117
 
139
118
  .github-featured__desc {
@@ -161,6 +140,13 @@
161
140
  padding: var(--space-m);
162
141
  }
163
142
 
143
+ /* Details inside featured cards: add separator */
144
+ .github-featured__repo .details {
145
+ border-block-start: 1px solid var(--color-border);
146
+ margin-block-start: var(--space-s);
147
+ padding-block-start: var(--space-s);
148
+ }
149
+
164
150
  /* Language indicator */
165
151
  .github-lang {
166
152
  margin-inline-end: var(--space-xs);
@@ -172,7 +158,7 @@
172
158
  font-size: var(--step--1);
173
159
  }
174
160
 
175
- /* Repo card styles */
161
+ /* Repo card */
176
162
  .github-repo {
177
163
  flex-direction: column;
178
164
  }
@@ -192,7 +178,7 @@
192
178
  font-weight: var(--font-weight-semibold);
193
179
  }
194
180
 
195
- /* SHA badge styles */
181
+ /* SHA badge */
196
182
  .github-sha {
197
183
  background: var(--color-offset);
198
184
  border-radius: var(--radius-s);
@@ -201,7 +187,7 @@
201
187
  padding-inline: var(--space-2xs);
202
188
  }
203
189
 
204
- /* Star styles */
190
+ /* Star card */
205
191
  .github-star {
206
192
  flex-direction: column;
207
193
  }
@@ -220,12 +206,7 @@
220
206
  font-weight: var(--font-weight-semibold);
221
207
  }
222
208
 
223
- /*
224
- * Link styles - grouped by specificity (ascending)
225
- * Non-pseudo selectors first, then pseudo selectors
226
- */
227
-
228
- /* Specificity: 0,1,1 (one class, one element) */
209
+ /* Link styles */
229
210
  .github-featured__name a {
230
211
  text-decoration: none;
231
212
  }
@@ -234,12 +215,10 @@
234
215
  text-decoration: none;
235
216
  }
236
217
 
237
- /* Specificity: 0,1,2 (one class, two elements) */
238
218
  .github-commit-list code a {
239
219
  text-decoration: none;
240
220
  }
241
221
 
242
- /* Pseudo-class selectors */
243
222
  .github-featured__name a:hover {
244
223
  text-decoration: underline;
245
224
  }
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import express from "express";
2
2
 
3
3
  import { activityController } from "./lib/controllers/activity.js";
4
+ import { changelogController } from "./lib/controllers/changelog.js";
4
5
  import { commitsController } from "./lib/controllers/commits.js";
5
6
  import { contributionsController } from "./lib/controllers/contributions.js";
6
7
  import { dashboardController } from "./lib/controllers/dashboard.js";
@@ -85,6 +86,7 @@ export default class GitHubEndpoint {
85
86
  publicRouter.get("/api/contributions", contributionsController.api);
86
87
  publicRouter.get("/api/activity", activityController.api);
87
88
  publicRouter.get("/api/featured", featuredController.api);
89
+ publicRouter.get("/api/changelog", changelogController.api);
88
90
 
89
91
  return publicRouter;
90
92
  }
@@ -0,0 +1,166 @@
1
+ import { GitHubClient } from "../github-client.js";
2
+
3
+ /**
4
+ * Categorize a repo by its name prefix
5
+ * @param {string} name - Repository name
6
+ * @returns {string} - Category key
7
+ */
8
+ function categorizeRepo(name) {
9
+ if (name === "indiekit") return "core";
10
+ if (name === "indiekit-cloudron" || name === "indiekit-deploy")
11
+ return "deployment";
12
+ if (name.includes("theme")) return "theme";
13
+ if (name.startsWith("indiekit-endpoint-")) return "endpoints";
14
+ if (name.startsWith("indiekit-syndicator-")) return "syndicators";
15
+ if (name.startsWith("indiekit-post-type-")) return "post-types";
16
+ if (name.startsWith("indiekit-preset-")) return "presets";
17
+ return "other";
18
+ }
19
+
20
+ const CATEGORY_LABELS = {
21
+ core: "Core",
22
+ deployment: "Deployment",
23
+ theme: "Theme",
24
+ endpoints: "Endpoints",
25
+ syndicators: "Syndicators",
26
+ "post-types": "Post Types",
27
+ presets: "Presets",
28
+ other: "Other",
29
+ };
30
+
31
+ /**
32
+ * Split an array into chunks of a given size
33
+ * @param {Array} array
34
+ * @param {number} size
35
+ * @returns {Array<Array>}
36
+ */
37
+ function chunks(array, size) {
38
+ const result = [];
39
+ for (let i = 0; i < array.length; i += size) {
40
+ result.push(array.slice(i, i + size));
41
+ }
42
+ return result;
43
+ }
44
+
45
+ /**
46
+ * Changelog API controller
47
+ * @type {import("express").RequestHandler}
48
+ */
49
+ export const changelogController = {
50
+ async api(request, response, next) {
51
+ try {
52
+ const { username, token, cacheTtl } =
53
+ request.app.locals.application.githubConfig;
54
+
55
+ if (!username) {
56
+ return response.status(400).json({ error: "No username configured" });
57
+ }
58
+
59
+ const client = new GitHubClient({ token, cacheTtl });
60
+
61
+ // Parse days param — default 30, "all" for unlimited
62
+ const daysParam = request.query.days || "30";
63
+ let sinceDate = null;
64
+ let daysValue = daysParam;
65
+
66
+ if (daysParam !== "all") {
67
+ const days = Number.parseInt(daysParam, 10);
68
+ if (Number.isNaN(days) || days < 1) {
69
+ return response
70
+ .status(400)
71
+ .json({ error: "Invalid days parameter" });
72
+ }
73
+ daysValue = days;
74
+ const since = new Date();
75
+ since.setDate(since.getDate() - days);
76
+ sinceDate = since.toISOString();
77
+ }
78
+
79
+ // Fetch all user repos (100 to cover all indiekit repos)
80
+ const repos = await client.getUserRepos(username, 100, "pushed");
81
+
82
+ if (!Array.isArray(repos)) {
83
+ return response.json({
84
+ commits: [],
85
+ categories: {},
86
+ totalCommits: 0,
87
+ days: daysValue,
88
+ generatedAt: new Date().toISOString(),
89
+ });
90
+ }
91
+
92
+ // Filter to indiekit repos only
93
+ const indiekitRepos = repos.filter((repo) =>
94
+ repo.name.includes("indiekit"),
95
+ );
96
+
97
+ // Build categories map from discovered repos
98
+ const categories = {};
99
+ for (const repo of indiekitRepos) {
100
+ const cat = categorizeRepo(repo.name);
101
+ if (!categories[cat]) {
102
+ categories[cat] = {
103
+ label: CATEGORY_LABELS[cat] || cat,
104
+ repos: [],
105
+ };
106
+ }
107
+ categories[cat].repos.push(repo.name);
108
+ }
109
+
110
+ // Fetch commits in batches of 5 to avoid secondary rate limits
111
+ const allCommits = [];
112
+ for (const batch of chunks(indiekitRepos, 5)) {
113
+ const results = await Promise.all(
114
+ batch.map(async (repo) => {
115
+ try {
116
+ const commits = await client.getRepoCommits(
117
+ repo.owner.login,
118
+ repo.name,
119
+ 20,
120
+ sinceDate,
121
+ );
122
+
123
+ if (!Array.isArray(commits)) return [];
124
+
125
+ // Filter out merge commits and map to response shape
126
+ return commits
127
+ .filter((c) => (c.parents?.length || 0) <= 1)
128
+ .map((c) => ({
129
+ sha: c.sha.slice(0, 7),
130
+ fullSha: c.sha,
131
+ title: c.commit.message.split("\n")[0],
132
+ body: c.commit.message.split("\n").slice(1).join("\n").trim(),
133
+ url: c.html_url,
134
+ date:
135
+ c.commit.author?.date || c.commit.committer?.date || null,
136
+ author: c.commit.author?.name || "Unknown",
137
+ repo: repo.full_name,
138
+ repoName: repo.name,
139
+ repoUrl: repo.html_url,
140
+ category: categorizeRepo(repo.name),
141
+ }));
142
+ } catch {
143
+ return [];
144
+ }
145
+ }),
146
+ );
147
+ allCommits.push(...results.flat());
148
+ }
149
+
150
+ // Sort by date descending
151
+ allCommits.sort(
152
+ (a, b) => new Date(b.date || 0) - new Date(a.date || 0),
153
+ );
154
+
155
+ response.json({
156
+ commits: allCommits,
157
+ categories,
158
+ totalCommits: allCommits.length,
159
+ days: daysValue,
160
+ generatedAt: new Date().toISOString(),
161
+ });
162
+ } catch (error) {
163
+ next(error);
164
+ }
165
+ },
166
+ };
@@ -43,7 +43,7 @@ async function fetchCommitsFromRepos(client, username, limit = 10) {
43
43
  .toSorted((a, b) => new Date(b.date) - new Date(a.date))
44
44
  .slice(0, limit);
45
45
  } catch (error) {
46
- console.error("[dashboard] Error fetching commits from repos:", error.message);
46
+ console.error("[GitHub] Error fetching commits from repos:", error.message);
47
47
  return [];
48
48
  }
49
49
  }
@@ -89,7 +89,7 @@ async function fetchContributionsFromSearch(client, username, limit = 10) {
89
89
  .toSorted((a, b) => new Date(b.date) - new Date(a.date))
90
90
  .slice(0, limit);
91
91
  } catch (error) {
92
- console.error("[dashboard] Error fetching contributions from search:", error.message);
92
+ console.error("[GitHub] Error fetching contributions:", error.message);
93
93
  return [];
94
94
  }
95
95
  }
@@ -101,12 +101,9 @@ async function fetchContributionsFromSearch(client, username, limit = 10) {
101
101
  export const dashboardController = {
102
102
  async get(request, response, next) {
103
103
  try {
104
- console.log("[GitHub Endpoint] Dashboard controller started");
105
-
106
104
  const { githubConfig } = request.app.locals.application;
107
105
 
108
106
  if (!githubConfig) {
109
- console.error("[GitHub Endpoint] ERROR: githubConfig is undefined");
110
107
  return response.status(500).render("github", {
111
108
  title: "GitHub",
112
109
  actions: [],
@@ -115,16 +112,8 @@ export const dashboardController = {
115
112
  }
116
113
 
117
114
  const { username, token, cacheTtl, limits, featuredRepos } = githubConfig;
118
- console.log("[GitHub Endpoint] Config:", {
119
- username,
120
- hasToken: !!token,
121
- cacheTtl,
122
- limits,
123
- featuredRepos: featuredRepos || [],
124
- });
125
115
 
126
116
  if (!username) {
127
- console.log("[GitHub Endpoint] No username configured");
128
117
  return response.render("github", {
129
118
  title: response.locals.__("github.title"),
130
119
  actions: [],
@@ -133,7 +122,6 @@ export const dashboardController = {
133
122
  }
134
123
 
135
124
  const client = new GitHubClient({ token, cacheTtl });
136
- console.log("[GitHub Endpoint] Using authenticated API:", !!token);
137
125
 
138
126
  let user;
139
127
  let events = [];
@@ -141,20 +129,14 @@ export const dashboardController = {
141
129
  let repos = [];
142
130
 
143
131
  try {
144
- console.log("[GitHub Endpoint] Fetching GitHub data for:", username);
145
132
  [user, events, starred, repos] = await Promise.all([
146
133
  client.getUser(username),
147
134
  client.getUserEvents(username, 30),
148
135
  client.getUserStarred(username, limits.stars),
149
136
  client.getUserRepos(username, limits.repos || 10),
150
137
  ]);
151
- console.log("[GitHub Endpoint] Raw user data:", JSON.stringify(user));
152
- console.log("[GitHub Endpoint] Events count:", events?.length);
153
- console.log("[GitHub Endpoint] Event types:", events?.map(e => e.type));
154
- console.log("[GitHub Endpoint] Starred count:", starred?.length);
155
- console.log("[GitHub Endpoint] Repos count:", repos?.length);
156
138
  } catch (apiError) {
157
- console.error("[GitHub Endpoint] API error:", apiError);
139
+ console.error("[GitHub] API error:", apiError.message);
158
140
  return response.render("github", {
159
141
  title: response.locals.__("github.title"),
160
142
  actions: [],
@@ -162,37 +144,26 @@ export const dashboardController = {
162
144
  });
163
145
  }
164
146
 
165
- console.log("[GitHub Endpoint] Processing data...");
166
147
  let commits = utils.extractCommits(events);
167
- console.log("[GitHub Endpoint] Extracted commits from events:", commits?.length);
168
148
 
169
149
  // Fallback: fetch commits directly from repos if events didn't have them
170
150
  if (commits.length === 0) {
171
- console.log("[GitHub Endpoint] Events API returned no commits, fetching from repos");
172
151
  commits = await fetchCommitsFromRepos(client, username, limits.commits || 10);
173
- console.log("[GitHub Endpoint] Fetched commits from repos:", commits?.length);
174
152
  }
175
153
 
176
154
  let contributions = utils.extractContributions(events);
177
- console.log("[GitHub Endpoint] Extracted contributions from events:", contributions?.length);
178
155
 
179
156
  // Fallback: use Search API if events didn't have contributions
180
157
  if (contributions.length === 0) {
181
- console.log("[GitHub Endpoint] Events API returned no contributions, using Search API");
182
158
  contributions = await fetchContributionsFromSearch(client, username, limits.contributions || 10);
183
- console.log("[GitHub Endpoint] Fetched contributions from search:", contributions?.length);
184
159
  }
185
160
 
186
161
  const stars = utils.formatStarred(starred);
187
- console.log("[GitHub Endpoint] Formatted stars:", stars?.length);
188
-
189
162
  const repositories = utils.formatRepos(repos);
190
- console.log("[GitHub Endpoint] Formatted repos:", repositories?.length);
191
163
 
192
164
  // Fetch commits from featured repos
193
165
  let featured = [];
194
166
  if (featuredRepos && featuredRepos.length > 0) {
195
- console.log("[GitHub Endpoint] Fetching featured repos:", featuredRepos);
196
167
  const featuredPromises = featuredRepos.map(async (repoPath) => {
197
168
  const [owner, repo] = repoPath.split("/");
198
169
  try {
@@ -211,34 +182,26 @@ export const dashboardController = {
211
182
  })),
212
183
  };
213
184
  } catch (error) {
214
- console.error(`[GitHub Endpoint] Error fetching ${repoPath}:`, error.message);
185
+ console.error(`[GitHub] Error fetching ${repoPath}:`, error.message);
215
186
  return null;
216
187
  }
217
188
  });
218
189
  featured = (await Promise.all(featuredPromises)).filter(Boolean);
219
- console.log("[GitHub Endpoint] Featured repos loaded:", featured.length);
220
190
  }
221
191
 
222
- const starsLimit = limits.stars || 20;
223
- const reposLimit = limits.repos || 10;
224
-
225
- console.log("[GitHub Endpoint] Rendering with limits - stars:", starsLimit, "repos:", reposLimit);
226
-
227
192
  response.render("github", {
228
193
  title: response.locals.__("github.title"),
229
194
  actions: [],
230
195
  user,
231
196
  commits: commits.slice(0, limits.commits || 10),
232
197
  contributions: contributions.slice(0, limits.contributions || 5),
233
- stars: stars.slice(0, starsLimit),
234
- repositories: repositories.slice(0, reposLimit),
198
+ stars: stars.slice(0, limits.stars || 20),
199
+ repositories: repositories.slice(0, limits.repos || 10),
235
200
  featured,
236
201
  mountPath: request.baseUrl,
237
202
  });
238
- console.log("[GitHub Endpoint] Render complete");
239
203
  } catch (error) {
240
- console.error("[GitHub Endpoint] Unexpected error:", error);
241
- console.error("[GitHub Endpoint] Stack:", error.stack);
204
+ console.error("[GitHub] Unexpected error:", error);
242
205
  next(error);
243
206
  }
244
207
  },
@@ -71,10 +71,15 @@ export class GitHubClient {
71
71
  * @param {string} owner - Repository owner
72
72
  * @param {string} repo - Repository name
73
73
  * @param {number} [limit] - Number of commits to fetch
74
+ * @param {string} [since] - ISO 8601 date string to filter commits after
74
75
  * @returns {Promise<Array>} - Repository commits
75
76
  */
76
- async getRepoCommits(owner, repo, limit = 10) {
77
- return this.fetch(`/repos/${owner}/${repo}/commits?per_page=${limit}`);
77
+ async getRepoCommits(owner, repo, limit = 10, since = null) {
78
+ let endpoint = `/repos/${owner}/${repo}/commits?per_page=${limit}`;
79
+ if (since) {
80
+ endpoint += `&since=${since}`;
81
+ }
82
+ return this.fetch(endpoint);
78
83
  }
79
84
 
80
85
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-github",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "GitHub activity endpoint for Indiekit. Display commits, stars, contributions, and featured repositories.",
5
5
  "keywords": [
6
6
  "indiekit",
@@ -1,6 +1,6 @@
1
- {% extends "document.njk" %}
1
+ {% extends "layouts/github.njk" %}
2
2
 
3
- {% block content %}
3
+ {% block github %}
4
4
  {% if error %}
5
5
  {{ prose({ text: error.message }) }}
6
6
  {% elif activity and activity.length > 0 %}
package/views/commits.njk CHANGED
@@ -1,6 +1,6 @@
1
- {% extends "document.njk" %}
1
+ {% extends "layouts/github.njk" %}
2
2
 
3
- {% block content %}
3
+ {% block github %}
4
4
  {% if error %}
5
5
  {{ prose({ text: error.message }) }}
6
6
  {% elif commits and commits.length > 0 %}
@@ -1,6 +1,6 @@
1
- {% extends "document.njk" %}
1
+ {% extends "layouts/github.njk" %}
2
2
 
3
- {% block content %}
3
+ {% block github %}
4
4
  {% if error %}
5
5
  {{ prose({ text: error.message }) }}
6
6
  {% elif contributions and contributions.length > 0 %}
package/views/github.njk CHANGED
@@ -1,13 +1,12 @@
1
- {% extends "document.njk" %}
1
+ {% extends "layouts/github.njk" %}
2
2
 
3
- {% block content %}
3
+ {% block github %}
4
4
  {% if error %}
5
5
  {{ prose({ text: error.message }) }}
6
6
  {% else %}
7
7
  {# Featured Projects #}
8
8
  {% if featured and featured.length > 0 %}
9
- <section class="github-section">
10
- <h2>{{ __("github.featured.title") }}</h2>
9
+ {% call section({ title: __("github.featured.title") }) %}
11
10
  <div class="github-featured">
12
11
  {% for repo in featured %}
13
12
  <article class="github-featured__repo">
@@ -30,8 +29,7 @@
30
29
  {% endif %}
31
30
  </div>
32
31
  {% if repo.commits and repo.commits.length > 0 %}
33
- <details class="github-featured__commits">
34
- <summary>Recent commits ({{ repo.commits.length }})</summary>
32
+ {% call details({ summary: "Recent commits (" ~ repo.commits.length ~ ")" }) %}
35
33
  <ul class="github-commit-list">
36
34
  {% for commit in repo.commits %}
37
35
  <li>
@@ -41,17 +39,16 @@
41
39
  </li>
42
40
  {% endfor %}
43
41
  </ul>
44
- </details>
42
+ {% endcall %}
45
43
  {% endif %}
46
44
  </article>
47
45
  {% endfor %}
48
46
  </div>
49
- </section>
47
+ {% endcall %}
50
48
  {% endif %}
51
49
 
52
50
  {# Recent Commits #}
53
- <section class="github-section">
54
- <h2>{{ __("github.commits.title") }}</h2>
51
+ {% call section({ title: __("github.commits.title") }) %}
55
52
  {% if commits and commits.length > 0 %}
56
53
  <ul class="github-list">
57
54
  {% for commit in commits %}
@@ -67,11 +64,10 @@
67
64
  {% else %}
68
65
  {{ prose({ text: __("github.commits.none") }) }}
69
66
  {% endif %}
70
- </section>
67
+ {% endcall %}
71
68
 
72
69
  {# Recently Starred #}
73
- <section class="github-section">
74
- <h2>{{ __("github.stars.title") }}</h2>
70
+ {% call section({ title: __("github.stars.title") }) %}
75
71
  {% if stars and stars.length > 0 %}
76
72
  <ul class="github-list github-list--grid">
77
73
  {% for star in stars %}
@@ -92,12 +88,11 @@
92
88
  {% else %}
93
89
  {{ prose({ text: __("github.stars.none") }) }}
94
90
  {% endif %}
95
- </section>
91
+ {% endcall %}
96
92
 
97
93
  {# PRs & Issues #}
98
94
  {% if contributions and contributions.length > 0 %}
99
- <section class="github-section">
100
- <h2>{{ __("github.contributions.title") }}</h2>
95
+ {% call section({ title: __("github.contributions.title") }) %}
101
96
  <ul class="github-list">
102
97
  {% for item in contributions %}
103
98
  <li class="github-list__item">
@@ -113,12 +108,11 @@
113
108
  </li>
114
109
  {% endfor %}
115
110
  </ul>
116
- </section>
111
+ {% endcall %}
117
112
  {% endif %}
118
113
 
119
114
  {# My Repositories #}
120
- <section class="github-section">
121
- <h2>{{ __("github.repos.title") }}</h2>
115
+ {% call section({ title: __("github.repos.title") }) %}
122
116
  {% if repositories and repositories.length > 0 %}
123
117
  <ul class="github-list github-list--grid">
124
118
  {% for repo in repositories %}
@@ -150,6 +144,6 @@
150
144
  {% else %}
151
145
  {{ prose({ text: __("github.repos.none") }) }}
152
146
  {% endif %}
153
- </section>
147
+ {% endcall %}
154
148
  {% endif %}
155
149
  {% endblock %}
@@ -0,0 +1,6 @@
1
+ {% extends "document.njk" %}
2
+
3
+ {% block content %}
4
+ <link rel="stylesheet" href="/assets/@rmdes-indiekit-endpoint-github/styles.css">
5
+ {% block github %}{% endblock %}
6
+ {% endblock %}
package/views/stars.njk CHANGED
@@ -1,6 +1,6 @@
1
- {% extends "document.njk" %}
1
+ {% extends "layouts/github.njk" %}
2
2
 
3
- {% block content %}
3
+ {% block github %}
4
4
  {% if error %}
5
5
  {{ prose({ text: error.message }) }}
6
6
  {% elif stars and stars.length > 0 %}