From 1b5037bd77d77817e5f821aee8ceccb49b00e0d9 Mon Sep 17 00:00:00 2001 From: Dani Fernández Date: Wed, 12 Feb 2025 15:08:38 +0100 Subject: Update netlify adapter to integrate includeFiles and excludeFiles options (#13194) * feat: integrated includeFiles and excludeFiles on netlify adapter * feat: added netlify include and exclude files tests * feat: changelogs added * fix: avoid problems with glob file url on windows * feat: improved JS Docs to include examples and important information * feat: removed non necessary root path as glob is already absolute * Apply suggestions from code review * Update packages/integrations/netlify/src/index.ts Co-authored-by: Matt Kane * Update .changeset/ninety-clouds-judge.md Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --------- Co-authored-by: Emanuele Stoppa Co-authored-by: Matt Kane Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --- .../netlify/test/functions/include-files.test.js | 184 +++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 packages/integrations/netlify/test/functions/include-files.test.js (limited to 'packages/integrations/netlify/test/functions/include-files.test.js') diff --git a/packages/integrations/netlify/test/functions/include-files.test.js b/packages/integrations/netlify/test/functions/include-files.test.js new file mode 100644 index 000000000..a7fa11ca3 --- /dev/null +++ b/packages/integrations/netlify/test/functions/include-files.test.js @@ -0,0 +1,184 @@ +import * as assert from 'node:assert/strict'; +import { existsSync } from 'node:fs'; +import { after, before, describe, it } from 'node:test'; +import netlify from '@astrojs/netlify'; +import { loadFixture } from '../../../../astro/test/test-utils.js'; +import * as cheerio from 'cheerio'; +import glob from 'fast-glob'; + +describe( + 'Included vite assets files', + () => { + let fixture; + + const root = new URL('./fixtures/includes/', import.meta.url); + const expectedCwd = new URL('.netlify/v1/functions/ssr/packages/integrations/netlify/', root); + + const expectedAssetsInclude = ['./*.json']; + const excludedAssets = ['./files/exclude-asset.json']; + + before(async () => { + fixture = await loadFixture({ + root, + vite: { + assetsInclude: expectedAssetsInclude, + }, + adapter: netlify({ + excludeFiles: excludedAssets, + }), + }); + await fixture.build(); + }); + + it('Emits vite assets files', async () => { + for (const pattern of expectedAssetsInclude) { + const files = glob.sync(pattern); + for (const file of files) { + assert.ok( + existsSync(new URL(file, expectedCwd)), + `Expected file ${pattern} to exist in build`, + ); + } + } + }); + + it('Does not include vite assets files when excluded', async () => { + for (const file of excludedAssets) { + assert.ok( + !existsSync(new URL(file, expectedCwd)), + `Expected file ${file} to not exist in build`, + ); + } + }); + + after(async () => { + await fixture.clean(); + }); + }, + { + timeout: 120000, + }, +); + +describe( + 'Included files', + () => { + let fixture; + + const root = new URL('./fixtures/includes/', import.meta.url); + const expectedCwd = new URL( + '.netlify/v1/functions/ssr/packages/integrations/netlify/test/functions/fixtures/includes/', + root, + ); + + const expectedFiles = [ + './files/include-this.txt', + './files/also-this.csv', + './files/subdirectory/and-this.csv', + ]; + + before(async () => { + fixture = await loadFixture({ + root, + adapter: netlify({ + includeFiles: expectedFiles, + }), + }); + await fixture.build(); + }); + + it('Emits include files', async () => { + for (const file of expectedFiles) { + assert.ok(existsSync(new URL(file, expectedCwd)), `Expected file ${file} to exist`); + } + }); + + it('Can load included files correctly', async () => { + const entryURL = new URL( + './fixtures/includes/.netlify/v1/functions/ssr/ssr.mjs', + import.meta.url, + ); + const { default: handler } = await import(entryURL); + const resp = await handler(new Request('http://example.com/?file=include-this.txt'), {}); + const html = await resp.text(); + const $ = cheerio.load(html); + assert.equal($('h1').text(), 'hello'); + }); + + it('Includes traced node modules with symlinks', async () => { + const expected = new URL( + '.netlify/v1/functions/ssr/node_modules/.pnpm/cowsay@1.6.0/node_modules/cowsay/cows/happy-whale.cow', + root, + ); + assert.ok(existsSync(expected, 'Expected excluded file to exist in default build')); + }); + + after(async () => { + await fixture.clean(); + }); + }, + { + timeout: 120000, + }, +); + +describe( + 'Excluded files', + () => { + let fixture; + + const root = new URL('./fixtures/includes/', import.meta.url); + const expectedCwd = new URL( + '.netlify/v1/functions/ssr/packages/integrations/netlify/test/functions/fixtures/includes/', + root, + ); + + const includeFiles = ['./files/**/*.txt']; + const excludedTxt = ['./files/subdirectory/not-this.txt', './files/subdirectory/or-this.txt']; + const excludeFiles = [...excludedTxt, '../../../../../../../node_modules/.pnpm/cowsay@*/**']; + + before(async () => { + fixture = await loadFixture({ + root, + adapter: netlify({ + includeFiles: includeFiles, + excludeFiles: excludeFiles, + }), + }); + await fixture.build(); + }); + + it('Excludes traced node modules', async () => { + const expected = new URL( + '.netlify/v1/functions/ssr/node_modules/.pnpm/cowsay@1.6.0/node_modules/cowsay/cows/happy-whale.cow', + root, + ); + assert.ok(!existsSync(expected), 'Expected excluded file to not exist in build'); + }); + + it('Does not include files when excluded', async () => { + for (const pattern of includeFiles) { + const files = glob.sync(pattern, { ignore: excludedTxt }); + for (const file of files) { + assert.ok( + existsSync(new URL(file, expectedCwd)), + `Expected file ${pattern} to exist in build`, + ); + } + } + for (const file of excludedTxt) { + assert.ok( + !existsSync(new URL(file, expectedCwd)), + `Expected file ${file} to not exist in build`, + ); + } + }); + + after(async () => { + await fixture.clean(); + }); + }, + { + timeout: 120000, + }, +); -- cgit v1.2.3