-
-
Notifications
You must be signed in to change notification settings - Fork 262
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: maksim.khramtsov <[email protected]> Co-authored-by: Tim <[email protected]>
- Loading branch information
1 parent
3db5a97
commit 81ddd45
Showing
10 changed files
with
224 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@effect/platform": patch | ||
--- | ||
|
||
Integration with [Scalar](https://scalar.com/) has been implemented |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
import * as Effect from "effect/Effect" | ||
import type { Layer } from "effect/Layer" | ||
import { Api } from "./HttpApi.js" | ||
import { Router } from "./HttpApiBuilder.js" | ||
import * as HttpServerResponse from "./HttpServerResponse.js" | ||
import * as internal from "./internal/httpApiScalar.js" | ||
import * as OpenApi from "./OpenApi.js" | ||
|
||
/** | ||
* @since 1.0.0 | ||
* @category model | ||
*/ | ||
export type ScalarThemeId = | ||
| "alternate" | ||
| "default" | ||
| "moon" | ||
| "purple" | ||
| "solarized" | ||
| "bluePlanet" | ||
| "deepSpace" | ||
| "saturn" | ||
| "kepler" | ||
| "mars" | ||
| "none" | ||
|
||
/** | ||
* @since 1.0.0 | ||
* @category model | ||
* | ||
* cdn: `https://cdn.jsdelivr.net/npm/@scalar/api-reference@${source.version}/dist/browser/standalone.min.js` | ||
*/ | ||
export type ScalarScriptSource = | ||
| string | ||
| { type: "default" } | ||
| { | ||
type: "cdn" | ||
version?: "latest" | (string & {}) | ||
} | ||
|
||
/** | ||
* @since 1.0.0 | ||
* @category model | ||
* @see https://github.com/scalar/scalar/blob/main/documentation/configuration.md | ||
*/ | ||
export type ScalarConfig = { | ||
/** A string to use one of the color presets */ | ||
theme?: ScalarThemeId | ||
/** The layout to use for the references */ | ||
layout?: "modern" | "classic" | ||
/** URL to a request proxy for the API client */ | ||
proxy?: string | ||
/** Whether the spec input should show */ | ||
isEditable?: boolean | ||
/** Whether to show the sidebar */ | ||
showSidebar?: boolean | ||
/** | ||
* Whether to show models in the sidebar, search, and content. | ||
* | ||
* @default false | ||
*/ | ||
hideModels?: boolean | ||
/** | ||
* Whether to show the “Download OpenAPI Document” button | ||
* | ||
* @default false | ||
*/ | ||
hideDownloadButton?: boolean | ||
/** | ||
* Whether to show the “Test Request” button | ||
* | ||
* @default: false | ||
*/ | ||
hideTestRequestButton?: boolean | ||
/** | ||
* Whether to show the sidebar search bar | ||
* | ||
* @default: false | ||
*/ | ||
hideSearch?: boolean | ||
/** Whether dark mode is on or off initially (light mode) */ | ||
darkMode?: boolean | ||
/** forceDarkModeState makes it always this state no matter what*/ | ||
forceDarkModeState?: "dark" | "light" | ||
/** Whether to show the dark mode toggle */ | ||
hideDarkModeToggle?: boolean | ||
/** | ||
* Path to a favicon image | ||
* | ||
* @default undefined | ||
* @example '/favicon.svg' | ||
*/ | ||
favicon?: string | ||
/** Custom CSS to be added to the page */ | ||
customCss?: string | ||
/** | ||
* The baseServerURL is used when the spec servers are relative paths and we are using SSR. | ||
* On the client we can grab the window.location.origin but on the server we need | ||
* to use this prop. | ||
* | ||
* @default undefined | ||
* @example 'http://localhost:3000' | ||
*/ | ||
baseServerURL?: string | ||
/** | ||
* We’re using Inter and JetBrains Mono as the default fonts. If you want to use your own fonts, set this to false. | ||
* | ||
* @default true | ||
*/ | ||
withDefaultFonts?: boolean | ||
/** | ||
* By default we only open the relevant tag based on the url, however if you want all the tags open by default then set this configuration option :) | ||
* | ||
* @default false | ||
*/ | ||
defaultOpenAllTags?: boolean | ||
} | ||
|
||
/** | ||
* @since 1.0.0 | ||
* @category layers | ||
*/ | ||
export const layer = (options?: { | ||
readonly path?: `/${string}` | undefined | ||
readonly source?: ScalarScriptSource | ||
readonly scalar?: ScalarConfig | ||
}): Layer<never, never, Api> => | ||
Router.use((router) => | ||
Effect.gen(function*() { | ||
const { api } = yield* Api | ||
const spec = OpenApi.fromApi(api) | ||
|
||
const source = options?.source | ||
const defaultScript = internal.javascript | ||
const src: string | null = source | ||
? typeof source === "string" | ||
? source | ||
: source.type === "cdn" | ||
? `https://cdn.jsdelivr.net/npm/@scalar/api-reference@${ | ||
source.version ?? "latest" | ||
}/dist/browser/standalone.min.js` | ||
: null | ||
: null | ||
|
||
const scalarConfig = { | ||
_integration: "http", | ||
...options?.scalar | ||
} | ||
|
||
const response = HttpServerResponse.html(`<!doctype html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<title>${spec.info.title}</title> | ||
${ | ||
!spec.info.description | ||
? "" | ||
: `<meta name="description" content="${spec.info.description}"/>` | ||
} | ||
${ | ||
!spec.info.description | ||
? "" | ||
: `<meta name="og:description" content="${spec.info.description}"/>` | ||
} | ||
<meta | ||
name="viewport" | ||
content="width=device-width, initial-scale=1" /> | ||
</head> | ||
<body> | ||
<script id="api-reference" type="application/json"> | ||
${JSON.stringify(spec)} | ||
</script> | ||
<script> | ||
document.getElementById('api-reference').dataset.configuration = JSON.stringify(${JSON.stringify(scalarConfig)}) | ||
</script> | ||
${ | ||
src | ||
? `<script src="${src}" crossorigin></script>` | ||
: `<script>${defaultScript}</script>` | ||
} | ||
</body> | ||
</html>`) | ||
yield* router.get(options?.path ?? "/docs", Effect.succeed(response)) | ||
}) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* eslint-disable no-undef */ | ||
import * as Fs from "fs/promises" | ||
|
||
const jsBundle = await fetch( | ||
"https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest/dist/browser/standalone.min.js" | ||
).then((res) => res.text()) | ||
|
||
const source = `/* eslint-disable */ | ||
/** @internal */ | ||
export const javascript = ${JSON.stringify(`${jsBundle}`)} | ||
` | ||
|
||
await Fs.writeFile("packages/platform/src/internal/httpApiScalar.ts", source) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters