From 54a45ebc27d5cf13e8fe52b6869d38ebf5716cc1 Mon Sep 17 00:00:00 2001 From: Martin Sosic Date: Tue, 23 Jan 2024 21:56:29 +0100 Subject: [PATCH] Moved middleware configuration to SDK + fixed sdk/server/config. --- .../data/Generator/templates/sdk/package.json | 2 +- .../sdk/server/middleware/globalMiddleware.ts | 6 ++ .../templates/sdk/server/middleware/index.ts | 1 + .../server/src/middleware/globalMiddleware.ts | 6 +- waspc/examples/todo-typescript/main.wasp | 8 +++ .../todo-typescript/package-lock.json | 72 +++++++++++++++++++ waspc/examples/todo-typescript/package.json | 13 ++-- .../todo-typescript/src/serverSetup.ts | 23 ++++++ waspc/src/Wasp/Generator/SdkGenerator.hs | 8 +++ 9 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 waspc/data/Generator/templates/sdk/server/middleware/globalMiddleware.ts create mode 100644 waspc/data/Generator/templates/sdk/server/middleware/index.ts create mode 100644 waspc/examples/todo-typescript/src/serverSetup.ts diff --git a/waspc/data/Generator/templates/sdk/package.json b/waspc/data/Generator/templates/sdk/package.json index 91de08a021..47ed5f58af 100644 --- a/waspc/data/Generator/templates/sdk/package.json +++ b/waspc/data/Generator/templates/sdk/package.json @@ -88,7 +88,7 @@ "./universal/validators": "./dist/universal/validators.js", {=! Used by our code, uncodumented (but accessible) for users. =} "./server/dbClient": "./dist/server/dbClient.js", - {=! Used by our code, uncodumented (but accessible) for users. =} + {=! Used by users and by our code, documented. =} "./server/config": "./dist/server/config.js", {=! Parts are used by users, documented. Parts are probably used by our code, undocumented (but accessible). =} "./server/utils": "./dist/server/utils.js", diff --git a/waspc/data/Generator/templates/sdk/server/middleware/globalMiddleware.ts b/waspc/data/Generator/templates/sdk/server/middleware/globalMiddleware.ts new file mode 100644 index 0000000000..28c2631149 --- /dev/null +++ b/waspc/data/Generator/templates/sdk/server/middleware/globalMiddleware.ts @@ -0,0 +1,6 @@ +import { type RequestHandler } from 'express' + +export type MiddlewareConfig = Map + +export type MiddlewareConfigFn = (middlewareConfig: MiddlewareConfig) => MiddlewareConfig + diff --git a/waspc/data/Generator/templates/sdk/server/middleware/index.ts b/waspc/data/Generator/templates/sdk/server/middleware/index.ts new file mode 100644 index 0000000000..50996ec27d --- /dev/null +++ b/waspc/data/Generator/templates/sdk/server/middleware/index.ts @@ -0,0 +1 @@ +export * from './globalMiddleware.js' diff --git a/waspc/data/Generator/templates/server/src/middleware/globalMiddleware.ts b/waspc/data/Generator/templates/server/src/middleware/globalMiddleware.ts index be6fec4dff..7f576b1353 100644 --- a/waspc/data/Generator/templates/server/src/middleware/globalMiddleware.ts +++ b/waspc/data/Generator/templates/server/src/middleware/globalMiddleware.ts @@ -6,6 +6,8 @@ import cors from 'cors' import helmet from 'helmet' import config from 'wasp/server/config' +import type { MiddlewareConfig, MiddlewareConfigFn } from 'wasp/server/middleware' +export type { MiddlewareConfig, MiddlewareConfigFn } from 'wasp/server/middleware' {=# globalMiddlewareConfigFn.isDefined =} {=& globalMiddlewareConfigFn.importStatement =} @@ -14,10 +16,6 @@ import config from 'wasp/server/config' const {=& globalMiddlewareConfigFn.importAlias =} = (mc: MiddlewareConfig) => mc {=/ globalMiddlewareConfigFn.isDefined =} -export type MiddlewareConfig = Map - -export type MiddlewareConfigFn = (middlewareConfig: MiddlewareConfig) => MiddlewareConfig - // This is the set of middleware Wasp supplies by default. // NOTE: Remember to update the docs of these change. const defaultGlobalMiddlewareConfig: MiddlewareConfig = new Map([ diff --git a/waspc/examples/todo-typescript/main.wasp b/waspc/examples/todo-typescript/main.wasp index 70f2b63374..80cb6d9354 100644 --- a/waspc/examples/todo-typescript/main.wasp +++ b/waspc/examples/todo-typescript/main.wasp @@ -40,6 +40,9 @@ app TodoTypescript { ], system: PostgreSQL }, + server: { + middlewareConfigFn: import { serverMiddlewareFn } from "@src/serverSetup.js" + } } // Use Prisma Schema Language (PSL) to define our entities: https://www.prisma.io/docs/concepts/components/prisma-schema @@ -121,3 +124,8 @@ api fooBar { fn: import { fooBar } from "@src/api.js", httpRoute: (GET, "/foo/bar") } + +apiNamespace fooBarNamespace { + middlewareConfigFn: import { fooBarNamespace } from "@src/serverSetup.js", + path: "/foo/bar" +} \ No newline at end of file diff --git a/waspc/examples/todo-typescript/package-lock.json b/waspc/examples/todo-typescript/package-lock.json index a0d6c45fec..fa14ee42d3 100644 --- a/waspc/examples/todo-typescript/package-lock.json +++ b/waspc/examples/todo-typescript/package-lock.json @@ -6,10 +6,13 @@ "": { "name": "prototype", "dependencies": { + "cors": "^2.8.5", "react": "^18.2.0", "wasp": "file:.wasp/out/sdk/wasp" }, "devDependencies": { + "@types/cors": "^2.8.5", + "@types/express": "^4.17.13", "@types/react": "^18.0.37", "prisma": "4.16.2", "typescript": "^5.1.0", @@ -142,6 +145,46 @@ "integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw==", "dev": true }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, "node_modules/@types/express-serve-static-core": { "version": "4.17.41", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", @@ -153,6 +196,12 @@ "@types/send": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -208,6 +257,17 @@ "@types/node": "*" } }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -346,6 +406,18 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", diff --git a/waspc/examples/todo-typescript/package.json b/waspc/examples/todo-typescript/package.json index a3aceaf30c..bad70f6765 100644 --- a/waspc/examples/todo-typescript/package.json +++ b/waspc/examples/todo-typescript/package.json @@ -1,13 +1,16 @@ { "name": "prototype", "dependencies": { - "wasp": "file:.wasp/out/sdk/wasp", - "react": "^18.2.0" + "cors": "^2.8.5", + "react": "^18.2.0", + "wasp": "file:.wasp/out/sdk/wasp" }, "devDependencies": { - "typescript": "^5.1.0", - "vite": "^4.3.9", + "@types/cors": "^2.8.5", + "@types/express": "^4.17.13", "@types/react": "^18.0.37", - "prisma": "4.16.2" + "prisma": "4.16.2", + "typescript": "^5.1.0", + "vite": "^4.3.9" } } diff --git a/waspc/examples/todo-typescript/src/serverSetup.ts b/waspc/examples/todo-typescript/src/serverSetup.ts new file mode 100644 index 0000000000..968dfe8514 --- /dev/null +++ b/waspc/examples/todo-typescript/src/serverSetup.ts @@ -0,0 +1,23 @@ +import express from 'express' +import cors from 'cors' +import type { MiddlewareConfigFn } from 'wasp/server/middleware' +import config from 'wasp/server/config' + +export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => { + // Example of adding an extra domains to CORS. + middlewareConfig.set('cors', cors({ + origin: [config.frontendUrl, 'https://example1.com', 'https://example2.com'] + })) + return middlewareConfig +} + +export const fooBarNamespace: MiddlewareConfigFn = (middlewareConfig) => { + const customMiddleware: express.RequestHandler = (_req, _res, next) => { + console.log('fooBarNamespaceMiddlewareFn: custom middleware') + next() + } + + middlewareConfig.set('custom.middleware', customMiddleware) + + return middlewareConfig +} diff --git a/waspc/src/Wasp/Generator/SdkGenerator.hs b/waspc/src/Wasp/Generator/SdkGenerator.hs index c0d913a17a..60109edb50 100644 --- a/waspc/src/Wasp/Generator/SdkGenerator.hs +++ b/waspc/src/Wasp/Generator/SdkGenerator.hs @@ -93,6 +93,7 @@ genSdkReal spec = <++> genExternalCodeDir (AS.externalCodeFiles spec) <++> genEntitiesAndServerTypesDirs spec <++> genApis spec + <++> genMiddleware spec where genFileCopy = return . C.mkTmplFd @@ -286,3 +287,10 @@ genServerUtils :: AppSpec -> Generator FileDraft genServerUtils spec = return $ C.mkTmplFdWithData [relfile|server/utils.ts|] tmplData where tmplData = object ["isAuthEnabled" .= (isAuthEnabled spec :: Bool)] + +genMiddleware :: AppSpec -> Generator [FileDraft] +genMiddleware _spec = + sequence + [ return $ C.mkTmplFd [relfile|server/middleware/index.ts|], + return $ C.mkTmplFd [relfile|server/middleware/globalMiddleware.ts|] + ]