Add GitHub fork status test coverage
This commit is contained in:
parent
ba32f4e8f7
commit
e3745e24e8
47
__tests__/github.test.ts
Normal file
47
__tests__/github.test.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { getGitHubMetaWithFallback, getGitHubPublicFork } from '@/admin/github';
|
||||
import { TEMPLATE_BASE_OWNER, TEMPLATE_BASE_REPO } from '@/site/config';
|
||||
|
||||
describe('GitHub', () => {
|
||||
it('fetches base repo meta', async () => {
|
||||
const meta = await getGitHubMetaWithFallback({
|
||||
owner: TEMPLATE_BASE_OWNER,
|
||||
repo: TEMPLATE_BASE_REPO,
|
||||
});
|
||||
expect(meta).toBeDefined();
|
||||
expect(meta.url).toBeDefined();
|
||||
expect(meta.isForkedFromBase).toEqual(false);
|
||||
expect(meta.label).toBeDefined();
|
||||
expect(meta.title).toBeDefined();
|
||||
expect(meta.isBehind).toEqual(false);
|
||||
expect(meta.isBaseRepo).toBe(true);
|
||||
});
|
||||
it('fetches fork meta', async () => {
|
||||
const fork = await getGitHubPublicFork();
|
||||
const metaFork = await getGitHubMetaWithFallback(fork);
|
||||
expect(metaFork.isForkedFromBase).toEqual(true);
|
||||
});
|
||||
it('handles nonexistent repos', async () => {
|
||||
const meta = await getGitHubMetaWithFallback({
|
||||
owner: 'nonexistent',
|
||||
repo: 'nonexistent',
|
||||
});
|
||||
expect(meta).toBeDefined();
|
||||
expect(meta.url).toBeDefined();
|
||||
expect(meta.isForkedFromBase).toEqual(false);
|
||||
expect(meta.label).toEqual('Unknown');
|
||||
expect(meta.title).toEqual('Unknown');
|
||||
expect(meta.isBehind).toBeUndefined();
|
||||
});
|
||||
it('handles fetch errors', async () => {
|
||||
const meta = await getGitHubMetaWithFallback({
|
||||
owner: 'gibberish / / *',
|
||||
repo: 'bad text for a url.com',
|
||||
});
|
||||
expect(meta).toBeDefined();
|
||||
expect(meta.url).toBeDefined();
|
||||
expect(meta.isForkedFromBase).toEqual(false);
|
||||
expect(meta.label).toEqual('Unknown');
|
||||
expect(meta.title).toEqual('Unknown');
|
||||
expect(meta.isBehind).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@ -1,4 +1,5 @@
|
||||
/* eslint-disable max-len */
|
||||
import type { Config } from 'jest';
|
||||
import nextJest from 'next/jest.js';
|
||||
|
||||
const createJestConfig = nextJest({
|
||||
@ -7,12 +8,10 @@ const createJestConfig = nextJest({
|
||||
});
|
||||
|
||||
// Add any custom config to be passed to Jest
|
||||
/** @type {import('jest').Config} */
|
||||
const config = {
|
||||
// Add more setup options before each test is run
|
||||
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
|
||||
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
const config: Config = {
|
||||
coverageProvider: 'v8',
|
||||
testEnvironment: 'jsdom',
|
||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||
};
|
||||
|
||||
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
|
||||
1
jest.setup.ts
Normal file
1
jest.setup.ts
Normal file
@ -0,0 +1 @@
|
||||
import 'cross-fetch/polyfill';
|
||||
@ -47,6 +47,7 @@
|
||||
"@next/bundle-analyzer": "15.1.6",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.2.0",
|
||||
"@types/jest": "^29.5.14",
|
||||
@ -57,12 +58,14 @@
|
||||
"@types/sanitize-html": "^2.13.0",
|
||||
"autoprefixer": "10.4.20",
|
||||
"clsx": "^2.1.1",
|
||||
"cross-fetch": "^4.1.0",
|
||||
"eslint": "9.18.0",
|
||||
"eslint-config-next": "15.1.6",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"postcss": "8.5.1",
|
||||
"tailwindcss": "3.4.17",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "5.7.3"
|
||||
}
|
||||
}
|
||||
|
||||
209
pnpm-lock.yaml
generated
209
pnpm-lock.yaml
generated
@ -113,16 +113,19 @@ importers:
|
||||
version: 15.1.6
|
||||
'@tailwindcss/container-queries':
|
||||
specifier: ^0.1.1
|
||||
version: 0.1.1(tailwindcss@3.4.17)
|
||||
version: 0.1.1(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)))
|
||||
'@tailwindcss/forms':
|
||||
specifier: ^0.5.10
|
||||
version: 0.5.10(tailwindcss@3.4.17)
|
||||
version: 0.5.10(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)))
|
||||
'@testing-library/dom':
|
||||
specifier: ^10.4.0
|
||||
version: 10.4.0
|
||||
'@testing-library/jest-dom':
|
||||
specifier: ^6.6.3
|
||||
version: 6.6.3
|
||||
'@testing-library/react':
|
||||
specifier: ^16.2.0
|
||||
version: 16.2.0(@testing-library/dom@10.1.0)(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 16.2.0(@testing-library/dom@10.4.0)(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@types/jest':
|
||||
specifier: ^29.5.14
|
||||
version: 29.5.14
|
||||
@ -147,6 +150,9 @@ importers:
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
cross-fetch:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
eslint:
|
||||
specifier: 9.18.0
|
||||
version: 9.18.0(jiti@1.21.7)
|
||||
@ -155,7 +161,7 @@ importers:
|
||||
version: 15.1.6(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3)
|
||||
jest:
|
||||
specifier: ^29.7.0
|
||||
version: 29.7.0(@types/node@22.10.7)
|
||||
version: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
jest-environment-jsdom:
|
||||
specifier: ^29.7.0
|
||||
version: 29.7.0
|
||||
@ -164,7 +170,10 @@ importers:
|
||||
version: 8.5.1
|
||||
tailwindcss:
|
||||
specifier: 3.4.17
|
||||
version: 3.4.17
|
||||
version: 3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@types/node@22.10.7)(typescript@5.7.3)
|
||||
typescript:
|
||||
specifier: 5.7.3
|
||||
version: 5.7.3
|
||||
@ -566,6 +575,10 @@ packages:
|
||||
'@bcoe/v8-coverage@0.2.3':
|
||||
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@discoveryjs/json-ext@0.5.7':
|
||||
resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@ -847,6 +860,9 @@ packages:
|
||||
'@jridgewell/trace-mapping@0.3.25':
|
||||
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||
|
||||
'@next/bundle-analyzer@15.1.6':
|
||||
resolution: {integrity: sha512-hGzQyDqJzFHcHNCyTqM3o05BpVq5tGnRODccZBVJDBf5Miv/26UJPMB0wh9L9j3ylgHC+0/v8BaBnBBek1rC6Q==}
|
||||
|
||||
@ -1487,8 +1503,8 @@ packages:
|
||||
peerDependencies:
|
||||
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
|
||||
|
||||
'@testing-library/dom@10.1.0':
|
||||
resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==}
|
||||
'@testing-library/dom@10.4.0':
|
||||
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@testing-library/jest-dom@6.6.3':
|
||||
@ -1514,6 +1530,18 @@ packages:
|
||||
resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
'@tsconfig/node10@1.0.11':
|
||||
resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
|
||||
|
||||
'@tsconfig/node12@1.0.11':
|
||||
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
|
||||
|
||||
'@tsconfig/node14@1.0.3':
|
||||
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
|
||||
|
||||
'@tsconfig/node16@1.0.4':
|
||||
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
|
||||
|
||||
'@types/aria-query@5.0.4':
|
||||
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
|
||||
|
||||
@ -1819,6 +1847,9 @@ packages:
|
||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
arg@4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
|
||||
arg@5.0.2:
|
||||
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
||||
|
||||
@ -2112,6 +2143,12 @@ packages:
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
||||
create-require@1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
|
||||
cross-fetch@4.1.0:
|
||||
resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
engines: {node: '>= 8'}
|
||||
@ -2250,6 +2287,10 @@ packages:
|
||||
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
|
||||
diff@4.0.2:
|
||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
||||
dlv@1.1.3:
|
||||
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
||||
|
||||
@ -3217,6 +3258,9 @@ packages:
|
||||
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
make-error@1.3.6:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
|
||||
makeerror@1.0.12:
|
||||
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
|
||||
|
||||
@ -3355,6 +3399,15 @@ packages:
|
||||
sass:
|
||||
optional: true
|
||||
|
||||
node-fetch@2.7.0:
|
||||
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
peerDependencies:
|
||||
encoding: ^0.1.0
|
||||
peerDependenciesMeta:
|
||||
encoding:
|
||||
optional: true
|
||||
|
||||
node-int64@0.4.0:
|
||||
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
|
||||
|
||||
@ -4098,6 +4151,9 @@ packages:
|
||||
resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tr46@0.0.3:
|
||||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
|
||||
tr46@3.0.0:
|
||||
resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==}
|
||||
engines: {node: '>=12'}
|
||||
@ -4114,6 +4170,20 @@ packages:
|
||||
ts-interface-checker@0.1.13:
|
||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||
|
||||
ts-node@10.9.2:
|
||||
resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@swc/core': '>=1.2.50'
|
||||
'@swc/wasm': '>=1.2.50'
|
||||
'@types/node': '*'
|
||||
typescript: '>=2.7'
|
||||
peerDependenciesMeta:
|
||||
'@swc/core':
|
||||
optional: true
|
||||
'@swc/wasm':
|
||||
optional: true
|
||||
|
||||
tsconfig-paths@3.15.0:
|
||||
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
|
||||
|
||||
@ -4233,6 +4303,9 @@ packages:
|
||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||
hasBin: true
|
||||
|
||||
v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
|
||||
v8-to-istanbul@9.2.0:
|
||||
resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==}
|
||||
engines: {node: '>=10.12.0'}
|
||||
@ -4255,6 +4328,9 @@ packages:
|
||||
walker@1.0.8:
|
||||
resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
|
||||
|
||||
webidl-conversions@3.0.1:
|
||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||
|
||||
webidl-conversions@7.0.0:
|
||||
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
|
||||
engines: {node: '>=12'}
|
||||
@ -4276,6 +4352,9 @@ packages:
|
||||
resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
which-boxed-primitive@1.1.1:
|
||||
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -4371,6 +4450,10 @@ packages:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yn@3.1.1:
|
||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
@ -5121,6 +5204,10 @@ snapshots:
|
||||
|
||||
'@bcoe/v8-coverage@0.2.3': {}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
|
||||
'@discoveryjs/json-ext@0.5.7': {}
|
||||
|
||||
'@emnapi/runtime@1.2.0':
|
||||
@ -5305,7 +5392,7 @@ snapshots:
|
||||
jest-util: 29.7.0
|
||||
slash: 3.0.0
|
||||
|
||||
'@jest/core@29.7.0':
|
||||
'@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))':
|
||||
dependencies:
|
||||
'@jest/console': 29.7.0
|
||||
'@jest/reporters': 29.7.0
|
||||
@ -5319,7 +5406,7 @@ snapshots:
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-changed-files: 29.7.0
|
||||
jest-config: 29.7.0(@types/node@22.10.7)
|
||||
jest-config: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
jest-haste-map: 29.7.0
|
||||
jest-message-util: 29.7.0
|
||||
jest-regex-util: 29.6.3
|
||||
@ -5475,6 +5562,11 @@ snapshots:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
'@next/bundle-analyzer@15.1.6':
|
||||
dependencies:
|
||||
webpack-bundle-analyzer: 4.10.1
|
||||
@ -6169,16 +6261,16 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@tailwindcss/container-queries@0.1.1(tailwindcss@3.4.17)':
|
||||
'@tailwindcss/container-queries@0.1.1(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)))':
|
||||
dependencies:
|
||||
tailwindcss: 3.4.17
|
||||
tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
|
||||
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.17)':
|
||||
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)))':
|
||||
dependencies:
|
||||
mini-svg-data-uri: 1.4.4
|
||||
tailwindcss: 3.4.17
|
||||
tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
|
||||
'@testing-library/dom@10.1.0':
|
||||
'@testing-library/dom@10.4.0':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.24.2
|
||||
'@babel/runtime': 7.24.5
|
||||
@ -6199,10 +6291,10 @@ snapshots:
|
||||
lodash: 4.17.21
|
||||
redent: 3.0.0
|
||||
|
||||
'@testing-library/react@16.2.0(@testing-library/dom@10.1.0)(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@testing-library/react@16.2.0(@testing-library/dom@10.4.0)(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.24.5
|
||||
'@testing-library/dom': 10.1.0
|
||||
'@testing-library/dom': 10.4.0
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
@ -6211,6 +6303,14 @@ snapshots:
|
||||
|
||||
'@tootallnate/once@2.0.0': {}
|
||||
|
||||
'@tsconfig/node10@1.0.11': {}
|
||||
|
||||
'@tsconfig/node12@1.0.11': {}
|
||||
|
||||
'@tsconfig/node14@1.0.3': {}
|
||||
|
||||
'@tsconfig/node16@1.0.4': {}
|
||||
|
||||
'@types/aria-query@5.0.4': {}
|
||||
|
||||
'@types/babel__core@7.20.5':
|
||||
@ -6552,6 +6652,8 @@ snapshots:
|
||||
normalize-path: 3.0.0
|
||||
picomatch: 2.3.1
|
||||
|
||||
arg@4.1.3: {}
|
||||
|
||||
arg@5.0.2: {}
|
||||
|
||||
argparse@1.0.10:
|
||||
@ -6902,13 +7004,13 @@ snapshots:
|
||||
|
||||
cookie@0.7.1: {}
|
||||
|
||||
create-jest@29.7.0(@types/node@22.10.7):
|
||||
create-jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)):
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
chalk: 4.1.2
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-config: 29.7.0(@types/node@22.10.7)
|
||||
jest-config: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
jest-util: 29.7.0
|
||||
prompts: 2.4.2
|
||||
transitivePeerDependencies:
|
||||
@ -6917,6 +7019,14 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
create-require@1.1.1: {}
|
||||
|
||||
cross-fetch@4.1.0:
|
||||
dependencies:
|
||||
node-fetch: 2.7.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
@ -7029,6 +7139,8 @@ snapshots:
|
||||
|
||||
diff-sequences@29.6.3: {}
|
||||
|
||||
diff@4.0.2: {}
|
||||
|
||||
dlv@1.1.3: {}
|
||||
|
||||
doctrine@2.1.0:
|
||||
@ -7926,16 +8038,16 @@ snapshots:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
|
||||
jest-cli@29.7.0(@types/node@22.10.7):
|
||||
jest-cli@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)):
|
||||
dependencies:
|
||||
'@jest/core': 29.7.0
|
||||
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
chalk: 4.1.2
|
||||
create-jest: 29.7.0(@types/node@22.10.7)
|
||||
create-jest: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
exit: 0.1.2
|
||||
import-local: 3.1.0
|
||||
jest-config: 29.7.0(@types/node@22.10.7)
|
||||
jest-config: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
yargs: 17.7.2
|
||||
@ -7945,7 +8057,7 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
jest-config@29.7.0(@types/node@22.10.7):
|
||||
jest-config@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.24.5
|
||||
'@jest/test-sequencer': 29.7.0
|
||||
@ -7971,6 +8083,7 @@ snapshots:
|
||||
strip-json-comments: 3.1.1
|
||||
optionalDependencies:
|
||||
'@types/node': 22.10.7
|
||||
ts-node: 10.9.2(@types/node@22.10.7)(typescript@5.7.3)
|
||||
transitivePeerDependencies:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
@ -8205,12 +8318,12 @@ snapshots:
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
|
||||
jest@29.7.0(@types/node@22.10.7):
|
||||
jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)):
|
||||
dependencies:
|
||||
'@jest/core': 29.7.0
|
||||
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
'@jest/types': 29.6.3
|
||||
import-local: 3.1.0
|
||||
jest-cli: 29.7.0(@types/node@22.10.7)
|
||||
jest-cli: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
@ -8355,6 +8468,8 @@ snapshots:
|
||||
dependencies:
|
||||
semver: 7.6.3
|
||||
|
||||
make-error@1.3.6: {}
|
||||
|
||||
makeerror@1.0.12:
|
||||
dependencies:
|
||||
tmpl: 1.0.5
|
||||
@ -8465,6 +8580,10 @@ snapshots:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
|
||||
node-fetch@2.7.0:
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
|
||||
node-int64@0.4.0: {}
|
||||
|
||||
node-releases@2.0.14: {}
|
||||
@ -8678,12 +8797,13 @@ snapshots:
|
||||
camelcase-css: 2.0.1
|
||||
postcss: 8.5.1
|
||||
|
||||
postcss-load-config@4.0.2(postcss@8.5.1):
|
||||
postcss-load-config@4.0.2(postcss@8.5.1)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)):
|
||||
dependencies:
|
||||
lilconfig: 3.1.3
|
||||
yaml: 2.4.2
|
||||
optionalDependencies:
|
||||
postcss: 8.5.1
|
||||
ts-node: 10.9.2(@types/node@22.10.7)(typescript@5.7.3)
|
||||
|
||||
postcss-nested@6.2.0(postcss@8.5.1):
|
||||
dependencies:
|
||||
@ -9194,7 +9314,7 @@ snapshots:
|
||||
|
||||
symbol-tree@3.2.4: {}
|
||||
|
||||
tailwindcss@3.4.17:
|
||||
tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3)):
|
||||
dependencies:
|
||||
'@alloc/quick-lru': 5.2.0
|
||||
arg: 5.0.2
|
||||
@ -9213,7 +9333,7 @@ snapshots:
|
||||
postcss: 8.5.1
|
||||
postcss-import: 15.1.0(postcss@8.5.1)
|
||||
postcss-js: 4.0.1(postcss@8.5.1)
|
||||
postcss-load-config: 4.0.2(postcss@8.5.1)
|
||||
postcss-load-config: 4.0.2(postcss@8.5.1)(ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3))
|
||||
postcss-nested: 6.2.0(postcss@8.5.1)
|
||||
postcss-selector-parser: 6.1.2
|
||||
resolve: 1.22.8
|
||||
@ -9256,6 +9376,8 @@ snapshots:
|
||||
universalify: 0.2.0
|
||||
url-parse: 1.5.10
|
||||
|
||||
tr46@0.0.3: {}
|
||||
|
||||
tr46@3.0.0:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
@ -9270,6 +9392,24 @@ snapshots:
|
||||
|
||||
ts-interface-checker@0.1.13: {}
|
||||
|
||||
ts-node@10.9.2(@types/node@22.10.7)(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.11
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 22.10.7
|
||||
acorn: 8.14.0
|
||||
acorn-walk: 8.3.2
|
||||
arg: 4.1.3
|
||||
create-require: 1.1.1
|
||||
diff: 4.0.2
|
||||
make-error: 1.3.6
|
||||
typescript: 5.7.3
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
|
||||
tsconfig-paths@3.15.0:
|
||||
dependencies:
|
||||
'@types/json5': 0.0.29
|
||||
@ -9391,6 +9531,8 @@ snapshots:
|
||||
|
||||
uuid@9.0.1: {}
|
||||
|
||||
v8-compile-cache-lib@3.0.1: {}
|
||||
|
||||
v8-to-istanbul@9.2.0:
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
@ -9418,6 +9560,8 @@ snapshots:
|
||||
dependencies:
|
||||
makeerror: 1.0.12
|
||||
|
||||
webidl-conversions@3.0.1: {}
|
||||
|
||||
webidl-conversions@7.0.0: {}
|
||||
|
||||
webpack-bundle-analyzer@4.10.1:
|
||||
@ -9450,6 +9594,11 @@ snapshots:
|
||||
tr46: 3.0.0
|
||||
webidl-conversions: 7.0.0
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
dependencies:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
which-boxed-primitive@1.1.1:
|
||||
dependencies:
|
||||
is-bigint: 1.1.0
|
||||
@ -9543,6 +9692,8 @@ snapshots:
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
yn@3.1.1: {}
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
zod-to-json-schema@3.24.1(zod@3.23.8):
|
||||
|
||||
@ -4,7 +4,7 @@ import {
|
||||
VERCEL_GIT_REPO_OWNER,
|
||||
VERCEL_GIT_REPO_SLUG,
|
||||
} from '@/site/config';
|
||||
import { getGitHubMeta } from '.';
|
||||
import { getGitHubMetaWithFallback } from '.';
|
||||
|
||||
export default async function GitHubForkStatusBadgeServer() {
|
||||
const owner = VERCEL_GIT_REPO_OWNER;
|
||||
@ -17,24 +17,14 @@ export default async function GitHubForkStatusBadgeServer() {
|
||||
label,
|
||||
title,
|
||||
isBehind,
|
||||
} = await getGitHubMeta({ owner, repo, branch })
|
||||
.catch(() => {
|
||||
console.error('Error retrieving GitHub meta', { owner, repo, branch });
|
||||
return {
|
||||
url: undefined,
|
||||
isForkedFromBase: false,
|
||||
label: undefined,
|
||||
title: undefined,
|
||||
isBehind: undefined,
|
||||
};
|
||||
});
|
||||
} = await getGitHubMetaWithFallback({ owner, repo, branch });
|
||||
|
||||
return isForkedFromBase
|
||||
? <GitHubForkStatusBadgeClient {...{
|
||||
url,
|
||||
label,
|
||||
title,
|
||||
style: isBehind ? 'warning' : 'mono',
|
||||
style: isBehind === undefined || isBehind ? 'warning' : 'mono',
|
||||
}} />
|
||||
: null;
|
||||
}
|
||||
|
||||
@ -6,6 +6,14 @@ import {
|
||||
|
||||
const DEFAULT_BRANCH = 'main';
|
||||
|
||||
const FALLBACK_TEXT = 'Unknown';
|
||||
|
||||
// Cache all results for 2 minutes to avoid rate limiting
|
||||
// GitHub API requests limited to 60 requests per hour
|
||||
const FETCH_CONFIG: RequestInit = {
|
||||
next: { revalidate: 120 },
|
||||
};
|
||||
|
||||
interface RepoParams {
|
||||
owner?: string
|
||||
repo?: string
|
||||
@ -39,6 +47,9 @@ const getGitHubApiRepoUrl = ({
|
||||
const getGitHubApiCommitsUrl = (params?: RepoParams) =>
|
||||
`${getGitHubApiRepoUrl(params)}/commits/main`;
|
||||
|
||||
const getGitHubApiForksUrl = (params?: RepoParams) =>
|
||||
`${getGitHubApiRepoUrl(params)}/forks`;
|
||||
|
||||
const getGitHubApiCompareUrl = ({
|
||||
owner,
|
||||
repo,
|
||||
@ -49,14 +60,14 @@ const getGitHubApiCompareUrl = ({
|
||||
|
||||
// Requests
|
||||
|
||||
const getLatestBaseRepoCommitSha = async () => {
|
||||
const response = await fetch(getGitHubApiCommitsUrl());
|
||||
export const getLatestBaseRepoCommitSha = async () => {
|
||||
const response = await fetch(getGitHubApiCommitsUrl(), FETCH_CONFIG);
|
||||
const data = await response.json();
|
||||
return data.sha.slice(0, 7) as string;
|
||||
return data.sha ? data.sha.slice(0, 7) as string : undefined;
|
||||
};
|
||||
|
||||
const getIsRepoForkedFromBase = async (params: RepoParams) => {
|
||||
const response = await fetch(getGitHubApiRepoUrl(params));
|
||||
const response = await fetch(getGitHubApiRepoUrl(params), FETCH_CONFIG);
|
||||
const data = await response.json();
|
||||
return (
|
||||
Boolean(data.fork) &&
|
||||
@ -65,7 +76,7 @@ const getIsRepoForkedFromBase = async (params: RepoParams) => {
|
||||
};
|
||||
|
||||
const getGitHubCommitsBehind = async (params?: RepoParams) => {
|
||||
const response = await fetch(getGitHubApiCompareUrl(params));
|
||||
const response = await fetch(getGitHubApiCompareUrl(params), FETCH_CONFIG);
|
||||
const data = await response.json();
|
||||
return data.behind_by as number;
|
||||
};
|
||||
@ -74,36 +85,69 @@ const isRepoBaseRepo = async ({ owner, repo }: RepoParams) =>
|
||||
owner?.toLowerCase() === TEMPLATE_BASE_OWNER &&
|
||||
repo?.toLowerCase() === TEMPLATE_BASE_REPO;
|
||||
|
||||
export const getGitHubMeta = async (params: RepoParams) => {
|
||||
export const getGitHubPublicFork = async (
|
||||
params?: RepoParams,
|
||||
): Promise<RepoParams> => {
|
||||
const response = await fetch(getGitHubApiForksUrl(params), FETCH_CONFIG);
|
||||
const fork = (await response.json())[0];
|
||||
return {
|
||||
owner: fork.owner.login,
|
||||
repo: fork.name,
|
||||
};
|
||||
};
|
||||
|
||||
const getGitHubMeta = async (params: RepoParams) => {
|
||||
const [
|
||||
url,
|
||||
isForkedFromBase,
|
||||
isBaseRepo,
|
||||
latestBaseRepoCommitSha,
|
||||
behindBy,
|
||||
] = await Promise.all([
|
||||
getGitHubRepoUrl(params),
|
||||
getIsRepoForkedFromBase(params),
|
||||
isRepoBaseRepo(params),
|
||||
getLatestBaseRepoCommitSha(),
|
||||
getGitHubCommitsBehind(params),
|
||||
]);
|
||||
|
||||
const isBehind = behindBy > 0;
|
||||
const label = isBehind ? `${behindBy} Behind` : 'Synced';
|
||||
const title = isBehind
|
||||
// eslint-disable-next-line max-len
|
||||
? `This fork is ${behindBy} commit${behindBy === 1 ? '' : 's'} behind. Consider syncing on GitHub for the latest updates.`
|
||||
: 'This fork is up to date.';
|
||||
const isBehind = behindBy === undefined
|
||||
? undefined
|
||||
: behindBy > 0;
|
||||
|
||||
const label = isBehind === undefined
|
||||
? FALLBACK_TEXT
|
||||
: isBehind
|
||||
? `${behindBy} Behind`
|
||||
: 'Synced';
|
||||
|
||||
const title = isBehind === undefined
|
||||
? FALLBACK_TEXT
|
||||
: isBehind
|
||||
// eslint-disable-next-line max-len
|
||||
? `This fork is ${behindBy} commit${behindBy === 1 ? '' : 's'} behind. Consider syncing on GitHub for the latest updates.`
|
||||
: 'This fork is up to date.';
|
||||
|
||||
return {
|
||||
url,
|
||||
isForkedFromBase,
|
||||
isBaseRepo,
|
||||
latestBaseRepoCommitSha,
|
||||
behindBy,
|
||||
isBehind,
|
||||
label,
|
||||
title,
|
||||
};
|
||||
};
|
||||
|
||||
export const getGitHubMetaWithFallback = (params: RepoParams) =>
|
||||
getGitHubMeta(params)
|
||||
.catch(e => {
|
||||
console.error('Error retrieving GitHub meta', { params, error: e });
|
||||
return {
|
||||
url: undefined,
|
||||
isForkedFromBase: false,
|
||||
isBaseRepo: undefined,
|
||||
behindBy: undefined,
|
||||
isBehind: undefined,
|
||||
label: FALLBACK_TEXT,
|
||||
title: FALLBACK_TEXT,
|
||||
};
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user