first commit

This commit is contained in:
Daniel Ledda
2024-10-30 20:42:01 +01:00
commit e6f20af28d
13 changed files with 556 additions and 0 deletions

80
transpileTs.ts Normal file
View File

@@ -0,0 +1,80 @@
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;
}
}