Skip to content
This repository has been archived by the owner on Jan 18, 2023. It is now read-only.

Commit

Permalink
feat(1.6): add models and factories (#59)
Browse files Browse the repository at this point in the history
feat(1.6): add models and factories
  • Loading branch information
nahtnam authored Jan 21, 2020
2 parents fd508c2 + 513f45f commit db9bb0c
Show file tree
Hide file tree
Showing 45 changed files with 907 additions and 628 deletions.
1 change: 1 addition & 0 deletions .bookignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
README.md
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"@typescript-eslint/indent": ["error", 2],
"@typescript-eslint/no-explicit-any": "off",
"jest/no-disabled-tests": "off",
"no-underscore-dangle": "off"
"no-underscore-dangle": "off",
"import/extensions": "off"
},
"settings": {
"import/resolver": {
Expand Down
415 changes: 306 additions & 109 deletions package-lock.json

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@
"chokidar": "^2.1.8",
"decache": "^4.5.1",
"emojic": "^1.1.15",
"find-my-way": "^2.1.0",
"find-my-way": "^2.2.1",
"lodash.camelcase": "^4.3.0",
"lodash.set": "^4.3.2",
"micro": "^9.3.4",
"micro-boom": "^1.2.0",
"micromatch": "^4.0.2",
"path-parser": "^4.2.0",
"pino": "^5.13.2",
"pino-http": "^4.2.0",
"pino": "^5.15.0",
"pino-http": "^4.3.0",
"repl.history": "^0.1.4",
"signale": "^1.4.0",
"test-listen": "^1.1.0",
Expand All @@ -60,29 +60,29 @@
"youch-terminal": "^1.0.0"
},
"devDependencies": {
"@types/jest": "^24.0.18",
"@types/jest": "^24.0.25",
"@types/lodash.camelcase": "^4.3.6",
"@types/lodash.set": "^4.3.6",
"@types/micro": "^7.3.3",
"@types/micromatch": "^3.1.0",
"@types/node": "^11.13.19",
"@types/node-fetch": "^2.5.0",
"@types/pino-http": "^4.0.3",
"@types/micromatch": "^3.1.1",
"@types/node": "^11.15.3",
"@types/node-fetch": "^2.5.4",
"@types/pino-http": "^4.3.2",
"@types/signale": "^1.2.1",
"@types/test-listen": "^1.1.0",
"@types/url-join": "^4.0.0",
"@types/yargs": "^13.0.2",
"@types/yargs": "^13.0.4",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"coveralls": "^3.0.6",
"coveralls": "^3.0.9",
"eslint": "^5.16.0",
"eslint-config-airbnb-base": "^13.2.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jest": "^22.15.2",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-jest": "^22.21.0",
"jest": "^24.9.0",
"node-fetch": "^2.6.0",
"strip-ansi": "^5.2.0",
"ts-jest": "^24.0.2",
"typescript": "^3.5.3"
"ts-jest": "^24.2.0",
"typescript": "^3.7.4"
}
}
6 changes: 3 additions & 3 deletions src/cli/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import chalk from 'chalk';
import decache from 'decache';

