Skip to content

Commit

Permalink
feat: Add table of contents to README (#59)
Browse files Browse the repository at this point in the history
* --wip-- [skip ci]

* --wip-- [skip ci]

* Add table of contents to README

* ci: Format code

* Add Contents heading

* ci: Format code

* Update Webhooks section title

* ci: Generate code

* ci: Format code

* Remove note about preview version

---------

Co-authored-by: Seam Bot <[email protected]>
  • Loading branch information
razor-x and seambot authored Mar 29, 2024
1 parent 78fb149 commit 79403af
Show file tree
Hide file tree
Showing 5 changed files with 785 additions and 66 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/generate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ jobs:
install_dependencies: 'false'
- name: Normalize package-lock.json
run: npm install
- name: Generate README.md usage
run: npm run generate:readme
- name: Generate code
run: npm run generate
- name: Commit
uses: stefanzweifel/git-auto-commit-action@v5
with:
Expand Down
132 changes: 83 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@

JavaScript SDK for the Seam API written in TypeScript.

_This repository hosts the next major version of the Seam JavaScript SDK.
This SDK is available for early preview.
It will eventually replace the [seamapi](https://github.com/seamapi/javascript/) package._

## Description

[Seam] makes it easy to integrate IoT devices with your applications.
Expand All @@ -19,12 +15,7 @@ The SDK is fully tree-shakeable
and optimized for use in both client and server applications.

The repository does not contain the SDK code.
Instead, it re-exports from a core set of Seam modules.

_While this SDK is still in preview,
please refer to the individual README files in these repositories for
additional usage documentation not yet available in the primary Seam documentation.
See [this issue for a draft migration guide](https://github.com/seamapi/javascript-next/issues/1) from the seamapi package._
Instead, it re-exports from a core set of Seam modules:

- [@seamapi/http]: JavaScript HTTP client for the Seam API written in TypeScript.
- [@seamapi/webhook]: Webhook SDK for the Seam API written in TypeScript.
Expand All @@ -36,6 +27,47 @@ See [this issue for a draft migration guide](https://github.com/seamapi/javascri
[@seamapi/http]: https://github.com/seamapi/javascript-http
[@seamapi/webhook]: https://github.com/seamapi/javascript-webhook

## Contents

<!-- toc -->

- [Installation](#installation)
- [Usage](#usage)
- [Examples](#examples)
- [List devices](#list-devices)
- [Unlock a door](#unlock-a-door)
- [Authentication Methods](#authentication-methods)
- [API Key](#api-key)
- [Client Session Token](#client-session-token)
- [Publishable Key](#publishable-key)
- [Personal Access Token](#personal-access-token)
- [Console Session Token](#console-session-token)
- [Action Attempts](#action-attempts)
- [Interacting with Multiple Workspaces](#interacting-with-multiple-workspaces)
- [Personal Access Token](#personal-access-token-1)
- [Console Session Token](#console-session-token-1)
- [Advanced Usage](#advanced-usage)
- [Additional Options](#additional-options)
- [Setting the endpoint](#setting-the-endpoint)
- [Configuring the Axios Client](#configuring-the-axios-client)
- [Using the Axios Client](#using-the-axios-client)
- [Overriding the Client](#overriding-the-client)
- [Inspecting the Request](#inspecting-the-request)
- [Receiving Webhooks](#receiving-webhooks)
- [Development and Testing](#development-and-testing)
- [Quickstart](#quickstart)
- [Source code](#source-code)
- [Requirements](#requirements)
- [Publishing](#publishing)
- [Automatic](#automatic)
- [Manual](#manual)
- [GitHub Actions](#github-actions)
- [Contributing](#contributing)
- [License](#license)
- [Warranty](#warranty)

<!-- tocstop -->

## Installation

Add this as a dependency to your project using [npm] with
Expand All @@ -48,45 +80,6 @@ $ npm install seam

## Usage

First, create a webhook using the Seam API or Seam Console
and obtain a Seam webhook secret.

_This example is for [Express], see the [Svix docs for more examples in specific frameworks](https://docs.svix.com/receiving/verifying-payloads/how)._

```js
import { SeamWebhook } from 'seam'
import express from 'express'
import bodyParser from 'body-parser'

import { storeEvent } from './store-event.js'

const app = express()

const webhook = new SeamWebhook(process.env.SEAM_WEBHOOK_SECRET)

app.post(
'/webhook',
bodyParser.raw({ type: 'application/json' }),
(req, res) => {
let data
try {
data = webhook.verify(payload, headers)
} catch {
return res.status(400).send()
}

storeEvent(data, (err) => {
if (err != null) {
return res.status(500).send()
}
res.status(204).send()
})
},
)
```

[Express]: https://expressjs.com/

### Examples

_These examples assume `SEAM_API_KEY` is set in your environment._
Expand Down Expand Up @@ -438,6 +431,47 @@ console.log(`${request.method} ${request.url}`, JSON.stringify(request.body))
const devices = await request.execute()
```

### Receiving Webhooks

First, create a webhook using the Seam API or Seam Console
and obtain a Seam webhook secret.

_This example is for [Express], see the [Svix docs for more examples in specific frameworks](https://docs.svix.com/receiving/verifying-payloads/how)._

```js
import { SeamWebhook } from 'seam'
import express from 'express'
import bodyParser from 'body-parser'

import { storeEvent } from './store-event.js'

const app = express()

const webhook = new SeamWebhook(process.env.SEAM_WEBHOOK_SECRET)

app.post(
'/webhook',
bodyParser.raw({ type: 'application/json' }),
(req, res) => {
let data
try {
data = webhook.verify(payload, headers)
} catch {
return res.status(400).send()
}

storeEvent(data, (err) => {
if (err != null) {
return res.status(500).send()
}
res.status(204).send()
})
},
)
```

[Express]: https://expressjs.com/

## Development and Testing

### Quickstart
Expand Down
42 changes: 28 additions & 14 deletions generate-readme.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
import fs from 'node:fs/promises'
import path from 'node:path'

const submodules = [
path.join('@seamapi', 'webhook'),
path.join('@seamapi', 'http'),
const readmeName = 'README.md'

interface Submodule {
heading: string | null
readmePath: string
}

const submodules: Submodule[] = [
{
heading: null,
readmePath: path.join('node_modules', '@seamapi', 'http', readmeName),
},
{
heading: 'Receiving Webhooks',
readmePath: path.join('node_modules', '@seamapi', 'webhook', readmeName),
},
]

const sections = await Promise.all(submodules.map(readUsageSection))
await writeReadmeUsage(sections.join('\n'))

async function readUsageSection(modulePath: string): Promise<string> {
const data = await fs.readFile(
path.join('node_modules', modulePath, 'README.md'),
{
encoding: 'utf-8',
},
)
async function readUsageSection({
readmePath,
heading,
}: Submodule): Promise<string> {
const data = await fs.readFile(readmePath)

const regex = /#* Usage\s*([\s\S]*?(?=\n## \w))/
const matches = regex.exec(data)
const matches = regex.exec(data.toString())
if (matches == null || matches.length !== 2) {
throw new Error('Missing [## Usage] section')
}
Expand All @@ -28,11 +39,14 @@ async function readUsageSection(modulePath: string): Promise<string> {
throw new Error('Invalid [## Usage] format')
}

return usage.trimStart().trimEnd()
const content = usage.trim()

if (heading == null) return content
return `### ${heading}\n\n${content}`
}

async function writeReadmeUsage(content: string): Promise<void> {
const projectReadme = await fs.readFile('README.md', {
const projectReadme = await fs.readFile(readmeName, {
encoding: 'utf-8',
})

Expand All @@ -41,7 +55,7 @@ async function writeReadmeUsage(content: string): Promise<void> {
const matches = usageRegex.exec(projectReadme)

if (matches == null || matches.length !== 2 || matches[1] == null) {
throw new Error('Invalid README.md format')
throw new Error(`Invalid ${readmeName} format`)
}

const updatedContent = content
Expand Down
Loading

0 comments on commit 79403af

Please sign in to comment.