build: allow node package depends on workspace packages (#11963)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a unified CLI entry point for server operations and introduced a new CLI executable alias. - Centralized and simplified server startup, allowing selection between CLI and server modes. - Added static migration module aggregation for easier migration management. - **Bug Fixes** - Improved platform-specific native module loading for better compatibility and reliability. - **Refactor** - Streamlined server build, startup, and artifact management processes. - Reorganized and simplified workflow and configuration files for backend services. - Transitioned export styles and import mechanisms for native modules to enhance maintainability. - **Chores** - Removed unused dependencies and configuration files. - Updated test cases to reflect refined server flavor logic. - Adjusted package and build configurations for consistency and clarity. - **Revert** - Removed legacy scripts and loaders no longer needed after refactor. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
4ffa37d1c3
commit
f4ffdb9995
2
.github/deployment/node/Dockerfile
vendored
2
.github/deployment/node/Dockerfile
vendored
@ -10,4 +10,4 @@ RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends openssl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
CMD ["node", "--import", "./scripts/register.js", "./dist/index.js"]
|
||||
CMD ["node", "./dist/main.js"]
|
||||
|
60
.github/deployment/self-host/compose.yaml
vendored
60
.github/deployment/self-host/compose.yaml
vendored
@ -1,60 +0,0 @@
|
||||
services:
|
||||
affine:
|
||||
image: ghcr.io/toeverything/affine-graphql:stable
|
||||
container_name: affine_selfhosted
|
||||
command:
|
||||
['sh', '-c', 'node ./scripts/self-host-predeploy && node ./dist/index.js']
|
||||
ports:
|
||||
- '3010:3010'
|
||||
- '5555:5555'
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
# custom configurations
|
||||
- ~/.affine/self-host/config:/root/.affine/config
|
||||
# blob storage
|
||||
- ~/.affine/self-host/storage:/root/.affine/storage
|
||||
logging:
|
||||
driver: 'json-file'
|
||||
options:
|
||||
max-size: '1000m'
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- NODE_OPTIONS="--import=./scripts/register.js"
|
||||
- AFFINE_CONFIG_PATH=/root/.affine/config
|
||||
- REDIS_SERVER_HOST=redis
|
||||
- DATABASE_URL=postgres://affine:affine@postgres:5432/affine
|
||||
- NODE_ENV=production
|
||||
# Telemetry allows us to collect data on how you use the affine. This data will helps us improve the app and provide better features.
|
||||
# Uncomment next line if you wish to quit telemetry.
|
||||
# - TELEMETRY_ENABLE=false
|
||||
redis:
|
||||
image: redis
|
||||
container_name: affine_redis
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ~/.affine/self-host/redis:/data
|
||||
healthcheck:
|
||||
test: ['CMD', 'redis-cli', '--raw', 'incr', 'ping']
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
postgres:
|
||||
image: postgres:16
|
||||
container_name: affine_postgres
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ~/.affine/self-host/postgres:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -U affine']
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
environment:
|
||||
POSTGRES_USER: affine
|
||||
POSTGRES_PASSWORD: affine
|
||||
POSTGRES_DB: affine
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
86
.github/workflows/build-images.yml
vendored
86
.github/workflows/build-images.yml
vendored
@ -13,31 +13,6 @@ permissions:
|
||||
packages: 'write'
|
||||
|
||||
jobs:
|
||||
build-server:
|
||||
name: Build Server
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Version
|
||||
id: version
|
||||
uses: ./.github/actions/setup-version
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
extra-flags: workspaces focus @affine/server @types/affine__env
|
||||
- name: Build Server
|
||||
run: |
|
||||
find packages/backend/server/src -type d -name "__tests__" -exec rm -rf {} +
|
||||
rm -rf packages/backend/server/src/seed
|
||||
yarn workspace @affine/server build
|
||||
- name: Upload server dist
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: server-dist
|
||||
path: ./packages/backend/server/dist
|
||||
if-no-files-found: error
|
||||
|
||||
build-web:
|
||||
name: Build @affine/web
|
||||
runs-on: ubuntu-latest
|
||||
@ -143,7 +118,7 @@ jobs:
|
||||
matrix:
|
||||
targets:
|
||||
- name: x86_64-unknown-linux-gnu
|
||||
file: server-native.node
|
||||
file: server-native.x64.node
|
||||
- name: aarch64-unknown-linux-gnu
|
||||
file: server-native.arm64.node
|
||||
- name: armv7-unknown-linux-gnueabihf
|
||||
@ -164,11 +139,46 @@ jobs:
|
||||
with:
|
||||
target: ${{ matrix.targets.name }}
|
||||
package: '@affine/server-native'
|
||||
- name: Rename ${{ matrix.targets.file }}
|
||||
run: |
|
||||
mv ./packages/backend/native/server-native.node ./packages/backend/native/${{ matrix.targets.file }}
|
||||
- name: Upload ${{ matrix.targets.file }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.targets.file }}
|
||||
path: ./packages/backend/native/server-native.node
|
||||
name: server-native-${{ matrix.targets.file }}
|
||||
path: ./packages/backend/native/${{ matrix.targets.file }}
|
||||
if-no-files-found: error
|
||||
|
||||
build-server:
|
||||
name: Build Server
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build-server-native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Version
|
||||
id: version
|
||||
uses: ./.github/actions/setup-version
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
extra-flags: workspaces focus @affine/server @types/affine__env
|
||||
- name: Download server-native
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: server-native-*
|
||||
merge-multiple: true
|
||||
path: ./packages/backend/native
|
||||
- name: List server-native files
|
||||
run: ls -alh ./packages/backend/native
|
||||
- name: Build Server
|
||||
run: yarn workspace @affine/server build
|
||||
- name: Upload server dist
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: server-dist
|
||||
path: ./packages/backend/server/dist
|
||||
if-no-files-found: error
|
||||
|
||||
build-images:
|
||||
@ -179,7 +189,6 @@ jobs:
|
||||
- build-web
|
||||
- build-mobile
|
||||
- build-admin
|
||||
- build-server-native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download server dist
|
||||
@ -187,25 +196,6 @@ jobs:
|
||||
with:
|
||||
name: server-dist
|
||||
path: ./packages/backend/server/dist
|
||||
- name: Download server-native.node
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
- name: Download server-native.node arm64
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.arm64.node
|
||||
path: ./packages/backend/native
|
||||
- name: Download server-native.node arm64
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.armv7.node
|
||||
path: .
|
||||
- name: move server-native files
|
||||
run: |
|
||||
mv ./packages/backend/native/server-native.node ./packages/backend/server/server-native.arm64.node
|
||||
mv server-native.node ./packages/backend/server/server-native.armv7.node
|
||||
- name: Setup env
|
||||
run: |
|
||||
echo "GIT_SHORT_HASH=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
|
||||
|
10
.github/workflows/build-test.yml
vendored
10
.github/workflows/build-test.yml
vendored
@ -582,7 +582,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
uses: ./.github/actions/server-test-env
|
||||
@ -644,7 +644,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
uses: ./.github/actions/server-test-env
|
||||
@ -885,7 +885,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
if: ${{ steps.check-blocksuite-update.outputs.skip != 'true' || steps.apifilter.outputs.changed == 'true' }}
|
||||
@ -982,7 +982,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
if: ${{ steps.check-blocksuite-update.outputs.skip != 'true' || steps.e2efilter.outputs.changed == 'true' }}
|
||||
@ -1077,7 +1077,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Download affine.linux-x64-gnu.node
|
||||
uses: actions/download-artifact@v4
|
||||
|
4
.github/workflows/copilot-test.yml
vendored
4
.github/workflows/copilot-test.yml
vendored
@ -73,7 +73,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
env:
|
||||
@ -142,7 +142,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/server
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
env:
|
||||
|
@ -58,7 +58,6 @@
|
||||
"@magic-works/i18n-codegen": "^0.6.1",
|
||||
"@playwright/test": "=1.51.1",
|
||||
"@smarttools/eslint-plugin-rxjs": "^1.0.8",
|
||||
"@swc/core": "^1.10.1",
|
||||
"@taplo/cli": "^0.7.0",
|
||||
"@toeverything/infra": "workspace:*",
|
||||
"@types/eslint": "^9.6.1",
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
/** @type {import('.')} */
|
||||
const binding = require('./server-native.node');
|
||||
let binding;
|
||||
try {
|
||||
binding = require('./server-native.node');
|
||||
} catch {
|
||||
binding =
|
||||
process.arch === 'arm64'
|
||||
? require('./server-native.arm64.node')
|
||||
: process.arch === 'arm'
|
||||
? require('./server-native.armv7.node')
|
||||
: require('./server-native.x64.node');
|
||||
}
|
||||
|
||||
export const mergeUpdatesInApplyWay = binding.mergeUpdatesInApplyWay;
|
||||
export const verifyChallengeResponse = binding.verifyChallengeResponse;
|
||||
export const mintChallengeResponse = binding.mintChallengeResponse;
|
||||
export const getMime = binding.getMime;
|
||||
export const Tokenizer = binding.Tokenizer;
|
||||
export const fromModelName = binding.fromModelName;
|
||||
export const htmlSanitize = binding.htmlSanitize;
|
||||
export const parseDoc = binding.parseDoc;
|
||||
module.exports = binding;
|
||||
|
@ -4,7 +4,6 @@
|
||||
"engines": {
|
||||
"node": ">= 10.16.0 < 11 || >= 11.8.0"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "./index.js",
|
||||
"module": "./index.js",
|
||||
"types": "index.d.ts",
|
||||
|
@ -8,7 +8,7 @@
|
||||
"run-test": "./scripts/run-test.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -b",
|
||||
"build": "affine bundle -p @affine/server",
|
||||
"dev": "nodemon ./src/index.ts",
|
||||
"dev:mail": "email dev -d src/mails",
|
||||
"test": "ava --concurrency 1 --serial",
|
||||
@ -17,14 +17,16 @@
|
||||
"test:copilot:coverage": "c8 ava --timeout=5m \"src/__tests__/copilot-*.spec.ts\"",
|
||||
"e2e": "cross-env TEST_MODE=e2e ava --serial",
|
||||
"e2e:coverage": "cross-env TEST_MODE=e2e c8 ava --serial",
|
||||
"data-migration": "cross-env NODE_ENV=development r ./src/data/index.ts",
|
||||
"data-migration": "cross-env NODE_ENV=development SERVER_FLAVOR=script r ./src/index.ts",
|
||||
"init": "yarn prisma migrate dev && yarn data-migration run",
|
||||
"seed": "r ./src/seed/index.ts",
|
||||
"genconfig": "r ./scripts/genconfig.ts",
|
||||
"predeploy": "yarn prisma migrate deploy && node --import ./scripts/register.js ./dist/data/index.js run",
|
||||
"cli": "cross-env SERVER_FLAVOR=script node ./dist/main.js",
|
||||
"predeploy": "yarn prisma migrate deploy && yarn cli run",
|
||||
"postinstall": "prisma generate"
|
||||
},
|
||||
"dependencies": {
|
||||
"@affine/server-native": "workspace:*",
|
||||
"@ai-sdk/google": "^1.2.10",
|
||||
"@ai-sdk/openai": "^1.3.18",
|
||||
"@ai-sdk/perplexity": "^1.1.6",
|
||||
@ -72,6 +74,7 @@
|
||||
"ai": "^4.3.4",
|
||||
"bullmq": "^5.40.2",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cross-env": "^7.0.3",
|
||||
"date-fns": "^4.0.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"eventemitter2": "^6.4.9",
|
||||
@ -117,7 +120,6 @@
|
||||
"@affine-tools/cli": "workspace:*",
|
||||
"@affine-tools/utils": "workspace:*",
|
||||
"@affine/graphql": "workspace:*",
|
||||
"@affine/server-native": "workspace:*",
|
||||
"@faker-js/faker": "^9.6.0",
|
||||
"@nestjs/testing": "patch:@nestjs/testing@npm%3A10.4.15#~/.yarn/patches/@nestjs-testing-npm-10.4.15-d591a1705a.patch",
|
||||
"@types/cookie-parser": "^1.4.8",
|
||||
@ -138,7 +140,6 @@
|
||||
"@types/supertest": "^6.0.2",
|
||||
"ava": "^6.2.0",
|
||||
"c8": "^10.1.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"nodemon": "^3.1.7",
|
||||
"react-email": "4.0.7",
|
||||
"sinon": "^20.0.0",
|
||||
|
@ -1,11 +0,0 @@
|
||||
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;
|
@ -1,4 +0,0 @@
|
||||
import { register } from 'node:module';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
register('./scripts/loader.js', pathToFileURL('./'));
|
@ -111,7 +111,7 @@ test('should tell flavors correctly', t => {
|
||||
sync: true,
|
||||
renderer: true,
|
||||
doc: true,
|
||||
script: true,
|
||||
script: false,
|
||||
});
|
||||
|
||||
process.env.SERVER_FLAVOR = 'graphql';
|
||||
@ -122,6 +122,15 @@ test('should tell flavors correctly', t => {
|
||||
doc: false,
|
||||
script: false,
|
||||
});
|
||||
|
||||
process.env.SERVER_FLAVOR = 'script';
|
||||
t.deepEqual(new Env().flavors, {
|
||||
graphql: false,
|
||||
sync: false,
|
||||
renderer: false,
|
||||
doc: false,
|
||||
script: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('should tell selfhosted correctly', t => {
|
||||
|
@ -1,16 +1,12 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { CommandFactory } from 'nest-commander';
|
||||
|
||||
async function bootstrap() {
|
||||
process.env.SERVER_FLAVOR = 'script';
|
||||
import { CliAppModule } from './data/app';
|
||||
|
||||
await import('../prelude');
|
||||
const { CliAppModule } = await import('./app');
|
||||
export async function run() {
|
||||
await CommandFactory.run(CliAppModule, new Logger()).catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
await bootstrap();
|
@ -1,5 +1,5 @@
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { appendFileSync, writeFileSync } from 'node:fs';
|
||||
import { join, parse } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { Logger } from '@nestjs/common';
|
||||
@ -45,15 +45,21 @@ export class CreateCommand extends CommandRunner {
|
||||
|
||||
const timestamp = Date.now();
|
||||
const content = this.createScript(upperFirst(camelCase(name)) + timestamp);
|
||||
const fileName = `${timestamp}-${kebabCase(name)}.ts`;
|
||||
const filePath = join(
|
||||
const migrationDir = join(
|
||||
fileURLToPath(import.meta.url),
|
||||
'../../migrations',
|
||||
fileName
|
||||
'../../migrations'
|
||||
);
|
||||
const fileName = `${timestamp}-${kebabCase(name)}.ts`;
|
||||
const filePath = join(migrationDir, fileName);
|
||||
|
||||
this.logger.log(`Creating ${fileName}...`);
|
||||
writeFileSync(filePath, content);
|
||||
const indexFile = join(migrationDir, 'index.ts');
|
||||
appendFileSync(
|
||||
indexFile,
|
||||
`export * from './${parse(fileName).name}';`,
|
||||
'utf-8'
|
||||
);
|
||||
this.logger.log(`Migration file created at ${filePath}`);
|
||||
this.logger.log('Done');
|
||||
}
|
||||
|
@ -1,49 +1,28 @@
|
||||
import { readdirSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { once } from 'lodash-es';
|
||||
import { Command, CommandRunner } from 'nest-commander';
|
||||
|
||||
import * as migrations from '../migrations';
|
||||
|
||||
interface Migration {
|
||||
file: string;
|
||||
name: string;
|
||||
always?: boolean;
|
||||
up: (db: PrismaClient, injector: ModuleRef) => Promise<void>;
|
||||
down: (db: PrismaClient, injector: ModuleRef) => Promise<void>;
|
||||
}
|
||||
|
||||
export const collectMigrations = once(async () => {
|
||||
const folder = join(fileURLToPath(import.meta.url), '../../migrations');
|
||||
|
||||
const migrationFiles = readdirSync(folder)
|
||||
.filter(desc =>
|
||||
desc.endsWith(import.meta.url.endsWith('.ts') ? '.ts' : '.js')
|
||||
)
|
||||
.map(desc => join(folder, desc));
|
||||
|
||||
migrationFiles.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
const migrations: Migration[] = await Promise.all(
|
||||
migrationFiles.map(async file => {
|
||||
return import(pathToFileURL(file).href).then(mod => {
|
||||
const migration = mod[Object.keys(mod)[0]];
|
||||
|
||||
return {
|
||||
file,
|
||||
name: migration.name,
|
||||
always: migration.always,
|
||||
up: migration.up,
|
||||
down: migration.down,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return migrations;
|
||||
export const collectMigrations = once(() => {
|
||||
return Object.values(migrations).map(migration => {
|
||||
return {
|
||||
name: migration.name,
|
||||
// @ts-expect-error optional
|
||||
always: migration.always,
|
||||
up: migration.up,
|
||||
down: migration.down,
|
||||
};
|
||||
}) as Migration[];
|
||||
});
|
||||
|
||||
@Command({
|
||||
@ -60,7 +39,7 @@ export class RunCommand extends CommandRunner {
|
||||
}
|
||||
|
||||
override async run(): Promise<void> {
|
||||
const migrations = await collectMigrations();
|
||||
const migrations = collectMigrations();
|
||||
const done: Migration[] = [];
|
||||
for (const migration of migrations) {
|
||||
const exists = await this.db.dataMigration.count({
|
||||
@ -85,7 +64,7 @@ export class RunCommand extends CommandRunner {
|
||||
}
|
||||
|
||||
async runOne(name: string) {
|
||||
const migrations = await collectMigrations();
|
||||
const migrations = collectMigrations();
|
||||
const migration = migrations.find(m => m.name === name);
|
||||
|
||||
if (!migration) {
|
||||
@ -162,7 +141,7 @@ export class RevertCommand extends CommandRunner {
|
||||
throw new Error('A migration name is required');
|
||||
}
|
||||
|
||||
const migrations = await collectMigrations();
|
||||
const migrations = collectMigrations();
|
||||
|
||||
const migration = migrations.find(m => m.name === name);
|
||||
|
||||
|
7
packages/backend/server/src/data/migrations/index.ts
Normal file
7
packages/backend/server/src/data/migrations/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './0001-refresh-features';
|
||||
export * from './1698398506533-guid';
|
||||
export * from './1703756315970-unamed-account';
|
||||
export * from './1721299086340-refresh-unnamed-user';
|
||||
export * from './1732861452428-migrate-invite-status';
|
||||
export * from './1733125339942-universal-subscription';
|
||||
export * from './1738590347632-feature-redundant';
|
@ -102,7 +102,8 @@ export class Env implements AppEnv {
|
||||
sync: this.isFlavor(Flavor.Sync),
|
||||
renderer: this.isFlavor(Flavor.Renderer),
|
||||
doc: this.isFlavor(Flavor.Doc),
|
||||
script: this.isFlavor(Flavor.Script),
|
||||
// Script in a special flavor, return true only when it is set explicitly
|
||||
script: this.FLAVOR === Flavor.Script,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,11 @@
|
||||
/// <reference types="./global.d.ts" />
|
||||
import './prelude';
|
||||
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { run as runCli } from './cli';
|
||||
import { run as runServer } from './server';
|
||||
|
||||
import { createApp } from './app';
|
||||
import { Config, URLHelper } from './base';
|
||||
|
||||
const app = await createApp();
|
||||
const config = app.get(Config);
|
||||
const url = app.get(URLHelper);
|
||||
const listeningHost = '0.0.0.0';
|
||||
|
||||
await app.listen(config.server.port, listeningHost);
|
||||
|
||||
const logger = new Logger('App');
|
||||
|
||||
logger.log(`AFFiNE Server is running in [${env.DEPLOYMENT_TYPE}] mode`);
|
||||
logger.log(`Listening on http://${listeningHost}:${config.server.port}`);
|
||||
logger.log(`And the public server should be recognized as ${url.home}`);
|
||||
if (env.flavors.script) {
|
||||
await runCli();
|
||||
} else {
|
||||
await runServer();
|
||||
}
|
||||
|
@ -1,17 +1,4 @@
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
let serverNativeModule: typeof import('@affine/server-native');
|
||||
try {
|
||||
serverNativeModule = await import('@affine/server-native');
|
||||
} catch {
|
||||
const require = createRequire(import.meta.url);
|
||||
serverNativeModule =
|
||||
process.arch === 'arm64'
|
||||
? require('../server-native.arm64.node')
|
||||
: process.arch === 'arm'
|
||||
? require('../server-native.armv7.node')
|
||||
: require('../server-native.node');
|
||||
}
|
||||
import serverNativeModule from '@affine/server-native';
|
||||
|
||||
export const mergeUpdatesInApplyWay = serverNativeModule.mergeUpdatesInApplyWay;
|
||||
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
CloudThrottlerGuard,
|
||||
Config,
|
||||
GlobalExceptionFilter,
|
||||
URLHelper,
|
||||
} from './base';
|
||||
import { SocketIoAdapter } from './base/websocket';
|
||||
import { AuthGuard } from './core/auth';
|
||||
@ -16,7 +17,7 @@ import { serverTimingAndCache } from './middleware/timing';
|
||||
|
||||
const OneMB = 1024 * 1024;
|
||||
|
||||
export async function createApp() {
|
||||
export async function run() {
|
||||
const { AppModule } = await import('./app.module');
|
||||
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
|
||||
@ -28,7 +29,8 @@ export async function createApp() {
|
||||
|
||||
app.useBodyParser('raw', { limit: 100 * OneMB });
|
||||
|
||||
app.useLogger(app.get(AFFiNELogger));
|
||||
const logger = app.get(AFFiNELogger);
|
||||
app.useLogger(logger);
|
||||
const config = app.get(Config);
|
||||
|
||||
if (config.server.path) {
|
||||
@ -57,5 +59,12 @@ export async function createApp() {
|
||||
const adapter = new SocketIoAdapter(app);
|
||||
app.useWebSocketAdapter(adapter);
|
||||
|
||||
return app;
|
||||
const url = app.get(URLHelper);
|
||||
const listeningHost = '0.0.0.0';
|
||||
|
||||
await app.listen(config.server.port, listeningHost);
|
||||
|
||||
logger.log(`AFFiNE Server is running in [${env.DEPLOYMENT_TYPE}] mode`);
|
||||
logger.log(`Listening on http://${listeningHost}:${config.server.port}`);
|
||||
logger.log(`And the public server should be recognized as ${url.home}`);
|
||||
}
|
@ -12,9 +12,9 @@
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [
|
||||
{ "path": "../native" },
|
||||
{ "path": "../../../tools/cli" },
|
||||
{ "path": "../../../tools/utils" },
|
||||
{ "path": "../../common/graphql" },
|
||||
{ "path": "../native" }
|
||||
{ "path": "../../common/graphql" }
|
||||
]
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
"devDependencies": {
|
||||
"@affine/templates": "workspace:*",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@swc/core": "^1.10.1",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.1.0",
|
||||
"@types/react": "^19.0.1",
|
||||
|
@ -84,7 +84,6 @@
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@swc/core": "^1.10.1",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.1.0",
|
||||
"@types/animejs": "^3.1.12",
|
||||
|
5
tools/cli/bin/cli.js
Executable file
5
tools/cli/bin/cli.js
Executable file
@ -0,0 +1,5 @@
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
spawnSync('yarn', ['r', 'affine.ts', ...process.argv.slice(2)], {
|
||||
stdio: 'inherit',
|
||||
});
|
@ -4,6 +4,7 @@
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"bin": {
|
||||
"affine": "./bin/cli.js",
|
||||
"r": "./bin/runner.js"
|
||||
},
|
||||
"exports": {
|
||||
@ -21,6 +22,7 @@
|
||||
"@napi-rs/simple-git": "^0.1.19",
|
||||
"@perfsee/webpack": "^1.13.0",
|
||||
"@sentry/webpack-plugin": "^3.0.0",
|
||||
"@swc/core": "^1.10.1",
|
||||
"@tailwindcss/postcss": "^4.0.0",
|
||||
"@vanilla-extract/webpack-plugin": "^2.3.15",
|
||||
"autoprefixer": "^10.4.20",
|
||||
@ -34,6 +36,7 @@
|
||||
"lodash-es": "^4.17.21",
|
||||
"mime-types": "^3.0.0",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
"node-loader": "^2.1.0",
|
||||
"postcss": "^8.4.49",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"prettier": "^3.4.2",
|
||||
|
@ -10,12 +10,16 @@ import WebpackDevServer, {
|
||||
} from 'webpack-dev-server';
|
||||
|
||||
import { Option, PackageCommand } from './command';
|
||||
import { createHTMLTargetConfig, createWorkerTargetConfig } from './webpack';
|
||||
import {
|
||||
createHTMLTargetConfig,
|
||||
createNodeTargetConfig,
|
||||
createWorkerTargetConfig,
|
||||
} from './webpack';
|
||||
|
||||
function getBundleConfigs(pkg: Package) {
|
||||
function getBaseWorkerConfigs(pkg: Package) {
|
||||
const core = new Package('@affine/core');
|
||||
|
||||
const workerConfigs = [
|
||||
return [
|
||||
createWorkerTargetConfig(
|
||||
pkg,
|
||||
core.srcPath.join(
|
||||
@ -31,7 +35,9 @@ function getBundleConfigs(pkg: Package) {
|
||||
core.srcPath.join('blocksuite/extensions/turbo-painter.worker.ts').value
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
function getBundleConfigs(pkg: Package) {
|
||||
switch (pkg.name) {
|
||||
case '@affine/admin': {
|
||||
return [createHTMLTargetConfig(pkg, pkg.srcPath.join('index.tsx').value)];
|
||||
@ -40,6 +46,7 @@ function getBundleConfigs(pkg: Package) {
|
||||
case '@affine/mobile':
|
||||
case '@affine/ios':
|
||||
case '@affine/android': {
|
||||
const workerConfigs = getBaseWorkerConfigs(pkg);
|
||||
workerConfigs.push(
|
||||
createWorkerTargetConfig(
|
||||
pkg,
|
||||
@ -58,6 +65,8 @@ function getBundleConfigs(pkg: Package) {
|
||||
];
|
||||
}
|
||||
case '@affine/electron-renderer': {
|
||||
const workerConfigs = getBaseWorkerConfigs(pkg);
|
||||
|
||||
return [
|
||||
createHTMLTargetConfig(
|
||||
pkg,
|
||||
@ -78,10 +87,14 @@ function getBundleConfigs(pkg: Package) {
|
||||
...workerConfigs,
|
||||
];
|
||||
}
|
||||
case '@affine/server': {
|
||||
return [createNodeTargetConfig(pkg, pkg.srcPath.join('index.ts').value)];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported package: ${pkg.name}`);
|
||||
}
|
||||
|
||||
const IN_CI = !!process.env.CI;
|
||||
const httpProxyMiddlewareLogLevel = IN_CI ? 'silent' : 'error';
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { createRequire } from 'node:module';
|
||||
import path from 'node:path';
|
||||
|
||||
import { getBuildConfig } from '@affine-tools/utils/build-config';
|
||||
import { ProjectRoot } from '@affine-tools/utils/path';
|
||||
import { Path, ProjectRoot } from '@affine-tools/utils/path';
|
||||
import { Package } from '@affine-tools/utils/workspace';
|
||||
import { PerfseePlugin } from '@perfsee/webpack';
|
||||
import { sentryWebpackPlugin } from '@sentry/webpack-plugin';
|
||||
@ -75,10 +75,7 @@ export function createHTMLTargetConfig(
|
||||
},
|
||||
entry,
|
||||
output: {
|
||||
environment: {
|
||||
module: true,
|
||||
dynamicImport: true,
|
||||
},
|
||||
environment: { module: true, dynamicImport: true },
|
||||
filename: buildConfig.debug
|
||||
? 'js/[name].js'
|
||||
: 'js/[name].[contenthash:8].js',
|
||||
@ -127,12 +124,7 @@ export function createHTMLTargetConfig(
|
||||
},
|
||||
//#region rules
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?js?$/,
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
{ test: /\.m?js?$/, resolve: { fullySpecified: false } },
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
@ -185,9 +177,7 @@ export function createHTMLTargetConfig(
|
||||
target: 'es2022',
|
||||
externalHelpers: false,
|
||||
transform: {
|
||||
react: {
|
||||
runtime: 'automatic',
|
||||
},
|
||||
react: { runtime: 'automatic' },
|
||||
useDefineForClassFields: false,
|
||||
decoratorVersion: '2022-03',
|
||||
},
|
||||
@ -200,18 +190,9 @@ export function createHTMLTargetConfig(
|
||||
test: /\.(png|jpg|gif|svg|webp|mp4|zip)$/,
|
||||
type: 'asset/resource',
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|eot|woff|woff2)$/,
|
||||
type: 'asset/resource',
|
||||
},
|
||||
{
|
||||
test: /\.txt$/,
|
||||
type: 'asset/source',
|
||||
},
|
||||
{
|
||||
test: /\.inline\.svg$/,
|
||||
type: 'asset/inline',
|
||||
},
|
||||
{ test: /\.(ttf|eot|woff|woff2)$/, type: 'asset/resource' },
|
||||
{ test: /\.txt$/, type: 'asset/source' },
|
||||
{ test: /\.inline\.svg$/, type: 'asset/inline' },
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
@ -242,12 +223,7 @@ export function createHTMLTargetConfig(
|
||||
]
|
||||
: [
|
||||
cssnano({
|
||||
preset: [
|
||||
'default',
|
||||
{
|
||||
convertValues: false,
|
||||
},
|
||||
],
|
||||
preset: ['default', { convertValues: false }],
|
||||
}),
|
||||
],
|
||||
},
|
||||
@ -298,9 +274,7 @@ export function createHTMLTargetConfig(
|
||||
new WebpackS3Plugin(),
|
||||
!buildConfig.debug &&
|
||||
process.env.PERFSEE_TOKEN &&
|
||||
new PerfseePlugin({
|
||||
project: 'affine-toeverything',
|
||||
}),
|
||||
new PerfseePlugin({ project: 'affine-toeverything' }),
|
||||
process.env.SENTRY_AUTH_TOKEN &&
|
||||
process.env.SENTRY_ORG &&
|
||||
process.env.SENTRY_PROJECT &&
|
||||
@ -325,9 +299,7 @@ export function createHTMLTargetConfig(
|
||||
]),
|
||||
//#endregion
|
||||
|
||||
stats: {
|
||||
errorDetails: true,
|
||||
},
|
||||
stats: { errorDetails: true },
|
||||
|
||||
//#region optimization
|
||||
optimization: {
|
||||
@ -339,12 +311,8 @@ export function createHTMLTargetConfig(
|
||||
extractComments: true,
|
||||
terserOptions: {
|
||||
ecma: 2020,
|
||||
compress: {
|
||||
unused: true,
|
||||
},
|
||||
mangle: {
|
||||
keep_classnames: true,
|
||||
},
|
||||
compress: { unused: true },
|
||||
mangle: { keep_classnames: true },
|
||||
},
|
||||
}),
|
||||
],
|
||||
@ -353,9 +321,7 @@ export function createHTMLTargetConfig(
|
||||
usedExports: true,
|
||||
sideEffects: true,
|
||||
removeAvailableModules: true,
|
||||
runtimeChunk: {
|
||||
name: 'runtime',
|
||||
},
|
||||
runtimeChunk: { name: 'runtime' },
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
minSize: 1,
|
||||
@ -382,11 +348,7 @@ export function createHTMLTargetConfig(
|
||||
priority: -10,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
default: {
|
||||
minChunks: 2,
|
||||
priority: -20,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
default: { minChunks: 2, priority: -20, reuseExistingChunk: true },
|
||||
styles: {
|
||||
name: 'styles',
|
||||
type: 'css/mini-extract',
|
||||
@ -416,9 +378,7 @@ export function createWorkerTargetConfig(
|
||||
outputModule: false,
|
||||
syncWebAssembly: true,
|
||||
},
|
||||
entry: {
|
||||
[workerName]: entry,
|
||||
},
|
||||
entry: { [workerName]: entry },
|
||||
output: {
|
||||
filename: `js/${workerName}-${buildConfig.appVersion}.worker.js`,
|
||||
path: pkg.distPath.value,
|
||||
@ -432,14 +392,9 @@ export function createWorkerTargetConfig(
|
||||
devtool: buildConfig.debug ? 'cheap-module-source-map' : 'source-map',
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
extensionAlias: {
|
||||
'.js': ['.js', '.ts'],
|
||||
'.mjs': ['.mjs', '.mts'],
|
||||
},
|
||||
extensionAlias: { '.js': ['.js', '.ts'], '.mjs': ['.mjs', '.mts'] },
|
||||
extensions: ['.js', '.ts'],
|
||||
alias: {
|
||||
yjs: ProjectRoot.join('node_modules', 'yjs').value,
|
||||
},
|
||||
alias: { yjs: ProjectRoot.join('node_modules', 'yjs').value },
|
||||
},
|
||||
|
||||
module: {
|
||||
@ -454,12 +409,7 @@ export function createWorkerTargetConfig(
|
||||
},
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?js?$/,
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
{ test: /\.m?js?$/, resolve: { fullySpecified: false } },
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
@ -508,9 +458,7 @@ export function createWorkerTargetConfig(
|
||||
{} as Record<string, string>
|
||||
)
|
||||
),
|
||||
new webpack.optimize.LimitChunkCountPlugin({
|
||||
maxChunks: 1,
|
||||
}),
|
||||
new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
|
||||
process.env.SENTRY_AUTH_TOKEN &&
|
||||
process.env.SENTRY_ORG &&
|
||||
process.env.SENTRY_PROJECT &&
|
||||
@ -520,9 +468,7 @@ export function createWorkerTargetConfig(
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
}),
|
||||
]),
|
||||
stats: {
|
||||
errorDetails: true,
|
||||
},
|
||||
stats: { errorDetails: true },
|
||||
optimization: {
|
||||
minimize: !buildConfig.debug,
|
||||
minimizer: [
|
||||
@ -532,12 +478,8 @@ export function createWorkerTargetConfig(
|
||||
extractComments: true,
|
||||
terserOptions: {
|
||||
ecma: 2020,
|
||||
compress: {
|
||||
unused: true,
|
||||
},
|
||||
mangle: {
|
||||
keep_classnames: true,
|
||||
},
|
||||
compress: { unused: true },
|
||||
mangle: { keep_classnames: true },
|
||||
},
|
||||
}),
|
||||
],
|
||||
@ -549,8 +491,120 @@ export function createWorkerTargetConfig(
|
||||
runtimeChunk: false,
|
||||
splitChunks: false,
|
||||
},
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
performance: { hints: false },
|
||||
};
|
||||
}
|
||||
|
||||
export function createNodeTargetConfig(
|
||||
pkg: Package,
|
||||
entry: string
|
||||
): Omit<webpack.Configuration, 'name'> & { name: string } {
|
||||
return {
|
||||
name: entry,
|
||||
context: ProjectRoot.value,
|
||||
experiments: {
|
||||
topLevelAwait: true,
|
||||
outputModule: pkg.packageJson.type === 'module',
|
||||
syncWebAssembly: true,
|
||||
},
|
||||
entry: { index: entry },
|
||||
output: {
|
||||
filename: `main.js`,
|
||||
path: pkg.distPath.value,
|
||||
clean: true,
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
target: ['node', 'es2022'],
|
||||
externals: (data, callback) => {
|
||||
if (
|
||||
data.request &&
|
||||
// import ... from 'module'
|
||||
/^[a-zA-Z@]/.test(data.request) &&
|
||||
// not workspace deps
|
||||
!pkg.deps.some(dep => data.request!.startsWith(dep.name))
|
||||
) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
callback(null, false);
|
||||
}
|
||||
},
|
||||
externalsPresets: { node: true },
|
||||
node: { __dirname: false, __filename: false },
|
||||
mode: 'none',
|
||||
devtool: 'source-map',
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
extensionAlias: { '.js': ['.js', '.ts'], '.mjs': ['.mjs', '.mts'] },
|
||||
extensions: ['.js', '.ts', '.tsx', '.node'],
|
||||
alias: { yjs: ProjectRoot.join('node_modules', 'yjs').value },
|
||||
},
|
||||
module: {
|
||||
parser: {
|
||||
javascript: { url: false, importMeta: false, createRequire: false },
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
include: /@blocksuite/,
|
||||
use: ['source-map-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.node$/,
|
||||
loader: Path.dir(import.meta.url).join('node-loader.js').value,
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
// https://swc.rs/docs/configuring-swc/
|
||||
jsc: {
|
||||
preserveAllComments: true,
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
dynamicImport: true,
|
||||
topLevelAwait: true,
|
||||
tsx: true,
|
||||
decorators: true,
|
||||
},
|
||||
target: 'es2022',
|
||||
externalHelpers: false,
|
||||
transform: {
|
||||
legacyDecorator: true,
|
||||
decoratorMetadata: true,
|
||||
react: { runtime: 'automatic' },
|
||||
},
|
||||
},
|
||||
sourceMaps: true,
|
||||
inlineSourcesContent: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: compact([
|
||||
new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
|
||||
new webpack.IgnorePlugin({
|
||||
checkResource(resource) {
|
||||
const lazyImports = [
|
||||
'@nestjs/microservices',
|
||||
'@nestjs/websockets/socket-module',
|
||||
'@apollo/subgraph',
|
||||
'@apollo/gateway',
|
||||
'@as-integrations/fastify',
|
||||
'ts-morph',
|
||||
'class-validator',
|
||||
'class-transformer',
|
||||
];
|
||||
return lazyImports.some(lazyImport =>
|
||||
resource.startsWith(lazyImport)
|
||||
);
|
||||
},
|
||||
}),
|
||||
]),
|
||||
stats: { errorDetails: true },
|
||||
optimization: { nodeEnv: false },
|
||||
performance: { hints: false },
|
||||
ignoreWarnings: [/^(?!CriticalDependenciesWarning$)/],
|
||||
};
|
||||
}
|
||||
|
18
tools/cli/src/webpack/node-loader.js
Normal file
18
tools/cli/src/webpack/node-loader.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { parse } from 'node:path';
|
||||
|
||||
export const raw = true;
|
||||
/**
|
||||
* @type {import('webpack').LoaderDefinitionFunction}
|
||||
*/
|
||||
export default function loader(content) {
|
||||
const name = parse(this.resourcePath).base;
|
||||
this.emitFile(name, content);
|
||||
|
||||
return `
|
||||
import { createRequire } from 'node:module'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const binding = require('./${name}')
|
||||
export default binding
|
||||
`;
|
||||
}
|
@ -8,13 +8,12 @@ export interface YarnWorkspaceItem {
|
||||
|
||||
export interface CommonPackageJsonContent {
|
||||
name: string;
|
||||
type?: 'module' | 'commonjs';
|
||||
version: string;
|
||||
private?: boolean;
|
||||
dependencies?: { [key: string]: string };
|
||||
devDependencies?: { [key: string]: string };
|
||||
scripts?: { [key: string]: string };
|
||||
main?: string;
|
||||
exports?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
exports?: { [key: string]: string | { [key: string]: string } };
|
||||
}
|
||||
|
@ -963,10 +963,10 @@ export const PackageList = [
|
||||
location: 'packages/backend/server',
|
||||
name: '@affine/server',
|
||||
workspaceDependencies: [
|
||||
'packages/backend/native',
|
||||
'tools/cli',
|
||||
'tools/utils',
|
||||
'packages/common/graphql',
|
||||
'packages/backend/native',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
19
yarn.lock
19
yarn.lock
@ -122,6 +122,7 @@ __metadata:
|
||||
"@napi-rs/simple-git": "npm:^0.1.19"
|
||||
"@perfsee/webpack": "npm:^1.13.0"
|
||||
"@sentry/webpack-plugin": "npm:^3.0.0"
|
||||
"@swc/core": "npm:^1.10.1"
|
||||
"@tailwindcss/postcss": "npm:^4.0.0"
|
||||
"@types/lodash-es": "npm:^4.17.12"
|
||||
"@types/mime-types": "npm:^2.1.4"
|
||||
@ -139,6 +140,7 @@ __metadata:
|
||||
lodash-es: "npm:^4.17.21"
|
||||
mime-types: "npm:^3.0.0"
|
||||
mini-css-extract-plugin: "npm:^2.9.2"
|
||||
node-loader: "npm:^2.1.0"
|
||||
postcss: "npm:^8.4.49"
|
||||
postcss-loader: "npm:^8.1.1"
|
||||
prettier: "npm:^3.4.2"
|
||||
@ -155,6 +157,7 @@ __metadata:
|
||||
webpack-dev-server: "npm:^5.2.0"
|
||||
webpack-merge: "npm:^6.0.1"
|
||||
bin:
|
||||
affine: ./bin/cli.js
|
||||
r: ./bin/runner.js
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
@ -417,7 +420,6 @@ __metadata:
|
||||
"@radix-ui/react-slot": "npm:^1.1.1"
|
||||
"@radix-ui/react-toolbar": "npm:^1.1.1"
|
||||
"@sentry/react": "npm:^9.2.0"
|
||||
"@swc/core": "npm:^1.10.1"
|
||||
"@testing-library/dom": "npm:^10.4.0"
|
||||
"@testing-library/react": "npm:^16.1.0"
|
||||
"@toeverything/infra": "workspace:*"
|
||||
@ -760,7 +762,6 @@ __metadata:
|
||||
"@magic-works/i18n-codegen": "npm:^0.6.1"
|
||||
"@playwright/test": "npm:=1.51.1"
|
||||
"@smarttools/eslint-plugin-rxjs": "npm:^1.0.8"
|
||||
"@swc/core": "npm:^1.10.1"
|
||||
"@taplo/cli": "npm:^0.7.0"
|
||||
"@toeverything/infra": "workspace:*"
|
||||
"@types/eslint": "npm:^9.6.1"
|
||||
@ -14286,7 +14287,6 @@ __metadata:
|
||||
"@affine/templates": "workspace:*"
|
||||
"@emotion/react": "npm:^11.14.0"
|
||||
"@preact/signals-core": "npm:^1.8.0"
|
||||
"@swc/core": "npm:^1.10.1"
|
||||
"@testing-library/dom": "npm:^10.4.0"
|
||||
"@testing-library/react": "npm:^16.1.0"
|
||||
"@types/react": "npm:^19.0.1"
|
||||
@ -25152,7 +25152,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"loader-utils@npm:^2.0.0":
|
||||
"loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.3":
|
||||
version: 2.0.4
|
||||
resolution: "loader-utils@npm:2.0.4"
|
||||
dependencies:
|
||||
@ -27414,6 +27414,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-loader@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "node-loader@npm:2.1.0"
|
||||
dependencies:
|
||||
loader-utils: "npm:^2.0.3"
|
||||
peerDependencies:
|
||||
webpack: ^5.0.0
|
||||
checksum: 10/d2f20b1e0f946055fcbbf365c3927ffecfff9aee3b5cc2d71e45229ca27010267d3d6fdea04dcb7c0bc7ce9b87878105b8c1d15c05065c813b5c8ec5ef1fb4d1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-releases@npm:^2.0.19":
|
||||
version: 2.0.19
|
||||
resolution: "node-releases@npm:2.0.19"
|
||||
|
Loading…
x
Reference in New Issue
Block a user