Skip to content

Commit

Permalink
feat(swc-plugins): Show data (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 authored Aug 26, 2024
1 parent 0b6b258 commit 75465cb
Show file tree
Hide file tree
Showing 11 changed files with 352 additions and 6 deletions.
7 changes: 5 additions & 2 deletions swc-plugins/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"extends": "next/core-web-vitals"
}
"extends": "next/core-web-vitals",
"rules": {
"@typescript-eslint/no-unused-vars": "off"
}
}
32 changes: 32 additions & 0 deletions swc-plugins/app/compat/core/[version]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use client";

import { apiClient } from "@/lib/trpc/web-client";
import Link from "next/link";

export default function Page({
params: { version },
}: {
params: { version: string };
}) {
const [compatRange] = apiClient.compatRange.byVersion.useSuspenseQuery({
version,
});

return (
<div>
{compatRange ? (
<>
<Link href={`/compat/range/${compatRange.id}`}>
{compatRange.from} ~ {compatRange.to}
</Link>
</>
) : (
<>
<p>No compat range found</p>
</>
)}
</div>
);
}

export const dynamic = "force-dynamic";
43 changes: 43 additions & 0 deletions swc-plugins/app/compat/range/[compatRangeId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";

import { apiClient } from "@/lib/trpc/web-client";

export default function Page({
params: { compatRangeId },
}: {
params: { compatRangeId: string };
}) {
const [compatRange] = apiClient.compatRange.get.useSuspenseQuery({
id: BigInt(compatRangeId),
});

return (
<div>
<h1 className="text-2xl font-bold">
<kbd>swc_core</kbd>@<kbd>{compatRange.from}</kbd> -{" "}
<kbd>{compatRange.to}</kbd>
</h1>

<h2 className="text-xl font-bold">Runtimes</h2>
<ul>
{compatRange.runtimes.map((runtime) => (
<li key={runtime.name}>
<kbd>{runtime.name}</kbd>
<kbd>{runtime.minVersion}</kbd> - <kbd>{runtime.maxVersion}</kbd>
</li>
))}
</ul>

<h2 className="text-xl font-bold">Plugins</h2>
<ul>
{compatRange.plugins.map((plugin) => (
<li key={plugin.name}>
<kbd>{plugin.name}</kbd>
</li>
))}
</ul>
</div>
);
}

export const dynamic = "force-dynamic";
26 changes: 26 additions & 0 deletions swc-plugins/app/compat/range/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { createCaller } from "@/lib/server";
import Link from "next/link";

export default async function Page() {
const api = await createCaller();
const ranges = await api.compatRange.list();

return (
<div>
<h1 className="text-2xl font-bold">Compat Ranges</h1>
<ul>
{ranges.map((range) => (
<li key={range.id}>
<Link href={`/compat/range/${range.id}`}>
<kbd>swc_core</kbd>@<kbd>{range.from}</kbd> -{" "}
<kbd>{range.to}</kbd>
</Link>
</li>
))}
</ul>
</div>
);
}

export const dynamic = "force-dynamic";
export const fetchCache = "force-no-store";
7 changes: 7 additions & 0 deletions swc-plugins/app/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Loading() {
return (
<div className="bg-muted flex min-h-screen w-full items-center justify-center">
<div className="animate-pulse">Loading...</div>
</div>
);
}
167 changes: 167 additions & 0 deletions swc-plugins/lib/api/compatRange/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { publicProcedure, router } from "@/lib/base";
import { db } from "@/lib/prisma";
import semver from "semver";
import { z } from "zod";
import { VersionRange, VersionRangeSchema } from "./zod";

export const compatRangeRouter = router({
list: publicProcedure
.input(z.void())
.output(
z.array(
z.object({
id: z.bigint(),
from: z.string(),
to: z.string(),
})
)
)
.query(async ({ ctx }) => {
const versions = await db.compatRange.findMany({
orderBy: {
from: "asc",
},
});

return versions;
}),

get: publicProcedure
.input(
z.object({
id: z.bigint(),
})
)
.output(
z.object({
id: z.bigint(),
from: z.string(),
to: z.string(),
plugins: z.array(VersionRangeSchema),
runtimes: z.array(VersionRangeSchema),
})
)
.query(async ({ ctx, input: { id } }) => {
const range = await db.compatRange.findUnique({
where: {
id: id,
},
select: {
id: true,
from: true,
to: true,
plugins: {
select: {
id: true,
version: true,
plugin: {
select: {
name: true,
},
},
},
},
runtimes: {
select: {
id: true,
version: true,
runtime: {
select: {
name: true,
},
},
},
},
},
});

if (!range) {
throw new Error("CompatRange not found");
}
const plugins = merge(
range.plugins.map((p) => ({ name: p.plugin.name, version: p.version }))
);
const runtimes = merge(
range.runtimes.map((p) => ({
name: p.runtime.name,
version: p.version,
}))
);

return {
id: range.id,
from: range.from,
to: range.to,
plugins,
runtimes,
};
}),

byVersion: publicProcedure
.input(
z.object({
version: z.string(),
})
)
.output(
z.nullable(
z.object({
id: z.bigint(),
from: z.string(),
to: z.string(),
})
)
)
.query(async ({ ctx, input: { version } }) => {
const versions = await db.compatRange.findMany({
select: {
id: true,
from: true,
to: true,
},
});

for (const range of versions) {
if (semver.lt(version, range.from)) {
continue;
}

if (semver.gte(version, range.to)) {
return range;
}
}

return null;
}),
});

function merge(ranges: { name: string; version: string }[]): VersionRange[] {
const merged: { [key: string]: VersionRange } = {};

for (const { name, version } of ranges) {
if (!merged[name]) {
merged[name] = { name, minVersion: "0.0.0", maxVersion: "0.0.0" };
}

const { min, max } = mergeVersion(
merged[name].minVersion,
merged[name].maxVersion,
version
);
merged[name] = { name, minVersion: min, maxVersion: max };
}

return Object.values(merged);
}
/**
*
* @param min semver
* @param max semver
* @param newValue semver
*/
function mergeVersion(min: string, max: string, newValue: string) {
const minVersion = semver.lt(min, newValue) ? min : newValue;
const maxVersion = semver.gt(max, newValue) ? max : newValue;

return { min: minVersion, max: maxVersion };
}
8 changes: 8 additions & 0 deletions swc-plugins/lib/api/compatRange/zod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { z } from "zod";

export const VersionRangeSchema = z.object({
name: z.string(),
minVersion: z.string(),
maxVersion: z.string(),
});
export type VersionRange = z.infer<typeof VersionRangeSchema>;
3 changes: 3 additions & 0 deletions swc-plugins/lib/api/router.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { router } from "@/lib/base";

import { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
import { compatRangeRouter } from "./compatRange/router";
import { userRouter } from "./users/router";

export const apiRouter = router({
users: userRouter,

compatRange: compatRangeRouter,
});

export type ApiRouter = typeof apiRouter;
Expand Down
11 changes: 8 additions & 3 deletions swc-plugins/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import { z } from "zod";

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
return twMerge(clsx(inputs));
}

export function typed<T>(schema: z.ZodSchema<T>, data: T): T {
return schema.parse(data);
}
2 changes: 2 additions & 0 deletions swc-plugins/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"react-hook-form": "^7.52.0",
"react-resizable-panels": "^2.1.1",
"recharts": "^2.12.7",
"semver": "^7.6.3",
"sharp": "^0.33.2",
"sonner": "^1.5.0",
"superjson": "^2.2.1",
Expand All @@ -85,6 +86,7 @@
"@types/node": "20.14.2",
"@types/react": "18.3.3",
"@types/react-dom": "18.2.18",
"@types/semver": "^7.5.8",
"autoprefixer": "10.4.17",
"postcss": "8.4.33",
"prisma": "^5.17.0",
Expand Down
Loading

0 comments on commit 75465cb

Please sign in to comment.