From 7987824a3b6c8ae50aa83c1511799312f64f6e54 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 27 May 2025 16:50:37 -0700 Subject: [PATCH] feat: add SvelteKit support --- README.md | 13 +++++++++- grant.js | 8 +++++++ lib/handler/sveltekit.js | 51 ++++++++++++++++++++++++++++++++++++++++ lib/session.js | 8 +++---- 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 lib/handler/sveltekit.js diff --git a/README.md b/README.md index f5a3e9b7..c5eba75f 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - **[Providers](#grant)** - **Handlers** - - [Express](#handlers) / [Koa](#handlers) / [Hapi](#handlers) / [Fastify](#handlers) + - [Express](#handlers) / [Koa](#handlers) / [Hapi](#handlers) / [Fastify](#handlers) / [SvelteKit](#handlers) - [AWS Lambda](#handlers) / [Azure Function](#handlers) / [Google Cloud Function](#handlers) / [Vercel](#handlers) - **Configuration** - [Basics](#configuration-basics) / [Description](#configuration-description) / [Values](#configuration-values) / [Scopes](#configuration-scopes) @@ -102,6 +102,17 @@ fastify() ``` +
SvelteKit + +```js +import grant from 'grant'; + +export const handle = grant.sveltekit({ + config: {/*configuration - see below*/}, session: {secret: 'grant'} +}); +``` +
+ ### Serverless Functions
AWS Lambda diff --git a/grant.js b/grant.js index c2d210b0..6f5a4fab 100644 --- a/grant.js +++ b/grant.js @@ -64,6 +64,9 @@ function grant ({handler, ...rest}) { else if (handler === 'vercel') { return require('./lib/handler/vercel')(rest) } + else if (handler === 'sveltekit') { + return require('./lib/handler/sveltekit')(rest) + } } grant.express = (options) => { @@ -135,5 +138,10 @@ grant.vercel = (options) => { return options ? handler(options) : handler } +grant.sveltekit = (options) => { + var handler = require('./lib/handler/sveltekit') + return options ? handler(options) : handler +} + grant.default = grant module.exports = grant diff --git a/lib/handler/sveltekit.js b/lib/handler/sveltekit.js new file mode 100644 index 00000000..24c7b387 --- /dev/null +++ b/lib/handler/sveltekit.js @@ -0,0 +1,51 @@ +var qs = require('qs') +var Grant = require('../grant') +var Session = require('../session') + +module.exports = function (args = {}) { + var grant = Grant(args.config ? args : {config: args}) + app.config = grant.config + + var regex = new RegExp([ + '^', + app.config.defaults.prefix, + /(?:\/([^\/\?]+?))/.source, // /:provider + /(?:\/([^\/\?]+?))?/.source, // /:override? + /(?:\/$|\/?\?+.*)?$/.source, // querystring + ].join(''), 'i') + + var store = Session(args.session) + + async function app ({ event, resolve }) { + var session = store(event.request) + var match = regex.exec(event.url.pathname + event.url.search) + if (!match) { + return resolve(event) + } + + var {location, session:sess, state} = await grant({ + method: event.request.method, + params: {provider: match[1], override: match[2]}, + query: qs.parse(event.url.searchParams.toString()), + body: qs.parse(await event.request.text()), + state, + session: (await session.get()).grant, + }) + + await session.set({grant: sess}) + + if (location) { + return new Response(null, { + status: 307, + headers: { + location, + 'set-cookie': session.headers['set-cookie'] + } + }) + } else { + return resolve(event) + } + } + + return app +} diff --git a/lib/session.js b/lib/session.js index e76898e6..2f19b7e8 100644 --- a/lib/session.js +++ b/lib/session.js @@ -15,12 +15,12 @@ module.exports = ({name, secret, cookie:options, store}) => { var embed = !store return (req) => { - var headers = Object.keys(req.headers) + var headerObj = req.headers instanceof Headers; + var headers = (headerObj ? Array.from(req.headers.keys()) : Object.keys(req.headers)) .filter((key) => /(?:set-)?cookie/i.test(key)) - .reduce((all, key) => (all[key.toLowerCase()] = req.headers[key], all), {}) - + .reduce((all, key) => (all[key.toLowerCase()] = headerObj ? req.headers.get(key) : req.headers[key], all), {}) headers['set-cookie'] = - headers['set-cookie'] || + (headerObj ? headers.get('set-cookie') : headers['set-cookie']) || (req.multiValueHeaders && req.multiValueHeaders['Set-Cookie']) || []