@storybook/react 10.5.0-alpha.4 → 10.5.0-alpha.6
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/_browser-chunks/{chunk-IMEABK32.js → chunk-JQJMT7FV.js} +25 -2
- package/dist/_browser-chunks/{chunk-S7Q5R54F.js → chunk-SKX2IJJR.js} +1 -1
- package/dist/entry-preview-docs.js +1 -1
- package/dist/index.js +2 -2
- package/dist/preset.js +2332 -2166
- package/dist/preview.js +2 -2
- package/package.json +4 -3
package/dist/preset.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_swx3ow7zp9i from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_swx3ow7zp9i from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_swx3ow7zp9i from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_swx3ow7zp9i.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_swx3ow7zp9i.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_swx3ow7zp9i.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
@@ -15314,2323 +15314,2427 @@ var extractArgTypesFromDocgenTypescript = async ({
|
|
|
15314
15314
|
};
|
|
15315
15315
|
|
|
15316
15316
|
// src/componentManifest/generator.ts
|
|
15317
|
-
import {
|
|
15318
|
-
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
import { logger as logger8 } from "storybook/internal/node-logger";
|
|
15322
|
-
|
|
15323
|
-
// src/componentManifest/componentMeta/ComponentMetaManager.ts
|
|
15324
|
-
import { logger as logger5 } from "storybook/internal/node-logger";
|
|
15325
|
-
import { existsSync as existsSync3, watch } from "fs";
|
|
15326
|
-
import * as path3 from "path";
|
|
15317
|
+
import {
|
|
15318
|
+
getStoryImportPathFromEntry,
|
|
15319
|
+
selectComponentEntriesByComponentId
|
|
15320
|
+
} from "storybook/internal/common";
|
|
15327
15321
|
|
|
15328
|
-
// src/componentManifest/
|
|
15329
|
-
|
|
15330
|
-
import
|
|
15322
|
+
// src/componentManifest/buildReactComponentDocgen.ts
|
|
15323
|
+
import { getComponentIdFromEntry } from "storybook/internal/common";
|
|
15324
|
+
import { extractDescription as extractDescription2 } from "storybook/internal/csf-tools";
|
|
15331
15325
|
|
|
15332
|
-
// src/componentManifest/
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
return
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
}
|
|
15340
|
-
function isWrappedExpression(typescript, expression) {
|
|
15341
|
-
return typescript.isParenthesizedExpression(expression) || typescript.isAsExpression(expression) || typescript.isNonNullExpression(expression) || (typescript.isSatisfiesExpression?.(expression) ?? !1);
|
|
15342
|
-
}
|
|
15343
|
-
function resolveAliasedSymbol(typescript, checker, symbol) {
|
|
15344
|
-
return symbol.flags & typescript.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
15345
|
-
}
|
|
15346
|
-
function getSymbolContextNode(symbol) {
|
|
15347
|
-
return symbol.valueDeclaration ?? symbol.getDeclarations()?.[0];
|
|
15348
|
-
}
|
|
15349
|
-
function resolveComponentSymbolFromNode(typescript, checker, node) {
|
|
15350
|
-
if (!node)
|
|
15351
|
-
return;
|
|
15352
|
-
let symbol = checker.getSymbolAtLocation(node);
|
|
15353
|
-
return symbol ? resolveComponentSymbol(typescript, checker, symbol, node) : void 0;
|
|
15326
|
+
// src/componentManifest/extractComponentDescription.ts
|
|
15327
|
+
function extractComponentDescription(metaJsDoc, docgenDescription, docgenJsDocTags) {
|
|
15328
|
+
let jsdocComment = metaJsDoc || docgenDescription, extracted = jsdocComment ? extractJSDocInfo(jsdocComment) : void 0, tags = docgenJsDocTags ?? extracted?.tags ?? {}, description = extracted?.description;
|
|
15329
|
+
return {
|
|
15330
|
+
description: ((tags?.describe?.[0] || tags?.desc?.[0]) ?? description)?.trim(),
|
|
15331
|
+
summary: tags.summary?.[0],
|
|
15332
|
+
jsDocTags: tags
|
|
15333
|
+
};
|
|
15354
15334
|
}
|
|
15355
|
-
|
|
15356
|
-
|
|
15357
|
-
|
|
15358
|
-
|
|
15359
|
-
|
|
15360
|
-
|
|
15361
|
-
|
|
15362
|
-
|
|
15363
|
-
|
|
15364
|
-
|
|
15365
|
-
|
|
15366
|
-
|
|
15367
|
-
|
|
15368
|
-
|
|
15369
|
-
return resolveComponentSymbol(
|
|
15370
|
-
typescript,
|
|
15371
|
-
checker,
|
|
15372
|
-
valueSymbol,
|
|
15373
|
-
declaration.name,
|
|
15374
|
-
depth + 1
|
|
15375
|
-
);
|
|
15376
|
-
}
|
|
15377
|
-
if (typescript.isPropertyAssignment(declaration)) {
|
|
15378
|
-
let next = resolveComponentSymbolFromNode(typescript, checker, declaration.initializer);
|
|
15379
|
-
if (next)
|
|
15380
|
-
return next;
|
|
15381
|
-
}
|
|
15382
|
-
if (typescript.isBinaryExpression(declaration) && declaration.operatorToken.kind === typescript.SyntaxKind.EqualsToken) {
|
|
15383
|
-
let next = resolveComponentSymbolFromNode(typescript, checker, declaration.right);
|
|
15384
|
-
if (next)
|
|
15385
|
-
return next;
|
|
15386
|
-
}
|
|
15335
|
+
|
|
15336
|
+
// src/componentManifest/getComponentImports.ts
|
|
15337
|
+
import { dirname as dirname6 } from "node:path";
|
|
15338
|
+
import { babelParse as babelParse2, recast, types as t2 } from "storybook/internal/babel";
|
|
15339
|
+
import { logger as logger6 } from "storybook/internal/node-logger";
|
|
15340
|
+
|
|
15341
|
+
// src/componentManifest/reactDocgenTypescript.ts
|
|
15342
|
+
import { dirname as dirname5 } from "node:path";
|
|
15343
|
+
import { logger as logger5 } from "storybook/internal/node-logger";
|
|
15344
|
+
var typeScriptPromise, reactDocgenTypescriptPromise, loadTypeScript = () => typeScriptPromise ??= import("typescript"), loadReactDocgenTypescript = () => reactDocgenTypescriptPromise ??= import("react-docgen-typescript"), LARGE_NON_USER_SOURCE_THRESHOLD = 30, getPropSource = (prop) => prop.parent?.fileName ?? prop.declarations?.[0]?.fileName, getLargeNonUserPropSources = (props) => {
|
|
15345
|
+
let countBySource = /* @__PURE__ */ new Map();
|
|
15346
|
+
for (let prop of Object.values(props)) {
|
|
15347
|
+
let source = getPropSource(prop);
|
|
15348
|
+
(source?.includes("node_modules") || source?.endsWith(".d.ts")) && countBySource.set(source, (countBySource.get(source) ?? 0) + 1);
|
|
15387
15349
|
}
|
|
15388
|
-
let
|
|
15389
|
-
|
|
15390
|
-
|
|
15391
|
-
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
|
|
15397
|
-
|
|
15398
|
-
|
|
15350
|
+
let largeNonUserSources = /* @__PURE__ */ new Set();
|
|
15351
|
+
for (let [source, count] of countBySource)
|
|
15352
|
+
count > LARGE_NON_USER_SOURCE_THRESHOLD && largeNonUserSources.add(source);
|
|
15353
|
+
return largeNonUserSources;
|
|
15354
|
+
};
|
|
15355
|
+
function findDisplayNameAssignment(typescript, sourceFile, identifierName) {
|
|
15356
|
+
for (let statement of sourceFile.statements) {
|
|
15357
|
+
if (!typescript.isExpressionStatement(statement))
|
|
15358
|
+
continue;
|
|
15359
|
+
let expr = statement.expression;
|
|
15360
|
+
if (typescript.isBinaryExpression(expr) && expr.operatorToken.kind === typescript.SyntaxKind.EqualsToken && typescript.isPropertyAccessExpression(expr.left) && expr.left.name.text === "displayName" && typescript.isIdentifier(expr.left.expression) && expr.left.expression.text === identifierName && typescript.isStringLiteral(expr.right))
|
|
15361
|
+
return expr.right.text;
|
|
15399
15362
|
}
|
|
15400
|
-
return resolved;
|
|
15401
15363
|
}
|
|
15402
|
-
function
|
|
15403
|
-
let
|
|
15404
|
-
if (!
|
|
15405
|
-
return;
|
|
15406
|
-
let
|
|
15407
|
-
for (let
|
|
15408
|
-
|
|
15409
|
-
|
|
15410
|
-
let moduleSpec = stmt.moduleSpecifier;
|
|
15411
|
-
if (!typescript.isStringLiteral(moduleSpec) || moduleSpec.text !== importSpecifier)
|
|
15364
|
+
function getExportNameMap(typescript, checker, sourceFile) {
|
|
15365
|
+
let moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
15366
|
+
if (!moduleSymbol)
|
|
15367
|
+
return /* @__PURE__ */ new Map();
|
|
15368
|
+
let result = /* @__PURE__ */ new Map(), fileName = sourceFile.fileName.replace(/.*\//, "").replace(/\.[^.]+$/, "");
|
|
15369
|
+
for (let exportSymbol of checker.getExportsOfModule(moduleSymbol)) {
|
|
15370
|
+
let resolved = exportSymbol.flags & typescript.SymbolFlags.Alias ? checker.getAliasedSymbol(exportSymbol) : exportSymbol, declaration = resolved.valueDeclaration ?? resolved.getDeclarations()?.[0];
|
|
15371
|
+
if (!declaration)
|
|
15412
15372
|
continue;
|
|
15413
|
-
let
|
|
15414
|
-
|
|
15415
|
-
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
for (let spec of clause.namedBindings.elements)
|
|
15425
|
-
if ((spec.propertyName ?? spec.name).text === importName) {
|
|
15426
|
-
importSymbol = checker.getSymbolAtLocation(spec.name);
|
|
15427
|
-
break;
|
|
15428
|
-
}
|
|
15429
|
-
}
|
|
15430
|
-
if (!importSymbol && memberAccess && clause.namedBindings && typescript.isNamespaceImport(clause.namedBindings) && (importSymbol = checker.getSymbolAtLocation(clause.namedBindings.name)), importSymbol)
|
|
15431
|
-
break;
|
|
15432
|
-
}
|
|
15433
|
-
}
|
|
15434
|
-
if (!importSymbol)
|
|
15435
|
-
return;
|
|
15436
|
-
let result;
|
|
15437
|
-
function extractPropsFromJsx(node) {
|
|
15438
|
-
let sig = checker.getResolvedSignature(node);
|
|
15439
|
-
if (!sig)
|
|
15440
|
-
return;
|
|
15441
|
-
let params = sig.getParameters();
|
|
15442
|
-
return params.length === 0 ? checker.getTypeFromTypeNode(typescript.factory.createTypeLiteralNode([])) : checker.getTypeOfSymbolAtLocation(params[0], node);
|
|
15443
|
-
}
|
|
15444
|
-
function visit(node) {
|
|
15445
|
-
if (!result) {
|
|
15446
|
-
if (typescript.isJsxSelfClosingElement(node) || typescript.isJsxOpeningElement(node)) {
|
|
15447
|
-
let tagName = node.tagName;
|
|
15448
|
-
if (memberAccess) {
|
|
15449
|
-
if (typescript.isPropertyAccessExpression(tagName) && tagName.name.text === memberAccess) {
|
|
15450
|
-
let leftSym = checker.getSymbolAtLocation(tagName.expression);
|
|
15451
|
-
if (leftSym && importSymbol && leftSym === importSymbol) {
|
|
15452
|
-
let propsType = extractPropsFromJsx(node);
|
|
15453
|
-
if (propsType) {
|
|
15454
|
-
let memberSymbol = checker.getSymbolAtLocation(tagName.name) ?? checker.getTypeAtLocation(tagName.expression).getProperty(tagName.name.text) ?? resolveComponentSymbolFromNode(typescript, checker, tagName);
|
|
15455
|
-
result = {
|
|
15456
|
-
componentRef,
|
|
15457
|
-
propsType,
|
|
15458
|
-
symbol: memberSymbol ? resolveComponentSymbol(typescript, checker, memberSymbol, tagName.name) : resolveAliasedSymbol(typescript, checker, importSymbol)
|
|
15459
|
-
};
|
|
15460
|
-
return;
|
|
15461
|
-
}
|
|
15462
|
-
}
|
|
15463
|
-
}
|
|
15464
|
-
} else if (typescript.isIdentifier(tagName)) {
|
|
15465
|
-
let sym = checker.getSymbolAtLocation(tagName);
|
|
15466
|
-
if (sym && importSymbol && sym === importSymbol) {
|
|
15467
|
-
let propsType = extractPropsFromJsx(node);
|
|
15468
|
-
if (propsType) {
|
|
15469
|
-
result = {
|
|
15470
|
-
componentRef,
|
|
15471
|
-
propsType,
|
|
15472
|
-
symbol: resolveAliasedSymbol(typescript, checker, sym)
|
|
15473
|
-
};
|
|
15474
|
-
return;
|
|
15475
|
-
}
|
|
15476
|
-
}
|
|
15477
|
-
}
|
|
15478
|
-
}
|
|
15479
|
-
typescript.forEachChild(node, visit);
|
|
15373
|
+
let type = checker.getTypeOfSymbolAtLocation(resolved, declaration), isStateless = type.getCallSignatures().some((sig) => {
|
|
15374
|
+
let params = sig.getParameters();
|
|
15375
|
+
return params.length === 1 || params.length > 0 && params[0].getName() === "props";
|
|
15376
|
+
}), isStateful = type.getConstructSignatures().some(
|
|
15377
|
+
(sig) => sig.getReturnType().getProperty("props") !== void 0
|
|
15378
|
+
);
|
|
15379
|
+
if (isStateless || isStateful) {
|
|
15380
|
+
let exportName = exportSymbol.getName(), resolvedName = resolved.getName();
|
|
15381
|
+
result.set(resolvedName, exportName), exportName === "default" && result.set(fileName, "default");
|
|
15382
|
+
let displayNameValue = findDisplayNameAssignment(typescript, sourceFile, resolvedName);
|
|
15383
|
+
displayNameValue && result.set(displayNameValue, exportName);
|
|
15480
15384
|
}
|
|
15481
15385
|
}
|
|
15482
|
-
return
|
|
15386
|
+
return result;
|
|
15483
15387
|
}
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15491
|
-
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
15495
|
-
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
|
|
15388
|
+
var cachedCompilerOptions, cachedFileNames, previousProgram, parser, cachedParserOptionsKey;
|
|
15389
|
+
function invalidateParser() {
|
|
15390
|
+
parser = void 0, cachedCompilerOptions = void 0, cachedFileNames = void 0, cachedParserOptionsKey = void 0;
|
|
15391
|
+
}
|
|
15392
|
+
async function getParser5(userOptions) {
|
|
15393
|
+
let [typescript, reactDocgenTypescript] = await Promise.all([
|
|
15394
|
+
loadTypeScript(),
|
|
15395
|
+
loadReactDocgenTypescript()
|
|
15396
|
+
]), optionsKey = JSON.stringify(userOptions ?? {});
|
|
15397
|
+
if (parser && cachedParserOptionsKey !== optionsKey && (parser = void 0), !parser) {
|
|
15398
|
+
let configPath = findTsconfigPath(process.cwd());
|
|
15399
|
+
if (cachedCompilerOptions = { noErrorTruncation: !0, strict: !0 }, configPath) {
|
|
15400
|
+
let { config } = typescript.readConfigFile(configPath, typescript.sys.readFile), parsed = typescript.parseJsonConfigFileContent(
|
|
15401
|
+
config,
|
|
15402
|
+
typescript.sys,
|
|
15403
|
+
dirname5(configPath)
|
|
15404
|
+
);
|
|
15405
|
+
cachedCompilerOptions = { ...parsed.options, noErrorTruncation: !0 }, cachedFileNames = parsed.fileNames;
|
|
15406
|
+
} else
|
|
15407
|
+
logger5.warn(
|
|
15408
|
+
"No tsconfig.json (or tsconfig.base.json / tsconfig.app.json) found. TypeScript component props will not be documented by react-docgen-typescript. Create a tsconfig.json in your project root to enable automatic controls."
|
|
15409
|
+
);
|
|
15410
|
+
let program = typescript.createProgram(
|
|
15411
|
+
cachedFileNames ?? [],
|
|
15412
|
+
cachedCompilerOptions,
|
|
15413
|
+
void 0,
|
|
15414
|
+
previousProgram
|
|
15415
|
+
);
|
|
15416
|
+
previousProgram = program;
|
|
15417
|
+
let parserOptions = {
|
|
15418
|
+
shouldExtractLiteralValuesFromEnum: !0,
|
|
15419
|
+
shouldRemoveUndefinedFromOptional: !0,
|
|
15420
|
+
...userOptions,
|
|
15421
|
+
// Always force savePropValueAsString so default values are in a consistent format
|
|
15422
|
+
savePropValueAsString: !0
|
|
15423
|
+
};
|
|
15424
|
+
parser = {
|
|
15425
|
+
program,
|
|
15426
|
+
fileParser: reactDocgenTypescript.withCompilerOptions(cachedCompilerOptions, parserOptions)
|
|
15427
|
+
}, cachedParserOptionsKey = optionsKey;
|
|
15502
15428
|
}
|
|
15429
|
+
return { ...parser, typescript };
|
|
15503
15430
|
}
|
|
15504
|
-
function
|
|
15505
|
-
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15511
|
-
|
|
15512
|
-
|
|
15513
|
-
}
|
|
15514
|
-
}
|
|
15515
|
-
function getParentType(typescript, prop) {
|
|
15516
|
-
let declarations = prop.getDeclarations();
|
|
15517
|
-
if (!declarations?.length)
|
|
15518
|
-
return;
|
|
15519
|
-
let node = declarations[0].parent;
|
|
15520
|
-
for (; node; ) {
|
|
15521
|
-
if (typescript.isInterfaceDeclaration(node) || typescript.isTypeAliasDeclaration(node))
|
|
15522
|
-
return {
|
|
15523
|
-
name: node.name.getText(),
|
|
15524
|
-
fileName: node.getSourceFile().fileName
|
|
15525
|
-
};
|
|
15526
|
-
node = node.parent;
|
|
15527
|
-
}
|
|
15431
|
+
function matchComponentDoc(docs, {
|
|
15432
|
+
importName,
|
|
15433
|
+
localImportName,
|
|
15434
|
+
componentName
|
|
15435
|
+
}) {
|
|
15436
|
+
if (docs.length !== 0)
|
|
15437
|
+
return docs.length === 1 ? docs[0] : docs.find(
|
|
15438
|
+
(doc) => doc.exportName === importName || doc.exportName === localImportName || doc.displayName === importName || doc.displayName === localImportName || doc.displayName === componentName
|
|
15439
|
+
);
|
|
15528
15440
|
}
|
|
15529
|
-
function
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
|
|
15536
|
-
|
|
15537
|
-
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15544
|
-
|
|
15441
|
+
function getReactDocgenTypescriptError(path5, {
|
|
15442
|
+
importName,
|
|
15443
|
+
localImportName,
|
|
15444
|
+
componentName
|
|
15445
|
+
}, docs) {
|
|
15446
|
+
return docs.length === 0 ? {
|
|
15447
|
+
name: "react-docgen-typescript found no component docs",
|
|
15448
|
+
message: [
|
|
15449
|
+
`File: ${path5}`,
|
|
15450
|
+
"react-docgen-typescript did not return any component docs for this file."
|
|
15451
|
+
].join(`
|
|
15452
|
+
`)
|
|
15453
|
+
} : {
|
|
15454
|
+
name: "react-docgen-typescript could not match component docs",
|
|
15455
|
+
message: [
|
|
15456
|
+
`File: ${path5}`,
|
|
15457
|
+
"react-docgen-typescript returned component docs for this file, but none matched the story's component import.",
|
|
15458
|
+
`Looked for: componentName=${componentName}, localImportName=${localImportName ?? "<none>"}, importName=${importName ?? "<none>"}.`
|
|
15459
|
+
].join(`
|
|
15460
|
+
`)
|
|
15461
|
+
};
|
|
15545
15462
|
}
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
|
|
15551
|
-
(t6) => !(t6.getFlags() & typescript.TypeFlags.Undefined)
|
|
15552
|
-
), literalMembers = nonUndefinedTypes.filter(isLiteralType);
|
|
15553
|
-
if (literalMembers.length > 0 && literalMembers.length === nonUndefinedTypes.length)
|
|
15463
|
+
var parseWithReactDocgenTypescript = asyncCache(
|
|
15464
|
+
async (filePath, userOptions) => {
|
|
15465
|
+
let { program, fileParser, typescript } = await getParser5(userOptions), checker = program.getTypeChecker(), sourceFile = program.getSourceFile(filePath), docs = fileParser.parseWithProgramProvider(filePath, () => program), exportNameMap = sourceFile ? getExportNameMap(typescript, checker, sourceFile) : /* @__PURE__ */ new Map();
|
|
15466
|
+
return docs.map((doc) => {
|
|
15467
|
+
let largeNonUserSources = getLargeNonUserPropSources(doc.props);
|
|
15554
15468
|
return {
|
|
15555
|
-
|
|
15556
|
-
|
|
15557
|
-
|
|
15558
|
-
|
|
15559
|
-
|
|
15469
|
+
...doc,
|
|
15470
|
+
// Use name-based lookup: displayName is the resolved symbol name, so look it up in the
|
|
15471
|
+
// export map to get the public export name. Falls back to displayName when not aliased.
|
|
15472
|
+
exportName: exportNameMap.get(doc.displayName) ?? doc.displayName,
|
|
15473
|
+
// Filter out bulk props from non-user sources (React built-ins, DOM, CSS-in-JS system props)
|
|
15474
|
+
props: Object.fromEntries(
|
|
15475
|
+
Object.entries(doc.props).filter(([, prop]) => {
|
|
15476
|
+
let source = getPropSource(prop);
|
|
15477
|
+
return !source || !largeNonUserSources.has(source);
|
|
15478
|
+
})
|
|
15479
|
+
)
|
|
15560
15480
|
};
|
|
15561
|
-
|
|
15562
|
-
|
|
15563
|
-
}
|
|
15564
|
-
|
|
15565
|
-
|
|
15566
|
-
|
|
15567
|
-
|
|
15568
|
-
|
|
15569
|
-
|
|
15570
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
15574
|
-
|
|
15575
|
-
|
|
15481
|
+
});
|
|
15482
|
+
},
|
|
15483
|
+
{ name: "parseWithReactDocgenTypescript" }
|
|
15484
|
+
);
|
|
15485
|
+
|
|
15486
|
+
// src/componentManifest/getComponentImports.ts
|
|
15487
|
+
var baseIdentifier = (component) => component.split(".")[0] ?? component, isTypeSpecifier = (s) => t2.isImportSpecifier(s) && s.importKind === "type", importedName = (im) => t2.isIdentifier(im) ? im.name : im.value, addUniqueBy = (arr, item, eq2) => {
|
|
15488
|
+
arr.find(eq2) || arr.push(item);
|
|
15489
|
+
}, getComponents = async ({
|
|
15490
|
+
csf,
|
|
15491
|
+
storyFilePath,
|
|
15492
|
+
typescriptOptions = {},
|
|
15493
|
+
docgenEngine,
|
|
15494
|
+
additionalComponentNames = []
|
|
15495
|
+
}) => {
|
|
15496
|
+
let { reactDocgenTypescriptOptions } = typescriptOptions, program = csf._file.path, componentSet = /* @__PURE__ */ new Set(), componentDepth = /* @__PURE__ */ new Map(), localToImport = /* @__PURE__ */ new Map(), jsxDepth = 0;
|
|
15497
|
+
program.traverse({
|
|
15498
|
+
JSXElement: {
|
|
15499
|
+
enter() {
|
|
15500
|
+
jsxDepth++;
|
|
15501
|
+
},
|
|
15502
|
+
exit() {
|
|
15503
|
+
jsxDepth--;
|
|
15576
15504
|
}
|
|
15577
|
-
|
|
15578
|
-
|
|
15579
|
-
|
|
15580
|
-
|
|
15581
|
-
|
|
15582
|
-
|
|
15583
|
-
|
|
15584
|
-
|
|
15585
|
-
|
|
15586
|
-
|
|
15505
|
+
},
|
|
15506
|
+
JSXOpeningElement(p) {
|
|
15507
|
+
let n = p.node.name, name;
|
|
15508
|
+
if (t2.isJSXIdentifier(n))
|
|
15509
|
+
name = n.name, name && /[A-Z]/.test(name.charAt(0)) && componentSet.add(name);
|
|
15510
|
+
else if (t2.isJSXMemberExpression(n)) {
|
|
15511
|
+
let jsxNameToString = (nm) => t2.isJSXIdentifier(nm) ? nm.name : `${jsxNameToString(nm.object)}.${jsxNameToString(nm.property)}`;
|
|
15512
|
+
name = jsxNameToString(n), componentSet.add(name);
|
|
15513
|
+
}
|
|
15514
|
+
if (name) {
|
|
15515
|
+
let depth = jsxDepth - 1, existing = componentDepth.get(name);
|
|
15516
|
+
(existing === void 0 || depth < existing) && componentDepth.set(name, depth);
|
|
15587
15517
|
}
|
|
15588
15518
|
}
|
|
15589
|
-
}
|
|
15590
|
-
|
|
15591
|
-
|
|
15592
|
-
|
|
15593
|
-
|
|
15594
|
-
|
|
15595
|
-
|
|
15596
|
-
|
|
15597
|
-
|
|
15598
|
-
|
|
15599
|
-
|
|
15600
|
-
|
|
15601
|
-
|
|
15602
|
-
|
|
15603
|
-
|
|
15604
|
-
|
|
15605
|
-
|
|
15606
|
-
|
|
15607
|
-
|
|
15608
|
-
|
|
15609
|
-
|
|
15610
|
-
|
|
15611
|
-
|
|
15612
|
-
|
|
15613
|
-
}
|
|
15614
|
-
function collectBindingDefaults(typescript, pattern, defaults, checker) {
|
|
15615
|
-
for (let element of pattern.elements)
|
|
15616
|
-
if (element.initializer) {
|
|
15617
|
-
let propName = element.propertyName ? element.propertyName.getText() : element.name.getText();
|
|
15618
|
-
defaults.set(
|
|
15619
|
-
propName,
|
|
15620
|
-
checker ? resolveLiteralValue(typescript, checker, element.initializer) : element.initializer.getText()
|
|
15621
|
-
);
|
|
15622
|
-
}
|
|
15623
|
-
}
|
|
15624
|
-
function unwrapExpression(typescript, expression) {
|
|
15625
|
-
let current2 = expression;
|
|
15626
|
-
for (; isWrappedExpression(typescript, current2); )
|
|
15627
|
-
current2 = current2.expression;
|
|
15628
|
-
return current2;
|
|
15629
|
-
}
|
|
15630
|
-
function isPropsIdentifier(typescript, node, paramName, checker) {
|
|
15631
|
-
if (!typescript.isIdentifier(node))
|
|
15632
|
-
return !1;
|
|
15633
|
-
if (!checker)
|
|
15634
|
-
return node.text === paramName.text;
|
|
15635
|
-
let symbol = checker.getSymbolAtLocation(node), paramSymbol = checker.getSymbolAtLocation(paramName);
|
|
15636
|
-
return symbol !== void 0 && symbol === paramSymbol;
|
|
15637
|
-
}
|
|
15638
|
-
function isPropsDerivedInitializer(typescript, initializer, paramName, checker) {
|
|
15639
|
-
let expr = unwrapExpression(typescript, initializer);
|
|
15640
|
-
return isPropsIdentifier(typescript, expr, paramName, checker) ? !0 : typescript.isAwaitExpression(expr) ? isPropsDerivedInitializer(typescript, expr.expression, paramName, checker) : typescript.isBinaryExpression(expr) && [
|
|
15641
|
-
typescript.SyntaxKind.BarBarToken,
|
|
15642
|
-
typescript.SyntaxKind.QuestionQuestionToken,
|
|
15643
|
-
typescript.SyntaxKind.AmpersandAmpersandToken
|
|
15644
|
-
].includes(expr.operatorToken.kind) ? isPropsDerivedInitializer(typescript, expr.left, paramName, checker) || isPropsDerivedInitializer(typescript, expr.right, paramName, checker) : typescript.isConditionalExpression(expr) ? isPropsDerivedInitializer(typescript, expr.whenTrue, paramName, checker) || isPropsDerivedInitializer(typescript, expr.whenFalse, paramName, checker) : typescript.isCallExpression(expr) || typescript.isNewExpression(expr) ? expr.arguments?.some(
|
|
15645
|
-
(arg) => isPropsDerivedInitializer(typescript, arg, paramName, checker)
|
|
15646
|
-
) ?? !1 : !1;
|
|
15647
|
-
}
|
|
15648
|
-
function extractDestructuringDefaults(typescript, resolved, checker) {
|
|
15649
|
-
let defaults = /* @__PURE__ */ new Map(), decl = resolved.valueDeclaration;
|
|
15650
|
-
if (!decl)
|
|
15651
|
-
return defaults;
|
|
15652
|
-
let fn;
|
|
15653
|
-
if (typescript.isFunctionDeclaration(decl)) {
|
|
15654
|
-
if (fn = decl, !fn.body) {
|
|
15655
|
-
let allDecls = resolved.getDeclarations?.() ?? [];
|
|
15656
|
-
for (let d of allDecls)
|
|
15657
|
-
if (typescript.isFunctionDeclaration(d) && d.body) {
|
|
15658
|
-
fn = d;
|
|
15659
|
-
break;
|
|
15519
|
+
});
|
|
15520
|
+
let metaComp = csf._meta?.component;
|
|
15521
|
+
metaComp && componentSet.add(metaComp);
|
|
15522
|
+
for (let componentName of additionalComponentNames)
|
|
15523
|
+
componentSet.add(componentName);
|
|
15524
|
+
let components = Array.from(componentSet).sort((a, b) => a.localeCompare(b)), body = program.get("body");
|
|
15525
|
+
for (let stmt of body) {
|
|
15526
|
+
if (!stmt.isImportDeclaration())
|
|
15527
|
+
continue;
|
|
15528
|
+
let decl = stmt.node;
|
|
15529
|
+
if (decl.importKind === "type")
|
|
15530
|
+
continue;
|
|
15531
|
+
let specifiers = decl.specifiers ?? [];
|
|
15532
|
+
if (specifiers.length !== 0)
|
|
15533
|
+
for (let s of specifiers) {
|
|
15534
|
+
if (!("local" in s) || !s.local || isTypeSpecifier(s))
|
|
15535
|
+
continue;
|
|
15536
|
+
let importId = decl.source.value;
|
|
15537
|
+
if (t2.isImportDefaultSpecifier(s))
|
|
15538
|
+
localToImport.set(s.local.name, { importId, importName: "default" });
|
|
15539
|
+
else if (t2.isImportNamespaceSpecifier(s))
|
|
15540
|
+
localToImport.set(s.local.name, { importId, importName: "*" });
|
|
15541
|
+
else if (t2.isImportSpecifier(s)) {
|
|
15542
|
+
let imported = importedName(s.imported);
|
|
15543
|
+
localToImport.set(s.local.name, { importId, importName: imported });
|
|
15660
15544
|
}
|
|
15661
|
-
|
|
15662
|
-
} else typescript.isVariableDeclaration(decl) && decl.initializer ? fn = unwrapToFunction(typescript, decl.initializer, 0, checker) : typescript.isExportAssignment(decl) && decl.expression && (fn = unwrapToFunction(typescript, decl.expression, 0, checker));
|
|
15663
|
-
if (!fn)
|
|
15664
|
-
return defaults;
|
|
15665
|
-
let firstParam = fn.parameters[0];
|
|
15666
|
-
if (!firstParam)
|
|
15667
|
-
return defaults;
|
|
15668
|
-
if (typescript.isObjectBindingPattern(firstParam.name))
|
|
15669
|
-
return collectBindingDefaults(typescript, firstParam.name, defaults, checker), defaults;
|
|
15670
|
-
let propsParamName = typescript.isIdentifier(firstParam.name) ? firstParam.name : void 0;
|
|
15671
|
-
if (fn.body && propsParamName) {
|
|
15672
|
-
let body = typescript.isBlock(fn.body) ? fn.body : void 0;
|
|
15673
|
-
if (body) {
|
|
15674
|
-
for (let stmt of body.statements)
|
|
15675
|
-
if (typescript.isVariableStatement(stmt))
|
|
15676
|
-
for (let varDecl of stmt.declarationList.declarations)
|
|
15677
|
-
typescript.isObjectBindingPattern(varDecl.name) && varDecl.initializer && isPropsDerivedInitializer(typescript, varDecl.initializer, propsParamName, checker) && collectBindingDefaults(typescript, varDecl.name, defaults, checker);
|
|
15678
|
-
}
|
|
15545
|
+
}
|
|
15679
15546
|
}
|
|
15680
|
-
|
|
15681
|
-
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
|
|
15685
|
-
|
|
15686
|
-
|
|
15687
|
-
|
|
15688
|
-
let
|
|
15689
|
-
|
|
15690
|
-
|
|
15691
|
-
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
|
|
15699
|
-
|
|
15700
|
-
|
|
15701
|
-
|
|
15702
|
-
|
|
15547
|
+
let isLocallyDefinedWithoutImport = (base2) => {
|
|
15548
|
+
let binding = program.scope.getBinding(base2);
|
|
15549
|
+
return binding ? !!!(binding.path.isImportSpecifier?.() || binding.path.isImportDefaultSpecifier?.() || binding.path.isImportNamespaceSpecifier?.()) : !1;
|
|
15550
|
+
}, filteredComponents = components.filter(
|
|
15551
|
+
(c) => !isLocallyDefinedWithoutImport(baseIdentifier(c))
|
|
15552
|
+
);
|
|
15553
|
+
return (await Promise.all(
|
|
15554
|
+
filteredComponents.map(async (c) => {
|
|
15555
|
+
let depth = componentDepth.get(c), dot = c.indexOf("."), component = dot !== -1 ? (() => {
|
|
15556
|
+
let ns = c.slice(0, dot), mem = c.slice(dot + 1), direct = localToImport.get(ns);
|
|
15557
|
+
return direct ? direct.importName === "*" ? {
|
|
15558
|
+
componentName: c,
|
|
15559
|
+
localImportName: ns,
|
|
15560
|
+
importId: direct.importId,
|
|
15561
|
+
importName: mem,
|
|
15562
|
+
namespace: ns,
|
|
15563
|
+
member: mem,
|
|
15564
|
+
jsxDepth: depth
|
|
15565
|
+
} : {
|
|
15566
|
+
componentName: c,
|
|
15567
|
+
localImportName: ns,
|
|
15568
|
+
importId: direct.importId,
|
|
15569
|
+
importName: direct.importName,
|
|
15570
|
+
member: mem,
|
|
15571
|
+
jsxDepth: depth
|
|
15572
|
+
} : { componentName: c, member: mem, jsxDepth: depth };
|
|
15573
|
+
})() : (() => {
|
|
15574
|
+
let direct = localToImport.get(c);
|
|
15575
|
+
return direct ? {
|
|
15576
|
+
componentName: c,
|
|
15577
|
+
localImportName: c,
|
|
15578
|
+
importId: direct.importId,
|
|
15579
|
+
importName: direct.importName,
|
|
15580
|
+
jsxDepth: depth
|
|
15581
|
+
} : { componentName: c, jsxDepth: depth };
|
|
15582
|
+
})(), path5, isPackage = !1;
|
|
15583
|
+
try {
|
|
15584
|
+
component.importId && storyFilePath && (path5 = cachedResolveImport(matchPath(component.importId, dirname6(storyFilePath)), {
|
|
15585
|
+
basedir: dirname6(storyFilePath)
|
|
15586
|
+
}));
|
|
15587
|
+
} catch (e) {
|
|
15588
|
+
logger6.debug(e);
|
|
15589
|
+
}
|
|
15590
|
+
try {
|
|
15591
|
+
component.importId && !component.importId.startsWith(".") && storyFilePath && (cachedResolveImport(component.importId, { basedir: dirname6(storyFilePath) }), isPackage = !0);
|
|
15592
|
+
} catch {
|
|
15593
|
+
}
|
|
15594
|
+
let componentWithPackage = { ...component, isPackage };
|
|
15595
|
+
if (path5) {
|
|
15596
|
+
if (docgenEngine === "react-docgen-typescript") {
|
|
15597
|
+
let reactDocgenTypescript, reactDocgenTypescriptError;
|
|
15598
|
+
try {
|
|
15599
|
+
let docs = await parseWithReactDocgenTypescript(path5, reactDocgenTypescriptOptions);
|
|
15600
|
+
reactDocgenTypescript = matchComponentDoc(docs, component), reactDocgenTypescript || (reactDocgenTypescriptError = getReactDocgenTypescriptError(path5, component, docs));
|
|
15601
|
+
} catch (e) {
|
|
15602
|
+
let message = e instanceof Error ? e.message : String(e);
|
|
15603
|
+
logger6.debug(`react-docgen-typescript failed for ${path5}: ${message}`), reactDocgenTypescriptError = {
|
|
15604
|
+
name: "react-docgen-typescript parse error",
|
|
15605
|
+
message: `File: ${path5}
|
|
15606
|
+
${message}`
|
|
15607
|
+
};
|
|
15608
|
+
}
|
|
15609
|
+
let importOverride = reactDocgenTypescript ? getImportTag(reactDocgenTypescript) : void 0;
|
|
15610
|
+
return {
|
|
15611
|
+
...componentWithPackage,
|
|
15612
|
+
path: path5,
|
|
15613
|
+
...reactDocgenTypescript ? { reactDocgenTypescript } : {},
|
|
15614
|
+
...reactDocgenTypescriptError ? { reactDocgenTypescriptError } : {},
|
|
15615
|
+
importOverride
|
|
15616
|
+
};
|
|
15617
|
+
}
|
|
15618
|
+
if (docgenEngine === "react-docgen") {
|
|
15619
|
+
let reactDocgen = getReactDocgen(path5, componentWithPackage);
|
|
15620
|
+
return {
|
|
15621
|
+
...componentWithPackage,
|
|
15622
|
+
path: path5,
|
|
15623
|
+
reactDocgen,
|
|
15624
|
+
importOverride: reactDocgen.type === "success" ? getImportTag(reactDocgen.data) : void 0
|
|
15625
|
+
};
|
|
15626
|
+
}
|
|
15627
|
+
if (docgenEngine === "react-component-meta")
|
|
15628
|
+
return {
|
|
15629
|
+
...componentWithPackage,
|
|
15630
|
+
path: path5
|
|
15631
|
+
};
|
|
15632
|
+
}
|
|
15633
|
+
return componentWithPackage;
|
|
15634
|
+
})
|
|
15635
|
+
)).sort((a, b) => a.componentName.localeCompare(b.componentName));
|
|
15636
|
+
}, getImports = ({
|
|
15637
|
+
components,
|
|
15638
|
+
packageName
|
|
15639
|
+
}) => {
|
|
15640
|
+
let withSource = components.filter((c) => !!c.importId).map((c, idx) => {
|
|
15641
|
+
let importId = c.importId, overrideSource = (() => {
|
|
15642
|
+
if (c.importOverride)
|
|
15643
|
+
try {
|
|
15644
|
+
let src = babelParse2(c.importOverride).program.body.find((n) => t2.isImportDeclaration(n))?.source?.value;
|
|
15645
|
+
return typeof src == "string" ? src : void 0;
|
|
15646
|
+
} catch {
|
|
15647
|
+
return;
|
|
15648
|
+
}
|
|
15649
|
+
})(), rewritten = overrideSource !== void 0 ? overrideSource : (
|
|
15650
|
+
// only rewrite to the package name it the import id is not already a valid package
|
|
15651
|
+
// tsconfig paths such as ~/components/Button and components/Button are not seen as packages
|
|
15652
|
+
packageName && !c.isPackage ? packageName : importId
|
|
15653
|
+
);
|
|
15654
|
+
return { c, src: t2.stringLiteral(rewritten), key: rewritten, ord: idx };
|
|
15655
|
+
}), orderOfSource = {};
|
|
15656
|
+
for (let w of withSource)
|
|
15657
|
+
orderOfSource[w.key] === void 0 && (orderOfSource[w.key] = w.ord);
|
|
15658
|
+
let buckets = /* @__PURE__ */ new Map(), ensureBucket = (key, src) => {
|
|
15659
|
+
let prev = buckets.get(key);
|
|
15660
|
+
if (prev)
|
|
15661
|
+
return prev;
|
|
15662
|
+
let b = {
|
|
15663
|
+
source: src,
|
|
15664
|
+
defaults: [],
|
|
15665
|
+
namespaces: [],
|
|
15666
|
+
named: [],
|
|
15667
|
+
order: orderOfSource[key] ?? 0
|
|
15668
|
+
};
|
|
15669
|
+
return buckets.set(key, b), b;
|
|
15670
|
+
};
|
|
15671
|
+
for (let { c, src, key } of withSource) {
|
|
15672
|
+
let b = ensureBucket(key, src), rewritten = src.value !== c.importId, overrideSpec = (() => {
|
|
15673
|
+
if (c.importOverride)
|
|
15674
|
+
try {
|
|
15675
|
+
let decl = babelParse2(c.importOverride).program.body.find((n) => t2.isImportDeclaration(n));
|
|
15676
|
+
if (!decl)
|
|
15677
|
+
return;
|
|
15678
|
+
let spec = (decl.specifiers ?? []).find((s) => !isTypeSpecifier(s));
|
|
15679
|
+
return spec ? t2.isImportNamespaceSpecifier(spec) ? { kind: "namespace", local: spec.local.name } : t2.isImportDefaultSpecifier(spec) ? { kind: "default" } : t2.isImportSpecifier(spec) ? { kind: "named", imported: t2.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value } : void 0 : void 0;
|
|
15680
|
+
} catch {
|
|
15681
|
+
return;
|
|
15682
|
+
}
|
|
15683
|
+
})();
|
|
15684
|
+
if (overrideSpec) {
|
|
15685
|
+
if (overrideSpec.kind === "namespace") {
|
|
15686
|
+
let ns = t2.identifier(overrideSpec.local);
|
|
15687
|
+
addUniqueBy(b.namespaces, ns, (n) => n.name === ns.name);
|
|
15703
15688
|
continue;
|
|
15704
|
-
|
|
15705
|
-
|
|
15689
|
+
}
|
|
15690
|
+
if (!c.localImportName)
|
|
15691
|
+
continue;
|
|
15692
|
+
if (overrideSpec.kind === "default") {
|
|
15693
|
+
let id = t2.identifier(c.localImportName);
|
|
15694
|
+
addUniqueBy(b.defaults, id, (d) => d.name === id.name);
|
|
15695
|
+
continue;
|
|
15696
|
+
}
|
|
15697
|
+
if (overrideSpec.kind === "named") {
|
|
15698
|
+
let local = t2.identifier(c.localImportName), imported = t2.identifier(overrideSpec.imported);
|
|
15699
|
+
addUniqueBy(
|
|
15700
|
+
b.named,
|
|
15701
|
+
t2.importSpecifier(local, imported),
|
|
15702
|
+
(n) => n.local.name === local.name && importedName(n.imported) === imported.name
|
|
15703
|
+
);
|
|
15704
|
+
continue;
|
|
15705
|
+
}
|
|
15706
|
+
}
|
|
15707
|
+
if (c.namespace) {
|
|
15708
|
+
if (rewritten) {
|
|
15709
|
+
if (!c.importName)
|
|
15706
15710
|
continue;
|
|
15707
|
-
let
|
|
15708
|
-
|
|
15709
|
-
|
|
15710
|
-
|
|
15711
|
-
|
|
15712
|
-
|
|
15711
|
+
let member = c.importName, id = t2.identifier(member);
|
|
15712
|
+
addUniqueBy(
|
|
15713
|
+
b.named,
|
|
15714
|
+
t2.importSpecifier(id, id),
|
|
15715
|
+
(n) => n.local.name === member && importedName(n.imported) === member
|
|
15716
|
+
);
|
|
15717
|
+
} else {
|
|
15718
|
+
let ns = t2.identifier(c.namespace);
|
|
15719
|
+
addUniqueBy(b.namespaces, ns, (n) => n.name === ns.name);
|
|
15713
15720
|
}
|
|
15721
|
+
continue;
|
|
15714
15722
|
}
|
|
15715
|
-
if (
|
|
15716
|
-
|
|
15717
|
-
if (!typescript.isPropertyAccessExpression(left) || left.name.text !== "defaultProps")
|
|
15718
|
-
continue;
|
|
15719
|
-
let targetSymbol = checker.getSymbolAtLocation(left.expression);
|
|
15720
|
-
if (!targetSymbol || (targetSymbol.flags & typescript.SymbolFlags.Alias ? checker.getAliasedSymbol(targetSymbol) : targetSymbol) !== resolved)
|
|
15723
|
+
if (c.importName === "default") {
|
|
15724
|
+
if (!c.localImportName)
|
|
15721
15725
|
continue;
|
|
15722
|
-
|
|
15723
|
-
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
+
if (rewritten) {
|
|
15727
|
+
let id = t2.identifier(c.localImportName);
|
|
15728
|
+
addUniqueBy(
|
|
15729
|
+
b.named,
|
|
15730
|
+
t2.importSpecifier(id, id),
|
|
15731
|
+
(n) => n.local.name === id.name && importedName(n.imported) === id.name
|
|
15732
|
+
);
|
|
15733
|
+
} else {
|
|
15734
|
+
let id = t2.identifier(c.localImportName);
|
|
15735
|
+
addUniqueBy(b.defaults, id, (d) => d.name === id.name);
|
|
15726
15736
|
}
|
|
15727
|
-
|
|
15737
|
+
continue;
|
|
15738
|
+
}
|
|
15739
|
+
if (c.importName) {
|
|
15740
|
+
if (!c.localImportName)
|
|
15741
|
+
continue;
|
|
15742
|
+
let local = t2.identifier(c.localImportName), imported = t2.identifier(c.importName);
|
|
15743
|
+
addUniqueBy(
|
|
15744
|
+
b.named,
|
|
15745
|
+
t2.importSpecifier(local, imported),
|
|
15746
|
+
(n) => n.local.name === local.name && importedName(n.imported) === imported.name
|
|
15747
|
+
);
|
|
15748
|
+
continue;
|
|
15728
15749
|
}
|
|
15729
15750
|
}
|
|
15730
|
-
|
|
15731
|
-
}
|
|
15732
|
-
|
|
15733
|
-
|
|
15734
|
-
for (let
|
|
15735
|
-
|
|
15736
|
-
|
|
15737
|
-
|
|
15738
|
-
|
|
15739
|
-
|
|
15740
|
-
|
|
15741
|
-
|
|
15742
|
-
|
|
15743
|
-
|
|
15744
|
-
|
|
15745
|
-
|
|
15746
|
-
|
|
15747
|
-
|
|
15748
|
-
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
let cached2 = propSourceCache.get(prop);
|
|
15753
|
-
return cached2 === void 0 && !propSourceCache.has(prop) && (cached2 = getPropSourceFile(prop), propSourceCache.set(prop, cached2)), cached2;
|
|
15754
|
-
}, sourceCount = /* @__PURE__ */ new Map();
|
|
15755
|
-
for (let prop of properties) {
|
|
15756
|
-
let source = getSource(prop);
|
|
15757
|
-
source && (source.includes("node_modules") || source.endsWith(".d.ts")) && sourceCount.set(source, (sourceCount.get(source) ?? 0) + 1);
|
|
15751
|
+
let merged = [], printDecl = (specs, src) => {
|
|
15752
|
+
let node = t2.importDeclaration(specs, src), code = recast.print(node, {}).code;
|
|
15753
|
+
merged.push(code);
|
|
15754
|
+
}, sortedBuckets = Array.from(buckets.values()).sort((a, b) => a.order - b.order);
|
|
15755
|
+
for (let bucket of sortedBuckets) {
|
|
15756
|
+
let { source, defaults, namespaces, named } = bucket;
|
|
15757
|
+
if (!(defaults.length === 0 && namespaces.length === 0 && named.length === 0))
|
|
15758
|
+
if (namespaces.length > 0) {
|
|
15759
|
+
let firstSpecs = [];
|
|
15760
|
+
defaults[0] && firstSpecs.push(t2.importDefaultSpecifier(defaults[0])), firstSpecs.push(t2.importNamespaceSpecifier(namespaces[0])), printDecl(firstSpecs, source), named.length > 0 && printDecl(named, source);
|
|
15761
|
+
for (let d of defaults.slice(1))
|
|
15762
|
+
printDecl([t2.importDefaultSpecifier(d)], source);
|
|
15763
|
+
for (let ns of namespaces.slice(1))
|
|
15764
|
+
printDecl([t2.importNamespaceSpecifier(ns)], source);
|
|
15765
|
+
} else {
|
|
15766
|
+
if (defaults.length > 0 || named.length > 0) {
|
|
15767
|
+
let specs = [];
|
|
15768
|
+
defaults[0] && specs.push(t2.importDefaultSpecifier(defaults[0])), specs.push(...named), printDecl(specs, source);
|
|
15769
|
+
}
|
|
15770
|
+
for (let d of defaults.slice(1))
|
|
15771
|
+
printDecl([t2.importDefaultSpecifier(d)], source);
|
|
15772
|
+
}
|
|
15758
15773
|
}
|
|
15759
|
-
|
|
15760
|
-
|
|
15761
|
-
|
|
15762
|
-
|
|
15763
|
-
|
|
15764
|
-
|
|
15774
|
+
return merged;
|
|
15775
|
+
};
|
|
15776
|
+
|
|
15777
|
+
// src/componentManifest/resolveComponents.ts
|
|
15778
|
+
import { recast as recast2 } from "storybook/internal/babel";
|
|
15779
|
+
import { storyNameFromExport } from "storybook/internal/csf";
|
|
15780
|
+
import { extractDescription, loadCsf } from "storybook/internal/csf-tools";
|
|
15781
|
+
|
|
15782
|
+
// src/componentManifest/generateCodeSnippet.ts
|
|
15783
|
+
import { types as t3 } from "storybook/internal/babel";
|
|
15784
|
+
function getCodeSnippet(csf, storyName, componentName) {
|
|
15785
|
+
let storyDeclaration = csf._storyDeclarationPath[storyName], metaObj = csf._metaNode;
|
|
15786
|
+
if (!storyDeclaration) {
|
|
15787
|
+
let message = "Expected story to be a function or variable declaration";
|
|
15788
|
+
throw csf._storyPaths[storyName]?.buildCodeFrameError(message) ?? message;
|
|
15765
15789
|
}
|
|
15766
|
-
|
|
15767
|
-
|
|
15768
|
-
|
|
15769
|
-
|
|
15770
|
-
|
|
15771
|
-
|
|
15772
|
-
|
|
15773
|
-
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
|
|
15790
|
+
let storyPath;
|
|
15791
|
+
if (storyDeclaration.isFunctionDeclaration())
|
|
15792
|
+
storyPath = storyDeclaration;
|
|
15793
|
+
else if (storyDeclaration.isVariableDeclarator()) {
|
|
15794
|
+
let init = storyDeclaration.get("init");
|
|
15795
|
+
invariant(
|
|
15796
|
+
init.isExpression(),
|
|
15797
|
+
() => storyDeclaration.buildCodeFrameError("Expected story initializer to be an expression").message
|
|
15798
|
+
), storyPath = init;
|
|
15799
|
+
} else
|
|
15800
|
+
throw storyDeclaration.buildCodeFrameError(
|
|
15801
|
+
"Expected story to be a function or variable declaration"
|
|
15802
|
+
);
|
|
15803
|
+
let normalizedPath = storyPath;
|
|
15804
|
+
if (storyPath.isCallExpression()) {
|
|
15805
|
+
let callee = storyPath.get("callee");
|
|
15806
|
+
if (callee.isMemberExpression()) {
|
|
15807
|
+
let obj = callee.get("object"), prop = callee.get("property"), isBind = prop.isIdentifier() && prop.node.name === "bind" || t3.isStringLiteral(prop.node) && prop.node.value === "bind";
|
|
15808
|
+
if (obj.isIdentifier() && isBind) {
|
|
15809
|
+
let resolved = resolveIdentifierInit(storyDeclaration, obj);
|
|
15810
|
+
resolved && (normalizedPath = resolved);
|
|
15811
|
+
}
|
|
15812
|
+
}
|
|
15813
|
+
if (storyPath === normalizedPath) {
|
|
15814
|
+
let args = storyPath.get("arguments");
|
|
15815
|
+
if (args.length !== 0) {
|
|
15816
|
+
invariant(
|
|
15817
|
+
args.length === 1,
|
|
15818
|
+
() => storyPath.buildCodeFrameError("Could not evaluate story expression").message
|
|
15819
|
+
);
|
|
15820
|
+
let storyArg = args[0];
|
|
15821
|
+
invariant(
|
|
15822
|
+
storyArg.isExpression(),
|
|
15823
|
+
() => storyPath.buildCodeFrameError("Could not evaluate story expression").message
|
|
15824
|
+
), normalizedPath = storyArg;
|
|
15825
|
+
}
|
|
15826
|
+
}
|
|
15827
|
+
}
|
|
15828
|
+
normalizedPath = normalizedPath.isTSSatisfiesExpression() || normalizedPath.isTSAsExpression() ? normalizedPath.get("expression") : normalizedPath;
|
|
15829
|
+
let storyFn;
|
|
15830
|
+
if (normalizedPath.isArrowFunctionExpression() || normalizedPath.isFunctionExpression() || normalizedPath.isFunctionDeclaration())
|
|
15831
|
+
storyFn = normalizedPath;
|
|
15832
|
+
else if (!normalizedPath.isObjectExpression() && !(normalizedPath.isCallExpression() && Array.isArray(normalizedPath.node.arguments) && normalizedPath.node.arguments.length === 0))
|
|
15833
|
+
throw normalizedPath.buildCodeFrameError(
|
|
15834
|
+
"Expected story to be csf factory, function or an object expression"
|
|
15835
|
+
);
|
|
15836
|
+
let storyProps = normalizedPath.isObjectExpression() ? normalizedPath.get("properties").filter((p) => p.isObjectProperty()) : [], metaPath = pathForNode(csf._file.path, metaObj), metaProps = metaPath?.isObjectExpression() ? metaPath.get("properties").filter((p) => p.isObjectProperty()) : [], getRenderPath = (object) => {
|
|
15837
|
+
let renderPath = object.find((p) => keyOf(p.node) === "render")?.get("value");
|
|
15838
|
+
if (!renderPath)
|
|
15839
|
+
return { kind: "missing" };
|
|
15840
|
+
if (renderPath.isIdentifier()) {
|
|
15841
|
+
let resolved = resolveIdentifierInit(storyDeclaration, renderPath);
|
|
15842
|
+
return resolved && (resolved.isArrowFunctionExpression() || resolved.isFunctionExpression() || resolved.isFunctionDeclaration()) ? { kind: "resolved", path: resolved } : { kind: "unresolved" };
|
|
15843
|
+
}
|
|
15844
|
+
if (!(renderPath.isArrowFunctionExpression() || renderPath.isFunctionExpression()))
|
|
15845
|
+
throw renderPath.buildCodeFrameError(
|
|
15846
|
+
"Expected render to be an arrow function or function expression"
|
|
15847
|
+
);
|
|
15848
|
+
return { kind: "resolved", path: renderPath };
|
|
15849
|
+
}, metaRender = getRenderPath(metaProps), storyRender = getRenderPath(storyProps);
|
|
15850
|
+
storyFn || (storyFn = storyRender.kind === "resolved" ? storyRender.path : storyRender.kind === "missing" && metaRender.kind === "resolved" ? metaRender.path : void 0);
|
|
15851
|
+
let metaArgs = metaArgsRecord(metaObj ?? null), storyArgsPath = storyProps.filter((p) => keyOf(p.node) === "args").map((p) => p.get("value")).find((v) => v.isObjectExpression()), storyArgs = argsRecordFromObjectPath(storyArgsPath), storyAssignedArgsPath = storyArgsAssignmentPath(csf._file.path, storyName), storyAssignedArgs = argsRecordFromObjectPath(storyAssignedArgsPath), merged = { ...metaArgs, ...storyArgs, ...storyAssignedArgs }, entries = Object.entries(merged).filter(([k]) => k !== "children"), validEntries = entries.filter(([k, v]) => isValidJsxAttrName(k) && v != null), invalidEntries = entries.filter(([k, v]) => !isValidJsxAttrName(k) && v != null), injectedAttrs = validEntries.map(([k, v]) => toAttr(k, v)).filter((a) => a != null);
|
|
15852
|
+
if (storyFn) {
|
|
15853
|
+
let fn = storyFn.node;
|
|
15854
|
+
if (t3.isArrowFunctionExpression(fn) && (t3.isJSXElement(fn.body) || t3.isJSXFragment(fn.body))) {
|
|
15855
|
+
let spreadRes = transformArgsSpreadsInJsx(fn.body, merged), inlineRes = inlineArgsInJsx(spreadRes.node, merged);
|
|
15856
|
+
if (spreadRes.changed || inlineRes.changed) {
|
|
15857
|
+
let newFn = t3.arrowFunctionExpression([], inlineRes.node, fn.async);
|
|
15858
|
+
return t3.variableDeclaration("const", [
|
|
15859
|
+
t3.variableDeclarator(t3.identifier(storyName), newFn)
|
|
15860
|
+
]);
|
|
15861
|
+
}
|
|
15862
|
+
}
|
|
15863
|
+
let stmts = t3.isFunctionDeclaration(fn) || t3.isArrowFunctionExpression(fn) && t3.isBlockStatement(fn.body) || t3.isFunctionExpression(fn) && t3.isBlockStatement(fn.body) ? fn.body.body : void 0;
|
|
15864
|
+
if (stmts) {
|
|
15865
|
+
let changed = !1, newBody = stmts.map((stmt) => {
|
|
15866
|
+
if (t3.isReturnStatement(stmt) && stmt.argument && (t3.isJSXElement(stmt.argument) || t3.isJSXFragment(stmt.argument))) {
|
|
15867
|
+
let spreadRes = transformArgsSpreadsInJsx(stmt.argument, merged), inlineRes = inlineArgsInJsx(spreadRes.node, merged);
|
|
15868
|
+
if (spreadRes.changed || inlineRes.changed)
|
|
15869
|
+
return changed = !0, t3.returnStatement(inlineRes.node);
|
|
15870
|
+
}
|
|
15871
|
+
return stmt;
|
|
15872
|
+
});
|
|
15873
|
+
if (changed)
|
|
15874
|
+
return t3.isFunctionDeclaration(fn) ? t3.functionDeclaration(
|
|
15875
|
+
t3.identifier(storyName),
|
|
15876
|
+
[],
|
|
15877
|
+
t3.blockStatement(newBody),
|
|
15878
|
+
fn.generator,
|
|
15879
|
+
fn.async
|
|
15880
|
+
) : t3.variableDeclaration("const", [
|
|
15881
|
+
t3.variableDeclarator(
|
|
15882
|
+
t3.identifier(storyName),
|
|
15883
|
+
t3.arrowFunctionExpression([], t3.blockStatement(newBody), fn.async)
|
|
15884
|
+
)
|
|
15885
|
+
]);
|
|
15886
|
+
}
|
|
15887
|
+
return t3.isFunctionDeclaration(fn) ? t3.functionDeclaration(t3.identifier(storyName), fn.params, fn.body, fn.generator, fn.async) : t3.variableDeclaration("const", [t3.variableDeclarator(t3.identifier(storyName), fn)]);
|
|
15888
|
+
}
|
|
15889
|
+
invariant(componentName, "Could not generate snippet without component name.");
|
|
15890
|
+
let invalidSpread = buildInvalidSpread(invalidEntries), name = t3.jsxIdentifier(componentName), openingElAttrs = invalidSpread ? [...injectedAttrs, invalidSpread] : injectedAttrs, children = toJsxChildren(merged.children), selfClosing = children.length === 0, arrow = t3.arrowFunctionExpression(
|
|
15891
|
+
[],
|
|
15892
|
+
t3.jsxElement(
|
|
15893
|
+
t3.jsxOpeningElement(name, openingElAttrs, selfClosing),
|
|
15894
|
+
selfClosing ? null : t3.jsxClosingElement(name),
|
|
15895
|
+
children,
|
|
15896
|
+
selfClosing
|
|
15897
|
+
)
|
|
15898
|
+
);
|
|
15899
|
+
return t3.variableDeclaration("const", [t3.variableDeclarator(t3.identifier(storyName), arrow)]);
|
|
15777
15900
|
}
|
|
15778
|
-
function
|
|
15779
|
-
|
|
15780
|
-
|
|
15781
|
-
|
|
15782
|
-
|
|
15783
|
-
return Object.fromEntries(
|
|
15784
|
-
Object.entries(groupedTags).map(([name, grouped]) => [
|
|
15785
|
-
name,
|
|
15786
|
-
(grouped ?? []).map((tag) => typescript.displayPartsToString(tag.text ?? []).trim())
|
|
15787
|
-
])
|
|
15901
|
+
function buildInvalidSpread(entries) {
|
|
15902
|
+
if (entries.length === 0)
|
|
15903
|
+
return null;
|
|
15904
|
+
let objectProps = entries.map(
|
|
15905
|
+
([k, v]) => t3.objectProperty(t3.stringLiteral(k), t3.isExpression(v) ? v : t3.identifier("undefined"))
|
|
15788
15906
|
);
|
|
15907
|
+
return t3.jsxSpreadAttribute(t3.objectExpression(objectProps));
|
|
15789
15908
|
}
|
|
15790
|
-
|
|
15791
|
-
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
|
|
15801
|
-
let moduleSymbol = checker.getSymbolAtLocation(sourceFile), exportSymbol = moduleSymbol ? checker.getExportsOfModule(moduleSymbol).find((candidate) => candidate.getName() === exportName) : void 0, allProperties, unionForceOptional;
|
|
15802
|
-
if (isUnionType(propsType)) {
|
|
15803
|
-
let seen = /* @__PURE__ */ new Map(), forceOptional = /* @__PURE__ */ new Set(), unionMembers = propsType.types, allMemberPropSets = [];
|
|
15804
|
-
for (let member of unionMembers) {
|
|
15805
|
-
let memberPropNames = /* @__PURE__ */ new Set();
|
|
15806
|
-
for (let prop of member.getApparentProperties()) {
|
|
15807
|
-
let name = prop.getName();
|
|
15808
|
-
memberPropNames.add(name);
|
|
15809
|
-
let propType = checker.getTypeOfSymbolAtLocation(prop, contextNode), isOptional = !!(prop.flags & typescript.SymbolFlags.Optional), isDegraded = !!(propType.getFlags() & typescript.TypeFlags.Never) || !!(propType.getFlags() & typescript.TypeFlags.Undefined);
|
|
15810
|
-
(isOptional || isDegraded) && forceOptional.add(name);
|
|
15811
|
-
let existing = seen.get(name);
|
|
15812
|
-
if (!existing)
|
|
15813
|
-
seen.set(name, prop);
|
|
15814
|
-
else if (!isDegraded) {
|
|
15815
|
-
let existingType = checker.getTypeOfSymbolAtLocation(existing, contextNode);
|
|
15816
|
-
(!!(existingType.getFlags() & typescript.TypeFlags.Never) || !!(existingType.getFlags() & typescript.TypeFlags.Undefined)) && seen.set(name, prop);
|
|
15817
|
-
}
|
|
15909
|
+
var keyOf = (p) => t3.isIdentifier(p.key) ? p.key.name : t3.isStringLiteral(p.key) ? p.key.value : null, isValidJsxAttrName = (n) => /^[A-Za-z_][A-Za-z0-9_:-]*$/.test(n), argsRecordFromObjectPath = (objPath) => objPath ? Object.fromEntries(
|
|
15910
|
+
objPath.get("properties").filter((p) => p.isObjectProperty()).map((p) => [keyOf(p.node), p.get("value").node]).filter((e) => !!e[0])
|
|
15911
|
+
) : {};
|
|
15912
|
+
function storyArgsAssignmentPath(program, storyName) {
|
|
15913
|
+
let found = null;
|
|
15914
|
+
return program.traverse({
|
|
15915
|
+
AssignmentExpression(p) {
|
|
15916
|
+
let left = p.get("left"), right = p.get("right");
|
|
15917
|
+
if (left.isMemberExpression()) {
|
|
15918
|
+
let obj = left.get("object"), prop = left.get("property"), isStoryIdent = obj.isIdentifier() && obj.node.name === storyName, isArgsProp = prop.isIdentifier() && prop.node.name === "args" && !left.node.computed || t3.isStringLiteral(prop.node) && left.node.computed && prop.node.value === "args";
|
|
15919
|
+
isStoryIdent && isArgsProp && right.isObjectExpression() && (found = right);
|
|
15818
15920
|
}
|
|
15819
|
-
allMemberPropSets.push(memberPropNames);
|
|
15820
15921
|
}
|
|
15821
|
-
|
|
15822
|
-
|
|
15823
|
-
|
|
15824
|
-
|
|
15825
|
-
|
|
15826
|
-
|
|
15827
|
-
|
|
15828
|
-
|
|
15829
|
-
|
|
15830
|
-
|
|
15831
|
-
|
|
15832
|
-
|
|
15833
|
-
|
|
15834
|
-
|
|
15922
|
+
}), found;
|
|
15923
|
+
}
|
|
15924
|
+
var argsRecordFromObjectNode = (obj) => obj ? Object.fromEntries(
|
|
15925
|
+
obj.properties.filter((p) => t3.isObjectProperty(p)).map((p) => [keyOf(p), p.value]).filter((e) => !!e[0])
|
|
15926
|
+
) : {}, metaArgsRecord = (meta) => {
|
|
15927
|
+
if (!meta)
|
|
15928
|
+
return {};
|
|
15929
|
+
let argsProp = meta.properties.find(
|
|
15930
|
+
(p) => t3.isObjectProperty(p) && keyOf(p) === "args"
|
|
15931
|
+
);
|
|
15932
|
+
return argsProp && t3.isObjectExpression(argsProp.value) ? argsRecordFromObjectNode(argsProp.value) : {};
|
|
15933
|
+
}, toAttr = (key, value) => t3.isBooleanLiteral(value) ? value.value ? t3.jsxAttribute(t3.jsxIdentifier(key), null) : t3.jsxAttribute(t3.jsxIdentifier(key), t3.jsxExpressionContainer(value)) : t3.isStringLiteral(value) ? t3.jsxAttribute(t3.jsxIdentifier(key), t3.stringLiteral(value.value)) : t3.isExpression(value) ? t3.jsxAttribute(t3.jsxIdentifier(key), t3.jsxExpressionContainer(value)) : null, toJsxChildren = (node) => node ? t3.isStringLiteral(node) ? [t3.jsxText(node.value)] : t3.isJSXElement(node) || t3.isJSXFragment(node) ? [node] : t3.isExpression(node) ? [t3.jsxExpressionContainer(node)] : [] : [];
|
|
15934
|
+
function getArgsMemberKey(expr) {
|
|
15935
|
+
if (t3.isMemberExpression(expr) && t3.isIdentifier(expr.object) && expr.object.name === "args") {
|
|
15936
|
+
if (t3.isIdentifier(expr.property) && !expr.computed)
|
|
15937
|
+
return expr.property.name;
|
|
15938
|
+
if (t3.isStringLiteral(expr.property) && expr.computed)
|
|
15939
|
+
return expr.property.value;
|
|
15835
15940
|
}
|
|
15836
|
-
|
|
15837
|
-
|
|
15838
|
-
|
|
15839
|
-
|
|
15840
|
-
|
|
15841
|
-
|
|
15842
|
-
continue;
|
|
15843
|
-
let item = extractPropItem(typescript, checker, prop, contextNode, defaultsMap);
|
|
15844
|
-
unionForceOptional?.has(prop.getName()) && (item.required = !1), props[prop.getName()] = item;
|
|
15941
|
+
if (t3.isOptionalMemberExpression?.(expr) && t3.isIdentifier(expr.object) && expr.object.name === "args") {
|
|
15942
|
+
let prop = expr.property;
|
|
15943
|
+
if (t3.isIdentifier(prop) && !expr.computed)
|
|
15944
|
+
return prop.name;
|
|
15945
|
+
if (t3.isStringLiteral(prop) && expr.computed)
|
|
15946
|
+
return prop.value;
|
|
15845
15947
|
}
|
|
15846
|
-
|
|
15847
|
-
exportSymbol,
|
|
15848
|
-
resolvedSymbol: resolved
|
|
15849
|
-
}) ?? displayNameOverride, description = typescript.displayPartsToString(resolved.getDocumentationComment(checker)), selectedJsDocTags = extractComponentJsDocTags(typescript, checker, resolved), exportResolved = exportSymbol && exportSymbol !== resolved ? resolveAliasedSymbol(typescript, checker, exportSymbol) : void 0, exportJsDocTags = exportResolved ? extractComponentJsDocTags(typescript, checker, exportResolved) : void 0, jsDocTags = selectedJsDocTags?.import || !exportJsDocTags?.import ? selectedJsDocTags : {
|
|
15850
|
-
...selectedJsDocTags ?? {},
|
|
15851
|
-
import: exportJsDocTags.import
|
|
15852
|
-
};
|
|
15853
|
-
return {
|
|
15854
|
-
displayName,
|
|
15855
|
-
exportName,
|
|
15856
|
-
filePath,
|
|
15857
|
-
description,
|
|
15858
|
-
jsDocTags,
|
|
15859
|
-
props
|
|
15860
|
-
};
|
|
15948
|
+
return null;
|
|
15861
15949
|
}
|
|
15862
|
-
function
|
|
15863
|
-
|
|
15864
|
-
|
|
15865
|
-
|
|
15866
|
-
|
|
15867
|
-
|
|
15868
|
-
|
|
15869
|
-
|
|
15870
|
-
|
|
15871
|
-
|
|
15872
|
-
|
|
15873
|
-
|
|
15874
|
-
|
|
15875
|
-
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
|
|
15879
|
-
|
|
15880
|
-
|
|
15881
|
-
|
|
15950
|
+
function inlineArgsInJsx(node, merged) {
|
|
15951
|
+
let changed = !1;
|
|
15952
|
+
if (t3.isJSXElement(node)) {
|
|
15953
|
+
let opening = node.openingElement, newAttrs = opening.attributes.flatMap((a) => {
|
|
15954
|
+
if (!t3.isJSXAttribute(a))
|
|
15955
|
+
return [a];
|
|
15956
|
+
let name = t3.isJSXIdentifier(a.name) ? a.name.name : null;
|
|
15957
|
+
if (!(name && a.value && t3.isJSXExpressionContainer(a.value)))
|
|
15958
|
+
return [a];
|
|
15959
|
+
let key = getArgsMemberKey(a.value.expression);
|
|
15960
|
+
if (!(key && key in merged))
|
|
15961
|
+
return [a];
|
|
15962
|
+
let repl = toAttr(name, merged[key]);
|
|
15963
|
+
return changed = !0, repl ? [repl] : [];
|
|
15964
|
+
}), newChildren = node.children.flatMap((c) => {
|
|
15965
|
+
if (t3.isJSXElement(c) || t3.isJSXFragment(c)) {
|
|
15966
|
+
let res = inlineArgsInJsx(c, merged);
|
|
15967
|
+
return changed ||= res.changed, [res.node];
|
|
15968
|
+
}
|
|
15969
|
+
return t3.isJSXExpressionContainer(c) && getArgsMemberKey(c.expression) === "children" && merged.children ? (changed = !0, toJsxChildren(merged.children)) : [c];
|
|
15970
|
+
}), selfClosing = opening.selfClosing && newChildren.length === 0;
|
|
15971
|
+
return {
|
|
15972
|
+
node: t3.jsxElement(
|
|
15973
|
+
t3.jsxOpeningElement(opening.name, newAttrs, selfClosing),
|
|
15974
|
+
selfClosing ? null : node.closingElement ?? t3.jsxClosingElement(opening.name),
|
|
15975
|
+
newChildren,
|
|
15976
|
+
selfClosing
|
|
15977
|
+
),
|
|
15978
|
+
changed
|
|
15979
|
+
};
|
|
15882
15980
|
}
|
|
15883
|
-
let
|
|
15884
|
-
|
|
15885
|
-
|
|
15886
|
-
|
|
15887
|
-
if (!firstParam)
|
|
15888
|
-
return defaults;
|
|
15889
|
-
if (typescript.isObjectBindingPattern(firstParam.name))
|
|
15890
|
-
collectBindingDefaults(typescript, firstParam.name, defaults);
|
|
15891
|
-
else if (fn.body) {
|
|
15892
|
-
let propsParamName = typescript.isIdentifier(firstParam.name) ? firstParam.name : void 0, body = typescript.isBlock(fn.body) ? fn.body : void 0;
|
|
15893
|
-
if (body && propsParamName) {
|
|
15894
|
-
for (let stmt of body.statements)
|
|
15895
|
-
if (typescript.isVariableStatement(stmt))
|
|
15896
|
-
for (let varDecl of stmt.declarationList.declarations)
|
|
15897
|
-
typescript.isObjectBindingPattern(varDecl.name) && varDecl.initializer && isPropsDerivedInitializer(typescript, varDecl.initializer, propsParamName) && collectBindingDefaults(typescript, varDecl.name, defaults);
|
|
15981
|
+
let fragChildren = node.children.flatMap((c) => {
|
|
15982
|
+
if (t3.isJSXElement(c) || t3.isJSXFragment(c)) {
|
|
15983
|
+
let res = inlineArgsInJsx(c, merged);
|
|
15984
|
+
return changed ||= res.changed, [res.node];
|
|
15898
15985
|
}
|
|
15899
|
-
|
|
15900
|
-
|
|
15986
|
+
return t3.isJSXExpressionContainer(c) && getArgsMemberKey(c.expression) === "children" && "children" in merged ? (changed = !0, toJsxChildren(merged.children)) : [c];
|
|
15987
|
+
});
|
|
15988
|
+
return { node: t3.jsxFragment(node.openingFragment, node.closingFragment, fragChildren), changed };
|
|
15901
15989
|
}
|
|
15902
|
-
function
|
|
15903
|
-
|
|
15904
|
-
|
|
15905
|
-
|
|
15906
|
-
|
|
15907
|
-
|
|
15990
|
+
function transformArgsSpreadsInJsx(node, merged) {
|
|
15991
|
+
let changed = !1, makeInjectedPieces = (existing) => {
|
|
15992
|
+
let entries = Object.entries(merged).filter(([k, v]) => v != null && k !== "children"), validEntries = entries.filter(([k]) => isValidJsxAttrName(k)), invalidEntries = entries.filter(([k]) => !isValidJsxAttrName(k)), injectedAttrs = validEntries.map(([k, v]) => toAttr(k, v)).filter((a) => !!a).filter((a) => t3.isJSXIdentifier(a.name) && !existing.has(a.name.name)), invalidSpread = buildInvalidSpread(invalidEntries.filter(([k]) => !existing.has(k)));
|
|
15993
|
+
return invalidSpread ? [...injectedAttrs, invalidSpread] : injectedAttrs;
|
|
15994
|
+
};
|
|
15995
|
+
if (t3.isJSXElement(node)) {
|
|
15996
|
+
let opening = node.openingElement, attrs = opening.attributes, isArgsSpread = (a) => t3.isJSXSpreadAttribute(a) && t3.isIdentifier(a.argument) && a.argument.name === "args", sawArgsSpread = attrs.some(isArgsSpread), firstIdx = attrs.findIndex(isArgsSpread), nonArgsAttrs = attrs.filter((a) => !isArgsSpread(a)), insertionIndex = sawArgsSpread ? attrs.slice(0, firstIdx).filter((a) => !isArgsSpread(a)).length : 0, newAttrs = sawArgsSpread ? (() => {
|
|
15997
|
+
let existing = new Set(
|
|
15998
|
+
nonArgsAttrs.filter((a) => t3.isJSXAttribute(a)).flatMap((a) => t3.isJSXIdentifier(a.name) ? [a.name.name] : [])
|
|
15999
|
+
), pieces = makeInjectedPieces(existing);
|
|
16000
|
+
return changed = !0, [
|
|
16001
|
+
...nonArgsAttrs.slice(0, insertionIndex),
|
|
16002
|
+
...pieces,
|
|
16003
|
+
...nonArgsAttrs.slice(insertionIndex)
|
|
16004
|
+
];
|
|
16005
|
+
})() : nonArgsAttrs, newChildren = node.children.flatMap((c) => {
|
|
16006
|
+
if (t3.isJSXElement(c) || t3.isJSXFragment(c)) {
|
|
16007
|
+
let res = transformArgsSpreadsInJsx(c, merged);
|
|
16008
|
+
return changed ||= res.changed, [res.node];
|
|
16009
|
+
}
|
|
16010
|
+
return [c];
|
|
16011
|
+
}), children = sawArgsSpread && newChildren.length === 0 && merged.children ? (changed = !0, toJsxChildren(merged.children)) : newChildren, selfClosing = children.length === 0;
|
|
16012
|
+
return {
|
|
16013
|
+
node: t3.jsxElement(
|
|
16014
|
+
t3.jsxOpeningElement(opening.name, newAttrs, selfClosing),
|
|
16015
|
+
selfClosing ? null : node.closingElement ?? t3.jsxClosingElement(opening.name),
|
|
16016
|
+
children,
|
|
16017
|
+
selfClosing
|
|
16018
|
+
),
|
|
16019
|
+
changed
|
|
16020
|
+
};
|
|
16021
|
+
}
|
|
16022
|
+
let fragChildren = node.children.flatMap((c) => {
|
|
16023
|
+
if (t3.isJSXElement(c) || t3.isJSXFragment(c)) {
|
|
16024
|
+
let res = transformArgsSpreadsInJsx(c, merged);
|
|
16025
|
+
return changed ||= res.changed, [res.node];
|
|
16026
|
+
}
|
|
16027
|
+
return [c];
|
|
16028
|
+
});
|
|
16029
|
+
return { node: t3.jsxFragment(node.openingFragment, node.closingFragment, fragChildren), changed };
|
|
15908
16030
|
}
|
|
15909
|
-
function
|
|
15910
|
-
let
|
|
15911
|
-
|
|
15912
|
-
|
|
15913
|
-
|
|
15914
|
-
|
|
16031
|
+
function resolveIdentifierInit(storyPath, identifier) {
|
|
16032
|
+
let programPath = storyPath.findParent((p) => p.isProgram());
|
|
16033
|
+
if (!programPath)
|
|
16034
|
+
return null;
|
|
16035
|
+
for (let stmt of programPath.get("body")) {
|
|
16036
|
+
if (stmt.isFunctionDeclaration() && stmt.node.id?.name === identifier.node.name)
|
|
16037
|
+
return stmt;
|
|
16038
|
+
if (stmt.isExportNamedDeclaration()) {
|
|
16039
|
+
let decl = stmt.get("declaration");
|
|
16040
|
+
if (decl.isFunctionDeclaration() && decl.node.id?.name === identifier.node.name)
|
|
16041
|
+
return decl;
|
|
15915
16042
|
}
|
|
15916
|
-
|
|
15917
|
-
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
|
|
15922
|
-
if (
|
|
15923
|
-
|
|
16043
|
+
}
|
|
16044
|
+
let match = programPath.get("body").flatMap((stmt) => {
|
|
16045
|
+
if (stmt.isVariableDeclaration())
|
|
16046
|
+
return stmt.get("declarations");
|
|
16047
|
+
if (stmt.isExportNamedDeclaration()) {
|
|
16048
|
+
let decl = stmt.get("declaration");
|
|
16049
|
+
if (decl && decl.isVariableDeclaration())
|
|
16050
|
+
return decl.get("declarations");
|
|
15924
16051
|
}
|
|
15925
|
-
|
|
15926
|
-
|
|
15927
|
-
|
|
15928
|
-
|
|
15929
|
-
|
|
15930
|
-
|
|
15931
|
-
|
|
15932
|
-
|
|
15933
|
-
|
|
15934
|
-
|
|
15935
|
-
|
|
15936
|
-
|
|
16052
|
+
return [];
|
|
16053
|
+
}).find((d) => {
|
|
16054
|
+
let id = d.get("id");
|
|
16055
|
+
return id.isIdentifier() && id.node.name === identifier.node.name;
|
|
16056
|
+
});
|
|
16057
|
+
if (!match)
|
|
16058
|
+
return null;
|
|
16059
|
+
let init = match.get("init");
|
|
16060
|
+
return init && init.isExpression() ? init : null;
|
|
16061
|
+
}
|
|
16062
|
+
function pathForNode(program, target) {
|
|
16063
|
+
if (!target)
|
|
16064
|
+
return;
|
|
16065
|
+
let found;
|
|
16066
|
+
return program.traverse({
|
|
16067
|
+
enter(p) {
|
|
16068
|
+
p.node && p.node === target && (found = p, p.stop());
|
|
15937
16069
|
}
|
|
16070
|
+
}), found;
|
|
16071
|
+
}
|
|
16072
|
+
|
|
16073
|
+
// src/componentManifest/subcomponents.ts
|
|
16074
|
+
import { types as t4 } from "storybook/internal/babel";
|
|
16075
|
+
function findExactComponentMatch(components, componentName) {
|
|
16076
|
+
if (componentName)
|
|
16077
|
+
return components.find((component) => component.componentName === componentName);
|
|
16078
|
+
}
|
|
16079
|
+
function extractDeclaredSubcomponents(csf) {
|
|
16080
|
+
let rawSubcomponents = unwrapSubcomponentNode(
|
|
16081
|
+
csf._metaAnnotations.subcomponents,
|
|
16082
|
+
csf._ast.program
|
|
16083
|
+
);
|
|
16084
|
+
return !rawSubcomponents || !t4.isObjectExpression(rawSubcomponents) ? [] : rawSubcomponents.properties.flatMap((property) => {
|
|
16085
|
+
if (!t4.isObjectProperty(property))
|
|
16086
|
+
return [];
|
|
16087
|
+
let name = getObjectKeyName(property.key), directComponentName = getComponentExpressionName(property.value), componentExpression = unwrapSubcomponentNode(property.value, csf._ast.program), componentName = getComponentExpressionName(componentExpression) ?? directComponentName;
|
|
16088
|
+
return name && componentName ? [{ name, componentName }] : [];
|
|
16089
|
+
});
|
|
16090
|
+
}
|
|
16091
|
+
function findVariableInitialization(identifier, program) {
|
|
16092
|
+
for (let node of program.body) {
|
|
16093
|
+
let declaration = (t4.isVariableDeclaration(node) ? node.declarations : t4.isExportNamedDeclaration(node) && t4.isVariableDeclaration(node.declaration) ? node.declaration.declarations : void 0)?.find(
|
|
16094
|
+
(decl) => t4.isVariableDeclarator(decl) && t4.isIdentifier(decl.id) && decl.id.name === identifier
|
|
16095
|
+
);
|
|
16096
|
+
if (declaration?.init && t4.isExpression(declaration.init))
|
|
16097
|
+
return declaration.init;
|
|
15938
16098
|
}
|
|
15939
|
-
if (targetExpr || (targetExpr = varMap.get(exportName)), !!targetExpr)
|
|
15940
|
-
return unwrapToFunctionAST(typescript, targetExpr, varMap, 0);
|
|
15941
16099
|
}
|
|
15942
|
-
function
|
|
15943
|
-
|
|
15944
|
-
|
|
15945
|
-
|
|
15946
|
-
|
|
15947
|
-
|
|
15948
|
-
|
|
15949
|
-
|
|
15950
|
-
if (typescript.isPropertyAccessExpression(callee) && typescript.isIdentifier(callee.expression) && callee.expression.text === "Object" && callee.name.text === "assign" && node.arguments.length >= 1 || node.arguments.length >= 1)
|
|
15951
|
-
return unwrapToFunctionAST(typescript, node.arguments[0], varMap, depth + 1);
|
|
16100
|
+
function unwrapSubcomponentNode(node, program, visitedIdentifiers = /* @__PURE__ */ new Set()) {
|
|
16101
|
+
let current2 = node;
|
|
16102
|
+
for (; current2; ) {
|
|
16103
|
+
if (t4.isIdentifier(current2)) {
|
|
16104
|
+
if (visitedIdentifiers.has(current2.name))
|
|
16105
|
+
return;
|
|
16106
|
+
visitedIdentifiers.add(current2.name), current2 = findVariableInitialization(current2.name, program);
|
|
16107
|
+
continue;
|
|
15952
16108
|
}
|
|
15953
|
-
if (
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
return unwrapToFunctionAST(typescript, init, varMap, depth + 1);
|
|
16109
|
+
if (t4.isParenthesizedExpression(current2) || t4.isTSAsExpression(current2) || t4.isTSSatisfiesExpression(current2) || t4.isTSNonNullExpression(current2)) {
|
|
16110
|
+
current2 = current2.expression;
|
|
16111
|
+
continue;
|
|
15957
16112
|
}
|
|
16113
|
+
return current2;
|
|
15958
16114
|
}
|
|
15959
16115
|
}
|
|
15960
|
-
function
|
|
15961
|
-
|
|
15962
|
-
|
|
15963
|
-
|
|
16116
|
+
function getObjectKeyName(key) {
|
|
16117
|
+
if (t4.isIdentifier(key))
|
|
16118
|
+
return key.name;
|
|
16119
|
+
if (t4.isStringLiteral(key))
|
|
16120
|
+
return key.value;
|
|
15964
16121
|
}
|
|
15965
|
-
function
|
|
15966
|
-
|
|
16122
|
+
function getComponentExpressionName(node) {
|
|
16123
|
+
if (node) {
|
|
16124
|
+
if (t4.isIdentifier(node))
|
|
16125
|
+
return node.name;
|
|
16126
|
+
if (t4.isMemberExpression(node) && !node.computed) {
|
|
16127
|
+
let objectName = getComponentExpressionName(node.object), propertyName = getComponentExpressionName(node.property);
|
|
16128
|
+
return objectName && propertyName ? `${objectName}.${propertyName}` : void 0;
|
|
16129
|
+
}
|
|
16130
|
+
}
|
|
15967
16131
|
}
|
|
15968
16132
|
|
|
15969
|
-
// src/componentManifest/
|
|
15970
|
-
|
|
15971
|
-
|
|
15972
|
-
|
|
15973
|
-
|
|
15974
|
-
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
|
|
15983
|
-
|
|
15984
|
-
(fileName, includeFsFiles) => {
|
|
15985
|
-
if (!includeFsFiles)
|
|
15986
|
-
return;
|
|
15987
|
-
let cache = fsFileSnapshots.get(fileName), modifiedTime = typescript.sys.getModifiedTime?.(fileName)?.valueOf();
|
|
15988
|
-
if (!cache || cache[0] !== modifiedTime)
|
|
15989
|
-
if (typescript.sys.fileExists(fileName)) {
|
|
15990
|
-
let text = typescript.sys.readFile(fileName), snapshot2 = text !== void 0 ? typescript.ScriptSnapshot.fromString(text) : void 0;
|
|
15991
|
-
fsFileSnapshots.set(fileName, [modifiedTime, snapshot2]);
|
|
15992
|
-
} else
|
|
15993
|
-
fsFileSnapshots.set(fileName, [modifiedTime, void 0]);
|
|
15994
|
-
let snapshot = fsFileSnapshots.get(fileName)?.[1];
|
|
15995
|
-
snapshot ? language.scripts.set(fileName, snapshot) : language.scripts.delete(fileName);
|
|
15996
|
-
}
|
|
15997
|
-
), projectHost = {
|
|
15998
|
-
getCurrentDirectory: () => configFileName ? path2.dirname(configFileName) : commandLine.options.rootDir ?? process.cwd(),
|
|
15999
|
-
getCompilationSettings: () => this.commandLine.options,
|
|
16000
|
-
getProjectReferences: () => this.commandLine.projectReferences,
|
|
16001
|
-
getProjectVersion: () => (this.checkRootFilesUpdate(), this.projectVersion.toString()),
|
|
16002
|
-
getScriptFileNames: () => (this.checkRootFilesUpdate(), this.commandLine.fileNames)
|
|
16003
|
-
}, { languageServiceHost } = (0, import_typescript.createLanguageServiceHost)(
|
|
16004
|
-
typescript,
|
|
16005
|
-
typescript.sys,
|
|
16006
|
-
language,
|
|
16007
|
-
(s) => s,
|
|
16008
|
-
// asScriptId — identity for React (no URI mapping needed)
|
|
16009
|
-
projectHost
|
|
16010
|
-
);
|
|
16011
|
-
this.ls = typescript.createLanguageService(languageServiceHost);
|
|
16012
|
-
}
|
|
16013
|
-
getCommandLine() {
|
|
16014
|
-
return this.commandLine;
|
|
16015
|
-
}
|
|
16016
|
-
dispose() {
|
|
16017
|
-
clearTimeout(this.warmupTimer), this.ls.dispose();
|
|
16018
|
-
}
|
|
16019
|
-
// ---------------------------------------------------------------------------
|
|
16020
|
-
// Project management
|
|
16021
|
-
// ---------------------------------------------------------------------------
|
|
16022
|
-
/**
|
|
16023
|
-
* Batch-add multiple files to the project in one go. Only bumps projectVersion once, avoiding
|
|
16024
|
-
* repeated program rebuilds.
|
|
16025
|
-
*/
|
|
16026
|
-
ensureFiles(fileNames) {
|
|
16027
|
-
let added = !1;
|
|
16028
|
-
for (let fileName of fileNames)
|
|
16029
|
-
this.commandLine.fileNames.includes(fileName) || (this.commandLine.fileNames.push(fileName), added = !0);
|
|
16030
|
-
added && this.projectVersion++;
|
|
16031
|
-
}
|
|
16032
|
-
/**
|
|
16033
|
-
* Adapted from:
|
|
16034
|
-
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L436-L447
|
|
16035
|
-
*/
|
|
16036
|
-
checkRootFilesUpdate() {
|
|
16037
|
-
if (!this.shouldCheckRootFiles || (this.shouldCheckRootFiles = !1, !this.getCommandLineFn))
|
|
16038
|
-
return;
|
|
16039
|
-
let newCommandLine = this.getCommandLineFn();
|
|
16040
|
-
arrayItemsEqual(newCommandLine.fileNames, this.commandLine.fileNames) || (this.commandLine.fileNames = newCommandLine.fileNames, this.projectVersion++);
|
|
16041
|
-
}
|
|
16042
|
-
hasSourceFile(fileName) {
|
|
16043
|
-
return !!this.ls.getProgram()?.getSourceFile(fileName);
|
|
16044
|
-
}
|
|
16045
|
-
/**
|
|
16046
|
-
* Get all non-node_modules source file paths from the TS program. Used by ComponentMetaManager to
|
|
16047
|
-
* watch directories for file changes.
|
|
16048
|
-
*/
|
|
16049
|
-
getSourceFilePaths() {
|
|
16050
|
-
let program = this.ls.getProgram();
|
|
16051
|
-
return program ? program.getSourceFiles().map((sf) => sf.fileName.replace(/\\/g, "/")).filter((f) => !f.includes("node_modules")) : [];
|
|
16052
|
-
}
|
|
16053
|
-
/**
|
|
16054
|
-
* Adapted from:
|
|
16055
|
-
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L409-L432
|
|
16056
|
-
*
|
|
16057
|
-
* Created events only set shouldCheckRootFiles (version bump happens in checkRootFilesUpdate if
|
|
16058
|
-
* the file list actually changed). Deleted/created break early since they trigger a full config
|
|
16059
|
-
* reparse — processing remaining changes is unnecessary.
|
|
16060
|
-
*/
|
|
16061
|
-
onFilesChanged(changes) {
|
|
16062
|
-
for (let { filePath } of changes)
|
|
16063
|
-
this.fsFileSnapshots.delete(filePath);
|
|
16064
|
-
let oldVersion = this.projectVersion, program = this.ls.getProgram();
|
|
16065
|
-
for (let { filePath, type } of changes)
|
|
16066
|
-
if (type === "changed")
|
|
16067
|
-
program?.getSourceFile(filePath) && this.projectVersion++;
|
|
16068
|
-
else if (type === "deleted") {
|
|
16069
|
-
program?.getSourceFile(filePath) && this.projectVersion++, this.shouldCheckRootFiles = !0;
|
|
16070
|
-
break;
|
|
16071
|
-
} else if (type === "created") {
|
|
16072
|
-
this.shouldCheckRootFiles = !0;
|
|
16073
|
-
break;
|
|
16074
|
-
}
|
|
16075
|
-
this.projectVersion !== oldVersion && this.entries.length > 0 && (clearTimeout(this.warmupTimer), this.warmupTimer = setTimeout(() => {
|
|
16076
|
-
try {
|
|
16077
|
-
this.extractPropsFromStories(this.entries);
|
|
16078
|
-
} catch {
|
|
16079
|
-
}
|
|
16080
|
-
}, 100), this.warmupTimer?.unref?.());
|
|
16081
|
-
}
|
|
16082
|
-
// ---------------------------------------------------------------------------
|
|
16083
|
-
// Primary extraction method — probe-free
|
|
16084
|
-
// ---------------------------------------------------------------------------
|
|
16085
|
-
extractPropsFromStories(entries) {
|
|
16086
|
-
this.entries = entries;
|
|
16087
|
-
let allFiles = entries.flatMap(
|
|
16088
|
-
(entry) => entry.component?.path ? [entry.storyPath, entry.component.path] : [entry.storyPath]
|
|
16089
|
-
);
|
|
16090
|
-
this.ensureFiles(allFiles), this.ensureFresh(allFiles);
|
|
16091
|
-
let program = this.ls.getProgram();
|
|
16092
|
-
if (!program)
|
|
16093
|
-
return;
|
|
16094
|
-
let checker = program.getTypeChecker(), serializationContextByComponentPath = /* @__PURE__ */ new Map();
|
|
16095
|
-
for (let entry of entries)
|
|
16096
|
-
try {
|
|
16097
|
-
let storySourceFile = program.getSourceFile(entry.storyPath), entryComponent = entry.component, componentPath = entryComponent?.path, exportName = entryComponent?.importName;
|
|
16098
|
-
if (!storySourceFile || !componentPath || !exportName || !entryComponent)
|
|
16099
|
-
continue;
|
|
16100
|
-
let importId = entryComponent.importId, isPackageImport = importId && !importId.startsWith("."), componentSourceFile;
|
|
16101
|
-
if (isPackageImport) {
|
|
16102
|
-
let resolved = this.typescript.resolveModuleName(
|
|
16103
|
-
importId,
|
|
16104
|
-
entry.storyPath,
|
|
16105
|
-
this.commandLine.options,
|
|
16106
|
-
this.typescript.sys
|
|
16107
|
-
);
|
|
16108
|
-
componentSourceFile = resolved.resolvedModule ? program.getSourceFile(resolved.resolvedModule.resolvedFileName) : program.getSourceFile(componentPath);
|
|
16109
|
-
} else
|
|
16110
|
-
componentSourceFile = program.getSourceFile(componentPath);
|
|
16111
|
-
if (!componentSourceFile)
|
|
16112
|
-
continue;
|
|
16113
|
-
let resolvedComponent;
|
|
16114
|
-
if (importId && (resolvedComponent = resolvePropsFromStoryFile(
|
|
16115
|
-
this.typescript,
|
|
16116
|
-
checker,
|
|
16117
|
-
storySourceFile,
|
|
16118
|
-
entryComponent
|
|
16119
|
-
)), resolvedComponent || (resolvedComponent = this.resolveFromMetaComponent(
|
|
16120
|
-
checker,
|
|
16121
|
-
storySourceFile,
|
|
16122
|
-
entryComponent
|
|
16123
|
-
)), !resolvedComponent)
|
|
16124
|
-
continue;
|
|
16125
|
-
let serializationContext = serializationContextByComponentPath.get(componentPath);
|
|
16126
|
-
if (serializationContext === void 0) {
|
|
16127
|
-
let resolvedFileName = componentSourceFile.fileName;
|
|
16128
|
-
serializationContext = {
|
|
16129
|
-
sourceFile: componentSourceFile,
|
|
16130
|
-
defaultsSourcePath: resolvedFileName.endsWith(".d.ts") || resolvedFileName.endsWith(".d.mts") || resolvedFileName.endsWith(".d.cts") ? componentPath : void 0
|
|
16131
|
-
}, serializationContextByComponentPath.set(componentPath, serializationContext);
|
|
16132
|
-
}
|
|
16133
|
-
let doc = serializeComponentDoc(this.typescript, checker, {
|
|
16134
|
-
sourceFile: serializationContext.sourceFile,
|
|
16135
|
-
resolvedComponent,
|
|
16136
|
-
defaultsSourcePath: serializationContext.defaultsSourcePath
|
|
16137
|
-
});
|
|
16138
|
-
doc && (entryComponent.reactComponentMeta = doc, entryComponent.componentJsDocTags = doc.jsDocTags, entryComponent.importOverride = entryComponent.componentJsDocTags?.import?.[0]?.trim());
|
|
16139
|
-
} catch {
|
|
16140
|
-
continue;
|
|
16141
|
-
}
|
|
16142
|
-
}
|
|
16143
|
-
/**
|
|
16144
|
-
* Check mtime for specific files and bump projectVersion if any changed.
|
|
16145
|
-
*
|
|
16146
|
-
* This bypasses the sync() gate in createLanguageServiceHost — sync() only runs when
|
|
16147
|
-
* projectVersion changes, so mtime-based cache alone can't detect stale files. We do a targeted
|
|
16148
|
-
* mtime check for the files we're about to extract from, ensuring freshness even when the
|
|
16149
|
-
* fs.watch event hasn't arrived yet (race with HMR) or was missed entirely.
|
|
16150
|
-
*/
|
|
16151
|
-
ensureFresh(fileNames) {
|
|
16152
|
-
let stale = !1;
|
|
16153
|
-
for (let fileName of fileNames) {
|
|
16154
|
-
let cache = this.fsFileSnapshots.get(fileName);
|
|
16155
|
-
if (!cache)
|
|
16156
|
-
continue;
|
|
16157
|
-
let currentMtime = this.typescript.sys.getModifiedTime?.(fileName)?.valueOf();
|
|
16158
|
-
cache[0] !== currentMtime && (this.fsFileSnapshots.delete(fileName), stale = !0);
|
|
16159
|
-
}
|
|
16160
|
-
stale && this.projectVersion++;
|
|
16133
|
+
// src/componentManifest/resolveComponents.ts
|
|
16134
|
+
function findMatchingComponent(components, componentName, title) {
|
|
16135
|
+
let exactMatch = findExactComponentMatch(components, componentName);
|
|
16136
|
+
if (exactMatch)
|
|
16137
|
+
return exactMatch;
|
|
16138
|
+
let trimmedTitle = title.replace(/\s+/g, ""), matches = components.filter(
|
|
16139
|
+
(it) => trimmedTitle.includes(it.componentName) || it.localImportName && trimmedTitle.includes(it.localImportName) || it.importName && trimmedTitle.includes(it.importName)
|
|
16140
|
+
);
|
|
16141
|
+
if (matches.length <= 1)
|
|
16142
|
+
return matches[0];
|
|
16143
|
+
let best = matches[0];
|
|
16144
|
+
for (let cur of matches) {
|
|
16145
|
+
if (cur.jsxDepth === 0)
|
|
16146
|
+
return cur;
|
|
16147
|
+
(cur.jsxDepth ?? 1 / 0) < (best.jsxDepth ?? 1 / 0) && (best = cur);
|
|
16161
16148
|
}
|
|
16162
|
-
|
|
16163
|
-
|
|
16164
|
-
|
|
16165
|
-
|
|
16166
|
-
|
|
16167
|
-
|
|
16168
|
-
|
|
16169
|
-
|
|
16170
|
-
|
|
16171
|
-
|
|
16172
|
-
|
|
16173
|
-
|
|
16174
|
-
|
|
16175
|
-
|
|
16176
|
-
|
|
16177
|
-
|
|
16178
|
-
|
|
16179
|
-
|
|
16180
|
-
|
|
16181
|
-
|
|
16182
|
-
|
|
16183
|
-
|
|
16184
|
-
componentType = checker.getTypeOfSymbol(prop), selectedSymbol = prop;
|
|
16185
|
-
else
|
|
16186
|
-
return;
|
|
16187
|
-
}
|
|
16188
|
-
let propsType = resolvePropsFromComponentType(this.typescript, checker, componentType);
|
|
16189
|
-
if (!(!propsType || !selectedSymbol))
|
|
16149
|
+
return best;
|
|
16150
|
+
}
|
|
16151
|
+
async function resolveStoryFileComponents(options) {
|
|
16152
|
+
let { storyPath, title, typescriptOptions, docgenEngine } = options, storyFile = cachedReadTextFileSync(storyPath), csf = loadCsf(storyFile, { makeTitle: () => title }).parse(), componentName = csf._meta?.component, declaredSubcomponents = extractDeclaredSubcomponents(csf), allComponents = await getComponents({
|
|
16153
|
+
additionalComponentNames: declaredSubcomponents.map(
|
|
16154
|
+
(subcomponent) => subcomponent.componentName
|
|
16155
|
+
),
|
|
16156
|
+
csf,
|
|
16157
|
+
storyFilePath: storyPath,
|
|
16158
|
+
typescriptOptions,
|
|
16159
|
+
docgenEngine
|
|
16160
|
+
}), component = findMatchingComponent(allComponents, componentName, title), subcomponents = declaredSubcomponents.map((declared) => ({
|
|
16161
|
+
name: declared.name,
|
|
16162
|
+
component: findExactComponentMatch(allComponents, declared.componentName)
|
|
16163
|
+
}));
|
|
16164
|
+
return { storyPath, storyFile, csf, componentName, allComponents, component, subcomponents };
|
|
16165
|
+
}
|
|
16166
|
+
function extractStorySnippets(csf, componentName, filterStoryIds) {
|
|
16167
|
+
return Object.entries(csf._stories).filter(([, story]) => !filterStoryIds || filterStoryIds.has(story.id)).map(([storyExport, story]) => {
|
|
16168
|
+
let name = story.name ?? storyNameFromExport(storyExport);
|
|
16169
|
+
try {
|
|
16170
|
+
let jsdocComment = extractDescription(csf._storyStatements[storyExport]), { tags = {}, description } = jsdocComment ? extractJSDocInfo(jsdocComment) : {}, finalDescription = (tags?.describe?.[0] || tags?.desc?.[0]) ?? description;
|
|
16190
16171
|
return {
|
|
16191
|
-
|
|
16192
|
-
|
|
16193
|
-
|
|
16172
|
+
id: story.id,
|
|
16173
|
+
name,
|
|
16174
|
+
snippet: recast2.print(getCodeSnippet(csf, storyExport, componentName)).code,
|
|
16175
|
+
description: finalDescription?.trim(),
|
|
16176
|
+
summary: tags.summary?.[0]
|
|
16194
16177
|
};
|
|
16195
|
-
|
|
16196
|
-
|
|
16197
|
-
|
|
16198
|
-
|
|
16199
|
-
|
|
16200
|
-
let set = new Set(a);
|
|
16201
|
-
for (let file of b)
|
|
16202
|
-
if (!set.has(file))
|
|
16203
|
-
return !1;
|
|
16204
|
-
return !0;
|
|
16178
|
+
} catch (e) {
|
|
16179
|
+
let err = e instanceof Error ? e : new Error(String(e));
|
|
16180
|
+
return { id: story.id, name, error: { name: err.name, message: err.message } };
|
|
16181
|
+
}
|
|
16182
|
+
});
|
|
16205
16183
|
}
|
|
16206
16184
|
|
|
16207
|
-
// src/componentManifest/
|
|
16208
|
-
|
|
16209
|
-
|
|
16210
|
-
|
|
16211
|
-
|
|
16212
|
-
|
|
16213
|
-
|
|
16214
|
-
|
|
16215
|
-
|
|
16216
|
-
|
|
16217
|
-
|
|
16218
|
-
|
|
16219
|
-
this.rootTsConfigs = /* @__PURE__ */ new Set();
|
|
16220
|
-
this.searchedDirs = /* @__PURE__ */ new Set();
|
|
16221
|
-
// Our own file watching layer
|
|
16222
|
-
this.watching = !1;
|
|
16223
|
-
this.watchersByDir = /* @__PURE__ */ new Map();
|
|
16224
|
-
this.pendingEvents = /* @__PURE__ */ new Map();
|
|
16225
|
-
// Adapted from:
|
|
16226
|
-
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L83
|
|
16227
|
-
this.fsFileSnapshots = /* @__PURE__ */ new Map();
|
|
16185
|
+
// src/componentManifest/buildReactComponentDocgen.ts
|
|
16186
|
+
function getPackageInfo(componentPath, fallbackPath) {
|
|
16187
|
+
let nearestPkg = cachedFindUp("package.json", {
|
|
16188
|
+
cwd: path.dirname(componentPath ?? fallbackPath)
|
|
16189
|
+
});
|
|
16190
|
+
try {
|
|
16191
|
+
if (!nearestPkg)
|
|
16192
|
+
return;
|
|
16193
|
+
let parsed = JSON.parse(cachedReadTextFileSync(nearestPkg));
|
|
16194
|
+
return typeof parsed == "object" && parsed && "name" in parsed && typeof parsed.name == "string" ? parsed.name : void 0;
|
|
16195
|
+
} catch {
|
|
16196
|
+
return;
|
|
16228
16197
|
}
|
|
16229
|
-
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
|
|
16236
|
-
|
|
16237
|
-
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16242
|
-
|
|
16243
|
-
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
(
|
|
16247
|
-
)
|
|
16248
|
-
|
|
16249
|
-
|
|
16250
|
-
|
|
16251
|
-
|
|
16252
|
-
|
|
16198
|
+
}
|
|
16199
|
+
function getFallbackImport(packageName, componentName) {
|
|
16200
|
+
let exportName = componentName?.split(".").at(-1);
|
|
16201
|
+
return packageName && exportName ? `import { ${exportName} } from "${packageName}";` : "";
|
|
16202
|
+
}
|
|
16203
|
+
function relativizeComponentMetaPaths(doc) {
|
|
16204
|
+
let relativize = (fileName) => path.relative(process.cwd(), fileName), relativizeProp = (prop) => ({
|
|
16205
|
+
...prop,
|
|
16206
|
+
parent: prop.parent ? { ...prop.parent, fileName: relativize(prop.parent.fileName) } : prop.parent,
|
|
16207
|
+
declarations: prop.declarations?.map((declaration) => ({
|
|
16208
|
+
...declaration,
|
|
16209
|
+
fileName: relativize(declaration.fileName)
|
|
16210
|
+
}))
|
|
16211
|
+
});
|
|
16212
|
+
return {
|
|
16213
|
+
...doc,
|
|
16214
|
+
props: Object.fromEntries(
|
|
16215
|
+
Object.entries(doc.props).map(([name, prop]) => [name, relativizeProp(prop)])
|
|
16216
|
+
)
|
|
16217
|
+
};
|
|
16218
|
+
}
|
|
16219
|
+
function getComponentDocgenData(component, docgenEngine) {
|
|
16220
|
+
let reactDocgen, reactDocgenTypescript, reactComponentMeta, docgenDescription, docgenJsDocTags, docgenError;
|
|
16221
|
+
if (docgenEngine === "react-docgen") {
|
|
16222
|
+
let result = component?.reactDocgen;
|
|
16223
|
+
reactDocgen = result?.type === "success" ? result.data : void 0, docgenDescription = reactDocgen?.description, docgenError = result?.type === "error" ? result.error : void 0;
|
|
16224
|
+
} else docgenEngine === "react-docgen-typescript" ? (reactDocgenTypescript = component?.reactDocgenTypescript, docgenDescription = reactDocgenTypescript?.description, docgenError = component?.reactDocgenTypescriptError) : (reactComponentMeta = component?.reactComponentMeta ? relativizeComponentMetaPaths(component.reactComponentMeta) : void 0, docgenDescription = reactComponentMeta?.description, docgenJsDocTags = component?.componentJsDocTags);
|
|
16225
|
+
return {
|
|
16226
|
+
docgenDescription,
|
|
16227
|
+
docgenError,
|
|
16228
|
+
docgenJsDocTags,
|
|
16229
|
+
reactComponentMeta,
|
|
16230
|
+
reactDocgen,
|
|
16231
|
+
reactDocgenTypescript
|
|
16232
|
+
};
|
|
16233
|
+
}
|
|
16234
|
+
function createSubcomponentDocgen({
|
|
16235
|
+
component,
|
|
16236
|
+
declaredName,
|
|
16237
|
+
docgenEngine,
|
|
16238
|
+
packageName,
|
|
16239
|
+
storyFilePath
|
|
16240
|
+
}) {
|
|
16241
|
+
let imports = getImports({ components: component ? [component] : [], packageName }).join(`
|
|
16242
|
+
`).trim() || getFallbackImport(packageName, component?.componentName), {
|
|
16243
|
+
reactDocgen,
|
|
16244
|
+
reactDocgenTypescript,
|
|
16245
|
+
reactComponentMeta,
|
|
16246
|
+
docgenDescription,
|
|
16247
|
+
docgenJsDocTags,
|
|
16248
|
+
docgenError
|
|
16249
|
+
} = getComponentDocgenData(component, docgenEngine), { description, summary, jsDocTags } = extractComponentDescription(
|
|
16250
|
+
void 0,
|
|
16251
|
+
docgenDescription,
|
|
16252
|
+
docgenJsDocTags
|
|
16253
|
+
);
|
|
16254
|
+
return {
|
|
16255
|
+
name: declaredName,
|
|
16256
|
+
path: component?.path ?? storyFilePath,
|
|
16257
|
+
description,
|
|
16258
|
+
summary,
|
|
16259
|
+
import: imports || void 0,
|
|
16260
|
+
jsDocTags,
|
|
16261
|
+
reactDocgen,
|
|
16262
|
+
reactDocgenTypescript,
|
|
16263
|
+
reactComponentMeta,
|
|
16264
|
+
error: docgenError ?? (component ? void 0 : {
|
|
16265
|
+
name: "No component import found",
|
|
16266
|
+
message: `No component file found for the "${declaredName}" subcomponent.`
|
|
16267
|
+
})
|
|
16268
|
+
};
|
|
16269
|
+
}
|
|
16270
|
+
function buildReactComponentDocgenFromResolved({
|
|
16271
|
+
entry,
|
|
16272
|
+
storyPath,
|
|
16273
|
+
storyFilePath,
|
|
16274
|
+
storyFile,
|
|
16275
|
+
csf,
|
|
16276
|
+
componentName,
|
|
16277
|
+
component,
|
|
16278
|
+
allComponents,
|
|
16279
|
+
subcomponents,
|
|
16280
|
+
docgenEngine,
|
|
16281
|
+
filterStoryIds
|
|
16282
|
+
}) {
|
|
16283
|
+
let id = getComponentIdFromEntry(entry), title = entry.title.split("/").at(-1).replace(/\s+/g, ""), packageName = getPackageInfo(component?.path, storyPath), fallbackImport = getFallbackImport(packageName, componentName), imports = getImports({ components: allComponents, packageName }).join(`
|
|
16284
|
+
`).trim() || fallbackImport, stories = extractStorySnippets(csf, component?.componentName, filterStoryIds), base2 = {
|
|
16285
|
+
id,
|
|
16286
|
+
name: componentName ?? title,
|
|
16287
|
+
path: storyFilePath,
|
|
16288
|
+
stories,
|
|
16289
|
+
import: imports || void 0,
|
|
16290
|
+
jsDocTags: {}
|
|
16291
|
+
}, {
|
|
16292
|
+
reactDocgen,
|
|
16293
|
+
reactDocgenTypescript,
|
|
16294
|
+
reactComponentMeta,
|
|
16295
|
+
docgenDescription,
|
|
16296
|
+
docgenJsDocTags,
|
|
16297
|
+
docgenError
|
|
16298
|
+
} = getComponentDocgenData(component, docgenEngine);
|
|
16299
|
+
if (!reactDocgen && !reactDocgenTypescript && !reactComponentMeta) {
|
|
16300
|
+
let error = csf._meta?.component ? {
|
|
16301
|
+
name: "No component import found",
|
|
16302
|
+
message: `No component file found for the "${csf.meta.component}" component.`
|
|
16303
|
+
} : {
|
|
16304
|
+
name: "No component found",
|
|
16305
|
+
message: "We could not detect the component from your story file. Specify meta.component."
|
|
16306
|
+
};
|
|
16307
|
+
return {
|
|
16308
|
+
...base2,
|
|
16309
|
+
jsDocTags: base2.jsDocTags ?? {},
|
|
16310
|
+
error: docgenError ?? {
|
|
16311
|
+
name: error.name,
|
|
16312
|
+
message: (csf._metaStatementPath?.buildCodeFrameError(error.message).message ?? error.message) + `
|
|
16313
|
+
|
|
16314
|
+
${entry.importPath}:
|
|
16315
|
+
${storyFile}`
|
|
16253
16316
|
}
|
|
16317
|
+
};
|
|
16254
16318
|
}
|
|
16255
|
-
|
|
16256
|
-
|
|
16257
|
-
|
|
16258
|
-
|
|
16259
|
-
|
|
16260
|
-
|
|
16261
|
-
|
|
16262
|
-
|
|
16263
|
-
|
|
16264
|
-
|
|
16265
|
-
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16319
|
+
let metaJsDoc = extractDescription2(csf._metaStatement) || void 0, { description, summary, jsDocTags } = extractComponentDescription(
|
|
16320
|
+
metaJsDoc,
|
|
16321
|
+
docgenDescription,
|
|
16322
|
+
docgenJsDocTags
|
|
16323
|
+
), subcomponentEntries = Object.fromEntries(
|
|
16324
|
+
subcomponents.map((subcomponent) => [
|
|
16325
|
+
subcomponent.name,
|
|
16326
|
+
createSubcomponentDocgen({
|
|
16327
|
+
component: subcomponent.component,
|
|
16328
|
+
declaredName: subcomponent.name,
|
|
16329
|
+
docgenEngine,
|
|
16330
|
+
packageName,
|
|
16331
|
+
storyFilePath
|
|
16332
|
+
})
|
|
16333
|
+
])
|
|
16334
|
+
);
|
|
16335
|
+
return {
|
|
16336
|
+
...base2,
|
|
16337
|
+
description,
|
|
16338
|
+
summary,
|
|
16339
|
+
import: imports || void 0,
|
|
16340
|
+
reactDocgen,
|
|
16341
|
+
reactDocgenTypescript,
|
|
16342
|
+
reactComponentMeta,
|
|
16343
|
+
jsDocTags,
|
|
16344
|
+
...Object.keys(subcomponentEntries).length > 0 ? { subcomponents: subcomponentEntries } : {},
|
|
16345
|
+
error: docgenError
|
|
16346
|
+
};
|
|
16347
|
+
}
|
|
16348
|
+
|
|
16349
|
+
// src/componentManifest/componentMetaManagerSingleton.ts
|
|
16350
|
+
import { logger as logger8 } from "storybook/internal/node-logger";
|
|
16351
|
+
|
|
16352
|
+
// src/componentManifest/componentMeta/ComponentMetaManager.ts
|
|
16353
|
+
import { logger as logger7 } from "storybook/internal/node-logger";
|
|
16354
|
+
import { existsSync as existsSync3, watch } from "fs";
|
|
16355
|
+
import * as path3 from "path";
|
|
16356
|
+
|
|
16357
|
+
// src/componentManifest/componentMeta/ComponentMetaProject.ts
|
|
16358
|
+
var import_language_core = __toESM(require_language_core(), 1), import_typescript = __toESM(require_typescript(), 1);
|
|
16359
|
+
import * as path2 from "path";
|
|
16360
|
+
|
|
16361
|
+
// src/componentManifest/componentMeta/componentMetaExtractor.ts
|
|
16362
|
+
var LARGE_SOURCE_THRESHOLD = 30, MAX_UNWRAP_DEPTH = 5, MAX_SERIALIZATION_DEPTH = 5;
|
|
16363
|
+
function isLiteralType(type) {
|
|
16364
|
+
return type.isStringLiteral() || type.isNumberLiteral();
|
|
16365
|
+
}
|
|
16366
|
+
function isUnionType(type) {
|
|
16367
|
+
return type.isUnion();
|
|
16368
|
+
}
|
|
16369
|
+
function isWrappedExpression(typescript, expression) {
|
|
16370
|
+
return typescript.isParenthesizedExpression(expression) || typescript.isAsExpression(expression) || typescript.isNonNullExpression(expression) || (typescript.isSatisfiesExpression?.(expression) ?? !1);
|
|
16371
|
+
}
|
|
16372
|
+
function resolveAliasedSymbol(typescript, checker, symbol) {
|
|
16373
|
+
return symbol.flags & typescript.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
16374
|
+
}
|
|
16375
|
+
function getSymbolContextNode(symbol) {
|
|
16376
|
+
return symbol.valueDeclaration ?? symbol.getDeclarations()?.[0];
|
|
16377
|
+
}
|
|
16378
|
+
function resolveComponentSymbolFromNode(typescript, checker, node) {
|
|
16379
|
+
if (!node)
|
|
16380
|
+
return;
|
|
16381
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
16382
|
+
return symbol ? resolveComponentSymbol(typescript, checker, symbol, node) : void 0;
|
|
16383
|
+
}
|
|
16384
|
+
function resolveComponentSymbol(typescript, checker, symbol, contextNode, depth = 0) {
|
|
16385
|
+
let resolved = resolveAliasedSymbol(typescript, checker, symbol);
|
|
16386
|
+
if (depth > MAX_UNWRAP_DEPTH)
|
|
16387
|
+
return resolved;
|
|
16388
|
+
let declarationForPromotion = getSymbolContextNode(resolved);
|
|
16389
|
+
if (declarationForPromotion && (typescript.isArrowFunction(declarationForPromotion) || typescript.isFunctionExpression(declarationForPromotion)) && declarationForPromotion.parent && typescript.isVariableDeclaration(declarationForPromotion.parent) && typescript.isIdentifier(declarationForPromotion.parent.name)) {
|
|
16390
|
+
let variableSymbol = checker.getSymbolAtLocation(declarationForPromotion.parent.name);
|
|
16391
|
+
variableSymbol && (resolved = resolveAliasedSymbol(typescript, checker, variableSymbol));
|
|
16392
|
+
}
|
|
16393
|
+
let declaration = getSymbolContextNode(resolved);
|
|
16394
|
+
if (declaration) {
|
|
16395
|
+
if (typescript.isShorthandPropertyAssignment(declaration)) {
|
|
16396
|
+
let valueSymbol = checker.getShorthandAssignmentValueSymbol(declaration);
|
|
16397
|
+
if (valueSymbol)
|
|
16398
|
+
return resolveComponentSymbol(
|
|
16399
|
+
typescript,
|
|
16400
|
+
checker,
|
|
16401
|
+
valueSymbol,
|
|
16402
|
+
declaration.name,
|
|
16403
|
+
depth + 1
|
|
16404
|
+
);
|
|
16271
16405
|
}
|
|
16272
|
-
if (
|
|
16273
|
-
|
|
16274
|
-
|
|
16275
|
-
|
|
16276
|
-
|
|
16277
|
-
|
|
16278
|
-
|
|
16279
|
-
|
|
16280
|
-
|
|
16281
|
-
|
|
16282
|
-
|
|
16283
|
-
|
|
16284
|
-
|
|
16285
|
-
|
|
16286
|
-
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
|
|
16294
|
-
|
|
16295
|
-
|
|
16406
|
+
if (typescript.isPropertyAssignment(declaration)) {
|
|
16407
|
+
let next = resolveComponentSymbolFromNode(typescript, checker, declaration.initializer);
|
|
16408
|
+
if (next)
|
|
16409
|
+
return next;
|
|
16410
|
+
}
|
|
16411
|
+
if (typescript.isBinaryExpression(declaration) && declaration.operatorToken.kind === typescript.SyntaxKind.EqualsToken) {
|
|
16412
|
+
let next = resolveComponentSymbolFromNode(typescript, checker, declaration.right);
|
|
16413
|
+
if (next)
|
|
16414
|
+
return next;
|
|
16415
|
+
}
|
|
16416
|
+
}
|
|
16417
|
+
let typeSymbol = (!!(resolved.flags & typescript.SymbolFlags.Property) || declaration !== void 0 && (typescript.isPropertyAssignment(declaration) || typescript.isShorthandPropertyAssignment(declaration) || typescript.isPropertySignature(declaration) || typescript.isPropertyDeclaration(declaration) || typescript.isBinaryExpression(declaration) && declaration.operatorToken.kind === typescript.SyntaxKind.EqualsToken)) && checker.getTypeOfSymbolAtLocation(resolved, contextNode).getSymbol?.();
|
|
16418
|
+
if (typeSymbol) {
|
|
16419
|
+
let resolvedTypeSymbol = resolveAliasedSymbol(typescript, checker, typeSymbol), typeDeclaration = getSymbolContextNode(resolvedTypeSymbol);
|
|
16420
|
+
if (resolvedTypeSymbol !== resolved && typeDeclaration)
|
|
16421
|
+
return resolveComponentSymbol(
|
|
16422
|
+
typescript,
|
|
16423
|
+
checker,
|
|
16424
|
+
resolvedTypeSymbol,
|
|
16425
|
+
typeDeclaration,
|
|
16426
|
+
depth + 1
|
|
16427
|
+
);
|
|
16428
|
+
}
|
|
16429
|
+
return resolved;
|
|
16430
|
+
}
|
|
16431
|
+
function findImportSymbolInStoryFile(typescript, checker, storySourceFile, componentRef) {
|
|
16432
|
+
let importSpecifier = componentRef.importId, importName = componentRef.importName, memberAccess = componentRef.member;
|
|
16433
|
+
if (importSpecifier)
|
|
16434
|
+
for (let stmt of storySourceFile.statements) {
|
|
16435
|
+
if (!typescript.isImportDeclaration(stmt))
|
|
16436
|
+
continue;
|
|
16437
|
+
let moduleSpec = stmt.moduleSpecifier;
|
|
16438
|
+
if (!typescript.isStringLiteral(moduleSpec) || moduleSpec.text !== importSpecifier)
|
|
16439
|
+
continue;
|
|
16440
|
+
let clause = stmt.importClause;
|
|
16441
|
+
if (!clause)
|
|
16442
|
+
continue;
|
|
16443
|
+
let importSymbol;
|
|
16444
|
+
if (importName === "default") {
|
|
16445
|
+
if (clause.name && (importSymbol = checker.getSymbolAtLocation(clause.name)), !importSymbol && clause.namedBindings && typescript.isNamedImports(clause.namedBindings)) {
|
|
16446
|
+
for (let spec of clause.namedBindings.elements)
|
|
16447
|
+
if ((spec.propertyName ?? spec.name).text === "default") {
|
|
16448
|
+
importSymbol = checker.getSymbolAtLocation(spec.name);
|
|
16449
|
+
break;
|
|
16296
16450
|
}
|
|
16297
16451
|
}
|
|
16452
|
+
} else if (clause.namedBindings && typescript.isNamedImports(clause.namedBindings)) {
|
|
16453
|
+
for (let spec of clause.namedBindings.elements)
|
|
16454
|
+
if ((spec.propertyName ?? spec.name).text === importName) {
|
|
16455
|
+
importSymbol = checker.getSymbolAtLocation(spec.name);
|
|
16456
|
+
break;
|
|
16457
|
+
}
|
|
16298
16458
|
}
|
|
16299
|
-
|
|
16300
|
-
|
|
16301
|
-
|
|
16302
|
-
|
|
16303
|
-
|
|
16304
|
-
|
|
16305
|
-
|
|
16306
|
-
|
|
16307
|
-
|
|
16459
|
+
if (!importSymbol && memberAccess && clause.namedBindings && typescript.isNamespaceImport(clause.namedBindings) && (importSymbol = checker.getSymbolAtLocation(clause.namedBindings.name)), importSymbol)
|
|
16460
|
+
return importSymbol;
|
|
16461
|
+
}
|
|
16462
|
+
}
|
|
16463
|
+
function metaComponentMatchesRef(typescript, checker, storySourceFile, componentRef, metaComponentInitializer) {
|
|
16464
|
+
let refSymbol = findImportSymbolInStoryFile(typescript, checker, storySourceFile, componentRef), metaSymbol = resolveComponentSymbolFromNode(typescript, checker, metaComponentInitializer);
|
|
16465
|
+
if (refSymbol && metaSymbol && !componentRef.member)
|
|
16466
|
+
return resolveAliasedSymbol(typescript, checker, refSymbol) === resolveAliasedSymbol(typescript, checker, metaSymbol);
|
|
16467
|
+
if (typescript.isIdentifier(metaComponentInitializer))
|
|
16468
|
+
return componentRef.componentName === metaComponentInitializer.text;
|
|
16469
|
+
if (typescript.isPropertyAccessExpression(metaComponentInitializer) && typescript.isIdentifier(metaComponentInitializer.expression)) {
|
|
16470
|
+
let metaName = `${metaComponentInitializer.expression.text}.${metaComponentInitializer.name.text}`;
|
|
16471
|
+
return componentRef.componentName === metaName;
|
|
16472
|
+
}
|
|
16473
|
+
return !1;
|
|
16474
|
+
}
|
|
16475
|
+
function resolvePropsFromStoryFile(typescript, checker, storySourceFile, componentRef) {
|
|
16476
|
+
let memberAccess = componentRef.member, importSymbol = findImportSymbolInStoryFile(
|
|
16477
|
+
typescript,
|
|
16478
|
+
checker,
|
|
16479
|
+
storySourceFile,
|
|
16480
|
+
componentRef
|
|
16481
|
+
);
|
|
16482
|
+
if (!importSymbol)
|
|
16483
|
+
return;
|
|
16484
|
+
let result;
|
|
16485
|
+
function extractPropsFromJsx(node) {
|
|
16486
|
+
let sig = checker.getResolvedSignature(node);
|
|
16487
|
+
if (!sig)
|
|
16488
|
+
return;
|
|
16489
|
+
let params = sig.getParameters();
|
|
16490
|
+
return params.length === 0 ? checker.getTypeFromTypeNode(typescript.factory.createTypeLiteralNode([])) : checker.getTypeOfSymbolAtLocation(params[0], node);
|
|
16491
|
+
}
|
|
16492
|
+
function visit(node) {
|
|
16493
|
+
if (!result) {
|
|
16494
|
+
if (typescript.isJsxSelfClosingElement(node) || typescript.isJsxOpeningElement(node)) {
|
|
16495
|
+
let tagName = node.tagName;
|
|
16496
|
+
if (memberAccess) {
|
|
16497
|
+
if (typescript.isPropertyAccessExpression(tagName) && tagName.name.text === memberAccess) {
|
|
16498
|
+
let leftSym = checker.getSymbolAtLocation(tagName.expression);
|
|
16499
|
+
if (leftSym && importSymbol && leftSym === importSymbol) {
|
|
16500
|
+
let propsType = extractPropsFromJsx(node);
|
|
16501
|
+
if (propsType) {
|
|
16502
|
+
let memberSymbol = checker.getSymbolAtLocation(tagName.name) ?? checker.getTypeAtLocation(tagName.expression).getProperty(tagName.name.text) ?? resolveComponentSymbolFromNode(typescript, checker, tagName);
|
|
16503
|
+
result = {
|
|
16504
|
+
componentRef,
|
|
16505
|
+
propsType,
|
|
16506
|
+
symbol: memberSymbol ? resolveComponentSymbol(typescript, checker, memberSymbol, tagName.name) : resolveAliasedSymbol(typescript, checker, importSymbol)
|
|
16507
|
+
};
|
|
16508
|
+
return;
|
|
16509
|
+
}
|
|
16510
|
+
}
|
|
16308
16511
|
}
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
|
|
16312
|
-
|
|
16313
|
-
|
|
16314
|
-
|
|
16315
|
-
|
|
16316
|
-
|
|
16317
|
-
|
|
16318
|
-
|
|
16319
|
-
|
|
16512
|
+
} else if (typescript.isIdentifier(tagName)) {
|
|
16513
|
+
let sym = checker.getSymbolAtLocation(tagName);
|
|
16514
|
+
if (sym && importSymbol && sym === importSymbol) {
|
|
16515
|
+
let propsType = extractPropsFromJsx(node);
|
|
16516
|
+
if (propsType) {
|
|
16517
|
+
result = {
|
|
16518
|
+
componentRef,
|
|
16519
|
+
propsType,
|
|
16520
|
+
symbol: resolveAliasedSymbol(typescript, checker, sym)
|
|
16521
|
+
};
|
|
16522
|
+
return;
|
|
16523
|
+
}
|
|
16320
16524
|
}
|
|
16321
16525
|
}
|
|
16322
|
-
return newChains;
|
|
16323
|
-
} else
|
|
16324
|
-
return [[...before, tsConfig]];
|
|
16325
|
-
}, getCommandLine = (tsConfig) => this.getOrCreateConfiguredProject(tsConfig)?.getCommandLine();
|
|
16326
|
-
return prepareClosestRootCommandLine(), findDirectIncludeTsconfig() ?? findIndirectReferenceTsconfig();
|
|
16327
|
-
}
|
|
16328
|
-
// ---------------------------------------------------------------------------
|
|
16329
|
-
// Adapted from:
|
|
16330
|
-
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L236-L256
|
|
16331
|
-
// ---------------------------------------------------------------------------
|
|
16332
|
-
getOrCreateConfiguredProject(tsconfig) {
|
|
16333
|
-
tsconfig = tsconfig.replace(/\\/g, "/");
|
|
16334
|
-
let project = this.configProjects.get(tsconfig);
|
|
16335
|
-
if (!project)
|
|
16336
|
-
try {
|
|
16337
|
-
let getCommandLine = () => this.parseConfigWorker(tsconfig);
|
|
16338
|
-
project = new ComponentMetaProject(
|
|
16339
|
-
this.typescript,
|
|
16340
|
-
getCommandLine(),
|
|
16341
|
-
tsconfig,
|
|
16342
|
-
this.fsFileSnapshots,
|
|
16343
|
-
getCommandLine
|
|
16344
|
-
), this.configProjects.set(tsconfig, project), this.watching && (this.watchDirectory(path3.dirname(tsconfig)), this.watchProgramSourceDirs(project));
|
|
16345
|
-
} catch (err) {
|
|
16346
|
-
return logger5.debug(`[reactComponentMeta] Failed to parse tsconfig ${tsconfig}: ${err}`), null;
|
|
16347
16526
|
}
|
|
16348
|
-
|
|
16349
|
-
}
|
|
16350
|
-
// ---------------------------------------------------------------------------
|
|
16351
|
-
// Adapted from:
|
|
16352
|
-
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L258-L284
|
|
16353
|
-
// ---------------------------------------------------------------------------
|
|
16354
|
-
getOrCreateInferredProject(fileName) {
|
|
16355
|
-
return this.inferredProject || (this.inferredProject = new ComponentMetaProject(
|
|
16356
|
-
this.typescript,
|
|
16357
|
-
{
|
|
16358
|
-
options: {
|
|
16359
|
-
...DEFAULT_INFERRED_OPTIONS,
|
|
16360
|
-
target: this.typescript.ScriptTarget.Latest,
|
|
16361
|
-
module: this.typescript.ModuleKind.ESNext,
|
|
16362
|
-
moduleResolution: this.typescript.ModuleResolutionKind.Bundler,
|
|
16363
|
-
jsx: this.typescript.JsxEmit.ReactJSX
|
|
16364
|
-
},
|
|
16365
|
-
fileNames: [],
|
|
16366
|
-
errors: []
|
|
16367
|
-
},
|
|
16368
|
-
void 0,
|
|
16369
|
-
this.fsFileSnapshots
|
|
16370
|
-
)), this.inferredProject.ensureFiles([fileName]), this.inferredProject;
|
|
16371
|
-
}
|
|
16372
|
-
// ---------------------------------------------------------------------------
|
|
16373
|
-
// Adapted from:
|
|
16374
|
-
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProjectLs.ts#L262-L353
|
|
16375
|
-
// ---------------------------------------------------------------------------
|
|
16376
|
-
parseConfigWorker(tsconfig) {
|
|
16377
|
-
let config = this.typescript.readJsonConfigFile(tsconfig, this.typescript.sys.readFile), content = this.typescript.parseJsonSourceFileConfigFileContent(
|
|
16378
|
-
config,
|
|
16379
|
-
this.typescript.sys,
|
|
16380
|
-
path3.dirname(tsconfig),
|
|
16381
|
-
{},
|
|
16382
|
-
tsconfig
|
|
16383
|
-
);
|
|
16384
|
-
return content.options.outDir = void 0, content.fileNames = content.fileNames.map((fileName) => fileName.replace(/\\/g, "/")), content;
|
|
16385
|
-
}
|
|
16386
|
-
// ---------------------------------------------------------------------------
|
|
16387
|
-
// File events
|
|
16388
|
-
// ---------------------------------------------------------------------------
|
|
16389
|
-
/**
|
|
16390
|
-
* Broadcast file changes to all projects. Each project selectively bumps projectVersion.
|
|
16391
|
-
*
|
|
16392
|
-
* Adapted from:
|
|
16393
|
-
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L409-L432
|
|
16394
|
-
*/
|
|
16395
|
-
onFilesChanged(changes) {
|
|
16396
|
-
for (let project of this.configProjects.values())
|
|
16397
|
-
project.onFilesChanged(changes);
|
|
16398
|
-
this.inferredProject?.onFilesChanged(changes);
|
|
16399
|
-
}
|
|
16400
|
-
/**
|
|
16401
|
-
* Adapted from:
|
|
16402
|
-
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L43-L68
|
|
16403
|
-
*/
|
|
16404
|
-
onConfigChanged(configPath, type) {
|
|
16405
|
-
if (configPath = configPath.replace(/\\/g, "/"), type === "created")
|
|
16406
|
-
this.rootTsConfigs.add(configPath);
|
|
16407
|
-
else if ((type === "changed" || type === "deleted") && this.configProjects.has(configPath)) {
|
|
16408
|
-
type === "deleted" && this.rootTsConfigs.delete(configPath);
|
|
16409
|
-
let project = this.configProjects.get(configPath);
|
|
16410
|
-
this.configProjects.delete(configPath), project?.dispose();
|
|
16527
|
+
typescript.forEachChild(node, visit);
|
|
16411
16528
|
}
|
|
16412
|
-
this.searchedDirs.clear();
|
|
16413
16529
|
}
|
|
16414
|
-
|
|
16415
|
-
|
|
16416
|
-
|
|
16417
|
-
|
|
16418
|
-
|
|
16419
|
-
|
|
16420
|
-
|
|
16421
|
-
|
|
16422
|
-
|
|
16423
|
-
|
|
16530
|
+
return visit(storySourceFile), result;
|
|
16531
|
+
}
|
|
16532
|
+
function resolvePropsFromComponentType(typescript, checker, componentType) {
|
|
16533
|
+
let callSigs = componentType.getCallSignatures();
|
|
16534
|
+
if (callSigs.length > 0) {
|
|
16535
|
+
let sig = callSigs[0];
|
|
16536
|
+
if (sig.parameters.length === 0)
|
|
16537
|
+
return checker.getVoidType();
|
|
16538
|
+
let propsType = checker.getTypeOfSymbol(sig.parameters[0]);
|
|
16539
|
+
if (!(propsType.flags & typescript.TypeFlags.Any))
|
|
16540
|
+
return propsType;
|
|
16424
16541
|
}
|
|
16425
|
-
|
|
16426
|
-
|
|
16427
|
-
|
|
16428
|
-
|
|
16429
|
-
|
|
16430
|
-
|
|
16431
|
-
|
|
16432
|
-
if (singleProject)
|
|
16433
|
-
for (let filePath of singleProject.getSourceFilePaths())
|
|
16434
|
-
dirs.add(path3.dirname(filePath));
|
|
16435
|
-
else {
|
|
16436
|
-
for (let project of this.configProjects.values())
|
|
16437
|
-
for (let filePath of project.getSourceFilePaths())
|
|
16438
|
-
dirs.add(path3.dirname(filePath));
|
|
16439
|
-
if (this.inferredProject)
|
|
16440
|
-
for (let filePath of this.inferredProject.getSourceFilePaths())
|
|
16441
|
-
dirs.add(path3.dirname(filePath));
|
|
16442
|
-
}
|
|
16443
|
-
let roots = /* @__PURE__ */ new Set();
|
|
16444
|
-
for (let dir of dirs) {
|
|
16445
|
-
let candidate = dir;
|
|
16446
|
-
for (; candidate !== path3.dirname(candidate); ) {
|
|
16447
|
-
let normalized = candidate.replace(/\\/g, "/"), alreadyWatched = !1;
|
|
16448
|
-
for (let watched of this.watchersByDir.keys())
|
|
16449
|
-
if (normalized === watched || normalized.startsWith(watched + "/")) {
|
|
16450
|
-
alreadyWatched = !0;
|
|
16451
|
-
break;
|
|
16452
|
-
}
|
|
16453
|
-
if (alreadyWatched)
|
|
16454
|
-
break;
|
|
16455
|
-
if (this.typescript.sys.fileExists(path3.join(candidate, "package.json")) || this.typescript.sys.fileExists(path3.join(candidate, "tsconfig.json"))) {
|
|
16456
|
-
roots.add(candidate);
|
|
16457
|
-
break;
|
|
16458
|
-
}
|
|
16459
|
-
candidate = path3.dirname(candidate);
|
|
16460
|
-
}
|
|
16542
|
+
let ctorSigs = componentType.getConstructSignatures();
|
|
16543
|
+
for (let sig of ctorSigs) {
|
|
16544
|
+
let propsSym = sig.getReturnType().getProperty("props");
|
|
16545
|
+
if (propsSym) {
|
|
16546
|
+
let propsType = checker.getTypeOfSymbol(propsSym);
|
|
16547
|
+
if (!(propsType.flags & typescript.TypeFlags.Any))
|
|
16548
|
+
return propsType;
|
|
16461
16549
|
}
|
|
16462
|
-
for (let root of roots)
|
|
16463
|
-
this.watchDirectory(root);
|
|
16464
16550
|
}
|
|
16465
|
-
|
|
16466
|
-
|
|
16551
|
+
}
|
|
16552
|
+
function resolvePropsFromComponentExport(typescript, checker, componentSourceFile, componentRef) {
|
|
16553
|
+
let moduleSymbol = checker.getSymbolAtLocation(componentSourceFile);
|
|
16554
|
+
if (!moduleSymbol)
|
|
16555
|
+
return;
|
|
16556
|
+
let exports = checker.getExportsOfModule(checker.getMergedSymbol(moduleSymbol)), exportName = componentRef.importName ?? componentRef.componentName.split(".").at(-1);
|
|
16557
|
+
if (!exportName)
|
|
16558
|
+
return;
|
|
16559
|
+
let exportSymbol, componentType;
|
|
16560
|
+
if (componentRef.namespace && componentRef.member) {
|
|
16561
|
+
let namespaceExportName = componentRef.importName ?? componentRef.member;
|
|
16562
|
+
if (exportSymbol = namespaceExportName === "default" ? exports.find((symbol) => symbol.getName() === "default") : exports.find((symbol) => symbol.getName() === namespaceExportName), !exportSymbol)
|
|
16467
16563
|
return;
|
|
16468
|
-
|
|
16469
|
-
|
|
16470
|
-
|
|
16564
|
+
componentType = checker.getTypeOfSymbol(exportSymbol);
|
|
16565
|
+
} else {
|
|
16566
|
+
if (exportSymbol = exportName === "default" ? exports.find((symbol) => symbol.getName() === "default") : exports.find((symbol) => symbol.getName() === exportName), !exportSymbol)
|
|
16567
|
+
return;
|
|
16568
|
+
if (componentType = checker.getTypeOfSymbol(exportSymbol), componentRef.member) {
|
|
16569
|
+
let memberSymbol = componentType.getProperty(componentRef.member);
|
|
16570
|
+
if (!memberSymbol)
|
|
16471
16571
|
return;
|
|
16472
|
-
|
|
16473
|
-
watched.startsWith(normalized + "/") && (watcher.close(), this.watchersByDir.delete(watched));
|
|
16474
|
-
try {
|
|
16475
|
-
let watcher = watch(dir, { recursive: !0 }, (eventType, filename) => {
|
|
16476
|
-
if (!filename)
|
|
16477
|
-
return;
|
|
16478
|
-
let filePath = path3.resolve(dir, filename).replace(/\\/g, "/");
|
|
16479
|
-
if (filePath.includes("/node_modules/") || filePath.includes("/.git/"))
|
|
16480
|
-
return;
|
|
16481
|
-
let existing = this.pendingEvents.get(filePath);
|
|
16482
|
-
existing && clearTimeout(existing), this.pendingEvents.set(
|
|
16483
|
-
filePath,
|
|
16484
|
-
setTimeout(() => {
|
|
16485
|
-
this.pendingEvents.delete(filePath), eventType === "rename" ? existsSync3(filePath) ? this.handleFileEvent(filePath, "created") : this.handleFileEvent(filePath, "deleted") : this.handleFileEvent(filePath, "changed");
|
|
16486
|
-
}, 50)
|
|
16487
|
-
);
|
|
16488
|
-
});
|
|
16489
|
-
watcher.unref(), this.watchersByDir.set(normalized, watcher);
|
|
16490
|
-
} catch (err) {
|
|
16491
|
-
logger5.debug(`[reactComponentMeta] Failed to watch directory ${normalized}: ${err}`);
|
|
16572
|
+
exportSymbol = memberSymbol, componentType = checker.getTypeOfSymbol(memberSymbol);
|
|
16492
16573
|
}
|
|
16493
16574
|
}
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16502
|
-
|
|
16503
|
-
|
|
16504
|
-
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
* We reclassify here so that onFilesChanged stays 1:1 with Volar Kit.
|
|
16510
|
-
*/
|
|
16511
|
-
handleFileEvent(filePath, type) {
|
|
16512
|
-
if (type === "created") {
|
|
16513
|
-
for (let project of this.configProjects.values())
|
|
16514
|
-
if (project.hasSourceFile(filePath)) {
|
|
16515
|
-
type = "changed";
|
|
16516
|
-
break;
|
|
16517
|
-
}
|
|
16518
|
-
type === "created" && this.inferredProject?.hasSourceFile(filePath) && (type = "changed");
|
|
16519
|
-
}
|
|
16520
|
-
let basename3 = path3.basename(filePath);
|
|
16521
|
-
if (rootTsConfigNames.includes(basename3)) {
|
|
16522
|
-
this.onConfigChanged(filePath, type);
|
|
16523
|
-
return;
|
|
16575
|
+
let propsType = resolvePropsFromComponentType(typescript, checker, componentType), contextNode = exportSymbol ? getSymbolContextNode(exportSymbol) : void 0;
|
|
16576
|
+
if (!(!propsType || !exportSymbol || !contextNode))
|
|
16577
|
+
return {
|
|
16578
|
+
componentRef,
|
|
16579
|
+
propsType,
|
|
16580
|
+
symbol: resolveComponentSymbol(typescript, checker, exportSymbol, contextNode)
|
|
16581
|
+
};
|
|
16582
|
+
}
|
|
16583
|
+
function getPropSourceFile(prop) {
|
|
16584
|
+
let declarations = prop.getDeclarations();
|
|
16585
|
+
if (declarations?.length) {
|
|
16586
|
+
for (let decl of declarations) {
|
|
16587
|
+
let fileName = decl.getSourceFile().fileName;
|
|
16588
|
+
if (!fileName.includes("node_modules") && !fileName.endsWith(".d.ts"))
|
|
16589
|
+
return fileName;
|
|
16524
16590
|
}
|
|
16525
|
-
|
|
16526
|
-
}
|
|
16527
|
-
dispose() {
|
|
16528
|
-
this.stopWatching();
|
|
16529
|
-
for (let project of this.configProjects.values())
|
|
16530
|
-
project.dispose();
|
|
16531
|
-
this.inferredProject?.dispose(), this.configProjects.clear(), this.inferredProject = void 0, this.fsFileSnapshots.clear(), this.searchedDirs.clear(), this.rootTsConfigs.clear();
|
|
16591
|
+
return declarations[0].getSourceFile().fileName;
|
|
16532
16592
|
}
|
|
16533
|
-
}
|
|
16534
|
-
function
|
|
16535
|
-
let
|
|
16536
|
-
if (
|
|
16537
|
-
return
|
|
16538
|
-
let
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16593
|
+
}
|
|
16594
|
+
function getParentType(typescript, prop) {
|
|
16595
|
+
let declarations = prop.getDeclarations();
|
|
16596
|
+
if (!declarations?.length)
|
|
16597
|
+
return;
|
|
16598
|
+
let node = declarations[0].parent;
|
|
16599
|
+
for (; node; ) {
|
|
16600
|
+
if (typescript.isInterfaceDeclaration(node) || typescript.isTypeAliasDeclaration(node))
|
|
16601
|
+
return {
|
|
16602
|
+
name: node.name.getText(),
|
|
16603
|
+
fileName: node.getSourceFile().fileName
|
|
16604
|
+
};
|
|
16605
|
+
node = node.parent;
|
|
16542
16606
|
}
|
|
16543
|
-
return bLength - aLength;
|
|
16544
16607
|
}
|
|
16545
|
-
function
|
|
16546
|
-
let
|
|
16547
|
-
|
|
16608
|
+
function getAllDeclarationParents(typescript, prop) {
|
|
16609
|
+
let declarations = prop.getDeclarations();
|
|
16610
|
+
if (!declarations?.length)
|
|
16611
|
+
return;
|
|
16612
|
+
let parents = [];
|
|
16613
|
+
for (let declaration of declarations) {
|
|
16614
|
+
let { parent } = declaration;
|
|
16615
|
+
parent && (typescript.isInterfaceDeclaration(parent) || typescript.isTypeAliasDeclaration(parent) ? parents.push({
|
|
16616
|
+
name: parent.name.getText(),
|
|
16617
|
+
fileName: parent.getSourceFile().fileName
|
|
16618
|
+
}) : typescript.isTypeLiteralNode(parent) && parents.push({
|
|
16619
|
+
name: "TypeLiteral",
|
|
16620
|
+
fileName: parent.getSourceFile().fileName
|
|
16621
|
+
}));
|
|
16622
|
+
}
|
|
16623
|
+
return parents.length > 0 ? parents : void 0;
|
|
16548
16624
|
}
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16625
|
+
function serializeType(typescript, checker, type, isRequired, depth = 0) {
|
|
16626
|
+
if (depth > MAX_SERIALIZATION_DEPTH)
|
|
16627
|
+
return { name: checker.typeToString(type) };
|
|
16628
|
+
if (type.isUnion()) {
|
|
16629
|
+
let nonUndefinedTypes = type.types.filter(
|
|
16630
|
+
(t6) => !(t6.getFlags() & typescript.TypeFlags.Undefined)
|
|
16631
|
+
), literalMembers = nonUndefinedTypes.filter(isLiteralType);
|
|
16632
|
+
if (literalMembers.length > 0 && literalMembers.length === nonUndefinedTypes.length)
|
|
16633
|
+
return {
|
|
16634
|
+
name: "enum",
|
|
16635
|
+
raw: literalMembers.map((m) => checker.typeToString(m)).join(" | "),
|
|
16636
|
+
value: literalMembers.map((m) => ({
|
|
16637
|
+
value: JSON.stringify(m.value)
|
|
16638
|
+
}))
|
|
16639
|
+
};
|
|
16640
|
+
if (!isRequired && nonUndefinedTypes.length === 1 && nonUndefinedTypes.length < type.types.length)
|
|
16641
|
+
return { name: checker.typeToString(nonUndefinedTypes[0]) };
|
|
16557
16642
|
}
|
|
16558
|
-
let
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
);
|
|
16571
|
-
let normalizedPath = storyPath;
|
|
16572
|
-
if (storyPath.isCallExpression()) {
|
|
16573
|
-
let callee = storyPath.get("callee");
|
|
16574
|
-
if (callee.isMemberExpression()) {
|
|
16575
|
-
let obj = callee.get("object"), prop = callee.get("property"), isBind = prop.isIdentifier() && prop.node.name === "bind" || t2.isStringLiteral(prop.node) && prop.node.value === "bind";
|
|
16576
|
-
if (obj.isIdentifier() && isBind) {
|
|
16577
|
-
let resolved = resolveIdentifierInit(storyDeclaration, obj);
|
|
16578
|
-
resolved && (normalizedPath = resolved);
|
|
16643
|
+
let constraint = type.getConstraint?.();
|
|
16644
|
+
return constraint && constraint !== type ? serializeType(typescript, checker, constraint, isRequired, depth + 1) : { name: checker.typeToString(type) };
|
|
16645
|
+
}
|
|
16646
|
+
function unwrapToFunction(typescript, node, depth = 0, checker) {
|
|
16647
|
+
if (!(depth > MAX_UNWRAP_DEPTH)) {
|
|
16648
|
+
if (typescript.isArrowFunction(node) || typescript.isFunctionExpression(node) || typescript.isFunctionDeclaration(node))
|
|
16649
|
+
return node;
|
|
16650
|
+
if (typescript.isCallExpression(node))
|
|
16651
|
+
for (let arg of node.arguments) {
|
|
16652
|
+
let fn = unwrapToFunction(typescript, arg, depth + 1, checker);
|
|
16653
|
+
if (fn)
|
|
16654
|
+
return fn;
|
|
16579
16655
|
}
|
|
16580
|
-
|
|
16581
|
-
|
|
16582
|
-
|
|
16583
|
-
|
|
16584
|
-
|
|
16585
|
-
|
|
16586
|
-
|
|
16587
|
-
|
|
16588
|
-
|
|
16589
|
-
|
|
16590
|
-
storyArg.isExpression(),
|
|
16591
|
-
() => storyPath.buildCodeFrameError("Could not evaluate story expression").message
|
|
16592
|
-
), normalizedPath = storyArg;
|
|
16656
|
+
if (typescript.isParenthesizedExpression(node) || typescript.isAsExpression(node))
|
|
16657
|
+
return unwrapToFunction(typescript, node.expression, depth + 1, checker);
|
|
16658
|
+
if (typescript.isIdentifier(node) && checker) {
|
|
16659
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
16660
|
+
if (symbol) {
|
|
16661
|
+
let decl = (symbol.flags & typescript.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol).valueDeclaration;
|
|
16662
|
+
if (decl && typescript.isVariableDeclaration(decl) && decl.initializer)
|
|
16663
|
+
return unwrapToFunction(typescript, decl.initializer, depth + 1, checker);
|
|
16664
|
+
if (decl && typescript.isFunctionDeclaration(decl))
|
|
16665
|
+
return decl;
|
|
16593
16666
|
}
|
|
16594
16667
|
}
|
|
16595
16668
|
}
|
|
16596
|
-
|
|
16597
|
-
|
|
16598
|
-
if (
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
);
|
|
16604
|
-
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
|
|
16610
|
-
|
|
16669
|
+
}
|
|
16670
|
+
function resolveLiteralValue(typescript, checker, node, depth = 0) {
|
|
16671
|
+
if (depth > MAX_UNWRAP_DEPTH || typescript.isStringLiteral(node) || typescript.isNumericLiteral(node) || typescript.isNoSubstitutionTemplateLiteral(node) || node.kind === typescript.SyntaxKind.TrueKeyword || node.kind === typescript.SyntaxKind.FalseKeyword || node.kind === typescript.SyntaxKind.NullKeyword)
|
|
16672
|
+
return node.getText();
|
|
16673
|
+
if (typescript.isIdentifier(node)) {
|
|
16674
|
+
if (node.text === "undefined")
|
|
16675
|
+
return "undefined";
|
|
16676
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
16677
|
+
if (!symbol)
|
|
16678
|
+
return node.getText();
|
|
16679
|
+
let decl = (symbol.flags & typescript.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol).valueDeclaration;
|
|
16680
|
+
return decl && typescript.isVariableDeclaration(decl) && decl.initializer || decl && typescript.isEnumMember(decl) && decl.initializer || decl && typescript.isBindingElement(decl) && decl.initializer ? resolveLiteralValue(typescript, checker, decl.initializer, depth + 1) : node.getText();
|
|
16681
|
+
}
|
|
16682
|
+
if (typescript.isPropertyAccessExpression(node)) {
|
|
16683
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
16684
|
+
if (symbol) {
|
|
16685
|
+
let decl = symbol.valueDeclaration;
|
|
16686
|
+
if (decl && typescript.isEnumMember(decl) && decl.initializer || decl && typescript.isPropertyAssignment(decl) && decl.initializer || decl && typescript.isVariableDeclaration(decl) && decl.initializer)
|
|
16687
|
+
return resolveLiteralValue(typescript, checker, decl.initializer, depth + 1);
|
|
16611
16688
|
}
|
|
16612
|
-
|
|
16613
|
-
|
|
16614
|
-
|
|
16689
|
+
return node.getText();
|
|
16690
|
+
}
|
|
16691
|
+
return node.getText();
|
|
16692
|
+
}
|
|
16693
|
+
function collectBindingDefaults(typescript, pattern, defaults, checker) {
|
|
16694
|
+
for (let element of pattern.elements)
|
|
16695
|
+
if (element.initializer) {
|
|
16696
|
+
let propName = element.propertyName ? element.propertyName.getText() : element.name.getText();
|
|
16697
|
+
defaults.set(
|
|
16698
|
+
propName,
|
|
16699
|
+
checker ? resolveLiteralValue(typescript, checker, element.initializer) : element.initializer.getText()
|
|
16615
16700
|
);
|
|
16616
|
-
return { kind: "resolved", path: renderPath };
|
|
16617
|
-
}, metaRender = getRenderPath(metaProps), storyRender = getRenderPath(storyProps);
|
|
16618
|
-
storyFn || (storyFn = storyRender.kind === "resolved" ? storyRender.path : storyRender.kind === "missing" && metaRender.kind === "resolved" ? metaRender.path : void 0);
|
|
16619
|
-
let metaArgs = metaArgsRecord(metaObj ?? null), storyArgsPath = storyProps.filter((p) => keyOf(p.node) === "args").map((p) => p.get("value")).find((v) => v.isObjectExpression()), storyArgs = argsRecordFromObjectPath(storyArgsPath), storyAssignedArgsPath = storyArgsAssignmentPath(csf._file.path, storyName), storyAssignedArgs = argsRecordFromObjectPath(storyAssignedArgsPath), merged = { ...metaArgs, ...storyArgs, ...storyAssignedArgs }, entries = Object.entries(merged).filter(([k]) => k !== "children"), validEntries = entries.filter(([k, v]) => isValidJsxAttrName(k) && v != null), invalidEntries = entries.filter(([k, v]) => !isValidJsxAttrName(k) && v != null), injectedAttrs = validEntries.map(([k, v]) => toAttr(k, v)).filter((a) => a != null);
|
|
16620
|
-
if (storyFn) {
|
|
16621
|
-
let fn = storyFn.node;
|
|
16622
|
-
if (t2.isArrowFunctionExpression(fn) && (t2.isJSXElement(fn.body) || t2.isJSXFragment(fn.body))) {
|
|
16623
|
-
let spreadRes = transformArgsSpreadsInJsx(fn.body, merged), inlineRes = inlineArgsInJsx(spreadRes.node, merged);
|
|
16624
|
-
if (spreadRes.changed || inlineRes.changed) {
|
|
16625
|
-
let newFn = t2.arrowFunctionExpression([], inlineRes.node, fn.async);
|
|
16626
|
-
return t2.variableDeclaration("const", [
|
|
16627
|
-
t2.variableDeclarator(t2.identifier(storyName), newFn)
|
|
16628
|
-
]);
|
|
16629
|
-
}
|
|
16630
|
-
}
|
|
16631
|
-
let stmts = t2.isFunctionDeclaration(fn) || t2.isArrowFunctionExpression(fn) && t2.isBlockStatement(fn.body) || t2.isFunctionExpression(fn) && t2.isBlockStatement(fn.body) ? fn.body.body : void 0;
|
|
16632
|
-
if (stmts) {
|
|
16633
|
-
let changed = !1, newBody = stmts.map((stmt) => {
|
|
16634
|
-
if (t2.isReturnStatement(stmt) && stmt.argument && (t2.isJSXElement(stmt.argument) || t2.isJSXFragment(stmt.argument))) {
|
|
16635
|
-
let spreadRes = transformArgsSpreadsInJsx(stmt.argument, merged), inlineRes = inlineArgsInJsx(spreadRes.node, merged);
|
|
16636
|
-
if (spreadRes.changed || inlineRes.changed)
|
|
16637
|
-
return changed = !0, t2.returnStatement(inlineRes.node);
|
|
16638
|
-
}
|
|
16639
|
-
return stmt;
|
|
16640
|
-
});
|
|
16641
|
-
if (changed)
|
|
16642
|
-
return t2.isFunctionDeclaration(fn) ? t2.functionDeclaration(
|
|
16643
|
-
t2.identifier(storyName),
|
|
16644
|
-
[],
|
|
16645
|
-
t2.blockStatement(newBody),
|
|
16646
|
-
fn.generator,
|
|
16647
|
-
fn.async
|
|
16648
|
-
) : t2.variableDeclaration("const", [
|
|
16649
|
-
t2.variableDeclarator(
|
|
16650
|
-
t2.identifier(storyName),
|
|
16651
|
-
t2.arrowFunctionExpression([], t2.blockStatement(newBody), fn.async)
|
|
16652
|
-
)
|
|
16653
|
-
]);
|
|
16654
16701
|
}
|
|
16655
|
-
return t2.isFunctionDeclaration(fn) ? t2.functionDeclaration(t2.identifier(storyName), fn.params, fn.body, fn.generator, fn.async) : t2.variableDeclaration("const", [t2.variableDeclarator(t2.identifier(storyName), fn)]);
|
|
16656
|
-
}
|
|
16657
|
-
invariant(componentName, "Could not generate snippet without component name.");
|
|
16658
|
-
let invalidSpread = buildInvalidSpread(invalidEntries), name = t2.jsxIdentifier(componentName), openingElAttrs = invalidSpread ? [...injectedAttrs, invalidSpread] : injectedAttrs, children = toJsxChildren(merged.children), selfClosing = children.length === 0, arrow = t2.arrowFunctionExpression(
|
|
16659
|
-
[],
|
|
16660
|
-
t2.jsxElement(
|
|
16661
|
-
t2.jsxOpeningElement(name, openingElAttrs, selfClosing),
|
|
16662
|
-
selfClosing ? null : t2.jsxClosingElement(name),
|
|
16663
|
-
children,
|
|
16664
|
-
selfClosing
|
|
16665
|
-
)
|
|
16666
|
-
);
|
|
16667
|
-
return t2.variableDeclaration("const", [t2.variableDeclarator(t2.identifier(storyName), arrow)]);
|
|
16668
16702
|
}
|
|
16669
|
-
function
|
|
16670
|
-
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
16674
|
-
);
|
|
16675
|
-
return t2.jsxSpreadAttribute(t2.objectExpression(objectProps));
|
|
16703
|
+
function unwrapExpression(typescript, expression) {
|
|
16704
|
+
let current2 = expression;
|
|
16705
|
+
for (; isWrappedExpression(typescript, current2); )
|
|
16706
|
+
current2 = current2.expression;
|
|
16707
|
+
return current2;
|
|
16676
16708
|
}
|
|
16677
|
-
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
|
|
16681
|
-
|
|
16682
|
-
|
|
16683
|
-
|
|
16684
|
-
let left = p.get("left"), right = p.get("right");
|
|
16685
|
-
if (left.isMemberExpression()) {
|
|
16686
|
-
let obj = left.get("object"), prop = left.get("property"), isStoryIdent = obj.isIdentifier() && obj.node.name === storyName, isArgsProp = prop.isIdentifier() && prop.node.name === "args" && !left.node.computed || t2.isStringLiteral(prop.node) && left.node.computed && prop.node.value === "args";
|
|
16687
|
-
isStoryIdent && isArgsProp && right.isObjectExpression() && (found = right);
|
|
16688
|
-
}
|
|
16689
|
-
}
|
|
16690
|
-
}), found;
|
|
16709
|
+
function isPropsIdentifier(typescript, node, paramName, checker) {
|
|
16710
|
+
if (!typescript.isIdentifier(node))
|
|
16711
|
+
return !1;
|
|
16712
|
+
if (!checker)
|
|
16713
|
+
return node.text === paramName.text;
|
|
16714
|
+
let symbol = checker.getSymbolAtLocation(node), paramSymbol = checker.getSymbolAtLocation(paramName);
|
|
16715
|
+
return symbol !== void 0 && symbol === paramSymbol;
|
|
16691
16716
|
}
|
|
16692
|
-
|
|
16693
|
-
|
|
16694
|
-
) :
|
|
16695
|
-
|
|
16696
|
-
|
|
16697
|
-
|
|
16698
|
-
|
|
16699
|
-
|
|
16700
|
-
|
|
16701
|
-
}, toAttr = (key, value) => t2.isBooleanLiteral(value) ? value.value ? t2.jsxAttribute(t2.jsxIdentifier(key), null) : t2.jsxAttribute(t2.jsxIdentifier(key), t2.jsxExpressionContainer(value)) : t2.isStringLiteral(value) ? t2.jsxAttribute(t2.jsxIdentifier(key), t2.stringLiteral(value.value)) : t2.isExpression(value) ? t2.jsxAttribute(t2.jsxIdentifier(key), t2.jsxExpressionContainer(value)) : null, toJsxChildren = (node) => node ? t2.isStringLiteral(node) ? [t2.jsxText(node.value)] : t2.isJSXElement(node) || t2.isJSXFragment(node) ? [node] : t2.isExpression(node) ? [t2.jsxExpressionContainer(node)] : [] : [];
|
|
16702
|
-
function getArgsMemberKey(expr) {
|
|
16703
|
-
if (t2.isMemberExpression(expr) && t2.isIdentifier(expr.object) && expr.object.name === "args") {
|
|
16704
|
-
if (t2.isIdentifier(expr.property) && !expr.computed)
|
|
16705
|
-
return expr.property.name;
|
|
16706
|
-
if (t2.isStringLiteral(expr.property) && expr.computed)
|
|
16707
|
-
return expr.property.value;
|
|
16708
|
-
}
|
|
16709
|
-
if (t2.isOptionalMemberExpression?.(expr) && t2.isIdentifier(expr.object) && expr.object.name === "args") {
|
|
16710
|
-
let prop = expr.property;
|
|
16711
|
-
if (t2.isIdentifier(prop) && !expr.computed)
|
|
16712
|
-
return prop.name;
|
|
16713
|
-
if (t2.isStringLiteral(prop) && expr.computed)
|
|
16714
|
-
return prop.value;
|
|
16715
|
-
}
|
|
16716
|
-
return null;
|
|
16717
|
+
function isPropsDerivedInitializer(typescript, initializer, paramName, checker) {
|
|
16718
|
+
let expr = unwrapExpression(typescript, initializer);
|
|
16719
|
+
return isPropsIdentifier(typescript, expr, paramName, checker) ? !0 : typescript.isAwaitExpression(expr) ? isPropsDerivedInitializer(typescript, expr.expression, paramName, checker) : typescript.isBinaryExpression(expr) && [
|
|
16720
|
+
typescript.SyntaxKind.BarBarToken,
|
|
16721
|
+
typescript.SyntaxKind.QuestionQuestionToken,
|
|
16722
|
+
typescript.SyntaxKind.AmpersandAmpersandToken
|
|
16723
|
+
].includes(expr.operatorToken.kind) ? isPropsDerivedInitializer(typescript, expr.left, paramName, checker) || isPropsDerivedInitializer(typescript, expr.right, paramName, checker) : typescript.isConditionalExpression(expr) ? isPropsDerivedInitializer(typescript, expr.whenTrue, paramName, checker) || isPropsDerivedInitializer(typescript, expr.whenFalse, paramName, checker) : typescript.isCallExpression(expr) || typescript.isNewExpression(expr) ? expr.arguments?.some(
|
|
16724
|
+
(arg) => isPropsDerivedInitializer(typescript, arg, paramName, checker)
|
|
16725
|
+
) ?? !1 : !1;
|
|
16717
16726
|
}
|
|
16718
|
-
function
|
|
16719
|
-
let
|
|
16720
|
-
if (
|
|
16721
|
-
|
|
16722
|
-
|
|
16723
|
-
|
|
16724
|
-
|
|
16725
|
-
|
|
16726
|
-
|
|
16727
|
-
|
|
16728
|
-
|
|
16729
|
-
|
|
16730
|
-
|
|
16731
|
-
|
|
16732
|
-
|
|
16733
|
-
|
|
16734
|
-
|
|
16735
|
-
|
|
16736
|
-
|
|
16737
|
-
|
|
16738
|
-
|
|
16739
|
-
return
|
|
16740
|
-
|
|
16741
|
-
|
|
16742
|
-
|
|
16743
|
-
|
|
16744
|
-
|
|
16745
|
-
|
|
16746
|
-
|
|
16747
|
-
|
|
16727
|
+
function extractDestructuringDefaults(typescript, resolved, checker) {
|
|
16728
|
+
let defaults = /* @__PURE__ */ new Map(), decl = resolved.valueDeclaration;
|
|
16729
|
+
if (!decl)
|
|
16730
|
+
return defaults;
|
|
16731
|
+
let fn;
|
|
16732
|
+
if (typescript.isFunctionDeclaration(decl)) {
|
|
16733
|
+
if (fn = decl, !fn.body) {
|
|
16734
|
+
let allDecls = resolved.getDeclarations?.() ?? [];
|
|
16735
|
+
for (let d of allDecls)
|
|
16736
|
+
if (typescript.isFunctionDeclaration(d) && d.body) {
|
|
16737
|
+
fn = d;
|
|
16738
|
+
break;
|
|
16739
|
+
}
|
|
16740
|
+
}
|
|
16741
|
+
} else typescript.isVariableDeclaration(decl) && decl.initializer ? fn = unwrapToFunction(typescript, decl.initializer, 0, checker) : typescript.isExportAssignment(decl) && decl.expression && (fn = unwrapToFunction(typescript, decl.expression, 0, checker));
|
|
16742
|
+
if (!fn)
|
|
16743
|
+
return defaults;
|
|
16744
|
+
let firstParam = fn.parameters[0];
|
|
16745
|
+
if (!firstParam)
|
|
16746
|
+
return defaults;
|
|
16747
|
+
if (typescript.isObjectBindingPattern(firstParam.name))
|
|
16748
|
+
return collectBindingDefaults(typescript, firstParam.name, defaults, checker), defaults;
|
|
16749
|
+
let propsParamName = typescript.isIdentifier(firstParam.name) ? firstParam.name : void 0;
|
|
16750
|
+
if (fn.body && propsParamName) {
|
|
16751
|
+
let body = typescript.isBlock(fn.body) ? fn.body : void 0;
|
|
16752
|
+
if (body) {
|
|
16753
|
+
for (let stmt of body.statements)
|
|
16754
|
+
if (typescript.isVariableStatement(stmt))
|
|
16755
|
+
for (let varDecl of stmt.declarationList.declarations)
|
|
16756
|
+
typescript.isObjectBindingPattern(varDecl.name) && varDecl.initializer && isPropsDerivedInitializer(typescript, varDecl.initializer, propsParamName, checker) && collectBindingDefaults(typescript, varDecl.name, defaults, checker);
|
|
16757
|
+
}
|
|
16748
16758
|
}
|
|
16749
|
-
|
|
16750
|
-
|
|
16751
|
-
|
|
16752
|
-
|
|
16759
|
+
return defaults;
|
|
16760
|
+
}
|
|
16761
|
+
function collectObjectLiteralDefaults(typescript, checker, obj, defaults) {
|
|
16762
|
+
for (let prop of obj.properties)
|
|
16763
|
+
if (typescript.isPropertyAssignment(prop) && prop.name) {
|
|
16764
|
+
let name = prop.name.getText();
|
|
16765
|
+
defaults.set(name, resolveLiteralValue(typescript, checker, prop.initializer));
|
|
16766
|
+
} else if (typescript.isShorthandPropertyAssignment(prop)) {
|
|
16767
|
+
let name = prop.name.getText(), symbol = checker.getShorthandAssignmentValueSymbol(prop);
|
|
16768
|
+
symbol?.valueDeclaration && typescript.isVariableDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.initializer ? defaults.set(
|
|
16769
|
+
name,
|
|
16770
|
+
resolveLiteralValue(typescript, checker, symbol.valueDeclaration.initializer)
|
|
16771
|
+
) : defaults.set(name, name);
|
|
16753
16772
|
}
|
|
16754
|
-
return t2.isJSXExpressionContainer(c) && getArgsMemberKey(c.expression) === "children" && "children" in merged ? (changed = !0, toJsxChildren(merged.children)) : [c];
|
|
16755
|
-
});
|
|
16756
|
-
return { node: t2.jsxFragment(node.openingFragment, node.closingFragment, fragChildren), changed };
|
|
16757
16773
|
}
|
|
16758
|
-
function
|
|
16759
|
-
let
|
|
16760
|
-
|
|
16761
|
-
return
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
|
|
16767
|
-
|
|
16768
|
-
|
|
16769
|
-
|
|
16770
|
-
|
|
16771
|
-
|
|
16772
|
-
|
|
16773
|
-
|
|
16774
|
-
|
|
16775
|
-
|
|
16776
|
-
return changed ||= res.changed, [res.node];
|
|
16774
|
+
function extractStaticDefaultProps(typescript, checker, resolved) {
|
|
16775
|
+
let defaults = /* @__PURE__ */ new Map(), decl = resolved.valueDeclaration ?? resolved.getDeclarations()?.[0];
|
|
16776
|
+
if (!decl)
|
|
16777
|
+
return defaults;
|
|
16778
|
+
let componentSourceFile = decl.getSourceFile();
|
|
16779
|
+
for (let stmt of componentSourceFile.statements) {
|
|
16780
|
+
if (typescript.isClassDeclaration(stmt) && stmt.name) {
|
|
16781
|
+
if (checker.getSymbolAtLocation(stmt.name) !== resolved)
|
|
16782
|
+
continue;
|
|
16783
|
+
for (let member of stmt.members) {
|
|
16784
|
+
if (!typescript.isPropertyDeclaration(member) || !member.name || member.name.getText() !== "defaultProps" || !member.initializer)
|
|
16785
|
+
continue;
|
|
16786
|
+
let initializer = member.initializer;
|
|
16787
|
+
if (typescript.isIdentifier(initializer)) {
|
|
16788
|
+
let symDecl = checker.getSymbolAtLocation(initializer)?.valueDeclaration;
|
|
16789
|
+
symDecl && typescript.isVariableDeclaration(symDecl) && symDecl.initializer && (initializer = symDecl.initializer);
|
|
16790
|
+
}
|
|
16791
|
+
typescript.isObjectLiteralExpression(initializer) && collectObjectLiteralDefaults(typescript, checker, initializer, defaults);
|
|
16777
16792
|
}
|
|
16778
|
-
return [c];
|
|
16779
|
-
}), children = sawArgsSpread && newChildren.length === 0 && merged.children ? (changed = !0, toJsxChildren(merged.children)) : newChildren, selfClosing = children.length === 0;
|
|
16780
|
-
return {
|
|
16781
|
-
node: t2.jsxElement(
|
|
16782
|
-
t2.jsxOpeningElement(opening.name, newAttrs, selfClosing),
|
|
16783
|
-
selfClosing ? null : node.closingElement ?? t2.jsxClosingElement(opening.name),
|
|
16784
|
-
children,
|
|
16785
|
-
selfClosing
|
|
16786
|
-
),
|
|
16787
|
-
changed
|
|
16788
|
-
};
|
|
16789
|
-
}
|
|
16790
|
-
let fragChildren = node.children.flatMap((c) => {
|
|
16791
|
-
if (t2.isJSXElement(c) || t2.isJSXFragment(c)) {
|
|
16792
|
-
let res = transformArgsSpreadsInJsx(c, merged);
|
|
16793
|
-
return changed ||= res.changed, [res.node];
|
|
16794
16793
|
}
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
16799
|
-
|
|
16800
|
-
|
|
16801
|
-
|
|
16802
|
-
|
|
16803
|
-
|
|
16804
|
-
|
|
16805
|
-
|
|
16806
|
-
|
|
16807
|
-
|
|
16808
|
-
if (decl.isFunctionDeclaration() && decl.node.id?.name === identifier.node.name)
|
|
16809
|
-
return decl;
|
|
16794
|
+
if (typescript.isExpressionStatement(stmt) && typescript.isBinaryExpression(stmt.expression) && stmt.expression.operatorToken.kind === typescript.SyntaxKind.EqualsToken) {
|
|
16795
|
+
let left = stmt.expression.left;
|
|
16796
|
+
if (!typescript.isPropertyAccessExpression(left) || left.name.text !== "defaultProps")
|
|
16797
|
+
continue;
|
|
16798
|
+
let targetSymbol = checker.getSymbolAtLocation(left.expression);
|
|
16799
|
+
if (!targetSymbol || (targetSymbol.flags & typescript.SymbolFlags.Alias ? checker.getAliasedSymbol(targetSymbol) : targetSymbol) !== resolved)
|
|
16800
|
+
continue;
|
|
16801
|
+
let right = stmt.expression.right;
|
|
16802
|
+
if (typescript.isIdentifier(right)) {
|
|
16803
|
+
let symDecl = checker.getSymbolAtLocation(right)?.valueDeclaration;
|
|
16804
|
+
symDecl && typescript.isVariableDeclaration(symDecl) && symDecl.initializer && (right = symDecl.initializer);
|
|
16805
|
+
}
|
|
16806
|
+
typescript.isObjectLiteralExpression(right) && collectObjectLiteralDefaults(typescript, checker, right, defaults);
|
|
16810
16807
|
}
|
|
16811
16808
|
}
|
|
16812
|
-
|
|
16813
|
-
if (stmt.isVariableDeclaration())
|
|
16814
|
-
return stmt.get("declarations");
|
|
16815
|
-
if (stmt.isExportNamedDeclaration()) {
|
|
16816
|
-
let decl = stmt.get("declaration");
|
|
16817
|
-
if (decl && decl.isVariableDeclaration())
|
|
16818
|
-
return decl.get("declarations");
|
|
16819
|
-
}
|
|
16820
|
-
return [];
|
|
16821
|
-
}).find((d) => {
|
|
16822
|
-
let id = d.get("id");
|
|
16823
|
-
return id.isIdentifier() && id.node.name === identifier.node.name;
|
|
16824
|
-
});
|
|
16825
|
-
if (!match)
|
|
16826
|
-
return null;
|
|
16827
|
-
let init = match.get("init");
|
|
16828
|
-
return init && init.isExpression() ? init : null;
|
|
16809
|
+
return defaults;
|
|
16829
16810
|
}
|
|
16830
|
-
function
|
|
16831
|
-
|
|
16832
|
-
|
|
16833
|
-
|
|
16834
|
-
|
|
16835
|
-
enter(p) {
|
|
16836
|
-
p.node && p.node === target && (found = p, p.stop());
|
|
16837
|
-
}
|
|
16838
|
-
}), found;
|
|
16811
|
+
function getJSDocDefault(typescript, prop, checker) {
|
|
16812
|
+
let tags = prop.getJsDocTags(checker);
|
|
16813
|
+
for (let tag of tags)
|
|
16814
|
+
if (tag.name === "default" || tag.name === "defaultValue")
|
|
16815
|
+
return typescript.displayPartsToString(tag.text) || void 0;
|
|
16839
16816
|
}
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
for (let prop of Object.values(props)) {
|
|
16852
|
-
let source = getPropSource(prop);
|
|
16853
|
-
(source?.includes("node_modules") || source?.endsWith(".d.ts")) && countBySource.set(source, (countBySource.get(source) ?? 0) + 1);
|
|
16854
|
-
}
|
|
16855
|
-
let largeNonUserSources = /* @__PURE__ */ new Set();
|
|
16856
|
-
for (let [source, count] of countBySource)
|
|
16857
|
-
count > LARGE_NON_USER_SOURCE_THRESHOLD && largeNonUserSources.add(source);
|
|
16858
|
-
return largeNonUserSources;
|
|
16859
|
-
};
|
|
16860
|
-
function findDisplayNameAssignment(typescript, sourceFile, identifierName) {
|
|
16861
|
-
for (let statement of sourceFile.statements) {
|
|
16862
|
-
if (!typescript.isExpressionStatement(statement))
|
|
16863
|
-
continue;
|
|
16864
|
-
let expr = statement.expression;
|
|
16865
|
-
if (typescript.isBinaryExpression(expr) && expr.operatorToken.kind === typescript.SyntaxKind.EqualsToken && typescript.isPropertyAccessExpression(expr.left) && expr.left.name.text === "displayName" && typescript.isIdentifier(expr.left.expression) && expr.left.expression.text === identifierName && typescript.isStringLiteral(expr.right))
|
|
16866
|
-
return expr.right.text;
|
|
16867
|
-
}
|
|
16817
|
+
function extractPropItem(typescript, checker, prop, contextNode, defaultsMap) {
|
|
16818
|
+
let isRequired = !!!(prop.flags & typescript.SymbolFlags.Optional), propType = checker.getTypeOfSymbolAtLocation(prop, contextNode), type = serializeType(typescript, checker, propType, isRequired), description = typescript.displayPartsToString(prop.getDocumentationComment(checker)), parent = getParentType(typescript, prop), declarations = getAllDeclarationParents(typescript, prop), propName = prop.getName(), destructuringDefault = defaultsMap?.get(propName), jsDocDefault = getJSDocDefault(typescript, prop, checker), defaultStr = destructuringDefault ?? jsDocDefault;
|
|
16819
|
+
return {
|
|
16820
|
+
name: propName,
|
|
16821
|
+
required: isRequired,
|
|
16822
|
+
type,
|
|
16823
|
+
description,
|
|
16824
|
+
defaultValue: defaultStr !== void 0 ? { value: defaultStr } : null,
|
|
16825
|
+
parent,
|
|
16826
|
+
declarations
|
|
16827
|
+
};
|
|
16868
16828
|
}
|
|
16869
|
-
function
|
|
16870
|
-
let
|
|
16871
|
-
|
|
16872
|
-
return
|
|
16873
|
-
|
|
16874
|
-
for (let
|
|
16875
|
-
let
|
|
16876
|
-
|
|
16877
|
-
continue;
|
|
16878
|
-
let type = checker.getTypeOfSymbolAtLocation(resolved, declaration), isStateless = type.getCallSignatures().some((sig) => {
|
|
16879
|
-
let params = sig.getParameters();
|
|
16880
|
-
return params.length === 1 || params.length > 0 && params[0].getName() === "props";
|
|
16881
|
-
}), isStateful = type.getConstructSignatures().some(
|
|
16882
|
-
(sig) => sig.getReturnType().getProperty("props") !== void 0
|
|
16883
|
-
);
|
|
16884
|
-
if (isStateless || isStateful) {
|
|
16885
|
-
let exportName = exportSymbol.getName(), resolvedName = resolved.getName();
|
|
16886
|
-
result.set(resolvedName, exportName), exportName === "default" && result.set(fileName, "default");
|
|
16887
|
-
let displayNameValue = findDisplayNameAssignment(typescript, sourceFile, resolvedName);
|
|
16888
|
-
displayNameValue && result.set(displayNameValue, exportName);
|
|
16889
|
-
}
|
|
16829
|
+
function getBulkSourceExclusions(properties) {
|
|
16830
|
+
let propSourceCache = /* @__PURE__ */ new Map(), getSource = (prop) => {
|
|
16831
|
+
let cached2 = propSourceCache.get(prop);
|
|
16832
|
+
return cached2 === void 0 && !propSourceCache.has(prop) && (cached2 = getPropSourceFile(prop), propSourceCache.set(prop, cached2)), cached2;
|
|
16833
|
+
}, sourceCount = /* @__PURE__ */ new Map();
|
|
16834
|
+
for (let prop of properties) {
|
|
16835
|
+
let source = getSource(prop);
|
|
16836
|
+
source && (source.includes("node_modules") || source.endsWith(".d.ts")) && sourceCount.set(source, (sourceCount.get(source) ?? 0) + 1);
|
|
16890
16837
|
}
|
|
16891
|
-
|
|
16892
|
-
|
|
16893
|
-
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
|
|
16897
|
-
async function getParser5(userOptions) {
|
|
16898
|
-
let [typescript, reactDocgenTypescript] = await Promise.all([
|
|
16899
|
-
loadTypeScript(),
|
|
16900
|
-
loadReactDocgenTypescript()
|
|
16901
|
-
]), optionsKey = JSON.stringify(userOptions ?? {});
|
|
16902
|
-
if (parser && cachedParserOptionsKey !== optionsKey && (parser = void 0), !parser) {
|
|
16903
|
-
let configPath = findTsconfigPath(process.cwd());
|
|
16904
|
-
if (cachedCompilerOptions = { noErrorTruncation: !0, strict: !0 }, configPath) {
|
|
16905
|
-
let { config } = typescript.readConfigFile(configPath, typescript.sys.readFile), parsed = typescript.parseJsonConfigFileContent(
|
|
16906
|
-
config,
|
|
16907
|
-
typescript.sys,
|
|
16908
|
-
dirname7(configPath)
|
|
16909
|
-
);
|
|
16910
|
-
cachedCompilerOptions = { ...parsed.options, noErrorTruncation: !0 }, cachedFileNames = parsed.fileNames;
|
|
16911
|
-
} else
|
|
16912
|
-
logger6.warn(
|
|
16913
|
-
"No tsconfig.json (or tsconfig.base.json / tsconfig.app.json) found. TypeScript component props will not be documented by react-docgen-typescript. Create a tsconfig.json in your project root to enable automatic controls."
|
|
16914
|
-
);
|
|
16915
|
-
let program = typescript.createProgram(
|
|
16916
|
-
cachedFileNames ?? [],
|
|
16917
|
-
cachedCompilerOptions,
|
|
16918
|
-
void 0,
|
|
16919
|
-
previousProgram
|
|
16920
|
-
);
|
|
16921
|
-
previousProgram = program;
|
|
16922
|
-
let parserOptions = {
|
|
16923
|
-
shouldExtractLiteralValuesFromEnum: !0,
|
|
16924
|
-
shouldRemoveUndefinedFromOptional: !0,
|
|
16925
|
-
...userOptions,
|
|
16926
|
-
// Always force savePropValueAsString so default values are in a consistent format
|
|
16927
|
-
savePropValueAsString: !0
|
|
16928
|
-
};
|
|
16929
|
-
parser = {
|
|
16930
|
-
program,
|
|
16931
|
-
fileParser: reactDocgenTypescript.withCompilerOptions(cachedCompilerOptions, parserOptions)
|
|
16932
|
-
}, cachedParserOptionsKey = optionsKey;
|
|
16838
|
+
let bulkSources = new Set(
|
|
16839
|
+
[...sourceCount.entries()].filter(([, count]) => count > LARGE_SOURCE_THRESHOLD).map(([source]) => source)
|
|
16840
|
+
), excluded = /* @__PURE__ */ new Set();
|
|
16841
|
+
for (let prop of properties) {
|
|
16842
|
+
let source = getSource(prop);
|
|
16843
|
+
source && bulkSources.has(source) && excluded.add(prop.getName());
|
|
16933
16844
|
}
|
|
16934
|
-
return
|
|
16845
|
+
return excluded;
|
|
16935
16846
|
}
|
|
16936
|
-
function
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
componentName
|
|
16847
|
+
function computeDisplayName({
|
|
16848
|
+
exportSymbol,
|
|
16849
|
+
resolvedSymbol
|
|
16940
16850
|
}) {
|
|
16941
|
-
|
|
16942
|
-
|
|
16943
|
-
|
|
16944
|
-
|
|
16851
|
+
let resolvedName = resolvedSymbol.getName();
|
|
16852
|
+
if (!exportSymbol)
|
|
16853
|
+
return resolvedName && resolvedName !== "default" && resolvedName !== "__function" ? resolvedName : void 0;
|
|
16854
|
+
let exportName = exportSymbol.getName();
|
|
16855
|
+
return exportName === "default" ? resolvedName && resolvedName !== "default" && resolvedName !== "__function" ? resolvedName : void 0 : exportName;
|
|
16945
16856
|
}
|
|
16946
|
-
function
|
|
16947
|
-
|
|
16948
|
-
|
|
16949
|
-
|
|
16950
|
-
|
|
16951
|
-
return
|
|
16952
|
-
name
|
|
16953
|
-
|
|
16954
|
-
|
|
16955
|
-
|
|
16956
|
-
|
|
16957
|
-
`)
|
|
16958
|
-
} : {
|
|
16959
|
-
name: "react-docgen-typescript could not match component docs",
|
|
16960
|
-
message: [
|
|
16961
|
-
`File: ${path5}`,
|
|
16962
|
-
"react-docgen-typescript returned component docs for this file, but none matched the story's component import.",
|
|
16963
|
-
`Looked for: componentName=${componentName}, localImportName=${localImportName ?? "<none>"}, importName=${importName ?? "<none>"}.`
|
|
16964
|
-
].join(`
|
|
16965
|
-
`)
|
|
16966
|
-
};
|
|
16857
|
+
function extractComponentJsDocTags(typescript, checker, symbol) {
|
|
16858
|
+
let tags = symbol.getJsDocTags(checker);
|
|
16859
|
+
if (tags.length === 0)
|
|
16860
|
+
return;
|
|
16861
|
+
let groupedTags = groupBy(tags, (tag) => tag.name);
|
|
16862
|
+
return Object.fromEntries(
|
|
16863
|
+
Object.entries(groupedTags).map(([name, grouped]) => [
|
|
16864
|
+
name,
|
|
16865
|
+
(grouped ?? []).map((tag) => typescript.displayPartsToString(tag.text ?? []).trim())
|
|
16866
|
+
])
|
|
16867
|
+
);
|
|
16967
16868
|
}
|
|
16968
|
-
|
|
16969
|
-
|
|
16970
|
-
|
|
16971
|
-
|
|
16972
|
-
|
|
16973
|
-
|
|
16974
|
-
|
|
16975
|
-
|
|
16976
|
-
|
|
16977
|
-
|
|
16978
|
-
|
|
16979
|
-
|
|
16980
|
-
|
|
16981
|
-
|
|
16982
|
-
|
|
16983
|
-
|
|
16984
|
-
|
|
16985
|
-
|
|
16986
|
-
|
|
16987
|
-
|
|
16988
|
-
|
|
16989
|
-
);
|
|
16990
|
-
|
|
16991
|
-
|
|
16992
|
-
|
|
16993
|
-
|
|
16994
|
-
|
|
16995
|
-
|
|
16996
|
-
storyFilePath,
|
|
16997
|
-
typescriptOptions = {},
|
|
16998
|
-
docgenEngine,
|
|
16999
|
-
additionalComponentNames = []
|
|
17000
|
-
}) => {
|
|
17001
|
-
let { reactDocgenTypescriptOptions } = typescriptOptions, program = csf._file.path, componentSet = /* @__PURE__ */ new Set(), componentDepth = /* @__PURE__ */ new Map(), localToImport = /* @__PURE__ */ new Map(), jsxDepth = 0;
|
|
17002
|
-
program.traverse({
|
|
17003
|
-
JSXElement: {
|
|
17004
|
-
enter() {
|
|
17005
|
-
jsxDepth++;
|
|
17006
|
-
},
|
|
17007
|
-
exit() {
|
|
17008
|
-
jsxDepth--;
|
|
17009
|
-
}
|
|
17010
|
-
},
|
|
17011
|
-
JSXOpeningElement(p) {
|
|
17012
|
-
let n = p.node.name, name;
|
|
17013
|
-
if (t3.isJSXIdentifier(n))
|
|
17014
|
-
name = n.name, name && /[A-Z]/.test(name.charAt(0)) && componentSet.add(name);
|
|
17015
|
-
else if (t3.isJSXMemberExpression(n)) {
|
|
17016
|
-
let jsxNameToString = (nm) => t3.isJSXIdentifier(nm) ? nm.name : `${jsxNameToString(nm.object)}.${jsxNameToString(nm.property)}`;
|
|
17017
|
-
name = jsxNameToString(n), componentSet.add(name);
|
|
17018
|
-
}
|
|
17019
|
-
if (name) {
|
|
17020
|
-
let depth = jsxDepth - 1, existing = componentDepth.get(name);
|
|
17021
|
-
(existing === void 0 || depth < existing) && componentDepth.set(name, depth);
|
|
16869
|
+
function serializeComponentDoc(typescript, checker, {
|
|
16870
|
+
sourceFile,
|
|
16871
|
+
resolvedComponent,
|
|
16872
|
+
defaultsSourcePath
|
|
16873
|
+
}) {
|
|
16874
|
+
let { componentRef, propsType, symbol } = resolvedComponent, exportName = componentRef.importName;
|
|
16875
|
+
if (!exportName)
|
|
16876
|
+
return;
|
|
16877
|
+
let displayNameOverride = componentRef.componentName, isMemberSelection = !!componentRef.member, filePath = componentRef.path ?? sourceFile.fileName, resolved = resolveAliasedSymbol(typescript, checker, symbol), contextNode = resolved.valueDeclaration ?? resolved.getDeclarations()?.[0];
|
|
16878
|
+
if (!contextNode)
|
|
16879
|
+
return;
|
|
16880
|
+
let moduleSymbol = checker.getSymbolAtLocation(sourceFile), exportSymbol = moduleSymbol ? checker.getExportsOfModule(moduleSymbol).find((candidate) => candidate.getName() === exportName) : void 0, allProperties, unionForceOptional;
|
|
16881
|
+
if (isUnionType(propsType)) {
|
|
16882
|
+
let seen = /* @__PURE__ */ new Map(), forceOptional = /* @__PURE__ */ new Set(), unionMembers = propsType.types, allMemberPropSets = [];
|
|
16883
|
+
for (let member of unionMembers) {
|
|
16884
|
+
let memberPropNames = /* @__PURE__ */ new Set();
|
|
16885
|
+
for (let prop of member.getApparentProperties()) {
|
|
16886
|
+
let name = prop.getName();
|
|
16887
|
+
memberPropNames.add(name);
|
|
16888
|
+
let propType = checker.getTypeOfSymbolAtLocation(prop, contextNode), isOptional = !!(prop.flags & typescript.SymbolFlags.Optional), isDegraded = !!(propType.getFlags() & typescript.TypeFlags.Never) || !!(propType.getFlags() & typescript.TypeFlags.Undefined);
|
|
16889
|
+
(isOptional || isDegraded) && forceOptional.add(name);
|
|
16890
|
+
let existing = seen.get(name);
|
|
16891
|
+
if (!existing)
|
|
16892
|
+
seen.set(name, prop);
|
|
16893
|
+
else if (!isDegraded) {
|
|
16894
|
+
let existingType = checker.getTypeOfSymbolAtLocation(existing, contextNode);
|
|
16895
|
+
(!!(existingType.getFlags() & typescript.TypeFlags.Never) || !!(existingType.getFlags() & typescript.TypeFlags.Undefined)) && seen.set(name, prop);
|
|
16896
|
+
}
|
|
17022
16897
|
}
|
|
16898
|
+
allMemberPropSets.push(memberPropNames);
|
|
17023
16899
|
}
|
|
17024
|
-
|
|
17025
|
-
|
|
17026
|
-
|
|
17027
|
-
|
|
17028
|
-
|
|
17029
|
-
let
|
|
17030
|
-
|
|
17031
|
-
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
16900
|
+
for (let name of seen.keys())
|
|
16901
|
+
allMemberPropSets.every((s) => s.has(name)) || forceOptional.add(name);
|
|
16902
|
+
allProperties = Array.from(seen.values()), unionForceOptional = forceOptional;
|
|
16903
|
+
} else
|
|
16904
|
+
allProperties = propsType.getApparentProperties();
|
|
16905
|
+
let excluded = getBulkSourceExclusions(allProperties), defaultsMap = extractDestructuringDefaults(typescript, resolved, checker);
|
|
16906
|
+
if (defaultsMap.size === 0 && defaultsSourcePath) {
|
|
16907
|
+
let fallbackDefaults = extractDefaultsFromSourceFile(typescript, defaultsSourcePath, {
|
|
16908
|
+
exportName,
|
|
16909
|
+
localName: resolved.getName(),
|
|
16910
|
+
preferLocalName: isMemberSelection
|
|
16911
|
+
});
|
|
16912
|
+
for (let [key, value] of fallbackDefaults)
|
|
16913
|
+
defaultsMap.set(key, value);
|
|
16914
|
+
}
|
|
16915
|
+
let staticDefaults = extractStaticDefaultProps(typescript, checker, resolved);
|
|
16916
|
+
for (let [key, value] of staticDefaults)
|
|
16917
|
+
defaultsMap.has(key) || defaultsMap.set(key, value);
|
|
16918
|
+
let props = {};
|
|
16919
|
+
for (let prop of allProperties) {
|
|
16920
|
+
if (excluded.has(prop.getName()))
|
|
17035
16921
|
continue;
|
|
17036
|
-
let
|
|
17037
|
-
|
|
17038
|
-
for (let s of specifiers) {
|
|
17039
|
-
if (!("local" in s) || !s.local || isTypeSpecifier(s))
|
|
17040
|
-
continue;
|
|
17041
|
-
let importId = decl.source.value;
|
|
17042
|
-
if (t3.isImportDefaultSpecifier(s))
|
|
17043
|
-
localToImport.set(s.local.name, { importId, importName: "default" });
|
|
17044
|
-
else if (t3.isImportNamespaceSpecifier(s))
|
|
17045
|
-
localToImport.set(s.local.name, { importId, importName: "*" });
|
|
17046
|
-
else if (t3.isImportSpecifier(s)) {
|
|
17047
|
-
let imported = importedName(s.imported);
|
|
17048
|
-
localToImport.set(s.local.name, { importId, importName: imported });
|
|
17049
|
-
}
|
|
17050
|
-
}
|
|
16922
|
+
let item = extractPropItem(typescript, checker, prop, contextNode, defaultsMap);
|
|
16923
|
+
unionForceOptional?.has(prop.getName()) && (item.required = !1), props[prop.getName()] = item;
|
|
17051
16924
|
}
|
|
17052
|
-
let
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
},
|
|
17056
|
-
|
|
17057
|
-
|
|
17058
|
-
|
|
17059
|
-
|
|
17060
|
-
|
|
17061
|
-
|
|
17062
|
-
|
|
17063
|
-
|
|
17064
|
-
|
|
17065
|
-
|
|
17066
|
-
|
|
17067
|
-
|
|
17068
|
-
|
|
17069
|
-
|
|
17070
|
-
|
|
17071
|
-
|
|
17072
|
-
|
|
17073
|
-
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17077
|
-
|
|
17078
|
-
|
|
17079
|
-
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
if (
|
|
17102
|
-
let
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17112
|
-
|
|
17113
|
-
|
|
17114
|
-
|
|
17115
|
-
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17121
|
-
|
|
16925
|
+
let displayName = (isMemberSelection ? displayNameOverride : void 0) ?? computeDisplayName({
|
|
16926
|
+
exportSymbol,
|
|
16927
|
+
resolvedSymbol: resolved
|
|
16928
|
+
}) ?? displayNameOverride, description = typescript.displayPartsToString(resolved.getDocumentationComment(checker)), selectedJsDocTags = extractComponentJsDocTags(typescript, checker, resolved), exportResolved = exportSymbol && exportSymbol !== resolved ? resolveAliasedSymbol(typescript, checker, exportSymbol) : void 0, exportJsDocTags = exportResolved ? extractComponentJsDocTags(typescript, checker, exportResolved) : void 0, jsDocTags = selectedJsDocTags?.import || !exportJsDocTags?.import ? selectedJsDocTags : {
|
|
16929
|
+
...selectedJsDocTags ?? {},
|
|
16930
|
+
import: exportJsDocTags.import
|
|
16931
|
+
};
|
|
16932
|
+
return {
|
|
16933
|
+
displayName,
|
|
16934
|
+
exportName,
|
|
16935
|
+
filePath,
|
|
16936
|
+
description,
|
|
16937
|
+
jsDocTags,
|
|
16938
|
+
props
|
|
16939
|
+
};
|
|
16940
|
+
}
|
|
16941
|
+
function extractDefaultsFromSourceFile(typescript, filePath, {
|
|
16942
|
+
exportName,
|
|
16943
|
+
localName,
|
|
16944
|
+
preferLocalName = !1
|
|
16945
|
+
}) {
|
|
16946
|
+
let defaults = /* @__PURE__ */ new Map(), content = typescript.sys.readFile(filePath);
|
|
16947
|
+
if (!content)
|
|
16948
|
+
return defaults;
|
|
16949
|
+
let sf = typescript.createSourceFile(
|
|
16950
|
+
filePath,
|
|
16951
|
+
content,
|
|
16952
|
+
typescript.ScriptTarget.Latest,
|
|
16953
|
+
/* setParentNodes */
|
|
16954
|
+
!0
|
|
16955
|
+
), varMap = /* @__PURE__ */ new Map();
|
|
16956
|
+
for (let stmt of sf.statements) {
|
|
16957
|
+
if (typescript.isVariableStatement(stmt))
|
|
16958
|
+
for (let decl of stmt.declarationList.declarations)
|
|
16959
|
+
typescript.isIdentifier(decl.name) && decl.initializer && varMap.set(decl.name.text, decl.initializer);
|
|
16960
|
+
typescript.isFunctionDeclaration(stmt) && stmt.name && varMap.set(stmt.name.text, stmt);
|
|
16961
|
+
}
|
|
16962
|
+
let fn = preferLocalName ? findLocalFunction(typescript, sf, localName, varMap) ?? findExportedFunction(typescript, sf, exportName, varMap) : findExportedFunction(typescript, sf, exportName, varMap) ?? findLocalFunction(typescript, sf, localName, varMap);
|
|
16963
|
+
if (!fn)
|
|
16964
|
+
return defaults;
|
|
16965
|
+
let firstParam = fn.parameters[0];
|
|
16966
|
+
if (!firstParam)
|
|
16967
|
+
return defaults;
|
|
16968
|
+
if (typescript.isObjectBindingPattern(firstParam.name))
|
|
16969
|
+
collectBindingDefaults(typescript, firstParam.name, defaults);
|
|
16970
|
+
else if (fn.body) {
|
|
16971
|
+
let propsParamName = typescript.isIdentifier(firstParam.name) ? firstParam.name : void 0, body = typescript.isBlock(fn.body) ? fn.body : void 0;
|
|
16972
|
+
if (body && propsParamName) {
|
|
16973
|
+
for (let stmt of body.statements)
|
|
16974
|
+
if (typescript.isVariableStatement(stmt))
|
|
16975
|
+
for (let varDecl of stmt.declarationList.declarations)
|
|
16976
|
+
typescript.isObjectBindingPattern(varDecl.name) && varDecl.initializer && isPropsDerivedInitializer(typescript, varDecl.initializer, propsParamName) && collectBindingDefaults(typescript, varDecl.name, defaults);
|
|
16977
|
+
}
|
|
16978
|
+
}
|
|
16979
|
+
return defaults;
|
|
16980
|
+
}
|
|
16981
|
+
function findLocalFunction(typescript, sf, localName, varMap) {
|
|
16982
|
+
if (!localName)
|
|
16983
|
+
return;
|
|
16984
|
+
let targetExpr = varMap.get(localName);
|
|
16985
|
+
if (targetExpr)
|
|
16986
|
+
return unwrapToFunctionAST(typescript, targetExpr, varMap, 0);
|
|
16987
|
+
}
|
|
16988
|
+
function findExportedFunction(typescript, sf, exportName, varMap) {
|
|
16989
|
+
let targetExpr;
|
|
16990
|
+
for (let stmt of sf.statements) {
|
|
16991
|
+
if (exportName === "default" && typescript.isExportAssignment(stmt) && !stmt.isExportEquals) {
|
|
16992
|
+
targetExpr = stmt.expression;
|
|
16993
|
+
break;
|
|
16994
|
+
}
|
|
16995
|
+
if (typescript.isVariableStatement(stmt) && hasExportModifier(typescript, stmt)) {
|
|
16996
|
+
for (let decl of stmt.declarationList.declarations)
|
|
16997
|
+
if (typescript.isIdentifier(decl.name) && decl.name.text === exportName && decl.initializer) {
|
|
16998
|
+
targetExpr = decl.initializer;
|
|
16999
|
+
break;
|
|
17122
17000
|
}
|
|
17123
|
-
|
|
17124
|
-
|
|
17125
|
-
|
|
17126
|
-
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
|
|
17001
|
+
if (targetExpr)
|
|
17002
|
+
break;
|
|
17003
|
+
}
|
|
17004
|
+
if (typescript.isFunctionDeclaration(stmt) && hasExportModifier(typescript, stmt) && stmt.name?.text === exportName)
|
|
17005
|
+
return findFunctionImpl(typescript, sf, stmt.name.text) ?? stmt;
|
|
17006
|
+
if (typescript.isExportDeclaration(stmt) && stmt.exportClause && typescript.isNamedExports(stmt.exportClause)) {
|
|
17007
|
+
for (let spec of stmt.exportClause.elements) {
|
|
17008
|
+
let exported = spec.name.text, local = spec.propertyName ? spec.propertyName.text : spec.name.text;
|
|
17009
|
+
if (exported === exportName) {
|
|
17010
|
+
targetExpr = varMap.get(local);
|
|
17011
|
+
break;
|
|
17131
17012
|
}
|
|
17132
|
-
if (docgenEngine === "react-component-meta")
|
|
17133
|
-
return {
|
|
17134
|
-
...componentWithPackage,
|
|
17135
|
-
path: path5
|
|
17136
|
-
};
|
|
17137
17013
|
}
|
|
17138
|
-
|
|
17139
|
-
|
|
17140
|
-
|
|
17141
|
-
}
|
|
17142
|
-
|
|
17143
|
-
|
|
17144
|
-
}
|
|
17145
|
-
|
|
17146
|
-
|
|
17147
|
-
|
|
17148
|
-
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
|
|
17014
|
+
if (targetExpr)
|
|
17015
|
+
break;
|
|
17016
|
+
}
|
|
17017
|
+
}
|
|
17018
|
+
if (targetExpr || (targetExpr = varMap.get(exportName)), !!targetExpr)
|
|
17019
|
+
return unwrapToFunctionAST(typescript, targetExpr, varMap, 0);
|
|
17020
|
+
}
|
|
17021
|
+
function unwrapToFunctionAST(typescript, node, varMap, depth) {
|
|
17022
|
+
if (!(depth > MAX_UNWRAP_DEPTH)) {
|
|
17023
|
+
if (typescript.isFunctionExpression(node) || typescript.isArrowFunction(node) || typescript.isFunctionDeclaration(node))
|
|
17024
|
+
return node;
|
|
17025
|
+
if (typescript.isParenthesizedExpression(node) || typescript.isAsExpression(node) || typescript.isTypeAssertionExpression && typescript.isTypeAssertionExpression(node))
|
|
17026
|
+
return unwrapToFunctionAST(typescript, node.expression, varMap, depth + 1);
|
|
17027
|
+
if (typescript.isCallExpression(node)) {
|
|
17028
|
+
let callee = node.expression;
|
|
17029
|
+
if (typescript.isPropertyAccessExpression(callee) && typescript.isIdentifier(callee.expression) && callee.expression.text === "Object" && callee.name.text === "assign" && node.arguments.length >= 1 || node.arguments.length >= 1)
|
|
17030
|
+
return unwrapToFunctionAST(typescript, node.arguments[0], varMap, depth + 1);
|
|
17031
|
+
}
|
|
17032
|
+
if (typescript.isIdentifier(node)) {
|
|
17033
|
+
let init = varMap.get(node.text);
|
|
17034
|
+
if (init)
|
|
17035
|
+
return unwrapToFunctionAST(typescript, init, varMap, depth + 1);
|
|
17036
|
+
}
|
|
17037
|
+
}
|
|
17038
|
+
}
|
|
17039
|
+
function findFunctionImpl(typescript, sf, name) {
|
|
17040
|
+
for (let stmt of sf.statements)
|
|
17041
|
+
if (typescript.isFunctionDeclaration(stmt) && stmt.name?.text === name && stmt.body)
|
|
17042
|
+
return stmt;
|
|
17043
|
+
}
|
|
17044
|
+
function hasExportModifier(typescript, node) {
|
|
17045
|
+
return typescript.canHaveModifiers(node) && typescript.getModifiers(node)?.some((m) => m.kind === typescript.SyntaxKind.ExportKeyword) === !0;
|
|
17046
|
+
}
|
|
17047
|
+
|
|
17048
|
+
// src/componentManifest/componentMeta/ComponentMetaProject.ts
|
|
17049
|
+
var ComponentMetaProject = class {
|
|
17050
|
+
constructor(typescript, commandLine, configFileName, fsFileSnapshots = /* @__PURE__ */ new Map(), getCommandLineFn) {
|
|
17051
|
+
this.typescript = typescript;
|
|
17052
|
+
this.commandLine = commandLine;
|
|
17053
|
+
this.configFileName = configFileName;
|
|
17054
|
+
this.fsFileSnapshots = fsFileSnapshots;
|
|
17055
|
+
this.getCommandLineFn = getCommandLineFn;
|
|
17056
|
+
this.projectVersion = 0;
|
|
17057
|
+
this.shouldCheckRootFiles = !1;
|
|
17058
|
+
/** Entries to extract — set by the generator, replayed during warmup for targeted type resolution. */
|
|
17059
|
+
this.entries = [];
|
|
17060
|
+
let language = (0, import_language_core.createLanguage)(
|
|
17061
|
+
[{ getLanguageId: (fileName) => (0, import_typescript.resolveFileLanguageId)(fileName) }],
|
|
17062
|
+
new import_language_core.FileMap(typescript.sys.useCaseSensitiveFileNames),
|
|
17063
|
+
(fileName, includeFsFiles) => {
|
|
17064
|
+
if (!includeFsFiles)
|
|
17152
17065
|
return;
|
|
17153
|
-
|
|
17154
|
-
|
|
17155
|
-
|
|
17156
|
-
|
|
17157
|
-
|
|
17066
|
+
let cache = fsFileSnapshots.get(fileName), modifiedTime = typescript.sys.getModifiedTime?.(fileName)?.valueOf();
|
|
17067
|
+
if (!cache || cache[0] !== modifiedTime)
|
|
17068
|
+
if (typescript.sys.fileExists(fileName)) {
|
|
17069
|
+
let text = typescript.sys.readFile(fileName), snapshot2 = text !== void 0 ? typescript.ScriptSnapshot.fromString(text) : void 0;
|
|
17070
|
+
fsFileSnapshots.set(fileName, [modifiedTime, snapshot2]);
|
|
17071
|
+
} else
|
|
17072
|
+
fsFileSnapshots.set(fileName, [modifiedTime, void 0]);
|
|
17073
|
+
let snapshot = fsFileSnapshots.get(fileName)?.[1];
|
|
17074
|
+
snapshot ? language.scripts.set(fileName, snapshot) : language.scripts.delete(fileName);
|
|
17075
|
+
}
|
|
17076
|
+
), projectHost = {
|
|
17077
|
+
getCurrentDirectory: () => configFileName ? path2.dirname(configFileName) : commandLine.options.rootDir ?? process.cwd(),
|
|
17078
|
+
getCompilationSettings: () => this.commandLine.options,
|
|
17079
|
+
getProjectReferences: () => this.commandLine.projectReferences,
|
|
17080
|
+
getProjectVersion: () => (this.checkRootFilesUpdate(), this.projectVersion.toString()),
|
|
17081
|
+
getScriptFileNames: () => (this.checkRootFilesUpdate(), this.commandLine.fileNames)
|
|
17082
|
+
}, { languageServiceHost } = (0, import_typescript.createLanguageServiceHost)(
|
|
17083
|
+
typescript,
|
|
17084
|
+
typescript.sys,
|
|
17085
|
+
language,
|
|
17086
|
+
(s) => s,
|
|
17087
|
+
// asScriptId — identity for React (no URI mapping needed)
|
|
17088
|
+
projectHost
|
|
17089
|
+
);
|
|
17090
|
+
this.ls = typescript.createLanguageService(languageServiceHost);
|
|
17091
|
+
}
|
|
17092
|
+
getCommandLine() {
|
|
17093
|
+
return this.commandLine;
|
|
17094
|
+
}
|
|
17095
|
+
dispose() {
|
|
17096
|
+
clearTimeout(this.warmupTimer), this.ls.dispose();
|
|
17097
|
+
}
|
|
17098
|
+
// ---------------------------------------------------------------------------
|
|
17099
|
+
// Project management
|
|
17100
|
+
// ---------------------------------------------------------------------------
|
|
17101
|
+
/**
|
|
17102
|
+
* Batch-add multiple files to the project in one go. Only bumps projectVersion once, avoiding
|
|
17103
|
+
* repeated program rebuilds.
|
|
17104
|
+
*/
|
|
17105
|
+
ensureFiles(fileNames) {
|
|
17106
|
+
let added = !1;
|
|
17107
|
+
for (let fileName of fileNames)
|
|
17108
|
+
this.commandLine.fileNames.includes(fileName) || (this.commandLine.fileNames.push(fileName), added = !0);
|
|
17109
|
+
added && this.projectVersion++;
|
|
17110
|
+
}
|
|
17111
|
+
/**
|
|
17112
|
+
* Adapted from:
|
|
17113
|
+
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L436-L447
|
|
17114
|
+
*/
|
|
17115
|
+
checkRootFilesUpdate() {
|
|
17116
|
+
if (!this.shouldCheckRootFiles || (this.shouldCheckRootFiles = !1, !this.getCommandLineFn))
|
|
17117
|
+
return;
|
|
17118
|
+
let newCommandLine = this.getCommandLineFn();
|
|
17119
|
+
arrayItemsEqual(newCommandLine.fileNames, this.commandLine.fileNames) || (this.commandLine.fileNames = newCommandLine.fileNames, this.projectVersion++);
|
|
17120
|
+
}
|
|
17121
|
+
hasSourceFile(fileName) {
|
|
17122
|
+
return !!this.ls.getProgram()?.getSourceFile(fileName);
|
|
17123
|
+
}
|
|
17124
|
+
/**
|
|
17125
|
+
* Get all non-node_modules source file paths from the TS program. Used by ComponentMetaManager to
|
|
17126
|
+
* watch directories for file changes.
|
|
17127
|
+
*/
|
|
17128
|
+
getSourceFilePaths() {
|
|
17129
|
+
let program = this.ls.getProgram();
|
|
17130
|
+
return program ? program.getSourceFiles().map((sf) => sf.fileName.replace(/\\/g, "/")).filter((f) => !f.includes("node_modules")) : [];
|
|
17131
|
+
}
|
|
17132
|
+
/**
|
|
17133
|
+
* Adapted from:
|
|
17134
|
+
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L409-L432
|
|
17135
|
+
*
|
|
17136
|
+
* Created events only set shouldCheckRootFiles (version bump happens in checkRootFilesUpdate if
|
|
17137
|
+
* the file list actually changed). Deleted/created break early since they trigger a full config
|
|
17138
|
+
* reparse — processing remaining changes is unnecessary.
|
|
17139
|
+
*/
|
|
17140
|
+
onFilesChanged(changes) {
|
|
17141
|
+
for (let { filePath } of changes)
|
|
17142
|
+
this.fsFileSnapshots.delete(filePath);
|
|
17143
|
+
let oldVersion = this.projectVersion, program = this.ls.getProgram();
|
|
17144
|
+
for (let { filePath, type } of changes)
|
|
17145
|
+
if (type === "changed")
|
|
17146
|
+
program?.getSourceFile(filePath) && this.projectVersion++;
|
|
17147
|
+
else if (type === "deleted") {
|
|
17148
|
+
program?.getSourceFile(filePath) && this.projectVersion++, this.shouldCheckRootFiles = !0;
|
|
17149
|
+
break;
|
|
17150
|
+
} else if (type === "created") {
|
|
17151
|
+
this.shouldCheckRootFiles = !0;
|
|
17152
|
+
break;
|
|
17153
|
+
}
|
|
17154
|
+
this.projectVersion !== oldVersion && this.entries.length > 0 && (clearTimeout(this.warmupTimer), this.warmupTimer = setTimeout(() => {
|
|
17155
|
+
try {
|
|
17156
|
+
this.extractPropsFromStories(this.entries);
|
|
17157
|
+
} catch {
|
|
17158
|
+
}
|
|
17159
|
+
}, 100), this.warmupTimer?.unref?.());
|
|
17160
|
+
}
|
|
17161
|
+
// ---------------------------------------------------------------------------
|
|
17162
|
+
// Primary extraction method — probe-free
|
|
17163
|
+
// ---------------------------------------------------------------------------
|
|
17164
|
+
extractPropsFromStories(entries) {
|
|
17165
|
+
this.entries = entries;
|
|
17166
|
+
let allFiles = entries.flatMap(
|
|
17167
|
+
(entry) => entry.component?.path ? [entry.storyPath, entry.component.path] : [entry.storyPath]
|
|
17158
17168
|
);
|
|
17159
|
-
|
|
17160
|
-
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
let
|
|
17165
|
-
|
|
17166
|
-
|
|
17167
|
-
|
|
17168
|
-
|
|
17169
|
-
|
|
17170
|
-
|
|
17171
|
-
|
|
17172
|
-
|
|
17173
|
-
|
|
17174
|
-
|
|
17175
|
-
|
|
17176
|
-
|
|
17177
|
-
|
|
17178
|
-
|
|
17179
|
-
|
|
17180
|
-
|
|
17181
|
-
|
|
17182
|
-
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17169
|
+
this.ensureFiles(allFiles), this.ensureFresh(allFiles);
|
|
17170
|
+
let program = this.ls.getProgram();
|
|
17171
|
+
if (!program)
|
|
17172
|
+
return;
|
|
17173
|
+
let checker = program.getTypeChecker(), serializationContextByComponentPath = /* @__PURE__ */ new Map();
|
|
17174
|
+
for (let entry of entries)
|
|
17175
|
+
try {
|
|
17176
|
+
let storySourceFile = program.getSourceFile(entry.storyPath), entryComponent = entry.component, componentPath = entryComponent?.path, exportName = entryComponent?.importName;
|
|
17177
|
+
if (!storySourceFile || !componentPath || !exportName || !entryComponent)
|
|
17178
|
+
continue;
|
|
17179
|
+
let importId = entryComponent.importId, isPackageImport = importId && !importId.startsWith("."), componentSourceFile;
|
|
17180
|
+
if (isPackageImport) {
|
|
17181
|
+
let resolved = this.typescript.resolveModuleName(
|
|
17182
|
+
importId,
|
|
17183
|
+
entry.storyPath,
|
|
17184
|
+
this.commandLine.options,
|
|
17185
|
+
this.typescript.sys
|
|
17186
|
+
);
|
|
17187
|
+
componentSourceFile = resolved.resolvedModule ? program.getSourceFile(resolved.resolvedModule.resolvedFileName) : program.getSourceFile(componentPath);
|
|
17188
|
+
} else
|
|
17189
|
+
componentSourceFile = program.getSourceFile(componentPath);
|
|
17190
|
+
if (!componentSourceFile)
|
|
17191
|
+
continue;
|
|
17192
|
+
let resolvedComponent;
|
|
17193
|
+
if (importId && (resolvedComponent = resolvePropsFromStoryFile(
|
|
17194
|
+
this.typescript,
|
|
17195
|
+
checker,
|
|
17196
|
+
storySourceFile,
|
|
17197
|
+
entryComponent
|
|
17198
|
+
)), resolvedComponent || (resolvedComponent = this.resolveFromMetaComponent(
|
|
17199
|
+
checker,
|
|
17200
|
+
storySourceFile,
|
|
17201
|
+
entryComponent
|
|
17202
|
+
)), resolvedComponent || (resolvedComponent = resolvePropsFromComponentExport(
|
|
17203
|
+
this.typescript,
|
|
17204
|
+
checker,
|
|
17205
|
+
componentSourceFile,
|
|
17206
|
+
entryComponent
|
|
17207
|
+
)), !resolvedComponent)
|
|
17208
|
+
continue;
|
|
17209
|
+
let serializationContext = serializationContextByComponentPath.get(componentPath);
|
|
17210
|
+
if (serializationContext === void 0) {
|
|
17211
|
+
let resolvedFileName = componentSourceFile.fileName;
|
|
17212
|
+
serializationContext = {
|
|
17213
|
+
sourceFile: componentSourceFile,
|
|
17214
|
+
defaultsSourcePath: resolvedFileName.endsWith(".d.ts") || resolvedFileName.endsWith(".d.mts") || resolvedFileName.endsWith(".d.cts") ? componentPath : void 0
|
|
17215
|
+
}, serializationContextByComponentPath.set(componentPath, serializationContext);
|
|
17187
17216
|
}
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
}
|
|
17195
|
-
if (!c.localImportName)
|
|
17196
|
-
continue;
|
|
17197
|
-
if (overrideSpec.kind === "default") {
|
|
17198
|
-
let id = t3.identifier(c.localImportName);
|
|
17199
|
-
addUniqueBy(b.defaults, id, (d) => d.name === id.name);
|
|
17217
|
+
let doc = serializeComponentDoc(this.typescript, checker, {
|
|
17218
|
+
sourceFile: serializationContext.sourceFile,
|
|
17219
|
+
resolvedComponent,
|
|
17220
|
+
defaultsSourcePath: serializationContext.defaultsSourcePath
|
|
17221
|
+
});
|
|
17222
|
+
doc && (entryComponent.reactComponentMeta = doc, entryComponent.componentJsDocTags = doc.jsDocTags, entryComponent.importOverride = entryComponent.componentJsDocTags?.import?.[0]?.trim());
|
|
17223
|
+
} catch {
|
|
17200
17224
|
continue;
|
|
17201
17225
|
}
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
|
|
17205
|
-
|
|
17206
|
-
|
|
17207
|
-
|
|
17208
|
-
|
|
17226
|
+
}
|
|
17227
|
+
/**
|
|
17228
|
+
* Check mtime for specific files and bump projectVersion if any changed.
|
|
17229
|
+
*
|
|
17230
|
+
* This bypasses the sync() gate in createLanguageServiceHost — sync() only runs when
|
|
17231
|
+
* projectVersion changes, so mtime-based cache alone can't detect stale files. We do a targeted
|
|
17232
|
+
* mtime check for the files we're about to extract from, ensuring freshness even when the
|
|
17233
|
+
* fs.watch event hasn't arrived yet (race with HMR) or was missed entirely.
|
|
17234
|
+
*/
|
|
17235
|
+
ensureFresh(fileNames) {
|
|
17236
|
+
let stale = !1;
|
|
17237
|
+
for (let fileName of fileNames) {
|
|
17238
|
+
let cache = this.fsFileSnapshots.get(fileName);
|
|
17239
|
+
if (!cache)
|
|
17209
17240
|
continue;
|
|
17210
|
-
|
|
17241
|
+
let currentMtime = this.typescript.sys.getModifiedTime?.(fileName)?.valueOf();
|
|
17242
|
+
cache[0] !== currentMtime && (this.fsFileSnapshots.delete(fileName), stale = !0);
|
|
17211
17243
|
}
|
|
17212
|
-
|
|
17213
|
-
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
17220
|
-
|
|
17221
|
-
|
|
17222
|
-
|
|
17223
|
-
|
|
17224
|
-
|
|
17225
|
-
|
|
17226
|
-
|
|
17244
|
+
stale && this.projectVersion++;
|
|
17245
|
+
}
|
|
17246
|
+
// ---------------------------------------------------------------------------
|
|
17247
|
+
// Internal helpers
|
|
17248
|
+
// ---------------------------------------------------------------------------
|
|
17249
|
+
/**
|
|
17250
|
+
* Path 2 fallback: resolve the component type from the story file's `meta.component` property.
|
|
17251
|
+
* Only works when the user explicitly set `component:` in the meta — no node means no
|
|
17252
|
+
* extraction.
|
|
17253
|
+
*/
|
|
17254
|
+
resolveFromMetaComponent(checker, storySourceFile, componentRef) {
|
|
17255
|
+
let { member: memberAccess } = componentRef, moduleSymbol = checker.getSymbolAtLocation(storySourceFile);
|
|
17256
|
+
if (!moduleSymbol)
|
|
17257
|
+
return;
|
|
17258
|
+
let defaultExport = checker.getExportsOfModule(moduleSymbol).find((e) => e.getName() === "default");
|
|
17259
|
+
if (!defaultExport)
|
|
17260
|
+
return;
|
|
17261
|
+
let componentProp = checker.getTypeOfSymbol(defaultExport).getProperty("component");
|
|
17262
|
+
if (!componentProp?.valueDeclaration || !this.typescript.isPropertyAssignment(componentProp.valueDeclaration))
|
|
17263
|
+
return;
|
|
17264
|
+
let metaComponentInitializer = componentProp.valueDeclaration.initializer;
|
|
17265
|
+
if (!metaComponentInitializer || !metaComponentMatchesRef(
|
|
17266
|
+
this.typescript,
|
|
17267
|
+
checker,
|
|
17268
|
+
storySourceFile,
|
|
17269
|
+
componentRef,
|
|
17270
|
+
metaComponentInitializer
|
|
17271
|
+
))
|
|
17272
|
+
return;
|
|
17273
|
+
let componentType = checker.getTypeOfSymbol(componentProp), selectedSymbol = componentProp.valueDeclaration && this.typescript.isPropertyAssignment(componentProp.valueDeclaration) ? checker.getSymbolAtLocation(componentProp.valueDeclaration.initializer) : componentType.getSymbol?.();
|
|
17274
|
+
if (memberAccess) {
|
|
17275
|
+
let prop = componentType.getProperty(memberAccess);
|
|
17276
|
+
if (prop)
|
|
17277
|
+
componentType = checker.getTypeOfSymbol(prop), selectedSymbol = prop;
|
|
17278
|
+
else
|
|
17279
|
+
return;
|
|
17227
17280
|
}
|
|
17228
|
-
|
|
17229
|
-
|
|
17230
|
-
|
|
17231
|
-
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
|
|
17239
|
-
|
|
17240
|
-
|
|
17281
|
+
let propsType = resolvePropsFromComponentType(this.typescript, checker, componentType);
|
|
17282
|
+
if (!(!propsType || !selectedSymbol))
|
|
17283
|
+
return {
|
|
17284
|
+
componentRef,
|
|
17285
|
+
propsType,
|
|
17286
|
+
symbol: selectedSymbol
|
|
17287
|
+
};
|
|
17288
|
+
}
|
|
17289
|
+
};
|
|
17290
|
+
function arrayItemsEqual(a, b) {
|
|
17291
|
+
if (a.length !== b.length)
|
|
17292
|
+
return !1;
|
|
17293
|
+
let set = new Set(a);
|
|
17294
|
+
for (let file of b)
|
|
17295
|
+
if (!set.has(file))
|
|
17296
|
+
return !1;
|
|
17297
|
+
return !0;
|
|
17298
|
+
}
|
|
17299
|
+
|
|
17300
|
+
// src/componentManifest/componentMeta/ComponentMetaManager.ts
|
|
17301
|
+
var rootTsConfigNames = ["tsconfig.json", "jsconfig.json"], DEFAULT_INFERRED_OPTIONS = {
|
|
17302
|
+
strict: !0,
|
|
17303
|
+
esModuleInterop: !0,
|
|
17304
|
+
allowJs: !0,
|
|
17305
|
+
skipLibCheck: !0
|
|
17306
|
+
}, ComponentMetaManager = class {
|
|
17307
|
+
constructor(typescript) {
|
|
17308
|
+
this.typescript = typescript;
|
|
17309
|
+
// Adapted from:
|
|
17310
|
+
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L34-L37
|
|
17311
|
+
this.configProjects = /* @__PURE__ */ new Map();
|
|
17312
|
+
this.rootTsConfigs = /* @__PURE__ */ new Set();
|
|
17313
|
+
this.searchedDirs = /* @__PURE__ */ new Set();
|
|
17314
|
+
// Our own file watching layer
|
|
17315
|
+
this.watching = !1;
|
|
17316
|
+
this.watchersByDir = /* @__PURE__ */ new Map();
|
|
17317
|
+
this.pendingEvents = /* @__PURE__ */ new Map();
|
|
17318
|
+
// Adapted from:
|
|
17319
|
+
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L83
|
|
17320
|
+
this.fsFileSnapshots = /* @__PURE__ */ new Map();
|
|
17321
|
+
}
|
|
17322
|
+
// ---------------------------------------------------------------------------
|
|
17323
|
+
// Adapted from:
|
|
17324
|
+
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L70-L79
|
|
17325
|
+
// ---------------------------------------------------------------------------
|
|
17326
|
+
getProjectForFile(fileName) {
|
|
17327
|
+
let tsconfig = this.findMatchTSConfig(fileName);
|
|
17328
|
+
return tsconfig ? this.getOrCreateConfiguredProject(tsconfig) ?? this.getOrCreateInferredProject(fileName) : this.getOrCreateInferredProject(fileName);
|
|
17329
|
+
}
|
|
17330
|
+
/**
|
|
17331
|
+
* Batch-extract component props across all entries, grouping by tsconfig project so each project
|
|
17332
|
+
* builds its TS program only once.
|
|
17333
|
+
*/
|
|
17334
|
+
batchExtract(entries) {
|
|
17335
|
+
let extractableEntries = entries.filter(
|
|
17336
|
+
(storyRef) => storyRef.component?.path && storyRef.component.importName
|
|
17337
|
+
), byProject = groupByToMap(
|
|
17338
|
+
extractableEntries,
|
|
17339
|
+
(storyRef) => this.getProjectForFile(storyRef.storyPath)
|
|
17340
|
+
);
|
|
17341
|
+
for (let [project, projectEntries] of byProject)
|
|
17342
|
+
try {
|
|
17343
|
+
project.extractPropsFromStories(projectEntries);
|
|
17344
|
+
} catch (err) {
|
|
17345
|
+
logger7.debug(`[reactComponentMeta] Batch extraction failed: ${err}`);
|
|
17346
|
+
}
|
|
17347
|
+
}
|
|
17348
|
+
// ---------------------------------------------------------------------------
|
|
17349
|
+
// Adapted from:
|
|
17350
|
+
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L101-L234
|
|
17351
|
+
// ---------------------------------------------------------------------------
|
|
17352
|
+
findMatchTSConfig(filePath) {
|
|
17353
|
+
let fileName = filePath.replace(/\\/g, "/"), dir = path3.dirname(fileName);
|
|
17354
|
+
for (; !this.searchedDirs.has(dir); ) {
|
|
17355
|
+
this.searchedDirs.add(dir);
|
|
17356
|
+
for (let tsConfigName of rootTsConfigNames) {
|
|
17357
|
+
let tsconfigPath = path3.join(dir, tsConfigName).replace(/\\/g, "/");
|
|
17358
|
+
this.typescript.sys.fileExists(tsconfigPath) && this.rootTsConfigs.add(tsconfigPath);
|
|
17241
17359
|
}
|
|
17242
|
-
|
|
17243
|
-
|
|
17244
|
-
|
|
17245
|
-
|
|
17246
|
-
continue;
|
|
17247
|
-
let local = t3.identifier(c.localImportName), imported = t3.identifier(c.importName);
|
|
17248
|
-
addUniqueBy(
|
|
17249
|
-
b.named,
|
|
17250
|
-
t3.importSpecifier(local, imported),
|
|
17251
|
-
(n) => n.local.name === local.name && importedName(n.imported) === imported.name
|
|
17252
|
-
);
|
|
17253
|
-
continue;
|
|
17360
|
+
let parent = path3.dirname(dir);
|
|
17361
|
+
if (parent === dir)
|
|
17362
|
+
break;
|
|
17363
|
+
dir = parent;
|
|
17254
17364
|
}
|
|
17255
|
-
|
|
17256
|
-
|
|
17257
|
-
let
|
|
17258
|
-
|
|
17259
|
-
|
|
17260
|
-
|
|
17261
|
-
|
|
17262
|
-
|
|
17263
|
-
|
|
17264
|
-
|
|
17265
|
-
|
|
17266
|
-
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
|
|
17271
|
-
if (
|
|
17272
|
-
let
|
|
17273
|
-
|
|
17365
|
+
if (this.rootTsConfigs.size === 0)
|
|
17366
|
+
return null;
|
|
17367
|
+
let prepareClosestRootCommandLine = () => {
|
|
17368
|
+
let matches = [];
|
|
17369
|
+
for (let rootTsConfig of this.rootTsConfigs)
|
|
17370
|
+
isFileInDir(fileName, path3.dirname(rootTsConfig)) && matches.push(rootTsConfig);
|
|
17371
|
+
matches = matches.sort((a, b) => sortTSConfigs(fileName, a, b)), matches.length && getCommandLine(matches[0]);
|
|
17372
|
+
}, findIndirectReferenceTsconfig = () => findTSConfig((tsconfig) => !!this.configProjects.get(tsconfig)?.hasSourceFile(fileName)), findDirectIncludeTsconfig = () => findTSConfig((tsconfig) => {
|
|
17373
|
+
let commandLine = getCommandLine(tsconfig);
|
|
17374
|
+
return new Set(commandLine?.fileNames ?? []).has(fileName);
|
|
17375
|
+
}), findTSConfig = (match) => {
|
|
17376
|
+
let checked = /* @__PURE__ */ new Set();
|
|
17377
|
+
for (let rootTsConfig of [...this.rootTsConfigs].sort(
|
|
17378
|
+
(a, b) => sortTSConfigs(fileName, a, b)
|
|
17379
|
+
)) {
|
|
17380
|
+
let project = this.configProjects.get(rootTsConfig);
|
|
17381
|
+
if (project) {
|
|
17382
|
+
let chains = getReferencesChains(project.getCommandLine(), rootTsConfig, []);
|
|
17383
|
+
chains = chains.reverse();
|
|
17384
|
+
for (let chain of chains)
|
|
17385
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
17386
|
+
let tsconfig = chain[i];
|
|
17387
|
+
if (!checked.has(tsconfig) && (checked.add(tsconfig), match(tsconfig)))
|
|
17388
|
+
return tsconfig;
|
|
17389
|
+
}
|
|
17274
17390
|
}
|
|
17275
|
-
for (let d of defaults.slice(1))
|
|
17276
|
-
printDecl([t3.importDefaultSpecifier(d)], source);
|
|
17277
17391
|
}
|
|
17392
|
+
return null;
|
|
17393
|
+
}, getReferencesChains = (commandLine, tsConfig, before) => {
|
|
17394
|
+
if (commandLine.projectReferences?.length) {
|
|
17395
|
+
let newChains = [];
|
|
17396
|
+
for (let projectReference of commandLine.projectReferences) {
|
|
17397
|
+
let tsConfigPath = projectReference.path.replace(/\\/g, "/");
|
|
17398
|
+
if (this.typescript.sys.directoryExists(tsConfigPath)) {
|
|
17399
|
+
let newTsConfigPath = path3.join(tsConfigPath, "tsconfig.json"), newJsConfigPath = path3.join(tsConfigPath, "jsconfig.json");
|
|
17400
|
+
this.typescript.sys.fileExists(newTsConfigPath) ? tsConfigPath = newTsConfigPath : this.typescript.sys.fileExists(newJsConfigPath) && (tsConfigPath = newJsConfigPath);
|
|
17401
|
+
}
|
|
17402
|
+
let beforeIndex = before.indexOf(tsConfigPath);
|
|
17403
|
+
if (beforeIndex >= 0)
|
|
17404
|
+
newChains.push(before.slice(0, Math.max(beforeIndex, 1)));
|
|
17405
|
+
else {
|
|
17406
|
+
let referenceCommandLine = getCommandLine(tsConfigPath);
|
|
17407
|
+
if (referenceCommandLine)
|
|
17408
|
+
for (let chain of getReferencesChains(referenceCommandLine, tsConfigPath, [
|
|
17409
|
+
...before,
|
|
17410
|
+
tsConfig
|
|
17411
|
+
]))
|
|
17412
|
+
newChains.push(chain);
|
|
17413
|
+
}
|
|
17414
|
+
}
|
|
17415
|
+
return newChains;
|
|
17416
|
+
} else
|
|
17417
|
+
return [[...before, tsConfig]];
|
|
17418
|
+
}, getCommandLine = (tsConfig) => this.getOrCreateConfiguredProject(tsConfig)?.getCommandLine();
|
|
17419
|
+
return prepareClosestRootCommandLine(), findDirectIncludeTsconfig() ?? findIndirectReferenceTsconfig();
|
|
17278
17420
|
}
|
|
17279
|
-
|
|
17280
|
-
|
|
17281
|
-
|
|
17282
|
-
//
|
|
17283
|
-
|
|
17284
|
-
|
|
17285
|
-
|
|
17286
|
-
|
|
17287
|
-
|
|
17288
|
-
|
|
17289
|
-
|
|
17290
|
-
|
|
17291
|
-
|
|
17292
|
-
|
|
17293
|
-
|
|
17294
|
-
|
|
17295
|
-
|
|
17296
|
-
|
|
17297
|
-
|
|
17298
|
-
|
|
17299
|
-
|
|
17300
|
-
|
|
17301
|
-
|
|
17302
|
-
|
|
17303
|
-
|
|
17421
|
+
// ---------------------------------------------------------------------------
|
|
17422
|
+
// Adapted from:
|
|
17423
|
+
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L236-L256
|
|
17424
|
+
// ---------------------------------------------------------------------------
|
|
17425
|
+
getOrCreateConfiguredProject(tsconfig) {
|
|
17426
|
+
tsconfig = tsconfig.replace(/\\/g, "/");
|
|
17427
|
+
let project = this.configProjects.get(tsconfig);
|
|
17428
|
+
if (!project)
|
|
17429
|
+
try {
|
|
17430
|
+
let getCommandLine = () => this.parseConfigWorker(tsconfig);
|
|
17431
|
+
project = new ComponentMetaProject(
|
|
17432
|
+
this.typescript,
|
|
17433
|
+
getCommandLine(),
|
|
17434
|
+
tsconfig,
|
|
17435
|
+
this.fsFileSnapshots,
|
|
17436
|
+
getCommandLine
|
|
17437
|
+
), this.configProjects.set(tsconfig, project), this.watching && (this.watchDirectory(path3.dirname(tsconfig)), this.watchProgramSourceDirs(project));
|
|
17438
|
+
} catch (err) {
|
|
17439
|
+
return logger7.debug(`[reactComponentMeta] Failed to parse tsconfig ${tsconfig}: ${err}`), null;
|
|
17440
|
+
}
|
|
17441
|
+
return project;
|
|
17442
|
+
}
|
|
17443
|
+
// ---------------------------------------------------------------------------
|
|
17444
|
+
// Adapted from:
|
|
17445
|
+
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L258-L284
|
|
17446
|
+
// ---------------------------------------------------------------------------
|
|
17447
|
+
getOrCreateInferredProject(fileName) {
|
|
17448
|
+
return this.inferredProject || (this.inferredProject = new ComponentMetaProject(
|
|
17449
|
+
this.typescript,
|
|
17450
|
+
{
|
|
17451
|
+
options: {
|
|
17452
|
+
...DEFAULT_INFERRED_OPTIONS,
|
|
17453
|
+
target: this.typescript.ScriptTarget.Latest,
|
|
17454
|
+
module: this.typescript.ModuleKind.ESNext,
|
|
17455
|
+
moduleResolution: this.typescript.ModuleResolutionKind.Bundler,
|
|
17456
|
+
jsx: this.typescript.JsxEmit.ReactJSX
|
|
17457
|
+
},
|
|
17458
|
+
fileNames: [],
|
|
17459
|
+
errors: []
|
|
17460
|
+
},
|
|
17461
|
+
void 0,
|
|
17462
|
+
this.fsFileSnapshots
|
|
17463
|
+
)), this.inferredProject.ensureFiles([fileName]), this.inferredProject;
|
|
17464
|
+
}
|
|
17465
|
+
// ---------------------------------------------------------------------------
|
|
17466
|
+
// Adapted from:
|
|
17467
|
+
// https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProjectLs.ts#L262-L353
|
|
17468
|
+
// ---------------------------------------------------------------------------
|
|
17469
|
+
parseConfigWorker(tsconfig) {
|
|
17470
|
+
let config = this.typescript.readJsonConfigFile(tsconfig, this.typescript.sys.readFile), content = this.typescript.parseJsonSourceFileConfigFileContent(
|
|
17471
|
+
config,
|
|
17472
|
+
this.typescript.sys,
|
|
17473
|
+
path3.dirname(tsconfig),
|
|
17474
|
+
{},
|
|
17475
|
+
tsconfig
|
|
17304
17476
|
);
|
|
17305
|
-
|
|
17306
|
-
return declaration.init;
|
|
17477
|
+
return content.options.outDir = void 0, content.fileNames = content.fileNames.map((fileName) => fileName.replace(/\\/g, "/")), content;
|
|
17307
17478
|
}
|
|
17308
|
-
|
|
17309
|
-
|
|
17310
|
-
|
|
17311
|
-
|
|
17312
|
-
|
|
17313
|
-
|
|
17314
|
-
|
|
17315
|
-
|
|
17316
|
-
|
|
17479
|
+
// ---------------------------------------------------------------------------
|
|
17480
|
+
// File events
|
|
17481
|
+
// ---------------------------------------------------------------------------
|
|
17482
|
+
/**
|
|
17483
|
+
* Broadcast file changes to all projects. Each project selectively bumps projectVersion.
|
|
17484
|
+
*
|
|
17485
|
+
* Adapted from:
|
|
17486
|
+
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/kit/lib/createChecker.ts#L409-L432
|
|
17487
|
+
*/
|
|
17488
|
+
onFilesChanged(changes) {
|
|
17489
|
+
for (let project of this.configProjects.values())
|
|
17490
|
+
project.onFilesChanged(changes);
|
|
17491
|
+
this.inferredProject?.onFilesChanged(changes);
|
|
17492
|
+
}
|
|
17493
|
+
/**
|
|
17494
|
+
* Adapted from:
|
|
17495
|
+
* https://github.com/volarjs/volar.js/blob/882cd56d46a13d272f34e451f495d3d62251969a/packages/language-server/lib/project/typescriptProject.ts#L43-L68
|
|
17496
|
+
*/
|
|
17497
|
+
onConfigChanged(configPath, type) {
|
|
17498
|
+
if (configPath = configPath.replace(/\\/g, "/"), type === "created")
|
|
17499
|
+
this.rootTsConfigs.add(configPath);
|
|
17500
|
+
else if ((type === "changed" || type === "deleted") && this.configProjects.has(configPath)) {
|
|
17501
|
+
type === "deleted" && this.rootTsConfigs.delete(configPath);
|
|
17502
|
+
let project = this.configProjects.get(configPath);
|
|
17503
|
+
this.configProjects.delete(configPath), project?.dispose();
|
|
17317
17504
|
}
|
|
17318
|
-
|
|
17319
|
-
|
|
17320
|
-
|
|
17505
|
+
this.searchedDirs.clear();
|
|
17506
|
+
}
|
|
17507
|
+
// ---------------------------------------------------------------------------
|
|
17508
|
+
// Our own file watching layer (no Volar equivalent — we're standalone)
|
|
17509
|
+
// ---------------------------------------------------------------------------
|
|
17510
|
+
startWatching() {
|
|
17511
|
+
if (!this.watching) {
|
|
17512
|
+
this.watching = !0;
|
|
17513
|
+
for (let tsconfig of this.configProjects.keys())
|
|
17514
|
+
this.watchDirectory(path3.dirname(tsconfig));
|
|
17515
|
+
this.watchProgramSourceDirs();
|
|
17321
17516
|
}
|
|
17322
|
-
return current2;
|
|
17323
17517
|
}
|
|
17324
|
-
|
|
17325
|
-
|
|
17326
|
-
|
|
17327
|
-
|
|
17328
|
-
|
|
17329
|
-
|
|
17330
|
-
|
|
17331
|
-
|
|
17332
|
-
|
|
17333
|
-
|
|
17334
|
-
|
|
17335
|
-
|
|
17336
|
-
|
|
17337
|
-
|
|
17518
|
+
/**
|
|
17519
|
+
* Watch directories that contain source files from all TS programs. This covers monorepo setups
|
|
17520
|
+
* where stories import components via path aliases (e.g. apps/storybook/ imports from
|
|
17521
|
+
* packages/ui/ via tsconfig paths).
|
|
17522
|
+
*/
|
|
17523
|
+
watchProgramSourceDirs(singleProject) {
|
|
17524
|
+
let dirs = /* @__PURE__ */ new Set();
|
|
17525
|
+
if (singleProject)
|
|
17526
|
+
for (let filePath of singleProject.getSourceFilePaths())
|
|
17527
|
+
dirs.add(path3.dirname(filePath));
|
|
17528
|
+
else {
|
|
17529
|
+
for (let project of this.configProjects.values())
|
|
17530
|
+
for (let filePath of project.getSourceFilePaths())
|
|
17531
|
+
dirs.add(path3.dirname(filePath));
|
|
17532
|
+
if (this.inferredProject)
|
|
17533
|
+
for (let filePath of this.inferredProject.getSourceFilePaths())
|
|
17534
|
+
dirs.add(path3.dirname(filePath));
|
|
17535
|
+
}
|
|
17536
|
+
let roots = /* @__PURE__ */ new Set();
|
|
17537
|
+
for (let dir of dirs) {
|
|
17538
|
+
let candidate = dir;
|
|
17539
|
+
for (; candidate !== path3.dirname(candidate); ) {
|
|
17540
|
+
let normalized = candidate.replace(/\\/g, "/"), alreadyWatched = !1;
|
|
17541
|
+
for (let watched of this.watchersByDir.keys())
|
|
17542
|
+
if (normalized === watched || normalized.startsWith(watched + "/")) {
|
|
17543
|
+
alreadyWatched = !0;
|
|
17544
|
+
break;
|
|
17545
|
+
}
|
|
17546
|
+
if (alreadyWatched)
|
|
17547
|
+
break;
|
|
17548
|
+
if (this.typescript.sys.fileExists(path3.join(candidate, "package.json")) || this.typescript.sys.fileExists(path3.join(candidate, "tsconfig.json"))) {
|
|
17549
|
+
roots.add(candidate);
|
|
17550
|
+
break;
|
|
17551
|
+
}
|
|
17552
|
+
candidate = path3.dirname(candidate);
|
|
17553
|
+
}
|
|
17338
17554
|
}
|
|
17555
|
+
for (let root of roots)
|
|
17556
|
+
this.watchDirectory(root);
|
|
17339
17557
|
}
|
|
17340
|
-
|
|
17341
|
-
|
|
17342
|
-
// src/componentManifest/generator.ts
|
|
17343
|
-
var componentMetaManager;
|
|
17344
|
-
async function createComponentMetaManager(watch2) {
|
|
17345
|
-
if (componentMetaManager && watch2)
|
|
17346
|
-
return componentMetaManager;
|
|
17347
|
-
try {
|
|
17348
|
-
let ts = await import("typescript"), manager = new ComponentMetaManager(ts);
|
|
17349
|
-
return watch2 && (componentMetaManager = manager), manager;
|
|
17350
|
-
} catch {
|
|
17351
|
-
logger8.debug(
|
|
17352
|
-
"[reactComponentMeta] TypeScript not available, skipping component meta extraction"
|
|
17353
|
-
);
|
|
17354
|
-
}
|
|
17355
|
-
}
|
|
17356
|
-
function isAttachedDocsEntry(entry) {
|
|
17357
|
-
return entry.type === "docs" && entry.tags?.includes(Tag.ATTACHED_MDX) === !0 && entry.storiesImports.length > 0;
|
|
17358
|
-
}
|
|
17359
|
-
function selectComponentEntries(manifestEntries) {
|
|
17360
|
-
let entriesByComponentId = /* @__PURE__ */ new Map();
|
|
17361
|
-
return manifestEntries.filter(
|
|
17362
|
-
(entry) => entry.type === "story" && entry.subtype === "story" || // Attached docs entries are the only docs entries that can contribute to a
|
|
17363
|
-
// component manifest, because they point back to a story file through storiesImports.
|
|
17364
|
-
isAttachedDocsEntry(entry)
|
|
17365
|
-
).forEach((entry) => {
|
|
17366
|
-
let componentId = entry.id.split("--")[0], existingEntry = entriesByComponentId.get(componentId);
|
|
17367
|
-
if (!existingEntry) {
|
|
17368
|
-
entriesByComponentId.set(componentId, entry);
|
|
17558
|
+
watchDirectory(dir) {
|
|
17559
|
+
if (!this.watching)
|
|
17369
17560
|
return;
|
|
17561
|
+
let normalized = dir.replace(/\\/g, "/");
|
|
17562
|
+
for (let watched of this.watchersByDir.keys())
|
|
17563
|
+
if (normalized === watched || normalized.startsWith(watched + "/"))
|
|
17564
|
+
return;
|
|
17565
|
+
for (let [watched, watcher] of this.watchersByDir)
|
|
17566
|
+
watched.startsWith(normalized + "/") && (watcher.close(), this.watchersByDir.delete(watched));
|
|
17567
|
+
try {
|
|
17568
|
+
let watcher = watch(dir, { recursive: !0 }, (eventType, filename) => {
|
|
17569
|
+
if (!filename)
|
|
17570
|
+
return;
|
|
17571
|
+
let filePath = path3.resolve(dir, filename).replace(/\\/g, "/");
|
|
17572
|
+
if (filePath.includes("/node_modules/") || filePath.includes("/.git/"))
|
|
17573
|
+
return;
|
|
17574
|
+
let existing = this.pendingEvents.get(filePath);
|
|
17575
|
+
existing && clearTimeout(existing), this.pendingEvents.set(
|
|
17576
|
+
filePath,
|
|
17577
|
+
setTimeout(() => {
|
|
17578
|
+
this.pendingEvents.delete(filePath), eventType === "rename" ? existsSync3(filePath) ? this.handleFileEvent(filePath, "created") : this.handleFileEvent(filePath, "deleted") : this.handleFileEvent(filePath, "changed");
|
|
17579
|
+
}, 50)
|
|
17580
|
+
);
|
|
17581
|
+
});
|
|
17582
|
+
watcher.unref(), this.watchersByDir.set(normalized, watcher);
|
|
17583
|
+
} catch (err) {
|
|
17584
|
+
logger7.debug(`[reactComponentMeta] Failed to watch directory ${normalized}: ${err}`);
|
|
17370
17585
|
}
|
|
17371
|
-
existingEntry.type === "docs" && entry.type === "story" && entriesByComponentId.set(componentId, entry);
|
|
17372
|
-
}), [...entriesByComponentId.values()];
|
|
17373
|
-
}
|
|
17374
|
-
function findMatchingComponent(components, componentName, title) {
|
|
17375
|
-
let exactMatch = findExactComponentMatch(components, componentName);
|
|
17376
|
-
if (exactMatch)
|
|
17377
|
-
return exactMatch;
|
|
17378
|
-
let trimmedTitle = title.replace(/\s+/g, ""), matches = components.filter(
|
|
17379
|
-
(it) => trimmedTitle.includes(it.componentName) || it.localImportName && trimmedTitle.includes(it.localImportName) || it.importName && trimmedTitle.includes(it.importName)
|
|
17380
|
-
);
|
|
17381
|
-
if (matches.length <= 1)
|
|
17382
|
-
return matches[0];
|
|
17383
|
-
let best = matches[0];
|
|
17384
|
-
for (let cur of matches) {
|
|
17385
|
-
if (cur.jsxDepth === 0)
|
|
17386
|
-
return cur;
|
|
17387
|
-
(cur.jsxDepth ?? 1 / 0) < (best.jsxDepth ?? 1 / 0) && (best = cur);
|
|
17388
17586
|
}
|
|
17389
|
-
|
|
17390
|
-
|
|
17391
|
-
|
|
17392
|
-
|
|
17393
|
-
|
|
17394
|
-
|
|
17395
|
-
|
|
17396
|
-
|
|
17587
|
+
stopWatching() {
|
|
17588
|
+
for (let timeout of this.pendingEvents.values())
|
|
17589
|
+
clearTimeout(timeout);
|
|
17590
|
+
this.pendingEvents.clear();
|
|
17591
|
+
for (let watcher of this.watchersByDir.values())
|
|
17592
|
+
watcher.close();
|
|
17593
|
+
this.watchersByDir.clear(), this.watching = !1;
|
|
17594
|
+
}
|
|
17595
|
+
/**
|
|
17596
|
+
* Map raw fs.watch events to LSP-style FileChangeType before broadcasting.
|
|
17597
|
+
*
|
|
17598
|
+
* Fs.watch reports atomic saves (sed -i, editors) as `rename` → we classify as `created` (file
|
|
17599
|
+
* exists after rename). But an IDE/LSP would report an atomic save of an _existing_ file as
|
|
17600
|
+
* `Changed`, not `Created`.
|
|
17601
|
+
*
|
|
17602
|
+
* We reclassify here so that onFilesChanged stays 1:1 with Volar Kit.
|
|
17603
|
+
*/
|
|
17604
|
+
handleFileEvent(filePath, type) {
|
|
17605
|
+
if (type === "created") {
|
|
17606
|
+
for (let project of this.configProjects.values())
|
|
17607
|
+
if (project.hasSourceFile(filePath)) {
|
|
17608
|
+
type = "changed";
|
|
17609
|
+
break;
|
|
17610
|
+
}
|
|
17611
|
+
type === "created" && this.inferredProject?.hasSourceFile(filePath) && (type = "changed");
|
|
17612
|
+
}
|
|
17613
|
+
let basename3 = path3.basename(filePath);
|
|
17614
|
+
if (rootTsConfigNames.includes(basename3)) {
|
|
17615
|
+
this.onConfigChanged(filePath, type);
|
|
17397
17616
|
return;
|
|
17398
|
-
|
|
17399
|
-
|
|
17400
|
-
} catch {
|
|
17401
|
-
return;
|
|
17617
|
+
}
|
|
17618
|
+
this.onFilesChanged([{ filePath, type }]);
|
|
17402
17619
|
}
|
|
17620
|
+
dispose() {
|
|
17621
|
+
this.stopWatching();
|
|
17622
|
+
for (let project of this.configProjects.values())
|
|
17623
|
+
project.dispose();
|
|
17624
|
+
this.inferredProject?.dispose(), this.configProjects.clear(), this.inferredProject = void 0, this.fsFileSnapshots.clear(), this.searchedDirs.clear(), this.rootTsConfigs.clear();
|
|
17625
|
+
}
|
|
17626
|
+
};
|
|
17627
|
+
function sortTSConfigs(file, a, b) {
|
|
17628
|
+
let inA = isFileInDir(file, path3.dirname(a)), inB = isFileInDir(file, path3.dirname(b));
|
|
17629
|
+
if (inA !== inB)
|
|
17630
|
+
return (inB ? 1 : 0) - (inA ? 1 : 0);
|
|
17631
|
+
let aLength = a.split("/").length, bLength = b.split("/").length;
|
|
17632
|
+
if (aLength === bLength) {
|
|
17633
|
+
let aWeight = path3.basename(a) === "tsconfig.json" ? 1 : 0;
|
|
17634
|
+
return (path3.basename(b) === "tsconfig.json" ? 1 : 0) - aWeight;
|
|
17635
|
+
}
|
|
17636
|
+
return bLength - aLength;
|
|
17403
17637
|
}
|
|
17404
|
-
function
|
|
17405
|
-
let
|
|
17406
|
-
return
|
|
17407
|
-
}
|
|
17408
|
-
function getComponentDocgenData(component, docgenEngine) {
|
|
17409
|
-
let reactDocgen, reactDocgenTypescript, reactComponentMeta, docgenDescription, docgenJsDocTags, docgenError;
|
|
17410
|
-
if (docgenEngine === "react-docgen") {
|
|
17411
|
-
let result = component?.reactDocgen;
|
|
17412
|
-
reactDocgen = result?.type === "success" ? result.data : void 0, docgenDescription = reactDocgen?.description, docgenError = result?.type === "error" ? result.error : void 0;
|
|
17413
|
-
} else docgenEngine === "react-docgen-typescript" ? (reactDocgenTypescript = component?.reactDocgenTypescript, docgenDescription = reactDocgenTypescript?.description, docgenError = component?.reactDocgenTypescriptError) : (reactComponentMeta = component?.reactComponentMeta, docgenDescription = reactComponentMeta?.description, docgenJsDocTags = component?.componentJsDocTags);
|
|
17414
|
-
return {
|
|
17415
|
-
docgenDescription,
|
|
17416
|
-
docgenError,
|
|
17417
|
-
docgenJsDocTags,
|
|
17418
|
-
reactComponentMeta,
|
|
17419
|
-
reactDocgen,
|
|
17420
|
-
reactDocgenTypescript
|
|
17421
|
-
};
|
|
17422
|
-
}
|
|
17423
|
-
function createSubcomponentManifest({
|
|
17424
|
-
component,
|
|
17425
|
-
declaredName,
|
|
17426
|
-
docgenEngine,
|
|
17427
|
-
packageName,
|
|
17428
|
-
storyFilePath
|
|
17429
|
-
}) {
|
|
17430
|
-
let imports = getImports({ components: component ? [component] : [], packageName }).join(`
|
|
17431
|
-
`).trim() || getFallbackImport(packageName, component?.componentName), {
|
|
17432
|
-
reactDocgen,
|
|
17433
|
-
reactDocgenTypescript,
|
|
17434
|
-
reactComponentMeta,
|
|
17435
|
-
docgenDescription,
|
|
17436
|
-
docgenJsDocTags,
|
|
17437
|
-
docgenError
|
|
17438
|
-
} = getComponentDocgenData(component, docgenEngine), { description, summary, jsDocTags } = extractComponentDescription(
|
|
17439
|
-
void 0,
|
|
17440
|
-
docgenDescription,
|
|
17441
|
-
docgenJsDocTags
|
|
17442
|
-
);
|
|
17443
|
-
return {
|
|
17444
|
-
name: declaredName,
|
|
17445
|
-
path: component?.path ?? storyFilePath,
|
|
17446
|
-
description,
|
|
17447
|
-
summary,
|
|
17448
|
-
import: imports || void 0,
|
|
17449
|
-
jsDocTags,
|
|
17450
|
-
reactDocgen,
|
|
17451
|
-
reactDocgenTypescript,
|
|
17452
|
-
reactComponentMeta,
|
|
17453
|
-
error: docgenError ?? (component ? void 0 : {
|
|
17454
|
-
name: "No component import found",
|
|
17455
|
-
message: `No component file found for the "${declaredName}" subcomponent.`
|
|
17456
|
-
})
|
|
17457
|
-
};
|
|
17638
|
+
function isFileInDir(fileName, dir) {
|
|
17639
|
+
let relative3 = path3.relative(dir, fileName);
|
|
17640
|
+
return !!relative3 && !relative3.startsWith("..") && !path3.isAbsolute(relative3);
|
|
17458
17641
|
}
|
|
17459
|
-
|
|
17460
|
-
|
|
17461
|
-
|
|
17462
|
-
|
|
17463
|
-
|
|
17464
|
-
manifestEntryIds.has(story.id)
|
|
17465
|
-
)
|
|
17466
|
-
).map(([storyExport, story]) => {
|
|
17642
|
+
|
|
17643
|
+
// src/componentManifest/componentMetaManagerSingleton.ts
|
|
17644
|
+
var componentMetaManagerPromise;
|
|
17645
|
+
function getSharedComponentMetaManager() {
|
|
17646
|
+
return componentMetaManagerPromise || (componentMetaManagerPromise = (async () => {
|
|
17467
17647
|
try {
|
|
17468
|
-
let
|
|
17469
|
-
return
|
|
17470
|
-
|
|
17471
|
-
|
|
17472
|
-
|
|
17473
|
-
|
|
17474
|
-
|
|
17475
|
-
};
|
|
17476
|
-
} catch (e) {
|
|
17477
|
-
return invariant(e instanceof Error), {
|
|
17478
|
-
id: story.id,
|
|
17479
|
-
name: story.name ?? storyNameFromExport(storyExport),
|
|
17480
|
-
error: { name: e.name, message: e.message }
|
|
17481
|
-
};
|
|
17648
|
+
let ts = await import("typescript");
|
|
17649
|
+
return new ComponentMetaManager(ts);
|
|
17650
|
+
} catch {
|
|
17651
|
+
logger8.debug(
|
|
17652
|
+
"[reactComponentMeta] TypeScript not available, skipping component meta extraction."
|
|
17653
|
+
);
|
|
17654
|
+
return;
|
|
17482
17655
|
}
|
|
17483
|
-
});
|
|
17484
|
-
}
|
|
17485
|
-
function extractComponentDescription(metaJsDoc, docgenDescription, docgenJsDocTags) {
|
|
17486
|
-
let jsdocComment = metaJsDoc || docgenDescription, extracted = jsdocComment ? extractJSDocInfo(jsdocComment) : void 0, tags = docgenJsDocTags ?? extracted?.tags ?? {}, description = extracted?.description;
|
|
17487
|
-
return {
|
|
17488
|
-
description: ((tags?.describe?.[0] || tags?.desc?.[0]) ?? description)?.trim(),
|
|
17489
|
-
summary: tags.summary?.[0],
|
|
17490
|
-
jsDocTags: tags
|
|
17491
|
-
};
|
|
17656
|
+
})()), componentMetaManagerPromise;
|
|
17492
17657
|
}
|
|
17493
|
-
var manifests = async (existingManifests = {}, options) => {
|
|
17494
|
-
let { manifestEntries, presets, watch: watch2 } = options, typescriptOptions = await presets?.apply("typescript", {}) ?? {}, docgenEngine = (await presets?.apply("features", {}))?.experimentalReactComponentMeta ? "react-component-meta" : typescriptOptions.reactDocgen || "react-docgen";
|
|
17495
|
-
invalidateCache(), invalidateParser();
|
|
17496
|
-
let startTime = performance.now(), manager = docgenEngine === "react-component-meta" ? await createComponentMetaManager(watch2) : null;
|
|
17497
|
-
try {
|
|
17498
|
-
let entriesByUniqueComponent = selectComponentEntries(manifestEntries), resolvedEntries = await Promise.all(
|
|
17499
|
-
entriesByUniqueComponent.map(async (entry) => {
|
|
17500
|
-
let storyFilePath = entry.type === "story" ? entry.importPath : (
|
|
17501
|
-
// For attached docs entries, storiesImports[0] points to the stories file being attached to
|
|
17502
|
-
entry.storiesImports[0]
|
|
17503
|
-
), storyPath = path.join(process.cwd(), storyFilePath), storyFile = cachedReadTextFileSync(storyPath), csf = loadCsf(storyFile, {
|
|
17504
|
-
makeTitle: () => entry.title
|
|
17505
|
-
}).parse(), componentName = csf._meta?.component, declaredSubcomponents = extractDeclaredSubcomponents(csf), allComponents = await getComponents({
|
|
17506
|
-
additionalComponentNames: declaredSubcomponents.map(
|
|
17507
|
-
(subcomponent) => subcomponent.componentName
|
|
17508
|
-
),
|
|
17509
|
-
csf,
|
|
17510
|
-
storyFilePath: storyPath,
|
|
17511
|
-
typescriptOptions,
|
|
17512
|
-
docgenEngine
|
|
17513
|
-
}), component = findMatchingComponent(allComponents, componentName, entry.title), subcomponents = declaredSubcomponents.map((declaredSubcomponent) => ({
|
|
17514
|
-
component: findExactComponentMatch(allComponents, declaredSubcomponent.componentName),
|
|
17515
|
-
name: declaredSubcomponent.name
|
|
17516
|
-
}));
|
|
17517
|
-
return {
|
|
17518
|
-
storyPath,
|
|
17519
|
-
component,
|
|
17520
|
-
entry,
|
|
17521
|
-
storyFilePath,
|
|
17522
|
-
storyFile,
|
|
17523
|
-
csf,
|
|
17524
|
-
componentName,
|
|
17525
|
-
allComponents,
|
|
17526
|
-
subcomponents
|
|
17527
|
-
};
|
|
17528
|
-
})
|
|
17529
|
-
);
|
|
17530
|
-
docgenEngine === "react-component-meta" && manager && manager.batchExtract(
|
|
17531
|
-
resolvedEntries.flatMap(({ storyPath, component, subcomponents }) => [
|
|
17532
|
-
...component ? [{ storyPath, component }] : [],
|
|
17533
|
-
...subcomponents.filter(
|
|
17534
|
-
(subcomponent) => subcomponent.component !== void 0
|
|
17535
|
-
).map((subcomponent) => ({
|
|
17536
|
-
storyPath,
|
|
17537
|
-
component: subcomponent.component
|
|
17538
|
-
}))
|
|
17539
|
-
])
|
|
17540
|
-
);
|
|
17541
|
-
let components = resolvedEntries.map(
|
|
17542
|
-
({
|
|
17543
|
-
storyPath,
|
|
17544
|
-
component,
|
|
17545
|
-
entry,
|
|
17546
|
-
storyFilePath,
|
|
17547
|
-
storyFile,
|
|
17548
|
-
csf,
|
|
17549
|
-
componentName,
|
|
17550
|
-
allComponents,
|
|
17551
|
-
subcomponents
|
|
17552
|
-
}) => {
|
|
17553
|
-
let id = entry.id.split("--")[0], title = entry.title.split("/").at(-1).replace(/\s+/g, ""), packageName = getPackageInfo(component?.path, storyPath), fallbackImport = getFallbackImport(packageName, componentName), imports = getImports({ components: allComponents, packageName }).join(`
|
|
17554
|
-
`).trim() || fallbackImport, stories = extractStories(csf, component?.componentName, manifestEntries), base2 = {
|
|
17555
|
-
id,
|
|
17556
|
-
name: componentName ?? title,
|
|
17557
|
-
path: storyFilePath,
|
|
17558
|
-
stories,
|
|
17559
|
-
import: imports,
|
|
17560
|
-
jsDocTags: {}
|
|
17561
|
-
}, {
|
|
17562
|
-
reactDocgen,
|
|
17563
|
-
reactDocgenTypescript,
|
|
17564
|
-
reactComponentMeta,
|
|
17565
|
-
docgenDescription,
|
|
17566
|
-
docgenJsDocTags,
|
|
17567
|
-
docgenError
|
|
17568
|
-
} = getComponentDocgenData(component, docgenEngine);
|
|
17569
|
-
if (!reactDocgen && !reactDocgenTypescript && !reactComponentMeta) {
|
|
17570
|
-
let error = csf._meta?.component ? {
|
|
17571
|
-
name: "No component import found",
|
|
17572
|
-
message: `No component file found for the "${csf.meta.component}" component.`
|
|
17573
|
-
} : {
|
|
17574
|
-
name: "No component found",
|
|
17575
|
-
message: "We could not detect the component from your story file. Specify meta.component."
|
|
17576
|
-
};
|
|
17577
|
-
return {
|
|
17578
|
-
...base2,
|
|
17579
|
-
error: docgenError ?? {
|
|
17580
|
-
name: error.name,
|
|
17581
|
-
message: (csf._metaStatementPath?.buildCodeFrameError(error.message).message ?? error.message) + `
|
|
17582
17658
|
|
|
17583
|
-
|
|
17584
|
-
|
|
17585
|
-
|
|
17586
|
-
|
|
17587
|
-
}
|
|
17588
|
-
let metaJsDoc = extractDescription(csf._metaStatement) || void 0, { description, summary, jsDocTags } = extractComponentDescription(
|
|
17589
|
-
metaJsDoc,
|
|
17590
|
-
docgenDescription,
|
|
17591
|
-
docgenJsDocTags
|
|
17592
|
-
), subcomponentEntries = Object.fromEntries(
|
|
17593
|
-
subcomponents.map((subcomponent) => [
|
|
17594
|
-
subcomponent.name,
|
|
17595
|
-
createSubcomponentManifest({
|
|
17596
|
-
component: subcomponent.component,
|
|
17597
|
-
declaredName: subcomponent.name,
|
|
17598
|
-
docgenEngine,
|
|
17599
|
-
packageName,
|
|
17600
|
-
storyFilePath
|
|
17601
|
-
})
|
|
17602
|
-
])
|
|
17603
|
-
);
|
|
17604
|
-
return {
|
|
17605
|
-
...base2,
|
|
17606
|
-
description,
|
|
17607
|
-
summary,
|
|
17608
|
-
import: imports,
|
|
17609
|
-
reactDocgen,
|
|
17610
|
-
reactDocgenTypescript,
|
|
17611
|
-
reactComponentMeta,
|
|
17612
|
-
jsDocTags,
|
|
17613
|
-
...Object.keys(subcomponentEntries).length > 0 ? { subcomponents: subcomponentEntries } : {},
|
|
17614
|
-
error: docgenError
|
|
17615
|
-
};
|
|
17616
|
-
}
|
|
17617
|
-
).filter((component) => component !== void 0);
|
|
17618
|
-
manager && watch2 && manager.startWatching();
|
|
17619
|
-
let durationMs = Math.round(performance.now() - startTime);
|
|
17659
|
+
// src/componentManifest/generator.ts
|
|
17660
|
+
var manifests = async (existingManifests = {}, options) => {
|
|
17661
|
+
let { manifestEntries, presets, watch: watch2 } = options, typescriptOptions = await presets?.apply("typescript", {}) ?? {}, features = await presets?.apply("features", {});
|
|
17662
|
+
if (features?.experimentalDocgenServer)
|
|
17620
17663
|
return {
|
|
17621
17664
|
...existingManifests,
|
|
17622
17665
|
components: {
|
|
17623
17666
|
v: 0,
|
|
17624
|
-
components:
|
|
17625
|
-
meta: {
|
|
17626
|
-
docgen: docgenEngine,
|
|
17627
|
-
durationMs
|
|
17628
|
-
}
|
|
17667
|
+
components: {},
|
|
17668
|
+
meta: { docgen: "react-component-meta", durationMs: 0 }
|
|
17629
17669
|
}
|
|
17630
17670
|
};
|
|
17631
|
-
|
|
17632
|
-
|
|
17633
|
-
|
|
17671
|
+
let docgenEngine = features?.experimentalReactComponentMeta ? "react-component-meta" : typescriptOptions.reactDocgen || "react-docgen";
|
|
17672
|
+
invalidateCache(), invalidateParser();
|
|
17673
|
+
let startTime = performance.now(), manager = docgenEngine === "react-component-meta" ? await getSharedComponentMetaManager() : void 0, entriesByUniqueComponent = [
|
|
17674
|
+
...selectComponentEntriesByComponentId(manifestEntries).values()
|
|
17675
|
+
], resolvedEntries = await Promise.all(
|
|
17676
|
+
entriesByUniqueComponent.map(async (entry) => {
|
|
17677
|
+
let storyFilePath = getStoryImportPathFromEntry(entry);
|
|
17678
|
+
if (!storyFilePath)
|
|
17679
|
+
throw new Error(`No story file path for index entry ${entry.id}`);
|
|
17680
|
+
let storyPath = path.join(process.cwd(), storyFilePath), resolved = await resolveStoryFileComponents({
|
|
17681
|
+
storyPath,
|
|
17682
|
+
title: entry.title,
|
|
17683
|
+
typescriptOptions,
|
|
17684
|
+
docgenEngine
|
|
17685
|
+
});
|
|
17686
|
+
return { entry, storyFilePath, ...resolved };
|
|
17687
|
+
})
|
|
17688
|
+
);
|
|
17689
|
+
docgenEngine === "react-component-meta" && manager && manager.batchExtract(
|
|
17690
|
+
resolvedEntries.flatMap(({ storyPath, component, subcomponents }) => [
|
|
17691
|
+
...component ? [{ storyPath, component }] : [],
|
|
17692
|
+
...subcomponents.filter(
|
|
17693
|
+
(subcomponent) => subcomponent.component !== void 0
|
|
17694
|
+
).map((subcomponent) => ({
|
|
17695
|
+
storyPath,
|
|
17696
|
+
component: subcomponent.component
|
|
17697
|
+
}))
|
|
17698
|
+
])
|
|
17699
|
+
);
|
|
17700
|
+
let manifestEntryIds = new Set(manifestEntries.map((entry) => entry.id)), components = resolvedEntries.map(
|
|
17701
|
+
({
|
|
17702
|
+
storyPath,
|
|
17703
|
+
component,
|
|
17704
|
+
entry,
|
|
17705
|
+
storyFilePath,
|
|
17706
|
+
storyFile,
|
|
17707
|
+
csf,
|
|
17708
|
+
componentName,
|
|
17709
|
+
allComponents,
|
|
17710
|
+
subcomponents
|
|
17711
|
+
}) => buildReactComponentDocgenFromResolved({
|
|
17712
|
+
entry,
|
|
17713
|
+
storyPath,
|
|
17714
|
+
storyFilePath,
|
|
17715
|
+
storyFile,
|
|
17716
|
+
csf,
|
|
17717
|
+
componentName,
|
|
17718
|
+
component,
|
|
17719
|
+
allComponents,
|
|
17720
|
+
subcomponents,
|
|
17721
|
+
docgenEngine,
|
|
17722
|
+
filterStoryIds: manifestEntryIds
|
|
17723
|
+
})
|
|
17724
|
+
).filter((component) => component !== void 0);
|
|
17725
|
+
manager && watch2 && manager.startWatching();
|
|
17726
|
+
let durationMs = Math.round(performance.now() - startTime);
|
|
17727
|
+
return {
|
|
17728
|
+
...existingManifests,
|
|
17729
|
+
components: {
|
|
17730
|
+
v: 0,
|
|
17731
|
+
components: Object.fromEntries(components.map((component) => [component.id, component])),
|
|
17732
|
+
meta: {
|
|
17733
|
+
docgen: docgenEngine,
|
|
17734
|
+
durationMs
|
|
17735
|
+
}
|
|
17736
|
+
}
|
|
17737
|
+
};
|
|
17634
17738
|
};
|
|
17635
17739
|
|
|
17636
17740
|
// src/enrichCsf.ts
|
|
@@ -17706,6 +17810,67 @@ var enrichCsf = async (input, options) => {
|
|
|
17706
17810
|
};
|
|
17707
17811
|
};
|
|
17708
17812
|
|
|
17813
|
+
// src/docgen/preset.ts
|
|
17814
|
+
import { STORY_FILE_TEST_REGEXP, getStoryImportPathFromEntry as getStoryImportPathFromEntry3 } from "storybook/internal/common";
|
|
17815
|
+
|
|
17816
|
+
// src/docgen/buildDocgen.ts
|
|
17817
|
+
import { getStoryImportPathFromEntry as getStoryImportPathFromEntry2 } from "storybook/internal/common";
|
|
17818
|
+
async function buildDocgenPayload(input, context) {
|
|
17819
|
+
let storyFilePath = getStoryImportPathFromEntry2(input.entry);
|
|
17820
|
+
if (!storyFilePath)
|
|
17821
|
+
return;
|
|
17822
|
+
let storyPath = (context.resolvePath ?? ((importPath) => path.join(process.cwd(), importPath)))(storyFilePath), resolved;
|
|
17823
|
+
try {
|
|
17824
|
+
resolved = await resolveStoryFileComponents({
|
|
17825
|
+
storyPath,
|
|
17826
|
+
title: input.entry.title,
|
|
17827
|
+
typescriptOptions: context.typescriptOptions,
|
|
17828
|
+
docgenEngine: "react-component-meta"
|
|
17829
|
+
});
|
|
17830
|
+
} catch {
|
|
17831
|
+
return;
|
|
17832
|
+
}
|
|
17833
|
+
let { csf, componentName, component, allComponents, subcomponents, storyFile } = resolved, usableSubcomponents = subcomponents.filter(
|
|
17834
|
+
(sub) => sub.component !== void 0
|
|
17835
|
+
), storyRefs = [
|
|
17836
|
+
...component ? [{ storyPath, component }] : [],
|
|
17837
|
+
...usableSubcomponents.map((sub) => ({ storyPath, component: sub.component }))
|
|
17838
|
+
];
|
|
17839
|
+
return storyRefs.length > 0 && context.componentMetaManager.batchExtract(storyRefs), buildReactComponentDocgenFromResolved({
|
|
17840
|
+
entry: input.entry,
|
|
17841
|
+
storyPath,
|
|
17842
|
+
storyFilePath,
|
|
17843
|
+
storyFile,
|
|
17844
|
+
csf,
|
|
17845
|
+
componentName,
|
|
17846
|
+
component,
|
|
17847
|
+
allComponents,
|
|
17848
|
+
subcomponents,
|
|
17849
|
+
docgenEngine: "react-component-meta"
|
|
17850
|
+
});
|
|
17851
|
+
}
|
|
17852
|
+
|
|
17853
|
+
// src/docgen/preset.ts
|
|
17854
|
+
var experimental_docgenProvider = async (nextDocgen, options) => {
|
|
17855
|
+
let typescriptOptionsPromise = options.presets?.apply(
|
|
17856
|
+
"typescript",
|
|
17857
|
+
{}
|
|
17858
|
+
) ?? Promise.resolve({});
|
|
17859
|
+
return getSharedComponentMetaManager(), async (input) => {
|
|
17860
|
+
let storyImportPath = getStoryImportPathFromEntry3(input.entry);
|
|
17861
|
+
if (!storyImportPath || !STORY_FILE_TEST_REGEXP.test(storyImportPath))
|
|
17862
|
+
return nextDocgen(input);
|
|
17863
|
+
let componentMetaManager = await getSharedComponentMetaManager();
|
|
17864
|
+
if (!componentMetaManager)
|
|
17865
|
+
return nextDocgen(input);
|
|
17866
|
+
let ours = await buildDocgenPayload(input, {
|
|
17867
|
+
componentMetaManager,
|
|
17868
|
+
typescriptOptions: await typescriptOptionsPromise
|
|
17869
|
+
});
|
|
17870
|
+
return ours ? { ...await nextDocgen(input), ...ours } : nextDocgen(input);
|
|
17871
|
+
};
|
|
17872
|
+
};
|
|
17873
|
+
|
|
17709
17874
|
// src/preset.ts
|
|
17710
17875
|
var addons = [
|
|
17711
17876
|
import.meta.resolve("@storybook/react-dom-shim/preset")
|
|
@@ -17759,6 +17924,7 @@ async function internal_getArgTypesData(_input, options) {
|
|
|
17759
17924
|
var optimizeViteDeps = ["react-dom/test-utils"];
|
|
17760
17925
|
export {
|
|
17761
17926
|
addons,
|
|
17927
|
+
experimental_docgenProvider,
|
|
17762
17928
|
enrichCsf as experimental_enrichCsf,
|
|
17763
17929
|
manifests as experimental_manifests,
|
|
17764
17930
|
internal_getArgTypesData,
|