Skip to content

Commit d3655a2

Browse files
committed
i bet this will work
1 parent af67d7e commit d3655a2

13 files changed

Lines changed: 704 additions & 392 deletions

File tree

packages/app/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"vendor:octokit": "tsx script/octokit.ts",
1010
"prepare": "nuxi prepare && pnpm vendor:octokit",
1111
"test": "vitest run",
12-
"test:e2e": "cross-env TEST=true nuxi build && cross-env TEST=true vitest run --update",
1312
"start": "node .output/server/index.mjs",
1413
"start:generate": "npx serve .output/public",
1514
"lint": "eslint .",
@@ -27,7 +26,7 @@
2726
"@vueuse/nuxt": "^12.2.0",
2827
"marked": "^15.0.4",
2928
"nuxt": "^3.15.0",
30-
"octokit": "^3.2.1",
29+
"octokit": "^4.0.2",
3130
"query-registry": "^3.0.1",
3231
"vue": "^3.5.13",
3332
"vue-router": "^4.4.3",
@@ -43,6 +42,8 @@
4342
"@simulacrum/github-api-simulator": "^0.5.4",
4443
"cross-env": "^7.0.3",
4544
"dotenv": "^16.4.5",
45+
"esbuild": "^0.20.2",
46+
"esbuild-plugin-polyfill-node": "^0.3.0",
4647
"eslint": "^9.17.0",
4748
"fast-jwt": "^4.0.2",
4849
"nitro-cloudflare-dev": "0.1.2",

packages/app/script/octokit.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import { fileURLToPath } from "node:url";
21
import esbuild from "esbuild";
32
import { polyfillNode } from "esbuild-plugin-polyfill-node";
3+
import { createRequire } from "node:module";
4+
5+
const require = createRequire(import.meta.url);
6+
const octokitPath = require.resolve("octokit");
47

