@fragments-sdk/cli 0.11.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-client-I6MDWNYA.js +21 -0
- package/dist/bin.js +419 -410
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-HRFUSSZI.js → chunk-3SOAPJDX.js} +2 -2
- package/dist/{chunk-D5PYOXEI.js → chunk-4K7EAQ5L.js} +148 -13
- package/dist/{chunk-D5PYOXEI.js.map → chunk-4K7EAQ5L.js.map} +1 -1
- package/dist/chunk-DXX6HADE.js +443 -0
- package/dist/chunk-DXX6HADE.js.map +1 -0
- package/dist/chunk-EYXVAMEX.js +626 -0
- package/dist/chunk-EYXVAMEX.js.map +1 -0
- package/dist/{chunk-ZM4ZQZWZ.js → chunk-FO6EBJWP.js} +39 -37
- package/dist/chunk-FO6EBJWP.js.map +1 -0
- package/dist/{chunk-OQO55NKV.js → chunk-QM7SVOGF.js} +120 -12
- package/dist/chunk-QM7SVOGF.js.map +1 -0
- package/dist/{chunk-5G3VZH43.js → chunk-RF3C6LGA.js} +281 -351
- package/dist/chunk-RF3C6LGA.js.map +1 -0
- package/dist/{chunk-WXSR2II7.js → chunk-SM674YAS.js} +58 -6
- package/dist/chunk-SM674YAS.js.map +1 -0
- package/dist/chunk-SXTKFDCR.js +104 -0
- package/dist/chunk-SXTKFDCR.js.map +1 -0
- package/dist/{chunk-PW7QTQA6.js → chunk-UV5JQV3R.js} +2 -2
- package/dist/core/index.js +13 -1
- package/dist/{discovery-NEOY4MPN.js → discovery-VSGC76JN.js} +3 -3
- package/dist/{generate-FBHSXR3D.js → generate-QZXOXYFW.js} +4 -4
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/init-XK6PRUE5.js +636 -0
- package/dist/init-XK6PRUE5.js.map +1 -0
- package/dist/mcp-bin.js +2 -2
- package/dist/{scan-CJF2DOQW.js → scan-CHQHXWVD.js} +6 -6
- package/dist/scan-generate-U3RFVDTX.js +1115 -0
- package/dist/scan-generate-U3RFVDTX.js.map +1 -0
- package/dist/{service-TQYWY65E.js → service-MMEKG4MZ.js} +3 -3
- package/dist/{snapshot-SV2JOFZH.js → snapshot-53TUR3HW.js} +2 -2
- package/dist/{static-viewer-NUBFPKWH.js → static-viewer-KKCR4KXR.js} +3 -3
- package/dist/static-viewer-KKCR4KXR.js.map +1 -0
- package/dist/{test-Z5LVO724.js → test-5UCKXYSC.js} +4 -4
- package/dist/{tokens-CE46OTMD.js → tokens-L46MK5AW.js} +5 -5
- package/dist/{viewer-DLLJIMCK.js → viewer-M2EQQSGE.js} +14 -14
- package/dist/viewer-M2EQQSGE.js.map +1 -0
- package/package.json +11 -9
- package/src/ai-client.ts +156 -0
- package/src/bin.ts +99 -2
- package/src/build.ts +95 -33
- package/src/commands/__tests__/drift-sync.test.ts +252 -0
- package/src/commands/__tests__/scan-generate.test.ts +497 -45
- package/src/commands/enhance.ts +11 -35
- package/src/commands/govern.ts +122 -0
- package/src/commands/init.ts +288 -260
- package/src/commands/scan-generate.ts +740 -139
- package/src/commands/scan.ts +37 -32
- package/src/commands/setup.ts +143 -52
- package/src/commands/sync.ts +357 -0
- package/src/commands/validate.ts +43 -1
- package/src/core/component-extractor.test.ts +282 -0
- package/src/core/component-extractor.ts +1030 -0
- package/src/core/discovery.ts +93 -7
- package/src/service/enhance/props-extractor.ts +235 -13
- package/src/validators.ts +236 -0
- package/src/viewer/vite-plugin.ts +1 -1
- package/dist/chunk-5G3VZH43.js.map +0 -1
- package/dist/chunk-OQO55NKV.js.map +0 -1
- package/dist/chunk-WXSR2II7.js.map +0 -1
- package/dist/chunk-ZM4ZQZWZ.js.map +0 -1
- package/dist/init-UFGK5TCN.js +0 -867
- package/dist/init-UFGK5TCN.js.map +0 -1
- package/dist/scan-generate-SJAN5MVI.js +0 -691
- package/dist/scan-generate-SJAN5MVI.js.map +0 -1
- package/dist/viewer-DLLJIMCK.js.map +0 -1
- package/src/ai.ts +0 -266
- package/src/commands/init-framework.ts +0 -414
- package/src/mcp/bin.ts +0 -36
- package/src/migrate/bin.ts +0 -114
- package/src/theme/index.ts +0 -77
- package/src/viewer/bin.ts +0 -86
- package/src/viewer/cli/health.ts +0 -256
- package/src/viewer/cli/index.ts +0 -33
- package/src/viewer/cli/scan.ts +0 -124
- package/src/viewer/cli/utils.ts +0 -174
- /package/dist/{discovery-NEOY4MPN.js.map → ai-client-I6MDWNYA.js.map} +0 -0
- /package/dist/{chunk-HRFUSSZI.js.map → chunk-3SOAPJDX.js.map} +0 -0
- /package/dist/{chunk-PW7QTQA6.js.map → chunk-UV5JQV3R.js.map} +0 -0
- /package/dist/{scan-CJF2DOQW.js.map → discovery-VSGC76JN.js.map} +0 -0
- /package/dist/{generate-FBHSXR3D.js.map → generate-QZXOXYFW.js.map} +0 -0
- /package/dist/{service-TQYWY65E.js.map → scan-CHQHXWVD.js.map} +0 -0
- /package/dist/{static-viewer-NUBFPKWH.js.map → service-MMEKG4MZ.js.map} +0 -0
- /package/dist/{snapshot-SV2JOFZH.js.map → snapshot-53TUR3HW.js.map} +0 -0
- /package/dist/{test-Z5LVO724.js.map → test-5UCKXYSC.js.map} +0 -0
- /package/dist/{tokens-CE46OTMD.js.map → tokens-L46MK5AW.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/component-extractor.ts"],"sourcesContent":["/**\n * ComponentExtractor — persistent LanguageService-based prop extraction.\n *\n * Replaces auto-props.ts with:\n * - Persistent ts.LanguageService (not throwaway ts.createProgram())\n * - Incremental invalidation via projectVersion\n * - Compound component (Object.assign) sub-component prop extraction\n * - Full type serialization to PropMeta format\n *\n * Zero additional dependencies — uses raw TypeScript APIs.\n */\n\nimport ts from 'typescript';\nimport { existsSync, readFileSync, statSync, readdirSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ComponentExtractor {\n /** Extract metadata for a single component by export name */\n extract(filePath: string, exportName?: string): ComponentMeta | null;\n\n /** Extract all exported components found in a file */\n extractAll(filePath: string): ComponentMeta[];\n\n /** Notify extractor that a file changed (incremental) */\n invalidate(filePath: string): void;\n\n /** Clean up resources */\n dispose(): void;\n}\n\nexport interface ComponentMeta {\n name: string;\n filePath: string;\n description: string;\n props: Record<string, PropMeta>;\n composition: CompositionMeta | null;\n exports: string[];\n dependencies: string[];\n}\n\nexport interface PropMeta {\n name: string;\n type: string;\n typeKind: PropTypeKind;\n values?: string[];\n default?: string;\n description?: string;\n required: boolean;\n source: 'local' | 'inherited';\n}\n\nexport type PropTypeKind =\n | 'string' | 'number' | 'boolean'\n | 'enum'\n | 'function'\n | 'node'\n | 'element'\n | 'object' | 'array'\n | 'union'\n | 'custom';\n\nexport interface CompositionMeta {\n pattern: 'compound' | 'controlled' | 'simple';\n parts: PartMeta[];\n required: string[];\n}\n\nexport interface PartMeta {\n name: string;\n props: Record<string, PropMeta>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface ResolvedComponent {\n name: string;\n propsType: ts.Type | null;\n componentNode: ts.Node | null;\n compoundParts: Map<string, ts.Type> | null;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createComponentExtractor(tsconfigPath?: string): ComponentExtractor {\n let projectVersion = 0;\n const fileVersions = new Map<string, number>();\n const fileSnapshots = new Map<string, ts.IScriptSnapshot>();\n\n // Parse tsconfig or use inferred settings\n const rootDir = tsconfigPath ? dirname(resolve(tsconfigPath)) : process.cwd();\n const parsedCommandLine = tsconfigPath\n ? parseTsConfig(tsconfigPath)\n : inferCompilerOptions(rootDir);\n\n const scriptFileNames = new Set(parsedCommandLine.fileNames);\n\n const host: ts.LanguageServiceHost = {\n getProjectVersion: () => projectVersion.toString(),\n getScriptVersion: (fileName) => (fileVersions.get(fileName) ?? 0).toString(),\n getScriptSnapshot: (fileName) => {\n const cached = fileSnapshots.get(fileName);\n if (cached) return cached;\n\n let text: string;\n try {\n text = readFileSync(fileName, 'utf-8');\n } catch {\n return undefined;\n }\n const snapshot = ts.ScriptSnapshot.fromString(text);\n fileSnapshots.set(fileName, snapshot);\n return snapshot;\n },\n getScriptFileNames: () => [...scriptFileNames],\n getCompilationSettings: () => parsedCommandLine.options,\n getCurrentDirectory: () => rootDir,\n getDefaultLibFileName: ts.getDefaultLibFilePath,\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n readDirectory: ts.sys.readDirectory,\n directoryExists: ts.sys.directoryExists,\n getDirectories: ts.sys.getDirectories,\n };\n\n const languageService = ts.createLanguageService(host, ts.createDocumentRegistry());\n\n function ensureFile(filePath: string): void {\n const resolved = resolve(filePath);\n if (!scriptFileNames.has(resolved)) {\n scriptFileNames.add(resolved);\n projectVersion++;\n }\n }\n\n function getChecker(): ts.TypeChecker {\n const program = languageService.getProgram();\n if (!program) throw new Error('Failed to get program from LanguageService');\n return program.getTypeChecker();\n }\n\n function getSourceFile(filePath: string): ts.SourceFile | undefined {\n return languageService.getProgram()?.getSourceFile(resolve(filePath));\n }\n\n return {\n extract(filePath: string, exportName?: string): ComponentMeta | null {\n const resolved = resolve(filePath);\n ensureFile(resolved);\n\n const sourceFile = getSourceFile(resolved);\n if (!sourceFile) return null;\n\n const checker = getChecker();\n const moduleSymbol = checker.getSymbolAtLocation(sourceFile);\n if (!moduleSymbol) return null;\n\n const exports = checker.getExportsOfModule(moduleSymbol);\n const targetName = exportName ?? findPrimaryExport(exports, sourceFile);\n if (!targetName) return null;\n\n const exportSymbol = exports.find(s => s.getName() === targetName);\n if (!exportSymbol) return null;\n\n const component = resolveExportedComponent(checker, exportSymbol, sourceFile);\n if (!component) return null;\n\n return buildComponentMeta(checker, component, resolved, sourceFile, exports);\n },\n\n extractAll(filePath: string): ComponentMeta[] {\n const resolved = resolve(filePath);\n ensureFile(resolved);\n\n const sourceFile = getSourceFile(resolved);\n if (!sourceFile) return [];\n\n const checker = getChecker();\n const moduleSymbol = checker.getSymbolAtLocation(sourceFile);\n if (!moduleSymbol) return [];\n\n const exports = checker.getExportsOfModule(moduleSymbol);\n const results: ComponentMeta[] = [];\n\n for (const exportSymbol of exports) {\n const name = exportSymbol.getName();\n // Only consider PascalCase exports as potential components\n if (!/^[A-Z]/.test(name)) continue;\n\n const component = resolveExportedComponent(checker, exportSymbol, sourceFile);\n if (!component) continue;\n\n const meta = buildComponentMeta(checker, component, resolved, sourceFile, exports);\n if (meta) results.push(meta);\n }\n\n return results;\n },\n\n invalidate(filePath: string): void {\n const resolved = resolve(filePath);\n fileVersions.set(resolved, (fileVersions.get(resolved) ?? 0) + 1);\n fileSnapshots.delete(resolved);\n projectVersion++;\n },\n\n dispose(): void {\n languageService.dispose();\n fileSnapshots.clear();\n fileVersions.clear();\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// tsconfig parsing\n// ---------------------------------------------------------------------------\n\nfunction parseTsConfig(tsconfigPath: string): ts.ParsedCommandLine {\n const resolved = resolve(tsconfigPath);\n const configFile = ts.readConfigFile(resolved, ts.sys.readFile);\n if (configFile.error) {\n throw new Error(`Failed to read tsconfig: ${ts.flattenDiagnosticMessageText(configFile.error.messageText, '\\n')}`);\n }\n\n return ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n dirname(resolved),\n undefined,\n resolved,\n );\n}\n\nfunction inferCompilerOptions(rootDir: string): ts.ParsedCommandLine {\n return {\n options: {\n target: ts.ScriptTarget.ES2022,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.Bundler,\n jsx: ts.JsxEmit.ReactJSX,\n allowSyntheticDefaultImports: true,\n esModuleInterop: true,\n skipLibCheck: true,\n strict: false,\n noEmit: true,\n },\n fileNames: [],\n errors: [],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Export resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Find the \"primary\" export — prefers the default export or the first PascalCase export.\n */\nfunction findPrimaryExport(exports: ts.Symbol[], sourceFile: ts.SourceFile): string | null {\n // Default export\n const defaultExport = exports.find(s => s.getName() === 'default');\n if (defaultExport) return 'default';\n\n // First PascalCase named export\n for (const s of exports) {\n if (/^[A-Z][a-zA-Z0-9]*$/.test(s.getName())) {\n return s.getName();\n }\n }\n\n return null;\n}\n\n/**\n * Resolve an export symbol to a component with its props type.\n * Handles: direct functions, forwardRef, memo, Object.assign, FC<Props>.\n */\nfunction resolveExportedComponent(\n checker: ts.TypeChecker,\n exportSymbol: ts.Symbol,\n sourceFile: ts.SourceFile,\n): ResolvedComponent | null {\n const name = exportSymbol.getName();\n\n // Follow aliases (re-exports)\n let symbol = exportSymbol;\n if (symbol.flags & ts.SymbolFlags.Alias) {\n symbol = checker.getAliasedSymbol(symbol);\n }\n\n const declarations = symbol.getDeclarations();\n if (!declarations || declarations.length === 0) return null;\n\n const declaration = declarations[0];\n\n // Variable declaration: const X = ... (forwardRef, memo, Object.assign, arrow, FC)\n if (ts.isVariableDeclaration(declaration) && declaration.initializer) {\n return resolveFromExpression(checker, name, declaration.initializer, declaration, sourceFile);\n }\n\n // Function declaration: function X(props: Props) { ... }\n if (ts.isFunctionDeclaration(declaration)) {\n const propsType = extractPropsFromFunctionLike(checker, declaration);\n return propsType ? { name, propsType, componentNode: declaration, compoundParts: null } : null;\n }\n\n // Export assignment: export default X\n if (ts.isExportAssignment(declaration) && declaration.expression) {\n return resolveFromExpression(checker, name, declaration.expression, null, sourceFile);\n }\n\n return null;\n}\n\nfunction resolveFromExpression(\n checker: ts.TypeChecker,\n name: string,\n expression: ts.Expression,\n variableDecl: ts.VariableDeclaration | null,\n sourceFile: ts.SourceFile,\n): ResolvedComponent | null {\n // Unwrap parentheses, type assertions\n expression = unwrapExpression(expression);\n\n // Arrow function or function expression\n if (ts.isArrowFunction(expression) || ts.isFunctionExpression(expression)) {\n const propsType = extractPropsFromFunctionLike(checker, expression);\n return propsType ? { name, propsType, componentNode: expression, compoundParts: null } : null;\n }\n\n // Call expression: React.forwardRef, React.memo, Object.assign\n if (ts.isCallExpression(expression)) {\n return resolveCallExpression(checker, name, expression, variableDecl, sourceFile);\n }\n\n // Identifier reference — follow to its declaration\n if (ts.isIdentifier(expression)) {\n const sym = checker.getSymbolAtLocation(expression);\n if (sym) {\n const decls = sym.getDeclarations();\n if (decls && decls.length > 0) {\n const decl = decls[0];\n if (ts.isVariableDeclaration(decl) && decl.initializer) {\n return resolveFromExpression(checker, name, decl.initializer, decl, sourceFile);\n }\n if (ts.isFunctionDeclaration(decl)) {\n const propsType = extractPropsFromFunctionLike(checker, decl);\n return propsType ? { name, propsType, componentNode: decl, compoundParts: null } : null;\n }\n }\n }\n }\n\n // FC<Props> typed variable\n if (variableDecl?.type && ts.isTypeReferenceNode(variableDecl.type)) {\n const typeName = variableDecl.type.typeName.getText(sourceFile);\n if (typeName.includes('FC') || typeName.includes('FunctionComponent')) {\n const typeArg = variableDecl.type.typeArguments?.[0];\n if (typeArg) {\n const propsType = checker.getTypeFromTypeNode(typeArg);\n return { name, propsType, componentNode: expression, compoundParts: null };\n }\n }\n }\n\n return null;\n}\n\nfunction resolveCallExpression(\n checker: ts.TypeChecker,\n name: string,\n call: ts.CallExpression,\n variableDecl: ts.VariableDeclaration | null,\n sourceFile: ts.SourceFile,\n): ResolvedComponent | null {\n const callee = call.expression;\n\n // Object.assign(Root, { Header, Body, ... })\n if (isObjectAssignCall(callee, sourceFile)) {\n return resolveObjectAssign(checker, name, call, sourceFile);\n }\n\n // React.forwardRef<Ref, Props>(fn) or forwardRef<Ref, Props>(fn)\n if (isForwardRefCall(callee)) {\n return resolveForwardRef(checker, name, call, sourceFile);\n }\n\n // React.memo(Component) or memo(Component)\n if (isMemoCall(callee)) {\n const innerArg = call.arguments[0];\n if (innerArg) {\n return resolveFromExpression(checker, name, innerArg, variableDecl, sourceFile);\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Object.assign compound component resolution\n// ---------------------------------------------------------------------------\n\nfunction resolveObjectAssign(\n checker: ts.TypeChecker,\n name: string,\n call: ts.CallExpression,\n sourceFile: ts.SourceFile,\n): ResolvedComponent | null {\n if (call.arguments.length < 2) return null;\n\n // First arg is the root component\n const rootExpr = call.arguments[0];\n const rootResult = resolveFromExpression(checker, name, rootExpr, null, sourceFile);\n\n // Second arg is the object literal with sub-components\n const subsArg = call.arguments[1];\n const compoundParts = new Map<string, ts.Type>();\n\n if (ts.isObjectLiteralExpression(subsArg)) {\n for (const prop of subsArg.properties) {\n let subName: string | null = null;\n let subExpression: ts.Expression | null = null;\n\n if (ts.isShorthandPropertyAssignment(prop)) {\n subName = prop.name.text;\n // Resolve the identifier to its type\n const sym = checker.getSymbolAtLocation(prop.name);\n if (sym) {\n const subPropsType = extractPropsFromComponentSymbol(checker, sym);\n if (subPropsType) {\n compoundParts.set(subName, subPropsType);\n }\n }\n } else if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n subName = prop.name.text;\n subExpression = prop.initializer;\n if (subExpression) {\n const subType = extractPropsFromExpression(checker, subExpression, sourceFile);\n if (subType) {\n compoundParts.set(subName, subType);\n }\n }\n }\n }\n }\n\n return {\n name,\n propsType: rootResult?.propsType ?? null,\n componentNode: rootResult?.componentNode ?? rootExpr,\n compoundParts: compoundParts.size > 0 ? compoundParts : null,\n };\n}\n\n/**\n * Extract props type from a component symbol (function, variable, etc.)\n */\nfunction extractPropsFromComponentSymbol(checker: ts.TypeChecker, symbol: ts.Symbol): ts.Type | null {\n // Follow aliases\n let sym = symbol;\n if (sym.flags & ts.SymbolFlags.Alias) {\n sym = checker.getAliasedSymbol(sym);\n }\n\n const decls = sym.getDeclarations();\n if (!decls || decls.length === 0) return null;\n\n const decl = decls[0];\n\n if (ts.isFunctionDeclaration(decl)) {\n return extractPropsFromFunctionLike(checker, decl);\n }\n\n if (ts.isVariableDeclaration(decl) && decl.initializer) {\n // forwardRef, memo, arrow function, etc.\n return extractPropsFromExpressionDeep(checker, decl);\n }\n\n return null;\n}\n\n/**\n * Extract props type from an arbitrary expression (used for Object.assign values).\n */\nfunction extractPropsFromExpression(checker: ts.TypeChecker, expr: ts.Expression, sourceFile: ts.SourceFile): ts.Type | null {\n expr = unwrapExpression(expr);\n\n if (ts.isIdentifier(expr)) {\n const sym = checker.getSymbolAtLocation(expr);\n if (sym) return extractPropsFromComponentSymbol(checker, sym);\n }\n\n if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) {\n return extractPropsFromFunctionLike(checker, expr);\n }\n\n if (ts.isCallExpression(expr)) {\n if (isForwardRefCall(expr.expression)) {\n const typeArg = expr.typeArguments?.[1];\n if (typeArg) return checker.getTypeFromTypeNode(typeArg);\n const innerArg = expr.arguments[0];\n if (innerArg && (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg))) {\n return extractPropsFromFunctionLike(checker, innerArg);\n }\n }\n if (isMemoCall(expr.expression) && expr.arguments[0]) {\n return extractPropsFromExpression(checker, expr.arguments[0], sourceFile);\n }\n }\n\n return null;\n}\n\n/**\n * Deep extraction from a variable declaration.\n */\nfunction extractPropsFromExpressionDeep(checker: ts.TypeChecker, decl: ts.VariableDeclaration): ts.Type | null {\n if (!decl.initializer) return null;\n const expr = unwrapExpression(decl.initializer);\n\n if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) {\n return extractPropsFromFunctionLike(checker, expr);\n }\n\n if (ts.isCallExpression(expr)) {\n if (isForwardRefCall(expr.expression)) {\n const typeArg = expr.typeArguments?.[1];\n if (typeArg) return checker.getTypeFromTypeNode(typeArg);\n const innerArg = expr.arguments[0];\n if (innerArg && (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg))) {\n return extractPropsFromFunctionLike(checker, innerArg);\n }\n }\n if (isMemoCall(expr.expression) && expr.arguments[0]) {\n return extractPropsFromExpressionDeep(checker, {\n ...decl,\n initializer: expr.arguments[0],\n } as ts.VariableDeclaration);\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// forwardRef resolution\n// ---------------------------------------------------------------------------\n\nfunction resolveForwardRef(\n checker: ts.TypeChecker,\n name: string,\n call: ts.CallExpression,\n sourceFile: ts.SourceFile,\n): ResolvedComponent | null {\n // Try type arguments first: forwardRef<Ref, Props>(...)\n const propsTypeArg = call.typeArguments?.[1];\n if (propsTypeArg) {\n const propsType = checker.getTypeFromTypeNode(propsTypeArg);\n const innerArg = call.arguments[0];\n const componentNode = innerArg && (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg))\n ? innerArg : null;\n return { name, propsType, componentNode, compoundParts: null };\n }\n\n // Fall back to inner function's parameter type\n const innerArg = call.arguments[0];\n if (innerArg) {\n if (ts.isArrowFunction(innerArg) || ts.isFunctionExpression(innerArg)) {\n const propsType = extractPropsFromFunctionLike(checker, innerArg);\n return propsType ? { name, propsType, componentNode: innerArg, compoundParts: null } : null;\n }\n if (ts.isIdentifier(innerArg)) {\n const sym = checker.getSymbolAtLocation(innerArg);\n if (sym) {\n const propsType = extractPropsFromComponentSymbol(checker, sym);\n if (propsType) return { name, propsType, componentNode: innerArg, compoundParts: null };\n }\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Props extraction from function-like declarations\n// ---------------------------------------------------------------------------\n\n/**\n * Extract the props type from a function's first parameter.\n */\nfunction extractPropsFromFunctionLike(\n checker: ts.TypeChecker,\n func: ts.FunctionLikeDeclaration,\n): ts.Type | null {\n const firstParam = func.parameters[0];\n if (!firstParam) return null;\n\n // If there's a type annotation, use it\n if (firstParam.type) {\n return checker.getTypeFromTypeNode(firstParam.type);\n }\n\n // Otherwise try to infer from the parameter's symbol\n const paramSymbol = checker.getSymbolAtLocation(firstParam.name);\n if (paramSymbol) {\n return checker.getTypeOfSymbolAtLocation(paramSymbol, firstParam);\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Build ComponentMeta from resolved component\n// ---------------------------------------------------------------------------\n\nfunction buildComponentMeta(\n checker: ts.TypeChecker,\n component: ResolvedComponent,\n filePath: string,\n sourceFile: ts.SourceFile,\n moduleExports: ts.Symbol[],\n): ComponentMeta | null {\n const props: Record<string, PropMeta> = {};\n const sourceFilePath = toPosixPath(sourceFile.fileName);\n\n if (component.propsType) {\n extractPropsFromType(checker, component.propsType, props, sourceFilePath);\n }\n\n // Extract defaults from the component function body\n const defaults = component.componentNode\n ? extractDefaultValues(component.componentNode)\n : {};\n\n // Apply defaults\n for (const [propName, defaultVal] of Object.entries(defaults)) {\n if (props[propName]) {\n props[propName].default = defaultVal;\n }\n }\n\n // Build composition meta\n let composition: CompositionMeta | null = null;\n if (component.compoundParts && component.compoundParts.size > 0) {\n const parts: PartMeta[] = [];\n for (const [partName, partType] of component.compoundParts) {\n const partProps: Record<string, PropMeta> = {};\n extractPropsFromType(checker, partType, partProps, sourceFilePath);\n parts.push({ name: partName, props: partProps });\n }\n\n composition = {\n pattern: 'compound',\n parts,\n required: [], // Could be inferred from usage patterns\n };\n }\n\n // Extract description from JSDoc\n let description = '';\n const componentSymbol = moduleExports.find(s => s.getName() === component.name);\n if (componentSymbol) {\n description = extractJSDocDescription(checker, componentSymbol);\n }\n\n // Collect export names\n const exportNames = moduleExports\n .filter(s => /^[A-Z]/.test(s.getName()))\n .map(s => s.getName());\n\n // Collect import dependencies (other components imported)\n const dependencies = extractDependencies(sourceFile);\n\n return {\n name: component.name,\n filePath,\n description,\n props,\n composition,\n exports: exportNames,\n dependencies,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Type → PropMeta extraction\n// ---------------------------------------------------------------------------\n\nfunction extractPropsFromType(\n checker: ts.TypeChecker,\n propsType: ts.Type,\n result: Record<string, PropMeta>,\n sourceFilePath: string,\n): void {\n for (const symbol of checker.getPropertiesOfType(propsType)) {\n const propName = symbol.getName();\n\n // Skip internal/private props\n if (propName.startsWith('_') || propName.startsWith('$')) continue;\n\n // Skip React internal props\n if (propName === 'key' || propName === 'ref') continue;\n\n const declarations = symbol.getDeclarations() ?? [];\n\n // Determine source: local vs inherited\n const isLocal = declarations.some(\n d => toPosixPath(d.getSourceFile().fileName) === sourceFilePath,\n );\n\n const referenceNode = declarations[0];\n if (!referenceNode) continue;\n\n const propType = checker.getTypeOfSymbolAtLocation(symbol, referenceNode);\n const serialized = serializePropType(checker, propType);\n const description = ts.displayPartsToString(symbol.getDocumentationComment(checker)).trim();\n const required = (symbol.flags & ts.SymbolFlags.Optional) === 0;\n\n // Extract @default from JSDoc tags\n let jsDocDefault: string | undefined;\n const jsDocTags = symbol.getJsDocTags(checker);\n const defaultTag = jsDocTags.find(t => t.name === 'default');\n if (defaultTag?.text) {\n jsDocDefault = ts.displayPartsToString(defaultTag.text).trim();\n }\n\n result[propName] = {\n name: propName,\n type: serialized.type,\n typeKind: serialized.typeKind,\n values: serialized.values,\n default: jsDocDefault,\n description: description || undefined,\n required,\n source: isLocal ? 'local' : 'inherited',\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Type serializer: ts.Type → PropMeta shape\n// ---------------------------------------------------------------------------\n\nfunction serializePropType(\n checker: ts.TypeChecker,\n type: ts.Type,\n): Pick<PropMeta, 'type' | 'typeKind' | 'values'> {\n // Check for ReactNode/ReactElement BEFORE union decomposition,\n // because ReactNode is defined as a large union in React's types.\n const aliasSymbol = type.aliasSymbol;\n if (aliasSymbol) {\n const aliasName = aliasSymbol.getName();\n if (aliasName === 'ReactNode') {\n return { type: 'ReactNode', typeKind: 'node' };\n }\n if (aliasName === 'ReactElement') {\n return { type: 'ReactElement', typeKind: 'element' };\n }\n }\n\n // Handle union types (including optional which adds undefined)\n if (type.isUnion()) {\n const nonNullableTypes = type.types.filter(\n t => !((t.flags & ts.TypeFlags.Undefined) || (t.flags & ts.TypeFlags.Null) || (t.flags & ts.TypeFlags.Void)),\n );\n\n // Single type after filtering nullable\n if (nonNullableTypes.length === 1) {\n return serializePropType(checker, nonNullableTypes[0]);\n }\n\n // All string literals → enum\n if (nonNullableTypes.length > 0 && nonNullableTypes.every(t => t.isStringLiteral())) {\n const values = nonNullableTypes.map(t => (t as ts.StringLiteralType).value);\n return {\n type: values.map(v => `\"${v}\"`).join(' | '),\n typeKind: 'enum',\n values,\n };\n }\n\n // All boolean-like\n if (nonNullableTypes.every(t => isBooleanLike(t))) {\n return { type: 'boolean', typeKind: 'boolean' };\n }\n\n // Mixed union\n const typeStr = checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation);\n return { type: typeStr, typeKind: 'union' };\n }\n\n // Check for ReactNode / ReactElement\n const typeStr = checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation);\n if (typeStr.includes('ReactNode')) {\n return { type: 'ReactNode', typeKind: 'node' };\n }\n if (typeStr.includes('ReactElement') || typeStr.includes('JSX.Element')) {\n return { type: 'ReactElement', typeKind: 'element' };\n }\n\n // Function types\n if (type.getCallSignatures().length > 0) {\n return { type: typeStr, typeKind: 'function' };\n }\n\n // Primitives\n if (type.flags & ts.TypeFlags.String) return { type: 'string', typeKind: 'string' };\n if (type.flags & ts.TypeFlags.Number) return { type: 'number', typeKind: 'number' };\n if (type.flags & ts.TypeFlags.Boolean || type.flags & ts.TypeFlags.BooleanLiteral) {\n return { type: 'boolean', typeKind: 'boolean' };\n }\n\n // String literal (not in union)\n if (type.isStringLiteral()) {\n return { type: `\"${type.value}\"`, typeKind: 'enum', values: [type.value] };\n }\n\n // Array\n if (checker.isArrayType(type) || checker.isTupleType(type)) {\n return { type: typeStr, typeKind: 'array' };\n }\n\n // Object\n if (type.flags & ts.TypeFlags.Object) {\n return { type: typeStr, typeKind: 'object' };\n }\n\n return { type: typeStr, typeKind: 'custom' };\n}\n\n// ---------------------------------------------------------------------------\n// Default value extraction\n// ---------------------------------------------------------------------------\n\nfunction extractDefaultValues(node: ts.Node): Record<string, string> {\n const defaults: Record<string, string> = {};\n\n // Find function-like node\n let funcNode: ts.FunctionLikeDeclaration | null = null;\n if (ts.isFunctionDeclaration(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {\n funcNode = node;\n }\n\n if (!funcNode?.parameters?.length) return defaults;\n\n const firstParam = funcNode.parameters[0];\n if (!ts.isObjectBindingPattern(firstParam.name)) return defaults;\n\n for (const element of firstParam.name.elements) {\n let propName: string | null = null;\n\n if (element.propertyName) {\n if (ts.isIdentifier(element.propertyName) || ts.isStringLiteral(element.propertyName)) {\n propName = element.propertyName.text;\n }\n } else if (ts.isIdentifier(element.name)) {\n propName = element.name.text;\n }\n\n if (!propName || !element.initializer) continue;\n\n const value = readLiteralValue(element.initializer);\n if (value !== undefined) {\n defaults[propName] = value;\n }\n }\n\n return defaults;\n}\n\nfunction readLiteralValue(expression: ts.Expression): string | undefined {\n if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression)) {\n return expression.text;\n }\n if (ts.isNumericLiteral(expression)) {\n return expression.text;\n }\n if (expression.kind === ts.SyntaxKind.TrueKeyword) return 'true';\n if (expression.kind === ts.SyntaxKind.FalseKeyword) return 'false';\n if (expression.kind === ts.SyntaxKind.NullKeyword) return 'null';\n if (\n ts.isPrefixUnaryExpression(expression) &&\n expression.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(expression.operand)\n ) {\n return `-${expression.operand.text}`;\n }\n\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// JSDoc extraction\n// ---------------------------------------------------------------------------\n\nfunction extractJSDocDescription(checker: ts.TypeChecker, symbol: ts.Symbol): string {\n // Follow aliases\n let sym = symbol;\n if (sym.flags & ts.SymbolFlags.Alias) {\n sym = checker.getAliasedSymbol(sym);\n }\n\n const docComment = ts.displayPartsToString(sym.getDocumentationComment(checker)).trim();\n if (docComment) return docComment;\n\n // Try to get from the Props interface\n const decls = sym.getDeclarations();\n if (decls) {\n for (const decl of decls) {\n // Look for the Props type\n const sourceFile = decl.getSourceFile();\n for (const stmt of sourceFile.statements) {\n if (\n (ts.isInterfaceDeclaration(stmt) || ts.isTypeAliasDeclaration(stmt)) &&\n stmt.name.text === `${symbol.getName()}Props`\n ) {\n const propsDoc = ts.displayPartsToString(\n checker.getSymbolAtLocation(stmt.name)?.getDocumentationComment(checker) ?? [],\n ).trim();\n if (propsDoc) return propsDoc;\n }\n }\n }\n }\n\n return '';\n}\n\n// ---------------------------------------------------------------------------\n// Import dependency extraction\n// ---------------------------------------------------------------------------\n\nfunction extractDependencies(sourceFile: ts.SourceFile): string[] {\n const deps: string[] = [];\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n if (!ts.isStringLiteral(stmt.moduleSpecifier)) continue;\n\n const modulePath = stmt.moduleSpecifier.text;\n // Only relative imports to other components\n if (!modulePath.startsWith('.') && !modulePath.startsWith('/')) continue;\n\n const clause = stmt.importClause;\n if (!clause) continue;\n\n // Default import\n if (clause.name && /^[A-Z]/.test(clause.name.text)) {\n deps.push(clause.name.text);\n }\n\n // Named imports\n if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const element of clause.namedBindings.elements) {\n if (/^[A-Z]/.test(element.name.text)) {\n deps.push(element.name.text);\n }\n }\n }\n }\n return deps;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction unwrapExpression(expr: ts.Expression): ts.Expression {\n while (true) {\n if (ts.isParenthesizedExpression(expr)) {\n expr = expr.expression;\n } else if (ts.isAsExpression(expr) || ts.isTypeAssertionExpression(expr)) {\n expr = expr.expression;\n } else {\n return expr;\n }\n }\n}\n\nfunction isObjectAssignCall(callee: ts.Expression, sourceFile: ts.SourceFile): boolean {\n if (\n ts.isPropertyAccessExpression(callee) &&\n ts.isIdentifier(callee.expression) &&\n callee.expression.text === 'Object' &&\n callee.name.text === 'assign'\n ) {\n return true;\n }\n return false;\n}\n\nfunction isForwardRefCall(callee: ts.Expression): boolean {\n // React.forwardRef(...)\n if (ts.isPropertyAccessExpression(callee) && callee.name.text === 'forwardRef') {\n return true;\n }\n // forwardRef(...)\n if (ts.isIdentifier(callee) && callee.text === 'forwardRef') {\n return true;\n }\n return false;\n}\n\nfunction isMemoCall(callee: ts.Expression): boolean {\n if (ts.isPropertyAccessExpression(callee) && callee.name.text === 'memo') {\n return true;\n }\n if (ts.isIdentifier(callee) && callee.text === 'memo') {\n return true;\n }\n return false;\n}\n\nfunction isBooleanLike(type: ts.Type): boolean {\n return (\n (type.flags & ts.TypeFlags.BooleanLike) !== 0 ||\n type.flags === ts.TypeFlags.BooleanLiteral\n );\n}\n\nfunction toPosixPath(filePath: string): string {\n return filePath.replace(/\\\\/g, '/');\n}\n"],"mappings":"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","names":["innerArg","typeStr"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
loadConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3SOAPJDX.js";
|
|
5
5
|
import {
|
|
6
6
|
discoverAllComponents
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SM674YAS.js";
|
|
8
8
|
import {
|
|
9
9
|
convertToFragmentProps,
|
|
10
10
|
extractPropsFromFile,
|
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
inferAllRelations,
|
|
15
15
|
parseAllStories,
|
|
16
16
|
scanCodebase
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-4K7EAQ5L.js";
|
|
18
18
|
import {
|
|
19
19
|
BRAND
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-QM7SVOGF.js";
|
|
21
21
|
|
|
22
22
|
// src/commands/scan.ts
|
|
23
23
|
import { writeFile, mkdir } from "fs/promises";
|
|
@@ -27,6 +27,8 @@ async function scan(options = {}) {
|
|
|
27
27
|
const startTime = Date.now();
|
|
28
28
|
const errors = [];
|
|
29
29
|
const warnings = [];
|
|
30
|
+
const log = options.quiet ? (() => {
|
|
31
|
+
}) : console.log.bind(console);
|
|
30
32
|
let configDir;
|
|
31
33
|
let outputFile;
|
|
32
34
|
let componentPatterns;
|
|
@@ -40,18 +42,18 @@ async function scan(options = {}) {
|
|
|
40
42
|
outputFile = options.output || "fragments.json";
|
|
41
43
|
componentPatterns = options.componentPatterns;
|
|
42
44
|
}
|
|
43
|
-
|
|
45
|
+
log(pc.cyan(`
|
|
44
46
|
${BRAND.name} Scan
|
|
45
47
|
`));
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
log(pc.dim("Zero-config fragments.json generation from source code\n"));
|
|
49
|
+
log(pc.dim("Phase 1: Discovering components..."));
|
|
48
50
|
const components = await discoverAllComponents(configDir, {
|
|
49
51
|
patterns: componentPatterns,
|
|
50
52
|
exclude: ["**/*.test.*", "**/*.spec.*", "**/__tests__/**"],
|
|
51
53
|
barrelFiles: options.barrelFiles
|
|
52
54
|
});
|
|
53
55
|
if (components.length === 0) {
|
|
54
|
-
|
|
56
|
+
log(pc.yellow("No components found. Check your patterns or config."));
|
|
55
57
|
return {
|
|
56
58
|
success: false,
|
|
57
59
|
outputPath: resolve(configDir, outputFile),
|
|
@@ -64,16 +66,16 @@ ${BRAND.name} Scan
|
|
|
64
66
|
warnings: []
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
|
-
|
|
69
|
+
log(pc.green(` Found ${components.length} components`));
|
|
68
70
|
if (options.verbose) {
|
|
69
71
|
for (const comp of components.slice(0, 10)) {
|
|
70
|
-
|
|
72
|
+
log(pc.dim(` - ${comp.name}: ${comp.relativePath}`));
|
|
71
73
|
}
|
|
72
74
|
if (components.length > 10) {
|
|
73
|
-
|
|
75
|
+
log(pc.dim(` ... and ${components.length - 10} more`));
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
|
-
|
|
78
|
+
log(pc.dim("\nPhase 2: Extracting props from TypeScript..."));
|
|
77
79
|
const propsMap = /* @__PURE__ */ new Map();
|
|
78
80
|
const propsResults = /* @__PURE__ */ new Map();
|
|
79
81
|
let propsExtracted = 0;
|
|
@@ -96,12 +98,12 @@ ${BRAND.name} Scan
|
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
|
-
|
|
101
|
+
log(pc.green(` Extracted props for ${propsExtracted} components`));
|
|
100
102
|
let usageAnalysis;
|
|
101
103
|
let usagesFound = 0;
|
|
102
104
|
let allRelations = /* @__PURE__ */ new Map();
|
|
103
105
|
if (!options.skipUsage) {
|
|
104
|
-
|
|
106
|
+
log(pc.dim("\nPhase 3: Scanning for usage patterns..."));
|
|
105
107
|
const usageDir = options.usageDir || configDir;
|
|
106
108
|
try {
|
|
107
109
|
const componentNames = components.map((c) => c.name);
|
|
@@ -123,22 +125,22 @@ ${BRAND.name} Scan
|
|
|
123
125
|
0
|
|
124
126
|
);
|
|
125
127
|
allRelations = inferAllRelations(usageAnalysis);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
log(pc.green(` Found ${usagesFound} usages across ${usageAnalysis.totalFiles} files`));
|
|
129
|
+
log(pc.green(` Inferred relations for ${allRelations.size} components`));
|
|
128
130
|
} catch (e) {
|
|
129
131
|
warnings.push({
|
|
130
132
|
component: "*",
|
|
131
133
|
warning: `Usage scanning failed: ${e instanceof Error ? e.message : String(e)}`
|
|
132
134
|
});
|
|
133
|
-
|
|
135
|
+
log(pc.yellow(` Usage scanning failed: ${e instanceof Error ? e.message : "unknown error"}`));
|
|
134
136
|
}
|
|
135
137
|
} else {
|
|
136
|
-
|
|
138
|
+
log(pc.dim("\nPhase 3: Skipping usage analysis"));
|
|
137
139
|
}
|
|
138
140
|
const storiesMap = /* @__PURE__ */ new Map();
|
|
139
141
|
let storiesParsed = 0;
|
|
140
142
|
if (!options.skipStorybook) {
|
|
141
|
-
|
|
143
|
+
log(pc.dim("\nPhase 4: Parsing Storybook stories..."));
|
|
142
144
|
try {
|
|
143
145
|
const allStories = await parseAllStories(configDir);
|
|
144
146
|
for (const [name, stories] of Object.entries(allStories)) {
|
|
@@ -147,18 +149,18 @@ ${BRAND.name} Scan
|
|
|
147
149
|
storiesParsed++;
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
|
-
|
|
152
|
+
log(pc.green(` Parsed stories for ${storiesParsed} components`));
|
|
151
153
|
} catch (e) {
|
|
152
154
|
warnings.push({
|
|
153
155
|
component: "*",
|
|
154
156
|
warning: `Storybook parsing failed: ${e instanceof Error ? e.message : String(e)}`
|
|
155
157
|
});
|
|
156
|
-
|
|
158
|
+
log(pc.yellow(` Storybook parsing failed: ${e instanceof Error ? e.message : "unknown error"}`));
|
|
157
159
|
}
|
|
158
160
|
} else {
|
|
159
|
-
|
|
161
|
+
log(pc.dim("\nPhase 4: Skipping Storybook parsing"));
|
|
160
162
|
}
|
|
161
|
-
|
|
163
|
+
log(pc.dim("\nPhase 5: Generating fragments..."));
|
|
162
164
|
const fragments = {};
|
|
163
165
|
for (const comp of components) {
|
|
164
166
|
try {
|
|
@@ -187,32 +189,32 @@ ${BRAND.name} Scan
|
|
|
187
189
|
};
|
|
188
190
|
await writeFile(outputPath, JSON.stringify(output, null, 2));
|
|
189
191
|
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
+
log(pc.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
193
|
+
log(pc.green(`
|
|
192
194
|
\u2713 Generated fragments.json in ${elapsed}s`));
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));
|
|
196
|
+
log(pc.dim(` Components: ${Object.keys(fragments).length}`));
|
|
197
|
+
log(pc.dim(` Props extracted: ${propsExtracted}`));
|
|
198
|
+
log(pc.dim(` Usages found: ${usagesFound}`));
|
|
199
|
+
log(pc.dim(` Relations inferred: ${allRelations.size}`));
|
|
200
|
+
log(pc.dim(` Stories parsed: ${storiesParsed}`));
|
|
199
201
|
if (warnings.length > 0) {
|
|
200
|
-
|
|
202
|
+
log(pc.yellow(`
|
|
201
203
|
${warnings.length} warning(s)`));
|
|
202
204
|
if (options.verbose) {
|
|
203
205
|
for (const w of warnings) {
|
|
204
|
-
|
|
206
|
+
log(pc.dim(` ${w.component}: ${w.warning}`));
|
|
205
207
|
}
|
|
206
208
|
}
|
|
207
209
|
}
|
|
208
210
|
if (errors.length > 0) {
|
|
209
|
-
|
|
211
|
+
log(pc.red(`
|
|
210
212
|
${errors.length} error(s)`));
|
|
211
213
|
for (const e of errors) {
|
|
212
|
-
|
|
214
|
+
log(pc.dim(` ${e.component}: ${e.error}`));
|
|
213
215
|
}
|
|
214
216
|
}
|
|
215
|
-
|
|
217
|
+
log();
|
|
216
218
|
return {
|
|
217
219
|
success: errors.length === 0,
|
|
218
220
|
outputPath,
|
|
@@ -368,4 +370,4 @@ function calculateConfidence(props, usageAnalysis, storyFile) {
|
|
|
368
370
|
export {
|
|
369
371
|
scan
|
|
370
372
|
};
|
|
371
|
-
//# sourceMappingURL=chunk-
|
|
373
|
+
//# sourceMappingURL=chunk-FO6EBJWP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/scan.ts"],"sourcesContent":["/**\n * fragments scan - Zero-config fragments.json generation from source code\n *\n * Automatically extracts component documentation by:\n * 1. Discovering components from source files and barrel exports\n * 2. Extracting props from TypeScript interfaces\n * 3. Scanning codebase for usage patterns\n * 4. Parsing Storybook stories for examples\n * 5. Inferring component relationships from usage data\n * 6. Generating complete fragments.json without manual documentation\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, join, dirname, relative } from \"node:path\";\nimport pc from \"picocolors\";\nimport {\n BRAND,\n type CompiledFragmentsFile,\n type CompiledFragment,\n type PropDefinition,\n} from \"../core/index.js\";\nimport {\n loadConfig,\n discoverAllComponents,\n type DiscoveredComponent,\n} from \"../core/node.js\";\nimport {\n scanCodebase,\n extractPropsFromFile,\n parseAllStories,\n inferAllRelations,\n generateComponentContext,\n generateEnhancementSuggestions,\n filterBoilerplate,\n convertToFragmentProps,\n type UsageAnalysis,\n type ComponentRelation,\n type PropsExtractionResult,\n type ParsedStoryFile,\n} from \"../service/index.js\";\n\nexport interface ScanOptions {\n /** Path to config file */\n config?: string;\n /** Output file path (default: fragments.json) */\n output?: string;\n /** Component patterns to scan */\n componentPatterns?: string[];\n /** Barrel export files to parse */\n barrelFiles?: string[];\n /** Directory to scan for usage patterns */\n usageDir?: string;\n /** Skip usage analysis */\n skipUsage?: boolean;\n /** Skip Storybook parsing */\n skipStorybook?: boolean;\n /** Verbose output */\n verbose?: boolean;\n /** Suppress all console output (for use as a sub-step) */\n quiet?: boolean;\n}\n\nexport interface ScanResult {\n success: boolean;\n outputPath: string;\n componentCount: number;\n propsExtracted: number;\n usagesFound: number;\n relationsInferred: number;\n storiesParsed: number;\n errors: Array<{ component: string; error: string }>;\n warnings: Array<{ component: string; warning: string }>;\n}\n\n/**\n * Scan codebase and generate fragments.json directly from source\n */\nexport async function scan(options: ScanOptions = {}): Promise<ScanResult> {\n const startTime = Date.now();\n const errors: Array<{ component: string; error: string }> = [];\n const warnings: Array<{ component: string; warning: string }> = [];\n\n // In quiet mode, suppress all console output\n const log = options.quiet ? (() => {}) : console.log.bind(console);\n\n // Load config or use defaults\n let configDir: string;\n let outputFile: string;\n let componentPatterns: string[] | undefined;\n\n try {\n const loaded = await loadConfig(options.config);\n configDir = loaded.configDir;\n outputFile = options.output || loaded.config.outFile || \"fragments.json\";\n componentPatterns = options.componentPatterns || loaded.config.components;\n } catch {\n // No config file, use defaults\n configDir = process.cwd();\n outputFile = options.output || \"fragments.json\";\n componentPatterns = options.componentPatterns;\n }\n\n log(pc.cyan(`\\n${BRAND.name} Scan\\n`));\n log(pc.dim(\"Zero-config fragments.json generation from source code\\n\"));\n\n // Phase 1: Discover components\n log(pc.dim(\"Phase 1: Discovering components...\"));\n const components = await discoverAllComponents(configDir, {\n patterns: componentPatterns,\n exclude: [\"**/*.test.*\", \"**/*.spec.*\", \"**/__tests__/**\"],\n barrelFiles: options.barrelFiles,\n });\n\n if (components.length === 0) {\n log(pc.yellow(\"No components found. Check your patterns or config.\"));\n return {\n success: false,\n outputPath: resolve(configDir, outputFile),\n componentCount: 0,\n propsExtracted: 0,\n usagesFound: 0,\n relationsInferred: 0,\n storiesParsed: 0,\n errors: [{ component: \"*\", error: \"No components found\" }],\n warnings: [],\n };\n }\n\n log(pc.green(` Found ${components.length} components`));\n if (options.verbose) {\n for (const comp of components.slice(0, 10)) {\n log(pc.dim(` - ${comp.name}: ${comp.relativePath}`));\n }\n if (components.length > 10) {\n log(pc.dim(` ... and ${components.length - 10} more`));\n }\n }\n\n // Phase 2: Extract props from TypeScript\n log(pc.dim(\"\\nPhase 2: Extracting props from TypeScript...\"));\n const propsMap = new Map<string, ReturnType<typeof convertToFragmentProps>>();\n const propsResults = new Map<string, PropsExtractionResult>();\n let propsExtracted = 0;\n\n for (const comp of components) {\n try {\n const extraction = await extractPropsFromFile(comp.sourcePath, {\n propsTypeName: `${comp.name}Props`,\n });\n\n propsResults.set(comp.name, extraction);\n\n if (extraction.success && extraction.props.length > 0) {\n propsMap.set(comp.name, convertToFragmentProps(extraction.props));\n propsExtracted++;\n }\n } catch (e) {\n if (options.verbose) {\n warnings.push({\n component: comp.name,\n warning: `Props extraction failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n }\n\n log(pc.green(` Extracted props for ${propsExtracted} components`));\n\n // Phase 3: Scan for usage patterns\n let usageAnalysis: UsageAnalysis | undefined;\n let usagesFound = 0;\n let allRelations = new Map<string, ComponentRelation[]>();\n\n if (!options.skipUsage) {\n log(pc.dim(\"\\nPhase 3: Scanning for usage patterns...\"));\n const usageDir = options.usageDir || configDir;\n\n try {\n // Get component names for filtering\n const componentNames = components.map((c) => c.name);\n\n usageAnalysis = await scanCodebase({\n rootDir: usageDir,\n include: [\"**/*.tsx\", \"**/*.ts\", \"**/*.jsx\", \"**/*.js\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/*.stories.*\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n ],\n componentNames,\n useCache: true,\n });\n\n // Count total usages across all components\n usagesFound = Object.values(usageAnalysis.components).reduce(\n (sum, comp) => sum + comp.totalUsages,\n 0\n );\n\n // Infer relations\n allRelations = inferAllRelations(usageAnalysis);\n log(pc.green(` Found ${usagesFound} usages across ${usageAnalysis.totalFiles} files`));\n log(pc.green(` Inferred relations for ${allRelations.size} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Usage scanning failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n log(pc.yellow(` Usage scanning failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n log(pc.dim(\"\\nPhase 3: Skipping usage analysis\"));\n }\n\n // Phase 4: Parse Storybook stories\n const storiesMap = new Map<string, ParsedStoryFile>();\n let storiesParsed = 0;\n\n if (!options.skipStorybook) {\n log(pc.dim(\"\\nPhase 4: Parsing Storybook stories...\"));\n\n try {\n const allStories = await parseAllStories(configDir);\n\n for (const [name, stories] of Object.entries(allStories)) {\n if (stories && stories.stories.length > 0) {\n storiesMap.set(name, stories);\n storiesParsed++;\n }\n }\n\n log(pc.green(` Parsed stories for ${storiesParsed} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Storybook parsing failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n log(pc.yellow(` Storybook parsing failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n log(pc.dim(\"\\nPhase 4: Skipping Storybook parsing\"));\n }\n\n // Phase 5: Generate fragments\n log(pc.dim(\"\\nPhase 5: Generating fragments...\"));\n const fragments: Record<string, CompiledFragment> = {};\n\n for (const comp of components) {\n try {\n const fragment = generateFragmentFromData(\n comp,\n configDir,\n propsMap.get(comp.name),\n usageAnalysis?.components[comp.name],\n allRelations.get(comp.name),\n storiesMap.get(comp.name)\n );\n\n fragments[comp.name] = fragment;\n } catch (e) {\n errors.push({\n component: comp.name,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n // Write output\n const outputPath = resolve(configDir, outputFile);\n await mkdir(dirname(outputPath), { recursive: true });\n\n const output: CompiledFragmentsFile = {\n version: \"1.0.0\",\n generatedAt: new Date().toISOString(),\n fragments,\n };\n\n await writeFile(outputPath, JSON.stringify(output, null, 2));\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n\n // Summary\n log(pc.dim(\"\\n────────────────────────────────────────\"));\n log(pc.green(`\\n✓ Generated fragments.json in ${elapsed}s`));\n log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));\n log(pc.dim(` Components: ${Object.keys(fragments).length}`));\n log(pc.dim(` Props extracted: ${propsExtracted}`));\n log(pc.dim(` Usages found: ${usagesFound}`));\n log(pc.dim(` Relations inferred: ${allRelations.size}`));\n log(pc.dim(` Stories parsed: ${storiesParsed}`));\n\n if (warnings.length > 0) {\n log(pc.yellow(`\\n ${warnings.length} warning(s)`));\n if (options.verbose) {\n for (const w of warnings) {\n log(pc.dim(` ${w.component}: ${w.warning}`));\n }\n }\n }\n\n if (errors.length > 0) {\n log(pc.red(`\\n ${errors.length} error(s)`));\n for (const e of errors) {\n log(pc.dim(` ${e.component}: ${e.error}`));\n }\n }\n\n log();\n\n return {\n success: errors.length === 0,\n outputPath,\n componentCount: Object.keys(fragments).length,\n propsExtracted,\n usagesFound,\n relationsInferred: allRelations.size,\n storiesParsed,\n errors,\n warnings,\n };\n}\n\n/**\n * Generate a CompiledFragment from extracted data\n */\nfunction generateFragmentFromData(\n comp: DiscoveredComponent,\n configDir: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n relations: ComponentRelation[] | undefined,\n storyFile: ParsedStoryFile | undefined\n): CompiledFragment {\n // Generate context for AI suggestions\n const context = generateComponentContext(\n comp.name,\n usageAnalysis,\n undefined, // No extracted docs yet\n storyFile,\n undefined, // No props extraction result (we have the converted props already)\n relations\n );\n\n // Generate enhancement suggestions from context\n const suggestions = generateEnhancementSuggestions(context);\n\n // Filter boilerplate from suggestions\n const when = filterBoilerplate(suggestions.suggestions.when);\n const whenNot = filterBoilerplate(suggestions.suggestions.whenNot);\n\n // Infer category from path\n const category = inferCategory(comp.relativePath);\n\n // Infer status from path\n const status = inferStatus(comp.relativePath);\n\n // Build variants from stories\n const variants: CompiledFragment[\"variants\"] = [];\n if (storyFile?.stories) {\n for (const story of storyFile.stories) {\n variants.push({\n name: story.name,\n description: story.description || `${story.displayName} variant`,\n code: story.code,\n });\n }\n }\n\n // Build relations\n const compiledRelations: CompiledFragment[\"relations\"] = [];\n if (relations && relations.length > 0) {\n for (const rel of relations.slice(0, 10)) {\n compiledRelations.push({\n component: rel.component,\n relationship: rel.relationship,\n note: `Appears together ${rel.frequency} times`,\n });\n }\n }\n\n // Generate description\n const description = generateDescription(comp.name, props, usageAnalysis);\n\n return {\n filePath: comp.relativePath,\n meta: {\n name: comp.name,\n description,\n category,\n status,\n },\n usage: {\n when: when.length > 0 ? when : [`Use ${comp.name} for its intended purpose`],\n whenNot: whenNot,\n },\n props: props || {},\n relations: compiledRelations.length > 0 ? compiledRelations : undefined,\n variants,\n _generated: {\n source: \"ai\",\n sourceFile: comp.relativePath,\n confidence: calculateConfidence(props, usageAnalysis, storyFile),\n timestamp: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Infer category from file path\n */\nfunction inferCategory(relativePath: string): string {\n const parts = relativePath.toLowerCase().split(\"/\");\n\n // Common category patterns\n const categoryPatterns: Record<string, string[]> = {\n \"Actions\": [\"button\", \"action\", \"cta\"],\n \"Forms\": [\"form\", \"input\", \"select\", \"checkbox\", \"radio\", \"textarea\", \"field\"],\n \"Layout\": [\"layout\", \"container\", \"grid\", \"flex\", \"stack\", \"box\", \"divider\", \"spacer\"],\n \"Navigation\": [\"nav\", \"menu\", \"breadcrumb\", \"tab\", \"link\", \"pagination\"],\n \"Feedback\": [\"alert\", \"toast\", \"notification\", \"message\", \"badge\", \"indicator\", \"progress\", \"spinner\", \"loading\"],\n \"Data Display\": [\"table\", \"list\", \"card\", \"avatar\", \"stat\", \"timeline\", \"tree\"],\n \"Overlays\": [\"modal\", \"dialog\", \"drawer\", \"popover\", \"tooltip\", \"dropdown\"],\n \"Typography\": [\"text\", \"heading\", \"title\", \"label\", \"paragraph\"],\n \"Media\": [\"image\", \"video\", \"icon\", \"avatar\"],\n };\n\n for (const [category, patterns] of Object.entries(categoryPatterns)) {\n for (const pattern of patterns) {\n if (parts.some((part) => part.includes(pattern))) {\n return category;\n }\n }\n }\n\n // Check path structure for category\n const componentIdx = parts.findIndex((p) => p === \"components\");\n if (componentIdx !== -1 && parts.length > componentIdx + 1) {\n const categoryPart = parts[componentIdx + 1];\n return categoryPart.charAt(0).toUpperCase() + categoryPart.slice(1);\n }\n\n return \"Components\";\n}\n\n/**\n * Infer status from file path\n */\nfunction inferStatus(\n relativePath: string\n): \"stable\" | \"beta\" | \"experimental\" | \"deprecated\" {\n const lowerPath = relativePath.toLowerCase();\n\n if (lowerPath.includes(\"/experimental/\") || lowerPath.includes(\"/labs/\")) {\n return \"experimental\";\n }\n if (lowerPath.includes(\"/beta/\")) {\n return \"beta\";\n }\n if (lowerPath.includes(\"/deprecated/\") || lowerPath.includes(\"/legacy/\")) {\n return \"deprecated\";\n }\n\n return \"stable\";\n}\n\n/**\n * Generate component description\n */\nfunction generateDescription(\n name: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined\n): string {\n // Convert name to readable form\n const words = name\n .replace(/([A-Z])/g, \" $1\")\n .trim()\n .toLowerCase();\n\n // Check props for hints\n const hasOnClick = props && (\"onClick\" in props || \"onPress\" in props);\n const hasValue = props && (\"value\" in props || \"defaultValue\" in props);\n const hasChildren = props && \"children\" in props;\n const hasHref = props && \"href\" in props;\n\n // Check usage contexts\n const topContext = usageAnalysis?.contexts[0]?.type;\n\n if (hasHref) {\n return `Navigational ${words} for linking to other pages or resources`;\n }\n\n if (hasOnClick && !hasValue) {\n return `Interactive ${words} for triggering actions`;\n }\n\n if (hasValue) {\n return `Form ${words} for user input`;\n }\n\n if (topContext && topContext !== \"unknown\") {\n return `${words.charAt(0).toUpperCase() + words.slice(1)} commonly used in ${topContext} contexts`;\n }\n\n if (hasChildren) {\n return `Container ${words} for composing UI`;\n }\n\n return `${words.charAt(0).toUpperCase() + words.slice(1)} component`;\n}\n\n/**\n * Calculate confidence score based on available data\n */\nfunction calculateConfidence(\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n storyFile: ParsedStoryFile | undefined\n): number {\n let confidence = 0;\n\n // Props give +30 confidence\n if (props && Object.keys(props).length > 0) {\n confidence += 30;\n }\n\n // Usage data gives up to +40 confidence\n if (usageAnalysis) {\n if (usageAnalysis.totalUsages > 10) confidence += 40;\n else if (usageAnalysis.totalUsages > 5) confidence += 30;\n else if (usageAnalysis.totalUsages > 0) confidence += 20;\n }\n\n // Stories give +30 confidence\n if (storyFile && storyFile.stories.length > 0) {\n confidence += 30;\n }\n\n return Math.min(confidence, 100);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -241,7 +241,13 @@ var fragmentContractSchema = z.object({
|
|
|
241
241
|
a11yRules: z.array(z.string()).optional(),
|
|
242
242
|
bans: z.array(fragmentBanSchema).optional(),
|
|
243
243
|
scenarioTags: z.array(z.string()).optional(),
|
|
244
|
-
performanceBudget: z.number().positive().optional()
|
|
244
|
+
performanceBudget: z.number().positive().optional(),
|
|
245
|
+
compoundChildren: z.record(z.object({
|
|
246
|
+
required: z.boolean().optional(),
|
|
247
|
+
accepts: z.array(z.string()).optional(),
|
|
248
|
+
description: z.string().optional()
|
|
249
|
+
})).optional(),
|
|
250
|
+
canonicalUsage: z.array(z.string()).optional()
|
|
245
251
|
});
|
|
246
252
|
var fragmentGeneratedSchema = z.object({
|
|
247
253
|
source: z.enum(["storybook", "manual", "ai"]),
|
|
@@ -314,14 +320,76 @@ var fragmentsConfigSchema = z.object({
|
|
|
314
320
|
excludeSubComponents: z.boolean().optional()
|
|
315
321
|
}).optional()
|
|
316
322
|
});
|
|
323
|
+
var compositionMetadataSchema = z.object({
|
|
324
|
+
pattern: z.enum(["compound", "simple", "controlled", "wrapper"]).optional(),
|
|
325
|
+
subComponents: z.array(z.string()).optional(),
|
|
326
|
+
requiredChildren: z.array(z.string()).optional(),
|
|
327
|
+
commonPatterns: z.array(z.string()).optional()
|
|
328
|
+
});
|
|
329
|
+
var fragmentProvenanceSchema = z.object({
|
|
330
|
+
source: z.enum(["storybook", "manual", "ai", "scan"]),
|
|
331
|
+
sourceFile: z.string().optional(),
|
|
332
|
+
confidence: z.number().min(0).max(1).optional(),
|
|
333
|
+
timestamp: z.string().datetime().optional(),
|
|
334
|
+
autoFields: z.array(z.string()).optional(),
|
|
335
|
+
humanFields: z.array(z.string()).optional()
|
|
336
|
+
});
|
|
337
|
+
var fragmentDefinitionV2Schema = z.object({
|
|
338
|
+
component: z.any(),
|
|
339
|
+
meta: fragmentMetaSchema,
|
|
340
|
+
guidance: fragmentUsageSchema,
|
|
341
|
+
props: z.record(propDefinitionSchema),
|
|
342
|
+
relations: z.array(componentRelationSchema).optional(),
|
|
343
|
+
examples: z.array(fragmentVariantSchema),
|
|
344
|
+
composition: compositionMetadataSchema.optional(),
|
|
345
|
+
contract: fragmentContractSchema.optional(),
|
|
346
|
+
_provenance: fragmentProvenanceSchema.optional()
|
|
347
|
+
});
|
|
317
348
|
var recipeDefinitionSchema = blockDefinitionSchema;
|
|
349
|
+
function isV2Definition(def) {
|
|
350
|
+
return "guidance" in def || "examples" in def;
|
|
351
|
+
}
|
|
352
|
+
function normalizeToV1(def) {
|
|
353
|
+
let ai;
|
|
354
|
+
if (def.composition) {
|
|
355
|
+
ai = {
|
|
356
|
+
compositionPattern: def.composition.pattern,
|
|
357
|
+
subComponents: def.composition.subComponents,
|
|
358
|
+
requiredChildren: def.composition.requiredChildren,
|
|
359
|
+
commonPatterns: def.composition.commonPatterns
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
let generated;
|
|
363
|
+
if (def._provenance) {
|
|
364
|
+
generated = {
|
|
365
|
+
source: def._provenance.source === "scan" ? "ai" : def._provenance.source,
|
|
366
|
+
sourceFile: def._provenance.sourceFile,
|
|
367
|
+
confidence: def._provenance.confidence,
|
|
368
|
+
timestamp: def._provenance.timestamp
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
component: def.component,
|
|
373
|
+
meta: def.meta,
|
|
374
|
+
usage: def.guidance,
|
|
375
|
+
props: def.props,
|
|
376
|
+
relations: def.relations,
|
|
377
|
+
variants: def.examples,
|
|
378
|
+
contract: def.contract,
|
|
379
|
+
ai,
|
|
380
|
+
_generated: generated
|
|
381
|
+
};
|
|
382
|
+
}
|
|
318
383
|
function defineFragment(definition) {
|
|
319
384
|
if (process.env.NODE_ENV !== "production") {
|
|
320
|
-
const
|
|
385
|
+
const v2 = isV2Definition(definition);
|
|
386
|
+
const schema = v2 ? fragmentDefinitionV2Schema : fragmentDefinitionSchema;
|
|
387
|
+
const result = schema.safeParse(definition);
|
|
321
388
|
if (!result.success) {
|
|
389
|
+
const name = definition.meta?.name || "unknown";
|
|
322
390
|
const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
|
|
323
391
|
throw new Error(
|
|
324
|
-
`Invalid fragment definition for "${
|
|
392
|
+
`Invalid fragment definition for "${name}":
|
|
325
393
|
${errors}`
|
|
326
394
|
);
|
|
327
395
|
}
|
|
@@ -329,20 +397,22 @@ ${errors}`
|
|
|
329
397
|
return definition;
|
|
330
398
|
}
|
|
331
399
|
function compileFragment(definition, filePath) {
|
|
400
|
+
const v1 = isV2Definition(definition) ? normalizeToV1(definition) : definition;
|
|
332
401
|
return {
|
|
333
402
|
filePath,
|
|
334
|
-
meta:
|
|
335
|
-
usage:
|
|
336
|
-
props:
|
|
337
|
-
relations:
|
|
338
|
-
variants:
|
|
403
|
+
meta: v1.meta,
|
|
404
|
+
usage: v1.usage,
|
|
405
|
+
props: v1.props,
|
|
406
|
+
relations: v1.relations,
|
|
407
|
+
variants: v1.variants.map((v) => ({
|
|
339
408
|
name: v.name,
|
|
340
409
|
description: v.description,
|
|
341
410
|
code: v.code,
|
|
342
411
|
figma: v.figma
|
|
343
412
|
})),
|
|
344
|
-
contract:
|
|
345
|
-
|
|
413
|
+
contract: v1.contract,
|
|
414
|
+
ai: v1.ai,
|
|
415
|
+
_generated: v1._generated
|
|
346
416
|
};
|
|
347
417
|
}
|
|
348
418
|
function defineBlock(definition) {
|
|
@@ -1357,6 +1427,38 @@ function PreviewVariantRuntime({
|
|
|
1357
1427
|
const state = usePreviewVariantRuntime({ variant, loadedData });
|
|
1358
1428
|
return /* @__PURE__ */ jsx(Fragment, { children: children2(state) });
|
|
1359
1429
|
}
|
|
1430
|
+
function isReactComponent(value) {
|
|
1431
|
+
if (!value) return false;
|
|
1432
|
+
if (typeof value === "function") {
|
|
1433
|
+
return true;
|
|
1434
|
+
}
|
|
1435
|
+
if (typeof value === "object") {
|
|
1436
|
+
const obj = value;
|
|
1437
|
+
if (obj.$$typeof) return true;
|
|
1438
|
+
}
|
|
1439
|
+
return false;
|
|
1440
|
+
}
|
|
1441
|
+
function discoverComponents(moduleExports, options) {
|
|
1442
|
+
const exclude = options?.exclude;
|
|
1443
|
+
const names = [];
|
|
1444
|
+
for (const [exportName, exportValue] of Object.entries(moduleExports)) {
|
|
1445
|
+
if (exclude?.has(exportName)) continue;
|
|
1446
|
+
if (!isReactComponent(exportValue)) continue;
|
|
1447
|
+
if (exportName[0] !== exportName[0].toUpperCase()) continue;
|
|
1448
|
+
names.push(exportName);
|
|
1449
|
+
const componentObj = exportValue;
|
|
1450
|
+
for (const key of Object.keys(componentObj)) {
|
|
1451
|
+
if (key.startsWith("_") || key.startsWith("$")) continue;
|
|
1452
|
+
if (key === "displayName" || key === "propTypes" || key === "defaultProps") continue;
|
|
1453
|
+
if (key === "render" || key === "Tabbed") continue;
|
|
1454
|
+
const subComponent = componentObj[key];
|
|
1455
|
+
if (isReactComponent(subComponent)) {
|
|
1456
|
+
names.push(`${exportName}.${key}`);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
return names.sort();
|
|
1461
|
+
}
|
|
1360
1462
|
|
|
1361
1463
|
export {
|
|
1362
1464
|
BRAND,
|
|
@@ -1379,7 +1481,11 @@ export {
|
|
|
1379
1481
|
blockDefinitionSchema,
|
|
1380
1482
|
fragmentDefinitionSchema,
|
|
1381
1483
|
fragmentsConfigSchema,
|
|
1484
|
+
compositionMetadataSchema,
|
|
1485
|
+
fragmentProvenanceSchema,
|
|
1486
|
+
fragmentDefinitionV2Schema,
|
|
1382
1487
|
recipeDefinitionSchema,
|
|
1488
|
+
normalizeToV1,
|
|
1383
1489
|
defineFragment,
|
|
1384
1490
|
compileFragment,
|
|
1385
1491
|
defineBlock,
|
|
@@ -1405,6 +1511,8 @@ export {
|
|
|
1405
1511
|
executeVariantLoaders,
|
|
1406
1512
|
resolvePreviewRuntimeState,
|
|
1407
1513
|
usePreviewVariantRuntime,
|
|
1408
|
-
PreviewVariantRuntime
|
|
1514
|
+
PreviewVariantRuntime,
|
|
1515
|
+
isReactComponent,
|
|
1516
|
+
discoverComponents
|
|
1409
1517
|
};
|
|
1410
|
-
//# sourceMappingURL=chunk-
|
|
1518
|
+
//# sourceMappingURL=chunk-QM7SVOGF.js.map
|