Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@readme/http-headers

Package Overview
Dependencies
Maintainers
10
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@readme/http-headers - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

dist/http-headers.d.ts

48

dist/index.d.ts

@@ -1,36 +0,38 @@

import type { Parent, Node } from 'unist';
export declare const sourceUrl = "https://raw.githubusercontent.com/mdn/content/main/files/en-us/web/http/headers/index.md";
import type { HTTPHeader, HTTPHeaderDescription } from './types';
/**
* Fetch MDN HTTP Header source markdown.
* Converts potentially non-compliant string into HTTP header type
*/
export declare const retrieveMarkdown: () => Promise<string>;
export declare const normalizeHeader: (header: string) => HTTPHeader;
/**
* Normalizes and converts a header into markdown-representative identifier
* @example
* normalizeHeader('content-length') -> '{{HTTPHeader("content-length")}}'
* Is header documented via MDN's https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
*/
export declare const normalizeHeader: (header: string) => string;
export declare const isHeaderValid: (header: string) => boolean;
/**
* Builds complete HTTP header description
* Full description may be multi-line. Ensure we've captured complete text before returning.
* Returns if header is flagged as `experimental`.
*/
export declare const buildDescription: (tree: Parent, headerNode: ChildTextNode) => string;
export declare const isHeaderExperimental: (header: string) => boolean;
/**
* Interpolates description string content
* Returns if header is flagged as `deprecated`.
*/
export declare const isHeaderDeprecated: (header: string) => boolean;
/**
* Returns direct link to header's unique page in MDN.
* @example
* interpolateDescription('{{Glossary("MIME_type", "types")}}') => 'types'
* getHeaderLink('Accept') -> 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept'
*/
export declare const interpolateDescription: (description: string) => string;
interface ChildTextNode extends Node {
value?: string;
}
export declare const getHeaderLink: (header: string) => string;
/**
* Performs lookup in MDN HTTP Header markdown for target header.
* Returns a description, if found.
* Returns header description, as documented in MDN.
* @example
* getHeaderDescription('Authorization') => 'Contains the credentials to authenticate a user-agent with a server.
*/
export declare const searchHeaderDescription: (tree: Parent, header: string) => string;
export declare const getHeaderDescription: (header: string) => string;
/**
* Performs lookup in MDN HTTP Header markdown for target list of HTTP headers.
* Returns header description, formatted in markdown.
*/
export default function getHeaderDescription(header: string | string[]): Promise<Record<string, string>>;
export {};
export declare const getHeaderMarkdown: (header: string) => string;
/**
* Performs lookup of an HTTP Header in MDN's snapshotted documentation.
* Sourced from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers.
*/
export default function getHeader(header: string): HTTPHeaderDescription;

@@ -1,111 +0,83 @@

