UNPKG

@intlayer/chokidar

Version:

Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.

1 lines 6.19 kB
{"version":3,"file":"buildFilesList.mjs","names":[],"sources":["../../../src/utils/buildFilesList.ts"],"sourcesContent":["import { isAbsolute, normalize, relative, resolve } from 'node:path';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport fg from 'fast-glob';\n\n/**\n * Options for building the files list\n */\nexport type BuildComponentFilesListOptions = {\n /**\n * Glob patterns to match files\n */\n transformPattern: string | string[];\n /**\n * Glob patterns to exclude files\n */\n excludePattern?: string | string[];\n /**\n * Base directory (or directories) for file resolution.\n * When multiple directories are provided, subdirectories of others are\n * automatically deduplicated so files are never scanned twice.\n */\n baseDir: string | string[];\n /**\n * Whether to include dot-prefixed files and directories (default: false)\n */\n dot?: boolean;\n};\n\n/**\n * Normalizes a pattern value to an array\n */\nconst normalizeToArray = <T>(value: T | T[]): T[] =>\n Array.isArray(value) ? value : [value];\n\n/**\n * Remove directories that are subdirectories of others in the list so files\n * are never scanned twice.\n * Example: ['/root', '/root/src'] → ['/root']\n */\nconst getDistinctRootDirs = (dirs: string[]): string[] => {\n const uniqueDirs = Array.from(new Set(dirs.map((dir) => resolve(dir))));\n uniqueDirs.sort((a, b) => a.length - b.length);\n\n return uniqueDirs.reduce((acc: string[], dir) => {\n const isNested = acc.some((parent) => {\n const rel = relative(parent, dir);\n return !rel.startsWith('..') && !isAbsolute(rel) && rel !== '';\n });\n if (!isNested) acc.push(dir);\n return acc;\n }, []);\n};\n\n/**\n * Builds a deduplicated list of absolute file paths matching the given patterns.\n *\n * Handles multiple root directories (deduplicates overlapping roots), exclude\n * patterns, negation patterns embedded in `transformPattern`, and optional\n * dot-file inclusion.\n *\n * @example\n * // Single root with excludes\n * const files = buildComponentFilesList({\n * transformPattern: 'src/**\\/*.{ts,tsx}',\n * excludePattern: ['**\\/node_modules\\/**'],\n * baseDir: '/path/to/project',\n * });\n *\n * @example\n * // Multiple roots (e.g. baseDir + codeDir), dot files included\n * const files = buildComponentFilesList({\n * transformPattern: config.build.traversePattern,\n * baseDir: [config.system.baseDir, ...config.content.codeDir],\n * dot: true,\n * });\n */\nexport const buildComponentFilesList = (\n config: BuildComponentFilesListOptions\n): string[] => {\n const {\n transformPattern,\n excludePattern = [],\n baseDir,\n dot = false,\n } = config;\n\n const patterns = normalizeToArray(transformPattern)\n .filter(\n (pattern): pattern is string =>\n typeof pattern === 'string' && !pattern.startsWith('!')\n )\n .map(normalize); // Ensure it works with Windows\n\n const excludePatterns = [\n ...normalizeToArray(excludePattern),\n // Treat negation entries in transformPattern as additional excludes\n ...normalizeToArray(transformPattern)\n .filter(\n (pattern): pattern is string =>\n typeof pattern === 'string' && pattern.startsWith('!')\n )\n .map((pattern) => pattern.slice(1)),\n ]\n .filter((pattern): pattern is string => typeof pattern === 'string')\n .map(normalize); // Ensure it works with Windows\n\n const roots = getDistinctRootDirs(normalizeToArray(baseDir));\n\n return Array.from(\n new Set(\n roots.flatMap((root) =>\n fg.sync(patterns, {\n cwd: root,\n ignore: excludePatterns,\n absolute: true,\n dot,\n })\n )\n )\n );\n};\n\n/**\n * Convenience wrapper that derives all file-list options directly from an\n * `IntlayerConfig` object.\n *\n * Scans `[baseDir, ...codeDir]` using `build.traversePattern`, excludes\n * content declaration file extensions and any `compiler.excludePattern`\n * entries defined in the configuration, and includes dot files.\n */\nexport const buildComponentFilesListFromConfig = (\n intlayerConfig: IntlayerConfig\n): string[] => {\n const {\n build: { traversePattern },\n system: { baseDir },\n content: { codeDir, fileExtensions },\n compiler: { excludePattern },\n } = intlayerConfig;\n\n const excludePatterns = [\n // Exclude content declaration files (e.g. **/*.content.ts)\n ...fileExtensions.map((ext) => `**/*${ext}`),\n ...(Array.isArray(excludePattern) ? excludePattern : [excludePattern]),\n ].filter((p): p is string => typeof p === 'string');\n\n return buildComponentFilesList({\n transformPattern: traversePattern,\n excludePattern: excludePatterns,\n baseDir: [baseDir, ...codeDir],\n dot: true,\n });\n};\n"],"mappings":";;;;;;;AA+BA,MAAM,oBAAuB,UAC3B,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;;;;;;AAOvC,MAAM,uBAAuB,SAA6B;CACxD,MAAM,aAAa,MAAM,KAAK,IAAI,IAAI,KAAK,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC,CAAC;CACtE,WAAW,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;CAE7C,OAAO,WAAW,QAAQ,KAAe,QAAQ;EAK/C,IAAI,CAJa,IAAI,MAAM,WAAW;GACpC,MAAM,MAAM,SAAS,QAAQ,GAAG;GAChC,OAAO,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,WAAW,GAAG,KAAK,QAAQ;EAC9D,CACY,GAAG,IAAI,KAAK,GAAG;EAC3B,OAAO;CACT,GAAG,CAAC,CAAC;AACP;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,2BACX,WACa;CACb,MAAM,EACJ,kBACA,iBAAiB,CAAC,GAClB,SACA,MAAM,UACJ;CAEJ,MAAM,WAAW,iBAAiB,gBAAgB,EAC/C,QACE,YACC,OAAO,YAAY,YAAY,CAAC,QAAQ,WAAW,GAAG,CAC1D,EACC,IAAI,SAAS;CAEhB,MAAM,kBAAkB,CACtB,GAAG,iBAAiB,cAAc,GAElC,GAAG,iBAAiB,gBAAgB,EACjC,QACE,YACC,OAAO,YAAY,YAAY,QAAQ,WAAW,GAAG,CACzD,EACC,KAAK,YAAY,QAAQ,MAAM,CAAC,CAAC,CACtC,EACG,QAAQ,YAA+B,OAAO,YAAY,QAAQ,EAClE,IAAI,SAAS;CAEhB,MAAM,QAAQ,oBAAoB,iBAAiB,OAAO,CAAC;CAE3D,OAAO,MAAM,KACX,IAAI,IACF,MAAM,SAAS,SACb,GAAG,KAAK,UAAU;EAChB,KAAK;EACL,QAAQ;EACR,UAAU;EACV;CACF,CAAC,CACH,CACF,CACF;AACF;;;;;;;;;AAUA,MAAa,qCACX,mBACa;CACb,MAAM,EACJ,OAAO,EAAE,mBACT,QAAQ,EAAE,WACV,SAAS,EAAE,SAAS,kBACpB,UAAU,EAAE,qBACV;CAQJ,OAAO,wBAAwB;EAC7B,kBAAkB;EAClB,gBARsB,CAEtB,GAAG,eAAe,KAAK,QAAQ,OAAO,KAAK,GAC3C,GAAI,MAAM,QAAQ,cAAc,IAAI,iBAAiB,CAAC,cAAc,CACtE,EAAE,QAAQ,MAAmB,OAAO,MAAM,QAIV;EAC9B,SAAS,CAAC,SAAS,GAAG,OAAO;EAC7B,KAAK;CACP,CAAC;AACH"}