Skip to content
This repository has been archived by the owner on Mar 19, 2024. It is now read-only.

Commit

Permalink
feat: ported vary to deno
Browse files Browse the repository at this point in the history
  • Loading branch information
prisis committed Jun 7, 2020
1 parent 98298f8 commit b0977b0
Show file tree
Hide file tree
Showing 9 changed files with 429 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .github/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ repository:

# https://developer.github.com/v3/repos/branches/#remove-branch-protection

topics: "deno, module, library, template, dmpjs, linux, macos, windows"
topics: "deno, module, drash, vary"
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

62 changes: 52 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,67 @@
<h1 align="center">Deno module template</h1>
<h1 align="center">vary</h1>
<p align="center">
<a href="https://github.com/semantic-release/semantic-release"><img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square"></a>
<a href="https://github.com/dmpjs/vary/releases">
<img src="https://img.shields.io/github/release/dmpjs/vary.svg?color=bright_green&label=latest&style=flat-square">
</a>
<a href="https://github.com/dmpjs/vary/actions">
<img src="https://img.shields.io/github/workflow/status/dmpjs/vary/master?label=ci&style=flat-square">
</a>
<a href="https://github.com/semantic-release/semantic-release">
<img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square">
</a>
<a href="https://opensource.org/licenses/MIT">
<img src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square">
</a>
</p>

Provides a GitHub repository template for a deno module, using GitHub actions.
Manipulate the HTTP Vary header.

## Installation
vary is based on [vary](https://www.npmjs.com/package/vary) and has been ported for use on Deno

:bulb: this is a great place for showing how to import the module, see below:
## Installation

Run
Use the following import:

```
const { greeting } = "https://raw.githubusercontent.com/dmpjs/deno-module-template/master/mod.ts"; // import from github as raw data
const { vary } = "https://raw.githubusercontent.com/dmpjs/vary/master/mod.ts"; // import from github as raw data
const { greeting } = "https://deno.land/x/deno-module-template/mod.ts"; // If module is uploaded into deno.land
const { vary } = "https://deno.land/x/vary/mod.ts"; // If module is uploaded into deno.land
```

## Usage

:bulb: this is a great place for showing, usage examples
### vary(responseHeadersGet, responseHeadersSet, field)

Adds the given header field to the Vary response header of response. This can be a string of a single field, a string of a valid Vary header, or an array of multiple fields.

This will append the header if not already listed, otherwise leaves it listed in the current location.

```typescript
import { Drash } from "https://deno.land/x/drash@v1.0.5/mod.ts";
import { vary } from "https://raw.githubusercontent.com/dmpjs/vary/master/mod.ts";

let response: Drash.response

// Append "Origin" to the Vary header of the response
vary(
(header: string) => response.headers.get(header) || "",
(header: string, value: string) => { response.headers.set(header, value)},
'Origin'
)
```

## append(header, field)

Adds the given header field to the Vary response header string header. This can be a string of a single field, a string of a valid Vary header, or an array of multiple fields.

This will append the header if not already listed, otherwise leaves it listed in the current location. The new header string is returned.

```typescript
import { append } from "https://raw.githubusercontent.com/dmpjs/vary/master/mod.ts";

// Get header string appending "Origin" to "Accept, User-Agent"
append('Accept, User-Agent', 'Origin')
```

## Test

Expand Down Expand Up @@ -51,3 +92,4 @@ Please have a look at [`CODE_OF_CONDUCT.md`](.github/CODE_OF_CONDUCT.md).
This package is licensed using the MIT License.

Please have a look at [`LICENSE.md`](LICENSE.md).

9 changes: 2 additions & 7 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
export function greeting(str?: string): string {
if (str) {
return `Hello ${str}`;
} else {
throw new Error("Please provide an input");
}
}
export { append } from "./src/append.ts";
export { vary } from "./src/vary.ts";
3 changes: 2 additions & 1 deletion release.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ module.exports = {
"@semantic-release/git",
{
"assets": [
"composer.json",
"version.ts",
"mod.ts",
"src/*",
"UPGRADE.md",
"LICENSE.md",
Expand Down
93 changes: 93 additions & 0 deletions src/append.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* RegExp to match field-name in RFC 7230 sec 3.2
*
* field-name = token
* token = 1*tchar
* tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
* / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
* / DIGIT / ALPHA
* ; any VCHAR, except delimiters
*/
const FIELD_NAME_REGEXP = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;

/**
* Append a field to a vary header.
*
* @param {String} header
* @param {String|Array} field
*
* @return {String}
*/
export const append = (header: string, field: string | string[]): string => {
// get fields array
const fields = !Array.isArray(field) ? parse(String(field)) : field;

// assert on invalid field names
for (let j = 0; j < fields.length; j++) {
if (!FIELD_NAME_REGEXP.test(fields[j])) {
throw new TypeError("field argument contains an invalid header name");
}
}

// existing, unspecified vary
if (header === "*") {
return header;
}

// enumerate current values
let val = header;
const vals = parse(header.toLowerCase());

// unspecified vary
if (fields.indexOf("*") !== -1 || vals.indexOf("*") !== -1) {
return "*";
}

for (let i = 0; i < fields.length; i++) {
const fld = fields[i].toLowerCase();

// append value (case-preserving)
if (vals.indexOf(fld) === -1) {
vals.push(fld);
val = val ? val + ", " + fields[i] : fields[i];
}
}

return val;
};

/**
* Parse a vary header into an array.
*
* @param {String} header
*
* @return {Array}
*/
const parse = (header: string): string[] => {
const list = [];
let end = 0;
let start = 0;

// gather tokens
for (let i = 0, len = header.length; i < len; i++) {
switch (header.charCodeAt(i)) {
case 0x20:/* */
if (start === end) {
start = end = i + 1;
}
break;
case 0x2c:/* , */
list.push(header.substring(start, end));
start = end = i + 1;
break;
default:
end = i + 1;
break;
}
}

// final token
list.push(header.substring(start, end));

return list;
};
25 changes: 25 additions & 0 deletions src/vary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { append } from "./append.ts";

/**
* Mark that a request is varied on a header field.
*
* @param {function} responseHeadersGet
* @param {function} responseHeadersSet
* @param {String|Array} field
* @public
*/
export const vary = (
responseHeadersGet: (header: string) => string,
responseHeadersSet: (header: string, value: string) => void,
field: string | string[],
) => {
// get existing header
let val = responseHeadersGet("Vary");

const header = Array.isArray(val) ? val.join(", ") : String(val);

// set new header
if ((val = append(header, field))) {
responseHeadersSet("Vary", val);
}
};
Loading

0 comments on commit b0977b0

Please sign in to comment.