-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
153 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,6 @@ coverage/ | |
node_modules/ | ||
*.log | ||
.vscode | ||
.tap | ||
.tap | ||
*.d.ts | ||
!podium.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import fs from 'node:fs'; | ||
import path from 'node:path'; | ||
|
||
let podium = path.join(process.cwd(), 'types', 'podium.d.ts'); | ||
let module = path.join(process.cwd(), 'types', 'podlet-plugin.d.ts'); | ||
|
||
fs.writeFileSync( | ||
module, | ||
`${fs.readFileSync(podium, 'utf-8')} | ||
${fs.readFileSync(module, 'utf-8')}`, | ||
'utf-8', | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,85 @@ | ||
import { HttpIncoming, pathnameBuilder } from '@podium/utils'; | ||
import fp from 'fastify-plugin'; | ||
|
||
const podiumPodletFastifyPlugin = (fastify, podlet, done) => { | ||
// Decorate reply with .app.podium we can write to throught the request | ||
fastify.decorateReply('app', null); | ||
fastify.addHook('onRequest', async (request, reply) => { | ||
reply.app = { | ||
podium: {}, | ||
}; | ||
}); | ||
|
||
// Run parsers on pre handler and store state object on reply.app.podium | ||
fastify.addHook('preHandler', async (request, reply) => { | ||
const incoming = new HttpIncoming( | ||
request.raw, | ||
reply.raw, | ||
reply.app.params, | ||
); | ||
reply.app.podium = await podlet.process(incoming, { proxy: false }); | ||
}); | ||
|
||
// Set http headers on response | ||
fastify.addHook('preHandler', async (request, reply) => { | ||
reply.header('podlet-version', podlet.version); | ||
}); | ||
|
||
// Decorate response with .podiumSend() method | ||
fastify.decorateReply('podiumSend', function podiumSend(payload) { | ||
this.type('text/html; charset=utf-8'); // "this" here is the fastify 'Reply' object | ||
this.send(podlet.render(this.app.podium, payload)); | ||
}); | ||
|
||
// Mount proxy route as an instance so its executed only on | ||
// the registered path. Iow: the proxy check is not run on | ||
// any other routes | ||
fastify.register((instance, opts, next) => { | ||
const pathname = pathnameBuilder( | ||
podlet.httpProxy.pathname, | ||
podlet.httpProxy.prefix, | ||
'/*', | ||
); | ||
export default fp( | ||
/** | ||
* @type {import('fastify').FastifyPluginCallback<import('@podium/podlet').default>} | ||
*/ | ||
(fastify, podlet, done) => { | ||
// Decorate reply with .app.podium we can write to throught the request | ||
fastify.decorateReply('app', null); | ||
fastify.addHook('onRequest', async (request, reply) => { | ||
// @ts-ignore We decorate this above | ||
reply.app = { | ||
podium: {}, | ||
}; | ||
}); | ||
|
||
// Allow all content types for proxy requests | ||
// https://github.com/fastify/fastify/blob/main/docs/ContentTypeParser.md#catch-all | ||
instance.addContentTypeParser('*', (req, payload, cb) => { | ||
cb(); | ||
// Run parsers on pre handler and store state object on reply.app.podium | ||
fastify.addHook('preHandler', async (request, reply) => { | ||
const incoming = new HttpIncoming( | ||
request.raw, | ||
reply.raw, | ||
// @ts-ignore | ||
reply.app.params, | ||
); | ||
// @ts-ignore We decorate this above | ||
reply.app.podium = await podlet.process(incoming, { proxy: false }); | ||
}); | ||
|
||
instance.addHook('preHandler', async (req, reply) => { | ||
const incoming = await podlet.httpProxy.process(reply.app.podium); | ||
if (incoming.proxy) return; | ||
return incoming; | ||
// Set http headers on response | ||
fastify.addHook('preHandler', async (request, reply) => { | ||
reply.header('podlet-version', podlet.version); | ||
}); | ||
|
||
instance.all(pathname, (req, reply) => { | ||
reply.code(404).send('Not found'); | ||
// Decorate response with .podiumSend() method | ||
fastify.decorateReply('podiumSend', function podiumSend(payload) { | ||
this.type('text/html; charset=utf-8'); // "this" here is the fastify 'Reply' object | ||
this.send( | ||
podlet.render( | ||
// @ts-ignore We decorate this above | ||
this.app.podium, | ||
payload, | ||
), | ||
); | ||
}); | ||
|
||
next(); | ||
}); | ||
// Mount proxy route as an instance so its executed only on | ||
// the registered path. Iow: the proxy check is not run on | ||
// any other routes | ||
fastify.register((instance, opts, next) => { | ||
const pathname = pathnameBuilder( | ||
podlet.httpProxy.pathname, | ||
podlet.httpProxy.prefix, | ||
'/*', | ||
); | ||
|
||
done(); | ||
}; | ||
// Allow all content types for proxy requests | ||
// https://github.com/fastify/fastify/blob/main/docs/ContentTypeParser.md#catch-all | ||
instance.addContentTypeParser('*', (req, payload, cb) => { | ||
// @ts-ignore | ||
cb(); | ||
}); | ||
|
||
instance.addHook('preHandler', async (req, reply) => { | ||
const incoming = await podlet.httpProxy.process( | ||
// @ts-ignore We decorate this above | ||
reply.app.podium, | ||
); | ||
if (incoming.proxy) return; | ||
return incoming; | ||
}); | ||
|
||
instance.all(pathname, (req, reply) => { | ||
reply.code(404).send('Not found'); | ||
}); | ||
|
||
next(); | ||
}); | ||
|
||
export default fp(podiumPodletFastifyPlugin, { | ||
name: 'podium-podlet', | ||
}); | ||
done(); | ||
}, | ||
{ | ||
name: 'podium-podlet', | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
"type": "module", | ||
"description": "Fastify plugin for Podium Podlet", | ||
"main": "lib/podlet-plugin.js", | ||
"types": "types/podlet-plugin.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "[email protected]:podium-lib/fastify-podlet.git" | ||
|
@@ -17,13 +18,18 @@ | |
"CHANGELOG.md", | ||
"README.md", | ||
"LICENSE", | ||
"lib" | ||
"lib", | ||
"types" | ||
], | ||
"scripts": { | ||
"test": "tap --disable-coverage --allow-empty-coverage", | ||
"test:coverage": "tap", | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix" | ||
"lint:fix": "eslint . --fix", | ||
"types": "run-s types:tsc types:fixup", | ||
"types:tsc": "tsc", | ||
"types:test": "tsc --project tsconfig.test.json", | ||
"types:fixup": "node ./fixup.js" | ||
}, | ||
"author": "Trygve Lie", | ||
"license": "MIT", | ||
|
@@ -40,7 +46,7 @@ | |
}, | ||
"devDependencies": { | ||
"@fastify/formbody": "7.4.0", | ||
"@podium/podlet": "5.1.12", | ||
"@podium/podlet": "5.1.16", | ||
"@podium/test-utils": "2.5.2", | ||
"@semantic-release/changelog": "6.0.3", | ||
"@semantic-release/commit-analyzer": "11.1.0", | ||
|
@@ -53,8 +59,10 @@ | |
"eslint-plugin-prettier": "5.2.1", | ||
"fastify": "4.28.1", | ||
"globals": "15.9.0", | ||
"npm-run-all2": "6.2.3", | ||
"prettier": "3.3.3", | ||
"semantic-release": "23.1.1", | ||
"tap": "18.8.0" | ||
"tap": "18.8.0", | ||
"typescript": "5.6.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"compilerOptions": { | ||
"lib": ["es2020"], | ||
"module": "nodenext", | ||
"target": "es2020", | ||
"resolveJsonModule": true, | ||
"checkJs": true, | ||
"allowJs": true, | ||
"moduleResolution": "nodenext", | ||
"noEmit": true, | ||
"declaration": true, | ||
"allowSyntheticDefaultImports": true, | ||
"outDir": "types" | ||
}, | ||
"include": ["./lib/**/*.js"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"include": ["./tests/**/*.js"], | ||
"compilerOptions": { | ||
"module": "nodenext", | ||
"moduleResolution": "nodenext", | ||
"noEmit": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
declare module 'fastify' { | ||
interface PodiumLocals {} // this is declared in @podium/podlet, we just hook onto it here | ||
|
||
interface FastifyReply { | ||
app: PodiumLocals; | ||
|
||
/** | ||
* Calls the send / write method on the `http.ServerResponse` object. | ||
* | ||
* When in development mode this method will wrap the provided fragment in a | ||
* default HTML document before dispatching. When not in development mode, this | ||
* method will just dispatch the fragment. | ||
* | ||
* @example | ||
* app.get(podlet.content(), async (req, reply) => { | ||
* reply.podiumSend('<h1>Hello World</h1>'); | ||
* await reply; | ||
* }); | ||
*/ | ||
podiumSend(fragment: string, ...args: unknown[]): Response; | ||
} | ||
} |