Skip to content

Commit

Permalink
Merge pull request #690 from FoalTS/remove-express-types
Browse files Browse the repository at this point in the history
Fix Express types
  • Loading branch information
LoicPoullain authored May 1, 2020
2 parents c5c744a + 6ec30dc commit fa79f79
Show file tree
Hide file tree
Showing 21 changed files with 212 additions and 191 deletions.
10 changes: 3 additions & 7 deletions docs/tutorials/mongodb-todo-list/3-the-todo-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,15 @@ foal generate model todo
Open the file `todo.model.ts` in the `src/app/models` directory and add a `text` field.

```typescript
import { Document, model, Model, models, Schema } from 'mongoose';
import { model, models, Schema } from 'mongoose';

const todoSchema: Schema = new Schema({
const todoSchema = new Schema({
text: {
required: true,
type: String // String with a capital letter
}
});

export interface ITodo extends Document {
text: string; // string a lowercase letter
}

export const Todo: Model<ITodo> = models.Todo || model<ITodo>('Todo', todoSchema);
export const Todo = models.Todo || model('Todo', todoSchema);

```
2 changes: 1 addition & 1 deletion packages/acceptance-tests/src/error-handling.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('FoalTS should support custom error-handling', () => {
handleError: true
},
postMiddlewares: [
(err, req, res, next) => {
(err: any, req: any, res: any, next: (err?: any) => any) => {
next(new Error('Hi!'));
}
]
Expand Down
17 changes: 2 additions & 15 deletions packages/core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
"all": true
},
"dependencies": {
"@types/express-serve-static-core": "4.17.0",
"ajv": "~6.12.0",
"cookie-parser": "~1.4.4",
"express": "~4.17.1",
Expand Down
98 changes: 97 additions & 1 deletion packages/core/src/core/http/contexts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,102 @@
import { Request } from 'express-serve-static-core';
import { Session } from '../../sessions';

interface Readable {
[name: string]: any;
}

interface IncomingMessage extends Readable {
aborted: boolean;
complete: boolean;
headers: any;
// These two lines are present in @types/node but not in Node.js official documentation.
// Missing: httpVersionMajor: number;
// Missing: httpVersionMinor: string;
httpVersion: string;
method?: string;
rawHeaders: string[];
rawTrailers: string[];
socket: any;
statusCode?: number;
statusMessage?: number;
trailers: any;
url?: string;
destroy(err?: any): void;
// tslint:disable-next-line:ban-types
setTimeout(msecs: number, callback: Function): this;
}

/**
* Express Request interface.
*
* @interface Request
*/
interface Request extends IncomingMessage {
app: any;
baseUrl: string;
body: any;
cookies: any;
fresh: boolean;
// This line is present in @types/express but not in Express official documentation.
// host: string; // @deprecated
hostname: string;
ip: string;
ips: string[];
method: string;
originalUrl: string;
params: any;
path: string;
// The type is a string in @types/express.
procotol: 'http'|'https';
query: any;
route: any;
secure: boolean;
signedCookies: any;
stale: boolean;
subdomains: string[];
xhr: boolean;
// This line has been added based on @types/express in order not to make the url possibly undefined.
url: string;

// This line has been added based on @types/express but it is not present in Express official documentation.
accepts(): string[];
accepts(types: string|string[]): string|false;
accepts(...types: string[]): string|false;

// This line has been added based on @types/express but it is not present in Express official documentation.
acceptsCharsets(): string[];
acceptsCharsets(charset: string|string[]): string|false;
acceptsCharsets(...charset: string[]): string|false;

// This line has been added based on @types/express but it is not present in Express official documentation.
acceptsEncodings(): string[];
acceptsEncodings(encoding: string|string[]): string|false;
acceptsEncodings(...encoding: string[]): string|false;

// This line has been added based on @types/express but it is not present in Express official documentation.
acceptsLanguages(): string[];
acceptsLanguages(lang: string|string[]): string|false;
acceptsLanguages(...lang: string[]): string|false;

// This line has been added based on @types/express but it is not present in Express official documentation.
get(field: 'set-cookie'): string[] | undefined;
get(field: string): string|undefined;

// This line has been added based on @types/express but it is not present in Express official documentation.
header(field: 'set-cookie'): string[] | undefined;
header(field: string): string|undefined;

// The string[] type has been added based on @types/express but it is not present in Express official documentation.
is(type: string|string[]): string | false | null;

/**
* @deprecated
*/
param(name: string, defaultValue?: any): any;

// The undefined type has been added based on @types/express but it is not present in Express official documentation.
range(size: number, options?: { combine?: boolean }): -1|-2|any[]|undefined;
}

/**
* Class instantiated on each request. It includes:
* - the express request object,
Expand Down
17 changes: 6 additions & 11 deletions packages/core/src/express/create-app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ import { Buffer } from 'buffer';

// 3p
import * as express from 'express';
import {
NextFunction,
Request,
Response
} from 'express-serve-static-core';
import * as request from 'supertest';

// FoalTS
Expand Down Expand Up @@ -309,8 +304,8 @@ describe('createApp', () => {

const app = createApp(AppController, {
preMiddlewares: [
(req: Request, res: Response, next: NextFunction) => {
(req as any).foalMessage = 'Hello world!'; next();
(req: any, res: any, next: (err?: any) => any) => {
req.foalMessage = 'Hello world!'; next();
}
]
});
Expand All @@ -337,9 +332,9 @@ describe('createApp', () => {

const app = createApp(AppController, {
postMiddlewares: [
express.Router().get('/a', (req, res) => res.send('a2')),
express.Router().get('/b', (req, res) => res.send('b2')),
(err, req, res, next) => {
express.Router().get('/a', (req: any, res: any) => res.send('a2')),
express.Router().get('/b', (req: any, res: any) => res.send('b2')),
(err: any, req: any, res: any, next: any) => {
err.message += '!!!';
next(err);
}
Expand Down Expand Up @@ -436,7 +431,7 @@ describe('createAndInitApp', () => {

const app = await createAndInitApp(AppController, {
postMiddlewares: [
express.Router().get('/ping2', (req, res) => res.send('pong'))
express.Router().get('/ping2', (req: any, res: any) => res.send('pong'))
]
});

Expand Down
49 changes: 21 additions & 28 deletions packages/core/src/express/create-app.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
// 3p
import * as cookieParser from 'cookie-parser';
import * as express from 'express';
import {
ErrorRequestHandler,
Express,
NextFunction,
Request,
RequestHandler,
Response
} from 'express-serve-static-core';
import * as logger from 'morgan';

// FoalTS
Expand All @@ -22,21 +14,22 @@ import { createMiddleware } from './create-middleware';
import { handleErrors } from './handle-errors';
import { notFound } from './not-found';

export interface ExpressApplication extends Express {
[name: string]: any;
}
export type ExpressApplication = any;

type Middleware = (req: any, res: any, next: (err?: any) => any) => any;
type ErrorMiddleware = (err: any, req: any, res: any, next: (err?: any) => any) => any;

export interface CreateAppOptions {
expressInstance?: ExpressApplication;
expressInstance?: any;
methods?: {
handleError?: boolean;
};
serviceManager?: ServiceManager;
preMiddlewares?: (RequestHandler | ErrorRequestHandler)[];
postMiddlewares?: (RequestHandler | ErrorRequestHandler)[];
preMiddlewares?: (Middleware|ErrorMiddleware)[];
postMiddlewares?: (Middleware|ErrorMiddleware)[];
}

function handleJsonErrors(err: any, req: Request, res: Response, next: NextFunction) {
function handleJsonErrors(err: any, req: any, res: any, next: (err?: any) => any) {
if (err.type !== 'entity.parse.failed') {
next(err);
return;
Expand All @@ -47,7 +40,7 @@ function handleJsonErrors(err: any, req: Request, res: Response, next: NextFunct
});
}

function protectionHeaders(req: Request, res: Response, next: NextFunction) {
function protectionHeaders(req: any, res: any, next: (err?: any) => any) {
res.removeHeader('X-Powered-By');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-DNS-Prefetch-Control', 'off');
Expand All @@ -58,7 +51,7 @@ function protectionHeaders(req: Request, res: Response, next: NextFunction) {
next();
}

function getOptions(expressInstanceOrOptions?: ExpressApplication|CreateAppOptions): CreateAppOptions {
function getOptions(expressInstanceOrOptions?: any|CreateAppOptions): CreateAppOptions {
if (!expressInstanceOrOptions) {
return {};
}
Expand All @@ -75,9 +68,9 @@ function getOptions(expressInstanceOrOptions?: ExpressApplication|CreateAppOptio
*
* @export
* @param {Class} AppController - The root controller, usually called `AppController` and located in `src/app`.
* @param {(ExpressApplication|CreateAppOptions)} [expressInstanceOrOptions] - Express instance or options containaining
* @param {(any|CreateAppOptions)} [expressInstanceOrOptions] - Express instance or options containaining
* Express middlewares or other settings.
* @param {ExpressApplication} [expressInstanceOrOptions.expressInstance] - Express instance to be used as base for the
* @param {any} [expressInstanceOrOptions.expressInstance] - Express instance to be used as base for the
* returned application.
* @param {boolean} [expressInstanceOrOptions.methods.handleError] - Specifies if AppController.handleError should be
* used to handle errors.
Expand All @@ -87,14 +80,14 @@ function getOptions(expressInstanceOrOptions?: ExpressApplication|CreateAppOptio
* middlewares to be executed before the controllers and hooks.
* @param {(RequestHandler | ErrorRequestHandler)[]} [expressInstanceOrOptions.postMiddlewares] Express
* middlewares to be executed after the controllers and hooks, but before the 500 or 404 handler get called.
* @returns {ExpressApplication} The express application.
* @returns {any} The express application.
*/
export function createApp(
AppController: Class,
expressInstanceOrOptions?: ExpressApplication | CreateAppOptions,
): ExpressApplication {
expressInstanceOrOptions?: any | CreateAppOptions,
): any {
const options = getOptions(expressInstanceOrOptions);
const app: ExpressApplication = options.expressInstance || express();
const app = options.expressInstance || express();

// Add optional pre-middlewares.
for (const middleware of options.preMiddlewares || []) {
Expand Down Expand Up @@ -157,9 +150,9 @@ export function createApp(
*
* @export
* @param {Class} AppController - The root controller, usually called `AppController` and located in `src/app`.
* @param {(ExpressApplication|CreateAppOptions)} [expressInstanceOrOptions] - Express instance or options containaining
* @param {(any|CreateAppOptions)} [expressInstanceOrOptions] - Express instance or options containaining
* Express middlewares or other settings.
* @param {ExpressApplication} [expressInstanceOrOptions.expressInstance] - Express instance to be used as base for the
* @param {any} [expressInstanceOrOptions.expressInstance] - Express instance to be used as base for the
* returned application.
* @param {boolean} [expressInstanceOrOptions.methods.handleError] - Specifies if AppController.handleError should be
* used to handle errors.
Expand All @@ -169,11 +162,11 @@ export function createApp(
* middlewares to be executed before the controllers and hooks.
* @param {(RequestHandler | ErrorRequestHandler)[]} [expressInstanceOrOptions.postMiddlewares] Express
* middlewares to be executed after the controllers and hooks, but before the 500 or 404 handler get called.
* @returns {Promise<ExpressApplication>} The express application.
* @returns {Promise<any>} The express application.
*/
export async function createAndInitApp(
AppController: Class, expressInstanceOrOptions?: ExpressApplication | CreateAppOptions
): Promise<ExpressApplication> {
AppController: Class, expressInstanceOrOptions?: any | CreateAppOptions
): Promise<any> {
const app = createApp(AppController, expressInstanceOrOptions);

const controller = app.foal.services.get(AppController);
Expand Down
15 changes: 5 additions & 10 deletions packages/core/src/express/create-middleware.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import { deepStrictEqual, ok, strictEqual } from 'assert';

// 3p
import * as express from 'express';
import {
NextFunction,
Request,
Response
} from 'express-serve-static-core';
import { createRequest, createResponse } from 'node-mocks-http';
import * as request from 'supertest';

Expand Down Expand Up @@ -169,7 +164,7 @@ describe('createMiddleware', () => {
it('should forward an Error to the next error-handling middleware.', done => {
const app = express();
app.get('/a', createMiddleware(route(() => ({})), new ServiceManager()));
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
app.use((err: any, req: any, res: any, next: (err?: any) => any) => {
try {
ok(err instanceof Error);
strictEqual(err.message, 'The controller method "fn" should return an HttpResponse.');
Expand All @@ -195,7 +190,7 @@ describe('createMiddleware', () => {
path: '',
propertyKey: 'bar'
}, new ServiceManager()));
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
app.use((err: any, req: any, res: any, next: (err?: any) => any) => {
try {
ok(err instanceof Error);
strictEqual(err.message, 'Error thrown in a hook.');
Expand All @@ -215,7 +210,7 @@ describe('createMiddleware', () => {
route(() => { throw new Error('Error thrown in a controller method.'); }),
new ServiceManager())
);
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
app.use((err: any, req: any, res: any, next: (err?: any) => any) => {
try {
ok(err instanceof Error);
strictEqual(err.message, 'Error thrown in a controller method.');
Expand All @@ -239,7 +234,7 @@ describe('createMiddleware', () => {
path: '',
propertyKey: 'bar'
}, new ServiceManager()));
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
app.use((err: any, req: any, res: any, next: (err?: any) => any) => {
try {
ok(err instanceof Error);
strictEqual(err.message, 'Error rejected in a hook.');
Expand All @@ -259,7 +254,7 @@ describe('createMiddleware', () => {
route(async () => { throw new Error('Error rejected in a controller method.'); }),
new ServiceManager())
);
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
app.use((err: any, req: any, res: any, next: (err?: any) => any) => {
try {
ok(err instanceof Error);
strictEqual(err.message, 'Error rejected in a controller method.');
Expand Down
Loading

0 comments on commit fa79f79

Please sign in to comment.