From 55d3268a1439e5576c32cbb492c9d857a84cc1cf Mon Sep 17 00:00:00 2001 From: William Killerud Date: Tue, 25 Jun 2024 13:41:03 +0200 Subject: [PATCH] fix: include type definition --- .gitignore | 4 +- fixup.sh | 2 + lib/layout-plugin.js | 25 +++- package.json | 118 +++++++++--------- .../layout-plugin.test.js | 7 +- tsconfig.json | 16 +++ tsconfig.test.json | 9 ++ types/podium.d.ts | 28 +++++ 8 files changed, 143 insertions(+), 66 deletions(-) create mode 100755 fixup.sh rename test/layout-plugin.js => tests/layout-plugin.test.js (95%) create mode 100644 tsconfig.json create mode 100644 tsconfig.test.json create mode 100644 types/podium.d.ts diff --git a/.gitignore b/.gitignore index 671a52f..ff3d515 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ coverage/ node_modules/ *.log .vscode -.tap \ No newline at end of file +.tap +types/* +!types/podium.d.ts diff --git a/fixup.sh b/fixup.sh new file mode 100755 index 0000000..4837acf --- /dev/null +++ b/fixup.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +cat >> types/layout-plugin.d.ts < types/podium.d.ts diff --git a/lib/layout-plugin.js b/lib/layout-plugin.js index 8e71231..0b0ffbf 100644 --- a/lib/layout-plugin.js +++ b/lib/layout-plugin.js @@ -4,28 +4,43 @@ import { HttpIncoming, pathnameBuilder } from '@podium/utils'; import fp from 'fastify-plugin'; -const podiumLayoutFastifyPlugin = (fastify, layout, done) => { +export default fp( + (fastify, options, done) => { + const layout = /** @type {import('@podium/layout').default} */ (options); + // Decorate reply with .app.podium we can write to throughout the request fastify.decorateReply('app', null); fastify.addHook('onRequest', async (request, reply) => { // namespace + // @ts-ignore We type this for our consumers with fixup.sh reply.app = reply.app || {}; // used to pass additional values to HttpIncoming + // @ts-ignore We type this for our consumers with fixup.sh reply.app.params = reply.app.params || {}; // used to hold the HttpIncoming object + // @ts-ignore We type this for our consumers with fixup.sh reply.app.podium = new HttpIncoming( request.raw, reply.raw, + // @ts-ignore We type this for our consumers with fixup.sh reply.app.params, ); + // @ts-ignore We type this for our consumers with fixup.sh reply.app.podium = await layout.process(reply.app.podium, { proxy: false, }); }); // Decorate response with .podiumSend() method - fastify.decorateReply('podiumSend', function podiumSend(payload, ...args) { + fastify.decorateReply('podiumSend', + /** + * @see https://podium-lib.io/docs/api/layout#respodiumsendfragment + * @param {unknown} payload + * @param {unknown[]} args + */ + function podiumSend(payload, ...args) { this.type('text/html; charset=utf-8'); // "this" here is the fastify 'Reply' object + // @ts-ignore We type this for our consumers with fixup.sh this.send(layout.render(this.app.podium, payload, ...args)); }); @@ -42,10 +57,12 @@ const podiumLayoutFastifyPlugin = (fastify, layout, done) => { // Allow all content types for proxy requests // https://github.com/fastify/fastify/blob/master/docs/ContentTypeParser.md#catch-all instance.addContentTypeParser('*', (req, payload, cb) => { + // @ts-ignore cb(); }); instance.addHook('preHandler', async (req, reply) => { + // @ts-ignore We type this for our consumers with fixup.sh const incoming = await layout.httpProxy.process(reply.app.podium); if (incoming.proxy) return; return incoming; @@ -59,8 +76,6 @@ const podiumLayoutFastifyPlugin = (fastify, layout, done) => { }); done(); -}; - -export default fp(podiumLayoutFastifyPlugin, { +}, { name: 'podium-layout', }); diff --git a/package.json b/package.json index bd994cd..c2a7bd5 100644 --- a/package.json +++ b/package.json @@ -1,59 +1,63 @@ { - "name": "@podium/fastify-layout", - "version": "3.0.5", - "type": "module", - "description": "Fastify plugin for Podium Layout.", - "main": "lib/layout-plugin.js", - "license": "MIT", - "keywords": [ - "micro services", - "micro frontend", - "components", - "podium", - "fastify" - ], - "repository": { - "type": "git", - "url": "git@github.com:podium-lib/fastify-layout.git" - }, - "bugs": { - "url": "https://github.com/podium-lib/issues" - }, - "homepage": "https://podium-lib.io/", - "files": [ - "package.json", - "CHANGELOG.md", - "README.md", - "LICENSE", - "lib" - ], - "scripts": { - "test": "tap --disable-coverage --allow-empty-coverage", - "test:coverage": "tap", - "lint": "eslint .", - "lint:fix": "eslint . --fix" - }, - "author": "Trygve Lie", - "dependencies": { - "@podium/utils": "5.0.7", - "fastify-plugin": "4.5.1" - }, - "devDependencies": { - "@podium/layout": "5.0.3", - "@podium/test-utils": "2.5.2", - "@semantic-release/changelog": "6.0.3", - "@semantic-release/git": "10.0.1", - "fastify-formbody": "5.3.0", - "@babel/eslint-parser": "7.24.6", - "eslint": "8.57.0", - "eslint-config-airbnb-base": "15.0.0", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "2.29.1", - "eslint-plugin-prettier": "5.1.3", - "fastify": "4.27.0", - "@fastify/formbody": "7.4.0", - "prettier": "3.2.5", - "semantic-release": "22.0.12", - "tap": "18.7.2" - } + "name": "@podium/fastify-layout", + "version": "3.0.5", + "type": "module", + "description": "Fastify plugin for Podium Layout.", + "main": "lib/layout-plugin.js", + "types": "types/layout-plugin.d.ts", + "license": "MIT", + "keywords": [ + "micro services", + "micro frontend", + "components", + "podium", + "fastify" + ], + "repository": { + "type": "git", + "url": "git@github.com:podium-lib/fastify-layout.git" + }, + "bugs": { + "url": "https://github.com/podium-lib/issues" + }, + "homepage": "https://podium-lib.io/", + "files": [ + "package.json", + "CHANGELOG.md", + "README.md", + "LICENSE", + "lib", + "types" + ], + "scripts": { + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "test": "tap tests/*.js --disable-coverage --allow-empty-coverage && tsc --project tsconfig.test.json", + "test:coverage": "tap", + "types": "tsc --declaration --emitDeclarationOnly && ./fixup.sh" + }, + "author": "Trygve Lie", + "dependencies": { + "@podium/utils": "5.0.7", + "fastify-plugin": "4.5.1" + }, + "devDependencies": { + "@babel/eslint-parser": "7.24.6", + "@fastify/formbody": "7.4.0", + "@podium/layout": "5.1.14", + "@podium/test-utils": "3.0.2", + "@semantic-release/changelog": "6.0.3", + "@semantic-release/git": "10.0.1", + "eslint": "8.57.0", + "eslint-config-airbnb-base": "15.0.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-prettier": "5.1.3", + "fastify": "4.27.0", + "fastify-formbody": "5.3.0", + "prettier": "3.2.5", + "semantic-release": "22.0.12", + "tap": "19.0.0", + "typescript": "5.5.2" + } } diff --git a/test/layout-plugin.js b/tests/layout-plugin.test.js similarity index 95% rename from test/layout-plugin.js rename to tests/layout-plugin.test.js index c1d65c1..21cda02 100644 --- a/test/layout-plugin.js +++ b/tests/layout-plugin.test.js @@ -1,3 +1,4 @@ +/// import { PodletServer, request } from '@podium/test-utils'; import fastify from 'fastify'; import Layout from '@podium/layout'; @@ -31,7 +32,7 @@ class Server { this.app .listen({port: 0, host: '127.0.0.1'}) .then(() => { - const address = this.app.server.address(); + const address = /** @type {import('net').AddressInfo} */ (this.app.server.address()); const url = `http://${address.address}:${address.port}`; resolve(url); }) @@ -42,11 +43,11 @@ class Server { } close() { - return new Promise((resolve) => { + return /** @type {Promise} */(new Promise((resolve) => { this.app.close(() => { resolve(); }); - }); + })); } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..564be4f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "lib": ["es2020"], + "module": "nodenext", + "target": "es2020", + "resolveJsonModule": true, + "checkJs": true, + "allowJs": true, + "moduleResolution": "nodenext", + "declaration": true, + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + "outDir": "types" + }, + "include": ["./lib/**/*.js"] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..530ad59 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["./tests/**/*.js"], + "compilerOptions": { + "module": "nodenext", + "moduleResolution": "nodenext", + "noEmit": true + } +} diff --git a/types/podium.d.ts b/types/podium.d.ts new file mode 100644 index 0000000..86b9bac --- /dev/null +++ b/types/podium.d.ts @@ -0,0 +1,28 @@ +import { HttpIncoming } from "@podium/utils"; + +declare module "fastify" { + interface PodiumParams {} + + interface PodiumLocals { + /** + * @see https://podium-lib.io/docs/api/incoming + */ + podium: HttpIncoming; + params: PodiumParams; + } + + + interface FastifyReply { + app: PodiumLocals; + /** + * This method wraps the provided fragment in a default HTML document before dispatching. + * + * @param markup The HTML contents of the document + * @param args Parameters sent to the template function + * @returns {void} Sends the FastifyReply + * + * @see https://podium-lib.io/docs/api/layout#respodiumsendfragment + */ + podiumSend: (markup: unknown, ...args: unknown[]) => void; + } +}