@supernovaio/cli 2.0.39 → 2.0.41
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/dist/code-analyzer/analyzers/component-usage.d.ts +6 -0
- package/dist/code-analyzer/analyzers/component-usage.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/component-usage.js +344 -0
- package/dist/code-analyzer/analyzers/component-usage.js.map +1 -0
- package/dist/code-analyzer/analyzers/helpers.d.ts +11 -0
- package/dist/code-analyzer/analyzers/helpers.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/helpers.js +59 -0
- package/dist/code-analyzer/analyzers/helpers.js.map +1 -0
- package/dist/code-analyzer/analyzers/index.d.ts +8 -0
- package/dist/code-analyzer/analyzers/index.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/index.js +11 -0
- package/dist/code-analyzer/analyzers/index.js.map +1 -0
- package/dist/code-analyzer/analyzers/jsdoc.d.ts +3 -0
- package/dist/code-analyzer/analyzers/jsdoc.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/jsdoc.js +7 -0
- package/dist/code-analyzer/analyzers/jsdoc.js.map +1 -0
- package/dist/code-analyzer/analyzers/static-components.d.ts +3 -0
- package/dist/code-analyzer/analyzers/static-components.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/static-components.js +399 -0
- package/dist/code-analyzer/analyzers/static-components.js.map +1 -0
- package/dist/code-analyzer/analyzers/storybook-docs.d.ts +3 -0
- package/dist/code-analyzer/analyzers/storybook-docs.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/storybook-docs.js +163 -0
- package/dist/code-analyzer/analyzers/storybook-docs.js.map +1 -0
- package/dist/code-analyzer/analyzers/storybook-stories.d.ts +3 -0
- package/dist/code-analyzer/analyzers/storybook-stories.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/storybook-stories.js +91 -0
- package/dist/code-analyzer/analyzers/storybook-stories.js.map +1 -0
- package/dist/code-analyzer/analyzers/types.d.ts +88 -0
- package/dist/code-analyzer/analyzers/types.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/types.js +12 -0
- package/dist/code-analyzer/analyzers/types.js.map +1 -0
- package/dist/code-analyzer/analyzers/typescript-api.d.ts +3 -0
- package/dist/code-analyzer/analyzers/typescript-api.d.ts.map +1 -0
- package/dist/code-analyzer/analyzers/typescript-api.js +7 -0
- package/dist/code-analyzer/analyzers/typescript-api.js.map +1 -0
- package/dist/code-analyzer/components/analyze.d.ts +8 -0
- package/dist/code-analyzer/components/analyze.d.ts.map +1 -0
- package/dist/code-analyzer/components/analyze.js +38 -0
- package/dist/code-analyzer/components/analyze.js.map +1 -0
- package/dist/code-analyzer/components/mappers/component.d.ts +4 -0
- package/dist/code-analyzer/components/mappers/component.d.ts.map +1 -0
- package/dist/code-analyzer/components/mappers/component.js +20 -0
- package/dist/code-analyzer/components/mappers/component.js.map +1 -0
- package/dist/code-analyzer/components/mappers/property.d.ts +4 -0
- package/dist/code-analyzer/components/mappers/property.d.ts.map +1 -0
- package/dist/code-analyzer/components/mappers/property.js +19 -0
- package/dist/code-analyzer/components/mappers/property.js.map +1 -0
- package/dist/code-analyzer/components/parser/index.d.ts +6 -0
- package/dist/code-analyzer/components/parser/index.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/index.js +9 -0
- package/dist/code-analyzer/components/parser/index.js.map +1 -0
- package/dist/code-analyzer/components/parser/module-parser.d.ts +12 -0
- package/dist/code-analyzer/components/parser/module-parser.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/module-parser.js +116 -0
- package/dist/code-analyzer/components/parser/module-parser.js.map +1 -0
- package/dist/code-analyzer/components/parser/parser.d.ts +46 -0
- package/dist/code-analyzer/components/parser/parser.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/parser.js +904 -0
- package/dist/code-analyzer/components/parser/parser.js.map +1 -0
- package/dist/code-analyzer/components/parser/types.d.ts +123 -0
- package/dist/code-analyzer/components/parser/types.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/types.js +21 -0
- package/dist/code-analyzer/components/parser/types.js.map +1 -0
- package/dist/code-analyzer/components/parser/utils/build-filter.d.ts +3 -0
- package/dist/code-analyzer/components/parser/utils/build-filter.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/utils/build-filter.js +31 -0
- package/dist/code-analyzer/components/parser/utils/build-filter.js.map +1 -0
- package/dist/code-analyzer/components/parser/utils/filter-duplicates.d.ts +3 -0
- package/dist/code-analyzer/components/parser/utils/filter-duplicates.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/utils/filter-duplicates.js +17 -0
- package/dist/code-analyzer/components/parser/utils/filter-duplicates.js.map +1 -0
- package/dist/code-analyzer/components/parser/utils/is-react-component.d.ts +4 -0
- package/dist/code-analyzer/components/parser/utils/is-react-component.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/utils/is-react-component.js +43 -0
- package/dist/code-analyzer/components/parser/utils/is-react-component.js.map +1 -0
- package/dist/code-analyzer/components/parser/utils/trim-file-name.d.ts +2 -0
- package/dist/code-analyzer/components/parser/utils/trim-file-name.d.ts.map +1 -0
- package/dist/code-analyzer/components/parser/utils/trim-file-name.js +22 -0
- package/dist/code-analyzer/components/parser/utils/trim-file-name.js.map +1 -0
- package/dist/code-analyzer/components/types.d.ts +18 -0
- package/dist/code-analyzer/components/types.d.ts.map +1 -0
- package/dist/code-analyzer/components/types.js +5 -0
- package/dist/code-analyzer/components/types.js.map +1 -0
- package/dist/code-analyzer/components/utils/get-module-exports-path.d.ts +2 -0
- package/dist/code-analyzer/components/utils/get-module-exports-path.d.ts.map +1 -0
- package/dist/code-analyzer/components/utils/get-module-exports-path.js +60 -0
- package/dist/code-analyzer/components/utils/get-module-exports-path.js.map +1 -0
- package/dist/code-analyzer/index.d.ts +5 -0
- package/dist/code-analyzer/index.d.ts.map +1 -0
- package/dist/code-analyzer/index.js +8 -0
- package/dist/code-analyzer/index.js.map +1 -0
- package/dist/code-analyzer/orchestrator/index.d.ts +2 -0
- package/dist/code-analyzer/orchestrator/index.d.ts.map +1 -0
- package/dist/code-analyzer/orchestrator/index.js +5 -0
- package/dist/code-analyzer/orchestrator/index.js.map +1 -0
- package/dist/code-analyzer/orchestrator/run-analysis.d.ts +19 -0
- package/dist/code-analyzer/orchestrator/run-analysis.d.ts.map +1 -0
- package/dist/code-analyzer/orchestrator/run-analysis.js +109 -0
- package/dist/code-analyzer/orchestrator/run-analysis.js.map +1 -0
- package/dist/code-analyzer/snapshot/index.d.ts +2 -0
- package/dist/code-analyzer/snapshot/index.d.ts.map +1 -0
- package/dist/code-analyzer/snapshot/index.js +5 -0
- package/dist/code-analyzer/snapshot/index.js.map +1 -0
- package/dist/code-analyzer/snapshot/write-snapshot.d.ts +17 -0
- package/dist/code-analyzer/snapshot/write-snapshot.d.ts.map +1 -0
- package/dist/code-analyzer/snapshot/write-snapshot.js +60 -0
- package/dist/code-analyzer/snapshot/write-snapshot.js.map +1 -0
- package/dist/commands/analyze.d.ts +0 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +25 -5
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/components-import.js +3 -3
- package/dist/commands/components-import.js.map +1 -1
- package/dist/commands/publish-documentation.d.ts +2 -2
- package/dist/commands/run-local-exporter.js +2 -2
- package/dist/commands/run-local-exporter.js.map +1 -1
- package/dist/commands/storybook-import.d.ts +2 -2
- package/dist/commands/template-upload.d.ts +1 -0
- package/dist/commands/template-upload.d.ts.map +1 -1
- package/dist/commands/template-upload.js +57 -18
- package/dist/commands/template-upload.js.map +1 -1
- package/dist/docker-scripts/extract-private-packages-tarball.js +282 -0
- package/dist/types/config.d.ts +5 -5
- package/dist/types/types.js +2 -2
- package/dist/types/types.js.map +1 -1
- package/dist/utils/analyze-command.d.ts.map +1 -1
- package/dist/utils/analyze-command.js +30 -3
- package/dist/utils/analyze-command.js.map +1 -1
- package/dist/utils/discover.d.ts +2 -2
- package/dist/utils/discover.d.ts.map +1 -1
- package/dist/utils/discover.js +25 -23
- package/dist/utils/discover.js.map +1 -1
- package/dist/utils/figma-tokens-data-loader.js +2 -2
- package/dist/utils/figma-tokens-data-loader.js.map +1 -1
- package/dist/utils/run-exporter/exporter-utils.js +2 -2
- package/dist/utils/run-exporter/exporter-utils.js.map +1 -1
- package/dist/utils/validate-templates.d.ts +1 -1
- package/dist/utils/validate-templates.d.ts.map +1 -1
- package/dist/utils/validate-templates.js +4 -4
- package/dist/utils/validate-templates.js.map +1 -1
- package/oclif.manifest.json +13 -5
- package/package.json +8 -3
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2d262f78-ace0-5edb-971a-e5a64f11140a")}catch(e){}}();
|
|
3
|
+
import { access, readFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { globSync } from "glob";
|
|
6
|
+
import * as ts from "typescript";
|
|
7
|
+
import { analyzeComponents } from "../components/analyze.js";
|
|
8
|
+
import { componentKeyFrom } from "./helpers.js";
|
|
9
|
+
function getWorkspacePatterns(packageJson) {
|
|
10
|
+
const raw = packageJson.workspaces;
|
|
11
|
+
if (!raw) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
return Array.isArray(raw) ? raw : (raw.packages ?? []);
|
|
15
|
+
}
|
|
16
|
+
const ignoredReferenceTypeNames = new Set([
|
|
17
|
+
"AbortSignal",
|
|
18
|
+
"Array",
|
|
19
|
+
"ArrayBuffer",
|
|
20
|
+
"Blob",
|
|
21
|
+
"Booleanish",
|
|
22
|
+
"ChangeEvent",
|
|
23
|
+
"ClassName",
|
|
24
|
+
"CSSProperties",
|
|
25
|
+
"Date",
|
|
26
|
+
"ElementType",
|
|
27
|
+
"Error",
|
|
28
|
+
"Event",
|
|
29
|
+
"Exclude",
|
|
30
|
+
"Extract",
|
|
31
|
+
"FocusEvent",
|
|
32
|
+
"FormEvent",
|
|
33
|
+
"HTMLElement",
|
|
34
|
+
"HTMLInputElement",
|
|
35
|
+
"HTMLLabelElement",
|
|
36
|
+
"IntersectionObserver",
|
|
37
|
+
"JSX",
|
|
38
|
+
"KeyboardEvent",
|
|
39
|
+
"LegacyRef",
|
|
40
|
+
"Map",
|
|
41
|
+
"MouseEvent",
|
|
42
|
+
"NonNullable",
|
|
43
|
+
"Omit",
|
|
44
|
+
"Partial",
|
|
45
|
+
"Pick",
|
|
46
|
+
"PointerEvent",
|
|
47
|
+
"Promise",
|
|
48
|
+
"PropsWithChildren",
|
|
49
|
+
"Readonly",
|
|
50
|
+
"Record",
|
|
51
|
+
"Ref",
|
|
52
|
+
"RefObject",
|
|
53
|
+
"Required",
|
|
54
|
+
"ReturnType",
|
|
55
|
+
"Set",
|
|
56
|
+
"String",
|
|
57
|
+
"SubmitEvent",
|
|
58
|
+
"SyntheticEvent",
|
|
59
|
+
"Uint8Array",
|
|
60
|
+
"URL",
|
|
61
|
+
]);
|
|
62
|
+
function serializePropType(type) {
|
|
63
|
+
if (type == null) {
|
|
64
|
+
return "unknown";
|
|
65
|
+
}
|
|
66
|
+
if (typeof type === "string") {
|
|
67
|
+
return type;
|
|
68
|
+
}
|
|
69
|
+
if (typeof type === "object") {
|
|
70
|
+
const maybeRaw = type.raw;
|
|
71
|
+
if (typeof maybeRaw === "string" && maybeRaw.trim().length > 0) {
|
|
72
|
+
return maybeRaw.replaceAll(/\s+/g, " ").trim();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return JSON.stringify(type).replaceAll(/\s+/g, " ").trim();
|
|
76
|
+
}
|
|
77
|
+
function isLikelyReactNativeProp(property) {
|
|
78
|
+
const declarations = property.declarations ?? [];
|
|
79
|
+
if (declarations.length === 0) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return declarations.every(declaration => {
|
|
83
|
+
const file = declaration.fileName;
|
|
84
|
+
return (file.includes("node_modules/@types/react") ||
|
|
85
|
+
file.includes("node_modules/react") ||
|
|
86
|
+
file.includes("node_modules/@types/react-dom"));
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function shouldIncludeProp(property) {
|
|
90
|
+
if (!isLikelyReactNativeProp(property)) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return property.description.trim().length > 0;
|
|
94
|
+
}
|
|
95
|
+
function extractTypeReferences(typeText) {
|
|
96
|
+
const matches = typeText.match(/\b[A-Z][A-Za-z0-9_]*\b/g) ?? [];
|
|
97
|
+
return [...new Set(matches.filter(token => !ignoredReferenceTypeNames.has(token)))];
|
|
98
|
+
}
|
|
99
|
+
function resolveRelativeImportPath(fromFilePath, moduleSpecifier) {
|
|
100
|
+
if (!moduleSpecifier.startsWith(".")) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const basePath = path.resolve(path.dirname(fromFilePath), moduleSpecifier);
|
|
104
|
+
const candidates = [
|
|
105
|
+
basePath,
|
|
106
|
+
`${basePath}.ts`,
|
|
107
|
+
`${basePath}.tsx`,
|
|
108
|
+
`${basePath}.d.ts`,
|
|
109
|
+
path.join(basePath, "index.ts"),
|
|
110
|
+
path.join(basePath, "index.tsx"),
|
|
111
|
+
path.join(basePath, "index.d.ts"),
|
|
112
|
+
];
|
|
113
|
+
return candidates.find(candidate => ts.sys.fileExists(candidate)) ?? null;
|
|
114
|
+
}
|
|
115
|
+
function collectImportedTypeBindings(filePath) {
|
|
116
|
+
const sourceText = ts.sys.readFile(filePath);
|
|
117
|
+
if (!sourceText) {
|
|
118
|
+
return new Map();
|
|
119
|
+
}
|
|
120
|
+
const scriptKind = filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
|
|
121
|
+
const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, scriptKind);
|
|
122
|
+
const imports = new Map();
|
|
123
|
+
for (const statement of sourceFile.statements) {
|
|
124
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const resolvedImportPath = resolveRelativeImportPath(filePath, statement.moduleSpecifier.text);
|
|
128
|
+
if (!resolvedImportPath) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
132
|
+
if (!namedBindings || !ts.isNamedImports(namedBindings)) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
for (const element of namedBindings.elements) {
|
|
136
|
+
const localName = element.name.getText(sourceFile);
|
|
137
|
+
const importedName = element.propertyName ? element.propertyName.getText(sourceFile) : localName;
|
|
138
|
+
imports.set(localName, { importedName, sourceFilePath: resolvedImportPath });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return imports;
|
|
142
|
+
}
|
|
143
|
+
function collectRelativeImportSourceFiles(filePath) {
|
|
144
|
+
const sourceText = ts.sys.readFile(filePath);
|
|
145
|
+
if (!sourceText) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
const scriptKind = filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
|
|
149
|
+
const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, scriptKind);
|
|
150
|
+
const importSourceFiles = new Set();
|
|
151
|
+
for (const statement of sourceFile.statements) {
|
|
152
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const resolvedImportPath = resolveRelativeImportPath(filePath, statement.moduleSpecifier.text);
|
|
156
|
+
if (resolvedImportPath) {
|
|
157
|
+
importSourceFiles.add(resolvedImportPath);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return [...importSourceFiles];
|
|
161
|
+
}
|
|
162
|
+
function collectLocalTypeDeclarations(filePath) {
|
|
163
|
+
const sourceText = ts.sys.readFile(filePath);
|
|
164
|
+
if (!sourceText) {
|
|
165
|
+
return new Map();
|
|
166
|
+
}
|
|
167
|
+
const scriptKind = filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
|
|
168
|
+
const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, scriptKind);
|
|
169
|
+
const declarations = new Map();
|
|
170
|
+
const collectNode = (node) => {
|
|
171
|
+
if (ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) {
|
|
172
|
+
const start = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
173
|
+
const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
|
|
174
|
+
const declaration = {
|
|
175
|
+
definition: node.getText(sourceFile).trim(),
|
|
176
|
+
lineEnd: end.line + 1,
|
|
177
|
+
lineStart: start.line + 1,
|
|
178
|
+
name: node.name.getText(sourceFile),
|
|
179
|
+
};
|
|
180
|
+
declarations.set(declaration.name, declaration);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
for (const statement of sourceFile.statements) {
|
|
184
|
+
collectNode(statement);
|
|
185
|
+
}
|
|
186
|
+
return declarations;
|
|
187
|
+
}
|
|
188
|
+
function resolveLinkedTypes(component, sourceRootDir) {
|
|
189
|
+
const fileCandidates = [
|
|
190
|
+
path.resolve(sourceRootDir, component.componentPath),
|
|
191
|
+
path.resolve(sourceRootDir, "src", component.componentPath),
|
|
192
|
+
];
|
|
193
|
+
const componentFilePath = fileCandidates.find(candidate => ts.sys.fileExists(candidate));
|
|
194
|
+
if (!componentFilePath) {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
const declarationsByFile = new Map();
|
|
198
|
+
const importsByFile = new Map();
|
|
199
|
+
const importSourceFilesByFile = new Map();
|
|
200
|
+
const ensureFileData = (filePath) => {
|
|
201
|
+
if (!declarationsByFile.has(filePath)) {
|
|
202
|
+
declarationsByFile.set(filePath, collectLocalTypeDeclarations(filePath));
|
|
203
|
+
}
|
|
204
|
+
if (!importsByFile.has(filePath)) {
|
|
205
|
+
importsByFile.set(filePath, collectImportedTypeBindings(filePath));
|
|
206
|
+
}
|
|
207
|
+
if (!importSourceFilesByFile.has(filePath)) {
|
|
208
|
+
importSourceFilesByFile.set(filePath, collectRelativeImportSourceFiles(filePath));
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
ensureFileData(componentFilePath);
|
|
212
|
+
const queue = [];
|
|
213
|
+
const seen = new Set();
|
|
214
|
+
for (const property of Object.values(component.properties)) {
|
|
215
|
+
const serialized = serializePropType(property.type);
|
|
216
|
+
for (const reference of extractTypeReferences(serialized)) {
|
|
217
|
+
queue.push({ contextFilePath: componentFilePath, typeName: reference });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const resolved = [];
|
|
221
|
+
const added = new Set();
|
|
222
|
+
const toDisplaySourcePath = (filePath) => {
|
|
223
|
+
const sourceRelative = path.relative(sourceRootDir, filePath).replaceAll(path.sep, "/");
|
|
224
|
+
return sourceRelative.startsWith("src/") ? sourceRelative.slice(4) : sourceRelative;
|
|
225
|
+
};
|
|
226
|
+
while (queue.length > 0) {
|
|
227
|
+
const current = queue.shift();
|
|
228
|
+
if (!current) {
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
const stateKey = `${current.contextFilePath}::${current.typeName}`;
|
|
232
|
+
if (seen.has(stateKey)) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
seen.add(stateKey);
|
|
236
|
+
ensureFileData(current.contextFilePath);
|
|
237
|
+
const fileDeclarations = declarationsByFile.get(current.contextFilePath) ?? new Map();
|
|
238
|
+
const declaration = fileDeclarations.get(current.typeName);
|
|
239
|
+
if (declaration) {
|
|
240
|
+
const addedKey = `${current.contextFilePath}::${declaration.name}`;
|
|
241
|
+
if (!added.has(addedKey)) {
|
|
242
|
+
resolved.push({
|
|
243
|
+
definition: declaration.definition,
|
|
244
|
+
lineEnd: declaration.lineEnd,
|
|
245
|
+
lineStart: declaration.lineStart,
|
|
246
|
+
name: declaration.name,
|
|
247
|
+
sourcePath: toDisplaySourcePath(current.contextFilePath),
|
|
248
|
+
});
|
|
249
|
+
added.add(addedKey);
|
|
250
|
+
}
|
|
251
|
+
for (const nestedReference of extractTypeReferences(declaration.definition)) {
|
|
252
|
+
if (fileDeclarations.has(nestedReference)) {
|
|
253
|
+
queue.push({ contextFilePath: current.contextFilePath, typeName: nestedReference });
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const fileImports = importsByFile.get(current.contextFilePath) ?? new Map();
|
|
259
|
+
const importedBinding = fileImports.get(current.typeName);
|
|
260
|
+
if (importedBinding) {
|
|
261
|
+
queue.push({ contextFilePath: importedBinding.sourceFilePath, typeName: importedBinding.importedName });
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const candidateFiles = importSourceFilesByFile.get(current.contextFilePath) ?? [];
|
|
265
|
+
const matchingFiles = [];
|
|
266
|
+
for (const candidateFilePath of candidateFiles) {
|
|
267
|
+
ensureFileData(candidateFilePath);
|
|
268
|
+
const declarations = declarationsByFile.get(candidateFilePath);
|
|
269
|
+
if (declarations?.has(current.typeName)) {
|
|
270
|
+
matchingFiles.push(candidateFilePath);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (matchingFiles.length === 1) {
|
|
274
|
+
queue.push({ contextFilePath: matchingFiles[0], typeName: current.typeName });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return resolved.sort((a, b) => {
|
|
278
|
+
if (a.name === b.name) {
|
|
279
|
+
return a.sourcePath.localeCompare(b.sourcePath);
|
|
280
|
+
}
|
|
281
|
+
return a.name.localeCompare(b.name);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
function mapProps(component) {
|
|
285
|
+
return Object.values(component.properties)
|
|
286
|
+
.filter(property => shouldIncludeProp(property))
|
|
287
|
+
.map(property => ({
|
|
288
|
+
name: property.name,
|
|
289
|
+
required: property.required,
|
|
290
|
+
type: serializePropType(property.type),
|
|
291
|
+
}))
|
|
292
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
293
|
+
}
|
|
294
|
+
async function fileExists(filePath) {
|
|
295
|
+
try {
|
|
296
|
+
await access(filePath);
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async function resolveWorkspacePackageDirectory(projectRoot, importFrom) {
|
|
304
|
+
const rootPackageJsonPath = path.join(projectRoot, "package.json");
|
|
305
|
+
if (!(await fileExists(rootPackageJsonPath))) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
const rootPackageJson = JSON.parse(await readFile(rootPackageJsonPath, "utf8"));
|
|
309
|
+
const workspacePatterns = getWorkspacePatterns(rootPackageJson);
|
|
310
|
+
for (const workspacePattern of workspacePatterns) {
|
|
311
|
+
const packageJsonFiles = globSync(`${workspacePattern}/package.json`, {
|
|
312
|
+
absolute: true,
|
|
313
|
+
cwd: projectRoot,
|
|
314
|
+
nodir: true,
|
|
315
|
+
});
|
|
316
|
+
for (const packageJsonFile of packageJsonFiles) {
|
|
317
|
+
const packageJson = JSON.parse(await readFile(packageJsonFile, "utf8"));
|
|
318
|
+
if (packageJson.name === importFrom) {
|
|
319
|
+
return path.dirname(packageJsonFile);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
async function analyzeComponentsFromBestTarget(projectRoot, importFrom) {
|
|
326
|
+
const localWorkspacePackageDir = await resolveWorkspacePackageDirectory(projectRoot, importFrom);
|
|
327
|
+
const candidates = [];
|
|
328
|
+
if (localWorkspacePackageDir) {
|
|
329
|
+
const sourceDir = path.join(localWorkspacePackageDir, "src");
|
|
330
|
+
if ((await fileExists(path.join(sourceDir, "index.ts"))) || (await fileExists(path.join(sourceDir, "index.tsx")))) {
|
|
331
|
+
candidates.push({ importFrom: "src", rootDir: localWorkspacePackageDir });
|
|
332
|
+
}
|
|
333
|
+
candidates.push({ importFrom: ".", rootDir: localWorkspacePackageDir });
|
|
334
|
+
}
|
|
335
|
+
candidates.push({ importFrom, rootDir: projectRoot });
|
|
336
|
+
let lastError;
|
|
337
|
+
for (const candidate of candidates) {
|
|
338
|
+
try {
|
|
339
|
+
const components = await analyzeComponents({
|
|
340
|
+
importFrom: candidate.importFrom,
|
|
341
|
+
rootDir: candidate.rootDir,
|
|
342
|
+
});
|
|
343
|
+
if (components.length > 0) {
|
|
344
|
+
return {
|
|
345
|
+
components,
|
|
346
|
+
sourceRootDir: candidate.rootDir,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
lastError = error;
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (lastError) {
|
|
356
|
+
throw lastError;
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
components: [],
|
|
360
|
+
sourceRootDir: projectRoot,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
export async function analyzeStaticComponents(projectRoot, importFrom) {
|
|
364
|
+
const { components, sourceRootDir } = await analyzeComponentsFromBestTarget(projectRoot, importFrom);
|
|
365
|
+
const descriptors = [];
|
|
366
|
+
const jsdocByComponentKey = {};
|
|
367
|
+
const typescriptApiByComponentKey = {};
|
|
368
|
+
const existingKeys = new Set();
|
|
369
|
+
for (const component of components.sort((a, b) => a.exportName.localeCompare(b.exportName))) {
|
|
370
|
+
const componentKey = componentKeyFrom(component.exportName, component.componentPath, existingKeys);
|
|
371
|
+
descriptors.push({
|
|
372
|
+
componentKey,
|
|
373
|
+
componentPath: component.componentPath,
|
|
374
|
+
exportName: component.exportName,
|
|
375
|
+
});
|
|
376
|
+
if (component.description.trim().length > 0) {
|
|
377
|
+
jsdocByComponentKey[componentKey] = {
|
|
378
|
+
description: component.description,
|
|
379
|
+
sourcePath: component.componentPath,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
const props = mapProps(component);
|
|
383
|
+
if (props.length > 0) {
|
|
384
|
+
const linkedTypes = resolveLinkedTypes(component, sourceRootDir);
|
|
385
|
+
typescriptApiByComponentKey[componentKey] = {
|
|
386
|
+
linkedTypes,
|
|
387
|
+
props,
|
|
388
|
+
sourcePath: component.componentPath,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return {
|
|
393
|
+
components: descriptors.sort((a, b) => a.componentKey.localeCompare(b.componentKey)),
|
|
394
|
+
jsdocByComponentKey,
|
|
395
|
+
typescriptApiByComponentKey,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=static-components.js.map
|
|
399
|
+
//# debugId=2d262f78-ace0-5edb-971a-e5a64f11140a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-components.js","sources":["../../../src/code-analyzer/analyzers/static-components.ts"],"sourceRoot":"","sourcesContent":["import { access, readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { globSync } from \"glob\"\nimport * as ts from \"typescript\"\n\nimport { analyzeComponents } from \"../components/analyze.js\"\nimport { Component, ComponentProperty } from \"../components/types.js\"\nimport { componentKeyFrom } from \"./helpers.js\"\nimport {\n ComponentApiProperty,\n ComponentDescriptor,\n JsDocRecord,\n LinkedTypeRecord,\n StaticComponentAnalyzerResult,\n} from \"./types.js\"\n\ntype WorkspacePackageJson = {\n name?: string\n workspaces?: string[] | { packages?: string[] }\n}\n\nfunction getWorkspacePatterns(packageJson: WorkspacePackageJson): string[] {\n const raw = packageJson.workspaces\n if (!raw) {\n return []\n }\n\n return Array.isArray(raw) ? raw : (raw.packages ?? [])\n}\n\ntype AnalyzeTarget = {\n importFrom: string\n rootDir: string\n}\n\ntype AnalyzeComponentsResult = {\n components: Component[]\n sourceRootDir: string\n}\n\ntype LocalTypeDeclaration = {\n definition: string\n lineEnd: number\n lineStart: number\n name: string\n}\n\ntype ImportedTypeBinding = {\n importedName: string\n sourceFilePath: string\n}\n\nconst ignoredReferenceTypeNames = new Set([\n \"AbortSignal\",\n \"Array\",\n \"ArrayBuffer\",\n \"Blob\",\n \"Booleanish\",\n \"ChangeEvent\",\n \"ClassName\",\n \"CSSProperties\",\n \"Date\",\n \"ElementType\",\n \"Error\",\n \"Event\",\n \"Exclude\",\n \"Extract\",\n \"FocusEvent\",\n \"FormEvent\",\n \"HTMLElement\",\n \"HTMLInputElement\",\n \"HTMLLabelElement\",\n \"IntersectionObserver\",\n \"JSX\",\n \"KeyboardEvent\",\n \"LegacyRef\",\n \"Map\",\n \"MouseEvent\",\n \"NonNullable\",\n \"Omit\",\n \"Partial\",\n \"Pick\",\n \"PointerEvent\",\n \"Promise\",\n \"PropsWithChildren\",\n \"Readonly\",\n \"Record\",\n \"Ref\",\n \"RefObject\",\n \"Required\",\n \"ReturnType\",\n \"Set\",\n \"String\",\n \"SubmitEvent\",\n \"SyntheticEvent\",\n \"Uint8Array\",\n \"URL\",\n])\n\nfunction serializePropType(type: unknown): string {\n if (type == null) {\n return \"unknown\"\n }\n\n if (typeof type === \"string\") {\n return type\n }\n\n if (typeof type === \"object\") {\n const maybeRaw = (type as { raw?: unknown }).raw\n if (typeof maybeRaw === \"string\" && maybeRaw.trim().length > 0) {\n return maybeRaw.replaceAll(/\\s+/g, \" \").trim()\n }\n }\n\n return JSON.stringify(type).replaceAll(/\\s+/g, \" \").trim()\n}\n\nfunction isLikelyReactNativeProp(property: ComponentProperty): boolean {\n const declarations = property.declarations ?? []\n if (declarations.length === 0) {\n return false\n }\n\n return declarations.every(declaration => {\n const file = declaration.fileName\n return (\n file.includes(\"node_modules/@types/react\") ||\n file.includes(\"node_modules/react\") ||\n file.includes(\"node_modules/@types/react-dom\")\n )\n })\n}\n\nfunction shouldIncludeProp(property: ComponentProperty): boolean {\n if (!isLikelyReactNativeProp(property)) {\n return true\n }\n\n return property.description.trim().length > 0\n}\n\nfunction extractTypeReferences(typeText: string): string[] {\n const matches = typeText.match(/\\b[A-Z][A-Za-z0-9_]*\\b/g) ?? []\n return [...new Set(matches.filter(token => !ignoredReferenceTypeNames.has(token)))]\n}\n\nfunction resolveRelativeImportPath(fromFilePath: string, moduleSpecifier: string): string | null {\n if (!moduleSpecifier.startsWith(\".\")) {\n return null\n }\n\n const basePath = path.resolve(path.dirname(fromFilePath), moduleSpecifier)\n const candidates = [\n basePath,\n `${basePath}.ts`,\n `${basePath}.tsx`,\n `${basePath}.d.ts`,\n path.join(basePath, \"index.ts\"),\n path.join(basePath, \"index.tsx\"),\n path.join(basePath, \"index.d.ts\"),\n ]\n\n return candidates.find(candidate => ts.sys.fileExists(candidate)) ?? null\n}\n\nfunction collectImportedTypeBindings(filePath: string): Map<string, ImportedTypeBinding> {\n const sourceText = ts.sys.readFile(filePath)\n if (!sourceText) {\n return new Map<string, ImportedTypeBinding>()\n }\n\n const scriptKind = filePath.endsWith(\".tsx\") ? ts.ScriptKind.TSX : ts.ScriptKind.TS\n const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, scriptKind)\n const imports = new Map<string, ImportedTypeBinding>()\n\n for (const statement of sourceFile.statements) {\n if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) {\n continue\n }\n\n const resolvedImportPath = resolveRelativeImportPath(filePath, statement.moduleSpecifier.text)\n if (!resolvedImportPath) {\n continue\n }\n\n const namedBindings = statement.importClause?.namedBindings\n if (!namedBindings || !ts.isNamedImports(namedBindings)) {\n continue\n }\n\n for (const element of namedBindings.elements) {\n const localName = element.name.getText(sourceFile)\n const importedName = element.propertyName ? element.propertyName.getText(sourceFile) : localName\n imports.set(localName, { importedName, sourceFilePath: resolvedImportPath })\n }\n }\n\n return imports\n}\n\nfunction collectRelativeImportSourceFiles(filePath: string): string[] {\n const sourceText = ts.sys.readFile(filePath)\n if (!sourceText) {\n return []\n }\n\n const scriptKind = filePath.endsWith(\".tsx\") ? ts.ScriptKind.TSX : ts.ScriptKind.TS\n const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, scriptKind)\n const importSourceFiles = new Set<string>()\n\n for (const statement of sourceFile.statements) {\n if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) {\n continue\n }\n\n const resolvedImportPath = resolveRelativeImportPath(filePath, statement.moduleSpecifier.text)\n if (resolvedImportPath) {\n importSourceFiles.add(resolvedImportPath)\n }\n }\n\n return [...importSourceFiles]\n}\n\nfunction collectLocalTypeDeclarations(filePath: string): Map<string, LocalTypeDeclaration> {\n const sourceText = ts.sys.readFile(filePath)\n if (!sourceText) {\n return new Map<string, LocalTypeDeclaration>()\n }\n\n const scriptKind = filePath.endsWith(\".tsx\") ? ts.ScriptKind.TSX : ts.ScriptKind.TS\n const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, scriptKind)\n const declarations = new Map<string, LocalTypeDeclaration>()\n\n const collectNode = (node: ts.Node): void => {\n if (ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) {\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile))\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd())\n const declaration = {\n definition: node.getText(sourceFile).trim(),\n lineEnd: end.line + 1,\n lineStart: start.line + 1,\n name: node.name.getText(sourceFile),\n }\n declarations.set(declaration.name, declaration)\n }\n }\n\n for (const statement of sourceFile.statements) {\n collectNode(statement)\n }\n\n return declarations\n}\n\nfunction resolveLinkedTypes(component: Component, sourceRootDir: string): LinkedTypeRecord[] {\n const fileCandidates = [\n path.resolve(sourceRootDir, component.componentPath),\n path.resolve(sourceRootDir, \"src\", component.componentPath),\n ]\n const componentFilePath = fileCandidates.find(candidate => ts.sys.fileExists(candidate))\n if (!componentFilePath) {\n return []\n }\n\n const declarationsByFile = new Map<string, Map<string, LocalTypeDeclaration>>()\n const importsByFile = new Map<string, Map<string, ImportedTypeBinding>>()\n const importSourceFilesByFile = new Map<string, string[]>()\n\n const ensureFileData = (filePath: string): void => {\n if (!declarationsByFile.has(filePath)) {\n declarationsByFile.set(filePath, collectLocalTypeDeclarations(filePath))\n }\n\n if (!importsByFile.has(filePath)) {\n importsByFile.set(filePath, collectImportedTypeBindings(filePath))\n }\n\n if (!importSourceFilesByFile.has(filePath)) {\n importSourceFilesByFile.set(filePath, collectRelativeImportSourceFiles(filePath))\n }\n }\n\n ensureFileData(componentFilePath)\n const queue: Array<{ contextFilePath: string; typeName: string }> = []\n const seen = new Set<string>()\n\n for (const property of Object.values(component.properties)) {\n const serialized = serializePropType(property.type)\n for (const reference of extractTypeReferences(serialized)) {\n queue.push({ contextFilePath: componentFilePath, typeName: reference })\n }\n }\n\n const resolved: LinkedTypeRecord[] = []\n const added = new Set<string>()\n\n const toDisplaySourcePath = (filePath: string): string => {\n const sourceRelative = path.relative(sourceRootDir, filePath).replaceAll(path.sep, \"/\")\n return sourceRelative.startsWith(\"src/\") ? sourceRelative.slice(4) : sourceRelative\n }\n\n while (queue.length > 0) {\n const current = queue.shift()\n if (!current) {\n continue\n }\n\n const stateKey = `${current.contextFilePath}::${current.typeName}`\n if (seen.has(stateKey)) {\n continue\n }\n\n seen.add(stateKey)\n\n ensureFileData(current.contextFilePath)\n const fileDeclarations = declarationsByFile.get(current.contextFilePath) ?? new Map()\n const declaration = fileDeclarations.get(current.typeName)\n\n if (declaration) {\n const addedKey = `${current.contextFilePath}::${declaration.name}`\n if (!added.has(addedKey)) {\n resolved.push({\n definition: declaration.definition,\n lineEnd: declaration.lineEnd,\n lineStart: declaration.lineStart,\n name: declaration.name,\n sourcePath: toDisplaySourcePath(current.contextFilePath),\n })\n added.add(addedKey)\n }\n\n // Expand only nested local declarations from the same file to avoid noisy dependency explosion.\n for (const nestedReference of extractTypeReferences(declaration.definition)) {\n if (fileDeclarations.has(nestedReference)) {\n queue.push({ contextFilePath: current.contextFilePath, typeName: nestedReference })\n }\n }\n\n continue\n }\n\n const fileImports = importsByFile.get(current.contextFilePath) ?? new Map()\n const importedBinding = fileImports.get(current.typeName)\n if (importedBinding) {\n queue.push({ contextFilePath: importedBinding.sourceFilePath, typeName: importedBinding.importedName })\n continue\n }\n\n // Fallback: unresolved type may come transitively from a locally imported file\n // (e.g. prop type is Responsive<Size>, where Size is declared in an imported types file).\n const candidateFiles = importSourceFilesByFile.get(current.contextFilePath) ?? []\n const matchingFiles: string[] = []\n for (const candidateFilePath of candidateFiles) {\n ensureFileData(candidateFilePath)\n const declarations = declarationsByFile.get(candidateFilePath)\n if (declarations?.has(current.typeName)) {\n matchingFiles.push(candidateFilePath)\n }\n }\n\n if (matchingFiles.length === 1) {\n queue.push({ contextFilePath: matchingFiles[0], typeName: current.typeName })\n }\n }\n\n return resolved.sort((a, b) => {\n if (a.name === b.name) {\n return a.sourcePath.localeCompare(b.sourcePath)\n }\n\n return a.name.localeCompare(b.name)\n })\n}\n\nfunction mapProps(component: Component): ComponentApiProperty[] {\n return Object.values(component.properties)\n .filter(property => shouldIncludeProp(property))\n .map(property => ({\n name: property.name,\n required: property.required,\n type: serializePropType(property.type),\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath)\n return true\n } catch {\n return false\n }\n}\n\nasync function resolveWorkspacePackageDirectory(projectRoot: string, importFrom: string): Promise<string | null> {\n const rootPackageJsonPath = path.join(projectRoot, \"package.json\")\n if (!(await fileExists(rootPackageJsonPath))) {\n return null\n }\n\n const rootPackageJson = JSON.parse(await readFile(rootPackageJsonPath, \"utf8\")) as WorkspacePackageJson\n const workspacePatterns = getWorkspacePatterns(rootPackageJson)\n\n for (const workspacePattern of workspacePatterns) {\n const packageJsonFiles = globSync(`${workspacePattern}/package.json`, {\n absolute: true,\n cwd: projectRoot,\n nodir: true,\n })\n\n for (const packageJsonFile of packageJsonFiles) {\n const packageJson = JSON.parse(await readFile(packageJsonFile, \"utf8\")) as WorkspacePackageJson\n if (packageJson.name === importFrom) {\n return path.dirname(packageJsonFile)\n }\n }\n }\n\n return null\n}\n\nasync function analyzeComponentsFromBestTarget(projectRoot: string, importFrom: string): Promise<AnalyzeComponentsResult> {\n const localWorkspacePackageDir = await resolveWorkspacePackageDirectory(projectRoot, importFrom)\n\n const candidates: AnalyzeTarget[] = []\n if (localWorkspacePackageDir) {\n const sourceDir = path.join(localWorkspacePackageDir, \"src\")\n if ((await fileExists(path.join(sourceDir, \"index.ts\"))) || (await fileExists(path.join(sourceDir, \"index.tsx\")))) {\n candidates.push({ importFrom: \"src\", rootDir: localWorkspacePackageDir })\n }\n\n candidates.push({ importFrom: \".\", rootDir: localWorkspacePackageDir })\n }\n\n candidates.push({ importFrom, rootDir: projectRoot })\n\n let lastError: unknown\n\n for (const candidate of candidates) {\n try {\n const components = await analyzeComponents({\n importFrom: candidate.importFrom,\n rootDir: candidate.rootDir,\n })\n\n if (components.length > 0) {\n return {\n components,\n sourceRootDir: candidate.rootDir,\n }\n }\n } catch (error) {\n lastError = error\n continue\n }\n }\n\n if (lastError) {\n throw lastError\n }\n\n return {\n components: [],\n sourceRootDir: projectRoot,\n }\n}\n\nexport async function analyzeStaticComponents(projectRoot: string, importFrom: string): Promise<StaticComponentAnalyzerResult> {\n const { components, sourceRootDir } = await analyzeComponentsFromBestTarget(projectRoot, importFrom)\n\n const descriptors: ComponentDescriptor[] = []\n const jsdocByComponentKey: Record<string, JsDocRecord> = {}\n const typescriptApiByComponentKey: StaticComponentAnalyzerResult[\"typescriptApiByComponentKey\"] = {}\n const existingKeys = new Set<string>()\n\n for (const component of components.sort((a, b) => a.exportName.localeCompare(b.exportName))) {\n const componentKey = componentKeyFrom(component.exportName, component.componentPath, existingKeys)\n\n descriptors.push({\n componentKey,\n componentPath: component.componentPath,\n exportName: component.exportName,\n })\n\n if (component.description.trim().length > 0) {\n jsdocByComponentKey[componentKey] = {\n description: component.description,\n sourcePath: component.componentPath,\n }\n }\n\n const props = mapProps(component)\n if (props.length > 0) {\n const linkedTypes = resolveLinkedTypes(component, sourceRootDir)\n typescriptApiByComponentKey[componentKey] = {\n linkedTypes,\n props,\n sourcePath: component.componentPath,\n }\n }\n }\n\n return {\n components: descriptors.sort((a, b) => a.componentKey.localeCompare(b.componentKey)),\n jsdocByComponentKey,\n typescriptApiByComponentKey,\n }\n}\n"],"names":[],"mappings":"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","debug_id":"2d262f78-ace0-5edb-971a-e5a64f11140a"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storybook-docs.d.ts","sourceRoot":"","sources":["../../../src/code-analyzer/analyzers/storybook-docs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AA8G3D,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,mBAAmB,EAAE,EACjC,YAAY,GAAE,MAAM,EAAO,GAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAuFtC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0ce14f9a-c743-50b2-959b-559515b5fa6c")}catch(e){}}();
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { collectFiles, toRelative } from "./helpers.js";
|
|
6
|
+
const docsPattern = "**/*.{md,mdx}";
|
|
7
|
+
const snippetWindowBefore = 3;
|
|
8
|
+
const snippetWindowAfter = 8;
|
|
9
|
+
const maxReferenceSnippetsPerFile = 3;
|
|
10
|
+
function extractTitle(content) {
|
|
11
|
+
const headingMatch = content.match(/^#\s+(.+)$/m);
|
|
12
|
+
if (headingMatch?.[1]) {
|
|
13
|
+
return headingMatch[1].trim();
|
|
14
|
+
}
|
|
15
|
+
const metaMatch = content.match(/<Meta\s+title=["']([^"']+)["']/);
|
|
16
|
+
return metaMatch?.[1]?.trim();
|
|
17
|
+
}
|
|
18
|
+
function escapeRegex(input) {
|
|
19
|
+
return input.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
|
|
20
|
+
}
|
|
21
|
+
function toPosix(input) {
|
|
22
|
+
return input.split(path.sep).join("/");
|
|
23
|
+
}
|
|
24
|
+
function lineAt(content, index) {
|
|
25
|
+
return content.slice(0, index).split("\n").length;
|
|
26
|
+
}
|
|
27
|
+
function normalizeLine(input) {
|
|
28
|
+
return input.replaceAll(/\s+/g, " ").trim().toLowerCase();
|
|
29
|
+
}
|
|
30
|
+
function createSnippet(content, line) {
|
|
31
|
+
const lines = content.split("\n");
|
|
32
|
+
const lineIndex = Math.max(0, Math.min(lines.length - 1, line - 1));
|
|
33
|
+
let lineStart = Math.max(1, line - snippetWindowBefore);
|
|
34
|
+
let lineEnd = Math.min(lines.length, line + snippetWindowAfter);
|
|
35
|
+
for (let i = lineIndex; i >= lineStart - 1; i -= 1) {
|
|
36
|
+
if (lines[i]?.trim() === "") {
|
|
37
|
+
lineStart = i + 2;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (let i = lineIndex; i <= lineEnd - 1; i += 1) {
|
|
42
|
+
if (lines[i]?.trim() === "") {
|
|
43
|
+
lineEnd = i;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (lineStart > lineEnd) {
|
|
48
|
+
lineStart = line;
|
|
49
|
+
lineEnd = line;
|
|
50
|
+
}
|
|
51
|
+
const snippet = lines.slice(lineStart - 1, lineEnd).join("\n").trimEnd();
|
|
52
|
+
return { lineEnd, lineStart, snippet };
|
|
53
|
+
}
|
|
54
|
+
function classifyDocRecord(relativePath, component, content) {
|
|
55
|
+
const normalizedPath = toPosix(relativePath).toLowerCase();
|
|
56
|
+
const componentPath = toPosix(component.componentPath).toLowerCase();
|
|
57
|
+
const componentDir = path.posix.dirname(componentPath);
|
|
58
|
+
const fileName = path.posix.basename(normalizedPath);
|
|
59
|
+
const exportName = component.exportName.toLowerCase();
|
|
60
|
+
const title = extractTitle(content);
|
|
61
|
+
const normalizedTitle = title ? normalizeLine(title) : "";
|
|
62
|
+
const componentToken = normalizeLine(component.exportName);
|
|
63
|
+
const inComponentDir = normalizedPath.startsWith(`${componentDir}/`);
|
|
64
|
+
const isReadme = fileName === "readme.md" || fileName === "readme.mdx";
|
|
65
|
+
const isDocsLike = fileName.startsWith("docs.") || fileName.endsWith(".docs.md") || fileName.endsWith(".docs.mdx");
|
|
66
|
+
const fileContainsName = fileName.includes(exportName);
|
|
67
|
+
const titleContainsName = normalizedTitle.includes(componentToken);
|
|
68
|
+
if (inComponentDir && isReadme) {
|
|
69
|
+
return { kind: "doc", score: 100 };
|
|
70
|
+
}
|
|
71
|
+
if (inComponentDir && isDocsLike) {
|
|
72
|
+
return { kind: "doc", score: 95 };
|
|
73
|
+
}
|
|
74
|
+
if (inComponentDir) {
|
|
75
|
+
return { kind: "doc", score: 90 };
|
|
76
|
+
}
|
|
77
|
+
if (fileContainsName || titleContainsName) {
|
|
78
|
+
return { kind: "doc", score: 80 };
|
|
79
|
+
}
|
|
80
|
+
if (normalizedPath.includes("/docs/") || normalizedPath.includes("/documentation/")) {
|
|
81
|
+
return { kind: "reference", score: 40 };
|
|
82
|
+
}
|
|
83
|
+
if (normalizedPath.includes("/storybook/") || normalizedPath.includes(".stories.")) {
|
|
84
|
+
return { kind: "reference", score: 35 };
|
|
85
|
+
}
|
|
86
|
+
return { kind: "reference", score: 20 };
|
|
87
|
+
}
|
|
88
|
+
export async function analyzeStorybookDocs(projectRoot, components, excludePaths = []) {
|
|
89
|
+
const files = await collectFiles({
|
|
90
|
+
excludePaths,
|
|
91
|
+
pattern: docsPattern,
|
|
92
|
+
projectRoot,
|
|
93
|
+
});
|
|
94
|
+
const records = {};
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
const content = await readFile(file, "utf8");
|
|
97
|
+
const title = extractTitle(content);
|
|
98
|
+
const relativePath = toRelative(projectRoot, file);
|
|
99
|
+
for (const component of components) {
|
|
100
|
+
const classification = classifyDocRecord(relativePath, component, content);
|
|
101
|
+
const componentPattern = new RegExp(`\\b${escapeRegex(component.exportName)}\\b`, "gm");
|
|
102
|
+
const matches = [...content.matchAll(componentPattern)];
|
|
103
|
+
const isFullDoc = classification.kind === "doc";
|
|
104
|
+
if (!isFullDoc && matches.length === 0) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (!records[component.componentKey]) {
|
|
108
|
+
records[component.componentKey] = [];
|
|
109
|
+
}
|
|
110
|
+
if (isFullDoc) {
|
|
111
|
+
const firstMatchIndex = typeof matches[0]?.index === "number" ? matches[0].index : 0;
|
|
112
|
+
const line = lineAt(content, firstMatchIndex);
|
|
113
|
+
records[component.componentKey].push({
|
|
114
|
+
content,
|
|
115
|
+
docPath: relativePath,
|
|
116
|
+
kind: "doc",
|
|
117
|
+
lineEnd: line,
|
|
118
|
+
lineStart: line,
|
|
119
|
+
score: classification.score,
|
|
120
|
+
title,
|
|
121
|
+
});
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const snippetMatches = matches.slice(0, maxReferenceSnippetsPerFile);
|
|
125
|
+
for (const match of snippetMatches) {
|
|
126
|
+
if (typeof match.index !== "number") {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const matchLine = lineAt(content, match.index);
|
|
130
|
+
const snippet = createSnippet(content, matchLine);
|
|
131
|
+
records[component.componentKey].push({
|
|
132
|
+
docPath: relativePath,
|
|
133
|
+
kind: "reference",
|
|
134
|
+
lineEnd: snippet.lineEnd,
|
|
135
|
+
lineStart: snippet.lineStart,
|
|
136
|
+
score: classification.score,
|
|
137
|
+
snippet: snippet.snippet,
|
|
138
|
+
title,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
for (const componentKey of Object.keys(records)) {
|
|
144
|
+
records[componentKey] = records[componentKey].sort((a, b) => {
|
|
145
|
+
if (a.score !== b.score) {
|
|
146
|
+
return b.score - a.score;
|
|
147
|
+
}
|
|
148
|
+
if (a.kind !== b.kind) {
|
|
149
|
+
return a.kind === "doc" ? -1 : 1;
|
|
150
|
+
}
|
|
151
|
+
if (a.docPath === b.docPath) {
|
|
152
|
+
if (a.lineStart === b.lineStart) {
|
|
153
|
+
return a.lineEnd - b.lineEnd;
|
|
154
|
+
}
|
|
155
|
+
return a.lineStart - b.lineStart;
|
|
156
|
+
}
|
|
157
|
+
return a.docPath.localeCompare(b.docPath);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return records;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=storybook-docs.js.map
|
|
163
|
+
//# debugId=0ce14f9a-c743-50b2-959b-559515b5fa6c
|