diff --git a/packages/kamado/package.json b/packages/kamado/package.json index ecb24a7..ec61893 100644 --- a/packages/kamado/package.json +++ b/packages/kamado/package.json @@ -44,9 +44,11 @@ "hono": "4.11.3", "jsdom": "27.4.0", "open": "11.0.0", + "picomatch": "4.0.3", "yaml": "2.8.2" }, "devDependencies": { - "@types/jsdom": "27.0.0" + "@types/jsdom": "27.0.0", + "@types/picomatch": "4.0.2" } } diff --git a/packages/kamado/src/data/assets.spec.ts b/packages/kamado/src/data/assets.spec.ts index 73af862..ba16bb9 100644 --- a/packages/kamado/src/data/assets.spec.ts +++ b/packages/kamado/src/data/assets.spec.ts @@ -66,4 +66,51 @@ describe('getAssetGroup with virtual file system', () => { expect(result[0]).toHaveProperty('filePathStem', '/about'); expect(result[0]).toHaveProperty('extension', '.html'); }); + + test('should filter files with glob option (AND condition)', async () => { + const result = await getAssetGroup({ + inputDir: '/mock/input/dir', + outputDir: '/mock/output/dir', + compilerEntry: { + files: '**/*.{html,pug}', + outputExtension: '.html', + compiler: () => () => '', + }, + glob: '**/index.*', + }); + + expect(result.map((f) => f.inputPath)).toStrictEqual(['/mock/input/dir/index.html']); + }); + + test('should filter files with glob option matching specific directory', async () => { + const result = await getAssetGroup({ + inputDir: '/mock/input/dir', + outputDir: '/mock/output/dir', + compilerEntry: { + files: '**/*.{html,pug}', + outputExtension: '.html', + compiler: () => () => '', + }, + glob: '**/subdir/**', + }); + + expect(result.map((f) => f.inputPath)).toStrictEqual([ + '/mock/input/dir/subdir/page.html', + ]); + }); + + test('should return empty array when glob matches no files', async () => { + const result = await getAssetGroup({ + inputDir: '/mock/input/dir', + outputDir: '/mock/output/dir', + compilerEntry: { + files: '**/*.{html,pug}', + outputExtension: '.html', + compiler: () => () => '', + }, + glob: '**/nonexistent.*', + }); + + expect(result).toStrictEqual([]); + }); }); diff --git a/packages/kamado/src/data/assets.ts b/packages/kamado/src/data/assets.ts index 3644492..08967d1 100644 --- a/packages/kamado/src/data/assets.ts +++ b/packages/kamado/src/data/assets.ts @@ -4,6 +4,7 @@ import type { CompilableFile } from '../files/types.js'; import path from 'node:path'; import fg from 'fast-glob'; +import picomatch from 'picomatch'; import { getFile } from '../files/file.js'; @@ -20,14 +21,13 @@ interface GetAssetsOptions { * @param options.inputDir - Input directory path * @param options.outputDir - Output directory path * @param options.compilerEntry - Compiler with metadata configuration - * @param options.glob - Glob pattern for search targets (if omitted, uses compilerEntry.files) + * @param options.glob - Additional glob pattern to filter results (AND condition with compilerEntry.files) * @returns List of asset files */ export async function getAssetGroup( options: GetAssetsOptions, ): Promise { - const targetGlob = - options.glob ?? path.resolve(options.inputDir, options.compilerEntry.files); + const baseGlob = path.resolve(options.inputDir, options.compilerEntry.files); const fgOptions: { cwd: string; @@ -39,7 +39,12 @@ export async function getAssetGroup( fgOptions.ignore = [options.compilerEntry.ignore]; } - const filePaths = await fg(targetGlob, fgOptions); + let filePaths = await fg(baseGlob, fgOptions); + + if (options.glob) { + const isMatch = picomatch(options.glob); + filePaths = filePaths.filter((filePath) => isMatch(filePath)); + } const results: CompilableFile[] = []; diff --git a/yarn.lock b/yarn.lock index 1c5873b..b2d3eb1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3308,6 +3308,13 @@ __metadata: languageName: node linkType: hard +"@types/picomatch@npm:4.0.2": + version: 4.0.2 + resolution: "@types/picomatch@npm:4.0.2" + checksum: 10c0/0f46198c2d1beb5061816745355888e94a80a449a49af1ef69723f50e850c678b50cff299bd461f71e8009d46705e7cdeda8c8ffa23815b2e942c83877f855b9 + languageName: node + linkType: hard + "@types/postcss-import@npm:14.0.3": version: 14.0.3 resolution: "@types/postcss-import@npm:14.0.3" @@ -8658,6 +8665,7 @@ __metadata: "@d-zero/shared": "npm:0.17.1" "@hono/node-server": "npm:1.19.7" "@types/jsdom": "npm:27.0.0" + "@types/picomatch": "npm:4.0.2" ansi-colors: "npm:4.1.3" character-entities: "npm:2.0.2" cosmiconfig: "npm:9.0.0" @@ -8667,6 +8675,7 @@ __metadata: hono: "npm:4.11.3" jsdom: "npm:27.4.0" open: "npm:11.0.0" + picomatch: "npm:4.0.3" yaml: "npm:2.8.2" bin: kamado: ./dist/index.js @@ -11059,6 +11068,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:4.0.3, picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 + languageName: node + linkType: hard + "picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -11066,13 +11082,6 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": - version: 4.0.3 - resolution: "picomatch@npm:4.0.3" - checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 - languageName: node - linkType: hard - "pidtree@npm:^0.6.0": version: 0.6.0 resolution: "pidtree@npm:0.6.0"