From cb264791dc39c162c92337b58dd7d8752eeb0e85 Mon Sep 17 00:00:00 2001 From: Alexander Ryzhikov Date: Sun, 19 Nov 2023 10:42:49 +0200 Subject: [PATCH] Docs (#106) * 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. --- .github/workflows/docs.yml | 71 ++++++++++ Earthfile | 20 +++ docs/Earthfile | 10 ++ docs/c.list | 8 ++ docs/images/.gitkeep | 0 docs/topics/CLI-Reference.md | 43 ++++++ docs/topics/First-schema.md | 227 ++++++++++++++++++++++++++++++++ docs/topics/Installation.md | 61 +++++++++ docs/topics/Overview.md | 27 ++++ docs/topics/Watch-mode.md | 17 +++ docs/topics/starting-page.topic | 42 ++++++ docs/typed-fastify.tree | 17 +++ docs/v.list | 7 + docs/writerside.cfg | 8 ++ 14 files changed, 558 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 Earthfile create mode 100644 docs/Earthfile create mode 100644 docs/c.list create mode 100644 docs/images/.gitkeep create mode 100644 docs/topics/CLI-Reference.md create mode 100644 docs/topics/First-schema.md create mode 100644 docs/topics/Installation.md create mode 100644 docs/topics/Overview.md create mode 100644 docs/topics/Watch-mode.md create mode 100644 docs/topics/starting-page.topic create mode 100644 docs/typed-fastify.tree create mode 100644 docs/v.list create mode 100644 docs/writerside.cfg diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..dabb951 --- /dev/null +++ b/.github/workflows/docs.yml @@ -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 diff --git a/Earthfile b/Earthfile new file mode 100644 index 0000000..7cf6de8 --- /dev/null +++ b/Earthfile @@ -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 diff --git a/docs/Earthfile b/docs/Earthfile new file mode 100644 index 0000000..d81933d --- /dev/null +++ b/docs/Earthfile @@ -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: + diff --git a/docs/c.list b/docs/c.list new file mode 100644 index 0000000..de1a42d --- /dev/null +++ b/docs/c.list @@ -0,0 +1,8 @@ + + + + + + + diff --git a/docs/images/.gitkeep b/docs/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/topics/CLI-Reference.md b/docs/topics/CLI-Reference.md new file mode 100644 index 0000000..c9fb09d --- /dev/null +++ b/docs/topics/CLI-Reference.md @@ -0,0 +1,43 @@ +# CLI Reference + +`%pkg%` provides a command-line interface (CLI) for generating files. + +## Generate schema + +```shell +%cli% gen +``` + +## 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' +``` + diff --git a/docs/topics/First-schema.md b/docs/topics/First-schema.md new file mode 100644 index 0000000..af62703 --- /dev/null +++ b/docs/topics/First-schema.md @@ -0,0 +1,227 @@ + +Create your first schema and service implementation with %pkg% + + +# 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 = { + "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 + + + + + CodeSanbox playground + + diff --git a/docs/topics/Installation.md b/docs/topics/Installation.md new file mode 100644 index 0000000..11e2d7b --- /dev/null +++ b/docs/topics/Installation.md @@ -0,0 +1,61 @@ + +Add %pkg% to your project and setup generator task to package.json + + +# Installation + +1. Add package to your project + + + + +```bash +npm install %pkg% +``` + + + + +```bash +yarn add %pkg% +``` + + + + +```bash +pnpm add %pkg% +``` + + + +2. Add generator task to package.json + +```json +"gen:schema": "tfs gen src/**/*_schema.ts" +``` + +`%pkg%` doesn't have a built-in watcher, so you can use any watcher you want. +If you want your schema to be re-built on changes, you can use `nodemon` or any other watcher that is suitable for your +project. + +```json +"dev:schema": "nodemon --watch src/**/*_schema.ts --exec \"tfs gen src/**/*_schema.ts\"" +``` + +3. Setup is complete and you can build your first schema + +> See [First schema](First-schema.md) page to learn how to create your first schema. +> {style="note"} + +> **To learn more about the cli** +> +> For more information about `tfs` command, see [CLI](CLI-Reference.md) page. +> + + + + Learn more about CLI + Create first schema + + diff --git a/docs/topics/Overview.md b/docs/topics/Overview.md new file mode 100644 index 0000000..4fa3281 --- /dev/null +++ b/docs/topics/Overview.md @@ -0,0 +1,27 @@ + +%pkg% brings strong TypeScript support to Fastify request handlers and generates runtime validation for requests and responses. + + +# Overview + +Sound Types +: +Enhance TypeScript support for Fastify request handlers +and generate runtime validation for requests and responses with `%pkg%` + +OpenAPI Schema +: Design your service using the OpenAPI schema in TypeScript and utilize the types you already use directly in the API +contract. + +Type safety end-to-end +: Package generates runtime validations based on your schema and enforces returning correct data at the type +level. + + +## What are the benefits? + +- `%pkg%` adds strong TypeScript support to Fastify request handlers +- Fastify validates Requests and Responses in runtime based on the JSON Schema +- Type safety end-to-end, you avoid common mistakes when writing request handlers. +- Fast feedback loop, you get errors in your IDE based on types and in runtime. +- You can use the same types in your API contract and in your code. diff --git a/docs/topics/Watch-mode.md b/docs/topics/Watch-mode.md new file mode 100644 index 0000000..1ca7f72 --- /dev/null +++ b/docs/topics/Watch-mode.md @@ -0,0 +1,17 @@ +# Watching for changes + +Currently, `%pkg%` doesn't have a built-in watcher. + +If you want your schema to be re-built on changes, you can use `nodemon` or any other watcher that is suitable for your +project. + +```json +"watch": "nodemon --watch src/**/*_schema.ts --exec \"tfs gen src/**/*_schema.ts\"" +``` + + + + Nodemon + Watchexec + + diff --git a/docs/topics/starting-page.topic b/docs/topics/starting-page.topic new file mode 100644 index 0000000..5dbbc46 --- /dev/null +++ b/docs/topics/starting-page.topic @@ -0,0 +1,42 @@ + + + + + + + Discover %pkg% + + Bring end-to-end type-safety to your Fastify projects by writing OpenAPI schemas in TypeScript. + %pkg% will add type checking and runtime validation to your project. + + + + Overview + Installation + + + + + Get started + + + + + + Explore advanced features + + + + + diff --git a/docs/typed-fastify.tree b/docs/typed-fastify.tree new file mode 100644 index 0000000..bdf4dd0 --- /dev/null +++ b/docs/typed-fastify.tree @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/docs/v.list b/docs/v.list new file mode 100644 index 0000000..7397eb0 --- /dev/null +++ b/docs/v.list @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/writerside.cfg b/docs/writerside.cfg new file mode 100644 index 0000000..d2e763c --- /dev/null +++ b/docs/writerside.cfg @@ -0,0 +1,8 @@ + + + + + + + +