Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ dist
public/__redirects
public/analytics/static/downloads/main.css
src/content/workers-ai-models/*.json
src/content/partials/images/*.mdx
src/content/partials/images/*.mdx
src/content/style-guide/components/*.mdx
84 changes: 77 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
"tailwindcss": "4.1.4",
"tippy.js": "6.3.7",
"ts-blank-space": "0.6.2",
"ts-morph": "26.0.0",
"tsx": "4.20.5",
"typescript": "5.9.2",
"typescript-eslint": "8.41.0",
Expand Down
137 changes: 137 additions & 0 deletions src/components/WorkersTypesInterface.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
import { JSDocTagInfo, Project } from "ts-morph";
import RawTypes from "@cloudflare/workers-types/experimental/index.d.ts?raw";
import { marked } from "marked";
import AnchorHeading from "./AnchorHeading.astro";
import Type from "./Type.astro";
import { Code } from "@astrojs/starlight/components";
import { z } from "astro:schema";

type Props = z.input<typeof props>;

const props = z
.object({
name: z.string(),
})
.strict();

const { name: interfaceName } = props.parse(Astro.props);

function JSDocToMarkdown(jsdoc: JSDocTagInfo[]) {
return marked.parse(
jsdoc
.map((tag) => {
return tag
.getText()
.filter((part) => part.kind === "text")
.map((part) => {
return part.text;
})
.join(" ");
})
.join("\n"),
{ async: false },
);
}

const project = new Project();
const sourceFile = project.createSourceFile("index.d.ts", RawTypes);

const int = sourceFile.getInterface(interfaceName);

if (!int) {
throw new Error(
`[WorkersTypesInterface] Could not find interface "${interfaceName}"`,
);
}

const methods = int.getMethods();

if (!methods || methods.length === 0) {
throw new Error(
`[WorkersTypesInterface] Could not find any methods for interface "${interfaceName}"`,
);
}
---

<AnchorHeading title={interfaceName} depth={2} />
<Code lang="ts" code={int.print()} wrap={true} />
<AnchorHeading title="Methods" depth={3} slug={`${interfaceName}-methods`} />
{
methods.map((method) => {
const methodName = method.getName();
const signature = method.getSignature();

if (!signature) {
throw new Error(
`[WorkersTypesInterface] Could not find signature for method "${interfaceName}#${methodName}"`,
);
}

const comment = signature
.getDocumentationComments()
.map((comment) => {
return comment.getText();
})
.join("\n");

const jsdoc = signature.getJsDocTags();
const returnsJsdoc = jsdoc.find((tag) => tag.getName() === "returns");

const parameters = signature.getParameters();
const returns = signature.getReturnType();

return (
<>
<AnchorHeading
title={`\`${methodName}()\``}
depth={4}
slug={`${interfaceName}-${methodName}`}
/>
<p>{comment}</p>
<AnchorHeading
title="Signature"
depth={5}
slug={`${interfaceName}-${methodName}-signature`}
/>
<Code lang="ts" code={method.print()} wrap={true} />
<AnchorHeading
title="Parameters"
depth={5}
slug={`${interfaceName}-${methodName}-parameters`}
/>
<ul>
{parameters?.map((param) => {
const type = param.getDeclarations()[0].getType();
const jsdoc = param.getJsDocTags();

const markdown = JSDocToMarkdown(jsdoc);

return (
<li>
<span>
<code>{param.getName()}</code>
</span>{" "}
<Type text={type.getText()} />
<Fragment set:html={markdown} />
</li>
);
})}
</ul>
<AnchorHeading
title="Returns"
depth={5}
slug={`${interfaceName}-${methodName}-returns`}
/>
<ul>
<li>
<Type text={returns?.getText()} />
<Fragment
set:html={returnsJsdoc ? JSDocToMarkdown([returnsJsdoc]) : ""}
/>
</li>
</ul>
</>
);
})
}
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export { default as Width } from "./Width.astro";
export { default as WorkersArchitectureDiagram } from "./WorkersArchitectureDiagram.astro";
export { default as WorkersIsolateDiagram } from "./WorkersIsolateDiagram.astro";
export { default as WorkersTemplates } from "./WorkersTemplates.astro";
export { default as WorkersTypesInterface } from "./WorkersTypesInterface.astro";
export { default as YouTube } from "./YouTube.astro";
export { default as YouTubeVideos } from "./YouTubeVideos.astro";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Workers Types Interface
styleGuide:
component: WorkersTypesInterface
---

:::caution

This component should be considered a work-in-progress and there may be parts of an interface not properly represented yet.

:::

This component uses [`ts-morph`](https://ts-morph.com/) to generate documentation about the methods on an interface from `@cloudflare/workers-types`, including their parameters and return types.

## Import

```mdx
import { WorkersTypesInterface } from "~/components";
```

## Usage

```mdx live
import { WorkersTypesInterface } from "~/components";

<WorkersTypesInterface name="ForwardableEmailMessage" />
```

## `<WorkersTypesInterface>` Props

### `name`

**required**

**type:** `string`

The name of the TypeScript interface.