|
- import { contentType } from "jsr:@std/media-types";
- import { transpile } from "jsr:@deno/emit";
- import config from "./deno.json" with { type: "json" };
-
- const jsContentType = contentType(".js");
-
- export enum MediaType {
- TypeScript,
- JSX,
- TSX,
- };
-
- // https://github.com/denoland/deno_ast/blob/ea1ccec37e1aa8e5e1e70f983a7ed1472d0e132a/src/media_type.rs#L117
- const customContentType = {
- [MediaType.TypeScript]: "text/typescript; charset=utf-8",
- [MediaType.JSX]: "text/jsx; charset=utf-8",
- [MediaType.TSX]: "text/tsx; charset=utf-8",
- };
-
- async function rewriteTsResponse(response: Response, url: URL, mediaType: MediaType) {
- const tsCode = await response.text();
- const targetUrlStr = url.toString();
- try {
- const result = await transpile(url, {
- importMap: config,
- compilerOptions: config.compilerOptions,
- load(specifier) {
- if (specifier !== targetUrlStr) {
- return Promise.resolve({
- kind: "module",
- specifier,
- content: "",
- headers: { "content-type": "application/javascript; charset=utf-8" },
- });
- } else {
- return Promise.resolve({
- kind: "module",
- specifier,
- content: tsCode,
- headers: {
- "content-type": customContentType[mediaType],
- },
- });
- }
- },
- });
- const jsCode = result.get(targetUrlStr);
- const { headers } = response;
- headers.set("content-type", jsContentType);
- headers.delete("content-length");
-
- return new Response(jsCode, {
- status: response.status,
- statusText: response.statusText,
- headers,
- });
- } catch (e) {
- console.error(e);
- return new Response(`${e}`, {
- status: 500,
- statusText: `${e}`,
- headers: response.headers,
- });
- }
- }
-
- export default async function transpileResponse(response: Response, requestUrl: string, filepath?: string): Promise<Response> {
- const url = new URL(`ts-serve:///${ requestUrl }`);
- if (response.status !== 200) {
- return response;
- }
- const pathname = filepath !== undefined ? filepath : url.pathname;
- const extension = pathname.split('.').at(-1) ?? null;
- switch (extension) {
- case 'ts': return await rewriteTsResponse(response, url, MediaType.TypeScript);
- case 'tsx': return await rewriteTsResponse(response, url, MediaType.TSX);
- case 'jsx': return await rewriteTsResponse(response, url, MediaType.JSX);
- default: return response;
- }
- }
|