Skip to content
This repository has been archived by the owner on Feb 7, 2023. It is now read-only.

Commit

Permalink
Prepare for auto-generated type definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
mrbbot committed Sep 25, 2021
1 parent 3918848 commit 387652d
Show file tree
Hide file tree
Showing 25 changed files with 1,666 additions and 92 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.DS_Store
.vscode
node_modules
docs.json
overrides.json
4 changes: 2 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"singleQuote": true,
"printWidth": 100
"printWidth": 120,
"proseWrap": "always"
}
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 3.0.0

### Features

- **Types are automatically generated from the runtime - [@mrbbot], [pull/112]**
Types now match exactly what's defined in the runtime source code, meaning `webworker` should be removed from users' `tsconfig.json`s

[@mrbbot]: https://github.com/mrbbot
[pull/112]: https://github.com/cloudflare/workers-types/pull/112

## 2.2.2

### Features
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
## Install

```bash
npm install @cloudflare/workers-types
npm install -D @cloudflare/workers-types
-- Or
yarn add @cloudflare/workers-types
yarn add -D @cloudflare/workers-types
```

## Usage
Expand All @@ -19,7 +19,7 @@ The following is a minimal `tsconfig.json` for use alongside this package:
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"lib": ["ES2020", "WebWorker"],
"lib": ["ES2020"],
"types": ["@cloudflare/workers-types"]
}
}
Expand Down
23 changes: 23 additions & 0 deletions docs/kv.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## `KVNamespace`

Workers KV is a global, low-latency, key-value data store. It supports exceptionally high read volumes with low-latency,
making it possible to build highly dynamic APIs and websites which respond as quickly as a cached static file would.

### `KVNamespace#put`

Creates a new key-value pair, or updates the value for a particular key.

#### Parameters

- `key`: key to associate with the value. A key cannot be empty, `.` or `..`. All other keys are valid.
- `value`: value to store. The type is inferred. The maximum size of a value is 25MB.

#### Returns

Returns a `Promise` that you should `await` on in order to verify a successful update.

#### Examples

```js
await NAMESPACE.put(key, value)
```
161 changes: 161 additions & 0 deletions export/docs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/// <reference types="node" />
import * as fs from "fs";
import * as path from "path";
// marked is great for this: it includes the raw text in its tokens so
// we don't need to write code that renders tokens back to markdown
import marked from "marked";
import { Comment, CommentParam } from "./types";

interface CommentedField {
name: string;
comment?: Comment;
}

interface CommentedDeclaration {
name: string;
comment?: Comment;
members?: CommentedField[];
}

// Get files to build docs from
const docsDir = path.join(__dirname, "..", "docs");
const filePaths = fs.readdirSync(docsDir).map((fileName) => path.join(docsDir, fileName));

// Maps fenced code-block languages to those recognised by declaration renderers
const exampleLangRenames = {
js: "typescript",
ts: "typescript",
javascript: "typescript",
rs: "rust",
};

function trimComment(comment?: Comment) {
if (comment === undefined) return;
comment.text = comment.text.trim();
if (comment.params) {
comment.params = comment.params.map(({ name, text }) => ({ name, text: text.trim() }));
}
if (comment.returns) {
comment.returns = comment.returns.trim();
}
}

const declarations: Record<string, CommentedDeclaration> = {};
let declaration: CommentedDeclaration | undefined = undefined;
let field: CommentedField | undefined = undefined;

enum FieldState {
// Enum member names must case-sensitive match expected 4th level heading texts
Parameters,
Returns,
Examples,
}
let fieldState: FieldState | undefined = undefined;

function pushDeclaration() {
/// Adds the current declaration (if any) to the map
if (declaration !== undefined) {
trimComment(declaration.comment);
declarations[declaration.name] = declaration;

declaration = undefined;
fieldState = undefined;
}
}

function pushField() {
/// Adds the current field (if any) to the current declaration
if (declaration !== undefined && field !== undefined) {
trimComment(field.comment);
declaration.members ??= [];
declaration.members.push(field);

field = undefined;
fieldState = undefined;
}
}

for (const filePath of filePaths) {
const tokens = marked.lexer(fs.readFileSync(filePath, "utf8"));

for (const token of tokens) {
if (token.type === "heading" && token.depth === 2) {
// New declaration
pushDeclaration();
// token.text === "`Declaration`"
declaration = { name: token.text.substring(1, token.text.length - 1) };
continue;
} else if (declaration === undefined) {
// If this isn't a new declaration, wait until we've got a declaration to add to
continue;
}

if (token.type === "heading" && token.depth === 3) {
// New field
pushField();
// token.text === "`Declaration.field`" or "`Declaration#field`"
field = { name: token.text.substring(1 + declaration.name.length + 1, token.text.length - 1) };
continue;
}

if (field && token.type === "heading" && token.depth === 4) {
fieldState = undefined;
if (token.text in FieldState) {
fieldState = FieldState[token.text];
continue;
}
}

if (field && fieldState === FieldState.Parameters && token.type === "list") {
// Field parameters
field.comment ??= { text: "" };
field.comment.params ??= [];
field.comment.params.push(
...token.items.map<CommentParam>((item) => {
// item.text === "`name`: text" (text will be trimmed later by trimComment)
const colon = item.text.indexOf(":");
return {
name: item.text.substring(1, colon - 1),
text: item.text.substring(colon + 1),
};
})
);
continue;
}

if (field && fieldState === FieldState.Returns) {
// Field returns
field.comment ??= { text: "" };
field.comment.returns ??= "";
field.comment.returns += token.raw;
continue;
}

if (field && fieldState === FieldState.Examples && token.type === "code") {
// Field examples
if (!token.lang) continue;
let lang = token.lang;
if (lang in exampleLangRenames) lang = exampleLangRenames[lang];
field.comment ??= { text: "" };
field.comment.examples ??= {};
field.comment.examples[lang] ??= [];
field.comment.examples[lang].push(token.text);
continue;
}

// If we're in a field, add comments to that, otherwise add them to the declaration itself
if (field) {
field.comment ??= { text: "" };
field.comment.text += token.raw;
} else if (declaration) {
declaration.comment ??= { text: "" };
declaration.comment.text += token.raw;
}
}

// Record final field and declaration (if any)
pushField();
pushDeclaration();
}

fs.writeFileSync("docs.json", JSON.stringify(declarations, null, 2), "utf8");
Loading

0 comments on commit 387652d

Please sign in to comment.