├── .github └── workflows │ ├── branches.yml │ └── tags.yml ├── .gitignore ├── README.md ├── encrypted-cookie-store.ts ├── extendable-promise.ts ├── html-rewriter.ts ├── html.ts ├── index.ts ├── json-fetch.ts ├── json-stream.ts ├── kv-storage.ts ├── middleware.ts ├── request-cookie-store.ts ├── resolvable-promise.ts ├── response-creators.ts ├── router.ts ├── scripts └── build_npm.ts ├── signed-cookie-store.ts ├── stream-response.ts └── test └── index.test.js /.github/workflows/branches.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | 6 | on: 7 | push: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: denoland/setup-deno@v1 17 | with: 18 | deno-version: v1.x 19 | - run: deno test ./test 20 | -------------------------------------------------------------------------------- /.github/workflows/tags.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | 6 | on: 7 | push: 8 | tags: 9 | - v* 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: denoland/setup-deno@v1 17 | with: 18 | deno-version: v1.x 19 | - run: deno test ./test 20 | 21 | publish-npm: 22 | needs: test 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v2 26 | - uses: denoland/setup-deno@v1 27 | with: 28 | deno-version: v1.x 29 | - uses: actions/setup-node@v1 30 | with: 31 | node-version: 14 32 | registry-url: https://registry.npmjs.org/ 33 | - uses: pnpm/action-setup@v2 34 | with: 35 | version: 6 36 | run_install: false 37 | - run: deno run -A ./scripts/build_npm.ts 38 | - run: cd ./npm && npm publish 39 | env: 40 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /npm -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shed 2 | __Shed__ is the entire collection of [__Worker Tools__](https://workers.tools) under a single roof, which doubles as a complete web framework built for [Worker Runtimes](https://workers.js.org). 3 | 4 | *** 5 | 6 | __Work In Progress__ 7 | 8 | *** 9 | 10 | ## Tools 11 | - 🧭 [__Worker Router__][router] --- Complete routing solution that works across CF Workers, Deno and Service Workers 12 | - 🔋 [__Worker Middleware__][middleware] --- A suite of standalone HTTP server-side middleware with TypeScript support 13 | - 📄 [__Worker HTML__][html] --- HTML templating and streaming response library 14 | - 📦 [__Storage Area__][kv-storage] --- Storage abstractions for [Cloudflare's KV][cloudflare-kv-storage] and [Deno][deno-kv-storage] 15 | - 🆗 [__Response Creators__][response-creators] --- Factory functions for responses with pre-filled status and status text 16 | - 🎏 [__Stream Response__][stream-response] --- Use async generators to build streaming responses for SSE, etc... 17 | - 🥏 [__JSON Fetch__][json-fetch] --- Drop-in replacements for Fetch API classes with first class support for JSON. 18 | - 🦑 [__JSON Stream__][json-stream] --- Utilities for working with streaming JSON. 19 | - 🍪 [__Request Cookie Store__][request-cookie-store] --- An implementation of the Cookie Store API for use in request handlers. 20 | - ⏱ [__Extendable Promise__][extendable-promise] --- A promise that can be delayed/extended via repeated calls to `waitUntil`. 21 | 22 | 23 | 24 | 25 | Worker Tools also includes a number of polyfills that help bridge the gap between different Worker Runtimes: 26 | - ✏️ [__HTML Rewriter__][html-rewriter] --- Cloudflare's HTML Rewriter for use in Deno, browsers, etc... 27 | - 📍 [__Location Polyfill__][location-polyfill] --- A `Location` polyfill for Cloudflare Workers. 28 | - 🦕 [__Deno Fetch Event Adapter__][deno-fetch-event-adapter] --- Dispatches global `fetch` events using Deno’s native HTTP server. 29 | 30 | [router]: https://workers.tools/router 31 | [middleware]: https://workers.tools/middleware 32 | [html]: https://workers.tools/html 33 | [kv-storage]: https://workers.tools/kv-storage 34 | [cloudflare-kv-storage]: https://workers.tools/cloudflare-kv-storage 35 | [deno-kv-storage]: https://workers.tools/deno-kv-storage 36 | [response-creators]: https://workers.tools/response-creators 37 | [stream-response]: https://workers.tools/stream-response 38 | [json-fetch]: https://workers.tools/json-fetch 39 | [json-stream]: https://workers.tools/json-stream 40 | [request-cookie-store]: https://workers.tools/request-cookie-store 41 | [extendable-promise]: https://workers.tools/extendable-promise 42 | [html-rewriter]: https://workers.tools/html-rewriter 43 | [location-polyfill]: https://workers.tools/location-polyfill 44 | [deno-fetch-event-adapter]: https://workers.tools/deno-fetch-event-adapter 45 | [signed-cookie-store]: https://workers.tools/signed-cookie-store 46 | [encrypted-cookie-store]: https://workers.tools/encrypted-cookie-store 47 | [resolvable-promise]: https://workers.tools/resolvable-promise 48 | 49 | *[SSE]: Server Sent Events 50 | 51 | 52 | ## How to Use 53 | __Deno__ users can import Worker Tools directly from GitHub as they are written in TypeScript with fully qualified import specifiers: 54 | 55 | ```js 56 | import * as shed from 'https://ghuc.cc/worker-tools/shed/index.ts' 57 | ``` 58 | 59 | For __other runtimes__ such as module bundlers, webpack or esbuild, Worker Tools are distributed as node-ified modules that can be installed via __npm__ and behave like regular npm modules 60 | 61 | ```sh 62 | npm install @worker-tools/shed 63 | ``` 64 | 65 | 66 | *[SSE]: Server Sent Events 67 | -------------------------------------------------------------------------------- /encrypted-cookie-store.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/encrypted-cookie-store/index.ts' -------------------------------------------------------------------------------- /extendable-promise.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/extendable-promise/index.ts' -------------------------------------------------------------------------------- /html-rewriter.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/html-rewriter/index.ts' -------------------------------------------------------------------------------- /html.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/html/index.ts'; -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | export { WorkerRouter } from './router.ts' 2 | export type { URLPatternInit, URLPatternComponentResult, URLPatternInput, URLPatternResult, Awaitable, RouteContext, ErrorContext, Middleware, Handler, ErrorHandler, Method } from './router.ts' 3 | export * from './middleware.ts' 4 | export * from './response-creators.ts' 5 | export * from './html.ts' 6 | export * from './stream-response.ts' 7 | export * from './json-fetch.ts' 8 | export * from './json-stream.ts' 9 | export * from './kv-storage.ts' 10 | export * from './request-cookie-store.ts' 11 | export * from './signed-cookie-store.ts' 12 | export { EncryptedCookieStore } from './encrypted-cookie-store.ts' 13 | export type { EncryptedCookieStoreOptions } from './encrypted-cookie-store.ts'; 14 | export * from './resolvable-promise.ts' 15 | export * from './extendable-promise.ts' 16 | 17 | // TODO: Include polyfills in index!? 18 | // export * from './html-rewriter.ts' 19 | -------------------------------------------------------------------------------- /json-fetch.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/json-fetch/index.ts' -------------------------------------------------------------------------------- /json-stream.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/json-stream/index.ts' -------------------------------------------------------------------------------- /kv-storage.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/kv-storage/index.ts' -------------------------------------------------------------------------------- /middleware.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/middleware/index.ts'; -------------------------------------------------------------------------------- /request-cookie-store.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/request-cookie-store/index.ts' -------------------------------------------------------------------------------- /resolvable-promise.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/resolvable-promise/index.ts' -------------------------------------------------------------------------------- /response-creators.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/response-creators/index.ts'; -------------------------------------------------------------------------------- /router.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/router/index.ts'; -------------------------------------------------------------------------------- /scripts/build_npm.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S deno run --allow-read --allow-write=./,/Users/qwtel/Library/Caches/deno --allow-net --allow-env=HOME,DENO_AUTH_TOKENS,DENO_DIR --allow-run=git,pnpm 2 | 3 | import { basename } from "https://deno.land/std@0.133.0/path/mod.ts"; 4 | import { build, emptyDir } from "https://deno.land/x/dnt@0.23.0/mod.ts"; 5 | 6 | import { 7 | copyMdFiles, mkPackage, 8 | } from 'https://gist.githubusercontent.com/qwtel/ecf0c3ba7069a127b3d144afc06952f5/raw/latest-version.ts' 9 | 10 | await emptyDir("./npm"); 11 | 12 | const name = basename(Deno.cwd()) 13 | 14 | await build({ 15 | entryPoints: ["./index.ts", { 16 | name: './encrypted-cookie-store', 17 | path: 'encrypted-cookie-store.ts' 18 | }, { 19 | name: './extendable-promise', 20 | path: 'extendable-promise.ts' 21 | }, { 22 | name: './html-rewriter', 23 | path: 'html-rewriter.ts' 24 | }, { 25 | name: './html', 26 | path: 'html.ts' 27 | }, { 28 | name: './json-fetch', 29 | path: 'json-fetch.ts' 30 | }, { 31 | name: './json-stream', 32 | path: 'json-stream.ts' 33 | }, { 34 | name: './kv-storage', 35 | path: 'kv-storage.ts' 36 | }, { 37 | name: './middleware', 38 | path: 'middleware.ts' 39 | }, { 40 | name: './request-cookie-store', 41 | path: 'request-cookie-store.ts' 42 | }, { 43 | name: './resolvable-promise', 44 | path: 'resolvable-promise.ts' 45 | }, { 46 | name: './response-creators', 47 | path: 'response-creators.ts' 48 | }, { 49 | name: './router', 50 | path: 'router.ts' 51 | }, { 52 | name: './signed-cookie-store', 53 | path: 'signed-cookie-store.ts' 54 | }, { 55 | name: './stream-response', 56 | path: 'stream-response.ts' 57 | } 58 | ], 59 | outDir: "./npm", 60 | shims: {}, 61 | test: false, 62 | typeCheck: false, 63 | package: await mkPackage(name), 64 | declaration: true, 65 | packageManager: 'pnpm', 66 | compilerOptions: { 67 | sourceMap: true, 68 | target: 'ES2019', 69 | }, 70 | mappings: { 71 | "https://ghuc.cc/worker-tools/encrypted-cookie-store/index.ts": { 72 | name: "@worker-tools/encrypted-cookie-store", 73 | version: "latest" 74 | }, 75 | 'https://ghuc.cc/worker-tools/extendable-promise/index.ts': { 76 | name: "@worker-tools/extendable-promise", 77 | version: "latest" 78 | }, 79 | "https://ghuc.cc/worker-tools/html-rewriter/index.ts": { 80 | name: "@worker-tools/html-rewriter", 81 | version: "latest" 82 | }, 83 | "https://ghuc.cc/worker-tools/html/index.ts": { 84 | name: "@worker-tools/html", 85 | version: "latest" 86 | }, 87 | "https://ghuc.cc/worker-tools/json-fetch/index.ts": { 88 | name: "@worker-tools/json-fetch", 89 | version: "latest" 90 | }, 91 | "https://ghuc.cc/worker-tools/json-stream/index.ts": { 92 | name: "@worker-tools/json-stream", 93 | version: "latest" 94 | }, 95 | "https://ghuc.cc/worker-tools/kv-storage/index.ts": { 96 | name: "@worker-tools/kv-storage", 97 | version: "latest" 98 | }, 99 | "https://ghuc.cc/worker-tools/middleware/index.ts": { 100 | name: "@worker-tools/middleware", 101 | version: "latest" 102 | }, 103 | "https://ghuc.cc/worker-tools/request-cookie-store/index.ts": { 104 | name: "@worker-tools/request-cookie-store", 105 | version: "latest" 106 | }, 107 | 'https://ghuc.cc/worker-tools/resolvable-promise/index.ts': { 108 | name: "@worker-tools/resolvable-promise", 109 | version: "latest" 110 | }, 111 | "https://ghuc.cc/worker-tools/response-creators/index.ts": { 112 | name: "@worker-tools/response-creators", 113 | version: "latest" 114 | }, 115 | "https://ghuc.cc/worker-tools/router/index.ts": { 116 | name: "@worker-tools/router", 117 | version: "latest" 118 | }, 119 | "https://ghuc.cc/worker-tools/signed-cookie-store/index.ts": { 120 | name: "@worker-tools/signed-cookie-store", 121 | version: "latest" 122 | }, 123 | "https://ghuc.cc/worker-tools/stream-response/index.ts": { 124 | name: "@worker-tools/stream-response", 125 | version: "latest" 126 | }, 127 | }, 128 | }); 129 | 130 | // post build steps 131 | await copyMdFiles() 132 | -------------------------------------------------------------------------------- /signed-cookie-store.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/signed-cookie-store/index.ts' -------------------------------------------------------------------------------- /stream-response.ts: -------------------------------------------------------------------------------- 1 | export * from 'https://ghuc.cc/worker-tools/stream-response/index.ts' -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | import 'https://gist.githubusercontent.com/qwtel/b14f0f81e3a96189f7771f83ee113f64/raw/TestRequest.ts' 2 | import { 3 | assert, 4 | assertExists, 5 | assertEquals, 6 | assertStrictEquals, 7 | assertStringIncludes, 8 | assertThrows, 9 | assertRejects, 10 | assertArrayIncludes, 11 | } from 'https://deno.land/std@0.133.0/testing/asserts.ts' 12 | const { test } = Deno; 13 | 14 | import * as shed from '../index.ts' 15 | 16 | test('exists', () => { 17 | assertExists(shed) 18 | }) 19 | --------------------------------------------------------------------------------