diff --git a/package-lock.json b/package-lock.json index 269eee46..eae3fc21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,7 +4,10 @@ "requires": true, "packages": { "": { + "name": "sass", "dependencies": { + "@types/diff": "^5.0.1", + "@types/glob": "^7.1.4", "colors": "^1.3.3", "diff": "^4.0.1", "glob": "^7.1.3", @@ -221,12 +224,31 @@ "node": ">=6" } }, + "node_modules/@types/diff": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.1.tgz", + "integrity": "sha512-XIpxU6Qdvp1ZE6Kr3yrkv1qgUab0fyf4mHYvW8N3Bx3PCsbN6or1q9/q72cv5jIFWolaGH08U9XyYoLLIykyKQ==" + }, + "node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -236,8 +258,7 @@ "node_modules/@types/node": { "version": "14.17.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.10.tgz", - "integrity": "sha512-09x2d6kNBwjHgyh3jOUE2GE4DFoxDriDvWdu6mFhMP1ysynGYazt4ecZmJlL6/fe4Zi2vtYvTvtL7epjQQrBhA==", - "dev": true + "integrity": "sha512-09x2d6kNBwjHgyh3jOUE2GE4DFoxDriDvWdu6mFhMP1ysynGYazt4ecZmJlL6/fe4Zi2vtYvTvtL7epjQQrBhA==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -4727,12 +4748,31 @@ "defer-to-connect": "^1.0.1" } }, + "@types/diff": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.1.tgz", + "integrity": "sha512-XIpxU6Qdvp1ZE6Kr3yrkv1qgUab0fyf4mHYvW8N3Bx3PCsbN6or1q9/q72cv5jIFWolaGH08U9XyYoLLIykyKQ==" + }, + "@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -4742,8 +4782,7 @@ "@types/node": { "version": "14.17.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.10.tgz", - "integrity": "sha512-09x2d6kNBwjHgyh3jOUE2GE4DFoxDriDvWdu6mFhMP1ysynGYazt4ecZmJlL6/fe4Zi2vtYvTvtL7epjQQrBhA==", - "dev": true + "integrity": "sha512-09x2d6kNBwjHgyh3jOUE2GE4DFoxDriDvWdu6mFhMP1ysynGYazt4ecZmJlL6/fe4Zi2vtYvTvtL7epjQQrBhA==" }, "@types/normalize-package-data": { "version": "2.4.1", diff --git a/package.json b/package.json index cd58da2b..cbb287cd 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,16 @@ "engines": { "node": ">=14.0.0 <17.0.0" }, - "type": "module", "scripts": { - "link-check": "node test/link-check.js", - "toc-check": "node test/toc-check.js", + "link-check": "npx ts-node test/link-check.ts", + "toc-check": "npx ts-node test/toc-check.ts", + "update-toc": "npx ts-node tool/update-toc.ts", "fix": "gts fix", "test": "gts lint && tsc --noEmit && npm run toc-check && npm run link-check" }, "dependencies": { + "@types/diff": "^5.0.1", + "@types/glob": "^7.1.4", "colors": "^1.3.3", "diff": "^4.0.1", "glob": "^7.1.3", diff --git a/test/link-check.js b/test/link-check.ts similarity index 80% rename from test/link-check.js rename to test/link-check.ts index ecc9e074..0bf71583 100644 --- a/test/link-check.js +++ b/test/link-check.ts @@ -1,8 +1,9 @@ -import colors from 'colors/safe.js'; +import * as colors from 'colors/safe'; import * as fs from 'fs'; -import glob from 'glob'; -import markdownLinkCheck from 'markdown-link-check'; -import markdownToc from 'markdown-toc'; +import * as glob from 'glob'; +import markdownLinkCheck = require('markdown-link-check'); +import * as linkCheck from 'markdown-link-check'; +import markdownToc = require('markdown-toc'); import * as path from 'path'; import {fileURLToPath, pathToFileURL, URL} from 'url'; @@ -10,9 +11,9 @@ const files = glob.sync('**/*.md', { ignore: ['node_modules/**/*.md'], }); -const tocCache = new Map(); +const tocCache = new Map(); -function getToc(file) { +function getToc(file: string): string { file = path.normalize(file); let toc = tocCache.get(file); if (toc === undefined) { @@ -22,7 +23,10 @@ function getToc(file) { return toc; } -function verifyLinkCheckResults(file, results) { +function verifyLinkCheckResults( + file: string, + results: linkCheck.Result[] +): void { const toc = getToc(file); for (const result of results) { @@ -57,11 +61,12 @@ function verifyLinkCheckResults(file, results) { } } -function runLinkCheck(file, {rateLimit}) { +function runLinkCheck( + file: string, + {rateLimit}: {rateLimit?: number} +): Promise { return new Promise((resolve, reject) => { - setTimeout(check, rateLimit); - - function check() { + setTimeout(() => { markdownLinkCheck( fs.readFileSync(file).toString(), { @@ -82,7 +87,7 @@ function runLinkCheck(file, {rateLimit}) { } } ); - } + }, rateLimit); }); } diff --git a/test/toc-check.js b/test/toc-check.ts similarity index 90% rename from test/toc-check.js rename to test/toc-check.ts index 4116af5e..b5fef104 100644 --- a/test/toc-check.js +++ b/test/toc-check.ts @@ -1,8 +1,8 @@ -import colors from 'colors/safe.js'; +import * as colors from 'colors/safe'; import * as diff from 'diff'; import * as fs from 'fs'; -import * as toc from '../tool/toc.js'; +import * as toc from '../tool/toc'; toc.files.forEach(file => { const markdown = fs.readFileSync(file).toString(); diff --git a/tool/toc.js b/tool/toc.ts similarity index 80% rename from tool/toc.js rename to tool/toc.ts index ec6e83a5..f341879d 100644 --- a/tool/toc.js +++ b/tool/toc.ts @@ -1,5 +1,5 @@ -import glob from 'glob'; -import markdownToc from 'markdown-toc'; +import * as glob from 'glob'; +import markdownToc = require('markdown-toc'); /** Files that may contain tables of contents. */ export const files = glob.sync('**/*.md', { @@ -8,7 +8,7 @@ export const files = glob.sync('**/*.md', { // Returns the index of the first `*` in `markdown`'s table of contents, or // `null` if `markdown` doesn't include a table of contents. -function findStartIndex(markdown) { +function findStartIndex(markdown: string): number | null { const match = markdown.match(/\n## Table of Contents\n/); if (match === null || match.index === undefined) return null; return match.index + match[0].length - 1; @@ -18,7 +18,7 @@ function findStartIndex(markdown) { * Returns the table of contents in `markdown` if it contains one, or `null` * otherwise. */ -export function getCurrent(markdown) { +export function getCurrent(markdown: string): string | null { const startIndex = findStartIndex(markdown); if (startIndex === null) return null; @@ -29,7 +29,7 @@ export function getCurrent(markdown) { } /** Returns the expected table of contents for `markdown`. */ -export function generate(markdown) { +export function generate(markdown: string): string { return markdownToc(markdown, { filter: contents => contents.indexOf('Table of Contents') === -1, firsth1: false, diff --git a/tool/types/markdown-link-check.d.ts b/tool/types/markdown-link-check.d.ts new file mode 100644 index 00000000..5dca8735 --- /dev/null +++ b/tool/types/markdown-link-check.d.ts @@ -0,0 +1,22 @@ +declare module 'markdown-link-check' { + namespace linkCheck { + export interface Options { + baseUrl?: string; + retryOn429?: boolean; + } + + export interface Result { + link: string; + status: string; + statusCode: number; + } + } + + function linkCheck( + markdown: string, + options: linkCheck.Options, + callback: (error: unknown, results: linkCheck.Result[]) => void + ): void; + + export = linkCheck; +} diff --git a/tool/types/markdown-toc.d.ts b/tool/types/markdown-toc.d.ts new file mode 100644 index 00000000..a4c876db --- /dev/null +++ b/tool/types/markdown-toc.d.ts @@ -0,0 +1,13 @@ +declare module 'markdown-toc' { + namespace toc { + export interface Options { + filter?: (header: string) => boolean; + firsth1?: boolean; + bullets?: string; + } + } + + function toc(markdown: string, options?: toc.Options): {content: string}; + + export = toc; +} diff --git a/tool/update-toc.js b/tool/update-toc.ts similarity index 96% rename from tool/update-toc.js rename to tool/update-toc.ts index 5dde9ed7..14725e9d 100644 --- a/tool/update-toc.js +++ b/tool/update-toc.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; -import * as toc from './toc.js'; +import * as toc from './toc'; toc.files.forEach(file => { const markdown = fs.readFileSync(file).toString(); diff --git a/tsconfig.json b/tsconfig.json index 73d956b2..18015db1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,10 @@ "extends": "./node_modules/gts/tsconfig-google.json", "compilerOptions": { "allowJs": true, - "rootDir": "." + "rootDir": ".", + "paths": { + "*": ["./tool/types/*"] + } }, - "include": ["accepted/**/*.ts", "proposal/**/*.ts", "spec/**/*.ts"] + "include": ["accepted/**/*.ts", "proposal/**/*.ts", "spec/**/*.ts", "tool/**/*.ts", "test/**/*.ts"] }