diff --git a/codemods/debarrel/CHANGELOG.md b/codemods/debarrel/CHANGELOG.md index d1dfe96..f35b876 100644 --- a/codemods/debarrel/CHANGELOG.md +++ b/codemods/debarrel/CHANGELOG.md @@ -1,5 +1,66 @@ # debarrel +## 0.7.11 + +### Patch Changes + +- Parse JSONC `tsconfig.json` files (comments and trailing commas) so tsconfig path aliases resolve on real-world configs. +- Route semantic-analyzer-resolved rewrites through `buildRewriteFromTarget` so default imports and barrel metrics stay correct. +- Distinguish `export { default } from "./x"` from `export { Foo as default }` when choosing import type. +- Cache workspace source file listings during namespace-importer detection. +- Use `path.relative` instead of a hand-rolled relative path helper. + +## 0.7.10 + +### Patch Changes + +- Commit barrel renames when a barrel file has no import edits (fixes `.tsx` barrels being skipped when `edits` is empty). +- Add Sentry-shaped test fixtures for `sentry/stories` and `sentry/icons` namespace barrel preservation. + +## 0.7.9 + +### Patch Changes + +- Preserve namespace-imported barrels when tsconfig aliases share the package name (e.g. `sentry/stories` with `sentry/*` paths) by inverse-mapping alias strings and matching import paths directly. +- Scan `.mdx` files for namespace imports when deciding whether to keep a barrel. +- Resolve tsconfig and workspace roots with absolute paths during namespace-importer detection. + +## 0.7.8 + +### Patch Changes + +- Resolve barrel symbols using the imported name (`Foo` in `import { Foo as Bar }`), not the local alias, so folder barrels and wildcard aliases debarrel correctly. +- Replace `path.relative` with portable helpers for the JSSG runtime when computing paths from a barrel directory to its exports. +- Normalize barrel paths when detecting namespace importers so barrels are preserved reliably. + +## 0.7.7 + +### Patch Changes + +- Fix double `type` keyword in rewritten `import type { … }` statements when specifiers use inline `type` qualifiers. +- Resolve imports against `index.barrel.bak.*` when a barrel has already been renamed in the same pass, so consumers processed later still rewrite correctly. +- Match namespace-importer barrels by directory path, not only exact barrel file path. +- Rewrite relative folder imports (e.g. `../textarea`) to the concrete module when the directory barrel is removed. + +## 0.7.6 + +### Patch Changes + +- Fix invalid `import type { type Foo }` output when rewriting top-level `import type` statements. Inline `type` qualifiers are now only emitted for mixed value/type imports split across paths. +- Preserve barrel files that are namespace-imported (`import * as Ns from "…"`), since those imports cannot be debarreled to a single module. + +## 0.7.5 + +### Patch Changes + +- Rewrite default imports that flow through `export { Foo as default }` barrel re-exports when the semantic analyzer cannot resolve the binding. Also walk explicit `export { … } from` re-exports before falling back to `export *` chains, and preserve inline `import { type Foo }` specifiers when splitting partial barrel imports. + +## 0.7.4 + +### Patch Changes + +- Fix debarreling of tsconfig/webpack subpath aliases whose prefix matches the workspace `package.json` name (e.g. `myapp/widgets` when the package is named `myapp`). Previously the package-boundary guard treated every such import as a root package import and skipped rewriting, leaving consumers pointing at deleted barrel files. Also resolve alias imports when walking `export *` barrels and when semantic analysis resolves through a barrel to the source file. + ## 0.7.3 ### Patch Changes diff --git a/codemods/debarrel/codemod.yaml b/codemods/debarrel/codemod.yaml index 27b277d..fae98b6 100644 --- a/codemods/debarrel/codemod.yaml +++ b/codemods/debarrel/codemod.yaml @@ -1,7 +1,7 @@ schema_version: "1.0" name: "debarrel" -version: "0.7.3" +version: "0.7.11" description: "Debarrel JS/TS codebases. Removing barrel files and replacing import statements." author: "Mo Mohebifar " license: "MIT" diff --git a/codemods/debarrel/package.json b/codemods/debarrel/package.json index 729cd69..1000263 100644 --- a/codemods/debarrel/package.json +++ b/codemods/debarrel/package.json @@ -1,6 +1,6 @@ { "name": "debarrel", - "version": "0.7.3", + "version": "0.7.11", "description": "Debarrel JS/TS codebases. Removing barrel files and replacing import statements.", "type": "module", "scripts": { diff --git a/codemods/debarrel/scripts/codemod.ts b/codemods/debarrel/scripts/codemod.ts index 0fb4138..10f00b1 100644 --- a/codemods/debarrel/scripts/codemod.ts +++ b/codemods/debarrel/scripts/codemod.ts @@ -1,8 +1,8 @@ -import type { Codemod, Edit, GetSelector } from "codemod:ast-grep"; +import type { Codemod, Edit, GetSelector, SgNode } from "codemod:ast-grep"; import { useMetricAtom } from "codemod:metrics"; import path from "path"; import type { Language } from "./utils/language.ts"; -import { getStringContent } from "./utils/ast.ts"; +import { getStringContent, getImportSpecifierNames } from "./utils/ast.ts"; import { hasPackageJson, isBarrelFile, @@ -10,6 +10,7 @@ import { isNextPagesApiRoute, isPackageEntrypoint, } from "./utils/paths.ts"; +import { barrelHasNamespaceImporters } from "./utils/exportStar.ts"; import { isPureBarrel } from "./utils/barrel.ts"; import { resolveSpecifier, type SpecRewrite } from "./utils/specifiers.ts"; import { buildImportText, groupByPath } from "./utils/imports.ts"; @@ -48,6 +49,9 @@ const codemod: Codemod = async (root, options) => { // resolved declarations are `export type` aliases). const isTypeOnlyImport = importStmt.children().some((c) => c.is("type")); + const isTypeOnlySpecifier = (spec: SgNode) => + spec.children().some((c) => c.is("type")); + const rewrites: SpecRewrite[] = []; let totalSpecifiers = 0; @@ -61,19 +65,30 @@ const codemod: Codemod = async (root, options) => { }); totalSpecifiers += specifiers.length; for (const spec of specifiers) { - const identifiers = spec.findAll({ rule: { kind: "identifier" } }); - const localBinding = identifiers[identifiers.length - 1]; + const names = getImportSpecifierNames(spec); + if (!names) continue; + const { importedName, localName: consumerName } = names; + const localBinding = spec + .findAll({ rule: { kind: "identifier" } }) + .at(-1); if (!localBinding) continue; const def = localBinding.definition(); if (!def) continue; const rw = resolveSpecifier( - localBinding, + importedName, + consumerName, importPath, def, filename, relativeFilename, + false, ); - if (rw) rewrites.push(rw); + if (rw) { + if (!isTypeOnlyImport && isTypeOnlySpecifier(spec)) { + rw.typeOnly = true; + } + rewrites.push(rw); + } } } @@ -89,11 +104,13 @@ const codemod: Codemod = async (root, options) => { const def = defaultIdent.definition(); if (def) { const rw = resolveSpecifier( - defaultIdent, + defaultIdent.text(), + defaultIdent.text(), importPath, def, filename, relativeFilename, + true, ); if (rw) rewrites.push(rw); } @@ -159,6 +176,7 @@ const codemod: Codemod = async (root, options) => { // Barrel rename — skip files inside node_modules or inside a package // when the barrel is an actual package entrypoint (renaming it would break // consumers importing via the package name). + let barrelRenamed = false; if ( isBarrelFile(filename) && !isInsideNodeModules(filename) && @@ -166,12 +184,19 @@ const codemod: Codemod = async (root, options) => { (!hasPackageJson(filename) || !isPackageEntrypoint(filename)) ) { const { pure, hasWildcards } = isPureBarrel(rootNode); - if (pure && !hasWildcards) { + if ( + pure && + !hasWildcards && + !barrelHasNamespaceImporters(filename) + ) { root.rename(`index.barrel.bak${path.extname(filename)}`); + barrelRenamed = true; } } - if (edits.length === 0) return null; + if (edits.length === 0) { + return barrelRenamed ? rootNode.commitEdits([]) : null; + } return rootNode.commitEdits(edits); }; diff --git a/codemods/debarrel/scripts/utils/ast.ts b/codemods/debarrel/scripts/utils/ast.ts index b2eacfb..95ebf16 100644 --- a/codemods/debarrel/scripts/utils/ast.ts +++ b/codemods/debarrel/scripts/utils/ast.ts @@ -5,3 +5,14 @@ export function getStringContent(node: SgNode): string | null { const fragment = node.find({ rule: { kind: "string_fragment" } }); return fragment ? fragment.text() : null; } + +/** Imported binding vs local alias for `import { Foo as Bar }`. */ +export function getImportSpecifierNames( + spec: SgNode, +): { importedName: string; localName: string } | null { + const identifiers = spec.findAll({ rule: { kind: "identifier" } }); + if (identifiers.length === 0) return null; + const importedName = identifiers[0]!.text(); + const localName = identifiers[identifiers.length - 1]!.text(); + return { importedName, localName }; +} diff --git a/codemods/debarrel/scripts/utils/barrel.ts b/codemods/debarrel/scripts/utils/barrel.ts index 167af86..b434bd0 100644 --- a/codemods/debarrel/scripts/utils/barrel.ts +++ b/codemods/debarrel/scripts/utils/barrel.ts @@ -12,10 +12,17 @@ export interface BarrelExportInfo { /** * Parse a barrel file's export_statement to extract the re-export source and local name. */ +export interface ParseBarrelExportOptions { + /** True when the consumer uses `import Binding from "…"` syntax. */ + isDefaultImport?: boolean; +} + export function parseBarrelExport( exportStmt: SgNode, consumerImportName: string, + options: ParseBarrelExportOptions = {}, ): BarrelExportInfo | null { + const { isDefaultImport = false } = options; const children = exportStmt.children(); const sourceNode = children.find((c) => c.is("string")); const exportClause = children.find((c) => c.is("export_clause")); @@ -51,6 +58,15 @@ export function parseBarrelExport( importType: localName === "default" ? "default" : "named", }; } + if (isDefaultImport && exportedName === "default") { + return { + sourceFromBarrel: sourcePath, + localName: localName ?? consumerImportName, + // `export { default } from "./x"` re-exports a default binding; + // `export { Foo as default }` exposes a named symbol as default. + importType: localName === "default" ? "default" : "named", + }; + } } } diff --git a/codemods/debarrel/scripts/utils/exportStar.ts b/codemods/debarrel/scripts/utils/exportStar.ts index fb58edf..86fa051 100644 --- a/codemods/debarrel/scripts/utils/exportStar.ts +++ b/codemods/debarrel/scripts/utils/exportStar.ts @@ -3,7 +3,17 @@ import path from "path"; import { parse, type SgNode, type SgRoot } from "codemod:ast-grep"; import type { Language } from "./language.ts"; import { getStringContent } from "./ast.ts"; -import { isLocalRelativePath, resolveImportPath } from "./paths.ts"; +import { parseBarrelExport } from "./barrel.ts"; +import { + fileHasMdxNamespaceImportFrom, + findWorkspaceSourceRoot, + getAliasImportPathsForBarrel, + isLocalRelativePath, + normalizeAbsolutePath, + resolveImportPath, + resolveModuleImportPath, + getProjectSourceFiles, +} from "./paths.ts"; // The semantic analyzer's `definition()` does not chase through bare // `export * from "./y"` re-exports in this jssg runtime — for those @@ -138,6 +148,101 @@ export function findSymbolViaExportStar( return walk(barrelFile, name, new Set(), 0); } +export interface BarrelReexportMatch { + targetFile: string; + localName: string; + importType: "default" | "named"; +} + +/** + * Walk `barrelFile`'s explicit `export { … } from "./y"` re-exports to find + * which file provides `name` for a consumer import. Used when the semantic + * analyzer can't resolve the binding (e.g. default imports through + * `export { Foo as default }` re-exports). + */ +export function findSymbolViaBarrelReexports( + barrelFile: string, + consumerName: string, + isDefaultImport: boolean, +): BarrelReexportMatch | null { + const root = parseFile(barrelFile); + if (!root) return null; + + for (const stmt of root.root().children()) { + if (!stmt.is("export_statement")) continue; + // Namespace re-exports (`export * as Ns from "./y"`) are not debarreled here. + if (stmt.children().some((c) => c.is("namespace_export"))) continue; + const info = parseBarrelExport(stmt, consumerName, { isDefaultImport }); + if (!info || info.importType === "namespace") continue; + const targetFile = resolveImportPath(barrelFile, info.sourceFromBarrel); + if (!targetFile) continue; + return { + targetFile, + localName: info.localName, + importType: info.importType, + }; + } + return null; +} + +function barrelDirectory(filePath: string): string | null { + const base = path.basename(filePath); + if (!/^index(\.barrel\.bak)?\.(ts|tsx|js|jsx)$/.test(base)) return null; + return path.resolve(path.dirname(filePath)); +} + +function barrelPathsMatch(left: string, right: string): boolean { + const leftDir = barrelDirectory(left); + const rightDir = barrelDirectory(right); + if (leftDir && rightDir) return leftDir === rightDir; + return path.resolve(left) === path.resolve(right); +} + +/** + * True when any source file in the workspace namespace-imports `barrelFile`. + * Namespace imports cannot be debarreled to a single module, so the barrel must + * be kept when this returns true. + */ +export function barrelHasNamespaceImporters(barrelFile: string): boolean { + const workspaceRoot = findWorkspaceSourceRoot(barrelFile); + const normalizedBarrel = normalizeAbsolutePath(barrelFile, workspaceRoot); + const aliasImportPaths = new Set(getAliasImportPathsForBarrel(barrelFile)); + + for (const file of getProjectSourceFiles(workspaceRoot)) { + if (path.resolve(file) === path.resolve(normalizedBarrel)) continue; + + if (fileHasMdxNamespaceImportFrom(file, aliasImportPaths)) { + return true; + } + + const root = parseFile(file); + if (!root) continue; + + for (const importStmt of root.root().findAll({ + rule: { kind: "import_statement" }, + })) { + const importClause = importStmt + .children() + .find((c) => c.is("import_clause")); + if (!importClause?.find({ rule: { kind: "namespace_import" } })) continue; + + const sourceNode = importStmt.children().find((c) => c.is("string")); + const importPath = sourceNode ? getStringContent(sourceNode) : null; + if (!importPath) continue; + + if (aliasImportPaths.has(importPath)) { + return true; + } + + const resolved = resolveModuleImportPath(file, importPath); + if (resolved && barrelPathsMatch(resolved, normalizedBarrel)) { + return true; + } + } + } + return false; +} + function walk( file: string, name: string, diff --git a/codemods/debarrel/scripts/utils/imports.ts b/codemods/debarrel/scripts/utils/imports.ts index 1bdf5b6..eac077d 100644 --- a/codemods/debarrel/scripts/utils/imports.ts +++ b/codemods/debarrel/scripts/utils/imports.ts @@ -16,15 +16,27 @@ export function buildImportText( parts.push(`* as ${ns.consumerName}`); } const namedSpecs = specs.filter((s) => s.importType === "named"); + const allNamedAreTypeOnly = + namedSpecs.length > 0 && + !defaultSpec && + specs.every((s) => s.importType !== "namespace") && + namedSpecs.every((s) => s.typeOnly); if (namedSpecs.length > 0) { - const specTexts = namedSpecs.map((s) => - s.localName !== s.consumerName - ? `${s.localName} as ${s.consumerName}` - : s.consumerName, - ); + const specTexts = namedSpecs.map((s) => { + // Top-level `import type`, all-type-only imports, and inline `type` on + // specifiers are mutually exclusive — combining them yields invalid + // `import type { type Foo }`. + const typePrefix = + !typeOnly && !allNamedAreTypeOnly && s.typeOnly ? "type " : ""; + const binding = + s.localName !== s.consumerName + ? `${s.localName} as ${s.consumerName}` + : s.consumerName; + return `${typePrefix}${binding}`; + }); parts.push(`{ ${specTexts.join(", ")} }`); } - const typeKeyword = typeOnly ? "type " : ""; + const typeKeyword = typeOnly || allNamedAreTypeOnly ? "type " : ""; return `import ${typeKeyword}${parts.join(", ")} from ${quoteChar}${sourcePath}${quoteChar};`; } diff --git a/codemods/debarrel/scripts/utils/paths.ts b/codemods/debarrel/scripts/utils/paths.ts index f9d3486..23d2c6a 100644 --- a/codemods/debarrel/scripts/utils/paths.ts +++ b/codemods/debarrel/scripts/utils/paths.ts @@ -10,6 +10,23 @@ export function isLocalRelativePath(source: string): boolean { ); } +/** + * Relative path from a directory to a file, normalized to POSIX separators. + * Uses `path.relative` (available in the JSSG runtime, though undocumented). + */ +export function relativePathFromDir(fromDir: string, toFile: string): string { + return path.relative(fromDir, toFile).replace(/\\/g, "/"); +} + +export function normalizeAbsolutePath( + filename: string, + workspaceRoot: string, +): string { + return path.isAbsolute(filename) + ? path.resolve(filename) + : path.resolve(workspaceRoot, filename); +} + export function joinImportPaths( barrelImportPath: string, sourceFromBarrel: string, @@ -51,7 +68,7 @@ export function joinImportPaths( } export function isBarrelFile(filename: string): boolean { - return /^index\.(ts|tsx|js|jsx)$/.test(path.basename(filename)); + return /^index(\.barrel\.bak)?\.(ts|tsx|js|jsx)$/.test(path.basename(filename)); } export function isNextPagesApiRoute(filename: string): boolean { @@ -71,6 +88,28 @@ const MODULE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"] as const; * * Returns null when the import path isn't relative or no candidate exists. */ +function resolveFileCandidates(resolvedBase: string): string | null { + for (const ext of MODULE_EXTENSIONS) { + const candidate = resolvedBase + ext; + if (fileExists(candidate)) return candidate; + } + for (const ext of MODULE_EXTENSIONS) { + const candidate = path.join(resolvedBase, `index${ext}`); + if (fileExists(candidate)) return candidate; + } + // During a single migration pass, earlier files may have already renamed a + // barrel to index.barrel.bak.* — still resolve it for later consumers. + for (const ext of MODULE_EXTENSIONS) { + const candidate = resolvedBase + `.barrel.bak${ext}`; + if (fileExists(candidate)) return candidate; + } + for (const ext of MODULE_EXTENSIONS) { + const candidate = path.join(resolvedBase, `index.barrel.bak${ext}`); + if (fileExists(candidate)) return candidate; + } + return null; +} + export function resolveImportPath( importerFilename: string, importPath: string, @@ -78,23 +117,284 @@ export function resolveImportPath( if (!isLocalRelativePath(importPath)) return null; const importerDir = path.dirname(importerFilename); const resolved = path.resolve(importerDir, importPath); - for (const ext of MODULE_EXTENSIONS) { - const candidate = resolved + ext; + return resolveFileCandidates(resolved); +} + +interface TsconfigPaths { + baseUrl: string; + paths: Record; +} + +export function findNearestTsconfig(filename: string): string | null { + let dir = path.dirname(path.resolve(filename)); + const root = path.parse(dir).root || "/"; + while (true) { + const candidate = path.join(dir, "tsconfig.json"); if (fileExists(candidate)) return candidate; + if (dir === root) return null; + dir = path.dirname(dir); } - for (const ext of MODULE_EXTENSIONS) { - const candidate = path.join(resolved, `index${ext}`); - if (fileExists(candidate)) return candidate; +} + +/** Strip line and block comments so JSONC tsconfig files parse. */ +function stripJsonComments(text: string): string { + let result = ""; + let i = 0; + while (i < text.length) { + const ch = text[i]!; + if (ch === '"') { + result += ch; + i++; + while (i < text.length) { + const inner = text[i]!; + result += inner; + if (inner === "\\") { + i++; + if (i < text.length) result += text[i]!; + } else if (inner === '"') { + break; + } + i++; + } + i++; + continue; + } + if (text.startsWith("//", i)) { + const newline = text.indexOf("\n", i); + if (newline === -1) break; + result += "\n"; + i = newline + 1; + continue; + } + if (text.startsWith("/*", i)) { + const end = text.indexOf("*/", i + 2); + i = end === -1 ? text.length : end + 2; + continue; + } + result += ch; + i++; + } + return result; +} + +function stripTrailingCommas(text: string): string { + return text.replace(/,(\s*[}\]])/g, "$1"); +} + +function readTsconfigJson(filePath: string): unknown | null { + try { + const raw = fs.readFileSync(filePath, "utf8"); + const stripped = stripTrailingCommas(stripJsonComments(raw)); + return JSON.parse(stripped); + } catch { + return null; + } +} + +function loadTsconfigPaths(tsconfigPath: string): TsconfigPaths | null { + const parsed = readTsconfigJson(tsconfigPath); + if (!parsed || typeof parsed !== "object") return null; + const compilerOptions = (parsed as { compilerOptions?: unknown }) + .compilerOptions; + if (!compilerOptions || typeof compilerOptions !== "object") return null; + const opts = compilerOptions as { baseUrl?: unknown; paths?: unknown }; + const baseUrl = + typeof opts.baseUrl === "string" ? opts.baseUrl : "."; + const paths = opts.paths; + if (!paths || typeof paths !== "object") return null; + const pathsRecord: Record = {}; + for (const [key, value] of Object.entries(paths)) { + if (typeof key === "string" && Array.isArray(value)) { + pathsRecord[key] = value.filter( + (entry): entry is string => typeof entry === "string", + ); + } + } + return { + baseUrl: path.resolve(path.dirname(tsconfigPath), baseUrl), + paths: pathsRecord, + }; +} + +function matchTsconfigPath( + importPath: string, + pattern: string, + targets: string[], +): string | null { + if (pattern.endsWith("/*")) { + const prefix = pattern.slice(0, -2); + if (!importPath.startsWith(`${prefix}/`)) return null; + const subst = importPath.slice(prefix.length + 1); + for (const target of targets) { + if (target.endsWith("/*")) { + return `${target.slice(0, -2)}/${subst}`; + } + } + return null; + } + if (pattern === importPath) { + return targets[0] ?? null; + } + return null; +} + +/** + * Resolve a tsconfig path alias (e.g. `myapp/widgets`) to the absolute file + * it points at on disk, or null when no mapping matches. + */ +export function resolveAliasImportPath( + importerFilename: string, + importPath: string, +): string | null { + if (isLocalRelativePath(importPath)) return null; + + const tsconfigPath = findNearestTsconfig(importerFilename); + if (!tsconfigPath) return null; + const tsconfig = loadTsconfigPaths(tsconfigPath); + if (!tsconfig) return null; + + for (const [pattern, targets] of Object.entries(tsconfig.paths)) { + const mapped = matchTsconfigPath(importPath, pattern, targets); + if (!mapped) continue; + const resolvedBase = path.isAbsolute(mapped) + ? mapped + : path.resolve(tsconfig.baseUrl, mapped); + const candidate = resolveFileCandidates(resolvedBase); + if (candidate) return candidate; } return null; } +/** + * Resolve either a relative import or a tsconfig path alias to an absolute + * module file path. + */ +export function resolveModuleImportPath( + importerFilename: string, + importPath: string, +): string | null { + return ( + resolveImportPath(importerFilename, importPath) ?? + resolveAliasImportPath(importerFilename, importPath) + ); +} + export function isInsideNodeModules(filename: string): boolean { return ( filename.includes("/node_modules/") || filename.includes("\\node_modules\\") ); } +/** Project root for scanning sibling source files (tsconfig dir, else package dir). */ +export function findWorkspaceSourceRoot(filename: string): string { + const absolute = path.resolve(filename); + const tsconfigPath = findNearestTsconfig(absolute); + if (tsconfigPath) return path.dirname(path.resolve(tsconfigPath)); + const packageJsonPath = findNearestPackageJson(absolute); + if (packageJsonPath) return path.dirname(path.resolve(packageJsonPath)); + return path.dirname(absolute); +} + +/** + * Tsconfig path aliases that resolve to `barrelFile` (e.g. `sentry/stories` for + * `static/app/stories/index.tsx` when `sentry/*` maps to `./static/app/*`). + */ +export function getAliasImportPathsForBarrel(barrelFile: string): string[] { + const workspaceRoot = findWorkspaceSourceRoot(barrelFile); + const absoluteBarrel = normalizeAbsolutePath(barrelFile, workspaceRoot); + const barrelDir = path.resolve(path.dirname(absoluteBarrel)); + const tsconfigPath = findNearestTsconfig(absoluteBarrel); + if (!tsconfigPath) return []; + + const tsconfig = loadTsconfigPaths(tsconfigPath); + if (!tsconfig) return []; + + const aliases: string[] = []; + for (const [pattern, targets] of Object.entries(tsconfig.paths)) { + if (!pattern.endsWith("/*")) continue; + const prefix = pattern.slice(0, -2); + for (const target of targets) { + if (!target.endsWith("/*")) continue; + const targetPrefix = path.resolve( + tsconfig.baseUrl, + target.slice(0, -2), + ); + if (barrelDir === targetPrefix) { + aliases.push(prefix); + continue; + } + if (!barrelDir.startsWith(`${targetPrefix}${path.sep}`)) continue; + const subst = path.relative(targetPrefix, barrelDir).replace(/\\/g, "/"); + if (!subst || subst.includes("..")) continue; + aliases.push(`${prefix}/${subst}`); + } + } + return aliases; +} + +const SOURCE_FILE_PATTERN = /\.(ts|tsx|js|jsx|mjs|cjs)$/; +const MDX_FILE_PATTERN = /\.mdx$/; +const NAMESPACE_IMPORT_RE = + /import\s+\*\s+as\s+[\w$]+\s+from\s+['"]([^'"]+)['"]/g; + +/** Recursively list source files under `rootDir`, skipping node_modules. */ +export function walkProjectSourceFiles( + rootDir: string, + files: string[] = [], +): string[] { + const absoluteRoot = path.resolve(rootDir); + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(absoluteRoot, { withFileTypes: true }); + } catch { + return files; + } + for (const entry of entries) { + if (entry.name === "node_modules" || entry.name.startsWith(".")) continue; + const fullPath = path.resolve(absoluteRoot, entry.name); + if (entry.isDirectory()) { + walkProjectSourceFiles(fullPath, files); + } else if ( + SOURCE_FILE_PATTERN.test(entry.name) || + MDX_FILE_PATTERN.test(entry.name) + ) { + files.push(fullPath); + } + } + return files; +} + +const projectSourceFilesCache = new Map(); + +/** Cached wrapper around {@link walkProjectSourceFiles} for a codemod run. */ +export function getProjectSourceFiles(rootDir: string): string[] { + const absoluteRoot = path.resolve(rootDir); + const cached = projectSourceFilesCache.get(absoluteRoot); + if (cached) return cached; + const files = walkProjectSourceFiles(absoluteRoot); + projectSourceFilesCache.set(absoluteRoot, files); + return files; +} + +/** True when an MDX file namespace-imports one of `importPaths`. */ +export function fileHasMdxNamespaceImportFrom( + filePath: string, + importPaths: Set, +): boolean { + if (!MDX_FILE_PATTERN.test(filePath)) return false; + let source: string; + try { + source = fs.readFileSync(filePath, "utf8"); + } catch { + return false; + } + for (const match of source.matchAll(NAMESPACE_IMPORT_RE)) { + const importPath = match[1]; + if (importPath && importPaths.has(importPath)) return true; + } + return false; +} + function fileExists(filePath: string): boolean { try { fs.accessSync(filePath); @@ -166,9 +466,7 @@ export function isPackageEntrypoint(filename: string): boolean { if (!parsed || typeof parsed !== "object") return false; const packageDir = path.dirname(packageJsonPath); - const relativeFilename = path - .relative(packageDir, filename) - .replace(/\\/g, "/"); + const relativeFilename = relativePathFromDir(packageDir, filename); if (!relativeFilename || relativeFilename.startsWith("../")) return false; const manifest = parsed as { diff --git a/codemods/debarrel/scripts/utils/specifiers.ts b/codemods/debarrel/scripts/utils/specifiers.ts index 5ea1959..08f5db7 100644 --- a/codemods/debarrel/scripts/utils/specifiers.ts +++ b/codemods/debarrel/scripts/utils/specifiers.ts @@ -8,10 +8,11 @@ import { isInsideNodeModules, isLocalRelativePath, joinImportPaths, - resolveImportPath, + relativePathFromDir, + resolveModuleImportPath, } from "./paths.ts"; import { parseBarrelExport } from "./barrel.ts"; -import { findSymbolViaExportStar } from "./exportStar.ts"; +import { findSymbolViaBarrelReexports, findSymbolViaExportStar } from "./exportStar.ts"; function getImportPackageName(importPath: string): string | null { if (importPath.startsWith("@")) { @@ -23,12 +24,25 @@ function getImportPackageName(importPath: string): string | null { return packageName || null; } +/** + * True when `importPath` targets a package root (e.g. `myapp`, `@acme/ui`), + * as opposed to a subpath that may be a tsconfig/webpack alias + * (e.g. `myapp/widgets`, `@acme/ui/internal`). + */ +function isPackageRootImport(importPath: string): boolean { + if (importPath.startsWith("@")) { + return importPath.split("/").length === 2; + } + return !importPath.includes("/"); +} + export interface SpecRewrite { consumerName: string; newImportPath: string; localName: string; importType: "default" | "named" | "namespace"; resolvedFilePath: string; + typeOnly?: boolean; } /** @@ -36,24 +50,28 @@ export interface SpecRewrite { * a direct import path bypassing the barrel. */ export function resolveSpecifier( - localBinding: SgNode, + importedName: string, + consumerName: string, importPath: string, def: { kind: string; root: SgRoot; node: SgNode }, importerFilename: string, importerRelativeFilename: string, + isDefaultImport = false, ): SpecRewrite | null { // When the semantic analyzer fully resolves the binding to a different // file we go through the `external` branches below. When it punts (most // commonly because the symbol flows through a bare `export *` re-export // that the analyzer can't enumerate statically), `def.kind` is "import" // and `def.root.filename()` is the importer itself — skip the - // external-only checks and head straight to the manual export-star walker. + // external-only checks and head straight to the manual barrel walkers. if (def.kind !== "external") { - return resolveViaExportStarWalk( - localBinding, + return resolveViaBarrelWalk( + importedName, + consumerName, importPath, importerFilename, importerRelativeFilename, + isDefaultImport, ); } @@ -62,14 +80,18 @@ export function resolveSpecifier( // package.json "exports" that would break if we change the import subpath. if (isInsideNodeModules(def.root.filename())) return null; - // For non-relative imports, only preserve the package boundary when the - // resolved file belongs to the same named package as the import specifier. - // This keeps tsconfig aliases like `~/foo` or `@acme/pkg/*` rewriteable - // even when the surrounding repo has an unrelated package.json. + // For non-relative imports, only preserve the package boundary for root + // package imports (e.g. `myapp`, `@acme/ui`). Subpath imports like + // `myapp/widgets` are often tsconfig/webpack aliases that share the + // package.json name and must still be debarreled. if (!isLocalRelativePath(importPath)) { const packageName = getPackageName(def.root.filename()); const importPackage = getImportPackageName(importPath); - if (packageName && importPackage === packageName) { + if ( + packageName && + importPackage === packageName && + isPackageRootImport(importPath) + ) { return null; } } @@ -77,10 +99,12 @@ export function resolveSpecifier( if (isBarrelFile(def.root.filename())) { // Definition landed on an export_statement in the barrel if (def.node.is("export_statement")) { - const info = parseBarrelExport(def.node, localBinding.text()); + const info = parseBarrelExport(def.node, importedName, { + isDefaultImport, + }); if (!info) return null; return { - consumerName: localBinding.text(), + consumerName, newImportPath: joinImportPaths(importPath, info.sourceFromBarrel), localName: info.localName, importType: info.importType, @@ -96,13 +120,13 @@ export function resolveSpecifier( if (!impSource) return null; const impPath = getStringContent(impSource); if (!impPath || !isLocalRelativePath(impPath)) return null; - let originalName = localBinding.text(); + let originalName = importedName; if (def.node.is("import_specifier")) { const idents = def.node.findAll({ rule: { kind: "identifier" } }); - if (idents.length >= 1) originalName = idents[0]?.text() ?? ""; + if (idents.length >= 1) originalName = idents[0]?.text() ?? importedName; } return { - consumerName: localBinding.text(), + consumerName, newImportPath: joinImportPaths(importPath, impPath), localName: originalName, importType: "named", @@ -110,41 +134,105 @@ export function resolveSpecifier( }; } - // Semantic analyzer resolved all the way through to the actual source file - // (not a barrel). If the resolved file is already the direct target of - // the import (e.g. @acme/api/models/utils/ratelimiter → ratelimiter.ts), - // the import is already correct — don't rewrite. + // Semantic analyzer resolved through the barrel to the actual source file. + // The import may still point at the barrel alias (e.g. `myapp/widgets`). + const resolvedFilename = def.root.filename(); + const barrelFile = resolveModuleImportPath(importerFilename, importPath); + if ( + barrelFile && + isBarrelFile(barrelFile) && + resolvedFilename !== barrelFile + ) { + const reexport = findSymbolViaBarrelReexports( + barrelFile, + importedName, + isDefaultImport, + ); + const localName = reexport?.localName ?? importedName; + const importType = + reexport?.importType ?? (isDefaultImport ? "default" : "named"); + + return buildRewriteFromTarget( + consumerName, + importPath, + barrelFile, + resolvedFilename, + importerFilename, + importerRelativeFilename, + localName, + importType, + ); + } + return null; } /** - * Walk the barrel pointed to by `importPath` and look for which file in its - * `export * from "./y"` chain declares `localBinding`'s name. Used when the - * semantic analyzer can't tell us — bare `export *` re-exports don't carry - * named bindings the analyzer can chase. + * Walk the barrel pointed to by `importPath` when the semantic analyzer + * can't resolve the binding. Tries explicit re-exports first, then bare + * `export *` chains. */ -function resolveViaExportStarWalk( - localBinding: SgNode, +function resolveViaBarrelWalk( + importedName: string, + consumerName: string, importPath: string, importerFilename: string, importerRelativeFilename: string, + isDefaultImport: boolean, ): SpecRewrite | null { - if (!isLocalRelativePath(importPath)) return null; - const barrelFile = resolveImportPath(importerFilename, importPath); + const barrelFile = resolveModuleImportPath(importerFilename, importPath); if (!barrelFile || !isBarrelFile(barrelFile)) return null; - const targetFile = findSymbolViaExportStar(barrelFile, localBinding.text()); + const reexport = findSymbolViaBarrelReexports( + barrelFile, + importedName, + isDefaultImport, + ); + if (reexport) { + return buildRewriteFromTarget( + consumerName, + importPath, + barrelFile, + reexport.targetFile, + importerFilename, + importerRelativeFilename, + reexport.localName, + reexport.importType, + ); + } + + const targetFile = findSymbolViaExportStar(barrelFile, importedName); if (!targetFile || targetFile === barrelFile) return null; + return buildRewriteFromTarget( + consumerName, + importPath, + barrelFile, + targetFile, + importerFilename, + importerRelativeFilename, + importedName, + "named", + ); +} + +function buildRewriteFromTarget( + consumerName: string, + importPath: string, + barrelFile: string, + targetFile: string, + importerFilename: string, + importerRelativeFilename: string, + localName: string, + importType: "default" | "named", +): SpecRewrite { const barrelDir = path.dirname(barrelFile); - let rel = path.relative(barrelDir, targetFile); + let rel = relativePathFromDir(barrelDir, targetFile); const ext = path.extname(rel); if (ext) rel = rel.slice(0, -ext.length); rel = rel.replace(/\/index$/, "") || "."; const fromBarrel = rel.startsWith(".") ? rel : `./${rel}`; - // Mirror the barrel's workspace-relative path for the metric, so the - // `filePath` cardinality matches the named-reexport branches above. const barrelRelativeFilename = toWorkspaceRelative( importerFilename, importerRelativeFilename, @@ -152,10 +240,10 @@ function resolveViaExportStarWalk( ); return { - consumerName: localBinding.text(), + consumerName, newImportPath: joinImportPaths(importPath, fromBarrel), - localName: localBinding.text(), - importType: "named", + localName, + importType, resolvedFilePath: barrelRelativeFilename, }; } @@ -176,5 +264,5 @@ function toWorkspaceRelative( 0, importerFilename.length - importerRelativeFilename.length, ); - return path.relative(workspaceRoot, absolutePath).replace(/\\/g, "/"); + return relativePathFromDir(workspaceRoot, absolutePath).replace(/\\/g, "/"); } diff --git a/codemods/debarrel/tests/alias-relative-folder-import/expected/src/input/inputGroup.ts b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/input/inputGroup.ts new file mode 100644 index 0000000..85ec73e --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/input/inputGroup.ts @@ -0,0 +1,5 @@ +import type { TextAreaProps } from "../textarea/textarea"; +import { TextArea as CoreTextArea } from "../textarea/textarea"; + +const rows: TextAreaProps = { rows: 3 }; +console.log(CoreTextArea(rows)); diff --git a/codemods/debarrel/tests/alias-relative-folder-import/expected/src/input/metrics.json b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/input/metrics.json new file mode 100644 index 0000000..e9c69a3 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/input/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/textarea/index.ts", + "importer": "src/input/inputGroup.ts" + }, + "count": 2 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/alias-relative-folder-import/expected/src/textarea/index.barrel.bak.ts b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/textarea/index.barrel.bak.ts new file mode 100644 index 0000000..8c13da2 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/textarea/index.barrel.bak.ts @@ -0,0 +1 @@ +export { TextArea, type TextAreaProps } from "./textarea"; diff --git a/codemods/debarrel/tests/alias-relative-folder-import/expected/src/textarea/textarea.ts b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/textarea/textarea.ts new file mode 100644 index 0000000..44bfb52 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/expected/src/textarea/textarea.ts @@ -0,0 +1,5 @@ +export type TextAreaProps = { rows: number }; + +export function TextArea(props: TextAreaProps) { + return props.rows; +} diff --git a/codemods/debarrel/tests/alias-relative-folder-import/expected/tsconfig.json b/codemods/debarrel/tests/alias-relative-folder-import/expected/tsconfig.json new file mode 100644 index 0000000..9efb41a --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/expected/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": {} + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/alias-relative-folder-import/input/src/input/inputGroup.ts b/codemods/debarrel/tests/alias-relative-folder-import/input/src/input/inputGroup.ts new file mode 100644 index 0000000..da33ca1 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/input/src/input/inputGroup.ts @@ -0,0 +1,5 @@ +import type { TextAreaProps } from "../textarea"; +import { TextArea as CoreTextArea } from "../textarea"; + +const rows: TextAreaProps = { rows: 3 }; +console.log(CoreTextArea(rows)); diff --git a/codemods/debarrel/tests/alias-relative-folder-import/input/src/input/metrics.json b/codemods/debarrel/tests/alias-relative-folder-import/input/src/input/metrics.json new file mode 100644 index 0000000..e9c69a3 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/input/src/input/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/textarea/index.ts", + "importer": "src/input/inputGroup.ts" + }, + "count": 2 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/alias-relative-folder-import/input/src/textarea/index.ts b/codemods/debarrel/tests/alias-relative-folder-import/input/src/textarea/index.ts new file mode 100644 index 0000000..8c13da2 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/input/src/textarea/index.ts @@ -0,0 +1 @@ +export { TextArea, type TextAreaProps } from "./textarea"; diff --git a/codemods/debarrel/tests/alias-relative-folder-import/input/src/textarea/textarea.ts b/codemods/debarrel/tests/alias-relative-folder-import/input/src/textarea/textarea.ts new file mode 100644 index 0000000..44bfb52 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/input/src/textarea/textarea.ts @@ -0,0 +1,5 @@ +export type TextAreaProps = { rows: number }; + +export function TextArea(props: TextAreaProps) { + return props.rows; +} diff --git a/codemods/debarrel/tests/alias-relative-folder-import/input/tsconfig.json b/codemods/debarrel/tests/alias-relative-folder-import/input/tsconfig.json new file mode 100644 index 0000000..9efb41a --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/input/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": {} + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/alias-relative-folder-import/metrics.json b/codemods/debarrel/tests/alias-relative-folder-import/metrics.json new file mode 100644 index 0000000..e9c69a3 --- /dev/null +++ b/codemods/debarrel/tests/alias-relative-folder-import/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/textarea/index.ts", + "importer": "src/input/inputGroup.ts" + }, + "count": 2 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/App.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/App.ts new file mode 100644 index 0000000..f96248e --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/App.ts @@ -0,0 +1,4 @@ +import { Tag as TagBadge } from "@app/scraps/badge/tag"; +import { Image as ImageBase } from "@app/scraps/image/image"; + +console.log(TagBadge(), ImageBase()); diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/badge/index.barrel.bak.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/badge/index.barrel.bak.ts new file mode 100644 index 0000000..c82af3c --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/badge/index.barrel.bak.ts @@ -0,0 +1 @@ +export { Tag } from "./tag"; diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/badge/tag.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/badge/tag.ts new file mode 100644 index 0000000..1d72013 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/badge/tag.ts @@ -0,0 +1,3 @@ +export function Tag() { + return "tag"; +} diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/image/image.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/image/image.ts new file mode 100644 index 0000000..f4ef3fe --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/image/image.ts @@ -0,0 +1,3 @@ +export function Image() { + return "image"; +} diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/image/index.barrel.bak.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/image/index.barrel.bak.ts new file mode 100644 index 0000000..e38e488 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/core/image/index.barrel.bak.ts @@ -0,0 +1 @@ +export { Image } from "./image"; diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/metrics.json b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/metrics.json new file mode 100644 index 0000000..f70e808 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/src/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/badge/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/core/image/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/expected/tsconfig.json b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/tsconfig.json new file mode 100644 index 0000000..c47a40a --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@app/scraps/*": ["./src/core/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/App.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/App.ts new file mode 100644 index 0000000..b28bf72 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/App.ts @@ -0,0 +1,4 @@ +import { Tag as TagBadge } from "@app/scraps/badge"; +import { Image as ImageBase } from "@app/scraps/image"; + +console.log(TagBadge(), ImageBase()); diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/badge/index.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/badge/index.ts new file mode 100644 index 0000000..c82af3c --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/badge/index.ts @@ -0,0 +1 @@ +export { Tag } from "./tag"; diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/badge/tag.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/badge/tag.ts new file mode 100644 index 0000000..1d72013 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/badge/tag.ts @@ -0,0 +1,3 @@ +export function Tag() { + return "tag"; +} diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/image/image.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/image/image.ts new file mode 100644 index 0000000..f4ef3fe --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/image/image.ts @@ -0,0 +1,3 @@ +export function Image() { + return "image"; +} diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/image/index.ts b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/image/index.ts new file mode 100644 index 0000000..e38e488 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/core/image/index.ts @@ -0,0 +1 @@ +export { Image } from "./image"; diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/metrics.json b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/metrics.json new file mode 100644 index 0000000..f70e808 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/input/src/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/badge/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/core/image/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/input/tsconfig.json b/codemods/debarrel/tests/alias-wildcard-folder-import/input/tsconfig.json new file mode 100644 index 0000000..c47a40a --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@app/scraps/*": ["./src/core/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/alias-wildcard-folder-import/metrics.json b/codemods/debarrel/tests/alias-wildcard-folder-import/metrics.json new file mode 100644 index 0000000..f70e808 --- /dev/null +++ b/codemods/debarrel/tests/alias-wildcard-folder-import/metrics.json @@ -0,0 +1,18 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/badge/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + }, + { + "cardinality": { + "filePath": "src/core/image/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/barrel-processing-order/expected/src/a-stories/index.barrel.bak.ts b/codemods/debarrel/tests/barrel-processing-order/expected/src/a-stories/index.barrel.bak.ts new file mode 100644 index 0000000..8f533b6 --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/expected/src/a-stories/index.barrel.bak.ts @@ -0,0 +1 @@ +export { story } from "./storybook"; diff --git a/codemods/debarrel/tests/barrel-processing-order/expected/src/a-stories/storybook.ts b/codemods/debarrel/tests/barrel-processing-order/expected/src/a-stories/storybook.ts new file mode 100644 index 0000000..033c8ad --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/expected/src/a-stories/storybook.ts @@ -0,0 +1,3 @@ +export function story() { + return "story"; +} diff --git a/codemods/debarrel/tests/barrel-processing-order/expected/src/metrics.json b/codemods/debarrel/tests/barrel-processing-order/expected/src/metrics.json new file mode 100644 index 0000000..437ced3 --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/a-stories/index.ts", + "importer": "src/z-consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/barrel-processing-order/expected/src/z-consumer.ts b/codemods/debarrel/tests/barrel-processing-order/expected/src/z-consumer.ts new file mode 100644 index 0000000..ec4977d --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/expected/src/z-consumer.ts @@ -0,0 +1,3 @@ +import { story } from "myapp/a-stories/storybook"; + +console.log(story()); diff --git a/codemods/debarrel/tests/barrel-processing-order/expected/tsconfig.json b/codemods/debarrel/tests/barrel-processing-order/expected/tsconfig.json new file mode 100644 index 0000000..3b801c6 --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/barrel-processing-order/input/src/a-stories/index.ts b/codemods/debarrel/tests/barrel-processing-order/input/src/a-stories/index.ts new file mode 100644 index 0000000..8f533b6 --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/input/src/a-stories/index.ts @@ -0,0 +1 @@ +export { story } from "./storybook"; diff --git a/codemods/debarrel/tests/barrel-processing-order/input/src/a-stories/storybook.ts b/codemods/debarrel/tests/barrel-processing-order/input/src/a-stories/storybook.ts new file mode 100644 index 0000000..033c8ad --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/input/src/a-stories/storybook.ts @@ -0,0 +1,3 @@ +export function story() { + return "story"; +} diff --git a/codemods/debarrel/tests/barrel-processing-order/input/src/metrics.json b/codemods/debarrel/tests/barrel-processing-order/input/src/metrics.json new file mode 100644 index 0000000..437ced3 --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/a-stories/index.ts", + "importer": "src/z-consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/barrel-processing-order/input/src/z-consumer.ts b/codemods/debarrel/tests/barrel-processing-order/input/src/z-consumer.ts new file mode 100644 index 0000000..8dbba4e --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/input/src/z-consumer.ts @@ -0,0 +1,3 @@ +import { story } from "myapp/a-stories"; + +console.log(story()); diff --git a/codemods/debarrel/tests/barrel-processing-order/input/tsconfig.json b/codemods/debarrel/tests/barrel-processing-order/input/tsconfig.json new file mode 100644 index 0000000..3b801c6 --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/barrel-processing-order/metrics.json b/codemods/debarrel/tests/barrel-processing-order/metrics.json new file mode 100644 index 0000000..437ced3 --- /dev/null +++ b/codemods/debarrel/tests/barrel-processing-order/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/a-stories/index.ts", + "importer": "src/z-consumer.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/default-reexport-as-default/expected/package.json b/codemods/debarrel/tests/default-reexport-as-default/expected/package.json new file mode 100644 index 0000000..a0bc261 --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/expected/package.json @@ -0,0 +1,4 @@ +{ + "name": "default-reexport-as-default-fixture", + "private": true +} diff --git a/codemods/debarrel/tests/default-reexport-as-default/expected/src/App.ts b/codemods/debarrel/tests/default-reexport-as-default/expected/src/App.ts new file mode 100644 index 0000000..0ccef30 --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/expected/src/App.ts @@ -0,0 +1,3 @@ +import { InteractionStateLayer } from "@acme/scraps/interactionStateLayer/interactionStateLayer"; + +console.log(InteractionStateLayer); diff --git a/codemods/debarrel/tests/default-reexport-as-default/expected/src/core/interactionStateLayer/index.barrel.bak.ts b/codemods/debarrel/tests/default-reexport-as-default/expected/src/core/interactionStateLayer/index.barrel.bak.ts new file mode 100644 index 0000000..e19c30f --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/expected/src/core/interactionStateLayer/index.barrel.bak.ts @@ -0,0 +1 @@ +export { InteractionStateLayer as default } from "./interactionStateLayer"; diff --git a/codemods/debarrel/tests/default-reexport-as-default/expected/src/core/interactionStateLayer/interactionStateLayer.ts b/codemods/debarrel/tests/default-reexport-as-default/expected/src/core/interactionStateLayer/interactionStateLayer.ts new file mode 100644 index 0000000..35cff4c --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/expected/src/core/interactionStateLayer/interactionStateLayer.ts @@ -0,0 +1 @@ +export const InteractionStateLayer = "layer"; diff --git a/codemods/debarrel/tests/default-reexport-as-default/expected/src/metrics.json b/codemods/debarrel/tests/default-reexport-as-default/expected/src/metrics.json new file mode 100644 index 0000000..21fabdc --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/interactionStateLayer/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/default-reexport-as-default/expected/tsconfig.json b/codemods/debarrel/tests/default-reexport-as-default/expected/tsconfig.json new file mode 100644 index 0000000..327a5d2 --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@acme/scraps/*": ["./src/core/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/default-reexport-as-default/input/package.json b/codemods/debarrel/tests/default-reexport-as-default/input/package.json new file mode 100644 index 0000000..a0bc261 --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/input/package.json @@ -0,0 +1,4 @@ +{ + "name": "default-reexport-as-default-fixture", + "private": true +} diff --git a/codemods/debarrel/tests/default-reexport-as-default/input/src/App.ts b/codemods/debarrel/tests/default-reexport-as-default/input/src/App.ts new file mode 100644 index 0000000..f08982c --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/input/src/App.ts @@ -0,0 +1,3 @@ +import InteractionStateLayer from "@acme/scraps/interactionStateLayer"; + +console.log(InteractionStateLayer); diff --git a/codemods/debarrel/tests/default-reexport-as-default/input/src/core/interactionStateLayer/index.ts b/codemods/debarrel/tests/default-reexport-as-default/input/src/core/interactionStateLayer/index.ts new file mode 100644 index 0000000..e19c30f --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/input/src/core/interactionStateLayer/index.ts @@ -0,0 +1 @@ +export { InteractionStateLayer as default } from "./interactionStateLayer"; diff --git a/codemods/debarrel/tests/default-reexport-as-default/input/src/core/interactionStateLayer/interactionStateLayer.ts b/codemods/debarrel/tests/default-reexport-as-default/input/src/core/interactionStateLayer/interactionStateLayer.ts new file mode 100644 index 0000000..35cff4c --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/input/src/core/interactionStateLayer/interactionStateLayer.ts @@ -0,0 +1 @@ +export const InteractionStateLayer = "layer"; diff --git a/codemods/debarrel/tests/default-reexport-as-default/input/src/metrics.json b/codemods/debarrel/tests/default-reexport-as-default/input/src/metrics.json new file mode 100644 index 0000000..21fabdc --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/interactionStateLayer/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/default-reexport-as-default/input/tsconfig.json b/codemods/debarrel/tests/default-reexport-as-default/input/tsconfig.json new file mode 100644 index 0000000..327a5d2 --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@acme/scraps/*": ["./src/core/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/default-reexport-as-default/metrics.json b/codemods/debarrel/tests/default-reexport-as-default/metrics.json new file mode 100644 index 0000000..21fabdc --- /dev/null +++ b/codemods/debarrel/tests/default-reexport-as-default/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/interactionStateLayer/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/full-type-only-import/expected/src/App.ts b/codemods/debarrel/tests/full-type-only-import/expected/src/App.ts new file mode 100644 index 0000000..0eab7d8 --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/expected/src/App.ts @@ -0,0 +1,4 @@ +import type { ButtonProps } from "./components/button"; + +const props: ButtonProps = { label: "ok" }; +console.log(props.label); diff --git a/codemods/debarrel/tests/full-type-only-import/expected/src/components/button.ts b/codemods/debarrel/tests/full-type-only-import/expected/src/components/button.ts new file mode 100644 index 0000000..4776377 --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/expected/src/components/button.ts @@ -0,0 +1 @@ +export type ButtonProps = { label: string }; diff --git a/codemods/debarrel/tests/full-type-only-import/expected/src/components/index.barrel.bak.ts b/codemods/debarrel/tests/full-type-only-import/expected/src/components/index.barrel.bak.ts new file mode 100644 index 0000000..33323a0 --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/expected/src/components/index.barrel.bak.ts @@ -0,0 +1 @@ +export type { ButtonProps } from "./button"; diff --git a/codemods/debarrel/tests/full-type-only-import/expected/src/metrics.json b/codemods/debarrel/tests/full-type-only-import/expected/src/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/full-type-only-import/expected/tsconfig.json b/codemods/debarrel/tests/full-type-only-import/expected/tsconfig.json new file mode 100644 index 0000000..6e006aa --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/expected/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": "." + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/full-type-only-import/input/src/App.ts b/codemods/debarrel/tests/full-type-only-import/input/src/App.ts new file mode 100644 index 0000000..33bea86 --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/input/src/App.ts @@ -0,0 +1,4 @@ +import type { ButtonProps } from "./components"; + +const props: ButtonProps = { label: "ok" }; +console.log(props.label); diff --git a/codemods/debarrel/tests/full-type-only-import/input/src/components/button.ts b/codemods/debarrel/tests/full-type-only-import/input/src/components/button.ts new file mode 100644 index 0000000..4776377 --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/input/src/components/button.ts @@ -0,0 +1 @@ +export type ButtonProps = { label: string }; diff --git a/codemods/debarrel/tests/full-type-only-import/input/src/components/index.ts b/codemods/debarrel/tests/full-type-only-import/input/src/components/index.ts new file mode 100644 index 0000000..33323a0 --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/input/src/components/index.ts @@ -0,0 +1 @@ +export type { ButtonProps } from "./button"; diff --git a/codemods/debarrel/tests/full-type-only-import/input/src/metrics.json b/codemods/debarrel/tests/full-type-only-import/input/src/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/full-type-only-import/input/tsconfig.json b/codemods/debarrel/tests/full-type-only-import/input/tsconfig.json new file mode 100644 index 0000000..6e006aa --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/input/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": "." + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/full-type-only-import/metrics.json b/codemods/debarrel/tests/full-type-only-import/metrics.json new file mode 100644 index 0000000..544b62d --- /dev/null +++ b/codemods/debarrel/tests/full-type-only-import/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/components/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/inline-type-only-import/expected/src/App.ts b/codemods/debarrel/tests/inline-type-only-import/expected/src/App.ts new file mode 100644 index 0000000..3c1d184 --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/expected/src/App.ts @@ -0,0 +1,4 @@ +import type { Config } from "./lib/config"; + +const props: Config = { debug: true }; +console.log(props.debug); diff --git a/codemods/debarrel/tests/inline-type-only-import/expected/src/lib/config.ts b/codemods/debarrel/tests/inline-type-only-import/expected/src/lib/config.ts new file mode 100644 index 0000000..099aa31 --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/expected/src/lib/config.ts @@ -0,0 +1 @@ +export type Config = { debug: boolean }; diff --git a/codemods/debarrel/tests/inline-type-only-import/expected/src/lib/index.barrel.bak.ts b/codemods/debarrel/tests/inline-type-only-import/expected/src/lib/index.barrel.bak.ts new file mode 100644 index 0000000..46d546d --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/expected/src/lib/index.barrel.bak.ts @@ -0,0 +1 @@ +export { type Config } from "./config"; diff --git a/codemods/debarrel/tests/inline-type-only-import/expected/src/metrics.json b/codemods/debarrel/tests/inline-type-only-import/expected/src/metrics.json new file mode 100644 index 0000000..c12c459 --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/inline-type-only-import/expected/tsconfig.json b/codemods/debarrel/tests/inline-type-only-import/expected/tsconfig.json new file mode 100644 index 0000000..9efb41a --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/expected/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": {} + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/inline-type-only-import/input/src/App.ts b/codemods/debarrel/tests/inline-type-only-import/input/src/App.ts new file mode 100644 index 0000000..7336fea --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/input/src/App.ts @@ -0,0 +1,4 @@ +import { type Config } from "./lib"; + +const props: Config = { debug: true }; +console.log(props.debug); diff --git a/codemods/debarrel/tests/inline-type-only-import/input/src/lib/config.ts b/codemods/debarrel/tests/inline-type-only-import/input/src/lib/config.ts new file mode 100644 index 0000000..099aa31 --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/input/src/lib/config.ts @@ -0,0 +1 @@ +export type Config = { debug: boolean }; diff --git a/codemods/debarrel/tests/inline-type-only-import/input/src/lib/index.ts b/codemods/debarrel/tests/inline-type-only-import/input/src/lib/index.ts new file mode 100644 index 0000000..46d546d --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/input/src/lib/index.ts @@ -0,0 +1 @@ +export { type Config } from "./config"; diff --git a/codemods/debarrel/tests/inline-type-only-import/input/src/metrics.json b/codemods/debarrel/tests/inline-type-only-import/input/src/metrics.json new file mode 100644 index 0000000..c12c459 --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/inline-type-only-import/input/tsconfig.json b/codemods/debarrel/tests/inline-type-only-import/input/tsconfig.json new file mode 100644 index 0000000..9efb41a --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/input/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": {} + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/inline-type-only-import/metrics.json b/codemods/debarrel/tests/inline-type-only-import/metrics.json new file mode 100644 index 0000000..c12c459 --- /dev/null +++ b/codemods/debarrel/tests/inline-type-only-import/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/namespace-barrel-import/expected/src/consumer.ts b/codemods/debarrel/tests/namespace-barrel-import/expected/src/consumer.ts new file mode 100644 index 0000000..ee5ed29 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/expected/src/consumer.ts @@ -0,0 +1,3 @@ +import * as Stories from "myapp/stories"; + +console.log(Stories.story(), Stories.Demo()); diff --git a/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/demo.ts b/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/demo.ts new file mode 100644 index 0000000..caa39d5 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/demo.ts @@ -0,0 +1,3 @@ +export function Demo() { + return "demo"; +} diff --git a/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/index.ts b/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/index.ts new file mode 100644 index 0000000..fe46f36 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/index.ts @@ -0,0 +1,2 @@ +export { story } from "./storybook"; +export { Demo } from "./demo"; diff --git a/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/storybook.ts b/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/storybook.ts new file mode 100644 index 0000000..033c8ad --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/expected/src/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story() { + return "story"; +} diff --git a/codemods/debarrel/tests/namespace-barrel-import/expected/tsconfig.json b/codemods/debarrel/tests/namespace-barrel-import/expected/tsconfig.json new file mode 100644 index 0000000..3b801c6 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/namespace-barrel-import/input/src/consumer.ts b/codemods/debarrel/tests/namespace-barrel-import/input/src/consumer.ts new file mode 100644 index 0000000..ee5ed29 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/input/src/consumer.ts @@ -0,0 +1,3 @@ +import * as Stories from "myapp/stories"; + +console.log(Stories.story(), Stories.Demo()); diff --git a/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/demo.ts b/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/demo.ts new file mode 100644 index 0000000..caa39d5 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/demo.ts @@ -0,0 +1,3 @@ +export function Demo() { + return "demo"; +} diff --git a/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/index.ts b/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/index.ts new file mode 100644 index 0000000..fe46f36 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/index.ts @@ -0,0 +1,2 @@ +export { story } from "./storybook"; +export { Demo } from "./demo"; diff --git a/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/storybook.ts b/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/storybook.ts new file mode 100644 index 0000000..033c8ad --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/input/src/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story() { + return "story"; +} diff --git a/codemods/debarrel/tests/namespace-barrel-import/input/tsconfig.json b/codemods/debarrel/tests/namespace-barrel-import/input/tsconfig.json new file mode 100644 index 0000000..3b801c6 --- /dev/null +++ b/codemods/debarrel/tests/namespace-barrel-import/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/package.json b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/docs/widget.mdx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/docs/widget.mdx new file mode 100644 index 0000000..ae591d0 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/docs/widget.mdx @@ -0,0 +1,3 @@ +import * as Storybook from "sentry/stories"; + + diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons.stories.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons.stories.tsx new file mode 100644 index 0000000..ae8b318 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons.stories.tsx @@ -0,0 +1,3 @@ +import * as Icons from "sentry/icons"; + +console.log(Icons.IconAdd()); diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons/iconAdd.ts b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons/iconAdd.ts new file mode 100644 index 0000000..04f1e1e --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons/iconAdd.ts @@ -0,0 +1,3 @@ +export function IconAdd() { + return "add"; +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons/index.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons/index.tsx new file mode 100644 index 0000000..2f705fd --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/icons/index.tsx @@ -0,0 +1 @@ +export { IconAdd } from "./iconAdd"; diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/demo.ts b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/demo.ts new file mode 100644 index 0000000..caa39d5 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/demo.ts @@ -0,0 +1,3 @@ +export function Demo() { + return "demo"; +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/index.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/index.tsx new file mode 100644 index 0000000..fe46f36 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/index.tsx @@ -0,0 +1,2 @@ +export { story } from "./storybook"; +export { Demo } from "./demo"; diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/storybook.ts b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/storybook.ts new file mode 100644 index 0000000..033c8ad --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story() { + return "story"; +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/z-widget.stories.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/z-widget.stories.tsx new file mode 100644 index 0000000..d841025 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/src/z-widget.stories.tsx @@ -0,0 +1,3 @@ +import * as Storybook from "sentry/stories"; + +console.log(Storybook.story()); diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/tsconfig.json b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/tsconfig.json new file mode 100644 index 0000000..2ed441d --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "sentry/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/package.json b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/docs/widget.mdx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/docs/widget.mdx new file mode 100644 index 0000000..ae591d0 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/docs/widget.mdx @@ -0,0 +1,3 @@ +import * as Storybook from "sentry/stories"; + + diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons.stories.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons.stories.tsx new file mode 100644 index 0000000..ae8b318 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons.stories.tsx @@ -0,0 +1,3 @@ +import * as Icons from "sentry/icons"; + +console.log(Icons.IconAdd()); diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons/iconAdd.ts b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons/iconAdd.ts new file mode 100644 index 0000000..04f1e1e --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons/iconAdd.ts @@ -0,0 +1,3 @@ +export function IconAdd() { + return "add"; +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons/index.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons/index.tsx new file mode 100644 index 0000000..2f705fd --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/icons/index.tsx @@ -0,0 +1 @@ +export { IconAdd } from "./iconAdd"; diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/demo.ts b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/demo.ts new file mode 100644 index 0000000..caa39d5 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/demo.ts @@ -0,0 +1,3 @@ +export function Demo() { + return "demo"; +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/index.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/index.tsx new file mode 100644 index 0000000..fe46f36 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/index.tsx @@ -0,0 +1,2 @@ +export { story } from "./storybook"; +export { Demo } from "./demo"; diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/storybook.ts b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/storybook.ts new file mode 100644 index 0000000..033c8ad --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story() { + return "story"; +} diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/z-widget.stories.tsx b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/z-widget.stories.tsx new file mode 100644 index 0000000..d841025 --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/src/z-widget.stories.tsx @@ -0,0 +1,3 @@ +import * as Storybook from "sentry/stories"; + +console.log(Storybook.story()); diff --git a/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/tsconfig.json b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/tsconfig.json new file mode 100644 index 0000000..2ed441d --- /dev/null +++ b/codemods/debarrel/tests/package-name-alias-namespace-barrel/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "sentry/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/expected/package.json b/codemods/debarrel/tests/package-name-subpath-alias/expected/package.json new file mode 100644 index 0000000..9f6bc67 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/expected/package.json @@ -0,0 +1,3 @@ +{ + "name": "myapp" +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/expected/src/App.ts b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/App.ts new file mode 100644 index 0000000..69461a3 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/App.ts @@ -0,0 +1,3 @@ +import { Widget } from "myapp/widgets/Widget"; + +console.log(Widget()); diff --git a/codemods/debarrel/tests/package-name-subpath-alias/expected/src/metrics.json b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/metrics.json new file mode 100644 index 0000000..144ceda --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/widgets/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/expected/src/widgets/Widget.ts b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/widgets/Widget.ts new file mode 100644 index 0000000..76626e6 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/widgets/Widget.ts @@ -0,0 +1,3 @@ +export function Widget() { + return "widget"; +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/expected/src/widgets/index.barrel.bak.ts b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/widgets/index.barrel.bak.ts new file mode 100644 index 0000000..f3c2f6d --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/expected/src/widgets/index.barrel.bak.ts @@ -0,0 +1 @@ +export { Widget } from "./Widget"; diff --git a/codemods/debarrel/tests/package-name-subpath-alias/expected/tsconfig.json b/codemods/debarrel/tests/package-name-subpath-alias/expected/tsconfig.json new file mode 100644 index 0000000..3b801c6 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/input/package.json b/codemods/debarrel/tests/package-name-subpath-alias/input/package.json new file mode 100644 index 0000000..9f6bc67 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/input/package.json @@ -0,0 +1,3 @@ +{ + "name": "myapp" +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/input/src/App.ts b/codemods/debarrel/tests/package-name-subpath-alias/input/src/App.ts new file mode 100644 index 0000000..69e4a17 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/input/src/App.ts @@ -0,0 +1,3 @@ +import { Widget } from "myapp/widgets"; + +console.log(Widget()); diff --git a/codemods/debarrel/tests/package-name-subpath-alias/input/src/metrics.json b/codemods/debarrel/tests/package-name-subpath-alias/input/src/metrics.json new file mode 100644 index 0000000..8b5e4b6 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/widgets/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/package-name-subpath-alias/input/src/widgets/Widget.ts b/codemods/debarrel/tests/package-name-subpath-alias/input/src/widgets/Widget.ts new file mode 100644 index 0000000..76626e6 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/input/src/widgets/Widget.ts @@ -0,0 +1,3 @@ +export function Widget() { + return "widget"; +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/input/src/widgets/index.ts b/codemods/debarrel/tests/package-name-subpath-alias/input/src/widgets/index.ts new file mode 100644 index 0000000..f3c2f6d --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/input/src/widgets/index.ts @@ -0,0 +1 @@ +export { Widget } from "./Widget"; diff --git a/codemods/debarrel/tests/package-name-subpath-alias/input/tsconfig.json b/codemods/debarrel/tests/package-name-subpath-alias/input/tsconfig.json new file mode 100644 index 0000000..3b801c6 --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/package-name-subpath-alias/metrics.json b/codemods/debarrel/tests/package-name-subpath-alias/metrics.json new file mode 100644 index 0000000..144ceda --- /dev/null +++ b/codemods/debarrel/tests/package-name-subpath-alias/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/widgets/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} diff --git a/codemods/debarrel/tests/partial-with-type-specifiers/expected/src/consumer.ts b/codemods/debarrel/tests/partial-with-type-specifiers/expected/src/consumer.ts index d3a5061..d4872b6 100644 --- a/codemods/debarrel/tests/partial-with-type-specifiers/expected/src/consumer.ts +++ b/codemods/debarrel/tests/partial-with-type-specifiers/expected/src/consumer.ts @@ -1,5 +1,5 @@ import { VERSION } from "./lib"; -import { Config } from "./lib/config"; +import type { Config } from "./lib/config"; import { helper } from "./lib/helper"; const x: Config = { debug: true }; diff --git a/codemods/debarrel/tests/relative-folder-import/expected/src/input/inputGroup.ts b/codemods/debarrel/tests/relative-folder-import/expected/src/input/inputGroup.ts new file mode 100644 index 0000000..a9d41ec --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/expected/src/input/inputGroup.ts @@ -0,0 +1,5 @@ +import type { TextAreaProps } from "../textarea/textarea"; +import { TextArea } from "../textarea/textarea"; + +const rows: TextAreaProps = { rows: 3 }; +console.log(TextArea(rows)); diff --git a/codemods/debarrel/tests/relative-folder-import/expected/src/input/metrics.json b/codemods/debarrel/tests/relative-folder-import/expected/src/input/metrics.json new file mode 100644 index 0000000..e9c69a3 --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/expected/src/input/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/textarea/index.ts", + "importer": "src/input/inputGroup.ts" + }, + "count": 2 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/relative-folder-import/expected/src/textarea/index.barrel.bak.ts b/codemods/debarrel/tests/relative-folder-import/expected/src/textarea/index.barrel.bak.ts new file mode 100644 index 0000000..8c13da2 --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/expected/src/textarea/index.barrel.bak.ts @@ -0,0 +1 @@ +export { TextArea, type TextAreaProps } from "./textarea"; diff --git a/codemods/debarrel/tests/relative-folder-import/expected/src/textarea/textarea.ts b/codemods/debarrel/tests/relative-folder-import/expected/src/textarea/textarea.ts new file mode 100644 index 0000000..44bfb52 --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/expected/src/textarea/textarea.ts @@ -0,0 +1,5 @@ +export type TextAreaProps = { rows: number }; + +export function TextArea(props: TextAreaProps) { + return props.rows; +} diff --git a/codemods/debarrel/tests/relative-folder-import/expected/tsconfig.json b/codemods/debarrel/tests/relative-folder-import/expected/tsconfig.json new file mode 100644 index 0000000..9efb41a --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/expected/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": {} + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/relative-folder-import/input/src/input/inputGroup.ts b/codemods/debarrel/tests/relative-folder-import/input/src/input/inputGroup.ts new file mode 100644 index 0000000..1411e98 --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/input/src/input/inputGroup.ts @@ -0,0 +1,5 @@ +import type { TextAreaProps } from "../textarea"; +import { TextArea } from "../textarea"; + +const rows: TextAreaProps = { rows: 3 }; +console.log(TextArea(rows)); diff --git a/codemods/debarrel/tests/relative-folder-import/input/src/input/metrics.json b/codemods/debarrel/tests/relative-folder-import/input/src/input/metrics.json new file mode 100644 index 0000000..40df16c --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/input/src/input/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/textarea/index.ts", + "importer": "src/input/inputGroup.ts" + }, + "count": 2 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/relative-folder-import/input/src/textarea/index.ts b/codemods/debarrel/tests/relative-folder-import/input/src/textarea/index.ts new file mode 100644 index 0000000..8c13da2 --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/input/src/textarea/index.ts @@ -0,0 +1 @@ +export { TextArea, type TextAreaProps } from "./textarea"; diff --git a/codemods/debarrel/tests/relative-folder-import/input/src/textarea/textarea.ts b/codemods/debarrel/tests/relative-folder-import/input/src/textarea/textarea.ts new file mode 100644 index 0000000..44bfb52 --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/input/src/textarea/textarea.ts @@ -0,0 +1,5 @@ +export type TextAreaProps = { rows: number }; + +export function TextArea(props: TextAreaProps) { + return props.rows; +} diff --git a/codemods/debarrel/tests/relative-folder-import/input/tsconfig.json b/codemods/debarrel/tests/relative-folder-import/input/tsconfig.json new file mode 100644 index 0000000..9efb41a --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/input/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": {} + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/relative-folder-import/metrics.json b/codemods/debarrel/tests/relative-folder-import/metrics.json new file mode 100644 index 0000000..40df16c --- /dev/null +++ b/codemods/debarrel/tests/relative-folder-import/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/textarea/index.ts", + "importer": "src/input/inputGroup.ts" + }, + "count": 2 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/App.ts b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/App.ts new file mode 100644 index 0000000..7aa5975 --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/App.ts @@ -0,0 +1,3 @@ +import Widget from "./widgets/widget"; + +console.log(Widget()); diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/metrics.json b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/metrics.json new file mode 100644 index 0000000..10f4fdb --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/widgets/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/widgets/index.barrel.bak.ts b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/widgets/index.barrel.bak.ts new file mode 100644 index 0000000..32a09e0 --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/widgets/index.barrel.bak.ts @@ -0,0 +1 @@ +export { default } from "./widget"; diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/widgets/widget.ts b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/widgets/widget.ts new file mode 100644 index 0000000..63ac493 --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/expected/src/widgets/widget.ts @@ -0,0 +1,3 @@ +export default function Widget() { + return "widget"; +} diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/expected/tsconfig.json b/codemods/debarrel/tests/semantic-default-via-reexport/expected/tsconfig.json new file mode 100644 index 0000000..dcb65dc --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/expected/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler" + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/input/src/App.ts b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/App.ts new file mode 100644 index 0000000..904d6e3 --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/App.ts @@ -0,0 +1,3 @@ +import Widget from "./widgets"; + +console.log(Widget()); diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/input/src/metrics.json b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/metrics.json new file mode 100644 index 0000000..10f4fdb --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/widgets/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/input/src/widgets/index.ts b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/widgets/index.ts new file mode 100644 index 0000000..32a09e0 --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/widgets/index.ts @@ -0,0 +1 @@ +export { default } from "./widget"; diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/input/src/widgets/widget.ts b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/widgets/widget.ts new file mode 100644 index 0000000..63ac493 --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/input/src/widgets/widget.ts @@ -0,0 +1,3 @@ +export default function Widget() { + return "widget"; +} diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/input/tsconfig.json b/codemods/debarrel/tests/semantic-default-via-reexport/input/tsconfig.json new file mode 100644 index 0000000..dcb65dc --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/input/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler" + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/semantic-default-via-reexport/metrics.json b/codemods/debarrel/tests/semantic-default-via-reexport/metrics.json new file mode 100644 index 0000000..10f4fdb --- /dev/null +++ b/codemods/debarrel/tests/semantic-default-via-reexport/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/widgets/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/package.json b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/iconAdd.ts b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/iconAdd.ts new file mode 100644 index 0000000..db187a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/iconAdd.ts @@ -0,0 +1,3 @@ +export function IconAdd() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/icons.stories.tsx b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/icons.stories.tsx new file mode 100644 index 0000000..55fbb24 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/icons.stories.tsx @@ -0,0 +1,4 @@ +import * as Icons from 'sentry/icons'; + +// @ts-expect-error demo export +export default Icons.IconAdd; diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/index.tsx b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/index.tsx new file mode 100644 index 0000000..c27d3a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/icons/index.tsx @@ -0,0 +1 @@ +export {IconAdd} from './iconAdd'; diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/metrics.json b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/static/app/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/tsconfig.json b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/tsconfig.json new file mode 100644 index 0000000..c0afb4c --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "preserve", + "moduleResolution": "bundler", + "jsx": "preserve", + "paths": { + "sentry/*": ["./static/app/*"] + } + }, + "include": ["static/app"] +} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/package.json b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/iconAdd.ts b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/iconAdd.ts new file mode 100644 index 0000000..db187a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/iconAdd.ts @@ -0,0 +1,3 @@ +export function IconAdd() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/icons.stories.tsx b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/icons.stories.tsx new file mode 100644 index 0000000..55fbb24 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/icons.stories.tsx @@ -0,0 +1,4 @@ +import * as Icons from 'sentry/icons'; + +// @ts-expect-error demo export +export default Icons.IconAdd; diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/index.tsx b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/index.tsx new file mode 100644 index 0000000..c27d3a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/icons/index.tsx @@ -0,0 +1 @@ +export {IconAdd} from './iconAdd'; diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/metrics.json b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/static/app/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/tsconfig.json b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/tsconfig.json new file mode 100644 index 0000000..c0afb4c --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "preserve", + "moduleResolution": "bundler", + "jsx": "preserve", + "paths": { + "sentry/*": ["./static/app/*"] + } + }, + "include": ["static/app"] +} diff --git a/codemods/debarrel/tests/sentry-icons-namespace-barrel/metrics.json b/codemods/debarrel/tests/sentry-icons-namespace-barrel/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-icons-namespace-barrel/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/package.json b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/Page.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/Page.tsx new file mode 100644 index 0000000..cb7a567 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/Page.tsx @@ -0,0 +1,5 @@ +import {Alert} from '@sentry/scraps/alert'; + +export function Page() { + return Alert(); +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/alert/alert.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/alert/alert.ts new file mode 100644 index 0000000..03f59c4 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/alert/alert.ts @@ -0,0 +1,3 @@ +export function Alert() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/alert/index.barrel.bak.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/alert/index.barrel.bak.ts new file mode 100644 index 0000000..3e0ceea --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/alert/index.barrel.bak.ts @@ -0,0 +1 @@ +export {Alert} from './alert'; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/button/button.mdx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/button/button.mdx new file mode 100644 index 0000000..a465808 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/components/core/button/button.mdx @@ -0,0 +1,5 @@ +import * as Storybook from 'sentry/stories'; + +# Button + + diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/iconAdd.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/iconAdd.ts new file mode 100644 index 0000000..db187a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/iconAdd.ts @@ -0,0 +1,3 @@ +export function IconAdd() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/icons.stories.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/icons.stories.tsx new file mode 100644 index 0000000..b44090b --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/icons.stories.tsx @@ -0,0 +1,3 @@ +import * as Icons from 'sentry/icons'; + +export default Icons.IconAdd; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/index.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/index.tsx new file mode 100644 index 0000000..c27d3a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/icons/index.tsx @@ -0,0 +1 @@ +export {IconAdd} from './iconAdd'; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/metrics.json b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/demo.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/demo.ts new file mode 100644 index 0000000..b682dbf --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/demo.ts @@ -0,0 +1,3 @@ +export function Demo() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/index.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/index.tsx new file mode 100644 index 0000000..21b0be3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/index.tsx @@ -0,0 +1,3 @@ +export {story} from './storybook'; +export {Demo} from './demo'; +export {StoryHeader} from './view/storyHeader'; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/storybook.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/storybook.ts new file mode 100644 index 0000000..2d40d9d --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story(name: string, fn: (s: unknown) => void) { + return {name, fn}; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/view/storyHeader.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/view/storyHeader.tsx new file mode 100644 index 0000000..e8e30f5 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/static/app/stories/view/storyHeader.tsx @@ -0,0 +1,6 @@ +import {IconAdd} from 'sentry/icons'; +import * as Storybook from 'sentry/stories'; + +export function StoryHeader() { + return Storybook.story('header', () => {}); +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/tsconfig.json b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/tsconfig.json new file mode 100644 index 0000000..d5822a6 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/expected/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "preserve", + "moduleResolution": "bundler", + "jsx": "preserve", + "paths": { + "@sentry/scraps/*": ["./static/app/components/core/*"], + "sentry/*": ["./static/app/*"] + } + }, + "include": ["static/app"] +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/package.json b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/Page.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/Page.tsx new file mode 100644 index 0000000..cb7a567 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/Page.tsx @@ -0,0 +1,5 @@ +import {Alert} from '@sentry/scraps/alert'; + +export function Page() { + return Alert(); +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/alert/alert.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/alert/alert.ts new file mode 100644 index 0000000..03f59c4 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/alert/alert.ts @@ -0,0 +1,3 @@ +export function Alert() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/alert/index.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/alert/index.ts new file mode 100644 index 0000000..3e0ceea --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/alert/index.ts @@ -0,0 +1 @@ +export {Alert} from './alert'; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/button/button.mdx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/button/button.mdx new file mode 100644 index 0000000..a465808 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/components/core/button/button.mdx @@ -0,0 +1,5 @@ +import * as Storybook from 'sentry/stories'; + +# Button + + diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/iconAdd.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/iconAdd.ts new file mode 100644 index 0000000..db187a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/iconAdd.ts @@ -0,0 +1,3 @@ +export function IconAdd() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/icons.stories.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/icons.stories.tsx new file mode 100644 index 0000000..b44090b --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/icons.stories.tsx @@ -0,0 +1,3 @@ +import * as Icons from 'sentry/icons'; + +export default Icons.IconAdd; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/index.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/index.tsx new file mode 100644 index 0000000..c27d3a9 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/icons/index.tsx @@ -0,0 +1 @@ +export {IconAdd} from './iconAdd'; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/metrics.json b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/demo.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/demo.ts new file mode 100644 index 0000000..b682dbf --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/demo.ts @@ -0,0 +1,3 @@ +export function Demo() { + return null; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/index.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/index.tsx new file mode 100644 index 0000000..21b0be3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/index.tsx @@ -0,0 +1,3 @@ +export {story} from './storybook'; +export {Demo} from './demo'; +export {StoryHeader} from './view/storyHeader'; diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/storybook.ts b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/storybook.ts new file mode 100644 index 0000000..2d40d9d --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story(name: string, fn: (s: unknown) => void) { + return {name, fn}; +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/view/storyHeader.tsx b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/view/storyHeader.tsx new file mode 100644 index 0000000..e8e30f5 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/static/app/stories/view/storyHeader.tsx @@ -0,0 +1,6 @@ +import {IconAdd} from 'sentry/icons'; +import * as Storybook from 'sentry/stories'; + +export function StoryHeader() { + return Storybook.story('header', () => {}); +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/tsconfig.json b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/tsconfig.json new file mode 100644 index 0000000..d5822a6 --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/input/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "preserve", + "moduleResolution": "bundler", + "jsx": "preserve", + "paths": { + "@sentry/scraps/*": ["./static/app/components/core/*"], + "sentry/*": ["./static/app/*"] + } + }, + "include": ["static/app"] +} diff --git a/codemods/debarrel/tests/sentry-static-app-namespace-barrels/metrics.json b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/metrics.json new file mode 100644 index 0000000..d43ba3d --- /dev/null +++ b/codemods/debarrel/tests/sentry-static-app-namespace-barrels/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "static/app/components/core/alert/index.ts", + "importer": "static/app/components/Page.tsx" + }, + "count": 1 + } + ] +} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/package.json b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/components/button.mdx b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/components/button.mdx new file mode 100644 index 0000000..7a8b894 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/components/button.mdx @@ -0,0 +1,5 @@ +import * as Storybook from 'sentry/stories'; + +# Stories + +{Storybook.story('demo')} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/metrics.json b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/stories/index.tsx b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/stories/index.tsx new file mode 100644 index 0000000..9518911 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/stories/index.tsx @@ -0,0 +1 @@ +export {story} from './storybook'; diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/stories/storybook.ts b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/stories/storybook.ts new file mode 100644 index 0000000..62c4b68 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/static/app/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story(name: string) { + return name; +} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/tsconfig.json b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/tsconfig.json new file mode 100644 index 0000000..c0afb4c --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "preserve", + "moduleResolution": "bundler", + "jsx": "preserve", + "paths": { + "sentry/*": ["./static/app/*"] + } + }, + "include": ["static/app"] +} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/package.json b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/package.json new file mode 100644 index 0000000..da02de2 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/package.json @@ -0,0 +1,4 @@ +{ + "name": "sentry", + "private": true +} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/components/button.mdx b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/components/button.mdx new file mode 100644 index 0000000..7a8b894 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/components/button.mdx @@ -0,0 +1,5 @@ +import * as Storybook from 'sentry/stories'; + +# Stories + +{Storybook.story('demo')} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/metrics.json b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/stories/index.tsx b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/stories/index.tsx new file mode 100644 index 0000000..9518911 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/stories/index.tsx @@ -0,0 +1 @@ +export {story} from './storybook'; diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/stories/storybook.ts b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/stories/storybook.ts new file mode 100644 index 0000000..62c4b68 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/static/app/stories/storybook.ts @@ -0,0 +1,3 @@ +export function story(name: string) { + return name; +} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/tsconfig.json b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/tsconfig.json new file mode 100644 index 0000000..c0afb4c --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "preserve", + "moduleResolution": "bundler", + "jsx": "preserve", + "paths": { + "sentry/*": ["./static/app/*"] + } + }, + "include": ["static/app"] +} diff --git a/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/metrics.json b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/metrics.json new file mode 100644 index 0000000..69a88e3 --- /dev/null +++ b/codemods/debarrel/tests/sentry-stories-mdx-namespace-barrel/metrics.json @@ -0,0 +1 @@ +{} diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/package.json b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/package.json new file mode 100644 index 0000000..9f6bc67 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/package.json @@ -0,0 +1,3 @@ +{ + "name": "myapp" +} diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/App.ts b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/App.ts new file mode 100644 index 0000000..cbfe389 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/App.ts @@ -0,0 +1,3 @@ +import { helper } from "myapp/lib/helper"; + +console.log(helper); diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/lib/helper.ts b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/lib/helper.ts new file mode 100644 index 0000000..ec40407 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/lib/helper.ts @@ -0,0 +1 @@ +export const helper = "helper"; diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/lib/index.barrel.bak.ts b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/lib/index.barrel.bak.ts new file mode 100644 index 0000000..dc65684 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/lib/index.barrel.bak.ts @@ -0,0 +1 @@ +export { helper } from "./helper"; diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/metrics.json b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/metrics.json new file mode 100644 index 0000000..537b734 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/tsconfig.json b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/tsconfig.json new file mode 100644 index 0000000..a54c127 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/expected/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + // Real-world tsconfigs (e.g. Sentry) use JSONC comments in paths. + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/input/package.json b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/package.json new file mode 100644 index 0000000..9f6bc67 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/package.json @@ -0,0 +1,3 @@ +{ + "name": "myapp" +} diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/App.ts b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/App.ts new file mode 100644 index 0000000..be17aec --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/App.ts @@ -0,0 +1,3 @@ +import { helper } from "myapp/lib"; + +console.log(helper); diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/lib/helper.ts b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/lib/helper.ts new file mode 100644 index 0000000..ec40407 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/lib/helper.ts @@ -0,0 +1 @@ +export const helper = "helper"; diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/lib/index.ts b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/lib/index.ts new file mode 100644 index 0000000..dc65684 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/lib/index.ts @@ -0,0 +1 @@ +export { helper } from "./helper"; diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/metrics.json b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/metrics.json new file mode 100644 index 0000000..537b734 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/input/tsconfig.json b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/tsconfig.json new file mode 100644 index 0000000..a54c127 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/input/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + // Real-world tsconfigs (e.g. Sentry) use JSONC comments in paths. + "paths": { + "myapp/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/tsconfig-jsonc-paths/metrics.json b/codemods/debarrel/tests/tsconfig-jsonc-paths/metrics.json new file mode 100644 index 0000000..537b734 --- /dev/null +++ b/codemods/debarrel/tests/tsconfig-jsonc-paths/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/lib/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/App.ts b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/App.ts new file mode 100644 index 0000000..240f29b --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/App.ts @@ -0,0 +1,3 @@ +import { Tag } from "@app/scraps/badge/tag"; + +console.log(Tag()); diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/core/badge/index.barrel.bak.ts b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/core/badge/index.barrel.bak.ts new file mode 100644 index 0000000..c82af3c --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/core/badge/index.barrel.bak.ts @@ -0,0 +1 @@ +export { Tag } from "./tag"; diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/core/badge/tag.ts b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/core/badge/tag.ts new file mode 100644 index 0000000..1d72013 --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/core/badge/tag.ts @@ -0,0 +1,3 @@ +export function Tag() { + return "tag"; +} diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/metrics.json b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/metrics.json new file mode 100644 index 0000000..7c0de3b --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/expected/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/badge/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/expected/tsconfig.json b/codemods/debarrel/tests/wildcard-scraps-alias/expected/tsconfig.json new file mode 100644 index 0000000..c47a40a --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/expected/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@app/scraps/*": ["./src/core/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/input/src/App.ts b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/App.ts new file mode 100644 index 0000000..1d90abe --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/App.ts @@ -0,0 +1,3 @@ +import { Tag } from "@app/scraps/badge"; + +console.log(Tag()); diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/input/src/core/badge/index.ts b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/core/badge/index.ts new file mode 100644 index 0000000..c82af3c --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/core/badge/index.ts @@ -0,0 +1 @@ +export { Tag } from "./tag"; diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/input/src/core/badge/tag.ts b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/core/badge/tag.ts new file mode 100644 index 0000000..1d72013 --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/core/badge/tag.ts @@ -0,0 +1,3 @@ +export function Tag() { + return "tag"; +} diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/input/src/metrics.json b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/metrics.json new file mode 100644 index 0000000..7c0de3b --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/input/src/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/badge/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/input/tsconfig.json b/codemods/debarrel/tests/wildcard-scraps-alias/input/tsconfig.json new file mode 100644 index 0000000..c47a40a --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/input/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@app/scraps/*": ["./src/core/*"] + } + }, + "include": ["src"] +} diff --git a/codemods/debarrel/tests/wildcard-scraps-alias/metrics.json b/codemods/debarrel/tests/wildcard-scraps-alias/metrics.json new file mode 100644 index 0000000..7c0de3b --- /dev/null +++ b/codemods/debarrel/tests/wildcard-scraps-alias/metrics.json @@ -0,0 +1,11 @@ +{ + "barrel_import": [ + { + "cardinality": { + "filePath": "src/core/badge/index.ts", + "importer": "src/App.ts" + }, + "count": 1 + } + ] +} \ No newline at end of file