Skip to content

Commit f41013f

Browse files
Merge pull request #79 from bitgopatmcl/express-router-fn
Add router-returning function to express-wrapper
2 parents 10c2ab1 + 03468c2 commit f41013f

File tree

1 file changed

+51
-38
lines changed

1 file changed

+51
-38
lines changed

packages/express-wrapper/src/index.ts

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,46 +21,59 @@ export type { ResponseEncoder } from './response';
2121
const isHttpVerb = (verb: string): verb is 'get' | 'put' | 'post' | 'delete' =>
2222
verb === 'get' || verb === 'put' || verb === 'post' || verb === 'delete';
2323

24-
export const createServerWithResponseEncoder =
25-
(encoder: ResponseEncoder) =>
26-
<Spec extends ApiSpec>(
27-
spec: ApiSpec,
28-
configureExpressApplication: (app: express.Application) => {
29-
[ApiName in keyof Spec]: {
30-
[Method in keyof Spec[ApiName]]: RouteHandler<Spec[ApiName][Method]>;
31-
};
32-
},
33-
) => {
34-
const app: express.Application = express();
35-
const routes = configureExpressApplication(app);
36-
37-
const router = express.Router();
38-
for (const apiName of Object.keys(spec)) {
39-
const resource = spec[apiName] as Spec[string];
40-
for (const method of Object.keys(resource)) {
41-
if (!isHttpVerb(method)) {
42-
continue;
43-
}
44-
const httpRoute: HttpRoute = resource[method]!;
45-
const routeHandler = routes[apiName]![method]!;
46-
const expressRouteHandler = decodeRequestAndEncodeResponse(
47-
apiName,
48-
httpRoute,
49-
// FIXME: TS is complaining that `routeHandler` is not necessarily guaranteed to be a
50-
// `ServiceFunction`, because subtypes of Spec[string][string] can have arbitrary extra keys.
51-
getServiceFunction(routeHandler as any),
52-
encoder,
53-
);
54-
const handlers = [...getMiddleware(routeHandler), expressRouteHandler];
24+
type CreateRouterProps<Spec extends ApiSpec> = {
25+
spec: Spec;
26+
routeHandlers: {
27+
[ApiName in keyof Spec]: {
28+
[Method in keyof Spec[ApiName]]: RouteHandler<Spec[ApiName][Method]>;
29+
};
30+
};
31+
encoder?: ResponseEncoder;
32+
};
5533

56-
const expressPath = apiTsPathToExpress(httpRoute.path);
57-
router[method](expressPath, handlers);
34+
export function routerForApiSpec<Spec extends ApiSpec>({
35+
spec,
36+
routeHandlers,
37+
encoder = defaultResponseEncoder,
38+
}: CreateRouterProps<Spec>) {
39+
const router = express.Router();
40+
for (const apiName of Object.keys(spec)) {
41+
const resource = spec[apiName] as Spec[string];
42+
for (const method of Object.keys(resource)) {
43+
if (!isHttpVerb(method)) {
44+
continue;
5845
}
59-
}
46+
const httpRoute: HttpRoute = resource[method]!;
47+
const routeHandler = routeHandlers[apiName]![method]!;
48+
const expressRouteHandler = decodeRequestAndEncodeResponse(
49+
apiName,
50+
httpRoute,
51+
// FIXME: TS is complaining that `routeHandler` is not necessarily guaranteed to be a
52+
// `ServiceFunction`, because subtypes of Spec[string][string] can have arbitrary extra keys.
53+
getServiceFunction(routeHandler as any),
54+
encoder,
55+
);
56+
const handlers = [...getMiddleware(routeHandler), expressRouteHandler];
6057

61-
app.use(router);
58+
const expressPath = apiTsPathToExpress(httpRoute.path);
59+
router[method](expressPath, handlers);
60+
}
61+
}
6262

63-
return app;
64-
};
63+
return router;
64+
}
6565

66-
export const createServer = createServerWithResponseEncoder(defaultResponseEncoder);
66+
export const createServer = <Spec extends ApiSpec>(
67+
spec: Spec,
68+
configureExpressApplication: (app: express.Application) => {
69+
[ApiName in keyof Spec]: {
70+
[Method in keyof Spec[ApiName]]: RouteHandler<Spec[ApiName][Method]>;
71+
};
72+
},
73+
) => {
74+
const app = express();
75+
const routeHandlers = configureExpressApplication(app);
76+
const router = routerForApiSpec({ spec, routeHandlers });
77+
app.use(router);
78+
return app;
79+
};

0 commit comments

Comments
 (0)