From c4a99a8e2d3466305b2a38c582a96ec3e38283da Mon Sep 17 00:00:00 2001 From: William Killerud Date: Mon, 29 Jul 2024 13:39:39 +0200 Subject: [PATCH 1/6] fix: deprecate customSink and built-in sinks In favor of sink and the separate sink modules, to keep the API consistent between "built-ins" and third-party sinks. --- .npmrc | 1 + lib/main.js | 28 ++++++++++++++++++++++------ package.json | 1 + 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.npmrc b/.npmrc index 43c97e71..0ca8d2a0 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ package-lock=false +save-exact=true diff --git a/lib/main.js b/lib/main.js index 3c4734e1..aabe19bb 100644 --- a/lib/main.js +++ b/lib/main.js @@ -10,25 +10,41 @@ import eik from '@eik/core'; import config from './config.js'; import * as utils from './utils.js'; +/** + * @typedef {object} EikServiceOptions + * @property {import('@eik/sink').default} [sink] + * @property {import('@eik/sink').default} [customSink] [Deprecated] Use sink instead + * @property {string} [aliasCacheControl] + * @property {string} [notFoundCacheControl="public, max-age=5"] + */ + const EikService = class EikService { - constructor({ - customSink, - notFoundCacheControl, - aliasCacheControl, - } = {}) { + /** + * @param {EikServiceOptions} [options={}] + */ + constructor(options = {}) { + let { sink } = options; + const { + customSink, + notFoundCacheControl, + aliasCacheControl, + } = options; this._notFoundCacheControl = notFoundCacheControl || 'public, max-age=5'; const logger = pino({ + // @ts-ignore level: config.get('log.level'), name: config.get('name'), }); - let sink; if (customSink) { + logger.warn('The `customSink` option is deprecated and will be removed at a later stage. Use `sink` to remove this warning.'); sink = customSink; } else if (config.get('sink.type') === 'mem') { + logger.warn('Using the built-in sinks is deprecated and will be removed at a later stage. Install and use `@eik/sink-memory` to remove this warning.'); logger.info(`Server is running with a in memory sink. Uploaded files will be lost on restart!`); sink = new eik.sink.MEM(); } else { + logger.warn(`Using the built-in sinks is deprecated and will be removed at a later stage. Install and use \`@eik/sink-file-system\` to remove this warning.`); logger.info(`Server is running with the file system sink. Uploaded files will be stored under "${config.get('sink.path')}"`); sink = new eik.sink.FS({ sinkFsRootPath: config.get('sink.path') }); } diff --git a/package.json b/package.json index dc697e87..91435c39 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "homepage": "https://github.com/eik-lib/service#readme", "dependencies": { "@eik/core": "1.3.47", + "@eik/sink": "1.2.5", "@fastify/compress": "6.5.0", "@fastify/cors": "8.5.0", "@fastify/jwt": "7.2.4", From 96b4839d250bb395ce526bf83dd834f43f479458 Mon Sep 17 00:00:00 2001 From: William Killerud Date: Mon, 29 Jul 2024 13:44:06 +0200 Subject: [PATCH 2/6] docs: usage example --- README.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7aa4fec2..c3d276c3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,70 @@ -# service +# Eik HTTP Service + Eik REST API - As a standalone running HTTP service + +## Installation + +``` +npm install @eik/service +``` + +## Usage + +This server can either be run as a Node executable, or as a Fastify plugin. + +```sh +npx @eik/service +``` + +For a production setup, the Fastify plugin method is recommended. + +```js +import fastify from 'fastify'; +import Service from '@eik/service'; +import Sink from '@eik/sink-gcs'; + +// Set up the Google Cloud Storage sink +// https://github.com/eik-lib/sink-gcs?tab=readme-ov-file#example +const sink = new Sink({ + credentials: { + client_email: 'a@email.address', + private_key: '[ ...snip... ]', + projectId: 'myProject', + }, +}); + +// Set up the Eik service as a plugin +const service = new Service({ sink }); + +// Set up Fastify +const app = fastify({ + ignoreTrailingSlash: true, + modifyCoreObjects: false, + trustProxy: true, +}); + +// Register the Eik service in Fastify +app.register(service.api()); + +// Append custom HTTP ready checks +app.get('/_/health', (request, reply) => { + reply.send('ok'); +}); + +app.get('/_/ready', (request, reply) => { + reply.send('ok'); +}); + +// Start the server +const run = async () => { + await service.health(); + await app.listen( + service.config.get('http.port'), + service.config.get('http.address'), + ); +}; + +run(); +``` + +The example above shows the Google Cloud Storage sink. You can also use the [file system sink](https://github.com/eik-lib/sink-file-system), or implement the [sink interface](https://github.com/eik-lib/sink) for your own custom storage backend. From 59fa91c6b868426ade7aef4f1036bbe675f76096 Mon Sep 17 00:00:00 2001 From: William Killerud Date: Mon, 29 Jul 2024 13:45:54 +0200 Subject: [PATCH 3/6] chore: upgrade eik/core This uses the separate sink modules internally --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 91435c39..c1a4165d 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "homepage": "https://github.com/eik-lib/service#readme", "dependencies": { - "@eik/core": "1.3.47", + "@eik/core": "1.3.48", "@eik/sink": "1.2.5", "@fastify/compress": "6.5.0", "@fastify/cors": "8.5.0", From 28a4cb555452858936be6b896aeaa72dc0a5de66 Mon Sep 17 00:00:00 2001 From: William Killerud Date: Mon, 29 Jul 2024 13:47:30 +0200 Subject: [PATCH 4/6] chore: omit windows from the test matrix for now --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9f34832d..07303f91 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: build: strategy: matrix: - os: [ubuntu-latest, macOS-latest, windows-latest] + os: [ubuntu-latest, macOS-latest] node-version: [18, 20] runs-on: ${{ matrix.os }} From 0ba4a697ef01d47093e3191b7512a98eafd23c27 Mon Sep 17 00:00:00 2001 From: William Killerud Date: Tue, 30 Jul 2024 12:11:18 +0200 Subject: [PATCH 5/6] refactor: replace sinks from eik core with modules Undo marking them as deprecated since the binary depends on them. --- lib/main.js | 8 ++++---- package.json | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/main.js b/lib/main.js index aabe19bb..fde5d9b5 100644 --- a/lib/main.js +++ b/lib/main.js @@ -5,6 +5,8 @@ import pino from 'pino'; import cors from '@fastify/cors'; import jwt from '@fastify/jwt'; import eik from '@eik/core'; +import SinkMemory from '@eik/sink-memory'; +import SinkFileSystem from '@eik/sink-file-system'; import config from './config.js'; @@ -40,13 +42,11 @@ const EikService = class EikService { logger.warn('The `customSink` option is deprecated and will be removed at a later stage. Use `sink` to remove this warning.'); sink = customSink; } else if (config.get('sink.type') === 'mem') { - logger.warn('Using the built-in sinks is deprecated and will be removed at a later stage. Install and use `@eik/sink-memory` to remove this warning.'); logger.info(`Server is running with a in memory sink. Uploaded files will be lost on restart!`); - sink = new eik.sink.MEM(); + sink = new SinkMemory(); } else { - logger.warn(`Using the built-in sinks is deprecated and will be removed at a later stage. Install and use \`@eik/sink-file-system\` to remove this warning.`); logger.info(`Server is running with the file system sink. Uploaded files will be stored under "${config.get('sink.path')}"`); - sink = new eik.sink.FS({ sinkFsRootPath: config.get('sink.path') }); + sink = new SinkFileSystem({ sinkFsRootPath: config.get('sink.path') }); } // Transform organization config diff --git a/package.json b/package.json index c1a4165d..f30a7eb0 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,8 @@ "dependencies": { "@eik/core": "1.3.48", "@eik/sink": "1.2.5", + "@eik/sink-file-system": "1.0.1", + "@eik/sink-memory": "1.1.1", "@fastify/compress": "6.5.0", "@fastify/cors": "8.5.0", "@fastify/jwt": "7.2.4", From f609ede4bdcf6badf3d9cc9a92b6766eab11fbbc Mon Sep 17 00:00:00 2001 From: William Killerud Date: Tue, 30 Jul 2024 12:19:04 +0200 Subject: [PATCH 6/6] docs: review feedback --- README.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c3d276c3..6e9df770 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Eik HTTP Service -Eik REST API - As a standalone running HTTP service +As a standalone running HTTP service exposing the Eik Service. ## Installation @@ -12,20 +12,26 @@ npm install @eik/service This server can either be run as a Node executable, or as a Fastify plugin. +### CLI + +This spins up the built-in Fastify server using configuration from your `config/` folder, or from environment variables. + ```sh npx @eik/service ``` +### Fastify plugin + For a production setup, the Fastify plugin method is recommended. ```js import fastify from 'fastify'; import Service from '@eik/service'; -import Sink from '@eik/sink-gcs'; +import SinkGoogleCloudStorage from '@eik/sink-gcs'; // Set up the Google Cloud Storage sink // https://github.com/eik-lib/sink-gcs?tab=readme-ov-file#example -const sink = new Sink({ +const sink = new SinkGoogleCloudStorage({ credentials: { client_email: 'a@email.address', private_key: '[ ...snip... ]', @@ -46,15 +52,6 @@ const app = fastify({ // Register the Eik service in Fastify app.register(service.api()); -// Append custom HTTP ready checks -app.get('/_/health', (request, reply) => { - reply.send('ok'); -}); - -app.get('/_/ready', (request, reply) => { - reply.send('ok'); -}); - // Start the server const run = async () => { await service.health();