diff --git a/packages/core/src/files/paths.ts b/packages/core/src/files/paths.ts index eced866..fb114d0 100644 --- a/packages/core/src/files/paths.ts +++ b/packages/core/src/files/paths.ts @@ -64,7 +64,7 @@ export function createPathResolver( return { // `match` returns an object if true, here we're forcing it to return a boolean. /** - * Explanation: why does `isSourcePathMatch` checks if it isn't a locales path but `isLocalesPathMatch` doesn't? + * Explanation: why does `isSourcePath` checks if it isn't a locales path but `isLocalesPath` doesn't? * In a few cases, the source path can end up matching the locales path, like so: * * - Source path: `docs/test.mdx` (sourcePattern: `docs/@path`) @@ -73,9 +73,8 @@ export function createPathResolver( * In this case, the locales path fulfills the source pattern match, but the opposite can't happen, considering * the locales path strictly requires the `@lang` parameter that is limited to the configured locales. */ - isSourcePathMatch: (path: string) => - !!match(sourcePattern)(path) && !match(localesPattern)(path), - isLocalesPathMatch: (path: string) => !!match(localesPattern)(path), + isSourcePath: (path: string) => !!match(sourcePattern)(path) && !match(localesPattern)(path), + isLocalesPath: (path: string) => !!match(localesPattern)(path), toPath: (fromPath: string, toLang: string) => { // Since the path for the same source and localized content can have different patterns, // we have to check if the `toLang` is from the sourceLocale (i.e. source content) or diff --git a/packages/core/src/files/types.ts b/packages/core/src/files/types.ts index 7dd1ce4..e2d7ef5 100644 --- a/packages/core/src/files/types.ts +++ b/packages/core/src/files/types.ts @@ -1,8 +1,8 @@ export interface PathResolver { /** Checks if a path matches an source locale path. */ - isSourcePathMatch: (path: string) => boolean; + isSourcePath: (path: string) => boolean; /** Checks if a path matches an localized path. */ - isLocalesPathMatch: (path: string) => boolean; + isLocalesPath: (path: string) => boolean; /** Creates a path from one locale to the equivalent of another. */ toPath: (fromPath: string, toLang: string) => string; /** The resolved source pattern used by the path resolver. */ diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 9808424..1e42f3a 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -9,6 +9,7 @@ import { createPathResolver } from './files/paths.js'; import { LunariaGitInstance } from './status/git.js'; import { getDictionaryCompletion, isFileLocalizable } from './status/status.js'; import type { LunariaStatus, StatusLocalizationEntry } from './status/types.js'; +import picomatch from 'picomatch'; // Additional data to ensure we can force rebuild the cache. // Bump this whenever there are breaking changes to the status output. @@ -97,7 +98,7 @@ export class Lunaria { // We keep track of those to warn the user about them. const filteredOutPaths: string[] = []; - const { isSourcePathMatch } = this.getPathResolver(pattern); + const { isSourcePath } = this.getPathResolver(pattern); // Lunaria initially globs only the source files, and then proceed to // check the status of each localization file through dynamically // generated paths using `pattern`. @@ -107,7 +108,7 @@ export class Lunaria { ignore: exclude, }) ).filter((path) => { - if (!isSourcePathMatch(path)) { + if (!isSourcePath(path)) { filteredOutPaths.push(path); return false; } @@ -140,12 +141,10 @@ export class Lunaria { return undefined; } - const { isSourcePathMatch, toPath } = this.getPathResolver(fileConfig.pattern); + const { isSourcePath, toPath } = this.getPathResolver(fileConfig.pattern); /** The given path can be of another locale, therefore we always convert it to the source path */ - const sourcePath = isSourcePathMatch(path) - ? path - : toPath(path, this.#config.sourceLocale.lang); + const sourcePath = isSourcePath(path) ? path : toPath(path, this.#config.sourceLocale.lang); const isLocalizable = isFileLocalizable(path, this.#config.tracking.localizableProperty); @@ -228,10 +227,23 @@ export class Lunaria { findFileConfig(path: string) { return this.#config.files.find((file) => { // TODO: We should update this since the pattern might match, but not the include that determines a different type for it. - const { isSourcePathMatch, isLocalesPathMatch } = this.getPathResolver(file.pattern); - // We're checking if the path matches either the source or locales pattern, - // that way we can determine the `files` entry that should be used for the path. - return isSourcePathMatch(path) || isLocalesPathMatch(path); + const { isSourcePath, toPath } = this.getPathResolver(file.pattern); + + try { + const sourcePath = isSourcePath(path) ? path : toPath(path, this.#config.sourceLocale.lang); + + // There's a few cases in which the pattern might match, but the include/exclude filters don't, + // therefore we need to test both to find the correct `files` config. + return ( + isSourcePath(path) && + picomatch.isMatch(sourcePath, file.include, { + ignore: file.exclude, + }) + ); + // If it fails to match, we assume it's not the respective `files` config and return false. + } catch { + return false; + } }); } }