From d2c759a2666fcc8ea7f9503cf2f04c5a3609f77c Mon Sep 17 00:00:00 2001 From: William Killerud Date: Thu, 11 Jul 2024 15:05:54 +0200 Subject: [PATCH] chore: fix workflow OS matrix --- .eslintignore | 2 - .eslintrc | 20 ----- .gitattributes | 1 + .github/workflows/publish.yml | 68 ++++++++--------- .github/workflows/test.yml | 18 +++-- .prettierrc | 5 -- .prettierrc.json | 13 ++++ eslint.config.js | 22 ++++++ example/server.js | 9 +-- lib/layout-plugin.js | 139 ++++++++++++++++++---------------- package.json | 124 +++++++++++++++--------------- tests/layout-plugin.test.js | 18 +++-- 12 files changed, 229 insertions(+), 210 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc create mode 100644 .gitattributes delete mode 100644 .prettierrc create mode 100644 .prettierrc.json create mode 100644 eslint.config.js diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 19e3677..0000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -coverage/ -example/ diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 069d89b..0000000 --- a/.eslintrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": ["airbnb-base", "prettier"], - "plugins": ["prettier"], - "parser": "@babel/eslint-parser", - "parserOptions": { - "requireConfigFile": false, - "ecmaVersion": 2020, - "sourceType": "module" - }, -"rules": { - "default-param-last": [0], - "import/prefer-default-export": "off", - "class-methods-use-this": [0], - "lines-between-class-members": [0], - "import/extensions": ["error", { - "js": "ignorePackages" - } - ] - } -} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index df58268..716afd9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,39 +1,39 @@ name: Release and Publish on: - push: - branches: - - main - - alpha - - beta - - next + push: + branches: + - main + - alpha + - beta + - next jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20.x - - - name: npm install - run: npm install - - - name: npm lint - run: npm run lint - - - name: npm types - run: npm run types - - - name: npm test - run: npm test - - - name: npx semantic-release - run: npx semantic-release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: npm install + run: npm install + + - name: npm lint + run: npm run lint + + - name: npm types + run: npm run types + + - name: npm test + run: npm test + + - name: npx semantic-release + run: npx semantic-release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6d71393..bc99846 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,19 +1,20 @@ name: Run Lint and Tests on: - pull_request: - branches: - - main - - alpha - - beta - - next + push: + branches-ignore: + - main + - alpha + - beta + - next jobs: build: - runs-on: ubuntu-latest strategy: matrix: - node-version: [lts/-1, lts/*] + os: [ubuntu-latest, macOS-latest, windows-latest] + node-version: [18, 20] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -30,6 +31,7 @@ jobs: run: npm run lint - name: npm types + if: runner.os != 'Windows' # because of ./fixup.sh run: npm run types - name: npm test diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 3fb27da..0000000 --- a/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all", - "tabWidth": 4 -} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..649f132 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,13 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "tabWidth": 4, + "overrides": [ + { + "files": ["*.json", "*.yml"], + "options": { + "tabWidth": 2 + } + } + ] +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..30aa733 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,22 @@ +import prettierConfig from 'eslint-config-prettier'; +import prettierPlugin from 'eslint-plugin-prettier/recommended'; +import globals from 'globals'; +import js from '@eslint/js'; + +export default [ + js.configs.recommended, + prettierConfig, + prettierPlugin, + { + languageOptions: { + globals: { + ...globals.node, + ...globals.browser, + global: true, + }, + }, + }, + { + ignores: ['coverage/*', 'dist/*'], + }, +]; diff --git a/example/server.js b/example/server.js index 5fd0e48..a93e1f8 100644 --- a/example/server.js +++ b/example/server.js @@ -10,21 +10,18 @@ const layout = new Layout({ pathname: '/', logger: console, name: 'layout', - }); const podlet = layout.client.register({ name: 'myPodlet', - uri: 'http://localhost:7100/manifest.json' + uri: 'http://localhost:7100/manifest.json', }); app.register(FastifyLayout, layout); app.get('/', async (request, reply) => { const incoming = reply.app.podium; - const result = await Promise.all([ - podlet.fetch(incoming), - ]); + const result = await Promise.all([podlet.fetch(incoming)]); reply.podiumSend(result[0].content); }); @@ -37,5 +34,5 @@ const start = async () => { app.log.error(err); process.exit(1); } -} +}; start(); diff --git a/lib/layout-plugin.js b/lib/layout-plugin.js index 0b0ffbf..488c2c1 100644 --- a/lib/layout-plugin.js +++ b/lib/layout-plugin.js @@ -1,81 +1,86 @@ -/* eslint-disable no-param-reassign */ -/* eslint-disable consistent-return */ - import { HttpIncoming, pathnameBuilder } from '@podium/utils'; import fp from 'fastify-plugin'; 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, + const layout = /** @type {import('@podium/layout').default} */ ( + options ); - // @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', - /** - * @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)); - }); + // 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, + }); + }); - // 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( - layout.httpProxy.pathname, - layout.httpProxy.prefix, - '/*', + // Decorate response with .podiumSend() method + 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)); + }, ); - // 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(); - }); + // 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( + layout.httpProxy.pathname, + layout.httpProxy.prefix, + '/*', + ); - 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; - }); + // 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.all(pathname, (req, reply) => { - reply.code(404).send('Not found'); - }); + instance.addHook('preHandler', async (req, reply) => { + const incoming = await layout.httpProxy.process( + // @ts-ignore We type this for our consumers with fixup.sh + reply.app.podium, + ); + if (incoming.proxy) return; + return incoming; + }); + + instance.all(pathname, (req, reply) => { + reply.code(404).send('Not found'); + }); - next(); - }); + next(); + }); - done(); -}, { - name: 'podium-layout', -}); + done(); + }, + { + name: 'podium-layout', + }, +); diff --git a/package.json b/package.json index 2cb9973..d10c838 100644 --- a/package.json +++ b/package.json @@ -1,63 +1,65 @@ { - "name": "@podium/fastify-layout", - "version": "3.0.6", - "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.7", - "@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.3.2", - "semantic-release": "22.0.12", - "tap": "19.0.0", - "typescript": "5.5.2" - } + "name": "@podium/fastify-layout", + "version": "3.0.6", + "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": "run-s test:unit test:types", + "test:unit": "tap --disable-coverage --allow-empty-coverage", + "test:types": "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.7", + "@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": "9.6.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-prettier": "5.1.3", + "fastify": "4.27.0", + "fastify-formbody": "5.3.0", + "globals": "15.8.0", + "npm-run-all": "4.1.5", + "prettier": "3.3.2", + "semantic-release": "22.0.12", + "tap": "19.0.0", + "typescript": "5.5.2" + } } diff --git a/tests/layout-plugin.test.js b/tests/layout-plugin.test.js index 21cda02..a75cfe8 100644 --- a/tests/layout-plugin.test.js +++ b/tests/layout-plugin.test.js @@ -30,9 +30,11 @@ class Server { listen() { return new Promise((resolve, reject) => { this.app - .listen({port: 0, host: '127.0.0.1'}) + .listen({ port: 0, host: '127.0.0.1' }) .then(() => { - const address = /** @type {import('net').AddressInfo} */ (this.app.server.address()); + const address = /** @type {import('net').AddressInfo} */ ( + this.app.server.address() + ); const url = `http://${address.address}:${address.port}`; resolve(url); }) @@ -43,11 +45,13 @@ class Server { } close() { - return /** @type {Promise} */(new Promise((resolve) => { - this.app.close(() => { - resolve(); - }); - })); + return /** @type {Promise} */ ( + new Promise((resolve) => { + this.app.close(() => { + resolve(); + }); + }) + ); } }