diff --git a/examples/bun-graphql-streaming-zip/README.md b/examples/bun-graphql-streaming-zip/README.md new file mode 100644 index 0000000..e56fc96 --- /dev/null +++ b/examples/bun-graphql-streaming-zip/README.md @@ -0,0 +1,47 @@ +# Bun Server with graphql response streaming example + +This example show how to use the Lambda Web Adapter to run a bun server application with response streaming via a [AWS Lambda](https://aws.amazon.com/lambda) Function URL. + +### Build and Deploy + +Run the following commands to build and deploy the application to lambda. +``` + +```bash +sam build + +sam deploy --guided +``` +When the deployment completes, the Function URL will appear in the output list, which is the entrypoint for accessing + +### Verify it works + +When you open the Function URL in a browser: + +1. Write and execute GraphQL queries in the left panel +2. See the results in the right panel +3. Explore the API documentation using the "Docs" button + +Try this sample subscription query to test streaming: + +```graphql +subscription { + stream(addition: "testing") +} +``` + +You'll see each character stream in one by one with a small delay between them. + +For command line testing, you can use curl: + +```bash +curl --no-buffer -N \ + -H "Content-Type: application/json" \ + -H "Accept: text/event-stream" \ + -d '{"query": "subscription { stream(addition: \"test\") }"}' \ + https://your-function-url.lambda-url.us-east-1.on.aws/graphql +``` + +### Thanks + +@sumcoding diff --git a/examples/bun-graphql-streaming-zip/app/.gitignore b/examples/bun-graphql-streaming-zip/app/.gitignore new file mode 100644 index 0000000..a14702c --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/examples/bun-graphql-streaming-zip/app/Makefile b/examples/bun-graphql-streaming-zip/app/Makefile new file mode 100644 index 0000000..eb5781b --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/Makefile @@ -0,0 +1,11 @@ +.PHONY: build-BunGraphqlFunction build + +build-BunGraphqlFunction: + bun install + bun run build + mkdir -p $(ARTIFACTS_DIR) + cp run.sh out/ + cp -r out/* $(ARTIFACTS_DIR)/ + +build: + $(MAKE) build-BunGraphqlFunction diff --git a/examples/bun-graphql-streaming-zip/app/bun.lock b/examples/bun-graphql-streaming-zip/app/bun.lock new file mode 100644 index 0000000..d10eaf3 --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/bun.lock @@ -0,0 +1,101 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "yoga-graphql-streaming-zip", + "dependencies": { + "cross-env": "^7.0.3", + "graphql": "^16.10.0", + "graphql-yoga": "^5.13.1", + }, + "devDependencies": { + "@types/bun": "latest", + "typescript": "^5.8.2", + }, + "peerDependencies": { + "typescript": "^5", + }, + }, + }, + "packages": { + "@envelop/core": ["@envelop/core@5.2.3", "", { "dependencies": { "@envelop/instrumentation": "^1.0.0", "@envelop/types": "^5.2.1", "@whatwg-node/promise-helpers": "^1.2.4", "tslib": "^2.5.0" } }, "sha512-KfoGlYD/XXQSc3BkM1/k15+JQbkQ4ateHazeZoWl9P71FsLTDXSjGy6j7QqfhpIDSbxNISqhPMfZHYSbDFOofQ=="], + + "@envelop/instrumentation": ["@envelop/instrumentation@1.0.0", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.2.1", "tslib": "^2.5.0" } }, "sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw=="], + + "@envelop/types": ["@envelop/types@5.2.1", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.5.0" } }, "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg=="], + + "@graphql-tools/executor": ["@graphql-tools/executor@1.4.6", "", { "dependencies": { "@graphql-tools/utils": "^10.8.6", "@graphql-typed-document-node/core": "^3.2.0", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-vtwuotFe9DR1gZ2VXYRxcL6GVP6dYUHWibA9JNOkdRiwCW/icTY7oU9xUVITnOAfjNh9k8Z43kZmiyr2aMopVA=="], + + "@graphql-tools/merge": ["@graphql-tools/merge@9.0.24", "", { "dependencies": { "@graphql-tools/utils": "^10.8.6", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-NzWx/Afl/1qHT3Nm1bghGG2l4jub28AdvtG11PoUlmjcIjnFBJMv4vqL0qnxWe8A82peWo4/TkVdjJRLXwgGEw=="], + + "@graphql-tools/schema": ["@graphql-tools/schema@10.0.23", "", { "dependencies": { "@graphql-tools/merge": "^9.0.24", "@graphql-tools/utils": "^10.8.6", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-aEGVpd1PCuGEwqTXCStpEkmheTHNdMayiIKH1xDWqYp9i8yKv9FRDgkGrY4RD8TNxnf7iII+6KOBGaJ3ygH95A=="], + + "@graphql-tools/utils": ["@graphql-tools/utils@10.8.6", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "dset": "^3.1.4", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-Alc9Vyg0oOsGhRapfL3xvqh1zV8nKoFUdtLhXX7Ki4nClaIJXckrA86j+uxEuG3ic6j4jlM1nvcWXRn/71AVLQ=="], + + "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], + + "@graphql-yoga/logger": ["@graphql-yoga/logger@2.0.1", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA=="], + + "@graphql-yoga/subscription": ["@graphql-yoga/subscription@5.0.3", "", { "dependencies": { "@graphql-yoga/typed-event-target": "^3.0.2", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/events": "^0.1.0", "tslib": "^2.8.1" } }, "sha512-xLGEataxCULjL9rlTCVFL1IW2E90TnDIL+mE4lZBi9X92jc6s+Q+jk6Ax3I98kryCJh0UMiwjit7CaIIczTiJg=="], + + "@graphql-yoga/typed-event-target": ["@graphql-yoga/typed-event-target@3.0.2", "", { "dependencies": { "@repeaterjs/repeater": "^3.0.4", "tslib": "^2.8.1" } }, "sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA=="], + + "@repeaterjs/repeater": ["@repeaterjs/repeater@3.0.6", "", {}, "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA=="], + + "@types/bun": ["@types/bun@1.2.5", "", { "dependencies": { "bun-types": "1.2.5" } }, "sha512-w2OZTzrZTVtbnJew1pdFmgV99H0/L+Pvw+z1P67HaR18MHOzYnTYOi6qzErhK8HyT+DB782ADVPPE92Xu2/Opg=="], + + "@types/node": ["@types/node@22.13.10", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw=="], + + "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="], + + "@whatwg-node/disposablestack": ["@whatwg-node/disposablestack@0.0.6", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.6.3" } }, "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw=="], + + "@whatwg-node/events": ["@whatwg-node/events@0.1.2", "", { "dependencies": { "tslib": "^2.6.3" } }, "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ=="], + + "@whatwg-node/fetch": ["@whatwg-node/fetch@0.10.5", "", { "dependencies": { "@whatwg-node/node-fetch": "^0.7.11", "urlpattern-polyfill": "^10.0.0" } }, "sha512-+yFJU3hmXPAHJULwx0VzCIsvr/H0lvbPvbOH3areOH3NAuCxCwaJsQ8w6/MwwMcvEWIynSsmAxoyaH04KeosPg=="], + + "@whatwg-node/node-fetch": ["@whatwg-node/node-fetch@0.7.14", "", { "dependencies": { "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/promise-helpers": "^1.2.5", "busboy": "^1.6.0", "tslib": "^2.6.3" } }, "sha512-GMCUrFq3gXQSgWMnEBMaQUxh1rd1vi3Kp4MRQT6UKbnRycm4QmUSxp8ZIySxLQ96cpyBvonEH0BYmdQe/pWy8A=="], + + "@whatwg-node/promise-helpers": ["@whatwg-node/promise-helpers@1.3.0", "", { "dependencies": { "tslib": "^2.6.3" } }, "sha512-486CouizxHXucj8Ky153DDragfkMcHtVEToF5Pn/fInhUUSiCmt9Q4JVBa6UK5q4RammFBtGQ4C9qhGlXU9YbA=="], + + "@whatwg-node/server": ["@whatwg-node/server@0.10.1", "", { "dependencies": { "@envelop/instrumentation": "^1.0.0", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/fetch": "^0.10.5", "@whatwg-node/promise-helpers": "^1.2.3", "tslib": "^2.6.3" } }, "sha512-SKZjZAhQe8o34pDHUDFn5PV5Otq/gaj/A6AlQ6Sa4+A12YBO0znKKwfoCwGxv/BSRRx0zUqLdI8fZ0ui+EyUlw=="], + + "bun-types": ["bun-types@1.2.5", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-3oO6LVGGRRKI4kHINx5PIdIgnLRb7l/SprhzqXapmoYkFl5m4j6EvALvbDVuuBFaamB46Ap6HCUxIXNLCGy+tg=="], + + "busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="], + + "cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="], + + "cross-inspect": ["cross-inspect@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], + + "graphql": ["graphql@16.10.0", "", {}, "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ=="], + + "graphql-yoga": ["graphql-yoga@5.13.2", "", { "dependencies": { "@envelop/core": "^5.2.3", "@envelop/instrumentation": "^1.0.0", "@graphql-tools/executor": "^1.4.0", "@graphql-tools/schema": "^10.0.11", "@graphql-tools/utils": "^10.6.2", "@graphql-yoga/logger": "^2.0.1", "@graphql-yoga/subscription": "^5.0.3", "@whatwg-node/fetch": "^0.10.5", "@whatwg-node/promise-helpers": "^1.2.4", "@whatwg-node/server": "^0.10.1", "dset": "^3.1.4", "lru-cache": "^10.0.0", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^15.2.0 || ^16.0.0" } }, "sha512-ZXhIoAPCV2K2ozwpxDL1ZXhhI2SvIp3hJMaSRaHcojLGE9w9iV8oYGPnZKcV5eisF3VE13RcIF4Ys6TTkU338Q=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], + + "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], + + "urlpattern-polyfill": ["urlpattern-polyfill@10.0.0", "", {}, "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + } +} diff --git a/examples/bun-graphql-streaming-zip/app/package.json b/examples/bun-graphql-streaming-zip/app/package.json new file mode 100644 index 0000000..4240e20 --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/package.json @@ -0,0 +1,24 @@ +{ + "name": "graphql-yoga", + "version": "0.1.0", + "private": true, + "type": "module", + "module": "server.ts", + "scripts": { + "dev": "bun run server.ts", + "build": "bun build --target=bun --entrypoints ./server.ts --outfile=./out/server.js", + "typecheck": "tsc" + }, + "dependencies": { + "cross-env": "^7.0.3", + "graphql": "^16.10.0", + "graphql-yoga": "^5.13.1" + }, + "devDependencies": { + "@types/bun": "latest", + "typescript": "^5.8.2" + }, + "peerDependencies": { + "typescript": "^5" + } +} diff --git a/examples/bun-graphql-streaming-zip/app/run.sh b/examples/bun-graphql-streaming-zip/app/run.sh new file mode 100755 index 0000000..9d90287 --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/run.sh @@ -0,0 +1,3 @@ +#! /bin/sh +export PATH="/opt/bin:${PATH}" +exec bun run server.js diff --git a/examples/bun-graphql-streaming-zip/app/schema.ts b/examples/bun-graphql-streaming-zip/app/schema.ts new file mode 100644 index 0000000..11d722b --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/schema.ts @@ -0,0 +1,39 @@ +import { createSchema } from 'graphql-yoga' + +const typeDefs = /* GraphQL */ ` + type Query { + hello(addition: String): String! + } + type Subscription { + stream(addition: String): String! + } +` +const resolvers = { + Query: { + hello: async (_: any, { addition }: { addition: string }) => { + console.log(`Received addition: ${addition}`); + return `Hello, ${addition || 'Lambda!'}!` + }, + }, + Subscription: { + stream: { + subscribe: async function* (_: any, { addition }: { addition: string }) { + const message = `This is streaming from Lambda! ${addition || ''}\n`; + process.stdout.write("Streaming: "); + for (const char of message) { + process.stdout.write(char); + yield char; + // Sleep for 100ms between characters + await new Promise(resolve => setTimeout(resolve, 100)); + } + }, + resolve: (payload: any) => payload + }, + } +} + +export const schema = createSchema({ + typeDefs, + resolvers +}) + diff --git a/examples/bun-graphql-streaming-zip/app/server.ts b/examples/bun-graphql-streaming-zip/app/server.ts new file mode 100644 index 0000000..b3bf91b --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/server.ts @@ -0,0 +1,18 @@ +import { createYoga } from 'graphql-yoga' +import { schema } from './schema.js' + +// Create a Yoga instance with a GraphQL schema. +const yoga = createYoga({ schema }) + +// Pass it into a server to hook into request handlers. +const server = Bun.serve({ + fetch: yoga +}) + +// Start the server and you're done! +console.info( + `Server is running on ${new URL( + yoga.graphqlEndpoint, + `http://${server.hostname}:${server.port}` + )}` +) diff --git a/examples/bun-graphql-streaming-zip/app/tsconfig.json b/examples/bun-graphql-streaming-zip/app/tsconfig.json new file mode 100644 index 0000000..ab0f0b0 --- /dev/null +++ b/examples/bun-graphql-streaming-zip/app/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["esnext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/examples/bun-graphql-streaming-zip/template.yaml b/examples/bun-graphql-streaming-zip/template.yaml new file mode 100644 index 0000000..961ed0d --- /dev/null +++ b/examples/bun-graphql-streaming-zip/template.yaml @@ -0,0 +1,44 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: > + Bun graphql response streaming + +# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst +Globals: + Function: + Timeout: 60 + +Resources: + BunGraphqlFunction: + Type: AWS::Serverless::Function + Metadata: + BuildMethod: makefile + Properties: + CodeUri: app/ + Handler: run.sh + Runtime: provided.al2023 + Architectures: + - arm64 + MemorySize: 256 + Environment: + Variables: + AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap + AWS_LWA_INVOKE_MODE: response_stream + PORT: 3000 + Layers: + - !Sub arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerArm64:24 + - !Sub arn:aws:lambda:us-east-1:582637575117:layer:BunRuntimeArm64:1 + FunctionUrlConfig: + AuthType: NONE + InvokeMode: RESPONSE_STREAM + +Outputs: + BunGraphqlFunctionUrl: + Description: "Function URL for Bun Graphql function" + Value: !Join + - '' + - - !GetAtt BunGraphqlFunctionUrl.FunctionUrl + - 'graphql' + BunGraphqlFunction: + Description: "Bun Graphql Lambda Function ARN" + Value: !GetAtt BunGraphqlFunction.Arn diff --git a/examples/bun-graphql-zip/README.md b/examples/bun-graphql-zip/README.md new file mode 100644 index 0000000..813ae94 --- /dev/null +++ b/examples/bun-graphql-zip/README.md @@ -0,0 +1,48 @@ +# Bun Server with graphql API Gateway example + +This example show how to use Lambda Web Adapter to run a bun server application with via [AWS Lambda](https://aws.amazon.com/lambda) and API Gateway. + +### Build and Deploy + +Run the following commands to build and deploy the application to lambda. +``` + +```bash +sam build + +sam deploy --guided +``` +When the deployment completes, the API URL will appear in the output list, which is the entrypoint for accessing + +### Verify it works + +When you open the API URL in a browser: + +1. Write and execute GraphQL queries in the left panel +2. See the results in the right panel +3. Explore the API documentation using the "Docs" button + +Try this sample query to test: + +```graphql +query { + feed { + id + description + url + } +} +``` + +For command line testing, you can use curl: + +```bash +curl -N \ + -H "Content-Type: application/json" \ + -d '{"query": "query { feed {id url description} }"}' \ + https://.execute-api.us-east-1.amazonaws.com/graphql +``` + +### Thanks + +@sumcoding diff --git a/examples/bun-graphql-zip/app/.gitignore b/examples/bun-graphql-zip/app/.gitignore new file mode 100644 index 0000000..98a520a --- /dev/null +++ b/examples/bun-graphql-zip/app/.gitignore @@ -0,0 +1,13 @@ +/dist + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### VS Code ### +.vscode/ + +.aws-sam +node_modules diff --git a/examples/bun-graphql-zip/app/Makefile b/examples/bun-graphql-zip/app/Makefile new file mode 100644 index 0000000..eb5781b --- /dev/null +++ b/examples/bun-graphql-zip/app/Makefile @@ -0,0 +1,11 @@ +.PHONY: build-BunGraphqlFunction build + +build-BunGraphqlFunction: + bun install + bun run build + mkdir -p $(ARTIFACTS_DIR) + cp run.sh out/ + cp -r out/* $(ARTIFACTS_DIR)/ + +build: + $(MAKE) build-BunGraphqlFunction diff --git a/examples/bun-graphql-zip/app/bun.lock b/examples/bun-graphql-zip/app/bun.lock new file mode 100644 index 0000000..7c8f44c --- /dev/null +++ b/examples/bun-graphql-zip/app/bun.lock @@ -0,0 +1,101 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "graphql-yoga-api", + "dependencies": { + "cross-env": "^7.0.3", + "graphql": "^16.10.0", + "graphql-yoga": "^5.13.1", + }, + "devDependencies": { + "@types/bun": "latest", + "typescript": "^5.8.2", + }, + "peerDependencies": { + "typescript": "^5", + }, + }, + }, + "packages": { + "@envelop/core": ["@envelop/core@5.2.3", "", { "dependencies": { "@envelop/instrumentation": "^1.0.0", "@envelop/types": "^5.2.1", "@whatwg-node/promise-helpers": "^1.2.4", "tslib": "^2.5.0" } }, "sha512-KfoGlYD/XXQSc3BkM1/k15+JQbkQ4ateHazeZoWl9P71FsLTDXSjGy6j7QqfhpIDSbxNISqhPMfZHYSbDFOofQ=="], + + "@envelop/instrumentation": ["@envelop/instrumentation@1.0.0", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.2.1", "tslib": "^2.5.0" } }, "sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw=="], + + "@envelop/types": ["@envelop/types@5.2.1", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.5.0" } }, "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg=="], + + "@graphql-tools/executor": ["@graphql-tools/executor@1.4.6", "", { "dependencies": { "@graphql-tools/utils": "^10.8.6", "@graphql-typed-document-node/core": "^3.2.0", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-vtwuotFe9DR1gZ2VXYRxcL6GVP6dYUHWibA9JNOkdRiwCW/icTY7oU9xUVITnOAfjNh9k8Z43kZmiyr2aMopVA=="], + + "@graphql-tools/merge": ["@graphql-tools/merge@9.0.24", "", { "dependencies": { "@graphql-tools/utils": "^10.8.6", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-NzWx/Afl/1qHT3Nm1bghGG2l4jub28AdvtG11PoUlmjcIjnFBJMv4vqL0qnxWe8A82peWo4/TkVdjJRLXwgGEw=="], + + "@graphql-tools/schema": ["@graphql-tools/schema@10.0.23", "", { "dependencies": { "@graphql-tools/merge": "^9.0.24", "@graphql-tools/utils": "^10.8.6", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-aEGVpd1PCuGEwqTXCStpEkmheTHNdMayiIKH1xDWqYp9i8yKv9FRDgkGrY4RD8TNxnf7iII+6KOBGaJ3ygH95A=="], + + "@graphql-tools/utils": ["@graphql-tools/utils@10.8.6", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "dset": "^3.1.4", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-Alc9Vyg0oOsGhRapfL3xvqh1zV8nKoFUdtLhXX7Ki4nClaIJXckrA86j+uxEuG3ic6j4jlM1nvcWXRn/71AVLQ=="], + + "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], + + "@graphql-yoga/logger": ["@graphql-yoga/logger@2.0.1", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA=="], + + "@graphql-yoga/subscription": ["@graphql-yoga/subscription@5.0.3", "", { "dependencies": { "@graphql-yoga/typed-event-target": "^3.0.2", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/events": "^0.1.0", "tslib": "^2.8.1" } }, "sha512-xLGEataxCULjL9rlTCVFL1IW2E90TnDIL+mE4lZBi9X92jc6s+Q+jk6Ax3I98kryCJh0UMiwjit7CaIIczTiJg=="], + + "@graphql-yoga/typed-event-target": ["@graphql-yoga/typed-event-target@3.0.2", "", { "dependencies": { "@repeaterjs/repeater": "^3.0.4", "tslib": "^2.8.1" } }, "sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA=="], + + "@repeaterjs/repeater": ["@repeaterjs/repeater@3.0.6", "", {}, "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA=="], + + "@types/bun": ["@types/bun@1.2.5", "", { "dependencies": { "bun-types": "1.2.5" } }, "sha512-w2OZTzrZTVtbnJew1pdFmgV99H0/L+Pvw+z1P67HaR18MHOzYnTYOi6qzErhK8HyT+DB782ADVPPE92Xu2/Opg=="], + + "@types/node": ["@types/node@22.13.11", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g=="], + + "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="], + + "@whatwg-node/disposablestack": ["@whatwg-node/disposablestack@0.0.6", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.6.3" } }, "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw=="], + + "@whatwg-node/events": ["@whatwg-node/events@0.1.2", "", { "dependencies": { "tslib": "^2.6.3" } }, "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ=="], + + "@whatwg-node/fetch": ["@whatwg-node/fetch@0.10.5", "", { "dependencies": { "@whatwg-node/node-fetch": "^0.7.11", "urlpattern-polyfill": "^10.0.0" } }, "sha512-+yFJU3hmXPAHJULwx0VzCIsvr/H0lvbPvbOH3areOH3NAuCxCwaJsQ8w6/MwwMcvEWIynSsmAxoyaH04KeosPg=="], + + "@whatwg-node/node-fetch": ["@whatwg-node/node-fetch@0.7.14", "", { "dependencies": { "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/promise-helpers": "^1.2.5", "busboy": "^1.6.0", "tslib": "^2.6.3" } }, "sha512-GMCUrFq3gXQSgWMnEBMaQUxh1rd1vi3Kp4MRQT6UKbnRycm4QmUSxp8ZIySxLQ96cpyBvonEH0BYmdQe/pWy8A=="], + + "@whatwg-node/promise-helpers": ["@whatwg-node/promise-helpers@1.3.0", "", { "dependencies": { "tslib": "^2.6.3" } }, "sha512-486CouizxHXucj8Ky153DDragfkMcHtVEToF5Pn/fInhUUSiCmt9Q4JVBa6UK5q4RammFBtGQ4C9qhGlXU9YbA=="], + + "@whatwg-node/server": ["@whatwg-node/server@0.10.2", "", { "dependencies": { "@envelop/instrumentation": "^1.0.0", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/fetch": "^0.10.5", "@whatwg-node/promise-helpers": "^1.2.3", "tslib": "^2.6.3" } }, "sha512-PrqRhJgqCXNhfdhSN8XaVkuVnzhTQz0R17DZYTjgP5dXFQnrsNQnooBRTvdPFAjx5UmJ9fHPaNqRXm9Zc1b9lQ=="], + + "bun-types": ["bun-types@1.2.5", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-3oO6LVGGRRKI4kHINx5PIdIgnLRb7l/SprhzqXapmoYkFl5m4j6EvALvbDVuuBFaamB46Ap6HCUxIXNLCGy+tg=="], + + "busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="], + + "cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="], + + "cross-inspect": ["cross-inspect@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], + + "graphql": ["graphql@16.10.0", "", {}, "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ=="], + + "graphql-yoga": ["graphql-yoga@5.13.2", "", { "dependencies": { "@envelop/core": "^5.2.3", "@envelop/instrumentation": "^1.0.0", "@graphql-tools/executor": "^1.4.0", "@graphql-tools/schema": "^10.0.11", "@graphql-tools/utils": "^10.6.2", "@graphql-yoga/logger": "^2.0.1", "@graphql-yoga/subscription": "^5.0.3", "@whatwg-node/fetch": "^0.10.5", "@whatwg-node/promise-helpers": "^1.2.4", "@whatwg-node/server": "^0.10.1", "dset": "^3.1.4", "lru-cache": "^10.0.0", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^15.2.0 || ^16.0.0" } }, "sha512-ZXhIoAPCV2K2ozwpxDL1ZXhhI2SvIp3hJMaSRaHcojLGE9w9iV8oYGPnZKcV5eisF3VE13RcIF4Ys6TTkU338Q=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], + + "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], + + "urlpattern-polyfill": ["urlpattern-polyfill@10.0.0", "", {}, "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + } +} diff --git a/examples/bun-graphql-zip/app/package.json b/examples/bun-graphql-zip/app/package.json new file mode 100644 index 0000000..012370a --- /dev/null +++ b/examples/bun-graphql-zip/app/package.json @@ -0,0 +1,24 @@ +{ + "name": "graphql-yoga-api", + "version": "0.1.0", + "private": true, + "type": "module", + "module": "server.ts", + "scripts": { + "dev": "bun run server.ts", + "build": "bun build --target=bun --entrypoints ./server.ts --outfile=./out/server.js", + "typecheck": "tsc" + }, + "dependencies": { + "cross-env": "^7.0.3", + "graphql": "^16.10.0", + "graphql-yoga": "^5.13.1" + }, + "devDependencies": { + "@types/bun": "latest", + "typescript": "^5.8.2" + }, + "peerDependencies": { + "typescript": "^5" + } +} diff --git a/examples/bun-graphql-zip/app/run.sh b/examples/bun-graphql-zip/app/run.sh new file mode 100755 index 0000000..9d90287 --- /dev/null +++ b/examples/bun-graphql-zip/app/run.sh @@ -0,0 +1,3 @@ +#! /bin/sh +export PATH="/opt/bin:${PATH}" +exec bun run server.js diff --git a/examples/bun-graphql-zip/app/schema.ts b/examples/bun-graphql-zip/app/schema.ts new file mode 100644 index 0000000..54dbe9d --- /dev/null +++ b/examples/bun-graphql-zip/app/schema.ts @@ -0,0 +1,69 @@ +import { createSchema } from 'graphql-yoga' + +const typeDefs = /* GraphQL */ ` + type Query { + hello(addition: String): String! + info: String! + feed: [Link!]! + } + type Mutation { + postLink(url: String!, description: String!): Link! + } + type Link { + id: ID! + description: String! + url: String! + } +` +type Link = { + id: string + url: string + description: string +} + +const links: Link[] = [ + { + id: 'link-0', + url: 'www.howtographql.com', + description: 'Fullstack tutorial for GraphQL' + } +] + +const resolvers = { + Query: { + hello: async (_: any, { addition }: { addition: string }) => { + console.log(`Received addition: ${addition}`); + return `Hello, ${addition || 'Lambda!'}!` + }, + info: () => `This is the API of a Hackernews Clone`, + feed: () => links + }, + Mutation: { + postLink: (parent: unknown, args: { description: string; url: string }) => { + // 1 + let idCount = links.length + + // 2 + const link: Link = { + id: `link-${idCount}`, + description: args.description, + url: args.url + } + + links.push(link) + + return link + } + }, + Link: { + id: (parent: Link) => parent.id, + description: (parent: Link) => parent.description, + url: (parent: Link) => parent.url + } +} + +export const schema = createSchema({ + typeDefs, + resolvers +}) + diff --git a/examples/bun-graphql-zip/app/server.ts b/examples/bun-graphql-zip/app/server.ts new file mode 100644 index 0000000..b3bf91b --- /dev/null +++ b/examples/bun-graphql-zip/app/server.ts @@ -0,0 +1,18 @@ +import { createYoga } from 'graphql-yoga' +import { schema } from './schema.js' + +// Create a Yoga instance with a GraphQL schema. +const yoga = createYoga({ schema }) + +// Pass it into a server to hook into request handlers. +const server = Bun.serve({ + fetch: yoga +}) + +// Start the server and you're done! +console.info( + `Server is running on ${new URL( + yoga.graphqlEndpoint, + `http://${server.hostname}:${server.port}` + )}` +) diff --git a/examples/bun-graphql-zip/app/tsconfig.json b/examples/bun-graphql-zip/app/tsconfig.json new file mode 100644 index 0000000..ab0f0b0 --- /dev/null +++ b/examples/bun-graphql-zip/app/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["esnext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/examples/bun-graphql-zip/template.yaml b/examples/bun-graphql-zip/template.yaml new file mode 100644 index 0000000..97e89b3 --- /dev/null +++ b/examples/bun-graphql-zip/template.yaml @@ -0,0 +1,51 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: > + Bun Graphql Api + +# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst +Globals: + Function: + Timeout: 60 + +Resources: + BunGraphqlFunction: + Type: AWS::Serverless::Function + Metadata: + BuildMethod: makefile + Properties: + CodeUri: app/ + Handler: run.sh + Runtime: provided.al2023 + Architectures: + - x86_64 + MemorySize: 256 + Environment: + Variables: + AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap + PORT: 3000 + Layers: + - !Sub arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerX86:24 + - !Sub arn:aws:lambda:us-east-1:582637575117:layer:BunRuntimeX64:1 + Events: + RootEvent: + Type: HttpApi + Properties: + Path: / + Method: any + ProxyEvent: + Type: HttpApi + Properties: + Path: /{proxy+} + Method: any + +Outputs: + BunGraphqlApi: + Description: "API Gateway endpoint URL for Prod stage for Bun Graphql function" + Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/graphql" + BunGraphqlFunction: + Description: "Bun Graphql Lambda Function ARN" + Value: !GetAtt BunGraphqlFunction.Arn + BunGraphqlRole: + Description: "Implicit IAM Role created for Bun Graphql function" + Value: !GetAtt BunGraphqlFunctionRole.Arn