Skip to content

Commit

Permalink
chore: repository maintenance
Browse files Browse the repository at this point in the history
chore: re-enable prettier
chore: update github actions workflows
chore: add Node 14 and 16 to tests
docs: fix table of contest anchor links
  • Loading branch information
Cherry committed May 18, 2021
1 parent e96e520 commit a9bb992
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 121 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto
* text eol=lf
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
uses: actions/setup-node@v2
with:
node-version: '12.x'
- run: npm install -g markdownlint-cli@0.23.2
- run: npm install -g markdownlint-cli@0.27.1
- run: markdownlint '**/*.md' --ignore node_modules
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ jobs:

strategy:
matrix:
node-version: [8.x, 10.x, 12.x]
node-version: [8.x, 10.x, 12.x, 14.x, 16.x]

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: npm install, build, and test
Expand Down
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CHANGELOG.md
package.json
package-lock.json
dist/**/*
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"endOfLine": "lf",
"trailingComma": "all",
"singleQuote": true,
"semi": false,
Expand Down
22 changes: 11 additions & 11 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
- Focusing on what is best not just for us as individuals, but for the
overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting

## Enforcement Responsibilities
Expand Down Expand Up @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
Expand Down
49 changes: 25 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,25 @@ For users who _do_ want to customize their assets, and want to build complex exp

The Cloudflare Workers Discord server is an active place where Workers users get help, share feedback, and collaborate on making our platform better. The `#workers-sites` channel in particular is a great place to chat about `kv-asset-handler`, and building cool experiences for your users using these tools! If you have questions, want to share what you're working on, or give feedback, [join us in Discord and say hello](https://discord.gg/cloudflaredev)!

