diff --git a/src/actions/components.js b/src/actions/components.js index 01e41bb..25cae0f 100644 --- a/src/actions/components.js +++ b/src/actions/components.js @@ -110,6 +110,7 @@ export async function compileComponents() { const componentsDir = path.join(process.cwd(), 'components'); const components = []; for (const file of fs.readdirSync(componentsDir)) { + if (!fs.statSync(path.join(componentsDir, file)).isDirectory()) continue; const component = { name: file, latestHtml: fs.readFileSync( diff --git a/src/deploy.js b/src/deploy.js index bd5fedb..893e80e 100644 --- a/src/deploy.js +++ b/src/deploy.js @@ -226,6 +226,7 @@ export default async function deploy(options = {}) { const componentsDir = path.join(cwd, 'components'); if (fs.existsSync(componentsDir)) { for (const file of fs.readdirSync(componentsDir)) { + if (!fs.statSync(path.join(componentsDir, file)).isDirectory()) continue; const data = { file: fs.readFileSync(path.join(componentsDir, file, `${file}.js`), 'utf8'), config: JSON.parse( diff --git a/tests/deploy.test.js b/tests/deploy.test.js index 501b0dc..0a216d7 100644 --- a/tests/deploy.test.js +++ b/tests/deploy.test.js @@ -5,6 +5,7 @@ const mocks = vi.hoisted(() => { existsSync: vi.fn(), readdirSync: vi.fn(), readFileSync: vi.fn(), + statSync: vi.fn(), }; const ora = vi.fn((label) => { @@ -141,6 +142,7 @@ function setDefaultMocks() { if (target === '/repo/components') return []; return []; }); + mocks.fs.statSync.mockReturnValue({ isDirectory: () => true }); } describe('deploy command', () => { @@ -268,6 +270,31 @@ describe('deploy command', () => { expect(process.exitCode).toBeUndefined(); }); + test('skips non-directory entries (e.g. .DS_Store) in the components directory', async () => { + mocks.fs.readdirSync.mockImplementation((target, options) => { + if (options && options.withFileTypes) return []; + if (target === '/repo/components') return ['.DS_Store', 'hero']; + return []; + }); + mocks.fs.statSync.mockImplementation((target) => ({ + isDirectory: () => !String(target).endsWith('.DS_Store'), + })); + mocks.fs.readFileSync.mockImplementation((target) => { + if (String(target).endsWith('hero.json')) return '{}'; + return ''; + }); + + await deploy({}); + + expect(mocks.fs.readFileSync).not.toHaveBeenCalledWith( + expect.stringContaining('.DS_Store'), + expect.anything() + ); + expect(mocks.updateComponentConfig).toHaveBeenCalledTimes(1); + expect(mocks.updateComponentFile).toHaveBeenCalledTimes(1); + expect(process.exitCode).toBeUndefined(); + }); + test('skips pages without campaignUuid', async () => { mocks.fs.existsSync.mockImplementation( (target) => target !== '/repo/components'