From 540d07930891e8345fe3daf49b712ded2f9c4bd7 Mon Sep 17 00:00:00 2001 From: liuyi Date: Tue, 27 Feb 2024 07:22:21 +0000 Subject: [PATCH] ci: fix selfhost (#5920) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Type** enhancement ___ ## **Description** - Introduced a new ESM module resolution setup using `ts-node` to enhance the development and deployment process. - Implemented a dynamic loader script registration mechanism to facilitate ESM module loading. - Simplified the predeploy script execution by refining environment variable handling and stdout configuration. - Updated `package.json` to reflect changes in script commands for better ESM support and added necessary dependencies for `ts-node` and `typescript`. ___ ## **Changes walkthrough**
Relevant files
Enhancement
loader.js
Introduce ESM Module Resolution via ts-node                           

packages/backend/server/scripts/loader.js
  • Introduced ts-node configuration for ESM module resolution.
  • Exported a resolve function for module resolution.
  • +11/-0   
    register.js
    Implement Dynamic Loader Script Registration                         

    packages/backend/server/scripts/register.js
  • Implemented dynamic registration of the loader script.
  • Utilized node:module and node:url for script registration.
  • +4/-0     
    self-host-predeploy.js
    Simplify Predeploy Script Execution                                           

    packages/backend/server/scripts/self-host-predeploy.js
  • Simplified environment variable passing to execSync.
  • Changed stdout handling to inherit from the parent process.
  • +3/-5     
    package.json
    Update Scripts and Dependencies for ESM Support                   

    packages/backend/server/package.json
  • Updated script commands for ESM compatibility.
  • Added ts-node and typescript dependencies.
  • Removed redundant --es-module-specifier-resolution=node flags.
  • +6/-6     
    ___ > ✨ **PR-Agent usage**: >Comment `/help` on the PR to get a list of all available PR-Agent tools and their descriptions --- .github/deployment/node/Dockerfile | 2 +- .github/deployment/self-host/compose.yaml | 2 +- packages/backend/server/package.json | 12 +++---- packages/backend/server/scripts/loader.js | 11 +++++++ packages/backend/server/scripts/register.js | 4 +++ .../server/scripts/self-host-predeploy.js | 8 ++--- .../server/src/core/auth/next-auth-options.ts | 32 ++++++++++--------- 7 files changed, 43 insertions(+), 28 deletions(-) create mode 100644 packages/backend/server/scripts/loader.js create mode 100644 packages/backend/server/scripts/register.js diff --git a/.github/deployment/node/Dockerfile b/.github/deployment/node/Dockerfile index bd0ab7d514..50e3707002 100644 --- a/.github/deployment/node/Dockerfile +++ b/.github/deployment/node/Dockerfile @@ -8,4 +8,4 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends openssl && \ rm -rf /var/lib/apt/lists/* -CMD ["node", "--es-module-specifier-resolution=node", "./dist/index.js"] +CMD ["node", "--import", "./scripts/register.js", "./dist/index.js"] diff --git a/.github/deployment/self-host/compose.yaml b/.github/deployment/self-host/compose.yaml index e63238fa39..dc16d7c8fc 100644 --- a/.github/deployment/self-host/compose.yaml +++ b/.github/deployment/self-host/compose.yaml @@ -23,7 +23,7 @@ services: max-size: '1000m' restart: unless-stopped environment: - - NODE_OPTIONS="--es-module-specifier-resolution=node" + - NODE_OPTIONS="--import=./scripts/register.js" - AFFINE_CONFIG_PATH=/root/.affine/config - REDIS_SERVER_HOST=redis - DATABASE_URL=postgres://affine:affine@postgres:5432/affine diff --git a/packages/backend/server/package.json b/packages/backend/server/package.json index 64ff5ab7e0..b0d40f22dd 100644 --- a/packages/backend/server/package.json +++ b/packages/backend/server/package.json @@ -9,13 +9,13 @@ }, "scripts": { "build": "tsc", - "start": "node --loader ts-node/esm/transpile-only.mjs --es-module-specifier-resolution=node ./src/index.ts", + "start": "node --loader ts-node/esm/transpile-only.mjs ./src/index.ts", "dev": "nodemon ./src/index.ts", "test": "ava --concurrency 1 --serial", "test:coverage": "c8 ava --concurrency 1 --serial", "postinstall": "prisma generate", - "data-migration": "node --loader ts-node/esm/transpile-only.mjs --es-module-specifier-resolution=node ./src/data/index.ts", - "predeploy": "yarn prisma migrate deploy && node --es-module-specifier-resolution=node ./dist/data/index.js run" + "data-migration": "node --loader ts-node/esm/transpile-only.mjs ./src/data/index.ts", + "predeploy": "yarn prisma migrate deploy && node --import ./scripts/register.js ./dist/data/index.js run" }, "dependencies": { "@apollo/server": "^4.10.0", @@ -86,6 +86,8 @@ "semver": "^7.6.0", "socket.io": "^4.7.4", "stripe": "^14.18.0", + "ts-node": "^10.9.2", + "typescript": "^5.3.3", "ws": "^8.16.0", "yjs": "^13.6.12", "zod": "^3.22.4" @@ -112,9 +114,7 @@ "c8": "^9.1.0", "nodemon": "^3.1.0", "sinon": "^17.0.1", - "supertest": "^6.3.4", - "ts-node": "^10.9.2", - "typescript": "^5.3.3" + "supertest": "^6.3.4" }, "ava": { "timeout": "1m", diff --git a/packages/backend/server/scripts/loader.js b/packages/backend/server/scripts/loader.js new file mode 100644 index 0000000000..ce31fb5096 --- /dev/null +++ b/packages/backend/server/scripts/loader.js @@ -0,0 +1,11 @@ +import { create, createEsmHooks } from 'ts-node'; + +const service = create({ + experimentalSpecifierResolution: 'node', + transpileOnly: true, + logError: true, + skipProject: true, +}); +const hooks = createEsmHooks(service); + +export const resolve = hooks.resolve; diff --git a/packages/backend/server/scripts/register.js b/packages/backend/server/scripts/register.js new file mode 100644 index 0000000000..ce20ff5368 --- /dev/null +++ b/packages/backend/server/scripts/register.js @@ -0,0 +1,4 @@ +import { register } from 'node:module'; +import { pathToFileURL } from 'node:url'; + +register('./scripts/loader.js', pathToFileURL('./')); diff --git a/packages/backend/server/scripts/self-host-predeploy.js b/packages/backend/server/scripts/self-host-predeploy.js index 2e71f738d7..6d2cf55749 100644 --- a/packages/backend/server/scripts/self-host-predeploy.js +++ b/packages/backend/server/scripts/self-host-predeploy.js @@ -42,11 +42,9 @@ function prepare() { function runPredeployScript() { console.log('running predeploy script.'); execSync('yarn predeploy', { - env: { - ...process.env, - NODE_OPTIONS: - (process.env.NODE_OPTIONS ?? '') + ' --import ./dist/prelude.js', - }, + encoding: 'utf-8', + env: process.env, + stdio: 'inherit', }); } diff --git a/packages/backend/server/src/core/auth/next-auth-options.ts b/packages/backend/server/src/core/auth/next-auth-options.ts index 6d7c86b455..f177fd0790 100644 --- a/packages/backend/server/src/core/auth/next-auth-options.ts +++ b/packages/backend/server/src/core/auth/next-auth-options.ts @@ -116,9 +116,6 @@ export const NextAuthOptionsProvider: FactoryProvider = { // @ts-expect-error Third part library type mismatch adapter: prismaAdapter, debug: !config.node.prod, - session: { - strategy: 'database', - }, logger: { debug(code, metadata) { logger.debug(`${code}: ${JSON.stringify(metadata)}`); @@ -139,18 +136,6 @@ export const NextAuthOptionsProvider: FactoryProvider = { }, }; - if (config.mailer && mailer) { - nextAuthOptions.providers.push( - // @ts-expect-error esm interop issue - Email.default({ - server: config.mailer, - from: config.mailer.from, - sendVerificationRequest: (params: SendVerificationRequestParams) => - sendVerificationRequest(config, logger, mailer, session, params), - }) - ); - } - nextAuthOptions.providers.push( // @ts-expect-error esm interop issue Credentials.default({ @@ -183,6 +168,18 @@ export const NextAuthOptionsProvider: FactoryProvider = { }) ); + if (config.mailer && mailer) { + nextAuthOptions.providers.push( + // @ts-expect-error esm interop issue + Email.default({ + server: config.mailer, + from: config.mailer.from, + sendVerificationRequest: (params: SendVerificationRequestParams) => + sendVerificationRequest(config, logger, mailer, session, params), + }) + ); + } + if (config.auth.oauthProviders.github) { nextAuthOptions.providers.push( // @ts-expect-error esm interop issue @@ -209,6 +206,11 @@ export const NextAuthOptionsProvider: FactoryProvider = { ); } + if (nextAuthOptions.providers.length > 1) { + // not only credentials provider + nextAuthOptions.session = { strategy: 'database' }; + } + nextAuthOptions.jwt = { encode: async ({ token, maxAge }) => encode(config, prisma, token, maxAge),