Skip to content

Commit

Permalink
feat(stringify): add serialization function for accept-ranges header …
Browse files Browse the repository at this point in the history
…field
  • Loading branch information
TomokiMiyauci committed Mar 27, 2023
1 parent 0c8b01c commit 6f22c49
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 2 deletions.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ assertEquals(parseAcceptRanges(`bytes, unknown`), ["bytes", "unknown"]);
### Throwing error

Throws `SyntaxError` if the input is invalid
[`<Accept-Ranges>`](https://www.rfc-editor.org/rfc/rfc9110#section-14.3-2).
[`<Accept-Ranges>`](https://www.rfc-editor.org/rfc/rfc9110#section-14.3-2)
syntax.

```ts
import { parseAcceptRanges } from "https://deno.land/x/accept_ranges_parser@$VERSION/parse.ts";
Expand All @@ -38,6 +39,29 @@ import { assertThrows } from "https://deno.land/std/testing/asserts.ts";
assertThrows(() => parseAcceptRanges("<invalid>"));
```

## Serialization

Serialize string of array into string.

```ts
import { stringifyAcceptRanges } from "https://deno.land/x/accept_ranges_parser@$VERSION/stringify.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

assertEquals(stringifyAcceptRanges(["bytes"]), "bytes");
```

### Throwing error

Throws `TypeError` if the element contains invalid
[`<range-unit>`](https://www.rfc-editor.org/rfc/rfc9110#section-14.1-3) syntax.

```ts
import { stringifyAcceptRanges } from "https://deno.land/x/accept_ranges_parser@$VERSION/stringify.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";

assertThrows(() => stringifyAcceptRanges(["<invalid>", "none"]));
```

## AcceptRanges

`AcceptRanges` is a subtype of array with the following characteristics.
Expand Down
7 changes: 7 additions & 0 deletions _tools/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,11 @@ export const makeOptions = (version: string): BuildOptions => ({
publishConfig: { access: "public" },
},
packageManager: "pnpm",
mappings: {
"https://deno.land/x/isx@1.1.0/is_string.ts": {
name: "@miyauci/isx",
version: "1.1.0",
subPath: "is_string",
},
},
});
1 change: 1 addition & 0 deletions constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@

export const enum Msg {
InvalidSyntax = "invalid <Accept-Ranges> syntax.",
InvalidRangeUnit = "invalid <range-unit> syntax.",
}
3 changes: 2 additions & 1 deletion deno.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"https://deno.land/std@0.181.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7",
"https://deno.land/std@0.181.0/testing/_test_suite.ts": "30f018feeb3835f12ab198d8a518f9089b1bcb2e8c838a8b615ab10d5005465c",
"https://deno.land/std@0.181.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f",
"https://deno.land/std@0.181.0/testing/bdd.ts": "c5ca6d85940dbcc19b4d2bc3608d49ab65d81470aa91306d5efa4b0d5c945731"
"https://deno.land/std@0.181.0/testing/bdd.ts": "c5ca6d85940dbcc19b4d2bc3608d49ab65d81470aa91306d5efa4b0d5c945731",
"https://deno.land/x/isx@1.1.0/is_string.ts": "268254eab5f8dbc09ee879eb53675813cdc5350207dde436d457cb34462cc857"
}
}
2 changes: 2 additions & 0 deletions deps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license.
// This module is browser compatible.

export { isString } from "https://deno.land/x/isx@1.1.0/is_string.ts";

// TODO:(miyauci) Packaging and externalization this module.

export type UppercaseLetter =
Expand Down
1 change: 1 addition & 0 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
// This module is browser compatible.

export { parseAcceptRanges } from "./parse.ts";
export { stringifyAcceptRanges } from "./stringify.ts";
export type { AcceptRanges } from "./types.ts";
export { type Token } from "./deps.ts";
29 changes: 29 additions & 0 deletions stringify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { isString } from "./deps.ts";
import { isTokenFormat } from "./utils.ts";
import { Msg } from "./constants.ts";

/** Serialize string of array into string.
*
* @example
* ```ts
* import { stringifyAcceptRanges } from "https://deno.land/x/accept_ranges_parser@$VERSION/stringify.ts";
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
*
* assertEquals(stringifyAcceptRanges(["bytes"]), "bytes");
* ```
*
* @throws {TypeError} If the input is invalid [`<range-unit>`](https://www.rfc-editor.org/rfc/rfc9110#section-14.1-3) format.
*/
export function stringifyAcceptRanges(
acceptRanges: string | readonly [string, ...string[]],
): string {
const targets = isString(acceptRanges) ? [acceptRanges] : acceptRanges;

targets.forEach((rangeUnit) => {
if (!isTokenFormat(rangeUnit)) {
throw TypeError(`${Msg.InvalidRangeUnit} "${rangeUnit}"`);
}
});

return targets.join(", ");
}
72 changes: 72 additions & 0 deletions stringify_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { stringifyAcceptRanges } from "./stringify.ts";
import {
assertEquals,
assertIsError,
assertThrows,
describe,
it,
} from "./_dev_deps.ts";

describe("stringifyAcceptRanges", () => {
it("should return string if the input is valid string", () => {
const table: string[] = ["bytes", "none"];

table.forEach((input) => {
assertEquals(stringifyAcceptRanges(input), input);
});
});

it("should return string if the input is valid string of array", () => {
const table: [[string, ...string[]], string][] = [
[["bytes"], "bytes"],
[["bytes", "unknown"], "bytes, unknown"],
];

table.forEach(([input, expected]) => {
assertEquals(stringifyAcceptRanges(input), expected);
});
});

it("should throw error if the input is invalid string", () => {
const table: string[] = [
"",
" ",
"bytes, none",
"a ",
" a",
",",
" ,",
`"a"`,
`"a, b"`,
];

table.forEach((input) => {
assertThrows(() => stringifyAcceptRanges(input));
});
});

it("should throw error if the array input has is invalid string", () => {
const table: [string, ...string[]][] = [
[""],
["", ""],
["", "", "", ""],
["", "ok"],
["ng", ","],
];

table.forEach((input) => {
assertThrows(() => stringifyAcceptRanges(input));
});
});

it("should be error message", () => {
let err;
try {
stringifyAcceptRanges("");
} catch (e) {
err = e;
} finally {
assertIsError(err, TypeError, `invalid <range-unit> syntax. ""`);
}
});
});

0 comments on commit 6f22c49

Please sign in to comment.