Skip to content

Commit

Permalink
Docs (#106)
Browse files Browse the repository at this point in the history
* docs: add initial docs with Writers IDE

* ci: add write permissions to deploy in docs.yml

* ci: restrict docs workflow to main branch only

This update has made changes to .github/workflows/docs.yml to limit the triggering of the docs workflow to only the main branch. Previously, it was set to run on both main and docs branches.
  • Loading branch information
Coobaha authored Nov 19, 2023
1 parent d78beea commit cb26479
Show file tree
Hide file tree
Showing 14 changed files with 558 additions and 0 deletions.
71 changes: 71 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Build documentation

on:
push:
branches: ['main']

workflow_dispatch:

env:
# Name of module and id separated by a slash
INSTANCE: docs/typed-fastify
# Replace HI with the ID of the instance in capital letters
ARTIFACT: webHelpTYPED-FASTIFY2-all.zip

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
version: 'latest'

- name: Checkout repository
uses: actions/checkout@v4

- name: Run build
run: earthly +docs.build
- name: Run tests
run: earthly +docs.test

- name: Upload documentation
uses: actions/upload-artifact@v3
with:
name: docs
path: |
artifacts/${{ env.ARTIFACT }}
artifacts/report.json
retention-days: 7

deploy:
permissions:
id-token: write
pages: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: docs

- name: Unzip artifact
uses: montudor/action-zip@v1
with:
args: unzip -qq ${{ env.ARTIFACT }} -d dir

- name: Setup Pages
uses: actions/configure-pages@v3

- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: dir

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
20 changes: 20 additions & 0 deletions Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
VERSION 0.7

docs.deps:
FROM registry.jetbrains.team/p/writerside/builder/writerside-builder:232.10165.1

docs.build:
FROM +docs.deps
COPY docs docs
ENV DISPLAY :99
RUN Xvfb :99 & /opt/builder/bin/idea.sh helpbuilderinspect -source-dir=docs -product docs/typed-fastify -output-dir artifacts
SAVE ARTIFACT artifacts AS LOCAL artifacts

docs.test:
FROM openjdk:18-jdk-slim
RUN apt-get update && apt-get install -y curl
RUN curl -o wrs-doc-app.jar -L https://packages.jetbrains.team/maven/p/writerside/maven/com/jetbrains/writerside/writerside-ci-checker/1.0/writerside-ci-checker-1.0.jar

COPY artifacts artifacts

RUN java -jar wrs-doc-app.jar artifacts/report.json docs/typed-fastify
10 changes: 10 additions & 0 deletions docs/Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
VERSION 0.6
FROM registry.jetbrains.team/p/writerside/builder/writerside-builder:232.10165.1

docs_build:
COPY docs docs
ENV DISPLAY :99
RUN Xvfb :99 & /opt/builder/bin/idea.sh helpbuilderinspect -source-dir=docs -product docs/typed-fastify -output-dir artifacts

docs_test:

8 changes: 8 additions & 0 deletions docs/c.list
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE categories
SYSTEM "https://resources.jetbrains.com/writerside/1.0/categories.dtd">
<categories>
<category id="related" name="Related docs" order="1"/>
<category id="external" name="External docs" order="2"/>
<category id="misc" name="Miscellaneous" order="3"/>
</categories>
Empty file added docs/images/.gitkeep
Empty file.
43 changes: 43 additions & 0 deletions docs/topics/CLI-Reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# CLI Reference

`%pkg%` provides a command-line interface (CLI) for generating files.

## Generate schema

```shell
%cli% gen <file>
```

## Options

file
: Can be one or more file names or glob patterns.

### Other Options

--version
: Displays version information.

--help
: Displays help.

### Examples

Single file

```shell
%cli% gen src/example_schema.ts
```

Multiple files

```shell
%cli% gen src/example_schema.ts src/example_schema2.ts
```

Glob pattern

```shell
%cli% gen 'src/**/*_schema.ts'
```

227 changes: 227 additions & 0 deletions docs/topics/First-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
<card-summary>
Create your first schema and service implementation with %pkg%
</card-summary>

# First schema

> This tutorial assumes you already have a basic understanding of [Fastify](https://www.fastify.io/) and already have a
> project with Fastify set up.
With `%pkg%` you always start API development with schema defined in TypeScript.

## Show me the code

Use [CodeSanbox](https://codesandbox.io/p/github/Coobaha/typed-fastify-example?file=%2Fsrc%2Fexample_schema.ts) to quickly try out `%pkg%` with Fastify.

Try different requests `GET /`, `GET /?name=error` and `GET /?name=1&name=2`.
Also try changing the schema and use different types and implement new routes 🤓


## Define schema

Here is an example of an imaginary API schema:

```typescript
// example_schema.ts

import type { Schema } from "@coobaha/typed-fastify";

interface User {
name: string;
id: number;
}

interface ResponseError {
message: string;
code: number;
}

export interface ExampleSchema extends Schema {
paths: {
"GET /": {
request: {
querystring: {
name?: string;
};
};
response: {
200: {
content: User;
};
404: {
content: ResponseError;
};
};
};
};
}
```

## Use schema in service implementation

Create a service implementation that matches the schema:

```typescript
// example_service.ts

import { Service } from "@coobaha/typed-fastify";

import type { ExampleSchema } from "./example_schema";

const exampleService: Service<ExampleSchema> = {
"GET /": (req, reply) => {
const name = req.query.name ?? "John";
if (name === "error") {
return reply.status(404).send({
code: 404,
message: "Not Found",
});
}
return reply.status(200).send({
id: 1,
name: name,
});
},
};
```

> TypeScript will check that `exampleService` implementation matches the `ExampleSchema` schema.
> We will generate and use json schema for validation in the next step.{style="note"}{style="note"}
## Runtime validation of Request and Response

TypeScript compiler will ensure that `exampelService` is correctly implemented on a type level, but we also want to
validate the request and response at runtime. `%pkg%` can generate JSON schema for us that fastify will use for
validation.

Run the following command in terminal to generate JSON schema:

```bash
npx tfs gen example_schema.ts
```

```json
{
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "example_schema",
"properties": {
"User": {
"type": "object",
"required": [
"id",
"name"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "number"
}
}
},
"ResponseError": {
"type": "object",
"required": [
"code",
"message"
],
"additionalProperties": false,
"properties": {
"message": {
"type": "string"
},
"code": {
"type": "number"
}
}
}
},
"type": "object"
},
"fastify": {
"GET /": {
"request": {
"type": "object",
"required": [
"querystring"
],
"additionalProperties": false,
"properties": {
"querystring": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
}
}
}
}
},
"response": {
"200": {
"$ref": "example_schema#/properties/User"
},
"404": {
"$ref": "example_schema#/properties/ResponseError"
}
}
}
}
}
```

{collapsible="true" collapsed-title="Generated JSON Schema"}


## Add service to Fastify instance

We now have a JSON schema file `example_schema.gen.json` that we can use to validate requests and responses. To wire up
the service to Fastify, we need to add the schema and service to Fastify instance

> You can add this schema to version control and commit it to your repository.
> This way you can also verify diffs and always have the latest version of the schema in your repository.
>
> You can also configure file nesting in your Editor to hide generated files from the project view.
In the same file where you defined `exampleService`, add the following code:

```typescript
// example_service.ts

import jsonSchema from './example_schema.gen.json'

// ... other imports and exampleService implementation

const app = fastify();

addSchema(app, {
jsonSchema: jsonSchema,
service: exampleService,
});
```

## That's it

You can now run the server and try out the API.

It will have a:
1. Type safe implementation of the service, that matches the schema
2. Runtime validation of request and response
3. Generated JSON schema that allows you to use it for documentation and verification.

You can find the full example code here:

- Interactive playground [CodeSanbox](https://codesandbox.io/p/github/Coobaha/typed-fastify-example?file=%2Fsrc%2Fexample_schema.ts)
- [typed-fastify-example](https://github.com/coobaha/typed-fastify-example) on GitHub


<seealso style="links">
<category ref="external">
<a href="https://codesandbox.io/p/github/Coobaha/typed-fastify-example?file=%2Fsrc%2Fexample_schema.ts">CodeSanbox playground</a>
</category>
</seealso>
Loading

0 comments on commit cb26479

Please sign in to comment.