microsoft/typespec

Public

mirrored from https://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/create-github-action-issue

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/html-program-viewer/src/emitter.ts

69lines · modecode

1import { FluentProvider, webLightTheme } from "@fluentui/react-components";
2import {
3 createTypeSpecLibrary,
4 emitFile,
5 getDirectoryPath,
6 resolvePath,
7 type EmitContext,
8 type JSONSchemaType,
9 type Program,
10} from "@typespec/compiler";
11import { readFile } from "fs/promises";
12import { createElement } from "react";
13import ReactDOMServer from "react-dom/server";
14import { fileURLToPath } from "url";
15import { InspectType } from "./react/inspect-type/inspect-type.js";
16
17export interface HtmlProgramViewerOptions {
18 /**
19 * Override compiler output-dir
20 */
21 "output-dir"?: string;
22}
23
24const EmitterOptionsSchema: JSONSchemaType<HtmlProgramViewerOptions> = {
25 type: "object",
26 additionalProperties: false,
27 properties: {
28 "output-dir": { type: "string", nullable: true },
29 },
30 required: [],
31};
32
33export function renderProgram(program: Program) {
34 const html = ReactDOMServer.renderToString(
35 createElement(FluentProvider, {
36 theme: webLightTheme,
37 children: createElement(InspectType, { entity: program.getGlobalNamespaceType() }),
38 }), // [1
39 );
40 return html;
41}
42
43export const libDef = {
44 name: "@typespec/html-program-viewer",
45 diagnostics: {},
46 emitter: {
47 options: EmitterOptionsSchema as JSONSchemaType<HtmlProgramViewerOptions>,
48 },
49} as const;
50
51export const $lib = createTypeSpecLibrary(libDef);
52
53export async function $onEmit(context: EmitContext<HtmlProgramViewerOptions>) {
54 const html = renderProgram(context.program);
55 const outputDir = context.emitterOutputDir;
56 const htmlPath = resolvePath(outputDir, "typespec-program.html");
57 await emitFile(context.program, {
58 path: htmlPath,
59 content: `<!DOCTYPE html><html lang="en"><link rel="stylesheet" href="style.css"><body>${html}</body></html>`,
60 });
61
62 const css = await readFile(
63 resolvePath(getDirectoryPath(fileURLToPath(import.meta.url)), "style.css"),
64 );
65 await emitFile(context.program, {
66 path: resolvePath(outputDir, "style.css"),
67 content: css.toString(),
68 });
69}
70