@turnipxenon/pineapple 5.2.0-alpha.1 → 5.2.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.
@@ -6,7 +6,7 @@
6
6
  import { PinyaCard } from "../../elements/PinyaCard";
7
7
  import type { ProjectGroup, SnippetMeta } from "./";
8
8
  import { SectionType } from "./props";
9
- import { getCommitDateRemote } from "../../../util/getCommitDate.remote";
9
+ import { getCommitDate } from "../../../util/getCommitDate";
10
10
  import { onMount } from "svelte";
11
11
 
12
12
  let {
@@ -39,7 +39,7 @@
39
39
  if (refs.length === 0) return;
40
40
 
41
41
  try {
42
- const dates = await getCommitDateRemote(refs);
42
+ const dates = await getCommitDate(refs);
43
43
  resolvedEntryList = entryList.map(e => {
44
44
  const d = dates[e.key];
45
45
  if (!d) return e;
@@ -0,0 +1,14 @@
1
+ interface CommitDateRequest {
2
+ key: string;
3
+ startCommit?: string;
4
+ endCommit?: string;
5
+ gitRepoLink?: string;
6
+ }
7
+ interface ResolvedDates {
8
+ dateStarted?: string;
9
+ dateFinished?: string;
10
+ commitCount?: number;
11
+ }
12
+ export declare function getCommitDate(refs: CommitDateRequest[]): Promise<Record<string, ResolvedDates>>;
13
+ export {};
14
+ //# sourceMappingURL=getCommitDate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getCommitDate.d.ts","sourceRoot":"","sources":["../../src/lib/util/getCommitDate.ts"],"names":[],"mappings":"AAAA,UAAU,iBAAiB;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,aAAa;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAgFD,wBAAsB,aAAa,CAClC,IAAI,EAAE,iBAAiB,EAAE,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAgExC"}
@@ -0,0 +1,143 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ // localStorage cache to avoid hitting GitHub's 60 req/hr unauthenticated rate limit.
11
+ // Specific commit SHAs are immutable, so cache for 24h. Dynamic queries (latest commit,
12
+ // commit count) can change, so cache for 24h (staleness is acceptable for a portfolio).
13
+ // Safe to use localStorage here since this is only ever called from onMount (client-only).
14
+ const CACHE_PREFIX = "pineapple:github:";
15
+ const IMMUTABLE_TTL = 24 * 60 * 60 * 1000;
16
+ const DYNAMIC_TTL = 24 * 60 * 60 * 1000;
17
+ function githubFetch(url, ttlMs) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ const cacheKey = CACHE_PREFIX + url;
20
+ try {
21
+ const raw = localStorage.getItem(cacheKey);
22
+ if (raw) {
23
+ const cached = JSON.parse(raw);
24
+ if (Date.now() < cached.expiresAt) {
25
+ return cached.data;
26
+ }
27
+ }
28
+ }
29
+ catch (_a) {
30
+ // localStorage unavailable or parse error — proceed with fetch
31
+ }
32
+ try {
33
+ const res = yield fetch(url, { headers: { Accept: "application/vnd.github.v3+json" } });
34
+ if (!res.ok)
35
+ return null;
36
+ const data = yield res.json();
37
+ try {
38
+ localStorage.setItem(cacheKey, JSON.stringify({ data, expiresAt: Date.now() + ttlMs }));
39
+ }
40
+ catch (_b) {
41
+ // localStorage write failed (e.g. storage full) — ignore
42
+ }
43
+ return data;
44
+ }
45
+ catch (_c) {
46
+ return null;
47
+ }
48
+ });
49
+ }
50
+ function parseGithubCommitUrl(url) {
51
+ const match = url.match(/github\.com\/([^/]+)\/([^/]+)\/commit\/([a-f0-9]+)/i);
52
+ if (!match)
53
+ return null;
54
+ return { owner: match[1], repo: match[2], sha: match[3] };
55
+ }
56
+ function parseGithubRepoUrl(url) {
57
+ const match = url.match(/github\.com\/([^/]+)\/([^/]+)/i);
58
+ if (!match)
59
+ return null;
60
+ return { owner: match[1], repo: match[2].replace(/\.git$/, "") };
61
+ }
62
+ function fetchCommitDate(owner, repo, sha) {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ var _a, _b, _c;
65
+ const data = yield githubFetch(`https://api.github.com/repos/${owner}/${repo}/commits/${sha}`, IMMUTABLE_TTL);
66
+ return (_c = (_b = (_a = data === null || data === void 0 ? void 0 : data.commit) === null || _a === void 0 ? void 0 : _a.committer) === null || _b === void 0 ? void 0 : _b.date) !== null && _c !== void 0 ? _c : null;
67
+ });
68
+ }
69
+ function fetchLatestCommitDate(owner, repo) {
70
+ return __awaiter(this, void 0, void 0, function* () {
71
+ var _a, _b, _c;
72
+ const data = yield githubFetch(`https://api.github.com/repos/${owner}/${repo}/commits?sha=main&per_page=1`, DYNAMIC_TTL);
73
+ if (!Array.isArray(data) || data.length === 0)
74
+ return null;
75
+ return (_c = (_b = (_a = data[0].commit) === null || _a === void 0 ? void 0 : _a.committer) === null || _b === void 0 ? void 0 : _b.date) !== null && _c !== void 0 ? _c : null;
76
+ });
77
+ }
78
+ function fetchCommitCount(owner, repo, baseSha, headSha) {
79
+ return __awaiter(this, void 0, void 0, function* () {
80
+ var _a;
81
+ const data = yield githubFetch(`https://api.github.com/repos/${owner}/${repo}/compare/${baseSha}...${headSha}`, DYNAMIC_TTL);
82
+ return (_a = data === null || data === void 0 ? void 0 : data.total_commits) !== null && _a !== void 0 ? _a : null;
83
+ });
84
+ }
85
+ export function getCommitDate(refs) {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ const result = {};
88
+ const promises = [];
89
+ for (const ref of refs) {
90
+ const dates = {};
91
+ result[ref.key] = dates;
92
+ if (ref.startCommit) {
93
+ const parsed = parseGithubCommitUrl(ref.startCommit);
94
+ if (parsed) {
95
+ promises.push(fetchCommitDate(parsed.owner, parsed.repo, parsed.sha).then((d) => {
96
+ if (d)
97
+ dates.dateStarted = d;
98
+ }));
99
+ }
100
+ }
101
+ if (ref.endCommit) {
102
+ const parsed = parseGithubCommitUrl(ref.endCommit);
103
+ if (parsed) {
104
+ promises.push(fetchCommitDate(parsed.owner, parsed.repo, parsed.sha).then((d) => {
105
+ if (d)
106
+ dates.dateFinished = d;
107
+ }));
108
+ }
109
+ }
110
+ else if (ref.gitRepoLink) {
111
+ const parsed = parseGithubRepoUrl(ref.gitRepoLink);
112
+ if (parsed) {
113
+ promises.push(fetchLatestCommitDate(parsed.owner, parsed.repo).then((d) => {
114
+ if (d)
115
+ dates.dateFinished = d;
116
+ }));
117
+ }
118
+ }
119
+ if (ref.startCommit) {
120
+ const startParsed = parseGithubCommitUrl(ref.startCommit);
121
+ if (startParsed) {
122
+ if (ref.endCommit) {
123
+ const endParsed = parseGithubCommitUrl(ref.endCommit);
124
+ if (endParsed && endParsed.owner === startParsed.owner && endParsed.repo === startParsed.repo) {
125
+ promises.push(fetchCommitCount(startParsed.owner, startParsed.repo, startParsed.sha, endParsed.sha).then((c) => {
126
+ if (c != null)
127
+ dates.commitCount = c;
128
+ }));
129
+ }
130
+ }
131
+ else if (ref.gitRepoLink) {
132
+ promises.push(fetchCommitCount(startParsed.owner, startParsed.repo, startParsed.sha, "main").then((c) => {
133
+ if (c != null)
134
+ dates.commitCount = c;
135
+ }));
136
+ }
137
+ }
138
+ }
139
+ }
140
+ yield Promise.all(promises);
141
+ return result;
142
+ });
143
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@turnipxenon/pineapple",
3
3
  "description": "personal package for base styling for other personal projects",
4
- "version": "5.2.0-alpha.1",
4
+ "version": "5.2.0",
5
5
  "devDependencies": {
6
6
  "@commitlint/cli": "^19.8.1",
7
7
  "@commitlint/config-conventional": "^19.8.1",