* [Installation](#installation)
* [Usage](#usage)
* [`getAssetFromKV`](#-getassetfromkv-)
- [Example](#example)
+ [Return](#return)
+ [Optional Arguments](#optional-arguments)
- [`mapRequestToAsset`](#-maprequesttoasset-)
- [Example](#example-1)
- [`cacheControl`](#-cachecontrol-)
* [`browserTTL`](#-browserttl-)
* [`edgeTTL`](#-edgettl-)
* [`bypassCache`](#-bypasscache-)
- [`ASSET_NAMESPACE`](#-asset-namespace-)
- [`ASSET_MANIFEST` (optional)](#-asset-manifest---optional-)
- [Helper functions](#helper-functions)
* [`mapRequestToAsset`](#-maprequesttoasset--1)
* [`serveSinglePageApp`](#-servesinglepageapp-)
- [Cache revalidation and etags](#cache-revalidation-and-etags)
- [Installation](#installation)
- [Usage](#usage)
- [`getAssetFromKV`](#-getassetfromkv)
- [Example](#example)
* [Return](#return)
* [Optional Arguments](#optional-arguments)
- [`mapRequestToAsset`](#-maprequesttoasset)
- [Example](#example-1)
- [`cacheControl`](#-cachecontrol)
- [`browserTTL`](#-browserttl)
- [`edgeTTL`](#-edgettl)
- [`bypassCache`](#-bypasscache)
- [`ASSET_NAMESPACE`](#-asset-namespace)
- [`ASSET_MANIFEST` (optional)](#-asset-manifest---optional)

* [Helper functions](#helper-functions)
- [`mapRequestToAsset`](#-maprequesttoasset-1)
- [`serveSinglePageApp`](#-servesinglepageapp)
* [Cache revalidation and etags](#cache-revalidation-and-etags)

## Installation

Expand Down Expand Up @@ -69,7 +70,7 @@ Known errors to be thrown are:
```js
import { getAssetFromKV, NotFoundError, MethodNotAllowedError } from '@cloudflare/kv-asset-handler'

addEventListener('fetch', event => {
addEventListener('fetch', (event) => {
event.respondWith(handleEvent(event))
})

Expand All @@ -83,7 +84,7 @@ async function handleEvent(event) {
} else if (e instanceof MethodNotAllowedError) {
// ...
} else {
return new Response("An unexpected error occurred", { status: 500 })
return new Response('An unexpected error occurred', { status: 500 })
}
}
} else return fetch(event.request)
Expand All @@ -104,7 +105,7 @@ mapRequestToAsset(Request) => Request

Maps the incoming request to the value that will be looked up in Cloudflare's KV

By default, mapRequestToAsset is set to the exported function [`mapRequestToAsset`](#maprequesttoasset-1). This works for most static site generators, but you can customize this behavior by passing your own function as `mapRequestToAsset`. The function should take a `Request` object as its only argument, and return a new `Request` object with an updated path to be looked up in the asset manifest/KV.
By default, mapRequestToAsset is set to the exported function [`mapRequestToAsset`](#maprequesttoasset-1). This works for most static site generators, but you can customize this behavior by passing your own function as `mapRequestToAsset`. The function should take a `Request` object as its only argument, and return a new `Request` object with an updated path to be looked up in the asset manifest/KV.

For SPA mapping pass in the [`serveSinglePageApp`](#servesinglepageapp) function

Expand Down Expand Up @@ -219,8 +220,8 @@ All responses served from cache (including those with `cf-cache-status: MISS`) i

Resources served with an `etag` allow browsers to use the `if-none-match` request header to make conditional requests for that resource in the future. This has two major benefits:

* When a request's `if-none-match` value matches the `etag` of the resource in Cloudflare cache, Cloudflare will send a `304 Not Modified` response without a body, saving bandwidth.
* Changes to a file on the server are immediately reflected in the browser - even when the cache control directive `max-age` is unexpired.
- When a request's `if-none-match` value matches the `etag` of the resource in Cloudflare cache, Cloudflare will send a `304 Not Modified` response without a body, saving bandwidth.
- Changes to a file on the server are immediately reflected in the browser - even when the cache control directive `max-age` is unexpired.

#### Disable the `etag`

Expand All @@ -229,7 +230,7 @@ To turn `etags` **off**, you must bypass cache:
```js
/* Turn etags off */
let cacheControl = {
bypassCache: true
bypassCache: true,
}
```

Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
"scripts": {
"prepack": "npm run build",
"build": "tsc -d",
"format": "prettier --write '**/*.js'",
"format": "prettier --write \"**/*.{js,ts,json,md}\"",
"pretest": "npm run build",
"test": "ava dist/test/*.js --verbose"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cloudflare/workers-site-npm-pkg.git"
"url": "git+https://github.com/cloudflare/kv-asset-handler.git"
},
"keywords": [
"kv",
Expand All @@ -35,6 +35,7 @@
},
"devDependencies": {
"ava": "^3.9.0",
"prettier": "^2.3.0",
"service-worker-mock": "^2.0.5",
"typescript": "^3.9.5"
}
Expand Down
18 changes: 9 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,10 @@ const getAssetFromKV = async (event: FetchEvent, options?: Partial<Options>): Pr

const request = event.request
const ASSET_NAMESPACE = options.ASSET_NAMESPACE
const ASSET_MANIFEST = typeof (options.ASSET_MANIFEST) === 'string'
? JSON.parse(options.ASSET_MANIFEST)
: options.ASSET_MANIFEST
const ASSET_MANIFEST =
typeof options.ASSET_MANIFEST === 'string'
? JSON.parse(options.ASSET_MANIFEST)
: options.ASSET_MANIFEST

if (typeof ASSET_NAMESPACE === 'undefined') {
throw new InternalError(`there is no KV namespace bound to the script`)
Expand All @@ -103,13 +104,13 @@ const getAssetFromKV = async (event: FetchEvent, options?: Partial<Options>): Pr
} else if (ASSET_MANIFEST[rawPathKey]) {
requestKey = request
} else if (ASSET_MANIFEST[decodeURIComponent(rawPathKey)]) {
pathIsEncoded = true;
pathIsEncoded = true
requestKey = request
} else {
const mappedRequest = mapRequestToAsset(request)
const mappedRawPathKey = new URL(mappedRequest.url).pathname.replace(/^\/+/, '')
if (ASSET_MANIFEST[decodeURIComponent(mappedRawPathKey)]) {
pathIsEncoded = true;
pathIsEncoded = true
requestKey = mappedRequest
} else {
// use default mapRequestToAsset
Expand All @@ -132,7 +133,7 @@ const getAssetFromKV = async (event: FetchEvent, options?: Partial<Options>): Pr
const cache = caches.default
let mimeType = mime.getType(pathKey) || options.defaultMimeType
if (mimeType.startsWith('text') || mimeType === 'application/javascript') {
mimeType += '; charset=utf-8'
mimeType += '; charset=utf-8'
}

let shouldEdgeCache = false // false if storing in KV by raw file path i.e. no hash
Expand Down Expand Up @@ -197,11 +198,10 @@ const getAssetFromKV = async (event: FetchEvent, options?: Partial<Options>): Pr
request.headers.get('if-none-match') === `${pathKey}`,
].every(Boolean)


if (shouldRevalidate) {
// fixes issue #118
if (response.body && 'cancel' in Object.getPrototypeOf(response.body)) {
response.body.cancel();
response.body.cancel()
console.log('Body exists and environment supports readable streams. Body cancelled')
} else {
console.log('Environment doesnt support readable streams')
Expand All @@ -219,7 +219,7 @@ const getAssetFromKV = async (event: FetchEvent, options?: Partial<Options>): Pr
let opts = {
headers,
status: 0,
statusText: ''
statusText: '',
}
if (response.status) {
opts.status = response.status
Expand Down
29 changes: 16 additions & 13 deletions src/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,29 @@ export const mockManifest = () => {
'index.html': `index.${HASH}.html`,
'sub/blah.png': `sub/blah.${HASH}.png`,
'sub/index.html': `sub/index.${HASH}.html`,
'client': `client.${HASH}`,
client: `client.${HASH}`,
'client/index.html': `client.${HASH}`,
'你好/index.html': `你好/index.${HASH}.html`
'你好/index.html': `你好/index.${HASH}.html`,
})
}

let cacheStore: any = new Map()
interface CacheKey {
url:object;
headers:object
url: object
headers: object
}
export const mockCaches = () => {
return {
default: {
async match (key: any) {
async match(key: any) {
let cacheKey: CacheKey = {
url: key.url,
headers: {}
headers: {},
}
let response
if (key.headers.has('if-none-match')) {
cacheKey.headers = {
'etag': key.headers.get('if-none-match')
etag: key.headers.get('if-none-match'),
}
response = cacheStore.get(JSON.stringify(cacheKey))
} else {
Expand All @@ -87,7 +87,10 @@ export const mockCaches = () => {
// The Range request header triggers the response header Content-Range ...
const range = key.headers.get('range')
if (range) {
response.headers.set('content-range', `bytes ${range.split('=').pop()}/${response.headers.get('content-length')}`)
response.headers.set(
'content-range',
`bytes ${range.split('=').pop()}/${response.headers.get('content-length')}`,
)
}
// ... which we are using in this repository to set status 206
if (response.headers.has('content-range')) {
Expand All @@ -98,16 +101,16 @@ export const mockCaches = () => {
}
return response
},
async put (key: any, val: Response) {
async put(key: any, val: Response) {
let headers = new Headers(val.headers)
let body = await val.text()
let resp = new Response(body, { headers })
headers.set('content-length', (body.length).toString())
headers.set('content-length', body.length.toString())
let cacheKey: CacheKey = {
url: key.url,
headers: {
'etag': val.headers.get('etag')
}
etag: val.headers.get('etag'),
},
}
return cacheStore.set(JSON.stringify(cacheKey), resp)
},
Expand All @@ -122,5 +125,5 @@ export function mockGlobal() {
Object.assign(global, { caches: mockCaches() })
}
export const sleep = (milliseconds: number) => {
return new Promise(resolve => setTimeout(resolve, milliseconds))
return new Promise((resolve) => setTimeout(resolve, milliseconds))
}
Loading

0 comments on commit a9bb992

Please sign in to comment.