Files
vercel/packages/fs-detectors/test/unit.detect-file-system-api.test.ts
Steven 51fe09d5e9 [build-utils][fs-detectors][cli] MAJOR: move some of build-utils into new fs-detectors (#8054)
The `@vercel/build-utils` package was meant be shared functions necessary for writing a Vercel Builder (aka Runtime).

This package has since bloated into the catch-all package for anything that wasn't a Builder.

This PR removes the bloat in favor of a new package, `@vercel/fs-detectors`. It also removes the need for `@vercel/build-utils` to have a dependency on `@vercel/frameworks`.

- Related to #7951
2022-06-30 21:14:07 +00:00

446 lines
14 KiB
TypeScript
Vendored

import { detectFileSystemAPI } from '../src/detect-file-system-api';
describe('Test `detectFileSystemAPI`', () => {
it('should error when builds in vercel.json', async () => {
const vercelConfig = {
builds: [{ use: '@vercel/node', src: 'api/**/*.js' }],
};
const files = {
'vercel.json': JSON.stringify(vercelConfig),
'api/foo.js': 'console.log("foo")',
};
const result = await detectFileSystemAPI({
files,
projectSettings: {},
builders: vercelConfig.builds,
vercelConfig,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected `builds` in vercel.json. Please remove it in favor of CLI plugins.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when functions.runtimes in vercel.json', async () => {
const vercelConfig = {
functions: {
'api/**/*.rs': {
runtime: 'vercel-rust@latest',
},
},
};
const files = {
'vercel.json': JSON.stringify(vercelConfig),
'api/foo.rs': 'println!("foo")',
};
const result = await detectFileSystemAPI({
files,
projectSettings: {},
builders: [],
vercelConfig,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected `functions.runtime` in vercel.json. Please remove it in favor of CLI plugins.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when HUGO_VERSION env var used', async () => {
process.env.HUGO_VERSION = 'v0.58.2';
const files = { 'foo.html': '<h1>Foo</h1>' };
const result = await detectFileSystemAPI({
files,
projectSettings: {},
builders: [],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason: 'Detected `HUGO_VERSION` environment variable. Please remove it.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
delete process.env.HUGO_VERSION;
});
it('should error when ZOLA_VERSION env var used', async () => {
process.env.ZOLA_VERSION = 'v0.0.1';
const files = { 'foo.html': '<h1>Foo</h1>' };
const result = await detectFileSystemAPI({
files,
projectSettings: {},
builders: [],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason: 'Detected `ZOLA_VERSION` environment variable. Please remove it.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
delete process.env.ZOLA_VERSION;
});
it('should error when GUTENBERG_VERSION env var used', async () => {
process.env.GUTENBERG_VERSION = 'v0.0.1';
const files = { 'foo.html': '<h1>Foo</h1>' };
const result = await detectFileSystemAPI({
files,
projectSettings: {},
builders: [],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected `GUTENBERG_VERSION` environment variable. Please remove it.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
delete process.env.GUTENBERG_VERSION;
});
it('should error when Go detected without corresponding plugin', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.go': 'print("foo")' },
projectSettings: {},
builders: [{ use: '@vercel/go', src: 'api/**/*.go' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected `go` Serverless Function usage without plugin `vercel-plugin-go`. Please run `npm i vercel-plugin-go`.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when Python detected without corresponding plugin', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.py': 'print("foo")' },
projectSettings: {},
builders: [{ use: '@vercel/python', src: 'api/**/*.py' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected `python` Serverless Function usage without plugin `vercel-plugin-python`. Please run `npm i vercel-plugin-python`.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when Ruby detected without corresponding plugin', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.rb': 'print("foo")' },
projectSettings: {},
builders: [{ use: '@vercel/ruby', src: 'api/**/*.rb' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected `ruby` Serverless Function usage without plugin `vercel-plugin-ruby`. Please run `npm i vercel-plugin-ruby`.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should succeed when Go detected with corresponding plugin', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.go': 'print("foo")' },
projectSettings: {},
builders: [{ use: '@vercel/go', src: 'api/**/*.go' }],
vercelConfig: null,
pkg: { dependencies: { 'vercel-plugin-go': '^1.0.0' } },
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: {
use: '@vercelruntimes/file-system-api',
src: '**',
config: {
fileSystemAPI: true,
framework: null,
hasDotOutput: false,
hasMiddleware: false,
projectSettings: {},
},
},
reason: null,
metadata: {
hasDotOutput: false,
hasMiddleware: false,
plugins: ['vercel-plugin-go'],
},
});
});
it('should succeed when Python detected with corresponding plugin', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.py': 'print("foo")' },
projectSettings: {},
builders: [{ use: '@vercel/python', src: 'api/**/*.py' }],
vercelConfig: null,
pkg: { dependencies: { 'vercel-plugin-python': '^1.0.0' } },
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: {
use: '@vercelruntimes/file-system-api',
src: '**',
config: {
fileSystemAPI: true,
framework: null,
hasDotOutput: false,
hasMiddleware: false,
projectSettings: {},
},
},
reason: null,
metadata: {
hasDotOutput: false,
hasMiddleware: false,
plugins: ['vercel-plugin-python'],
},
});
});
it('should succeed when Ruby detected with corresponding plugin', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.rb': 'print("foo")' },
projectSettings: {},
builders: [{ use: '@vercel/ruby', src: 'api/**/*.rb' }],
vercelConfig: null,
pkg: { dependencies: { 'vercel-plugin-ruby': '^1.0.0' } },
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: {
use: '@vercelruntimes/file-system-api',
src: '**',
config: {
fileSystemAPI: true,
framework: null,
hasDotOutput: false,
hasMiddleware: false,
projectSettings: {},
},
},
reason: null,
metadata: {
hasDotOutput: false,
hasMiddleware: false,
plugins: ['vercel-plugin-ruby'],
},
});
});
it('should error when framework is nuxtjs', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.js': 'console.log("foo")' },
projectSettings: { framework: 'nuxtjs' },
builders: [{ use: '@vercel/node', src: 'api/**/*.js' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected framework `nuxtjs` that only supports legacy File System API. Please contact the framework author.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when framework is sveltekit', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.js': 'console.log("foo")' },
projectSettings: { framework: 'sveltekit' },
builders: [{ use: '@vercel/node', src: 'api/**/*.js' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected framework `sveltekit` that only supports legacy File System API. Please contact the framework author.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when framework is redwoodjs', async () => {
const result = await detectFileSystemAPI({
files: { 'api/foo.js': 'console.log("foo")' },
projectSettings: { framework: 'redwoodjs' },
builders: [{ use: '@vercel/node', src: 'api/**/*.js' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected framework `redwoodjs` that only supports legacy File System API. Please contact the framework author.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when framework is nextjs and has output dir', async () => {
const result = await detectFileSystemAPI({
files: { 'pages/foo.js': 'console.log("foo")' },
projectSettings: { framework: 'nextjs', outputDirectory: 'dist' },
builders: [{ use: '@vercel/next', src: 'package.json' }],
vercelConfig: null,
pkg: { dependencies: { next: '^12.0.0' } },
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected Next.js with Output Directory `dist` override. Please change it back to the default.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when framework is nextjs but missing from dependencies', async () => {
const result = await detectFileSystemAPI({
files: { 'pages/foo.js': 'console.log("foo")' },
projectSettings: { framework: 'nextjs' },
builders: [{ use: '@vercel/next', src: 'package.json' }],
vercelConfig: null,
pkg: { dependencies: { 'not-next': '^12.0.0' } },
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected Next.js in Project Settings but missing `next` package.json dependencies. Please run `npm i next`.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when framework is nextjs but dependency is older version', async () => {
const result = await detectFileSystemAPI({
files: { 'pages/foo.js': 'console.log("foo")' },
projectSettings: { framework: 'nextjs' },
builders: [{ use: '@vercel/next', src: 'package.json' }],
vercelConfig: null,
pkg: { dependencies: { next: '^9.0.0' } },
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected legacy Next.js version "^9.0.0" in package.json. Please run `npm i next@latest` to upgrade.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should error when vercel cli is older version', async () => {
const result = await detectFileSystemAPI({
files: { 'pages/foo.js': 'console.log("foo")' },
projectSettings: { framework: 'nextjs' },
builders: [{ use: '@vercel/next', src: 'package.json' }],
vercelConfig: null,
pkg: { dependencies: { next: '^12.1.0', vercel: '^23.1.1' } },
tag: '',
enableFlag: true,
});
expect(result).toEqual({
fsApiBuilder: null,
reason:
'Detected legacy Vercel CLI version "^23.1.1" in package.json. Please run `npm i vercel@latest` to upgrade.',
metadata: { hasDotOutput: false, hasMiddleware: false, plugins: [] },
});
});
it('should succeed when middleware detected', async () => {
const result = await detectFileSystemAPI({
files: { '_middleware.js': 'print("foo")' },
projectSettings: {},
builders: [{ use: '@vercel/static-build', src: 'package.json' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: false,
});
expect(result).toEqual({
fsApiBuilder: {
use: '@vercelruntimes/file-system-api',
src: '**',
config: {
fileSystemAPI: true,
framework: null,
hasDotOutput: false,
hasMiddleware: true,
projectSettings: {},
},
},
reason: null,
metadata: { hasDotOutput: false, hasMiddleware: true, plugins: [] },
});
});
it('should succeed when .output detected', async () => {
const result = await detectFileSystemAPI({
files: { '.output/routes-manifest.json': '{}' },
projectSettings: { framework: 'remix' },
builders: [{ use: '@vercel/static-build', src: 'package.json' }],
vercelConfig: null,
pkg: null,
tag: '',
enableFlag: false,
});
expect(result).toEqual({
fsApiBuilder: {
use: '@vercelruntimes/file-system-api',
src: '**',
config: {
fileSystemAPI: true,
framework: 'remix',
hasDotOutput: true,
hasMiddleware: false,
projectSettings: { framework: 'remix' },
},
},
reason: null,
metadata: { hasDotOutput: true, hasMiddleware: false, plugins: [] },
});
});
});