@codefast/cli 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +596 -0
- package/LICENSE +1 -1
- package/README.md +335 -129
- package/dist/arrange/analyze.d.ts +10 -0
- package/dist/arrange/cli-schema.d.ts +50 -0
- package/dist/arrange/command.d.ts +7 -0
- package/dist/arrange/domain/analyze-service.d.ts +18 -0
- package/dist/arrange/domain/ast/ast-node.d.ts +394 -0
- package/dist/arrange/domain/ast/collectors-cn.d.ts +26 -0
- package/dist/arrange/domain/ast/collectors-jsx.d.ts +8 -0
- package/dist/arrange/domain/ast/collectors-tv.d.ts +34 -0
- package/dist/arrange/domain/ast/helpers.d.ts +36 -0
- package/dist/arrange/domain/ast/helpers.js +1 -0
- package/dist/arrange/domain/ast/simplify-targets.d.ts +22 -0
- package/dist/arrange/domain/ast/targets.d.ts +20 -0
- package/dist/arrange/domain/constants.d.ts +111 -0
- package/dist/arrange/domain/grouping-service.d.ts +100 -0
- package/dist/arrange/domain/grouping.d.ts +21 -0
- package/dist/arrange/domain/imports.d.ts +14 -0
- package/dist/arrange/domain/source-text-formatters.d.ts +33 -0
- package/dist/arrange/domain/tailwind-token.d.ts +24 -0
- package/dist/arrange/domain/token-classifier.d.ts +47 -0
- package/dist/arrange/domain/types.d.ts +208 -0
- package/dist/arrange/output.d.ts +26 -0
- package/dist/arrange/process-file.d.ts +11 -0
- package/dist/arrange/resolve-target.d.ts +10 -0
- package/dist/arrange/resolve-target.js +3 -16
- package/dist/arrange/scan-target.d.ts +7 -0
- package/dist/arrange/simplify-process-file.d.ts +11 -0
- package/dist/arrange/simplify-sync.d.ts +13 -0
- package/dist/arrange/source-parse.d.ts +7 -0
- package/dist/arrange/suggest.d.ts +8 -0
- package/dist/arrange/sync.d.ts +11 -0
- package/dist/arrange/typescript-ast-translator.d.ts +31 -0
- package/dist/arrange/workspace.d.ts +13 -0
- package/dist/arrange/workspace.js +2 -2
- package/dist/audit/cli-schema.d.ts +93 -0
- package/dist/audit/cli-schema.js +14 -3
- package/dist/audit/command.d.ts +8 -0
- package/dist/audit/command.js +52 -12
- package/dist/audit/domain/audit-file.d.ts +7 -0
- package/dist/audit/domain/comment-content.d.ts +26 -0
- package/dist/audit/domain/comment-dividers.d.ts +62 -0
- package/dist/audit/domain/comment-dividers.js +48 -20
- package/dist/audit/domain/display-names.d.ts +11 -0
- package/dist/audit/domain/display-names.js +71 -0
- package/dist/audit/domain/import-policy.d.ts +34 -0
- package/dist/audit/domain/import-policy.js +147 -0
- package/dist/audit/domain/link-references.d.ts +40 -0
- package/dist/audit/domain/mappings.d.ts +45 -0
- package/dist/audit/domain/markdown-links.d.ts +44 -0
- package/dist/audit/domain/since-versions.d.ts +26 -0
- package/dist/audit/domain/tokenize.d.ts +14 -0
- package/dist/audit/domain/tsdoc-syntax.d.ts +20 -0
- package/dist/audit/domain/types.d.ts +171 -0
- package/dist/audit/output.d.ts +91 -0
- package/dist/audit/output.js +52 -11
- package/dist/audit/prepare.d.ts +70 -0
- package/dist/audit/prepare.js +41 -10
- package/dist/audit/run-comments.d.ts +17 -0
- package/dist/audit/run-comments.js +22 -18
- package/dist/audit/run-display-names.d.ts +14 -0
- package/dist/audit/run-display-names.js +60 -0
- package/dist/audit/run-imports.d.ts +14 -0
- package/dist/audit/{run-react.js → run-imports.js} +15 -5
- package/dist/audit/run-links.d.ts +14 -0
- package/dist/audit/run.d.ts +14 -0
- package/dist/bin.d.ts +2 -0
- package/dist/cli.d.ts +6 -0
- package/dist/core/cli/format-error.d.ts +7 -0
- package/dist/core/cli/global-options.d.ts +15 -0
- package/dist/core/cli/positional.d.ts +6 -0
- package/dist/core/cli/result-handle.d.ts +19 -0
- package/dist/core/config/define-config.d.ts +7 -0
- package/dist/core/config/define-config.js +8 -0
- package/dist/core/config/loader.d.ts +18 -0
- package/dist/core/config/loader.js +2 -7
- package/dist/core/config/schema.d.ts +99 -0
- package/dist/core/config/schema.js +7 -75
- package/dist/core/config/warnings.d.ts +6 -0
- package/dist/core/config.d.ts +12 -0
- package/dist/core/errors.d.ts +25 -0
- package/dist/core/exit-codes.d.ts +18 -0
- package/dist/core/filesystem/node.d.ts +7 -0
- package/dist/core/filesystem/node.js +1 -0
- package/dist/core/filesystem/port.d.ts +44 -0
- package/dist/core/glob.d.ts +19 -0
- package/dist/core/logger.d.ts +9 -0
- package/dist/core/result.d.ts +30 -0
- package/dist/core/schema-parse.d.ts +9 -0
- package/dist/core/source-text-edit.d.ts +33 -0
- package/dist/core/verbose-diagnostics.d.ts +6 -0
- package/dist/core/workspace/ancestor-directories.d.ts +12 -0
- package/dist/core/workspace/ancestor-directories.js +30 -0
- package/dist/core/workspace/markdown-walk.d.ts +7 -0
- package/dist/core/workspace/markdown-walk.js +2 -20
- package/dist/core/workspace/package-version.d.ts +9 -0
- package/dist/core/workspace/package-version.js +8 -12
- package/dist/core/workspace/resolver.d.ts +39 -0
- package/dist/core/workspace/resolver.js +58 -75
- package/dist/core/workspace/skip-directories.d.ts +6 -0
- package/dist/core/workspace/source-walk.d.ts +16 -0
- package/dist/core/workspace/source-walk.js +14 -20
- package/dist/core/workspace/typescript-walk.d.ts +7 -0
- package/dist/core/workspace/typescript-walk.js +2 -23
- package/dist/core/workspace/walk-files.d.ts +7 -0
- package/dist/core/workspace/walk-files.js +27 -0
- package/dist/core/workspace/well-known-files.d.ts +18 -0
- package/dist/core/workspace/well-known-files.js +18 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/mirror/cli-result.d.ts +13 -0
- package/dist/mirror/cli-schema.d.ts +8 -0
- package/dist/mirror/command.d.ts +7 -0
- package/dist/mirror/dist-filesystem-impl.d.ts +8 -0
- package/dist/mirror/domain/constants.d.ts +18 -0
- package/dist/mirror/domain/constants.js +0 -12
- package/dist/mirror/domain/dirent-guard.d.ts +10 -0
- package/dist/mirror/domain/dist-filesystem.d.ts +9 -0
- package/dist/mirror/domain/errors.d.ts +24 -0
- package/dist/mirror/domain/exports.d.ts +36 -0
- package/dist/mirror/domain/package-display-name.d.ts +8 -0
- package/dist/mirror/domain/path-normalizer.d.ts +6 -0
- package/dist/mirror/domain/types.d.ts +131 -0
- package/dist/mirror/output.d.ts +23 -0
- package/dist/mirror/package-path.d.ts +19 -0
- package/dist/mirror/prepare.d.ts +15 -0
- package/dist/mirror/prepare.js +2 -2
- package/dist/mirror/supplement-exports.d.ts +27 -0
- package/dist/mirror/supplement-exports.js +2 -2
- package/dist/mirror/sync-reporter.d.ts +60 -0
- package/dist/mirror/sync-reporter.js +4 -0
- package/dist/mirror/sync-types.d.ts +43 -0
- package/dist/mirror/sync-workspace-package.d.ts +9 -0
- package/dist/mirror/sync-workspace-package.js +3 -3
- package/dist/mirror/sync.d.ts +12 -0
- package/dist/mirror/sync.js +5 -3
- package/dist/mirror/write-exports.d.ts +15 -0
- package/dist/pack-slim/cli-result.d.ts +13 -0
- package/dist/pack-slim/cli-schema.d.ts +17 -0
- package/dist/pack-slim/command.d.ts +7 -0
- package/dist/pack-slim/command.js +5 -4
- package/dist/pack-slim/domain/transform.d.ts +69 -0
- package/dist/pack-slim/domain/transform.js +141 -15
- package/dist/pack-slim/domain/types.d.ts +46 -0
- package/dist/pack-slim/output.d.ts +15 -0
- package/dist/pack-slim/output.js +10 -1
- package/dist/pack-slim/sync.d.ts +23 -0
- package/dist/pack-slim/sync.js +14 -8
- package/dist/pack-slim/working-tree.d.ts +20 -0
- package/dist/tag/cli-result.d.ts +7 -0
- package/dist/tag/cli-schema.d.ts +8 -0
- package/dist/tag/command.d.ts +7 -0
- package/dist/tag/domain/types.d.ts +111 -0
- package/dist/tag/output.d.ts +17 -0
- package/dist/tag/prepare.d.ts +13 -0
- package/dist/tag/prepare.js +2 -2
- package/dist/tag/resolve-target-path.d.ts +10 -0
- package/dist/tag/since-writer.d.ts +32 -0
- package/dist/tag/sync.d.ts +42 -0
- package/dist/tag/target-candidates.d.ts +8 -0
- package/dist/tag/target-candidates.js +1 -1
- package/dist/tag/target-runner.d.ts +8 -0
- package/dist/tag/version-resolver.d.ts +7 -0
- package/package.json +16 -33
- package/dist/audit/domain/react-imports.js +0 -91
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ImportPolicyViolation } from "#/audit/domain/types";
|
|
2
|
+
/**
|
|
3
|
+
* One library's import policy: which forms of importing `module` are banned, optionally limited to
|
|
4
|
+
* files whose repo-relative path matches `scope`, plus an optional UMD-global name to flag when the
|
|
5
|
+
* file references `<name>.*` without importing it.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.10.0
|
|
8
|
+
*/
|
|
9
|
+
export interface ImportPolicyRule {
|
|
10
|
+
readonly module: string;
|
|
11
|
+
/** Banned forms: `namespace` (`import * as x`), `default` (`import x`), or `named:<name>`. */
|
|
12
|
+
readonly ban: ReadonlyArray<"namespace" | "default" | `named:${string}`>;
|
|
13
|
+
readonly scope?: ReadonlyArray<string> | undefined;
|
|
14
|
+
readonly umdGlobal?: string | undefined;
|
|
15
|
+
readonly message: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The import policies enforced across the monorepo: React members by name (never a namespace,
|
|
19
|
+
* default, or implicit `React.*` UMD global), and Zod as a namespace in front-end packages so
|
|
20
|
+
* bundlers can tree-shake it (a named `import { z }` pins Zod's full locale set into the bundle).
|
|
21
|
+
*
|
|
22
|
+
* @since 0.10.0
|
|
23
|
+
*/
|
|
24
|
+
export declare const defaultImportPolicyRules: ReadonlyArray<ImportPolicyRule>;
|
|
25
|
+
/**
|
|
26
|
+
* Scans one TypeScript source against the given import-policy rules and returns the violations.
|
|
27
|
+
*
|
|
28
|
+
* @remarks Each rule matches import declarations from its `module` and flags the banned forms;
|
|
29
|
+
* a rule with `umdGlobal` additionally flags implicit `<name>.*` type references when nothing in
|
|
30
|
+
* the file imports that name (the case tsc accepts silently through a UMD `export as namespace`).
|
|
31
|
+
*
|
|
32
|
+
* @since 0.10.0
|
|
33
|
+
*/
|
|
34
|
+
export declare function auditImportPolicySource(filePath: string, sourceText: string, rules: ReadonlyArray<ImportPolicyRule>): Array<ImportPolicyViolation>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { parseSync } from "oxc-parser";
|
|
2
|
+
/**
|
|
3
|
+
* The import policies enforced across the monorepo: React members by name (never a namespace,
|
|
4
|
+
* default, or implicit `React.*` UMD global), and Zod as a namespace in front-end packages so
|
|
5
|
+
* bundlers can tree-shake it (a named `import { z }` pins Zod's full locale set into the bundle).
|
|
6
|
+
*
|
|
7
|
+
* @since 0.10.0
|
|
8
|
+
*/
|
|
9
|
+
export const defaultImportPolicyRules = [
|
|
10
|
+
{
|
|
11
|
+
module: "react",
|
|
12
|
+
ban: ["namespace", "default"],
|
|
13
|
+
umdGlobal: "React",
|
|
14
|
+
message: 'import React members by name from "react"',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
module: "zod",
|
|
18
|
+
ban: ["named:z"],
|
|
19
|
+
scope: [
|
|
20
|
+
"packages/theme/**",
|
|
21
|
+
"packages/ui/**",
|
|
22
|
+
"packages/tailwind-variants/**",
|
|
23
|
+
"apps/web/**",
|
|
24
|
+
"examples/*/**",
|
|
25
|
+
"internal/benchmark-viewer/**",
|
|
26
|
+
],
|
|
27
|
+
message: 'import Zod as a namespace so bundlers can tree-shake it: import * as z from "zod"',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
function isOxcNode(value) {
|
|
31
|
+
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
32
|
+
}
|
|
33
|
+
function isIdentifierNamed(node, name) {
|
|
34
|
+
return isOxcNode(node) && node.type === "Identifier" && node.name === name;
|
|
35
|
+
}
|
|
36
|
+
function importedName(specifier) {
|
|
37
|
+
const imported = specifier.imported;
|
|
38
|
+
return isOxcNode(imported) && typeof imported.name === "string" ? imported.name : undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Scans one TypeScript source against the given import-policy rules and returns the violations.
|
|
42
|
+
*
|
|
43
|
+
* @remarks Each rule matches import declarations from its `module` and flags the banned forms;
|
|
44
|
+
* a rule with `umdGlobal` additionally flags implicit `<name>.*` type references when nothing in
|
|
45
|
+
* the file imports that name (the case tsc accepts silently through a UMD `export as namespace`).
|
|
46
|
+
*
|
|
47
|
+
* @since 0.10.0
|
|
48
|
+
*/
|
|
49
|
+
export function auditImportPolicySource(filePath, sourceText, rules) {
|
|
50
|
+
const { program } = parseSync(filePath, sourceText);
|
|
51
|
+
const statements = program.body;
|
|
52
|
+
const violations = [];
|
|
53
|
+
const boundUmdNames = new Set();
|
|
54
|
+
for (const rule of rules) {
|
|
55
|
+
const bannedNamed = new Set();
|
|
56
|
+
let banNamespace = false;
|
|
57
|
+
let banDefault = false;
|
|
58
|
+
for (const form of rule.ban) {
|
|
59
|
+
if (form === "namespace") {
|
|
60
|
+
banNamespace = true;
|
|
61
|
+
}
|
|
62
|
+
else if (form === "default") {
|
|
63
|
+
banDefault = true;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
bannedNamed.add(form.slice("named:".length));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const statement of statements) {
|
|
70
|
+
if (statement.type !== "ImportDeclaration") {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const source = statement.source;
|
|
74
|
+
if (!isOxcNode(source) || source.value !== rule.module) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const specifiers = Array.isArray(statement.specifiers) ? statement.specifiers.filter(isOxcNode) : [];
|
|
78
|
+
const umdGlobal = rule.umdGlobal;
|
|
79
|
+
if (umdGlobal !== undefined && specifiers.some((specifier) => isIdentifierNamed(specifier.local, umdGlobal))) {
|
|
80
|
+
boundUmdNames.add(umdGlobal);
|
|
81
|
+
}
|
|
82
|
+
for (const specifier of specifiers) {
|
|
83
|
+
if (banNamespace && specifier.type === "ImportNamespaceSpecifier") {
|
|
84
|
+
violations.push(violationAt(sourceText, statement, `namespace import of "${rule.module}" — ${rule.message}`));
|
|
85
|
+
}
|
|
86
|
+
else if (banDefault && specifier.type === "ImportDefaultSpecifier") {
|
|
87
|
+
violations.push(violationAt(sourceText, statement, `default import of "${rule.module}" — ${rule.message}`));
|
|
88
|
+
}
|
|
89
|
+
else if (specifier.type === "ImportSpecifier") {
|
|
90
|
+
const name = importedName(specifier);
|
|
91
|
+
if (name !== undefined && bannedNamed.has(name)) {
|
|
92
|
+
violations.push(violationAt(sourceText, statement, `named import { ${name} } from "${rule.module}" — ${rule.message}`));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (const rule of rules) {
|
|
99
|
+
if (rule.umdGlobal !== undefined && !boundUmdNames.has(rule.umdGlobal)) {
|
|
100
|
+
collectUmdGlobalReferences(program, sourceText, rule, violations);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
violations.sort((a, b) => a.line - b.line);
|
|
104
|
+
return violations;
|
|
105
|
+
}
|
|
106
|
+
function violationAt(sourceText, statement, reason) {
|
|
107
|
+
return {
|
|
108
|
+
line: lineOfOffset(sourceText, statement.start),
|
|
109
|
+
raw: firstLineOf(sourceText.slice(statement.start, statement.end)),
|
|
110
|
+
reason,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function collectUmdGlobalReferences(node, sourceText, rule, violations) {
|
|
114
|
+
if (node.type === "TSQualifiedName" && isIdentifierNamed(node.left, rule.umdGlobal ?? "")) {
|
|
115
|
+
violations.push({
|
|
116
|
+
line: lineOfOffset(sourceText, node.start),
|
|
117
|
+
raw: sourceText.slice(node.start, node.end),
|
|
118
|
+
reason: `implicit ${rule.umdGlobal}.* UMD global — ${rule.message}`,
|
|
119
|
+
});
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
for (const value of Object.values(node)) {
|
|
123
|
+
if (Array.isArray(value)) {
|
|
124
|
+
for (const item of value) {
|
|
125
|
+
if (isOxcNode(item)) {
|
|
126
|
+
collectUmdGlobalReferences(item, sourceText, rule, violations);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else if (isOxcNode(value)) {
|
|
131
|
+
collectUmdGlobalReferences(value, sourceText, rule, violations);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function lineOfOffset(sourceText, offset) {
|
|
136
|
+
let line = 1;
|
|
137
|
+
for (let index = 0; index < offset; index++) {
|
|
138
|
+
if (sourceText.charCodeAt(index) === 10) {
|
|
139
|
+
line++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return line;
|
|
143
|
+
}
|
|
144
|
+
function firstLineOf(text) {
|
|
145
|
+
const newlineIndex = text.indexOf("\n");
|
|
146
|
+
return newlineIndex === -1 ? text : text.slice(0, newlineIndex);
|
|
147
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves `{@link}` references against the scanned tree, so a rename that orphans one is caught.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* One `{@link}` occurrence found inside a comment.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.6.0
|
|
8
|
+
*/
|
|
9
|
+
export interface LinkReference {
|
|
10
|
+
readonly line: number;
|
|
11
|
+
/** The target as written, e.g. `writeJsonlRun`, `Foo.bar`, `../fixtures/adapter.ts`. */
|
|
12
|
+
readonly target: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Every `{@link}` target in a file's comments, in source order.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.6.0
|
|
18
|
+
*/
|
|
19
|
+
export declare function scanLinkReferences(content: string): Array<LinkReference>;
|
|
20
|
+
/**
|
|
21
|
+
* The identifier a declaration-style target must resolve through — `Foo.bar` resolves via `Foo`.
|
|
22
|
+
*
|
|
23
|
+
* @since 0.6.0
|
|
24
|
+
*/
|
|
25
|
+
export declare function linkTargetHead(target: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether a target names a file or URL rather than a declaration.
|
|
28
|
+
*
|
|
29
|
+
* @since 0.6.0
|
|
30
|
+
*/
|
|
31
|
+
export declare function isPathLinkTarget(target: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Counts word-boundary occurrences of each head across a body of source text.
|
|
34
|
+
*
|
|
35
|
+
* @remarks A `{@link X}` occurrence itself mentions `X` once, so a target is orphaned when its
|
|
36
|
+
* total mentions do not exceed its link occurrences — a rename removes every real mention.
|
|
37
|
+
*
|
|
38
|
+
* @since 0.6.0
|
|
39
|
+
*/
|
|
40
|
+
export declare function countHeadMentions(contents: Iterable<string>, heads: ReadonlySet<string>): Map<string, number>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Physical → logical replacements. Order matters: negative before positive,
|
|
3
|
+
* specific corners before general edges, with-value before bare.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.5.0-canary.6
|
|
6
|
+
*/
|
|
7
|
+
export declare const RTL_MAPPINGS: ReadonlyArray<readonly [string, string]>;
|
|
8
|
+
/**
|
|
9
|
+
* translate-x has no logical equivalent — it needs an rtl:-negated twin.
|
|
10
|
+
*
|
|
11
|
+
* @since 0.5.0-canary.6
|
|
12
|
+
*/
|
|
13
|
+
export declare const RTL_TRANSLATE_X_MAPPINGS: ReadonlyArray<readonly [string, string]>;
|
|
14
|
+
/**
|
|
15
|
+
* Classes that need an rtl:*-reverse companion.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.5.0-canary.6
|
|
18
|
+
*/
|
|
19
|
+
export declare const RTL_REVERSE_MAPPINGS: ReadonlyArray<readonly [string, string]>;
|
|
20
|
+
/**
|
|
21
|
+
* Classes that need an rtl: companion with the swapped value.
|
|
22
|
+
*
|
|
23
|
+
* @since 0.5.0-canary.6
|
|
24
|
+
*/
|
|
25
|
+
export declare const RTL_SWAP_MAPPINGS: ReadonlyArray<readonly [string, string]>;
|
|
26
|
+
/**
|
|
27
|
+
* Anything anchored to a physical side variant stays physical: Radix resolves
|
|
28
|
+
* `side` per direction, and a border/position/slide tied to that side must follow it.
|
|
29
|
+
*
|
|
30
|
+
* @since 0.5.0-canary.6
|
|
31
|
+
*/
|
|
32
|
+
export declare const PHYSICAL_SIDE_VARIANT: RegExp;
|
|
33
|
+
/**
|
|
34
|
+
* Slide animations under direction-resolved contexts are correct as-is:
|
|
35
|
+
* Radix flips `side`/`motion` values itself under DirectionProvider.
|
|
36
|
+
*
|
|
37
|
+
* @since 0.5.0-canary.6
|
|
38
|
+
*/
|
|
39
|
+
export declare const DIRECTION_RESOLVED_VARIANT: RegExp;
|
|
40
|
+
/**
|
|
41
|
+
* The physical slide-animation class prefixes the RTL audit inspects.
|
|
42
|
+
*
|
|
43
|
+
* @since 0.5.0-canary.6
|
|
44
|
+
*/
|
|
45
|
+
export declare const SLIDE_PREFIXES: readonly ["slide-in-from-left", "slide-in-from-right", "slide-out-to-left", "slide-out-to-right"];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the two things a markdown cross-reference can get wrong: where it points and what it lands on.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* One `[text](target)` whose target is a path in this repository.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.5.0
|
|
8
|
+
*/
|
|
9
|
+
type MarkdownLinkReference = {
|
|
10
|
+
readonly line: number;
|
|
11
|
+
/** The path as written, with any fragment stripped. Empty when the link is fragment-only. */
|
|
12
|
+
readonly targetPath: string;
|
|
13
|
+
/** The `#fragment`, without the hash, or `null`. */
|
|
14
|
+
readonly anchor: string | null;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* The anchors a document offers, and the references it makes.
|
|
18
|
+
*
|
|
19
|
+
* @since 0.5.0
|
|
20
|
+
*/
|
|
21
|
+
export type MarkdownLinkScan = {
|
|
22
|
+
readonly references: ReadonlyArray<MarkdownLinkReference>;
|
|
23
|
+
readonly anchors: ReadonlySet<string>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The anchor ids a rendered document exposes: explicit `<a id>` targets plus every heading's slug.
|
|
27
|
+
*
|
|
28
|
+
* @remarks Slugging matches GitHub's — lowercase, drop everything that is not a letter, number, space
|
|
29
|
+
* or hyphen, then hyphenate spaces. Duplicate headings get a `-1` suffix there; this returns the base
|
|
30
|
+
* only, so a link to the second copy reads as dangling rather than being silently accepted.
|
|
31
|
+
*
|
|
32
|
+
* @since 0.5.0
|
|
33
|
+
*/
|
|
34
|
+
export declare function collectMarkdownAnchors(content: string): Set<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Every repo-local link a document makes, with the anchors it offers.
|
|
37
|
+
*
|
|
38
|
+
* @remarks Fenced code is stripped first: a fence showing a link is an example, not a reference, and
|
|
39
|
+
* checking it would make the audit fail on documentation that is doing its job.
|
|
40
|
+
*
|
|
41
|
+
* @since 0.5.0
|
|
42
|
+
*/
|
|
43
|
+
export declare function scanMarkdownLinks(content: string): MarkdownLinkScan;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flags `@since` tags naming a version the owning package has not reached.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* One impossible `@since` stamp found in a file's comments.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.8.0
|
|
8
|
+
*/
|
|
9
|
+
export interface SinceVersionFinding {
|
|
10
|
+
readonly line: number;
|
|
11
|
+
readonly raw: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compares two SemVer strings by precedence — positive when `left` is greater,
|
|
15
|
+
* null when either side is not a SemVer version.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.8.0
|
|
18
|
+
*/
|
|
19
|
+
export declare function compareVersionPrecedence(left: string, right: string): number | null;
|
|
20
|
+
/**
|
|
21
|
+
* Scans a file's comments for `@since` tags stamped above the package's current
|
|
22
|
+
* version — a release that has not happened, so the stamp cannot be true.
|
|
23
|
+
*
|
|
24
|
+
* @since 0.8.0
|
|
25
|
+
*/
|
|
26
|
+
export declare function scanImpossibleSinceTags(content: string, packageVersion: string): Array<SinceVersionFinding>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RtlClassToken } from "#/audit/domain/types";
|
|
2
|
+
/**
|
|
3
|
+
* Splits a class token into [variant, value, modifier], colon/slash-aware of
|
|
4
|
+
* brackets and parens (arbitrary values like data-[side=left] or calc(...)).
|
|
5
|
+
*
|
|
6
|
+
* @since 0.5.0-canary.6
|
|
7
|
+
*/
|
|
8
|
+
export declare function splitClassName(token: string): [string | null, string, string | null];
|
|
9
|
+
/**
|
|
10
|
+
* Collects the parsed class tokens from every string literal in a file's content.
|
|
11
|
+
*
|
|
12
|
+
* @since 0.5.0-canary.6
|
|
13
|
+
*/
|
|
14
|
+
export declare function collectTokens(content: string): Array<RtlClassToken>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates every doc block against the official TSDoc grammar, not a regex approximation.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* One grammar diagnostic from the TSDoc parser.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.6.0
|
|
8
|
+
*/
|
|
9
|
+
export interface TsdocSyntaxFinding {
|
|
10
|
+
readonly line: number;
|
|
11
|
+
/** The parser's stable message id, e.g. `tsdoc-escape-right-brace` — the allowlist key. */
|
|
12
|
+
readonly raw: string;
|
|
13
|
+
readonly reason: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Every TSDoc grammar diagnostic in a file's doc blocks, in source order.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.6.0
|
|
19
|
+
*/
|
|
20
|
+
export declare function scanTsdocSyntax(content: string): Array<TsdocSyntaxFinding>;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A class token parsed from a source string literal, split into variant, value, and modifier.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.5.0-canary.6
|
|
5
|
+
*/
|
|
6
|
+
export type RtlClassToken = {
|
|
7
|
+
readonly raw: string;
|
|
8
|
+
readonly token: string;
|
|
9
|
+
readonly variant: string | null;
|
|
10
|
+
readonly value: string;
|
|
11
|
+
readonly modifier: string | null;
|
|
12
|
+
readonly line: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A physical class occurrence the RTL audit flags, with its suggested logical replacement.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.5.0-canary.6
|
|
18
|
+
*/
|
|
19
|
+
export type RtlViolation = {
|
|
20
|
+
readonly line: number;
|
|
21
|
+
readonly raw: string;
|
|
22
|
+
readonly suggestion: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The RTL violations found in one file.
|
|
26
|
+
*
|
|
27
|
+
* @since 0.5.0-canary.6
|
|
28
|
+
*/
|
|
29
|
+
export type RtlFileViolations = {
|
|
30
|
+
readonly relativePath: string;
|
|
31
|
+
readonly violations: Array<RtlViolation>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Outcome of one `audit rtl` run.
|
|
35
|
+
*
|
|
36
|
+
* @since 0.5.0-canary.6
|
|
37
|
+
*/
|
|
38
|
+
export type RtlAuditResult = {
|
|
39
|
+
readonly files: Array<RtlFileViolations>;
|
|
40
|
+
readonly violationCount: number;
|
|
41
|
+
readonly allowlistedCount: number;
|
|
42
|
+
readonly scannedFileCount: number;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* An import-policy violation: a banned import form (namespace / default / named), or an implicit
|
|
46
|
+
* UMD-global type reference under a name nothing in the file imports.
|
|
47
|
+
*
|
|
48
|
+
* @since 0.10.0
|
|
49
|
+
*/
|
|
50
|
+
export type ImportPolicyViolation = {
|
|
51
|
+
readonly line: number;
|
|
52
|
+
/** The offending source text — the import statement or the qualified type name. */
|
|
53
|
+
readonly raw: string;
|
|
54
|
+
readonly reason: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The import-policy violations found in one file.
|
|
58
|
+
*
|
|
59
|
+
* @since 0.10.0
|
|
60
|
+
*/
|
|
61
|
+
export type ImportPolicyFileViolations = {
|
|
62
|
+
readonly relativePath: string;
|
|
63
|
+
readonly violations: Array<ImportPolicyViolation>;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Outcome of one `audit imports` run.
|
|
67
|
+
*
|
|
68
|
+
* @since 0.10.0
|
|
69
|
+
*/
|
|
70
|
+
export type ImportsAuditResult = {
|
|
71
|
+
readonly files: Array<ImportPolicyFileViolations>;
|
|
72
|
+
readonly violationCount: number;
|
|
73
|
+
readonly allowlistedCount: number;
|
|
74
|
+
readonly scannedFileCount: number;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* A `token()`, `tag()` or module display name that breaks the display-name convention.
|
|
78
|
+
*
|
|
79
|
+
* @since 0.9.0
|
|
80
|
+
*/
|
|
81
|
+
export type DisplayNameViolation = {
|
|
82
|
+
readonly line: number;
|
|
83
|
+
/** The call as written, through its closing quote. */
|
|
84
|
+
readonly raw: string;
|
|
85
|
+
readonly reason: string;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* The display-name violations found in one file.
|
|
89
|
+
*
|
|
90
|
+
* @since 0.9.0
|
|
91
|
+
*/
|
|
92
|
+
export type DisplayNameFileViolations = {
|
|
93
|
+
readonly relativePath: string;
|
|
94
|
+
readonly violations: Array<DisplayNameViolation>;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Outcome of one `audit display-names` run.
|
|
98
|
+
*
|
|
99
|
+
* @since 0.9.0
|
|
100
|
+
*/
|
|
101
|
+
export type DisplayNameAuditResult = {
|
|
102
|
+
readonly files: Array<DisplayNameFileViolations>;
|
|
103
|
+
readonly violationCount: number;
|
|
104
|
+
readonly allowlistedCount: number;
|
|
105
|
+
readonly scannedFileCount: number;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* A broken link or anchor found by the link audit.
|
|
109
|
+
*
|
|
110
|
+
* @since 0.5.0
|
|
111
|
+
*/
|
|
112
|
+
export type LinkBreakage = {
|
|
113
|
+
readonly line: number;
|
|
114
|
+
/** The link target as written, fragment included. */
|
|
115
|
+
readonly raw: string;
|
|
116
|
+
readonly reason: string;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* The link breakages found in one markdown file.
|
|
120
|
+
*
|
|
121
|
+
* @since 0.5.0
|
|
122
|
+
*/
|
|
123
|
+
export type LinkFileBreakages = {
|
|
124
|
+
readonly relativePath: string;
|
|
125
|
+
readonly breakages: Array<LinkBreakage>;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Outcome of one `audit links` run.
|
|
129
|
+
*
|
|
130
|
+
* @since 0.5.0
|
|
131
|
+
*/
|
|
132
|
+
export type LinkAuditResult = {
|
|
133
|
+
readonly files: Array<LinkFileBreakages>;
|
|
134
|
+
readonly breakageCount: number;
|
|
135
|
+
readonly allowlistedCount: number;
|
|
136
|
+
readonly linkCount: number;
|
|
137
|
+
readonly scannedFileCount: number;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* A section divider that does not match the repo's one allowed form. Always `--fix`-able.
|
|
141
|
+
*
|
|
142
|
+
* @since 0.6.0
|
|
143
|
+
*/
|
|
144
|
+
export type DividerBreakage = {
|
|
145
|
+
readonly line: number;
|
|
146
|
+
/** The divider's opening line as written. */
|
|
147
|
+
readonly raw: string;
|
|
148
|
+
readonly reason: string;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* @see DividerBreakage
|
|
152
|
+
*
|
|
153
|
+
* @since 0.6.0
|
|
154
|
+
*/
|
|
155
|
+
export type DividerFileBreakages = {
|
|
156
|
+
readonly relativePath: string;
|
|
157
|
+
readonly breakages: Array<DividerBreakage>;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Outcome of one `audit comments` run. `fixedCount` stays `0` unless `--fix` was passed.
|
|
161
|
+
*
|
|
162
|
+
* @since 0.6.0
|
|
163
|
+
*/
|
|
164
|
+
export type CommentAuditResult = {
|
|
165
|
+
readonly files: Array<DividerFileBreakages>;
|
|
166
|
+
readonly breakageCount: number;
|
|
167
|
+
readonly allowlistedCount: number;
|
|
168
|
+
readonly fixedCount: number;
|
|
169
|
+
readonly dividerCount: number;
|
|
170
|
+
readonly scannedFileCount: number;
|
|
171
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { CommentAuditResult, ImportsAuditResult, LinkAuditResult, RtlAuditResult, DisplayNameAuditResult } from "#/audit/domain/types";
|
|
2
|
+
/**
|
|
3
|
+
* Exit `1` when any non-allowlisted violation remains.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.5.0-canary.6
|
|
6
|
+
*/
|
|
7
|
+
export declare function exitCodeForRtlAuditResult(result: RtlAuditResult): number;
|
|
8
|
+
/**
|
|
9
|
+
* Human-readable RTL audit report (matches the former packages/ui script shape).
|
|
10
|
+
*
|
|
11
|
+
* @since 0.5.0-canary.6
|
|
12
|
+
*/
|
|
13
|
+
export declare function presentRtlAuditResult(result: RtlAuditResult): void;
|
|
14
|
+
/**
|
|
15
|
+
* Machine-readable RTL audit summary for `--json`.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.5.0-canary.6
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatRtlAuditJsonOutput(result: RtlAuditResult, rootDir: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Exit `1` when any non-allowlisted broken link remains.
|
|
22
|
+
*
|
|
23
|
+
* @since 0.5.0
|
|
24
|
+
*/
|
|
25
|
+
export declare function exitCodeForLinkAuditResult(result: LinkAuditResult): number;
|
|
26
|
+
/**
|
|
27
|
+
* Human-readable link audit report.
|
|
28
|
+
*
|
|
29
|
+
* @since 0.5.0
|
|
30
|
+
*/
|
|
31
|
+
export declare function presentLinkAuditResult(result: LinkAuditResult): void;
|
|
32
|
+
/**
|
|
33
|
+
* Machine-readable link audit summary for `--json`.
|
|
34
|
+
*
|
|
35
|
+
* @since 0.5.0
|
|
36
|
+
*/
|
|
37
|
+
export declare function formatLinkAuditJsonOutput(result: LinkAuditResult, rootDir: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Exit `1` when any non-allowlisted import-policy violation remains.
|
|
40
|
+
*
|
|
41
|
+
* @since 0.10.0
|
|
42
|
+
*/
|
|
43
|
+
export declare function exitCodeForImportsAuditResult(result: ImportsAuditResult): number;
|
|
44
|
+
/**
|
|
45
|
+
* Human-readable import-policy report.
|
|
46
|
+
*
|
|
47
|
+
* @since 0.10.0
|
|
48
|
+
*/
|
|
49
|
+
export declare function presentImportsAuditResult(result: ImportsAuditResult): void;
|
|
50
|
+
/**
|
|
51
|
+
* Machine-readable import-policy summary for `--json`.
|
|
52
|
+
*
|
|
53
|
+
* @since 0.10.0
|
|
54
|
+
*/
|
|
55
|
+
export declare function formatImportsAuditJsonOutput(result: ImportsAuditResult, rootDir: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Exit `1` when any non-allowlisted divider still breaks the convention.
|
|
58
|
+
*
|
|
59
|
+
* @since 0.6.0
|
|
60
|
+
*/
|
|
61
|
+
export declare function exitCodeForCommentAuditResult(result: CommentAuditResult): number;
|
|
62
|
+
/**
|
|
63
|
+
* Human-readable comment-divider report.
|
|
64
|
+
*
|
|
65
|
+
* @since 0.6.0
|
|
66
|
+
*/
|
|
67
|
+
export declare function presentCommentAuditResult(result: CommentAuditResult): void;
|
|
68
|
+
/**
|
|
69
|
+
* Machine-readable comment-divider summary for `--json`.
|
|
70
|
+
*
|
|
71
|
+
* @since 0.6.0
|
|
72
|
+
*/
|
|
73
|
+
export declare function formatCommentAuditJsonOutput(result: CommentAuditResult, rootDir: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Exit `1` when any non-allowlisted display-name violation remains.
|
|
76
|
+
*
|
|
77
|
+
* @since 0.9.0
|
|
78
|
+
*/
|
|
79
|
+
export declare function exitCodeForDisplayNameAuditResult(result: DisplayNameAuditResult): number;
|
|
80
|
+
/**
|
|
81
|
+
* Human-readable display-name report.
|
|
82
|
+
*
|
|
83
|
+
* @since 0.9.0
|
|
84
|
+
*/
|
|
85
|
+
export declare function presentDisplayNameAuditResult(result: DisplayNameAuditResult): void;
|
|
86
|
+
/**
|
|
87
|
+
* Machine-readable display-name summary for `--json`.
|
|
88
|
+
*
|
|
89
|
+
* @since 0.9.0
|
|
90
|
+
*/
|
|
91
|
+
export declare function formatDisplayNameAuditJsonOutput(result: DisplayNameAuditResult, rootDir: string): string;
|