Closed SamuelLHuber closed 2 months ago
After fighting with Claude I got it to write a BunSwaggerFiles.ts that works to provide a SwaggerFilesLive layer to let me run the API
bun add swagger-ui-dist
and add BunSwaggerFiles.ts to provide the Layer
// your imports
import { SwaggerFilesLive } from "./BunSwaggerFiles"
// your app with RouterBuilder
const HttpLive = HttpServer.serve(app).pipe(
Layer.provide(BunHttpServer.layer({ port: 3000 })),
Layer.provide(SwaggerFilesLive),
Layer.provide(BunContext.layer),
Layer.launch,
Effect.scoped
)
BunRuntime.runMain(HttpLive)
BunSwaggerFiles.ts code
import * as FileSystem from "@effect/platform/FileSystem"
import * as Path from "@effect/platform/Path"
import * as SwaggerRouter from "effect-http/SwaggerRouter"
import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import * as Record from "effect/Record"
/** @internal */
const readFile = (path: string) => Effect.flatMap(FileSystem.FileSystem, (fs) => fs.readFile(path))
/** @internal */
const SWAGGER_FILE_NAMES = [
"index.css",
"swagger-ui.css",
"swagger-ui-bundle.js",
"swagger-ui-standalone-preset.js",
"favicon-32x32.png",
"favicon-16x16.png"
]
/** @internal */
const findSwaggerDistPath = Effect.gen(function*(_) {
const fs = yield* _(FileSystem.FileSystem)
const path = yield* _(Path.Path)
const swaggerPath = path.join(process.cwd(), "node_modules", "swagger-ui-dist")
if (yield* _(fs.exists(swaggerPath))) {
return swaggerPath
}
throw new Error("Could not find swagger-ui-dist directory")
})
/** @internal */
const readSwaggerFile = (swaggerBasePath: string, file: string) =>
Effect.flatMap(Path.Path, (path) => readFile(path.join(swaggerBasePath, file)).pipe(Effect.orDie))
/** @internal */
export const SwaggerFilesLive = Effect.gen(function*(_) {
const swaggerBasePath = yield* _(findSwaggerDistPath)
const files = yield* _(
SWAGGER_FILE_NAMES,
Effect.forEach((path) => Effect.zip(Effect.succeed(path), readSwaggerFile(swaggerBasePath, path))),
Effect.map(Record.fromEntries)
)
const size = Object.entries(files).reduce(
(acc, [_, content]) => acc + content.byteLength,
0
)
const sizeMb = (size / 1024 / 1024).toFixed(1)
yield* _(Effect.logDebug(`Static swagger UI files loaded (${sizeMb}MB)`))
return { files }
}).pipe(Layer.effect(SwaggerRouter.SwaggerFiles))
Hey, I updated the bun-server.ts
example. The NodeSwaggerFiles
should work for both bun and node. The new version of the example works for me locally as is, could you please try it? Tried with bun v1.1.24.
yes that works! also needed to run bun update
to make sure I have the newest effect-http-node version
Hello, I can't get it to run with Bun.
I tried running the bun-server.ts from the samples, but got
I'd love to run effect-http fully in Bun with the BunRuntime, but couldn't get that to work any way I tried.
@effect/platform-bun
provides a Bun HTTPServer sample.When I try to run it using
where app is built using RouterBuilder.make
I run into a TypeError with SwaggerFiles
once expanded to handle SwaggerFiles like the bun sample from effect-http-node
I get the same error
this may be due to node and bun being mixed when using NodeSwaggerFiles?