Skip to main content
Deno 2 is finally here 🎉️
Learn more

range-parser

deno land deno doc GitHub release (latest by date) codecov GitHub

test NPM

HTTP Range header field parser.

Compliant with RFC 9110, 14.2 Range

Parsing

Parses a string as HTTP Range header field and yield JavaScript Object.

The field naming conventions follow RFC 9110, 14.2. Range.

import { parse } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

const actual = parse("bytes=0-100, 200-, -300, test");

assertEquals(actual, {
  rangeUnit: "bytes",
  rangeSet: [
    { firstPos: 0, lastPos: 100 },
    { firstPos: 200, lastPos: undefined },
    { suffixLength: 300 },
    "test",
  ],
});

rangeSet is a list of one or more <int-range>, <suffix-range> and <other-range> according to the definition of <range-spec>.

It has the following data structure:

interface IntRange {
  firstPos: number;
  lastPos: number | undefined;
}
interface SuffixRange {
  suffixLength: number;
}
type OtherRange = string;

Parsing specification

The parser strictly adheres to the ABNF syntax. It also checks semantics.

Specifically, the parser guarantees the following:

  • The <int-range> or <suffix-range> number is a non-negative integer
  • <range-unit> and <other-range> are syntactically valid strings
  • <int-range>, <first-pos> is equal to or greater than <last-pos>.

Syntax error

Throws SyntaxError if it detects invalid syntax.

import { parse } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";

assertThrows(() => parse("<invalid:input>"));

Semantic error

The following cases are semantic error:

  • <int-range>, <last-pos> less than <first-pos>.

see RFC 9110, 14.1.1. Range Specifiers

In this case, it throws a RangeError.

import { parse } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";

assertThrows(() => parse("bytes=1-0"));

Utility

We provide some utilities.

isIntRange

Whether the RangeSpec is IntRange or not.

import {
  type IntRange,
  isIntRange,
  type OtherRange,
  type SuffixRange,
} from "https://deno.land/x/range_parser@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

declare const intRange: IntRange;
declare const suffixRange: SuffixRange;
declare const otherRange: OtherRange;

assert(isIntRange(intRange));
assert(!isIntRange(suffixRange));
assert(!isIntRange(otherRange));

isSuffixRange

Whether the RangeSpec is SuffixRange or not.

import {
  type IntRange,
  isSuffixRange,
  type OtherRange,
  type SuffixRange,
} from "https://deno.land/x/range_parser@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

declare const intRange: IntRange;
declare const suffixRange: SuffixRange;
declare const otherRange: OtherRange;

assert(isSuffixRange(suffixRange));
assert(!isSuffixRange(intRange));
assert(!isSuffixRange(otherRange));

isOtherRange

Whether the RangeSpec is OtherRange or not.

import {
  type IntRange,
  isOtherRange,
  type OtherRange,
  type SuffixRange,
} from "https://deno.land/x/range_parser@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";

declare const intRange: IntRange;
declare const suffixRange: SuffixRange;
declare const otherRange: OtherRange;

assert(isOtherRange(otherRange));
assert(!isOtherRange(intRange));
assert(!isOtherRange(suffixRange));

License

Copyright © 2023-present httpland.

Released under the MIT license