HTTP Range header field parser.
Compliant with RFC 9110, 14.2 Range
Parses a string as HTTP Range header field and yield JavaScript Object.
The field naming conventions follow RFC 9110, 14.2. Range.
import { parseRange } from "https://deno.land/x/range_parser@$VERSION/parse.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const actual = parseRange("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;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>.
Throws SyntaxError if it detects invalid syntax.
import { parseRange } from "https://deno.land/x/range_parser@$VERSION/parse.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";
assertThrows(() => parseRange("<invalid:input>"));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 { parseRange } from "https://deno.land/x/range_parser@$VERSION/parse.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";
assertThrows(() => parseRange("bytes=1-0"));Serializes Range into string.
import { stringifyRange } from "https://deno.land/x/range_parser@$VERSION/stringify.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
assertEquals(
  stringifyRange({
    rangeUnit: "bytes",
    rangeSet: [{ firstPos: 0, lastPos: 100 }, { suffixLength: 200 }],
  }),
  "bytes=0-100, -200",
);Throws TypeError if Range contains errors.
For error definitions, see the Parsing specification.
import { stringifyRange } from "https://deno.land/x/range_parser@$VERSION/stringify.ts";
import { assertThrows } from "https://deno.land/std/testing/asserts.ts";
assertThrows(() =>
  stringifyRange({
    rangeUnit: "bytes",
    rangeSet: [{ firstPos: NaN, lastPos: undefined }],
  })
);We provide some utilities.
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));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));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));Whether the input is HTTP Range header field format or not.
import { isRangeFormat } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";
assert(isRangeFormat("bytes=0-100, 200-, -500"));
assert(!isRangeFormat("<invalid>"));Copyright © 2023-present httpland.
Released under the MIT license
