Skip to content

Commit

Permalink
transfer repo
Browse files Browse the repository at this point in the history
  • Loading branch information
jill64 committed Oct 6, 2023
1 parent 30d570b commit 96d80a4
Show file tree
Hide file tree
Showing 17 changed files with 251 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"]
}
12 changes: 12 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: CI

on: push

jobs:
lint:
uses: jill64/workflows/.github/workflows/lint.yml@main
secrets:
APP_ID: ${{ secrets.APP_ID }}
APP_PEM: ${{ secrets.APP_PEM }}
build:
uses: jill64/workflows/.github/workflows/build.yml@main
7 changes: 7 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: CI

on: pull_request

jobs:
version-check:
uses: jill64/semantic-manager/.github/workflows/version-check.yml@main
10 changes: 10 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Release

on:
push:
branches: main

jobs:
release:
uses: jill64/semantic-manager/.github/workflows/release-npm.yml@main
secrets: inherit
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.DS_Store
node_modules
pnpm-lock.yaml
/dist
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "none"
}
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
# octoflare

A framework for building GitHub Apps with Cloudflare Worker

## Installation

```sh
npm i octoflare-app
```

## Example

```js
// src/index.js
import { octoflare } from 'octoflare-app'

export default octoflare((request, env, { app, payload }) => {
// Application Code
})
```

```toml
# wrangler.toml
name = "YOUR_APP_NAME"
main = "src/index.js"
compatibility_date = "YYYY-MM-DD"
compatibility_flags = ["nodejs_compat"]
```

[Type Definition](./src/types/OctoflareApp.ts)
54 changes: 54 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"name": "octoflare",
"version": "0.0.0",
"description": "A framework for building GitHub Apps with Cloudflare Worker",
"type": "module",
"main": "dist/index.js",
"license": "MIT",
"author": "jill64 <intents.turrets0h@icloud.com> (https://github.com/jill64)",
"bugs": "https://github.com/jill64/octoflare/issues",
"homepage": "https://github.com/jill64/octoflare#readme",
"files": [
"dist"
],
"keywords": [
"cloudflare",
"workers",
"github",
"app"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./workers": {
"types": "./dist/workers/index.d.ts",
"default": "./dist/workers/index.js"
},
"./octokit": {
"types": "./dist/octokit/index.d.ts",
"default": "./dist/octokit/index.js"
}
},
"repository": {
"type": "git",
"url": "https://github.com/jill64/octoflare.git"
},
"scripts": {
"build": "tsc && npx publint",
"lint": "npx prettier --check . && npx eslint && tsc",
"format": "npx prettier --write ."
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "6.7.4",
"@typescript-eslint/parser": "6.7.4",
"typescript": "5.2.2",
"@types/node": "20.8.2"
},
"dependencies": {
"@cloudflare/workers-types": "4.20231002.0",
"@octokit/webhooks-types": "7.3.1",
"octokit": "3.1.1"
}
}
4 changes: 4 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:best-practices", ":pinDependencies"]
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { octoflare } from './octoflare.js'
43 changes: 43 additions & 0 deletions src/octoflare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { WebhookEvent } from '@octokit/webhooks-types'
import { App } from 'octokit'
import { InternalEnv } from './types/InternalEnv.js'
import { OctoflareHandler } from './types/OctoflareHandler.js'
import { verifyRequest } from './verifyRequest.js'

export const octoflare = <Env extends InternalEnv>(
handler: OctoflareHandler<Env>
) => ({
async fetch(request: Request, env: Env): Promise<Response> {
const body = await request.text()

const invalidResponse = verifyRequest({ body, request, env })

if (invalidResponse) {
return invalidResponse
}

const payload = JSON.parse(body) as WebhookEvent

const app = new App({
appId: env.OCTOFLARE_APP_ID,
privateKey: env.OCTOFLARE_APP_PRIVATE_KEY_PKCS8
})

try {
const response = await handler({ request, env, app, payload })

return response
? response
: new Response(null, {
status: 204
})
} catch (e) {
return new Response(
JSON.stringify(e instanceof Error ? e.message : String(e), null, 2),
{
status: 500
}
)
}
}
})
1 change: 1 addition & 0 deletions src/octokit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@octokit/webhooks-types'
5 changes: 5 additions & 0 deletions src/types/InternalEnv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type InternalEnv = {
OCTOFLARE_APP_ID: string
OCTOFLARE_APP_PRIVATE_KEY_PKCS8: string
OCTOFLARE_APP_WEBHOOK_SECRET: string
}
10 changes: 10 additions & 0 deletions src/types/OctoflareHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { WebhookEvent } from '@octokit/webhooks-types'
import { App } from 'octokit'
import { InternalEnv } from './InternalEnv.js'

export type OctoflareHandler<Env extends InternalEnv> = (context: {
request: Request
env: Env
app: App
payload: WebhookEvent
}) => Promise<Response | void> | Response | void
50 changes: 50 additions & 0 deletions src/verifyRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import crypto from 'node:crypto'
import { InternalEnv } from './types/InternalEnv.js'

export const verifyRequest = ({
request,
body,
env
}: {
request: Request
body: string
env: InternalEnv
}): Response | null => {
const { headers, method } = request

if (method === 'GET' || method === 'HEAD') {
return new Response(null, {
status: 204
})
}

if (method !== 'POST') {
return new Response(null, {
status: 405,
headers: {
Allow: 'GET, HEAD, POST'
}
})
}

const headerSignature = headers.get('X-Hub-Signature-256')

if (!headerSignature) {
return new Response(null, {
status: 403
})
}

const signature = crypto
.createHmac('sha256', env.OCTOFLARE_APP_WEBHOOK_SECRET)
.update(body)
.digest('hex')

if (`sha256=${signature}` !== headerSignature) {
return new Response(null, {
status: 403
})
}

return null
}
1 change: 1 addition & 0 deletions src/workers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@cloudflare/workers-types'
11 changes: 11 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"outDir": "dist",
"declaration": true
}
}

0 comments on commit 96d80a4

Please sign in to comment.