Skip to content

Commit

Permalink
[now-build-utils] Add function detectApiExtensions() (#3653)
Browse files Browse the repository at this point in the history
* [now-routing-utils] Add function detectApiExtensions

* Add more tests, fix broken test

* Add missing check for extensions

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
styfle and kodiakhq[bot] committed Jan 24, 2020
1 parent 11bbda9 commit 243451e
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 22 deletions.
21 changes: 14 additions & 7 deletions packages/now-build-utils/src/detect-routes.ts
@@ -1,4 +1,4 @@
import { parse as parsePath } from 'path';
import { parse as parsePath, extname } from 'path';
import { Route, Source } from '@now/routing-utils';
import { Builder } from './types';
import { getIgnoreApiFilter, sortFiles } from './detect-builders';
Expand Down Expand Up @@ -337,6 +337,18 @@ export function detectApiDirectory(builders: Builder[]): string | null {
return found ? 'api' : null;
}

export function detectApiExtensions(builders: Builder[]): Set<string> {
return new Set<string>(
builders
.filter(
b =>
b.config && b.config.zeroConfig && b.src && b.src.startsWith('api/')
)
.map(b => extname(b.src))
.filter(Boolean)
);
}

export async function detectRoutes(
files: string[],
builders: Builder[],
Expand All @@ -363,12 +375,7 @@ export async function detectRoutes(
);
if (featHandleMiss) {
defaultRoutes.push({ handle: 'miss' });
const extSet = new Set(
builders
.filter(b => b.src && b.src.startsWith('api/'))
.map(b => parsePath(b.src).ext)
.filter(Boolean)
);
const extSet = detectApiExtensions(builders);
if (extSet.size > 0) {
const exts = Array.from(extSet)
.map(ext => ext.slice(1))
Expand Down
1 change: 1 addition & 0 deletions packages/now-build-utils/src/index.ts
Expand Up @@ -66,6 +66,7 @@ export {
detectRoutes,
detectOutputDirectory,
detectApiDirectory,
detectApiExtensions,
} from './detect-routes';
export { detectBuilders } from './detect-builders';
export { detectFramework } from './detect-framework';
Expand Down
@@ -1,6 +1,10 @@
import { Source, Route } from '@now/routing-utils';
import { detectBuilders, detectRoutes } from '../src';
import { detectOutputDirectory, detectApiDirectory } from '../';
import {
detectOutputDirectory,
detectApiDirectory,
detectApiExtensions,
} from '../';

describe('Test `detectBuilders`', () => {
it('package.json + no build', async () => {
Expand Down Expand Up @@ -1891,6 +1895,81 @@ describe('Test `detectApiDirectory`', () => {
});
});

describe('Test `detectApiExtensions`', () => {
it('should have correct extensions', async () => {
const builders = [
{
use: '@now/node',
src: 'api/**/*.js',
config: {
zeroConfig: true,
},
},
{
use: '@now/python',
src: 'api/**/*.py',
config: {
zeroConfig: true,
},
},
{
use: '@now/go',
src: 'api/**/*.go',
config: {
zeroConfig: true,
},
},
{
use: '@now/ruby',
src: 'api/**/*.rb',
config: {
zeroConfig: true,
},
},
{
use: 'now-bash',
src: 'api/**/*.sh',
// No zero config so it should not be added
},
{
use: 'now-no-extension',
src: 'api/executable',
// No extension should not be added
config: {
zeroConfig: true,
},
},
{
use: '@now/next',
src: 'package.json',
// No api directory should not be added
config: {
zeroConfig: true,
},
},
{
use: 'now-rust@1.0.1',
src: 'api/user.rs',
config: {
zeroConfig: true,
functions: {
'api/**/*.rs': {
runtime: 'now-rust@1.0.1',
},
},
},
},
];
const result = detectApiExtensions(builders);
expect(result.size).toBe(5);
expect(result.has('.js')).toBe(true);
expect(result.has('.py')).toBe(true);
expect(result.has('.go')).toBe(true);
expect(result.has('.rb')).toBe(true);
expect(result.has('.rs')).toBe(true);
});
});

/**
* Create a function that will replace matched redirects
* similar to how it works with `now-proxy` in production.
Expand Down
3 changes: 0 additions & 3 deletions packages/now-build-utils/test/unit.test.js
Expand Up @@ -116,10 +116,7 @@ it('should throw for discontinued versions', async () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => new Date('2020-02-14').getTime();

expect(getSupportedNodeVersion('', false)).rejects.toThrow();
expect(getSupportedNodeVersion('8.10.x', false)).rejects.toThrow();

expect(getSupportedNodeVersion('', true)).rejects.toThrow();
expect(getSupportedNodeVersion('8.10.x', true)).rejects.toThrow();

expect(getDiscontinuedNodeVersions().length).toBe(1);
Expand Down
11 changes: 5 additions & 6 deletions packages/now-cli/src/util/dev/builder.ts
Expand Up @@ -13,6 +13,7 @@ import {
FileBlob,
FileFsRef,
detectApiDirectory,
detectApiExtensions,
} from '@now/build-utils';
import stripAnsi from 'strip-ansi';
import chalk from 'chalk';
Expand Down Expand Up @@ -419,6 +420,7 @@ export async function getBuildMatches(
const noMatches: Builder[] = [];
const builds = nowConfig.builds || [{ src: '**', use: '@now/static' }];
const apiDir = detectApiDirectory(builds || []);
const apiExtensions = detectApiExtensions(builds || []);
const apiMatch = apiDir + '/';

for (const buildConfig of builds) {
Expand All @@ -438,13 +440,10 @@ export async function getBuildMatches(
// We need to escape brackets since `glob` will
// try to find a group otherwise
src = src.replace(/(\[|\])/g, '[$1]');

if (apiDir && src.startsWith(apiMatch)) {
const ext = extname(src);
if (apiDir && src.startsWith(apiMatch) && apiExtensions.has(ext)) {
// lambda function files are trimmed of their file extension
const ext = extname(src);
if (ext) {
src = src.slice(0, -ext.length);
}
src = src.slice(0, -ext.length);
}

const files = fileList
Expand Down
10 changes: 5 additions & 5 deletions packages/now-cli/src/util/dev/server.ts
Expand Up @@ -27,6 +27,7 @@ import {
detectBuilders,
detectRoutes,
detectApiDirectory,
detectApiExtensions,
} from '@now/build-utils';

import { once } from '../once';
Expand Down Expand Up @@ -733,16 +734,15 @@ export default class DevServer {
const files = await getFiles(this.cwd, nowConfig, opts);
const results: { [filePath: string]: FileFsRef } = {};
const apiDir = detectApiDirectory(nowConfig.builds || []);
const apiExtensions = detectApiExtensions(nowConfig.builds || []);
const apiMatch = apiDir + '/';
for (const fsPath of files) {
let path = relative(this.cwd, fsPath);
const { mode } = await fs.stat(fsPath);
if (apiDir && path.startsWith(apiMatch)) {
const ext = extname(path);
if (apiDir && path.startsWith(apiMatch) && apiExtensions.has(ext)) {
// lambda function files are trimmed of their file extension
const ext = extname(path);
if (ext) {
path = path.slice(0, -ext.length);
}
path = path.slice(0, -ext.length);
}
results[path] = new FileFsRef({ mode, fsPath });
}
Expand Down

1 comment on commit 243451e

@vercel
Copy link

@vercel vercel bot commented on 243451e Jan 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.