From 3b314135c11d20cdead0ad83ba79ffc47c2108b2 Mon Sep 17 00:00:00 2001 From: ayame113 <40050810+ayame113@users.noreply.github.com> Date: Wed, 12 Apr 2023 12:07:53 +0900 Subject: [PATCH 1/2] v3 --- README.md | 9 +- example/serve.ts | 49 ++++- example/serve_old.ts | 3 + middlewear/README.md | 6 + middlewear/_webp_encode.ts | 57 ++++++ middlewear/_webp_lib.ts | 59 ++++++ middlewear/gfm.ts | 55 ++++++ middlewear/ts-serve.ts | 35 ++++ middlewear/webp.ts | 32 +++ mod.ts | 26 +-- src/app/mod.ts | 187 ++++++++++++++++++ src/file_server.ts | 2 +- src/oak.ts | 2 +- oak_test.ts => src/oak_test.ts | 3 +- src/utils/fource_instantiate_wasm.ts | 22 +++ .../utils/fource_instantiate_wasm_test.ts | 3 +- {utils => src/utils}/transpile.ts | 0 {utils => src/utils}/transpile_bench.ts | 2 +- {utils => src/utils}/transpile_response.ts | 0 .../utils}/transpile_response_test.ts | 0 {utils => src/utils}/transpile_test.ts | 0 21 files changed, 521 insertions(+), 31 deletions(-) create mode 100644 example/serve_old.ts create mode 100644 middlewear/README.md create mode 100644 middlewear/_webp_encode.ts create mode 100644 middlewear/_webp_lib.ts create mode 100644 middlewear/gfm.ts create mode 100644 middlewear/ts-serve.ts create mode 100644 middlewear/webp.ts create mode 100644 src/app/mod.ts rename oak_test.ts => src/oak_test.ts (97%) create mode 100644 src/utils/fource_instantiate_wasm.ts rename mod_test.ts => src/utils/fource_instantiate_wasm_test.ts (88%) rename {utils => src/utils}/transpile.ts (100%) rename {utils => src/utils}/transpile_bench.ts (81%) rename {utils => src/utils}/transpile_response.ts (100%) rename {utils => src/utils}/transpile_response_test.ts (100%) rename {utils => src/utils}/transpile_test.ts (100%) diff --git a/README.md b/README.md index ac725e5..d97340a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,15 @@ -# ts-serve +# jit-server [![Test](https://github.com/ayame113/ts-serve/actions/workflows/test.yml/badge.svg)](https://github.com/ayame113/ts-serve/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/ayame113/ts-serve/branch/main/graph/badge.svg?token=mz0SfmUYRL)](https://codecov.io/gh/ayame113/ts-serve) +**jit-server** is a file server with just-in-time compilation. + +> **Note** Up until version 2, this library was a specialized server for +> transpiling TypeScript to JavaScript, called ts-serve. + +# ts-serve + TypeScript + ES Modules Transpile TypeScript on the fly and serve it from your server as ES Modules. diff --git a/example/serve.ts b/example/serve.ts index 3efeaf0..eddaf98 100644 --- a/example/serve.ts +++ b/example/serve.ts @@ -1,3 +1,48 @@ import { serve } from "https://deno.land/std@0.178.0/http/mod.ts"; -import { serveDirWithTs } from "../mod.ts"; -serve((req) => serveDirWithTs(req, { fsRoot: "example" })); +import { App } from "../mod.ts"; +import { tsServe } from "../middlewear/ts-serve.ts"; +import { markdown } from "../middlewear/gfm.ts"; +// import { webpConverter } from "../middlewear/webp.ts"; +// import basicAuth from "https://deno.land/x/lume@v1.15.3/middlewares/basic_auth.ts"; + +const app = new App(); + +// middleware +app + // .use(basicAuth({ + // users: { + // "user": "pass", + // }, + // })) + .use(tsServe()) + // .use(webpConverter()) + .use(markdown({ + renderOptions: { disableHtmlSanitization: true }, + frontMatter: true, + format(body, { CSS }, frontMatter) { + console.log(frontMatter); + return ` + + + + + + + + +
+ ${body} +
+ + + `; + }, + })); + +serve(app.handler); diff --git a/example/serve_old.ts b/example/serve_old.ts new file mode 100644 index 0000000..3efeaf0 --- /dev/null +++ b/example/serve_old.ts @@ -0,0 +1,3 @@ +import { serve } from "https://deno.land/std@0.178.0/http/mod.ts"; +import { serveDirWithTs } from "../mod.ts"; +serve((req) => serveDirWithTs(req, { fsRoot: "example" })); diff --git a/middlewear/README.md b/middlewear/README.md new file mode 100644 index 0000000..d76dd4b --- /dev/null +++ b/middlewear/README.md @@ -0,0 +1,6 @@ +## middlewares + +This directory contains middleware that can be used in conjunction with the +`App` class exported from `/mod.ts`. + +A detailed usage example is in [../example/serve.ts](../example/serve.ts). diff --git a/middlewear/_webp_encode.ts b/middlewear/_webp_encode.ts new file mode 100644 index 0000000..fc6f348 --- /dev/null +++ b/middlewear/_webp_encode.ts @@ -0,0 +1,57 @@ +// https://github.com/jamsinclair/jSquash/blob/1edfc086e22b6aa01910cff5fd20826cf9e3dfa2/packages/webp/encode.ts +// avoid top-level-await for deno deploy + +/** + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Notice: I (Jamie Sinclair) have modified this file. + * Updated to support a partial subset of WebP encoding options to be provided. + * The WebP options are defaulted to defaults from the meta.ts file. + * Also manually allow instantiation of the Wasm Module. + */ +import type { WebPModule } from "https://esm.sh/@jsquash/webp@1.1.3/codec/enc/webp_enc"; +import type { EncodeOptions } from "https://esm.sh/@jsquash/webp@1.1.3/meta"; + +import { defaultOptions } from "https://esm.sh/@jsquash/webp@1.1.3/meta"; +import { initEmscriptenModule } from "https://esm.sh/@jsquash/webp@1.1.3/utils"; +import { simd } from "https://esm.sh/wasm-feature-detect@1.5.0"; + +import webpEncoder from "https://esm.sh/@jsquash/webp@1.1.3/codec/enc/webp_enc"; +import webpEncoderSimd from "https://esm.sh/@jsquash/webp@1.1.3/codec/enc/webp_enc_simd"; + +let emscriptenModule: Promise; + +export async function init(module?: WebAssembly.Module): Promise { + if (await simd()) { + emscriptenModule = initEmscriptenModule(webpEncoderSimd, module); + return emscriptenModule; + } + emscriptenModule = initEmscriptenModule(webpEncoder, module); + return emscriptenModule; +} + +export default async function encode( + data: ImageData, + options: Partial = {}, +): Promise { + if (!emscriptenModule) emscriptenModule = init(); + + const _options: EncodeOptions = { ...defaultOptions, ...options }; + const module = await emscriptenModule; + const result = module.encode(data.data, data.width, data.height, _options); + + if (!result) throw new Error("Encoding error."); + + return result.buffer; +} diff --git a/middlewear/_webp_lib.ts b/middlewear/_webp_lib.ts new file mode 100644 index 0000000..830ef67 --- /dev/null +++ b/middlewear/_webp_lib.ts @@ -0,0 +1,59 @@ +import decodeJpeg, { + init as initJpegWasm, +} from "https://esm.sh/@jsquash/jpeg@1.1.5/decode"; +import decodePng, { + init as initPngWasm, +} from "https://esm.sh/@jsquash/png@2.0.0/decode"; +// import encodeWebp, { +// init as initWebpWasm, +// } from "https://esm.sh/@jsquash/webp@1.1.3/encode"; +import encodeWebp, { init as initWebpWasm } from "./_webp_encode.ts"; + +const jpegWasm = + "https://esm.sh/@jsquash/jpeg@1.1.5/codec/dec/mozjpeg_dec.wasm"; +const pngWasm = "https://esm.sh/@jsquash/png@2.0.0/codec/squoosh_png_bg.wasm"; +const webpWasm = + "https://esm.sh/@jsquash/webp@1.1.3/codec/enc/webp_enc_simd.wasm"; + +async function loadWasmModule(url: string) { + return await WebAssembly.compileStreaming(fetch(url)); +} + +export const jpegWasmInit = loadWasmModule(jpegWasm).then(initJpegWasm); +export const pngWasmInit = loadWasmModule(pngWasm).then(initPngWasm); +export const webpWasmInit = loadWasmModule(webpWasm).then(initWebpWasm); + +globalThis.ImageData ??= class ImageData { + colorSpace = "srgb" as const; + data: Uint8ClampedArray; + width: number; + height: number; + constructor(data: Uint8ClampedArray, width: number, height?: number); + constructor(data: number, width: number); + constructor( + data: Uint8ClampedArray | number, + width: number, + height?: number, + ) { + if (!(data instanceof Uint8ClampedArray) || typeof height !== "number") { + throw new Error("unimplemented"); + } + this.data = data; + this.width = width; + this.height = height; + } +}; + +export async function jpegToWebp(buf: ArrayBuffer) { + await jpegWasmInit; + const imageData = await decodeJpeg(buf); + await webpWasmInit; + return await encodeWebp(imageData); +} + +export async function pngToWebp(buf: ArrayBuffer) { + await pngWasmInit; + const imageData = await decodePng(buf); + await webpWasmInit; + return await encodeWebp(imageData); +} diff --git a/middlewear/gfm.ts b/middlewear/gfm.ts new file mode 100644 index 0000000..0ed0555 --- /dev/null +++ b/middlewear/gfm.ts @@ -0,0 +1,55 @@ +import { createTranspiler } from "../mod.ts"; +import { + CSS, + KATEX_CSS, + render, + type RenderOptions, +} from "https://deno.land/x/gfm@0.2.0/mod.ts"; +import { + extract, + test, +} from "https://deno.land/std@0.176.0/encoding/front_matter/any.ts"; +import type { JSONValue } from "https://deno.land/std@0.176.0/encoding/jsonc.ts"; + +export interface MarkdownOptions { + /** Transpile only if the file name matches this value (format follows URLPattern). */ + targetDir?: string; + /** If the file name matches this value, it will not be transpiled (format follows URLPattern). */ + excludeDir?: string; + /** whether to parse frontMatter. If set to true, the parsed frontMatter is given to the argument of the format function. */ + frontMatter?: boolean; + /** A function that creates full HTML from parsed markdown body. */ + format( + body: string, + css: { CSS: string; KATEX_CSS: string }, + frontMatter: JSONValue, + ): string | Promise; + /** Options passed to [deno.land/x/gfm](https://deno.land/x/gfm)'s render function */ + renderOptions?: RenderOptions; +} + +/** Middleware for converting markdown to HTML using [deno.land/x/gfm](https://deno.land/x/gfm) . */ +export function markdown(options: MarkdownOptions) { + const { + targetDir, + excludeDir, + frontMatter, + format, + renderOptions, + } = options; + + return createTranspiler({ + from: ".md", + to: ".html", + targetDir, + excludeDir, + fn(content) { + let attrs: JSONValue = {}; + if (frontMatter && test(content)) { + ({ body: content, attrs } = extract(content)); + } + const body = render(content, renderOptions); + return format(body, { CSS, KATEX_CSS }, attrs); + }, + }); +} diff --git a/middlewear/ts-serve.ts b/middlewear/ts-serve.ts new file mode 100644 index 0000000..c2da103 --- /dev/null +++ b/middlewear/ts-serve.ts @@ -0,0 +1,35 @@ +import { createTranspiler } from "../src/app/mod.ts"; +import { fourceInstantiateWasm } from "../src/utils/fource_instantiate_wasm.ts"; +import { MediaType, transpile } from "../src/utils/transpile.ts"; + +export interface TsServeOptions { + /** Transpile only if the file name matches this value (format follows URLPattern). */ + targetDir?: string; + /** If the file name matches this value, it will not be transpiled (format follows URLPattern). */ + excludeDir?: string; +} + +/** + * A Promise that resolves when the wasm files used internally by this library are initialized. + * Normally you wouldn't use this variable, but if a test gives an error that it's leaking an asynchronous resource, awaiting this promise before running this test might solve the problem. + */ +export const denoEmitWasmInitPromise = fourceInstantiateWasm(); + +/** Middleware that transpiles TypeScript to JavaScript. */ +export function tsServe({ targetDir, excludeDir }: TsServeOptions = {}) { + return createTranspiler({ + from: [".jsx", ".tsx", ".ts"], + to: ".js", + targetDir, + excludeDir, + fn(content, { ctx, request }) { + const url = new URL(request.url); + const mediaType = { + ".ts": MediaType.TypeScript, + ".jsx": MediaType.Jsx, + ".tsx": MediaType.Tsx, + }[ctx.type]; + return transpile(content, url, mediaType); + }, + }); +} diff --git a/middlewear/webp.ts b/middlewear/webp.ts new file mode 100644 index 0000000..34e5325 --- /dev/null +++ b/middlewear/webp.ts @@ -0,0 +1,32 @@ +import { createTranspiler } from "../mod.ts"; +import { jpegToWebp, pngToWebp } from "./_webp_lib.ts"; + +export interface WebpConverterOptions { + /** Transpile only if the file name matches this value (format follows URLPattern). */ + targetDir?: string; + /** If the file name matches this value, it will not be transpiled (format follows URLPattern). */ + excludeDir?: string; +} + +/** Middleware to transpile images to webp. */ +export function webpConverter( + { targetDir, excludeDir }: WebpConverterOptions = {}, +) { + return createTranspiler({ + from: [".jpg", ".jpeg", ".png"], + to: ".webp", + type: "arrayBuffer", + targetDir, + excludeDir, + async fn(content, { ctx, request }) { + if (!request.headers.get("accept")?.includes("image/webp")) { + throw new Error("Accept header does not contain image/webp."); + } + if (ctx.type === ".png") { + return new Uint8Array(await pngToWebp(content)); + } else { + return new Uint8Array(await jpegToWebp(content)); + } + }, + }); +} diff --git a/mod.ts b/mod.ts index a33defb..0fba913 100644 --- a/mod.ts +++ b/mod.ts @@ -1,25 +1,5 @@ export * from "./src/oak.ts"; export * from "./src/file_server.ts"; -export * from "./utils/transpile.ts"; -import { MediaType, transpile } from "./utils/transpile.ts"; - -/** - * Calling this function will load the wasm file used in the deno_emit of the dependency. - * Even if you don't call this function, if you call the transpile function, the wasm file will be read automatically at that timing. - * However, performance can be an issue on the server as loading the wasm file takes time. - * In that case, calling this function in advance can speed up later calls to the transpile function. - * - * ```ts - * import { serve } from "https://deno.land/std@0.178.0/http/mod.ts"; - * import { serveDirWithTs, fourceInstantiateWasm } from "https://deno.land/x/ts_serve@$MODULE_VERSION/mod.ts"; - * - * // load the wasm file in the background when the server starts. - * fourceInstantiateWasm(); - * serve((request) => serveDirWithTs(request)); - * ``` - */ -export async function fourceInstantiateWasm() { - try { - await transpile("", new URL("file:///src"), MediaType.TypeScript); - } catch (_) { /* ignore error*/ } -} +export * from "./src/utils/transpile.ts"; +export * from "./src/utils/fource_instantiate_wasm.ts"; +export * from "./src/app/mod.ts"; diff --git a/src/app/mod.ts b/src/app/mod.ts new file mode 100644 index 0000000..50af709 --- /dev/null +++ b/src/app/mod.ts @@ -0,0 +1,187 @@ +import type { ConnInfo } from "https://deno.land/std@0.178.0/http/mod.ts"; +import { serveDir } from "https://deno.land/std@0.178.0/http/file_server.ts"; +import { contentType } from "https://deno.land/std@0.178.0/media_types/mod.ts"; +import { extname } from "https://deno.land/std@0.178.0/path/mod.ts"; + +/** Middleware type used in `App#use`. */ +export type Middleware = ( + req: Request, + next: (req: Request) => Promise, + conn: ConnInfo, + ctx: Context, +) => Promise; + +/** The type of context passed to the middleware. */ +export interface Context { + /** Represents the current file type. An extension is usually used. (e.g. `.ts`, `.md`) */ + type: T; +} + +/** + * Create a file server. You can apply middleware to each request using the `app.use` method. + * + * Middleware runs similar to express, oak, and hono, but it is specialized for file servers and can be used in conjunction with other frameworks. + * + * ```ts + * import { serve } from "https://deno.land/std@0.178.0/http/mod.ts"; + * import { App } from "https://deno.land/x/ts_serve@$MODULE_VERSION/mod.ts"; + * import { tsServe } from "https://deno.land/x/ts_serve@$MODULE_VERSION/middlewear/ts-serve.ts"; + * + * const app = new App(); + * + * // use middleware + * app.use(tsServe()); + * + * // serve handler + * serve(app.handler); + * ``` + */ +export class App { + #handler; + #middleware: Middleware[] = []; + constructor({ handler = serveDir }: { + handler?: (req: Request) => Response | Promise; + } = {}) { + this.#handler = handler; + } + /** Add middleware to the server. */ + use(...middleware: Middleware[]) { + this.#middleware.push(...middleware); + return this; + } + /** Server handler function. It takes a Request object and returns a Response object. */ + handler = async (req: Request, conn: ConnInfo): Promise => { + // not supported range request + if (req.headers.has("Range")) { + req = new Request(req); + req.headers.delete("Range"); + } + const { pathname } = new URL(req.url); + const ctx: Context = { + type: extname(pathname) as `.${string}` || ".html", // todo handle index.html or other + }; + return await this.#dispatchMiddleware(0, req, conn, ctx); + }; + async #dispatchMiddleware( + i: number, + req: Request, + conn: ConnInfo, + ctx: Context, + ): Promise { + if (i === this.#middleware.length) { + return await this.#handler(req); + } + return await this.#middleware[i]( + req, + (req) => this.#dispatchMiddleware(i + 1, req, conn, ctx), + conn, + ctx, + ); + } +} + +export interface TranspilerOptions< + F extends `.${string}`, + T extends "string" | "arrayBuffer" | undefined, +> { + /** Extension to transpile. */ + from: F | readonly F[]; + /** Extension after transpilation. */ + to: `.${string}`; + /** Type of argument passed to optional function `fn`. */ + type?: T; + /** Transpile only if the file name matches this value (format follows URLPattern). */ + targetDir?: string; + /** If the file name matches this value, it will not be transpiled (format follows URLPattern). */ + excludeDir?: string; + /** Function called when transpiling. Takes the pre-transpiled content as an argument and returns the post-transpiled value. */ + fn(originalContent: T extends "arrayBuffer" ? ArrayBuffer : string, options: { + ctx: Context; + conn: ConnInfo; + request: Request; + response: Response; + }): + | Promise> + | string + | Uint8Array + | ReadableStream; +} + +/** Utilities for creating middleware. You can create middleware that transpiles only certain extensions. */ +export function createTranspiler< + F extends `.${string}`, + T extends "string" | "arrayBuffer" | undefined = "string", +>( + options: TranspilerOptions, +): Middleware { + const { from, to, type = "string", targetDir, excludeDir, fn } = options; + const preExtensions = new Set(Array.isArray(from) ? from : [from]); + const postMediaType = contentType(to); + const includePattern = targetDir + ? new URLPattern({ pathname: targetDir }) + : undefined; + const excludePattern = excludeDir + ? new URLPattern({ pathname: excludeDir }) + : undefined; + + return async function (req, next, conn, ctx) { + const res = await next(req); + if (includePattern && !includePattern.test(req.url)) { + return res; + } + if (excludePattern && excludePattern.test(req.url)) { + return res; + } + if (res.status !== 200) { + return res; + } + if (!preExtensions.has(ctx.type)) { + return res; + } + + let content; + switch (type) { + case "string": + content = await res.text(); + break; + case "arrayBuffer": + content = await res.arrayBuffer(); + break; + default: { + const _: never = type; + throw new Error("unreachable"); + } + } + const transpiled = await fn( + content as T extends "arrayBuffer" ? ArrayBuffer : string, + { + ctx: ctx as Context, + conn, + request: req, + response: res, + }, + ); + if (transpiled == null) { + console.warn("Transpile skipped because transpiler returned null."); + return new Response(content, { + headers: res.headers, + status: res.status, + statusText: res.statusText, + }); + } + + if (postMediaType) { + res.headers.set("Content-Type", postMediaType); + } else { + res.headers.delete("Content-Type"); + } + res.headers.delete("Content-Length"); + ctx.type = to; + + return new Response(transpiled, { + headers: res.headers, + status: res.status, + statusText: res.statusText, + }); + }; +} diff --git a/src/file_server.ts b/src/file_server.ts index 697c502..8a30631 100644 --- a/src/file_server.ts +++ b/src/file_server.ts @@ -5,7 +5,7 @@ import { type ServeFileOptions, } from "https://deno.land/std@0.178.0/http/file_server.ts"; -import { transpileResponse } from "../utils/transpile_response.ts"; +import { transpileResponse } from "./utils/transpile_response.ts"; /** * This can be used in the same way as the [serveFile](https://doc.deno.land/https://deno.land/std@0.178.0/http/file_server.ts/~/serveFile) function of the standard library, but if the file is TypeScript, it will be rewritten to JavaScript. diff --git a/src/oak.ts b/src/oak.ts index 96b8aff..48c5b01 100644 --- a/src/oak.ts +++ b/src/oak.ts @@ -1,7 +1,7 @@ import type { Context } from "https://deno.land/x/oak@v12.0.1/mod.ts"; import { convertBodyToBodyInit } from "https://deno.land/x/oak@v12.0.1/response.ts"; -import { MediaType, transpile } from "../utils/transpile.ts"; +import { MediaType, transpile } from "./utils/transpile.ts"; const decoder = new TextDecoder(); const tsType = new Set( diff --git a/oak_test.ts b/src/oak_test.ts similarity index 97% rename from oak_test.ts rename to src/oak_test.ts index 0c92e88..c0a50e3 100644 --- a/oak_test.ts +++ b/src/oak_test.ts @@ -4,7 +4,8 @@ import { } from "https://deno.land/std@0.178.0/testing/asserts.ts"; import { deferred } from "https://deno.land/std@0.178.0/async/mod.ts"; import { Application } from "https://deno.land/x/oak@v12.0.1/mod.ts"; -import { MediaType, transpile, tsMiddleware } from "./mod.ts"; +import { tsMiddleware } from "./oak.ts"; +import { MediaType, transpile } from "./utils/transpile.ts"; const port = 8888; const jsContentType = "application/javascript; charset=UTF-8"; diff --git a/src/utils/fource_instantiate_wasm.ts b/src/utils/fource_instantiate_wasm.ts new file mode 100644 index 0000000..18e16c5 --- /dev/null +++ b/src/utils/fource_instantiate_wasm.ts @@ -0,0 +1,22 @@ +import { MediaType, transpile } from "./transpile.ts"; + +/** + * Calling this function will load the wasm file used in the deno_emit of the dependency. + * Even if you don't call this function, if you call the transpile function, the wasm file will be read automatically at that timing. + * However, performance can be an issue on the server as loading the wasm file takes time. + * In that case, calling this function in advance can speed up later calls to the transpile function. + * + * ```ts + * import { serve } from "https://deno.land/std@0.178.0/http/mod.ts"; + * import { serveDirWithTs, fourceInstantiateWasm } from "https://deno.land/x/ts_serve@$MODULE_VERSION/mod.ts"; + * + * // load the wasm file in the background when the server starts. + * fourceInstantiateWasm(); + * serve((request) => serveDirWithTs(request)); + * ``` + */ +export async function fourceInstantiateWasm() { + try { + await transpile("", new URL("file:///src"), MediaType.TypeScript); + } catch (_) { /* ignore error*/ } +} diff --git a/mod_test.ts b/src/utils/fource_instantiate_wasm_test.ts similarity index 88% rename from mod_test.ts rename to src/utils/fource_instantiate_wasm_test.ts index f2ea3ce..bf47d2c 100644 --- a/mod_test.ts +++ b/src/utils/fource_instantiate_wasm_test.ts @@ -4,7 +4,8 @@ import { stub, } from "https://deno.land/std@0.178.0/testing/mock.ts"; -import { fourceInstantiateWasm, MediaType, transpile } from "./mod.ts"; +import { MediaType, transpile } from "./transpile.ts"; +import { fourceInstantiateWasm } from "./fource_instantiate_wasm.ts"; Deno.test({ name: "fourceInstantiateWasm", diff --git a/utils/transpile.ts b/src/utils/transpile.ts similarity index 100% rename from utils/transpile.ts rename to src/utils/transpile.ts diff --git a/utils/transpile_bench.ts b/src/utils/transpile_bench.ts similarity index 81% rename from utils/transpile_bench.ts rename to src/utils/transpile_bench.ts index fc3c9cd..ef8d14e 100644 --- a/utils/transpile_bench.ts +++ b/src/utils/transpile_bench.ts @@ -1,4 +1,4 @@ -import { MediaType, transpile } from "../mod.ts"; +import { MediaType, transpile } from "../../mod.ts"; const codes = ["function name(params:type) {}"]; const url = new URL("file:///src.ts"); diff --git a/utils/transpile_response.ts b/src/utils/transpile_response.ts similarity index 100% rename from utils/transpile_response.ts rename to src/utils/transpile_response.ts diff --git a/utils/transpile_response_test.ts b/src/utils/transpile_response_test.ts similarity index 100% rename from utils/transpile_response_test.ts rename to src/utils/transpile_response_test.ts diff --git a/utils/transpile_test.ts b/src/utils/transpile_test.ts similarity index 100% rename from utils/transpile_test.ts rename to src/utils/transpile_test.ts From 038baf67d0338572bc33b0121d6e6df18ce280e8 Mon Sep 17 00:00:00 2001 From: ayame113 <40050810+ayame113@users.noreply.github.com> Date: Mon, 17 Apr 2023 13:06:37 +0900 Subject: [PATCH 2/2] fix import path --- src/utils/transpile_response.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/transpile_response.ts b/src/utils/transpile_response.ts index 0f06d55..9559fd5 100644 --- a/src/utils/transpile_response.ts +++ b/src/utils/transpile_response.ts @@ -10,7 +10,7 @@ const jsContentType = contentType(".js"); * import { serve } from "https://deno.land/std@0.178.0/http/mod.ts"; * import { serveFile } from "https://deno.land/std@0.178.0/http/file_server.ts"; * - * import { transpileResponse } from "https://deno.land/x/ts_serve@$MODULE_VERSION/utils/transpile_response.ts" + * import { transpileResponse } from "https://deno.land/x/ts_serve@$MODULE_VERSION/src/utils/transpile_response.ts" * * serve(async (request) => { * const filePath = "./mod.ts";