import logger from '../../utils/logger';
import Route from '../../types/route';
import { RouteObject } from '../../types/route';
import { server } from '../../index';
import findRoutes from '../../utils/find-routes';
import addRoute from '../../utils/add-route';
Expand Down Expand Up @@ -46,7 +46,7 @@ const handle = async (argv: Args): Promise<void> => {
const routesPath = join(cwd, './routes');

const opts = {
isDev: true,
dev: true,
};

const app = server({
Expand Down Expand Up @@ -87,7 +87,7 @@ const handle = async (argv: Args): Promise<void> => {
decache(f.handler);
});
const routeObjs = importRoutes(files, routesPath, true);
routeObjs.forEach((route: Route): void => {
routeObjs.forEach((route: RouteObject): void => {
addRoute(app.router, route, opts);
});
});
Expand Down
23 changes: 23 additions & 0 deletions src/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
interface Factory {
_name?: string;
[key: string]: any;
}

export default (name: string): any => {
if (!name) throw new Error('factory must have a name');
return {
handler(factoryFn: any): Factory {
const factory = factoryFn();
const returnOBJ: Factory = {
_name: name,
...factory,
};

Object.keys(factory).forEach((key): void => {
returnOBJ[`${key}${name}`] = factory[key];
});

return returnOBJ;
},
};
};
1 change: 1 addition & 0 deletions src/global.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO: properly take into account the src folder
import { existsSync } from 'fs';
import { join } from 'path';

Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// export { default, default as light } from './light';

export { default as server } from './server';
export { default as model } from './model';
export { default as factory } from './factory';
export { default as params } from './params';
export { default as query } from './query';
export { default as test } from './test';
Expand Down
23 changes: 23 additions & 0 deletions src/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
interface Model {
_name?: string;
model: any;
[key: string]: any;
}

export default (name: string): any => {
if (!name) throw new Error('model must have a name');
return {
handler(modelFn: any): Model {
const model = modelFn();

const returnOBJ: Model = {
_name: name,
model,
};

returnOBJ[name] = model;

return returnOBJ;
},
};
};
20 changes: 4 additions & 16 deletions src/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { IncomingMessage, ServerResponse } from 'http';
import AWSServerlessMicro from 'aws-serverless-micro';
import { run } from 'micro';
import { handleErrors } from 'micro-boom';
Expand All @@ -7,23 +6,12 @@ import pinoHTTP from 'pino-http';
import Youch from 'youch';
import forTerminal from 'youch-terminal';

import { IM, SR, AP } from './types/http';
import { Options, Route } from './types/route';

import pinoPretty from './helpers/pino-pretty';

type IM = IncomingMessage;
type SR = ServerResponse;
type AP = Promise<any>;

interface Route {
handler: (fn: (req: IM, res: SR) => {} | any) => (req: IM, res: SR) => {};
middleware: (fn: any) => void;
plugin: (fn: any) => void;
}

interface Options {
dev?: boolean;
requestLogger?: boolean;
errorHandler?: boolean;
}
// TODO: abstract out more stuff

const { LIGHT_ENV } = process.env;

Expand Down
15 changes: 7 additions & 8 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ import { METHODS } from 'http';
import join from 'url-join';
import camelCase from 'lodash.camelcase';

interface RouterRouteType {
method: string;
path: string;
handler: string;
}
import { RouteObject } from './types/route';

// TODO: clean up interfaces
// TODO: write tests

export default (): any => {
// closures
const _routes: RouterRouteType[] = [];
const _routes: RouteObject[] = [];

const getRouterObj = (namespace: string): any => {
const obj: any = {
Expand All @@ -19,7 +18,7 @@ export default (): any => {
},
};

METHODS.forEach((method: string): void => {
[...METHODS, 'all'].forEach((method: string): void => {
const name = camelCase(method);
obj[name] = (rawPath: string | string[], handler: string): void => {
let path: any = rawPath;
Expand All @@ -28,7 +27,7 @@ export default (): any => {
}
path = path.map((r: string): string => join('/', namespace, r));
_routes.push({
method,
method: (method === 'all') ? METHODS : method,
path,
handler: join('/', handler),
});
Expand Down
40 changes: 17 additions & 23 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
import micro from 'micro';
import Router from 'find-my-way';
import { IncomingMessage, ServerResponse, Server } from 'http';

import { IM, SR } from './types/http';
import { LightServer } from './types/server';
import { RouteObject, Options } from './types/route';

import findRoutes from './utils/find-routes';
import RouteType from './types/route';
import importRoutes from './utils/import-routes';
import addRoute from './utils/add-route';
import glob from './global';

interface Light {
server: Server;
router: any;
}

type IM = IncomingMessage;
type SR = ServerResponse;
import globalRegister from './global';

// TODO: change opts type to the Options type in route.ts
const app = ({
export default ({
routes,
opts,
}: {
routes: string | RouteType[];
opts?: any;
}): Light => {
const g = glob();
routes: string | RouteObject[];
opts?: Options;
}): LightServer => {
// register global variables
const g = globalRegister();
(global as any).light = g;

// create find-my-way router with default 404 handler
const router = Router({
ignoreTrailingSlash: true,
defaultRoute: (req: IncomingMessage, res: ServerResponse): void => {
defaultRoute: (_: IM, res: SR): void => {
res.statusCode = 404;
res.end('Not Found');
},
});

let routeObjs: RouteType[] = [];
let routeObjs: RouteObject[] = [];

if (typeof routes === 'string') {
const files: any[] = findRoutes(routes);
const files: RouteObject[] = findRoutes(routes);
routeObjs = importRoutes(files, routes);
} else {
routeObjs = routes;
}

const server = micro(async (req: IM, res: SR): Promise<any> => router.lookup(req, res));

routeObjs.forEach((route: RouteType): void => {
routeObjs.forEach((route: RouteObject): void => {
addRoute(router, route, opts);
});

Expand All @@ -54,5 +50,3 @@ const app = ({
server,
};
};

export default app;
25 changes: 14 additions & 11 deletions src/test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import listen from 'test-listen';
import { METHODS } from 'http';

import { TestOptions } from './types/route';

import { server } from './index';

// TODO: support multiple routes with a given route object
export default async (route: any, opts?: any): Promise<any> => {
export default (route: any, opts?: TestOptions): any => {
// generate a server with only the route provided
const options = {
requestLogger: false,
Expand All @@ -14,20 +17,20 @@ export default async (route: any, opts?: any): Promise<any> => {
routes: [
{
handler: async (req: any, res: any): Promise<any> => route(req, res, options),
method: 'GET',
path: '/',
method: options.method || METHODS,
path: options.path || '/',
},
],
});

const url = await listen(app.server);
const srvr = app.server;

return {
url,
app,
server: app.server,
close(): void {
this.server.close();
async listen(): Promise<string> {
return listen(srvr);
},

close(): any {
srvr.close();
},
};
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions src/types/http.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-disable no-undef */
import { IncomingMessage, ServerResponse, Server } from 'http';

type IM = IncomingMessage;
type SR = ServerResponse;
type AP = Promise<any>;

export {
IM,
SR,
AP,
Server,
};
Loading

0 comments on commit db9bb0c

Please sign in to comment.