deno.land / std@0.224.0 / _tools / check_doc_imports.ts

check_doc_imports.ts
View Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { blue, red, yellow } from "../fmt/colors.ts";import { walk } from "../fs/walk.ts";import ts from "npm:typescript";const { createSourceFile, ScriptTarget, SyntaxKind,} = ts;
const EXTENSIONS = [".mjs", ".js", ".ts", ".md"];const EXCLUDED_PATHS = [ ".git", ".github", "_tools",];
const ROOT = new URL("../", import.meta.url);const ROOT_LENGTH = ROOT.pathname.slice(0, -1).length;
const RX_JSDOC_COMMENT = /\*\*[^*]*\*+(?:[^/*][^*]*\*+)*/gm;const RX_JSDOC_REMOVE_LEADING_ASTERISK = /^\s*\* ?/gm;const RX_CODE_BLOCK = /`{3}([\w]*)\n([\S\s]+?)\n`{3}/gm;
let shouldFail = false;let countChecked = 0;
function checkImportStatements( codeBlock: string, filePath: string, lineNumber: number,): void { const sourceFile = createSourceFile( "doc-imports-checker$", codeBlock, ScriptTarget.Latest, ); const importDeclarations = sourceFile.statements.filter((s) => s.kind === SyntaxKind.ImportDeclaration ) as ts.ImportDeclaration[];
for (const importDeclaration of importDeclarations) { const { moduleSpecifier } = importDeclaration; const importPath = (moduleSpecifier as ts.StringLiteral).text; const isRelative = importPath.startsWith("."); const isInternal = importPath.startsWith( "https://deno.land/std@$STD_VERSION/", ); const { line } = sourceFile.getLineAndCharacterOfPosition( moduleSpecifier.pos, );
if (isRelative || !isInternal) { console.log( yellow("Warn ") + (isRelative ? "relative import path" : "external or incorrectly versioned dependency") + ": " + red(`"${importPath}"`) + " at " + blue( filePath.substring(ROOT_LENGTH + 1), ) + yellow(":" + (lineNumber + line)), );
shouldFail = true; } }}
function checkCodeBlocks( content: string, filePath: string, lineNumber = 1,): void { for (const codeBlockMatch of content.matchAll(RX_CODE_BLOCK)) { const [, language, codeBlock] = codeBlockMatch; const codeBlockLineNumber = content.slice(0, codeBlockMatch.index).split("\n").length;
if ( ["ts", "js", "typescript", "javascript", ""].includes( language!.toLocaleLowerCase(), ) ) { checkImportStatements( codeBlock!, filePath, lineNumber + codeBlockLineNumber, ); } }}
for await ( const { path } of walk(ROOT, { exts: EXTENSIONS, includeDirs: false, skip: EXCLUDED_PATHS.map((p) => new RegExp(p + "$")), })) { const content = await Deno.readTextFile(path); countChecked++;
if (path.endsWith(".md")) { checkCodeBlocks(content, path); } else { for (const jsdocMatch of content.matchAll(RX_JSDOC_COMMENT)) { const comment = jsdocMatch[0].replaceAll( RX_JSDOC_REMOVE_LEADING_ASTERISK, "", ); const commentLineNumber = content.slice(0, jsdocMatch.index).split("\n").length;
checkCodeBlocks(comment, path, commentLineNumber); } }}
console.log(`Checked ${countChecked} files`);if (shouldFail) Deno.exit(1);
std

Version Info

Tagged at
6 months ago