@readme/http-headers
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -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', | ||
} | ||
**/ | ||
``` |
152
src/index.ts
@@ -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/**/*"] | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
102952
0
8
13
1739
54
No
- Removedmdast-util-from-markdown@^2.0.0
- Removednode-fetch@^3.3.2
- Removedunist-util-find@^2.0.0
- Removedunist-util-find-after@^5.0.0
- Removedunist-util-flat-filter@^2.0.0
- Removed@types/debug@4.1.12(transitive)
- Removed@types/mdast@4.0.4(transitive)
- Removed@types/ms@0.7.34(transitive)
- Removed@types/unist@2.0.113.0.3(transitive)
- Removedcharacter-entities@2.0.2(transitive)
- Removeddata-uri-to-buffer@4.0.1(transitive)
- Removeddebug@4.4.0(transitive)
- Removeddecode-named-character-reference@1.0.2(transitive)
- Removeddequal@2.0.3(transitive)
- Removeddevlop@1.1.0(transitive)
- Removedfetch-blob@3.2.0(transitive)
- Removedformdata-polyfill@4.0.10(transitive)
- Removedlodash.iteratee@4.7.0(transitive)
- Removedmdast-util-from-markdown@2.0.2(transitive)
- Removedmdast-util-to-string@4.0.0(transitive)
- Removedmicromark@4.0.1(transitive)
- Removedmicromark-core-commonmark@2.0.2(transitive)
- Removedmicromark-factory-destination@2.0.1(transitive)
- Removedmicromark-factory-label@2.0.1(transitive)
- Removedmicromark-factory-space@2.0.1(transitive)
- Removedmicromark-factory-title@2.0.1(transitive)
- Removedmicromark-factory-whitespace@2.0.1(transitive)
- Removedmicromark-util-character@2.1.1(transitive)
- Removedmicromark-util-chunked@2.0.1(transitive)
- Removedmicromark-util-classify-character@2.0.1(transitive)
- Removedmicromark-util-combine-extensions@2.0.1(transitive)
- Removedmicromark-util-decode-numeric-character-reference@2.0.2(transitive)
- Removedmicromark-util-decode-string@2.0.1(transitive)
- Removedmicromark-util-encode@2.0.1(transitive)
- Removedmicromark-util-html-tag-name@2.0.1(transitive)
- Removedmicromark-util-normalize-identifier@2.0.1(transitive)
- Removedmicromark-util-resolve-all@2.0.1(transitive)
- Removedmicromark-util-sanitize-uri@2.0.1(transitive)
- Removedmicromark-util-subtokenize@2.0.3(transitive)
- Removedmicromark-util-symbol@2.0.1(transitive)
- Removedmicromark-util-types@2.0.1(transitive)
- Removedms@2.1.3(transitive)
- Removednode-domexception@1.0.0(transitive)
- Removednode-fetch@3.3.2(transitive)
- Removedunist-util-find@2.0.0(transitive)
- Removedunist-util-find-after@5.0.0(transitive)
- Removedunist-util-flat-filter@2.0.0(transitive)
- Removedunist-util-is@5.2.16.0.0(transitive)
- Removedunist-util-stringify-position@4.0.0(transitive)
- Removedunist-util-visit@4.1.2(transitive)
- Removedunist-util-visit-parents@5.1.3(transitive)
- Removedweb-streams-polyfill@3.3.3(transitive)