58
await esbuild.build({
6-
entryPoints: [fileURLToPath(import.meta.resolve("octokit/dist-web"))],
9+
entryPoints: [octokitPath],
710
bundle: true,
811
format: "esm",
912
sourcemap: "inline",
Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
import { z } from 'zod'
1+
import { WorkflowData } from "../../../../types";
22

3-
const paramsSchema = z.object({
4-
owner: z.string(),
5-
repo: z.string(),
6-
npmOrg: z.string(),
7-
packageAndRefOrSha: z.string(),
8-
})
3+
type Params = Omit<WorkflowData, "sha" | "isPullRequest" | "ref"> & {
4+
npmOrg: string;
5+
packageAndRefOrSha: string;
6+
};
97

10-
export default eventHandler(async (event) => {
11-
const params = await getValidatedRouterParams(event, paramsSchema.parse)
12-
const [noScopePackageName, refOrSha] = params.packageAndRefOrSha.split('@')
13-
const packageName = `${params.npmOrg}/${noScopePackageName}`
8+
export default eventHandler((event) => {
9+
const params = getRouterParams(event) as Params;
10+
const [noScopePackageName, refOrSha] = params.packageAndRefOrSha.split("@");
11+
const packageName = params.npmOrg + "/" + noScopePackageName;
1412

1513
sendRedirect(
1614
event,
1715
`/${params.owner}/${params.repo}/${encodeURIComponent(packageName)}@${refOrSha}`,
18-
)
19-
})
16+
);
17+
});
Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,61 @@
1-
import { abbreviateCommitHash } from '@pkg-pr-new/utils'
2-
import { normalizeKey } from 'unstorage'
3-
import { z } from 'zod'
1+
import { abbreviateCommitHash } from "@pkg-pr-new/utils";
2+
import { normalizeKey } from "unstorage";
3+
import { WorkflowData } from "../../../types";
44

5-
const paramsSchema = z.object({
6-
owner: z.string(),
7-
repo: z.string(),
8-
packageAndRefOrSha: z.string(),
9-
})
5+
type Params = Omit<WorkflowData, "sha" | "ref"> & {
6+
packageAndRefOrSha: string;
7+
};
108

119
export default eventHandler(async (event) => {
12-
const params = await getValidatedRouterParams(event, paramsSchema.parse)
13-
let [encodedPackageName, longerRefOrSha] = params.packageAndRefOrSha.split('@')
14-
const packageName = decodeURIComponent(encodedPackageName)
15-
longerRefOrSha = longerRefOrSha.split('.tgz')[0] // yarn support
16-
const isSha = isValidGitHash(longerRefOrSha)
17-
const refOrSha = isSha ? abbreviateCommitHash(longerRefOrSha) : longerRefOrSha
18-
19-
const base = `${params.owner}:${params.repo}:${refOrSha}`
20-
let packageKey = `${base}:${packageName}`
21-
22-
const cursorKey = base
23-
24-
const packagesBucket = usePackagesBucket(event)
25-
const downloadedAtBucket = useDownloadedAtBucket(event)
26-
const cursorBucket = useCursorsBucket(event)
10+
const params = getRouterParams(event) as Params;
11+
// eslint-disable-next-line prefer-const
12+
let [encodedPackageName, longerRefOrSha] =
13+
params.packageAndRefOrSha.split("@");
14+
const packageName = decodeURIComponent(encodedPackageName);
15+
longerRefOrSha = longerRefOrSha.split(".tgz")[0]; // yarn support
16+
const isSha = isValidGitHash(longerRefOrSha);
17+
const refOrSha = isSha
18+
? abbreviateCommitHash(longerRefOrSha)
19+
: longerRefOrSha;
20+
21+
const base = `${params.owner}:${params.repo}:${refOrSha}`;
22+
let packageKey = `${base}:${packageName}`;
23+
24+
const cursorKey = base;
25+
26+
const packagesBucket = usePackagesBucket(event);
27+
const downloadedAtBucket = useDownloadedAtBucket(event);
28+
const cursorBucket = useCursorsBucket(event);
2729

2830
if (await cursorBucket.hasItem(cursorKey)) {
29-
const currentCursor = (await cursorBucket.getItem(cursorKey))!
31+
const currentCursor = (await cursorBucket.getItem(cursorKey))!;
3032

3133
sendRedirect(
3234
event,
3335
`/${params.owner}/${params.repo}/${packageName}@${currentCursor.sha}`,
34-
)
35-
return
36+
);
37+
return;
3638
}
3739

3840
// longer sha support with precision
39-
const binding = useBinding(event)
40-
const { objects } = await binding.list({ prefix: `${usePackagesBucket.base}:${base}` })
41+
const binding = useBinding(event);
42+
const { objects } = await binding.list({
43+
prefix: `${usePackagesBucket.base}:${base}`,
44+
});
4145
for (const { key } of objects) {
4246
// bucket:package:stackblitz-labs:pkg.pr.new:ded05e838c418096e5dd77a29101c8af9e73daea:playground-b
43-
const trimmedKey = key.slice(usePackagesBucket.base.length + 1)
47+
const trimmedKey = key.slice(usePackagesBucket.base.length + 1);
4448

4549
// https://github.com/unjs/unstorage/blob/e42c01d0c22092f394f57e3ec114371fc8dcf6dd/src/drivers/utils/index.ts#L14-L19
46-
const [keySha, ...keyPackageNameParts] = trimmedKey.split(':').slice(2)
47-
const keyPackageName = keyPackageNameParts.join(':')
48-
if (keyPackageName !== normalizeKey(packageName))
49-
continue
50+
const [keySha, ...keyPackageNameParts] = trimmedKey.split(":").slice(2);
51+
const keyPackageName = keyPackageNameParts.join(":");
52+
if (keyPackageName !== normalizeKey(packageName)) {
53+
continue;
54+
}
5055

5156
if (keySha.startsWith(longerRefOrSha)) {
52-
packageKey = trimmedKey
53-
break
57+
packageKey = trimmedKey;
58+
break;
5459
}
5560
}
5661

@@ -59,29 +64,29 @@ export default eventHandler(async (event) => {
5964
event,
6065
usePackagesBucket.base,
6166
packageKey,
62-
)
67+
);
6368
const obj = (await packagesBucket.getMeta(
6469
packageKey,
65-
)) as unknown as R2Object
70+
)) as unknown as R2Object;
6671

6772
await downloadedAtBucket.setItem(
6873
obj.key,
6974
Date.parse(new Date().toString()),
70-
)
75+
);
7176

72-
setResponseHeader(event, 'content-type', 'application/tar+gzip')
77+
setResponseHeader(event, "content-type", "application/tar+gzip");
7378
// TODO: add HTTP caching
74-
return stream
79+
return stream;
7580
}
7681

7782
throw createError({
7883
status: 404,
79-
})
80-
})
84+
});
85+
});
8186

82-
const sha1Regex = /^[a-f0-9]{40}$/i
83-
const sha256Regex = /^[a-f0-9]{64}$/i
87+
const sha1Regex = /^[\da-f]{40}$/i;
88+
const sha256Regex = /^[\da-f]{64}$/i;
8489

8590
function isValidGitHash(hash: string): boolean {
86-
return sha1Regex.test(hash) || sha256Regex.test(hash)
87-
}
91+
return sha1Regex.test(hash) || sha256Regex.test(hash);
92+
}
Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,46 @@
1-
import { extractOwnerAndRepo, extractRepository } from '@pkg-pr-new/utils'
2-
import { getPackageManifest } from 'query-registry'
3-
import { z } from 'zod'
1+
import { getPackageManifest } from "query-registry";
2+
import { extractOwnerAndRepo, extractRepository } from "@pkg-pr-new/utils";
3+
import { WorkflowData } from "../../../types";
44

5-
const paramsSchema = z.object({
6-
owner: z.string(),
7-
repo: z.string(),
8-
})
5+
type Params = Omit<WorkflowData, "sha" | "ref">;
96

107
// https://pkg.pr.new/tinylibs/tinybench@a832a55
118
export default eventHandler(async (event) => {
12-
const params = await getValidatedRouterParams(event, paramsSchema.parse)
13-
const [packageName, refOrSha] = params.repo.split('@')
9+
const params = getRouterParams(event) as Params;
10+
const [packageName, refOrSha] = params.repo.split("@");
1411

1512
// /@stackblitz/sdk@a832a55
16-
if (params.owner.startsWith('@')) {
13+
if (params.owner.startsWith("@")) {
1714
// it's not a short url, it's a scoped package in compact mode
18-
const npmOrg = params.owner
19-
const packageNameWithOrg = `${npmOrg}/${packageName}`
20-
const manifest = await getPackageManifest(packageNameWithOrg)
15+
const npmOrg = params.owner;
16+
const packageNameWithOrg = npmOrg + "/" + packageName;
17+
const manifest = await getPackageManifest(packageNameWithOrg);
2118

22-
const repository = extractRepository(manifest)
19+
const repository = extractRepository(manifest);
2320
if (!repository) {
2421
throw createError({
2522
status: 404,
26-
})
23+
});
2724
}
2825

29-
const match = extractOwnerAndRepo(repository)
26+
const match = extractOwnerAndRepo(repository);
3027
if (!match) {
3128
throw createError({
3229
status: 404,
33-
})
30+
});
3431
}
35-
const [owner, repo] = match
32+
const [owner, repo] = match;
3633

3734
sendRedirect(
3835
event,
3936
`/${owner}/${repo}/${encodeURIComponent(packageNameWithOrg)}@${refOrSha}`,
40-
)
41-
return
37+
);
38+
return;
4239
}
4340

4441
// -> https://pkg.pr.new/tinylibs/tinybench/tinybench@a832a55
4542
sendRedirect(
4643
event,
4744
`/${params.owner}/${packageName}/${packageName}@${refOrSha}`,
48-
)
49-
})
45+
);
46+
});
Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
import { extractOwnerAndRepo, extractRepository } from '@pkg-pr-new/utils'
2-
import { getPackageManifest } from 'query-registry'
3-
import { z } from 'zod'
1+
import { getPackageManifest } from "query-registry";
2+
import { extractOwnerAndRepo, extractRepository } from "@pkg-pr-new/utils";
3+
import { WorkflowData } from "../types";
44

5-
const paramsSchema = z.object({
6-
packageAndRefOrSha: z.string(),
7-
})
5+
type Params = Omit<WorkflowData, "sha" | "ref"> & {
6+
packageAndRefOrSha: string;
7+
};
88

99
export default eventHandler(async (event) => {
10-
const params = await getValidatedRouterParams(event, paramsSchema.parse)
11-
const [packageName, refOrSha] = params.packageAndRefOrSha.split('@')
10+
const params = getRouterParams(event) as Params;
11+
const [packageName, refOrSha] = params.packageAndRefOrSha.split("@");
1212

13-
const manifest = await getPackageManifest(packageName)
13+
const manifest = await getPackageManifest(packageName);
1414

15-
const repository = extractRepository(manifest)
15+
const repository = extractRepository(manifest);
1616
if (!repository) {
1717
throw createError({
1818
status: 404,
19-
})
19+
});
2020
}
2121

22-
const match = extractOwnerAndRepo(repository)
22+
const match = extractOwnerAndRepo(repository);
2323
if (!match) {
2424
throw createError({
2525
status: 404,
26-
})
26+
});
2727
}
28-
const [owner, repo] = match
28+
const [owner, repo] = match;
2929

30-
sendRedirect(event, `/${owner}/${repo}/${packageName}@${refOrSha}`)
31-
})
30+
sendRedirect(event, `/${owner}/${repo}/${packageName}@${refOrSha}`);
31+
});
Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,44 @@
11
export default eventHandler(async (event) => {
2-
const data = await readRawBody(event)
3-
const workflowsBucket = useWorkflowsBucket(event)
2+
const data = await readRawBody(event);
3+
const workflowsBucket = useWorkflowsBucket(event);
44

5-
const { owner, repo, key } = JSON.parse(data!)
5+
const { owner, repo, key } = JSON.parse(data!);
66

7-
const app = useOctokitApp(event)
7+
const app = useOctokitApp(event);
88

9-
let authenticated = false
9+
let authenticated = false;
1010

1111
try {
12-
await app.octokit.request('GET /repos/{owner}/{repo}/installation', {
12+
await app.octokit.request("GET /repos/{owner}/{repo}/installation", {
1313
owner,
1414
repo,
15-
})
16-
authenticated = true
17-
}
18-
catch {}
15+
});
16+
authenticated = true;
17+
} catch { }
1918

2019
try {
21-
await app.octokit.request('GET /orgs/{org}/installation', {
20+
await app.octokit.request("GET /orgs/{org}/installation", {
2221
org: owner,
23-
})
24-
authenticated = true
25-
}
26-
catch {}
22+
});
23+
authenticated = true;
24+
} catch { }
2725

2826
if (!authenticated) {
2927
throw createError({
3028
statusCode: 404,
3129
fatal: true,
3230
message: `The app https://github.com/apps/pkg-pr-new is not installed on ${owner}/${repo}.`,
33-
})
31+
});
3432
}
3533

36-
const workflowData = await workflowsBucket.getItem(key)
34+
const workflowData = await workflowsBucket.getItem(key);
3735

3836
if (!workflowData) {
3937
throw createError({
4038
statusCode: 404,
4139
fatal: true,
4240
message: `There is no workflow defined for ${key}`,
43-
})
41+
});
4442
}
45-
return { sha: workflowData.sha }
46-
})
43+
return { sha: workflowData.sha };
44+
});

0 commit comments

Comments
 (0)