UNPKG

@frontify/fondue

Version:
259 lines (258 loc) 7.07 kB
#!/usr/bin/env node import { Command } from "commander"; import { writeFileSync, existsSync, rmSync, readFileSync } from "node:fs"; import path, { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { createRequire } from "node:module"; import { execa } from "execa"; const deprecated = [ "Accordion", "AccordionHeaderIcon", "AccordionHeaderProps", "AccordionItem", "ActionMenuProps", "Breadcrumb", "Breadcrumbs", "CollapsibleWrap", "Color", "DatePicker", "DatePickerProps", "DatePickerTrigger", "EditableMode", "EditableText", "EditableTextProps", "FOCUS_VISIBLE_STYLE", "FOCUS_VISIBLE_STYLE_INSET", "FOCUS_WITHIN_STYLE", "FilterableMultiSelect", "FilterableMultiSelectItem", "FilterableMultiSelectProps", "FilterableMultiSelectSize", "FilterableMultiSelectType", "FormControl", "FormControlDirection", "FormControlProps", "FormControlStyle", "FrontifyPattern", "HelperPosition", "Item", "LegacyTextarea", "LegacyTextareaProps", "MenuItem", "MenuItemContentSize", "MenuItemProps", "MenuItemStyle", "MenuItemType", "MultiSelect", "MultiSelectItem", "MultiSelectProps", "MultiSelectSize", "MultiSelectType", "OrderableList", "OrderableListItem", "OrderableListItemStyle", "OrderableListProps", "Palette", "PatternDesign", "PatternScale", "PatternTheme", "ReactDatePickerRef", "RenderListItem", "TABBABLE_ELEMENTS", "Toast", "ToastAnimationDirection", "ToastStyle", "Validation", "useCopy", "useForwardedRef", "useMemoizedId", "useMobileDetection" ]; const active = [ "AssetInput", "AssetInputMenuBlock", "AssetInputMenuDefaultItemType", "AssetInputMenuItemContentProps", "AssetInputMenuItemContentSize", "AssetInputMenuItemProps", "AssetInputMenuItemStyle", "AssetInputMenuItemType", "AssetInputMenuSwitchItemType", "AssetInputProps", "AssetInputSelectionIndicatorIcon", "AssetInputSize", "AssetType", "CollapsibleWrap", "CollisionPosition", "DragHandle", "DragHandleProps", "DragHandlerPosition", "EXPAND_ONHOVER_DELAY", "ExpandButton", "ExpandButtonProps", "FilterableMultiSelect", "INDENTATION_WIDTH", "ImageAsset", "InputLabelProps", "InternalTreeItemMultiSelectProps", "InternalTreeItemProps", "LegacyTextarea", "LibrarySource", "MultiSelect", "OnExpandCallback", "OnSelectCallback", "OnSelectInternalCallback", "OnShrinkCallback", "OnTreeDropCallback", "OrderableList", "PatternScaleOrigin", "Projection", "ProjectionArgs", "ROOT_ID", "RegisterNodeChildrenPayload", "SensorContext", "SortableProps", "SortableTreeItemProps", "Tree", "TreeActive", "TreeAnnouncements", "TreeDragCancelEvent", "TreeDragEndEvent", "TreeDragMoveEvent", "TreeDragOverEvent", "TreeDragStartEvent", "TreeItem", "TreeItemBorderClassMap", "TreeItemBorderRadiusClassMap", "TreeItemBorderStyleClassMap", "TreeItemColors", "TreeItemColorsClassMap", "TreeItemMultiselect", "TreeItemMultiselectProps", "TreeItemMultiselectWithNodes", "TreeItemOverlay", "TreeItemProps", "TreeItemPropsSizing", "TreeItemShadowClassMap", "TreeItemSpacingClassMap", "TreeItemState", "TreeItemStyling", "TreeItemWithContentComponentProps", "TreeItemWithLabelProps", "TreeNodeWithoutElements", "TreeOver", "TreeProps", "TreeState", "TreeStateAction", "UploadSource", "addSelectedIds", "addSelectedItemsFromSelection", "cleanOrphanSelectedIds", "convertToPartialSelectedId", "currentNodesChanged", "extractNodeFromElement", "findIndexById", "fixParentSelectionState", "getAnnouncements", "getCurrentChildrenForNewNodesIfExpanded", "getExtendedId", "getMultiselectCheckBoxState", "getNewSelectedItems", "getNodeChildrenIds", "getNodesToRender", "getParentSelectedTreeItem", "getProjection", "getReactNodeIdsInFlatArray", "getReactNodesInFlatArray", "getSelectedChildrenItems", "getSelectedTreeItem", "getTreeNodesWithoutElements", "getVerticalPositioning", "handleKeyDownEvent", "removePartialFlagSelectedId", "removeReactNodesFromFlatArray", "removeSelectedIds", "sensorsActivationConstraint", "shouldUpdateTreeState", "updateNodeWithNewChildren", "useTreeItem" ]; const detectedExports = { deprecated, active }; const __dirname$2 = dirname(fileURLToPath(import.meta.url)); const require$1 = createRequire(import.meta.url); const transformsDirectory = join(__dirname$2, "transforms"); const jscodeshiftExecutable = require$1.resolve(".bin/jscodeshift"); const runCodeshift = async (pathToAnalyze, transformName, options) => { const transformPath = join(transformsDirectory, `${transformName}.ts`); await execa( jscodeshiftExecutable, [ "--parser", "tsx", "--extensions", "ts,tsx,js,jsx", "--ignore-pattern", "**/node_modules/**", "--ignore-pattern", "**/dist/**", "--ignore-pattern", "**/build/**", "--ignore-pattern", "**/.git/**", "--ignore-pattern", "**/public/**", "--transform", transformPath, pathToAnalyze ], { env: { ...options } } ); return; }; const __dirname$1 = dirname(fileURLToPath(import.meta.url)); const tempDir = path.resolve(__dirname$1, "./temp"); const getImports = (pathToAnalyze, selectedImports = []) => { if (existsSync(tempDir)) { rmSync(tempDir, { recursive: true }); } return runCodeshift(pathToAnalyze, "find-imports", { selectedImports: selectedImports.join(","), tempDir }).then(() => { if (existsSync(join(tempDir, "detected-imports.txt"))) { const detectedImports = readFileSync(join(tempDir, "detected-imports.txt"), "utf8").split("\n").filter((line) => line.trim() !== "").map((line) => JSON.parse(line)); rmSync(join(tempDir), { recursive: true }); return detectedImports; } else { return []; } }); }; const findUnusedExports = (pathToAnalyze, outputPath, onlyDeprecated) => { const fondueExports = [...detectedExports.deprecated, ...onlyDeprecated ? [] : detectedExports.active]; getImports(pathToAnalyze, fondueExports).then((detectedImports) => { const unusedExports = fondueExports.filter( (selectedExport) => !detectedImports.some((detectedImport) => detectedImport.imports.includes(selectedExport)) ); if (outputPath) { writeFileSync(outputPath, JSON.stringify(unusedExports, null, 4), "utf8"); } else { console.log(unusedExports); } }).catch((error) => { console.error("ERROR", error); }); }; const program = new Command(); program.name("fondue-analyzer").description("Analyze fondue usage"); program.command("find-unused-exports").description("Find unused fondue exports").argument("<path>", "Path to be analyzed").option("--only-deprecated", "Only find unused deprecated exports").option("-o, --output <path>", "Output path").action((path2, options) => { findUnusedExports(path2, options.output, options.onlyDeprecated); }); program.parse();