import { fromMarkdown } from 'mdast-util-from-markdown';
import fetch from 'node-fetch';
import { find } from 'unist-util-find';
import { findAfter } from 'unist-util-find-after';
import flatFilter from 'unist-util-flat-filter';
// Core Resource - Sourcing headers directly from MDN
export const sourceUrl = 'https://raw.githubusercontent.com/mdn/content/main/files/en-us/web/http/headers/index.md';
// Store MDN response in memory for future lookups
let markdown;
// Store previously looked-up header descriptions in memory
const cachedHTTPHeaders = {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHeaderMarkdown = exports.getHeaderDescription = exports.getHeaderLink = exports.isHeaderDeprecated = exports.isHeaderExperimental = exports.isHeaderValid = exports.normalizeHeader = void 0;
var http_headers_1 = require("./http-headers");
/**
* Fetch MDN HTTP Header source markdown.
* Converts potentially non-compliant string into HTTP header type
*/
export const retrieveMarkdown = () => {
return fetch(sourceUrl).then(res => {
if (!res.ok)
throw new Error('Failed to fetch markdown.');
return res.text();
});
var normalizeHeader = function (header) {
return header
.toLowerCase()
.split('-')
.map(function (h) { return h.charAt(0).toUpperCase() + h.slice(1); })
.join('-');
};
exports.normalizeHeader = normalizeHeader;
/**
* Normalizes and converts a header into markdown-representative identifier
* @example
* normalizeHeader('content-length') -> '{{HTTPHeader("content-length")}}'
* Is header documented via MDN's https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
*/
export const normalizeHeader = (header) => `{{HTTPHeader("${header}")}}`.toLowerCase();
var isHeaderValid = function (header) {
var normalizedHeader = (0, exports.normalizeHeader)(header);
return !!http_headers_1.default[normalizedHeader];
};
exports.isHeaderValid = isHeaderValid;
/**
* Builds complete HTTP header description
* Full description may be multi-line. Ensure we've captured complete text before returning.
* Returns if header is flagged as `experimental`.
*/
export const buildDescription = (tree, headerNode) => {
let description = '';
let currentNode = headerNode;
while (!description.endsWith('.')) {
currentNode = findAfter(tree, currentNode, { type: 'text' });
if (currentNode?.value) {
const [fallback, text] = currentNode.value.split(': ') ?? [];
description = description.concat(text || fallback || '');
}
}
return description;
var isHeaderExperimental = function (header) {
var _a;
var normalizedHeader = (0, exports.normalizeHeader)(header);
return !!((_a = http_headers_1.default[normalizedHeader]) === null || _a === void 0 ? void 0 : _a.experimental);
};
exports.isHeaderExperimental = isHeaderExperimental;
/**
* Interpolates description string content
* Returns if header is flagged as `deprecated`.
*/
var isHeaderDeprecated = function (header) {
var _a;
var normalizedHeader = (0, exports.normalizeHeader)(header);
return !!((_a = http_headers_1.default[normalizedHeader]) === null || _a === void 0 ? void 0 : _a.deprecated);
};
exports.isHeaderDeprecated = isHeaderDeprecated;
/**
* Returns direct link to header's unique page in MDN.
* @example
* interpolateDescription('{{Glossary("MIME_type", "types")}}') => 'types'
* getHeaderLink('Accept') -> 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept'
*/
export const interpolateDescription = (description) => {
// i.e. '{{Glossary("effective connection type")}}'
const simpleGlossaryRegexp = /\{\{Glossary\("([^"]+)"?\)\}\}/g;
// i.e. '{{Glossary("MIME_type", "types")}}'
const compoundGlossaryRegexp = /\{\{Glossary\("([^"]+)", "([^"]+)"\)\}\}/g;
// Prematurely return if nothing to process
if (!description)
return description;
if (description.match(simpleGlossaryRegexp))
return description.split(simpleGlossaryRegexp).join('');
if (description.match(compoundGlossaryRegexp)) {
const [start, , interpolation, end] = description.split(compoundGlossaryRegexp);
return `${start}${interpolation}${end}`;
}
return description;
var getHeaderLink = function (header) {
var _a;
var normalizedHeader = (0, exports.normalizeHeader)(header);
return ((_a = http_headers_1.default[normalizedHeader]) === null || _a === void 0 ? void 0 : _a.link) || '';
};
exports.getHeaderLink = getHeaderLink;
/**
* Performs lookup in MDN HTTP Header markdown for target header.
* Returns a description, if found.
* Returns header description, as documented in MDN.
* @example
* getHeaderDescription('Authorization') => 'Contains the credentials to authenticate a user-agent with a server.
*/
export const searchHeaderDescription = (tree, header) => {
if (tree && header) {
const headerNode = find(tree, (node) => {
return ((node.value?.toLowerCase().includes(normalizeHeader(header)) && node.position?.start.column === 3) || false);
});
if (headerNode) {
const description = buildDescription(tree, headerNode);
return interpolateDescription(description);
}
}
return '';
var getHeaderDescription = function (header) {
var _a;
var normalizedHeader = (0, exports.normalizeHeader)(header);
return ((_a = http_headers_1.default[normalizedHeader]) === null || _a === void 0 ? void 0 : _a.description) || '';
};
exports.getHeaderDescription = getHeaderDescription;
/**
* Performs lookup in MDN HTTP Header markdown for target list of HTTP headers.
* Returns header description, formatted in markdown.
*/
export default async function getHeaderDescription(header) {
try {
// If markdown has not been requested and cached, do so now
if (!markdown)
markdown = await retrieveMarkdown();
// Convert text -> markdown syntax tree
const mdast = fromMarkdown(markdown, 'utf-8');
// Flatten tree for easy value enumeration
const tree = flatFilter(mdast, node => node?.type === 'text');
// Convert args into a unified format
const headers = Array.isArray(header) ? header : [header];
// Process headers and apply found descriptions
return headers.reduce((acc, h) => {
if (cachedHTTPHeaders[h]) {
acc[h] = cachedHTTPHeaders[h];
}
else {
const description = searchHeaderDescription(tree, h);
cachedHTTPHeaders[h] = description;
acc[h] = description;
}
return acc;
}, {});
}
catch (e) {
return {};
}
var getHeaderMarkdown = function (header) {
var _a, _b;
var normalizedHeader = (0, exports.normalizeHeader)(header);
return ((_a = http_headers_1.default[normalizedHeader]) === null || _a === void 0 ? void 0 : _a.markdown) || ((_b = http_headers_1.default[normalizedHeader]) === null || _b === void 0 ? void 0 : _b.description) || '';
};
exports.getHeaderMarkdown = getHeaderMarkdown;
/**
* Performs lookup of an HTTP Header in MDN's snapshotted documentation.
* Sourced from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers.
*/
function getHeader(header) {
var normalizedHeader = (0, exports.normalizeHeader)(header);
if (!(0, exports.isHeaderValid)(normalizedHeader))
throw new Error("'".concat(header, "' is not a documented HTTP header."));
return http_headers_1.default[normalizedHeader];
}
exports.default = getHeader;
{
"name": "@readme/http-headers",
"version": "0.0.1",
"version": "0.0.2",
"description": "Retrieve HTTP Header Descriptions from MDN",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",

@@ -32,9 +31,2 @@ "engines": {

"license": "MIT",
"dependencies": {
"mdast-util-from-markdown": "^2.0.0",
"node-fetch": "^3.3.2",
"unist-util-find": "^2.0.0",
"unist-util-find-after": "^5.0.0",
"unist-util-flat-filter": "^2.0.0"
},
"devDependencies": {

@@ -44,6 +36,4 @@ "@commitlint/cli": "^17.6.3",

"@readme/eslint-config": "^12.0.3",
"@types/unist": "^3.0.0",
"@vitest/coverage-v8": "^0.34.1",
"eslint": "^8.40.0",
"nock": "^13.3.2",
"prettier": "^3.0.1",

@@ -50,0 +40,0 @@ "typescript": "^5.0.4",

@@ -17,21 +17,38 @@ # @readme/http-headers

`HTTP-Headers` pulls header descriptions directly from MDN, via a `fetch` request. It then stores response markdown in memory for future usage. That means that the library is inherently asynchronous, and will need to be used with a promise handler.
`HTTP-Headers` pulls header descriptions directly from [MDN's header documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
```js
import getHeaderDescription from '@readme/http-headers';
import getHeader from '@readme/http-headers';
console.log(await getHeaderDescription('Connection'));
// A typical header
console.log(getHeader('Connection'));
/**
{
Connection: 'Controls whether the network connection stays open after the current transaction finishes.',
description: 'Controls whether the network connection stays open after the current transaction finishes.',
link: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection',
}
**/
console.log(await getHeaderDescription(['Authorization', 'Content-Length']));
// A header with a markdown-flavored description
console.log(getHeader('Cookie'));
/**
{
Authorization: 'Contains the credentials to authenticate a user-agent with a server.',
'Content-Length': 'The size of the resource, in decimal number of bytes.',
description: 'Contains stored HTTP cookies previously sent by the server with the Set-Cookie header.',
link: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie',
markdown:
'Contains stored [HTTP cookies](/en-US/docs/Web/HTTP/Cookies) previously sent by the server with the "Set-Cookie" header',
}
**/
// A header with additional decorations
console.log(getHeader('DPR'));
/**
{
deprecated: true,
experimental: true,
description:
'Client device pixel ratio (DPR), which is the number of physical device pixels corresponding to every CSS pixel.',
link: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/DPR',
}
**/
```

@@ -1,132 +0,78 @@

import type { Parent, Node } from 'unist';
import type { HTTPHeader, HTTPHeaderDescription } from './types';
import { fromMarkdown } from 'mdast-util-from-markdown';
import fetch from 'node-fetch';
import { find } from 'unist-util-find';
import { findAfter } from 'unist-util-find-after';
import flatFilter from 'unist-util-flat-filter';
import HTTPHeaders from './http-headers';
// Core Resource - Sourcing headers directly from MDN
export const sourceUrl = 'https://raw.githubusercontent.com/mdn/content/main/files/en-us/web/http/headers/index.md';
// Store MDN response in memory for future lookups
let markdown: string;
// Store previously looked-up header descriptions in memory
const cachedHTTPHeaders: Record<string, string> = {};
/**
* Converts potentially non-compliant string into HTTP header type
*/
export const normalizeHeader = (header: string): HTTPHeader => {
return header
.toLowerCase()
.split('-')
.map(h => h.charAt(0).toUpperCase() + h.slice(1))
.join('-') as HTTPHeader;
};
/**
* Fetch MDN HTTP Header source markdown.
* Is header documented via MDN's https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
*/
export const retrieveMarkdown = (): Promise<string> => {
return fetch(sourceUrl).then(res => {
if (!res.ok) throw new Error('Failed to fetch markdown.');
return res.text();
});
export const isHeaderValid = (header: string): boolean => {
const normalizedHeader = normalizeHeader(header);
return !!HTTPHeaders[normalizedHeader];
};
/**
* Normalizes and converts a header into markdown-representative identifier
* @example
* normalizeHeader('content-length') -> '{{HTTPHeader("content-length")}}'
* Returns if header is flagged as `experimental`.
*/
export const normalizeHeader = (header: string): string => `{{HTTPHeader("${header}")}}`.toLowerCase();
export const isHeaderExperimental = (header: string): boolean => {
const normalizedHeader = normalizeHeader(header);
return !!HTTPHeaders[normalizedHeader]?.experimental;
};
/**
* Builds complete HTTP header description
* Full description may be multi-line. Ensure we've captured complete text before returning.
* Returns if header is flagged as `deprecated`.
*/
export const buildDescription = (tree: Parent, headerNode: ChildTextNode): string => {
let description = '';
let currentNode = headerNode;
export const isHeaderDeprecated = (header: string): boolean => {
const normalizedHeader = normalizeHeader(header);
return !!HTTPHeaders[normalizedHeader]?.deprecated;
};
while (!description.endsWith('.')) {
currentNode = findAfter(tree, currentNode, { type: 'text' }) as ChildTextNode;
if (currentNode?.value) {
const [fallback, text] = currentNode.value.split(': ') ?? [];
description = description.concat(text || fallback || '');
}
}
return description;
/**
* Returns direct link to header's unique page in MDN.
* @example
* getHeaderLink('Accept') -> 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept'
*/
export const getHeaderLink = (header: string): string => {
const normalizedHeader = normalizeHeader(header);
return HTTPHeaders[normalizedHeader]?.link || '';
};
/**
* Interpolates description string content
* Returns header description, as documented in MDN.
* @example
* interpolateDescription('{{Glossary("MIME_type", "types")}}') => 'types'
* getHeaderDescription('Authorization') => 'Contains the credentials to authenticate a user-agent with a server.
*/
export const interpolateDescription = (description: string): string => {
// i.e. '{{Glossary("effective connection type")}}'
const simpleGlossaryRegexp = /\{\{Glossary\("([^"]+)"?\)\}\}/g;
// i.e. '{{Glossary("MIME_type", "types")}}'
const compoundGlossaryRegexp = /\{\{Glossary\("([^"]+)", "([^"]+)"\)\}\}/g;
// Prematurely return if nothing to process
if (!description) return description;
if (description.match(simpleGlossaryRegexp)) return description.split(simpleGlossaryRegexp).join('');
if (description.match(compoundGlossaryRegexp)) {
const [start, , interpolation, end] = description.split(compoundGlossaryRegexp);
return `${start}${interpolation}${end}`;
}
return description;
export const getHeaderDescription = (header: string): string => {
const normalizedHeader = normalizeHeader(header);
return HTTPHeaders[normalizedHeader]?.description || '';
};
interface ChildTextNode extends Node {
value?: string;
}
/**
* Performs lookup in MDN HTTP Header markdown for target header.
* Returns a description, if found.
* Returns header description, formatted in markdown.
*/
export const searchHeaderDescription = (tree: Parent, header: string): string => {
if (tree && header) {
const headerNode = find(tree as any, (node: ChildTextNode) => {
return (
(node.value?.toLowerCase().includes(normalizeHeader(header)) && node.position?.start.column === 3) || false
);
});
if (headerNode) {
const description = buildDescription(tree, headerNode);
return interpolateDescription(description);
}
}
return '';
export const getHeaderMarkdown = (header: string): string => {
const normalizedHeader = normalizeHeader(header);
return HTTPHeaders[normalizedHeader]?.markdown || HTTPHeaders[normalizedHeader]?.description || '';
};
/**
* Performs lookup in MDN HTTP Header markdown for target list of HTTP headers.
* Performs lookup of an HTTP Header in MDN's snapshotted documentation.
* Sourced from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers.
*/
export default async function getHeaderDescription(header: string | string[]): Promise<Record<string, string>> {
try {
// If markdown has not been requested and cached, do so now
if (!markdown) markdown = await retrieveMarkdown();
export default function getHeader(header: string): HTTPHeaderDescription {
const normalizedHeader = normalizeHeader(header);
// Convert text -> markdown syntax tree
const mdast = fromMarkdown(markdown, 'utf-8') as any;
// Flatten tree for easy value enumeration
const tree = flatFilter(mdast, node => node?.type === 'text') as Parent;
// Convert args into a unified format
const headers = Array.isArray(header) ? header : [header];
if (!isHeaderValid(normalizedHeader)) throw new Error(`'${header}' is not a documented HTTP header.`);
// Process headers and apply found descriptions
return headers.reduce(
(acc, h) => {
if (cachedHTTPHeaders[h]) {
acc[h] = cachedHTTPHeaders[h];
} else {
const description = searchHeaderDescription(tree, h);
cachedHTTPHeaders[h] = description;
acc[h] = description;
}
return acc;
},
{} as Record<string, string>,
);
} catch (e) {
return {};
}
return HTTPHeaders[normalizedHeader];
}

@@ -5,12 +5,8 @@ {

"declaration": true,
"esModuleInterop": true,
"module": "NodeNext",
"noImplicitAny": true,
"outDir": "./dist",
"skipLibCheck": true,
"strict": true,
"target": "ESNext",
"moduleResolution": "NodeNext"
"strict": true
},
"include": ["./src/**/*"]
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc