mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-04 16:44:56 +00:00
Compare commits
5 Commits
06-18-feat
...
v0.19.5-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b14f1cdb7c | ||
|
|
22a8694972 | ||
|
|
bbe88c57b7 | ||
|
|
a3b502fad7 | ||
|
|
28f0dad3f9 |
@@ -5,10 +5,4 @@ rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.'cfg(target_os = "linux")']
|
||||
rustflags = ["-C", "link-args=-Wl,--warn-unresolved-symbols"]
|
||||
[target.'cfg(target_os = "macos")']
|
||||
rustflags = ["-C", "link-args=-Wl,-undefined,dynamic_lookup,-no_fixup_chains", "-C", "link-args=-all_load", "-C", "link-args=-weak_framework ScreenCaptureKit"]
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=21032
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=21031
|
||||
# https://github.com/rust-lang/rust/issues/134820
|
||||
# pthread_key_create() destructors and segfault after a DSO unloading
|
||||
[target.'cfg(all(target_env = "gnu", not(target_os = "windows")))']
|
||||
rustflags = ["-C", "link-args=-Wl,-z,nodelete"]
|
||||
rustflags = ["-C", "link-args=-all_load"]
|
||||
|
||||
9
.devcontainer/Dockerfile
Normal file
9
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
||||
FROM mcr.microsoft.com/devcontainers/base:bookworm
|
||||
|
||||
# Install Homebrew For Linux
|
||||
RUN /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && \
|
||||
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" && \
|
||||
echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> /home/vscode/.zshrc && \
|
||||
echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> /home/vscode/.bashrc && \
|
||||
# Install Graphite
|
||||
brew install withgraphite/tap/graphite && gt --version
|
||||
@@ -1,12 +1,15 @@
|
||||
#!/bin/bash
|
||||
# This is a script used by the devcontainer to build the project
|
||||
|
||||
#Enable yarn
|
||||
corepack enable
|
||||
corepack prepare yarn@stable --activate
|
||||
|
||||
# install dependencies
|
||||
yarn install
|
||||
|
||||
# Build Server Dependencies
|
||||
yarn affine @affine/server-native build
|
||||
yarn affine @affine/reader build
|
||||
|
||||
# Create database
|
||||
yarn affine @affine/server prisma migrate reset -f
|
||||
yarn affine @affine/server prisma db push
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json.
|
||||
{
|
||||
"name": "AFFiNE Dev Container",
|
||||
"name": "Debian",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
"containerEnv": {
|
||||
"COREPACK_ENABLE_DOWNLOAD_PROMPT": "0"
|
||||
},
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "lts",
|
||||
"installYarnUsingApt": false
|
||||
"version": "18"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/rust:1": {}
|
||||
},
|
||||
@@ -20,7 +16,7 @@
|
||||
"extensions": [
|
||||
"ms-playwright.playwright",
|
||||
"esbenp.prettier-vscode",
|
||||
"dbaeumer.vscode-eslint"
|
||||
"streetsidesoftware.code-spell-checker"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,7 +2,9 @@ version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
image: mcr.microsoft.com/devcontainers/base:bookworm
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
volumes:
|
||||
- ../..:/workspaces:cached
|
||||
command: sleep infinity
|
||||
@@ -10,10 +12,9 @@ services:
|
||||
environment:
|
||||
DATABASE_URL: postgresql://affine:affine@db:5432/affine
|
||||
REDIS_SERVER_HOST: redis
|
||||
AFFINE_INDEXER_SEARCH_ENDPOINT: http://indexer:9308
|
||||
|
||||
db:
|
||||
image: pgvector/pgvector:pg16
|
||||
image: postgres:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
@@ -23,20 +24,8 @@ services:
|
||||
POSTGRES_DB: affine
|
||||
redis:
|
||||
image: redis
|
||||
|
||||
indexer:
|
||||
image: manticoresearch/manticore:${MANTICORE_VERSION:-9.3.2}
|
||||
ulimits:
|
||||
nproc: 65535
|
||||
nofile:
|
||||
soft: 65535
|
||||
hard: 65535
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- manticoresearch_data:/var/lib/manticore
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
manticoresearch_data:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
set -e
|
||||
|
||||
npm install -g @withgraphite/graphite-cli@stable
|
||||
|
||||
if [ -v GRAPHITE_TOKEN ];then
|
||||
gt auth --token $GRAPHITE_TOKEN
|
||||
fi
|
||||
|
||||
git fetch origin canary:canary --depth=1
|
||||
git branch canary -t origin/canary
|
||||
gt init --trunk canary
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
# postgres major version
|
||||
DB_VERSION=16
|
||||
# database credentials
|
||||
DATABASE_LOCATION=./postgres
|
||||
DB_PASSWORD=affine
|
||||
DB_USERNAME=affine
|
||||
DB_DATABASE_NAME=affine
|
||||
|
||||
# elasticsearch env
|
||||
# ELASTIC_VERSION=9.0.1
|
||||
# enable for arm64, e.g.: macOS M1+
|
||||
# ELASTIC_VERSION_ARM64=-arm64
|
||||
# ELASTIC_PLATFORM=linux/arm64
|
||||
|
||||
# manticoresearch
|
||||
MANTICORE_VERSION=9.3.2
|
||||
DB_DATABASE_NAME=affine
|
||||
5
.docker/dev/.gitignore
vendored
5
.docker/dev/.gitignore
vendored
@@ -1,6 +1,3 @@
|
||||
postgres
|
||||
.env
|
||||
compose.yml
|
||||
certs/*
|
||||
!certs/.gitkeep
|
||||
nginx/conf.d/*
|
||||
compose.yml
|
||||
@@ -1,27 +0,0 @@
|
||||
# Dev containers
|
||||
|
||||
## Develop with domain
|
||||
|
||||
> MacOs only, OrbStack only
|
||||
|
||||
### 1. Generate and install Root CA
|
||||
|
||||
```bash
|
||||
# the root ca file will be located at `./.docker/dev/certs/ca`
|
||||
yarn affine cert --install
|
||||
```
|
||||
|
||||
### 2. Generate domain certs
|
||||
|
||||
```bash
|
||||
# certificates will be located at `./.docker/dev/certs/${domain}`
|
||||
yarn affine cert --domain dev.affine.fail
|
||||
```
|
||||
|
||||
### 3. Enable dns and nginx service in compose.yml
|
||||
|
||||
### 4. Add custom dns server
|
||||
|
||||
```bash
|
||||
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/dev.affine.fail
|
||||
```
|
||||
@@ -3,7 +3,7 @@ services:
|
||||
postgres:
|
||||
env_file:
|
||||
- .env
|
||||
image: pgvector/pgvector:pg${DB_VERSION:-16}
|
||||
image: postgres:16
|
||||
ports:
|
||||
- 5432:5432
|
||||
environment:
|
||||
@@ -24,78 +24,8 @@ services:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
|
||||
# https://manual.manticoresearch.com/Starting_the_server/Docker
|
||||
manticoresearch:
|
||||
image: manticoresearch/manticore:${MANTICORE_VERSION:-9.3.2}
|
||||
ports:
|
||||
- 9308:9308
|
||||
ulimits:
|
||||
nproc: 65535
|
||||
nofile:
|
||||
soft: 65535
|
||||
hard: 65535
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- manticoresearch_data:/var/lib/manticore
|
||||
|
||||
# elasticsearch:
|
||||
# image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-9.0.1}${ELASTIC_VERSION_ARM64}
|
||||
# platform: ${ELASTIC_PLATFORM}
|
||||
# labels:
|
||||
# co.elastic.logs/module: elasticsearch
|
||||
# volumes:
|
||||
# - elasticsearch_data:/usr/share/elasticsearch/data
|
||||
# ports:
|
||||
# - ${ES_PORT:-9200}:9200
|
||||
# environment:
|
||||
# - node.name=es01
|
||||
# - cluster.name=affine-dev
|
||||
# - discovery.type=single-node
|
||||
# - bootstrap.memory_lock=true
|
||||
# - xpack.security.enabled=false
|
||||
# - xpack.security.http.ssl.enabled=false
|
||||
# - xpack.security.transport.ssl.enabled=false
|
||||
# - xpack.license.self_generated.type=basic
|
||||
# mem_limit: ${ES_MEM_LIMIT:-1073741824}
|
||||
# ulimits:
|
||||
# memlock:
|
||||
# soft: -1
|
||||
# hard: -1
|
||||
# healthcheck:
|
||||
# test:
|
||||
# [
|
||||
# "CMD-SHELL",
|
||||
# "curl -s http://localhost:9200 | grep -q 'affine-dev'",
|
||||
# ]
|
||||
# interval: 10s
|
||||
# timeout: 10s
|
||||
# retries: 120
|
||||
|
||||
# dns:
|
||||
# image: strm/dnsmasq
|
||||
# volumes:
|
||||
# - ./dnsmasq.conf:/etc/dnsmasq.d/local.conf
|
||||
# ports:
|
||||
# - "53:53/udp"
|
||||
# cap_add:
|
||||
# - NET_ADMIN
|
||||
# depends_on:
|
||||
# - nginx
|
||||
|
||||
# nginx:
|
||||
# image: nginx:alpine
|
||||
# volumes:
|
||||
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
# - ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||
# - ./certs:/etc/nginx/certs:ro
|
||||
# network_mode: host
|
||||
|
||||
networks:
|
||||
dev:
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
manticoresearch_data:
|
||||
elasticsearch_data:
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
log-queries
|
||||
address=/dev.affine.fail/127.0.0.1
|
||||
@@ -1,28 +0,0 @@
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
client_max_body_size 512M;
|
||||
server_names_hash_bucket_size 128;
|
||||
ssi on;
|
||||
gzip on;
|
||||
include "/etc/nginx/conf.d/*";
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name DEV_DOMAIN;
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
ssl_certificate /etc/nginx/certs/$host/crt;
|
||||
ssl_certificate_key /etc/nginx/certs/$host/key;
|
||||
server_name DEV_DOMAIN;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
resolver 127.0.0.1;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
[req]
|
||||
distinguished_name = req_distinguished_name
|
||||
req_extensions = v3_req
|
||||
|
||||
[req_distinguished_name]
|
||||
countryName = Country Name (2 letter code)
|
||||
countryName_default = US
|
||||
stateOrProvinceName = State or Province Name (full name)
|
||||
stateOrProvinceName_default = MN
|
||||
localityName = Locality Name (eg, city)
|
||||
localityName_default = Minneapolis
|
||||
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||
organizationalUnitName_default = Domain Control Validated
|
||||
commonName = Internet Widgits Ltd
|
||||
commonName_max = 64
|
||||
|
||||
[ v3_req ]
|
||||
# Extensions to add to a certificate request
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = DEV_DOMAIN
|
||||
DNS.2 = *.DEV_DOMAIN
|
||||
@@ -20,4 +20,4 @@ CONFIG_LOCATION=~/.affine/self-host/config
|
||||
# database credentials
|
||||
DB_USERNAME=affine
|
||||
DB_PASSWORD=
|
||||
DB_DATABASE=affine
|
||||
DB_DATABASE=affine
|
||||
1
.docker/selfhost/.gitignore
vendored
1
.docker/selfhost/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
.env
|
||||
@@ -21,7 +21,6 @@ services:
|
||||
environment:
|
||||
- REDIS_SERVER_HOST=redis
|
||||
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}
|
||||
- AFFINE_INDEXER_ENABLED=false
|
||||
restart: unless-stopped
|
||||
|
||||
affine_migration:
|
||||
@@ -37,7 +36,6 @@ services:
|
||||
environment:
|
||||
- REDIS_SERVER_HOST=redis
|
||||
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}
|
||||
- AFFINE_INDEXER_ENABLED=false
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
@@ -46,7 +44,7 @@ services:
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
container_name: affine_redis
|
||||
container_name: redis
|
||||
healthcheck:
|
||||
test: ['CMD', 'redis-cli', '--raw', 'incr', 'ping']
|
||||
interval: 10s
|
||||
@@ -55,8 +53,8 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
postgres:
|
||||
image: pgvector/pgvector:pg16
|
||||
container_name: affine_postgres
|
||||
image: postgres:16
|
||||
container_name: postgres
|
||||
volumes:
|
||||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||
environment:
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"$schema": "https://github.com/toeverything/affine/releases/latest/download/config.schema.json",
|
||||
"server": {
|
||||
"name": "AFFiNE Self Hosted Server"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@@ -1,2 +1 @@
|
||||
/blocksuite/ @toeverything/blocksuite-core
|
||||
/packages/frontend/core/src/blocksuite @toeverything/blocksuite-core
|
||||
|
||||
23
.github/ISSUE_TEMPLATE/BUG-REPORT.yml
vendored
23
.github/ISSUE_TEMPLATE/BUG-REPORT.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
title: '[Bug]: '
|
||||
title: "\u200b"
|
||||
labels: ['bug']
|
||||
body:
|
||||
- type: markdown
|
||||
@@ -18,26 +18,20 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: distribution
|
||||
id: version
|
||||
attributes:
|
||||
label: Distribution version
|
||||
description: What distribution of AFFiNE are you using?
|
||||
description: What version of AFFiNE are you using?
|
||||
options:
|
||||
- macOS x64 (Intel)
|
||||
- macOS ARM 64 (Apple Silicon)
|
||||
- Windows x64
|
||||
- Linux
|
||||
- Web (https://app.affine.pro)
|
||||
- Beta Web (https://insider.affine.pro)
|
||||
- Canary Web (https://affine.fail)
|
||||
- Web (app.affine.pro)
|
||||
- Web (affine.fail)
|
||||
- Web (insider.affine.pro)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: App Version
|
||||
description: What version of AFFiNE are you using?
|
||||
placeholder: (You can find AFFiNE version in [About AFFiNE] setting panel)
|
||||
- type: dropdown
|
||||
id: browsers
|
||||
attributes:
|
||||
@@ -57,11 +51,6 @@ body:
|
||||
If you are self-hosting, please check the box and provide information about your setup.
|
||||
options:
|
||||
- label: 'Yes'
|
||||
- type: input
|
||||
id: selfhost-version
|
||||
attributes:
|
||||
label: Self-hosting Version
|
||||
description: What version of AFFiNE are you selfhosting?
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml
vendored
3
.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml
vendored
@@ -1,8 +1,7 @@
|
||||
name: Feature Request
|
||||
description: Suggest a feature or improvement
|
||||
title: '[Feature Request]: '
|
||||
title: "\u200b"
|
||||
labels: ['feat', 'story']
|
||||
assignees: ['hwangdev97']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
10
.github/actions/build-rust/action.yml
vendored
10
.github/actions/build-rust/action.yml
vendored
@@ -44,14 +44,12 @@ runs:
|
||||
RUSTUP_HOME: ${{ env.DEV_DRIVE }}/.rustup
|
||||
|
||||
- name: Set CC
|
||||
if: ${{ contains(inputs.target, 'linux') && inputs.no-build != 'true' }}
|
||||
if: ${{ contains(inputs.target, 'linux') && inputs.package != '@affine/native' && inputs.no-build != 'true' }}
|
||||
working-directory: ${{ env.DEV_DRIVE_WORKSPACE || github.workspace }}
|
||||
shell: bash
|
||||
# https://github.com/tree-sitter/tree-sitter/issues/4186
|
||||
# pass -D_BSD_SOURCE to clang to fix the tree-sitter build issue
|
||||
run: |
|
||||
echo "CC=clang -D_BSD_SOURCE" >> "$GITHUB_ENV"
|
||||
echo "TARGET_CC=clang -D_BSD_SOURCE" >> "$GITHUB_ENV"
|
||||
echo "CC=clang" >> "$GITHUB_ENV"
|
||||
echo "TARGET_CC=clang" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Cache cargo
|
||||
uses: Swatinem/rust-cache@v2
|
||||
@@ -84,7 +82,7 @@ runs:
|
||||
shell: bash
|
||||
if: ${{ runner.os == 'Windows' && inputs.no-build != 'true' }}
|
||||
run: |
|
||||
yarn workspace ${{ inputs.package }} build --target ${{ inputs.target }}
|
||||
yarn workspace ${{ inputs.package }} build --target ${{ inputs.target }} --use-napi-cross
|
||||
env:
|
||||
DEBUG: 'napi:*'
|
||||
CARGO_HOME: ${{ env.DEV_DRIVE }}/.cargo
|
||||
|
||||
11
.github/actions/copilot-test/action.yml
vendored
11
.github/actions/copilot-test/action.yml
vendored
@@ -5,16 +5,27 @@ inputs:
|
||||
description: 'Script to run'
|
||||
default: 'yarn affine @affine-test/affine-cloud-copilot e2e --forbid-only'
|
||||
required: false
|
||||
openai-key:
|
||||
description: 'OpenAI secret key'
|
||||
required: true
|
||||
fal-key:
|
||||
description: 'Fal secret key'
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Prepare Server Test Environment
|
||||
uses: ./.github/actions/server-test-env
|
||||
|
||||
- name: Server Copilot E2E Test
|
||||
shell: bash
|
||||
run: ${{ inputs.script }}
|
||||
env:
|
||||
COPILOT: true
|
||||
DEV_SERVER_URL: http://localhost:8080
|
||||
COPILOT_OPENAI_API_KEY: ${{ inputs.openai-key }}
|
||||
COPILOT_FAL_API_KEY: ${{ inputs.fal-key }}
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
|
||||
102
.github/actions/deploy/deploy.mjs
vendored
102
.github/actions/deploy/deploy.mjs
vendored
@@ -10,17 +10,30 @@ const {
|
||||
DATABASE_USERNAME,
|
||||
DATABASE_PASSWORD,
|
||||
DATABASE_NAME,
|
||||
GCLOUD_CONNECTION_NAME,
|
||||
R2_ACCOUNT_ID,
|
||||
R2_ACCESS_KEY_ID,
|
||||
R2_SECRET_ACCESS_KEY,
|
||||
CAPTCHA_TURNSTILE_SECRET,
|
||||
METRICS_CUSTOMER_IO_TOKEN,
|
||||
COPILOT_OPENAI_API_KEY,
|
||||
COPILOT_FAL_API_KEY,
|
||||
COPILOT_UNSPLASH_API_KEY,
|
||||
MAILER_SENDER,
|
||||
MAILER_USER,
|
||||
MAILER_PASSWORD,
|
||||
AFFINE_GOOGLE_CLIENT_ID,
|
||||
AFFINE_GOOGLE_CLIENT_SECRET,
|
||||
CLOUD_SQL_IAM_ACCOUNT,
|
||||
APP_IAM_ACCOUNT,
|
||||
REDIS_SERVER_HOST,
|
||||
REDIS_SERVER_PASSWORD,
|
||||
GCLOUD_CONNECTION_NAME,
|
||||
GCLOUD_CLOUD_SQL_INTERNAL_ENDPOINT,
|
||||
REDIS_HOST,
|
||||
REDIS_PASSWORD,
|
||||
STRIPE_API_KEY,
|
||||
STRIPE_WEBHOOK_KEY,
|
||||
STATIC_IP_NAME,
|
||||
AFFINE_INDEXER_SEARCH_PROVIDER,
|
||||
AFFINE_INDEXER_SEARCH_ENDPOINT,
|
||||
AFFINE_INDEXER_SEARCH_API_KEY,
|
||||
} = process.env;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const buildType = BUILD_TYPE || 'canary';
|
||||
|
||||
const isProduction = buildType === 'stable';
|
||||
@@ -33,21 +46,18 @@ const replicaConfig = {
|
||||
graphql: Number(process.env.PRODUCTION_GRAPHQL_REPLICA) || 3,
|
||||
sync: Number(process.env.PRODUCTION_SYNC_REPLICA) || 3,
|
||||
renderer: Number(process.env.PRODUCTION_RENDERER_REPLICA) || 3,
|
||||
doc: Number(process.env.PRODUCTION_DOC_REPLICA) || 3,
|
||||
},
|
||||
beta: {
|
||||
web: 2,
|
||||
graphql: Number(process.env.BETA_GRAPHQL_REPLICA) || 2,
|
||||
sync: Number(process.env.BETA_SYNC_REPLICA) || 2,
|
||||
renderer: Number(process.env.BETA_RENDERER_REPLICA) || 2,
|
||||
doc: Number(process.env.BETA_DOC_REPLICA) || 2,
|
||||
},
|
||||
canary: {
|
||||
web: 2,
|
||||
graphql: 2,
|
||||
sync: 2,
|
||||
renderer: 2,
|
||||
doc: 2,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -56,14 +66,12 @@ const cpuConfig = {
|
||||
web: '300m',
|
||||
graphql: '1',
|
||||
sync: '1',
|
||||
doc: '1',
|
||||
renderer: '300m',
|
||||
},
|
||||
canary: {
|
||||
web: '300m',
|
||||
graphql: '1',
|
||||
sync: '1',
|
||||
doc: '1',
|
||||
renderer: '300m',
|
||||
},
|
||||
};
|
||||
@@ -74,37 +82,27 @@ const createHelmCommand = ({ isDryRun }) => {
|
||||
const redisAndPostgres =
|
||||
isProduction || isBeta || isInternal
|
||||
? [
|
||||
`--set cloud-sql-proxy.enabled=true`,
|
||||
`--set-string cloud-sql-proxy.database.connectionName="${GCLOUD_CONNECTION_NAME}"`,
|
||||
`--set-string global.database.host=${DATABASE_URL}`,
|
||||
`--set-string global.database.url=${DATABASE_URL}`,
|
||||
`--set-string global.database.user=${DATABASE_USERNAME}`,
|
||||
`--set-string global.database.password=${DATABASE_PASSWORD}`,
|
||||
`--set-string global.database.name=${DATABASE_NAME}`,
|
||||
`--set-string global.redis.host="${REDIS_SERVER_HOST}"`,
|
||||
`--set-string global.redis.password="${REDIS_SERVER_PASSWORD}"`,
|
||||
`--set global.database.gcloud.enabled=true`,
|
||||
`--set-string global.database.gcloud.connectionName="${GCLOUD_CONNECTION_NAME}"`,
|
||||
`--set-string global.database.gcloud.cloudSqlInternal="${GCLOUD_CLOUD_SQL_INTERNAL_ENDPOINT}"`,
|
||||
`--set-string global.redis.host="${REDIS_HOST}"`,
|
||||
`--set-string global.redis.password="${REDIS_PASSWORD}"`,
|
||||
]
|
||||
: [];
|
||||
const indexerOptions = [
|
||||
`--set-string global.indexer.provider="${AFFINE_INDEXER_SEARCH_PROVIDER}"`,
|
||||
`--set-string global.indexer.endpoint="${AFFINE_INDEXER_SEARCH_ENDPOINT}"`,
|
||||
`--set-string global.indexer.apiKey="${AFFINE_INDEXER_SEARCH_API_KEY}"`,
|
||||
];
|
||||
const serviceAnnotations = [
|
||||
`--set-json web.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
|
||||
`--set-json graphql.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
|
||||
`--set-json sync.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
|
||||
`--set-json doc.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
|
||||
].concat(
|
||||
const serviceAnnotations =
|
||||
isProduction || isBeta || isInternal
|
||||
? [
|
||||
`--set-json web.service.annotations="{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }"`,
|
||||
`--set-json graphql.service.annotations="{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }"`,
|
||||
`--set-json sync.service.annotations="{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }"`,
|
||||
`--set-json cloud-sql-proxy.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${CLOUD_SQL_IAM_ACCOUNT}\\" }"`,
|
||||
`--set-json cloud-sql-proxy.nodeSelector="{ \\"iam.gke.io/gke-metadata-server-enabled\\": \\"true\\" }"`,
|
||||
`--set-json web.service.annotations=\"{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }\"`,
|
||||
`--set-json graphql.service.annotations=\"{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }\"`,
|
||||
`--set-json sync.service.annotations=\"{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }\"`,
|
||||
`--set-json cloud-sql-proxy.serviceAccount.annotations=\"{ \\"iam.gke.io/gcp-service-account\\": \\"${CLOUD_SQL_IAM_ACCOUNT}\\" }\"`,
|
||||
`--set-json cloud-sql-proxy.nodeSelector=\"{ \\"iam.gke.io/gke-metadata-server-enabled\\": \\"true\\" }\"`,
|
||||
]
|
||||
: []
|
||||
);
|
||||
: [];
|
||||
|
||||
const cpu = cpuConfig[buildType];
|
||||
const resources = cpu
|
||||
@@ -112,7 +110,6 @@ const createHelmCommand = ({ isDryRun }) => {
|
||||
`--set web.resources.requests.cpu="${cpu.web}"`,
|
||||
`--set graphql.resources.requests.cpu="${cpu.graphql}"`,
|
||||
`--set sync.resources.requests.cpu="${cpu.sync}"`,
|
||||
`--set doc.resources.requests.cpu="${cpu.doc}"`,
|
||||
]
|
||||
: [];
|
||||
|
||||
@@ -125,33 +122,50 @@ const createHelmCommand = ({ isDryRun }) => {
|
||||
: isInternal
|
||||
? 'internal'
|
||||
: 'dev';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const host = DEPLOY_HOST || CANARY_DEPLOY_HOST;
|
||||
const deployCommand = [
|
||||
`helm upgrade --install affine .github/helm/affine`,
|
||||
`--namespace ${namespace}`,
|
||||
`--set-string global.deployment.type="affine"`,
|
||||
`--set-string global.deployment.platform="gcp"`,
|
||||
`--set-string global.app.buildType="${buildType}"`,
|
||||
`--set global.ingress.enabled=true`,
|
||||
`--set-json global.ingress.annotations="{ \\"kubernetes.io/ingress.class\\": \\"gce\\", \\"kubernetes.io/ingress.allow-http\\": \\"true\\", \\"kubernetes.io/ingress.global-static-ip-name\\": \\"${STATIC_IP_NAME}\\" }"`,
|
||||
`--set-json global.ingress.annotations=\"{ \\"kubernetes.io/ingress.class\\": \\"gce\\", \\"kubernetes.io/ingress.allow-http\\": \\"true\\", \\"kubernetes.io/ingress.global-static-ip-name\\": \\"${STATIC_IP_NAME}\\" }\"`,
|
||||
`--set-string global.ingress.host="${host}"`,
|
||||
`--set global.objectStorage.r2.enabled=true`,
|
||||
`--set-string global.objectStorage.r2.accountId="${R2_ACCOUNT_ID}"`,
|
||||
`--set-string global.objectStorage.r2.accessKeyId="${R2_ACCESS_KEY_ID}"`,
|
||||
`--set-string global.objectStorage.r2.secretAccessKey="${R2_SECRET_ACCESS_KEY}"`,
|
||||
`--set-string global.version="${APP_VERSION}"`,
|
||||
...redisAndPostgres,
|
||||
...indexerOptions,
|
||||
`--set web.replicaCount=${replica.web}`,
|
||||
`--set-string web.image.tag="${imageTag}"`,
|
||||
`--set graphql.replicaCount=${replica.graphql}`,
|
||||
`--set-string graphql.image.tag="${imageTag}"`,
|
||||
`--set graphql.app.host=${host}`,
|
||||
`--set graphql.app.captcha.enabled=true`,
|
||||
`--set-string graphql.app.captcha.turnstile.secret="${CAPTCHA_TURNSTILE_SECRET}"`,
|
||||
`--set graphql.app.copilot.enabled=true`,
|
||||
`--set-string graphql.app.copilot.openai.key="${COPILOT_OPENAI_API_KEY}"`,
|
||||
`--set-string graphql.app.copilot.fal.key="${COPILOT_FAL_API_KEY}"`,
|
||||
`--set-string graphql.app.copilot.unsplash.key="${COPILOT_UNSPLASH_API_KEY}"`,
|
||||
`--set-string graphql.app.mailer.sender="${MAILER_SENDER}"`,
|
||||
`--set-string graphql.app.mailer.user="${MAILER_USER}"`,
|
||||
`--set-string graphql.app.mailer.password="${MAILER_PASSWORD}"`,
|
||||
`--set-string graphql.app.oauth.google.enabled=true`,
|
||||
`--set-string graphql.app.oauth.google.clientId="${AFFINE_GOOGLE_CLIENT_ID}"`,
|
||||
`--set-string graphql.app.oauth.google.clientSecret="${AFFINE_GOOGLE_CLIENT_SECRET}"`,
|
||||
`--set-string graphql.app.payment.stripe.apiKey="${STRIPE_API_KEY}"`,
|
||||
`--set-string graphql.app.payment.stripe.webhookKey="${STRIPE_WEBHOOK_KEY}"`,
|
||||
`--set graphql.app.metrics.enabled=true`,
|
||||
`--set-string graphql.app.metrics.customerIo.token="${METRICS_CUSTOMER_IO_TOKEN}"`,
|
||||
`--set graphql.app.experimental.enableJwstCodec=${namespace === 'dev'}`,
|
||||
`--set graphql.app.features.earlyAccessPreview=false`,
|
||||
`--set graphql.app.features.syncClientVersionCheck=true`,
|
||||
`--set sync.replicaCount=${replica.sync}`,
|
||||
`--set-string sync.image.tag="${imageTag}"`,
|
||||
`--set-string renderer.image.tag="${imageTag}"`,
|
||||
`--set renderer.app.host=${host}`,
|
||||
`--set renderer.replicaCount=${replica.renderer}`,
|
||||
`--set-string doc.image.tag="${imageTag}"`,
|
||||
`--set doc.app.host=${host}`,
|
||||
`--set doc.replicaCount=${replica.doc}`,
|
||||
...serviceAnnotations,
|
||||
...resources,
|
||||
`--timeout 10m`,
|
||||
|
||||
14
.github/actions/server-test-env/action.yml
vendored
14
.github/actions/server-test-env/action.yml
vendored
@@ -4,11 +4,6 @@ description: 'Prepare Server Test Environment'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Bundle @affine/reader
|
||||
shell: bash
|
||||
run: |
|
||||
yarn affine @affine/reader build
|
||||
|
||||
- name: Initialize database
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -24,12 +19,5 @@ runs:
|
||||
NODE_ENV: test
|
||||
run: |
|
||||
yarn affine @affine/server prisma generate
|
||||
yarn affine @affine/server prisma migrate deploy
|
||||
yarn affine @affine/server prisma db push
|
||||
yarn affine @affine/server data-migration run
|
||||
|
||||
- name: Import config
|
||||
shell: bash
|
||||
env:
|
||||
DEFAULT_CONFIG: '{}'
|
||||
run: |
|
||||
printf '%s\n' "${SERVER_CONFIG:-$DEFAULT_CONFIG}" > ./packages/backend/server/config.json
|
||||
|
||||
7
.github/actions/setup-node/action.yml
vendored
7
.github/actions/setup-node/action.yml
vendored
@@ -13,10 +13,6 @@ inputs:
|
||||
description: 'Run the install step for Playwright.'
|
||||
required: false
|
||||
default: 'false'
|
||||
playwright-platform:
|
||||
description: 'The platform to install Playwright for.'
|
||||
required: false
|
||||
default: 'chromium,webkit'
|
||||
electron-install:
|
||||
description: 'Download the Electron binary'
|
||||
required: false
|
||||
@@ -131,6 +127,7 @@ runs:
|
||||
|
||||
- name: yarn install
|
||||
if: ${{ inputs.package-install == 'true' }}
|
||||
continue-on-error: true
|
||||
shell: bash
|
||||
working-directory: ${{ steps.workspace-path.outputs.workspace_path }}
|
||||
run: yarn ${{ inputs.extra-flags }}
|
||||
@@ -176,7 +173,7 @@ runs:
|
||||
- name: Install Playwright's dependencies
|
||||
shell: bash
|
||||
if: inputs.playwright-install == 'true'
|
||||
run: yarn playwright install --with-deps $(echo "${{ inputs.playwright-platform }}" | tr ',' ' ')
|
||||
run: yarn playwright install --with-deps chromium webkit
|
||||
working-directory: ${{ steps.workspace-path.outputs.workspace_path }}
|
||||
env:
|
||||
PLAYWRIGHT_BROWSERS_PATH: ${{ steps.workspace-path.outputs.workspace_path }}/node_modules/.cache/ms-playwright
|
||||
|
||||
4
.github/deployment/node/Dockerfile
vendored
4
.github/deployment/node/Dockerfile
vendored
@@ -1,4 +1,4 @@
|
||||
FROM node:22-bookworm-slim
|
||||
FROM node:20-bookworm-slim
|
||||
|
||||
COPY ./packages/backend/server /app
|
||||
COPY ./packages/frontend/apps/web/dist /app/static
|
||||
@@ -10,4 +10,4 @@ RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends openssl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
CMD ["node", "./dist/main.js"]
|
||||
CMD ["node", "--import", "./scripts/register.js", "./dist/index.js"]
|
||||
|
||||
60
.github/deployment/self-host/compose.yaml
vendored
Normal file
60
.github/deployment/self-host/compose.yaml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
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
|
||||
2
.github/helm/affine/Chart.yaml
vendored
2
.github/helm/affine/Chart.yaml
vendored
@@ -3,4 +3,4 @@ name: affine
|
||||
description: AFFiNE cloud chart
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: "0.21.0"
|
||||
appVersion: "0.19.0"
|
||||
|
||||
11
.github/helm/affine/charts/doc/Chart.yaml
vendored
11
.github/helm/affine/charts/doc/Chart.yaml
vendored
@@ -1,11 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: doc
|
||||
description: AFFiNE doc server
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: "0.20.0"
|
||||
dependencies:
|
||||
- name: gcloud-sql-proxy
|
||||
version: 0.0.0
|
||||
repository: "file://../gcloud-sql-proxy"
|
||||
condition: .global.database.gcloud.enabled
|
||||
@@ -1,16 +0,0 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "doc.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "doc.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "doc.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "doc.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
@@ -1,63 +0,0 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "doc.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "doc.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "doc.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "doc.labels" -}}
|
||||
helm.sh/chart: {{ include "doc.chart" . }}
|
||||
{{ include "doc.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
monitoring: enabled
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "doc.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "doc.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "doc.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "doc.fullname" .) .Values.global.docService.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.global.docService.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,118 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "doc.fullname" . }}
|
||||
labels:
|
||||
{{- include "doc.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "doc.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "doc.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "doc.serviceAccountName" . }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
env:
|
||||
- name: AFFINE_PRIVATE_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.secret.secretName }}"
|
||||
key: key
|
||||
- name: NODE_ENV
|
||||
value: "{{ .Values.env }}"
|
||||
- name: NODE_OPTIONS
|
||||
value: "--max-old-space-size=4096"
|
||||
- name: NO_COLOR
|
||||
value: "1"
|
||||
- name: DEPLOYMENT_TYPE
|
||||
value: "{{ .Values.global.deployment.type }}"
|
||||
- name: DEPLOYMENT_PLATFORM
|
||||
value: "{{ .Values.global.deployment.platform }}"
|
||||
- name: SERVER_FLAVOR
|
||||
value: "doc"
|
||||
- name: AFFINE_ENV
|
||||
value: "{{ .Release.Namespace }}"
|
||||
- name: DATABASE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: pg-postgresql
|
||||
key: postgres-password
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.host }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
- name: REDIS_SERVER_ENABLED
|
||||
value: "true"
|
||||
- name: REDIS_SERVER_HOST
|
||||
value: "{{ .Values.global.redis.host }}"
|
||||
- name: REDIS_SERVER_PORT
|
||||
value: "{{ .Values.global.redis.port }}"
|
||||
- name: REDIS_SERVER_USER
|
||||
value: "{{ .Values.global.redis.username }}"
|
||||
- name: REDIS_SERVER_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis
|
||||
key: redis-password
|
||||
- name: REDIS_SERVER_DATABASE
|
||||
value: "{{ .Values.global.redis.database }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_PROVIDER
|
||||
value: "{{ .Values.global.indexer.provider }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_ENDPOINT
|
||||
value: "{{ .Values.global.indexer.endpoint }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: indexer
|
||||
key: indexer-apiKey
|
||||
- name: AFFINE_SERVER_PORT
|
||||
value: "{{ .Values.global.docService.port }}"
|
||||
- name: AFFINE_SERVER_SUB_PATH
|
||||
value: "{{ .Values.app.path }}"
|
||||
- name: AFFINE_SERVER_HOST
|
||||
value: "{{ .Values.app.host }}"
|
||||
- name: AFFINE_SERVER_HTTPS
|
||||
value: "{{ .Values.app.https }}"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.global.docService.port }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /info
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probe.initialDelaySeconds }}
|
||||
timeoutSeconds: {{ .Values.probe.timeoutSeconds }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /info
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probe.initialDelaySeconds }}
|
||||
timeoutSeconds: {{ .Values.probe.timeoutSeconds }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -1,19 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "doc.fullname" . }}
|
||||
labels:
|
||||
{{- include "doc.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.global.docService.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "doc.selectorLabels" . | nindent 4 }}
|
||||
@@ -1,12 +0,0 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "doc.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "doc.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "doc.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{- include "doc.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "doc.fullname" . }}:{{ .Values.global.docService.port }}']
|
||||
restartPolicy: Never
|
||||
43
.github/helm/affine/charts/doc/values.yaml
vendored
43
.github/helm/affine/charts/doc/values.yaml
vendored
@@ -1,43 +0,0 @@
|
||||
replicaCount: 1
|
||||
image:
|
||||
repository: ghcr.io/toeverything/affine-graphql
|
||||
pullPolicy: IfNotPresent
|
||||
tag: ''
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ''
|
||||
fullnameOverride: ''
|
||||
# map to NODE_ENV environment variable
|
||||
env: 'production'
|
||||
app:
|
||||
# AFFINE_SERVER_SUB_PATH
|
||||
path: ''
|
||||
# AFFINE_SERVER_HOST
|
||||
host: '0.0.0.0'
|
||||
https: true
|
||||
copilot:
|
||||
enabled: false
|
||||
secretName: copilot
|
||||
openai:
|
||||
key: ''
|
||||
serviceAccount:
|
||||
create: true
|
||||
annotations: {}
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
fsGroup: 2000
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: '1'
|
||||
memory: 4Gi
|
||||
|
||||
probe:
|
||||
initialDelaySeconds: 20
|
||||
timeoutSeconds: 5
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- if .Values.enabled -}}
|
||||
{{- if .Values.global.database.gcloud.enabled -}}
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "gcloud-sql-proxy.fullname" . }})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- if .Values.enabled -}}
|
||||
{{- if .Values.global.database.gcloud.enabled -}}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -42,7 +42,7 @@ spec:
|
||||
- "0.0.0.0"
|
||||
- "--structured-logs"
|
||||
- "--auto-iam-authn"
|
||||
- "{{ .Values.database.connectionName }}"
|
||||
- "{{ .Values.global.database.gcloud.connectionName }}"
|
||||
env:
|
||||
# Enable HTTP healthchecks on port 9801. This enables /liveness,
|
||||
# /readiness and /startup health check endpoints. Allow connections
|
||||
@@ -56,7 +56,7 @@ spec:
|
||||
value: 0.0.0.0
|
||||
ports:
|
||||
- name: cloud-sql-proxy
|
||||
containerPort: {{ .Values.service.port }}
|
||||
containerPort: {{ .Values.global.database.gcloud.proxyPort }}
|
||||
protocol: TCP
|
||||
- containerPort: 9801
|
||||
protocol: TCP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- if .Values.enabled -}}
|
||||
{{- if .Values.global.database.gcloud.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- if .Values.enabled -}}
|
||||
{{- if .Values.global.database.gcloud.enabled -}}
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- if .Values.enabled -}}
|
||||
{{- if .Values.global.database.gcloud.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
replicaCount: 3
|
||||
enabled: false
|
||||
database:
|
||||
connectionName: ""
|
||||
|
||||
image:
|
||||
# the tag is defined as chart appVersion.
|
||||
|
||||
@@ -3,7 +3,7 @@ name: graphql
|
||||
description: AFFiNE GraphQL server
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: "0.21.0"
|
||||
appVersion: "0.19.0"
|
||||
dependencies:
|
||||
- name: gcloud-sql-proxy
|
||||
version: 0.0.0
|
||||
|
||||
9
.github/helm/affine/charts/graphql/templates/captcha-secret.yaml
vendored
Normal file
9
.github/helm/affine/charts/graphql/templates/captcha-secret.yaml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{{- if .Values.app.captcha.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.captcha.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
turnstileSecret: {{ .Values.app.captcha.turnstile.secret | b64enc }}
|
||||
{{- end }}
|
||||
11
.github/helm/affine/charts/graphql/templates/copilot-secret.yaml
vendored
Normal file
11
.github/helm/affine/charts/graphql/templates/copilot-secret.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{{- if .Values.app.copilot.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.copilot.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
openaiSecret: {{ .Values.app.copilot.openai.key | b64enc }}
|
||||
falSecret: {{ .Values.app.copilot.fal.key | b64enc }}
|
||||
unsplashSecret: {{ .Values.app.copilot.unsplash.key | b64enc }}
|
||||
{{- end }}
|
||||
@@ -36,13 +36,11 @@ spec:
|
||||
- name: NODE_ENV
|
||||
value: "{{ .Values.env }}"
|
||||
- name: NODE_OPTIONS
|
||||
value: "--max-old-space-size=2048"
|
||||
value: "--max-old-space-size=4096"
|
||||
- name: NO_COLOR
|
||||
value: "1"
|
||||
- name: DEPLOYMENT_TYPE
|
||||
value: "{{ .Values.global.deployment.type }}"
|
||||
- name: DEPLOYMENT_PLATFORM
|
||||
value: "{{ .Values.global.deployment.platform }}"
|
||||
value: "affine"
|
||||
- name: SERVER_FLAVOR
|
||||
value: "graphql"
|
||||
- name: AFFINE_ENV
|
||||
@@ -53,7 +51,9 @@ spec:
|
||||
name: pg-postgresql
|
||||
key: postgres-password
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.host }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.url }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
- name: REDIS_SERVER_ENABLED
|
||||
value: "true"
|
||||
- name: REDIS_SERVER_HOST
|
||||
value: "{{ .Values.global.redis.host }}"
|
||||
- name: REDIS_SERVER_PORT
|
||||
@@ -67,15 +67,6 @@ spec:
|
||||
key: redis-password
|
||||
- name: REDIS_SERVER_DATABASE
|
||||
value: "{{ .Values.global.redis.database }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_PROVIDER
|
||||
value: "{{ .Values.global.indexer.provider }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_ENDPOINT
|
||||
value: "{{ .Values.global.indexer.endpoint }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: indexer
|
||||
key: indexer-apiKey
|
||||
- name: AFFINE_SERVER_PORT
|
||||
value: "{{ .Values.service.port }}"
|
||||
- name: AFFINE_SERVER_SUB_PATH
|
||||
@@ -84,8 +75,127 @@ spec:
|
||||
value: "{{ .Values.app.host }}"
|
||||
- name: AFFINE_SERVER_HTTPS
|
||||
value: "{{ .Values.app.https }}"
|
||||
- name: DOC_SERVICE_ENDPOINT
|
||||
value: "http://{{ .Values.global.docService.name }}:{{ .Values.global.docService.port }}"
|
||||
- name: ENABLE_R2_OBJECT_STORAGE
|
||||
value: "{{ .Values.global.objectStorage.r2.enabled }}"
|
||||
- name: FEATURES_EARLY_ACCESS_PREVIEW
|
||||
value: "{{ .Values.app.features.earlyAccessPreview }}"
|
||||
- name: FEATURES_SYNC_CLIENT_VERSION_CHECK
|
||||
value: "{{ .Values.app.features.syncClientVersionCheck }}"
|
||||
- name: MAILER_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.mailer.secretName }}"
|
||||
key: host
|
||||
- name: MAILER_PORT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.mailer.secretName }}"
|
||||
key: port
|
||||
- name: MAILER_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.mailer.secretName }}"
|
||||
key: user
|
||||
- name: MAILER_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.mailer.secretName }}"
|
||||
key: password
|
||||
- name: MAILER_SENDER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.mailer.secretName }}"
|
||||
key: sender
|
||||
- name: STRIPE_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.payment.stripe.secretName }}"
|
||||
key: stripeAPIKey
|
||||
- name: STRIPE_WEBHOOK_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.payment.stripe.secretName }}"
|
||||
key: stripeWebhookKey
|
||||
- name: DOC_MERGE_INTERVAL
|
||||
value: "{{ .Values.app.doc.mergeInterval }}"
|
||||
{{ if .Values.app.experimental.enableJwstCodec }}
|
||||
- name: DOC_MERGE_USE_JWST_CODEC
|
||||
value: "true"
|
||||
{{ end }}
|
||||
{{ if .Values.global.objectStorage.r2.enabled }}
|
||||
- name: R2_OBJECT_STORAGE_ACCOUNT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: accountId
|
||||
- name: R2_OBJECT_STORAGE_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: accessKeyId
|
||||
- name: R2_OBJECT_STORAGE_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: secretAccessKey
|
||||
{{ end }}
|
||||
{{ if .Values.app.captcha.enabled }}
|
||||
- name: CAPTCHA_TURNSTILE_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.captcha.secretName }}"
|
||||
key: turnstileSecret
|
||||
{{ end }}
|
||||
{{ if .Values.app.copilot.enabled }}
|
||||
- name: COPILOT_OPENAI_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.copilot.secretName }}"
|
||||
key: openaiSecret
|
||||
- name: COPILOT_FAL_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.copilot.secretName }}"
|
||||
key: falSecret
|
||||
- name: COPILOT_UNSPLASH_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.copilot.secretName }}"
|
||||
key: unsplashSecret
|
||||
{{ end }}
|
||||
{{ if .Values.app.oauth.google.enabled }}
|
||||
- name: OAUTH_GOOGLE_ENABLED
|
||||
value: "true"
|
||||
- name: OAUTH_GOOGLE_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.google.secretName }}"
|
||||
key: clientId
|
||||
- name: OAUTH_GOOGLE_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.google.secretName }}"
|
||||
key: clientSecret
|
||||
{{ end }}
|
||||
{{ if .Values.app.oauth.github.enabled }}
|
||||
- name: OAUTH_GITHUB_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.github.secretName }}"
|
||||
key: clientId
|
||||
- name: OAUTH_GITHUB_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.github.secretName }}"
|
||||
key: clientSecret
|
||||
{{ end }}
|
||||
{{ if .Values.app.metrics.enabled }}
|
||||
- name: METRICS_CUSTOMER_IO_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.metrics.secretName }}"
|
||||
key: customerIoSecret
|
||||
{{ end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
|
||||
13
.github/helm/affine/charts/graphql/templates/mailer.yaml
vendored
Normal file
13
.github/helm/affine/charts/graphql/templates/mailer.yaml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.app.mailer.secretName -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.mailer.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
host: "{{ .Values.app.mailer.host | b64enc }}"
|
||||
port: "{{ .Values.app.mailer.port | b64enc }}"
|
||||
user: "{{ .Values.app.mailer.user | b64enc }}"
|
||||
password: "{{ .Values.app.mailer.password | b64enc }}"
|
||||
sender: "{{ .Values.app.mailer.sender | b64enc }}"
|
||||
{{- end }}
|
||||
9
.github/helm/affine/charts/graphql/templates/metrics-secret.yaml
vendored
Normal file
9
.github/helm/affine/charts/graphql/templates/metrics-secret.yaml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{{- if .Values.app.metrics.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.metrics.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
customerIoSecret: {{ .Values.app.metrics.customerIo.token | b64enc }}
|
||||
{{- end }}
|
||||
@@ -23,36 +23,37 @@ spec:
|
||||
- name: AFFINE_ENV
|
||||
value: "{{ .Release.Namespace }}"
|
||||
- name: DEPLOYMENT_TYPE
|
||||
value: "{{ .Values.global.deployment.type }}"
|
||||
- name: DEPLOYMENT_PLATFORM
|
||||
value: "{{ .Values.global.deployment.platform }}"
|
||||
value: "affine"
|
||||
- name: DATABASE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: pg-postgresql
|
||||
key: postgres-password
|
||||
{{ if not .Values.global.database.gcloud.enabled }}
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.host }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
- name: REDIS_SERVER_HOST
|
||||
value: "{{ .Values.global.redis.host }}"
|
||||
- name: REDIS_SERVER_PORT
|
||||
value: "{{ .Values.global.redis.port }}"
|
||||
- name: REDIS_SERVER_USER
|
||||
value: "{{ .Values.global.redis.username }}"
|
||||
- name: REDIS_SERVER_PASSWORD
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.url }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
{{ end }}
|
||||
{{ if .Values.global.database.gcloud.enabled }}
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.gcloud.cloudSqlInternal }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
{{ end }}
|
||||
{{ if .Values.global.objectStorage.r2.enabled }}
|
||||
- name: R2_OBJECT_STORAGE_ACCOUNT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: redis
|
||||
key: redis-password
|
||||
- name: AFFINE_INDEXER_SEARCH_PROVIDER
|
||||
value: "{{ .Values.global.indexer.provider }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_ENDPOINT
|
||||
value: "{{ .Values.global.indexer.endpoint }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_API_KEY
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: accountId
|
||||
- name: R2_OBJECT_STORAGE_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: indexer
|
||||
key: indexer-apiKey
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: accessKeyId
|
||||
- name: R2_OBJECT_STORAGE_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: secretAccessKey
|
||||
{{ end }}
|
||||
resources:
|
||||
requests:
|
||||
cpu: '100m'
|
||||
|
||||
21
.github/helm/affine/charts/graphql/templates/oauth.yaml
vendored
Normal file
21
.github/helm/affine/charts/graphql/templates/oauth.yaml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.app.oauth.google.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.oauth.google.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
clientId: "{{ .Values.app.oauth.google.clientId | b64enc }}"
|
||||
clientSecret: "{{ .Values.app.oauth.google.clientSecret | b64enc }}"
|
||||
{{- end }}
|
||||
---
|
||||
{{- if .Values.app.oauth.github.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.oauth.github.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
clientId: "{{ .Values.app.oauth.github.clientId | b64enc }}"
|
||||
clientSecret: "{{ .Values.app.oauth.github.clientSecret | b64enc }}"
|
||||
{{- end }}
|
||||
8
.github/helm/affine/charts/graphql/templates/payment.yml
vendored
Normal file
8
.github/helm/affine/charts/graphql/templates/payment.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.payment.stripe.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
stripeAPIKey: "{{ .Values.app.payment.stripe.apiKey | b64enc }}"
|
||||
stripeWebhookKey: "{{ .Values.app.payment.stripe.webhookKey | b64enc }}"
|
||||
51
.github/helm/affine/charts/graphql/values.yaml
vendored
51
.github/helm/affine/charts/graphql/values.yaml
vendored
@@ -10,12 +10,57 @@ fullnameOverride: ''
|
||||
# map to NODE_ENV environment variable
|
||||
env: 'production'
|
||||
app:
|
||||
experimental:
|
||||
enableJwstCodec: true
|
||||
# AFFINE_SERVER_SUB_PATH
|
||||
path: ''
|
||||
# AFFINE_SERVER_HOST
|
||||
host: '0.0.0.0'
|
||||
https: true
|
||||
|
||||
doc:
|
||||
mergeInterval: "3000"
|
||||
captcha:
|
||||
enabled: false
|
||||
secretName: captcha
|
||||
turnstile:
|
||||
secret: ''
|
||||
copilot:
|
||||
enabled: false
|
||||
secretName: copilot
|
||||
openai:
|
||||
key: ''
|
||||
oauth:
|
||||
google:
|
||||
enabled: false
|
||||
secretName: oauth-google
|
||||
clientId: ''
|
||||
clientSecret: ''
|
||||
github:
|
||||
enabled: false
|
||||
secretName: oauth-github
|
||||
clientId: ''
|
||||
clientSecret: ''
|
||||
mailer:
|
||||
secretName: 'mailer'
|
||||
host: 'smtp.gmail.com'
|
||||
port: '465'
|
||||
user: ''
|
||||
password: ''
|
||||
sender: 'noreply@toeverything.info'
|
||||
metrics:
|
||||
enabled: false
|
||||
secretName: 'metrics'
|
||||
customerIo:
|
||||
token: ''
|
||||
payment:
|
||||
stripe:
|
||||
secretName: 'stripe'
|
||||
apiKey: ''
|
||||
webhookKey: ''
|
||||
features:
|
||||
earlyAccessPreview: false
|
||||
syncClientVersionCheck: false
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
annotations: {}
|
||||
@@ -28,8 +73,8 @@ podSecurityContext:
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: '2'
|
||||
memory: 2Gi
|
||||
cpu: '4'
|
||||
memory: 4Gi
|
||||
|
||||
probe:
|
||||
initialDelaySeconds: 20
|
||||
|
||||
@@ -36,13 +36,11 @@ spec:
|
||||
- name: NODE_ENV
|
||||
value: "{{ .Values.env }}"
|
||||
- name: NODE_OPTIONS
|
||||
value: "--max-old-space-size=2048"
|
||||
value: "--max-old-space-size=4096"
|
||||
- name: NO_COLOR
|
||||
value: "1"
|
||||
- name: DEPLOYMENT_TYPE
|
||||
value: "{{ .Values.global.deployment.type }}"
|
||||
- name: DEPLOYMENT_PLATFORM
|
||||
value: "{{ .Values.global.deployment.platform }}"
|
||||
value: "affine"
|
||||
- name: SERVER_FLAVOR
|
||||
value: "renderer"
|
||||
- name: AFFINE_ENV
|
||||
@@ -53,7 +51,7 @@ spec:
|
||||
name: pg-postgresql
|
||||
key: postgres-password
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.host }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.url }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
- name: REDIS_SERVER_ENABLED
|
||||
value: "true"
|
||||
- name: REDIS_SERVER_HOST
|
||||
@@ -69,15 +67,6 @@ spec:
|
||||
key: redis-password
|
||||
- name: REDIS_SERVER_DATABASE
|
||||
value: "{{ .Values.global.redis.database }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_PROVIDER
|
||||
value: "{{ .Values.global.indexer.provider }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_ENDPOINT
|
||||
value: "{{ .Values.global.indexer.endpoint }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: indexer
|
||||
key: indexer-apiKey
|
||||
- name: AFFINE_SERVER_PORT
|
||||
value: "{{ .Values.service.port }}"
|
||||
- name: AFFINE_SERVER_SUB_PATH
|
||||
@@ -86,8 +75,25 @@ spec:
|
||||
value: "{{ .Values.app.host }}"
|
||||
- name: AFFINE_SERVER_HTTPS
|
||||
value: "{{ .Values.app.https }}"
|
||||
- name: DOC_SERVICE_ENDPOINT
|
||||
value: "http://{{ .Values.global.docService.name }}:{{ .Values.global.docService.port }}"
|
||||
- name: ENABLE_R2_OBJECT_STORAGE
|
||||
value: "{{ .Values.global.objectStorage.r2.enabled }}"
|
||||
{{ if .Values.global.objectStorage.r2.enabled }}
|
||||
- name: R2_OBJECT_STORAGE_ACCOUNT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: accountId
|
||||
- name: R2_OBJECT_STORAGE_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: accessKeyId
|
||||
- name: R2_OBJECT_STORAGE_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
key: secretAccessKey
|
||||
{{ end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
|
||||
@@ -27,8 +27,8 @@ podSecurityContext:
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: '1'
|
||||
memory: 2Gi
|
||||
cpu: '4'
|
||||
memory: 4Gi
|
||||
|
||||
probe:
|
||||
initialDelaySeconds: 20
|
||||
|
||||
2
.github/helm/affine/charts/sync/Chart.yaml
vendored
2
.github/helm/affine/charts/sync/Chart.yaml
vendored
@@ -3,7 +3,7 @@ name: sync
|
||||
description: AFFiNE Sync Server
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: "0.21.0"
|
||||
appVersion: "0.19.0"
|
||||
dependencies:
|
||||
- name: gcloud-sql-proxy
|
||||
version: 0.0.0
|
||||
|
||||
@@ -42,9 +42,7 @@ spec:
|
||||
- name: NO_COLOR
|
||||
value: "1"
|
||||
- name: DEPLOYMENT_TYPE
|
||||
value: "{{ .Values.global.deployment.type }}"
|
||||
- name: DEPLOYMENT_PLATFORM
|
||||
value: "{{ .Values.global.deployment.platform }}"
|
||||
value: "affine"
|
||||
- name: SERVER_FLAVOR
|
||||
value: "sync"
|
||||
- name: AFFINE_ENV
|
||||
@@ -55,7 +53,9 @@ spec:
|
||||
name: pg-postgresql
|
||||
key: postgres-password
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.host }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
value: postgres://{{ .Values.global.database.user }}:$(DATABASE_PASSWORD)@{{ .Values.global.database.url }}:{{ .Values.global.database.port }}/{{ .Values.global.database.name }}
|
||||
- name: REDIS_SERVER_ENABLED
|
||||
value: "true"
|
||||
- name: REDIS_SERVER_HOST
|
||||
value: "{{ .Values.global.redis.host }}"
|
||||
- name: REDIS_SERVER_PORT
|
||||
@@ -69,21 +69,10 @@ spec:
|
||||
key: redis-password
|
||||
- name: REDIS_SERVER_DATABASE
|
||||
value: "{{ .Values.global.redis.database }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_PROVIDER
|
||||
value: "{{ .Values.global.indexer.provider }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_ENDPOINT
|
||||
value: "{{ .Values.global.indexer.endpoint }}"
|
||||
- name: AFFINE_INDEXER_SEARCH_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: indexer
|
||||
key: indexer-apiKey
|
||||
- name: AFFINE_SERVER_PORT
|
||||
value: "{{ .Values.service.port }}"
|
||||
- name: AFFINE_SERVER_HOST
|
||||
value: "{{ .Values.app.host }}"
|
||||
- name: DOC_SERVICE_ENDPOINT
|
||||
value: "http://{{ .Values.global.docService.name }}:{{ .Values.global.docService.port }}"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
|
||||
6
.github/helm/affine/charts/sync/values.yaml
vendored
6
.github/helm/affine/charts/sync/values.yaml
vendored
@@ -24,11 +24,11 @@ podSecurityContext:
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: '4'
|
||||
memory: 8Gi
|
||||
requests:
|
||||
cpu: '2'
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: '1'
|
||||
memory: 2Gi
|
||||
|
||||
probe:
|
||||
initialDelaySeconds: 20
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
{{- if .Values.global.indexer.apiKey -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: indexer
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-2"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
type: Opaque
|
||||
data:
|
||||
indexer-apiKey: {{ .Values.global.indexer.apiKey | b64enc }}
|
||||
{{- end }}
|
||||
13
.github/helm/affine/templates/monitoring.yaml
vendored
13
.github/helm/affine/templates/monitoring.yaml
vendored
@@ -1,13 +0,0 @@
|
||||
{{- if eq .Values.global.deployment.platform "gcp" -}}
|
||||
apiVersion: monitoring.googleapis.com/v1
|
||||
kind: PodMonitoring
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-monitoring"
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
endpoints:
|
||||
- port: 9464
|
||||
interval: 30s
|
||||
{{- end }}
|
||||
11
.github/helm/affine/templates/r2-secret.yaml
vendored
Normal file
11
.github/helm/affine/templates/r2-secret.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{{- if .Values.global.objectStorage.r2.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.global.objectStorage.r2.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
accountId: {{ .Values.global.objectStorage.r2.accountId | b64enc }}
|
||||
accessKeyId: {{ .Values.global.objectStorage.r2.accessKeyId | b64enc }}
|
||||
secretAccessKey: {{ .Values.global.objectStorage.r2.secretAccessKey | b64enc }}
|
||||
{{- end }}
|
||||
38
.github/helm/affine/values.yaml
vendored
38
.github/helm/affine/values.yaml
vendored
@@ -11,28 +11,34 @@ global:
|
||||
privateKey: ''
|
||||
database:
|
||||
user: 'postgres'
|
||||
host: 'pg-postgresql'
|
||||
url: 'pg-postgresql'
|
||||
port: '5432'
|
||||
name: 'affine'
|
||||
password: ''
|
||||
gcloud:
|
||||
enabled: false
|
||||
# use for migration
|
||||
cloudSqlInternal: ''
|
||||
connectionName: ''
|
||||
serviceAccount: ''
|
||||
cloudProxyReplicas: 3
|
||||
proxyPort: '5432'
|
||||
redis:
|
||||
enabled: true
|
||||
host: 'redis-master'
|
||||
port: '6379'
|
||||
username: ''
|
||||
password: ''
|
||||
database: 0
|
||||
indexer:
|
||||
provider: ''
|
||||
endpoint: ''
|
||||
username: ''
|
||||
password: ''
|
||||
docService:
|
||||
name: 'affine-doc'
|
||||
port: 3020
|
||||
deployment:
|
||||
# change to 'selfhosted' and 'unknown' if this chart is ready to be used for selfhosted deployment
|
||||
type: 'affine'
|
||||
platform: 'gcp'
|
||||
objectStorage:
|
||||
r2:
|
||||
enabled: false
|
||||
secretName: r2
|
||||
accountId: ''
|
||||
accessKeyId: ''
|
||||
secretAccessKey: ''
|
||||
gke:
|
||||
enabled: true
|
||||
|
||||
graphql:
|
||||
service:
|
||||
@@ -55,12 +61,6 @@ renderer:
|
||||
annotations:
|
||||
cloud.google.com/backend-config: '{"default": "affine-api-backendconfig"}'
|
||||
|
||||
doc:
|
||||
service:
|
||||
type: ClusterIP
|
||||
annotations:
|
||||
cloud.google.com/backend-config: '{"default": "affine-api-backendconfig"}'
|
||||
|
||||
web:
|
||||
service:
|
||||
type: ClusterIP
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
FROM pgvector/pgvector:pg15 AS builder
|
||||
|
||||
FROM bitnami/postgresql:15
|
||||
|
||||
COPY --from=builder /usr/lib/postgresql/15/lib/vector.so /opt/bitnami/postgresql/lib/
|
||||
COPY --from=builder /usr/share/postgresql/15/extension/vector* /opt/bitnami/postgresql/share/extension/
|
||||
35
.github/renovate.json
vendored
35
.github/renovate.json
vendored
@@ -21,34 +21,16 @@
|
||||
"groupName": "oxlint"
|
||||
},
|
||||
{
|
||||
"groupName": "all non-major rust dependencies",
|
||||
"groupSlug": "all-minor-patch",
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"matchManagers": ["cargo"]
|
||||
},
|
||||
{
|
||||
"groupName": "all non-major npm dependencies",
|
||||
"groupSlug": "all-minor-patch",
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"matchManagers": ["npm"],
|
||||
"matchPackageNames": ["*", "!/^@blocksuite//", "!/oxlint/"]
|
||||
"groupName": "blocksuite",
|
||||
"rangeStrategy": "replace",
|
||||
"changelogUrl": "https://github.com/toeverything/blocksuite/blob/master/packages/blocks/CHANGELOG.md",
|
||||
"matchPackageNames": ["/^@blocksuite/", "!@blocksuite/icons"]
|
||||
},
|
||||
{
|
||||
"groupName": "all non-major dependencies",
|
||||
"groupSlug": "all-minor-patch",
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"matchManagers": [
|
||||
"dockerfile",
|
||||
"github-actions",
|
||||
"helmv3",
|
||||
"helm-values",
|
||||
"gradle-wrapper",
|
||||
"gradle",
|
||||
"docker-compose",
|
||||
"devcontainer",
|
||||
"cocoapods",
|
||||
"bundler"
|
||||
]
|
||||
"matchPackageNames": ["*", "!/^@blocksuite//", "!/oxlint/"]
|
||||
},
|
||||
{
|
||||
"groupName": "rust toolchain",
|
||||
@@ -58,13 +40,6 @@
|
||||
{
|
||||
"groupName": "nestjs",
|
||||
"matchPackageNames": ["/^@nestjs/"]
|
||||
},
|
||||
{
|
||||
"groupName": "opentelemetry",
|
||||
"matchPackageNames": [
|
||||
"/^@opentelemetry/",
|
||||
"/^@google-cloud\/opentelemetry-/"
|
||||
]
|
||||
}
|
||||
],
|
||||
"commitMessagePrefix": "chore: ",
|
||||
|
||||
92
.github/workflows/build-images.yml
vendored
92
.github/workflows/build-images.yml
vendored
@@ -13,6 +13,28 @@ 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
|
||||
- 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-web:
|
||||
name: Build @affine/web
|
||||
runs-on: ubuntu-latest
|
||||
@@ -113,13 +135,12 @@ jobs:
|
||||
build-server-native:
|
||||
name: Build Server native - ${{ matrix.targets.name }}
|
||||
runs-on: ubuntu-latest
|
||||
environment: ${{ github.event.inputs.flavor }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
targets:
|
||||
- name: x86_64-unknown-linux-gnu
|
||||
file: server-native.x64.node
|
||||
file: server-native.node
|
||||
- name: aarch64-unknown-linux-gnu
|
||||
file: server-native.arm64.node
|
||||
- name: armv7-unknown-linux-gnueabihf
|
||||
@@ -137,54 +158,14 @@ jobs:
|
||||
extra-flags: workspaces focus @affine/server-native
|
||||
- name: Build Rust
|
||||
uses: ./.github/actions/build-rust
|
||||
env:
|
||||
AFFINE_PRO_PUBLIC_KEY: ${{ secrets.AFFINE_PRO_PUBLIC_KEY }}
|
||||
AFFINE_PRO_LICENSE_AES_KEY: ${{ secrets.AFFINE_PRO_LICENSE_AES_KEY }}
|
||||
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: 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 @affine/reader
|
||||
run: yarn workspace @affine/reader build
|
||||
- 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
|
||||
name: ${{ matrix.targets.file }}
|
||||
path: ./packages/backend/native/server-native.node
|
||||
if-no-files-found: error
|
||||
|
||||
build-images:
|
||||
@@ -195,6 +176,7 @@ jobs:
|
||||
- build-web
|
||||
- build-mobile
|
||||
- build-admin
|
||||
- build-server-native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download server dist
|
||||
@@ -202,6 +184,25 @@ 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"
|
||||
@@ -259,9 +260,6 @@ jobs:
|
||||
- name: Generate Prisma client
|
||||
run: yarn workspace @affine/server prisma generate
|
||||
|
||||
- name: Mv node_modules
|
||||
run: mv ./node_modules ./packages/backend/server
|
||||
|
||||
- name: Setup Version
|
||||
id: version
|
||||
uses: ./.github/actions/setup-version
|
||||
|
||||
753
.github/workflows/build-test.yml
vendored
753
.github/workflows/build-test.yml
vendored
File diff suppressed because it is too large
Load Diff
33
.github/workflows/copilot-test.yml
vendored
33
.github/workflows/copilot-test.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
REDIS_SERVER_HOST: localhost
|
||||
services:
|
||||
postgres:
|
||||
image: pgvector/pgvector:pg16
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
@@ -59,10 +59,6 @@ jobs:
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -77,17 +73,17 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
env:
|
||||
SERVER_CONFIG: ${{ secrets.TEST_SERVER_CONFIG }}
|
||||
uses: ./.github/actions/server-test-env
|
||||
|
||||
- name: Run server tests
|
||||
run: yarn affine @affine/server test:copilot:coverage --forbid-only
|
||||
env:
|
||||
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
|
||||
COPILOT_OPENAI_API_KEY: ${{ secrets.COPILOT_OPENAI_API_KEY }}
|
||||
COPILOT_FAL_API_KEY: ${{ secrets.COPILOT_FAL_API_KEY }}
|
||||
|
||||
- name: Upload server test coverage results
|
||||
uses: codecov/codecov-action@v5
|
||||
@@ -99,7 +95,7 @@ jobs:
|
||||
fail_ci_if_error: false
|
||||
|
||||
copilot-e2e-test:
|
||||
name: Frontend Copilot E2E Test
|
||||
name: Server Copilot E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DISTRIBUTION: web
|
||||
@@ -109,13 +105,13 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
shardTotal: [8]
|
||||
shardIndex: [1, 2, 3]
|
||||
shardTotal: [3]
|
||||
needs:
|
||||
- build-server-native
|
||||
services:
|
||||
postgres:
|
||||
image: pgvector/pgvector:pg16
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
@@ -129,10 +125,6 @@ jobs:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -147,17 +139,14 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
env:
|
||||
SERVER_CONFIG: ${{ secrets.TEST_SERVER_CONFIG }}
|
||||
uses: ./.github/actions/server-test-env
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Run Copilot E2E Test ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
uses: ./.github/actions/copilot-test
|
||||
with:
|
||||
script: yarn affine @affine-test/affine-cloud-copilot e2e --forbid-only --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
openai-key: ${{ secrets.COPILOT_OPENAI_API_KEY }}
|
||||
fal-key: ${{ secrets.COPILOT_FAL_API_KEY }}
|
||||
|
||||
test-done:
|
||||
needs:
|
||||
|
||||
28
.github/workflows/deploy.yml
vendored
28
.github/workflows/deploy.yml
vendored
@@ -92,20 +92,32 @@ jobs:
|
||||
APP_VERSION: ${{ steps.version.outputs.APP_VERSION }}
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
CANARY_DEPLOY_HOST: ${{ secrets.CANARY_DEPLOY_HOST }}
|
||||
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
|
||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
CAPTCHA_TURNSTILE_SECRET: ${{ secrets.CAPTCHA_TURNSTILE_SECRET }}
|
||||
COPILOT_OPENAI_API_KEY: ${{ secrets.COPILOT_OPENAI_API_KEY }}
|
||||
COPILOT_FAL_API_KEY: ${{ secrets.COPILOT_FAL_API_KEY }}
|
||||
COPILOT_UNSPLASH_API_KEY: ${{ secrets.COPILOT_UNSPLASH_API_KEY }}
|
||||
METRICS_CUSTOMER_IO_TOKEN: ${{ secrets.METRICS_CUSTOMER_IO_TOKEN }}
|
||||
MAILER_SENDER: ${{ secrets.OAUTH_EMAIL_SENDER }}
|
||||
MAILER_USER: ${{ secrets.OAUTH_EMAIL_LOGIN }}
|
||||
MAILER_PASSWORD: ${{ secrets.OAUTH_EMAIL_PASSWORD }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
AFFINE_GOOGLE_CLIENT_ID: ${{ secrets.AFFINE_GOOGLE_CLIENT_ID }}
|
||||
AFFINE_GOOGLE_CLIENT_SECRET: ${{ secrets.AFFINE_GOOGLE_CLIENT_SECRET }}
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
DATABASE_USERNAME: ${{ secrets.DATABASE_USERNAME }}
|
||||
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
|
||||
DATABASE_NAME: ${{ secrets.DATABASE_NAME }}
|
||||
GCLOUD_CONNECTION_NAME: ${{ secrets.GCLOUD_CONNECTION_NAME }}
|
||||
REDIS_SERVER_HOST: ${{ secrets.REDIS_SERVER_HOST }}
|
||||
REDIS_SERVER_PASSWORD: ${{ secrets.REDIS_SERVER_PASSWORD }}
|
||||
GCLOUD_CLOUD_SQL_INTERNAL_ENDPOINT: ${{ secrets.GCLOUD_CLOUD_SQL_INTERNAL_ENDPOINT }}
|
||||
REDIS_HOST: ${{ secrets.REDIS_HOST }}
|
||||
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }}
|
||||
CLOUD_SQL_IAM_ACCOUNT: ${{ secrets.CLOUD_SQL_IAM_ACCOUNT }}
|
||||
APP_IAM_ACCOUNT: ${{ secrets.APP_IAM_ACCOUNT }}
|
||||
STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }}
|
||||
STRIPE_WEBHOOK_KEY: ${{ secrets.STRIPE_WEBHOOK_KEY }}
|
||||
STATIC_IP_NAME: ${{ secrets.STATIC_IP_NAME }}
|
||||
AFFINE_INDEXER_SEARCH_PROVIDER: ${{ secrets.AFFINE_INDEXER_SEARCH_PROVIDER }}
|
||||
AFFINE_INDEXER_SEARCH_ENDPOINT: ${{ secrets.AFFINE_INDEXER_SEARCH_ENDPOINT }}
|
||||
AFFINE_INDEXER_SEARCH_API_KEY: ${{ secrets.AFFINE_INDEXER_SEARCH_API_KEY }}
|
||||
|
||||
deploy-done:
|
||||
needs:
|
||||
@@ -159,7 +171,7 @@ jobs:
|
||||
BLOCKSUITE_REPO_PATH: ${{ github.workspace }}/blocksuite
|
||||
- name: Post Failed event to a Slack channel
|
||||
id: failed-slack
|
||||
uses: slackapi/slack-github-action@v2.1.0
|
||||
uses: slackapi/slack-github-action@v2.0.0
|
||||
if: ${{ always() && contains(needs.*.result, 'failure') }}
|
||||
with:
|
||||
method: chat.postMessage
|
||||
@@ -174,7 +186,7 @@ jobs:
|
||||
text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy failed `${{ github.event.inputs.flavor }}`>"
|
||||
- name: Post Cancel event to a Slack channel
|
||||
id: cancel-slack
|
||||
uses: slackapi/slack-github-action@v2.1.0
|
||||
uses: slackapi/slack-github-action@v2.0.0
|
||||
if: ${{ always() && contains(needs.*.result, 'cancelled') && !contains(needs.*.result, 'failure') }}
|
||||
with:
|
||||
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
|
||||
26
.github/workflows/release-desktop.yml
vendored
26
.github/workflows/release-desktop.yml
vendored
@@ -73,11 +73,11 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
spec:
|
||||
- runner: macos-latest
|
||||
- runner: macos-14
|
||||
platform: darwin
|
||||
arch: x64
|
||||
target: x86_64-apple-darwin
|
||||
- runner: macos-latest
|
||||
- runner: macos-14
|
||||
platform: darwin
|
||||
arch: arm64
|
||||
target: aarch64-apple-darwin
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
|
||||
- name: Signing By Apple Developer ID
|
||||
if: ${{ matrix.spec.platform == 'darwin' }}
|
||||
uses: apple-actions/import-codesign-certs@v5
|
||||
uses: apple-actions/import-codesign-certs@v3
|
||||
with:
|
||||
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
|
||||
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
|
||||
@@ -142,19 +142,11 @@ jobs:
|
||||
# some flatpak deps need git protocol.file.allow
|
||||
git config --global protocol.file.allow always
|
||||
|
||||
- name: Remove nbstore node_modules
|
||||
shell: bash
|
||||
# node_modules of nbstore is not needed for building, and it will make the build process out of memory
|
||||
run: |
|
||||
rm -rf packages/frontend/apps/electron/node_modules/@affine/nbstore/node_modules/@blocksuite
|
||||
rm -rf packages/frontend/apps/electron/node_modules/@affine/native/node_modules
|
||||
|
||||
- name: make
|
||||
run: yarn affine @affine/electron make --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}
|
||||
env:
|
||||
SKIP_WEB_BUILD: 1
|
||||
HOIST_NODE_MODULES: 1
|
||||
NODE_OPTIONS: --max-old-space-size=14384
|
||||
|
||||
- name: signing DMG
|
||||
if: ${{ matrix.spec.platform == 'darwin' }}
|
||||
@@ -248,20 +240,11 @@ jobs:
|
||||
- name: Build Desktop Layers
|
||||
run: yarn affine @affine/electron build
|
||||
|
||||
- name: Remove nbstore node_modules
|
||||
shell: bash
|
||||
# node_modules of nbstore is not needed for building, and it will make the build process out of memory
|
||||
run: |
|
||||
rm -rf packages/frontend/apps/electron/node_modules/@affine/nbstore/node_modules/@blocksuite/affine/node_modules
|
||||
rm -rf packages/frontend/apps/electron/node_modules/@affine/native/node_modules
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
yarn affine @affine/electron package --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}
|
||||
run: yarn affine @affine/electron package --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}
|
||||
env:
|
||||
SKIP_WEB_BUILD: 1
|
||||
HOIST_NODE_MODULES: 1
|
||||
NODE_OPTIONS: --max-old-space-size=14384
|
||||
|
||||
- name: get all files to be signed
|
||||
id: get_files_to_be_signed
|
||||
@@ -460,7 +443,6 @@ jobs:
|
||||
run: |
|
||||
cp ./.docker/selfhost/compose.yml ./release/docker-compose.yml
|
||||
cp ./.docker/selfhost/.env.example ./release/.env.example
|
||||
cp ./.docker/selfhost/schema.json ./release/config.schema.json
|
||||
- name: Generate Release yml
|
||||
run: |
|
||||
node ./scripts/generate-release-yml.mjs
|
||||
|
||||
39
.github/workflows/release-mobile.yml
vendored
39
.github/workflows/release-mobile.yml
vendored
@@ -54,7 +54,7 @@ jobs:
|
||||
build-ios-web:
|
||||
needs:
|
||||
- output-env
|
||||
runs-on: ubuntu-24.04-arm
|
||||
runs-on: ubuntu-latest
|
||||
environment: ${{ needs.output-env.outputs.ENVIRONMENT }}
|
||||
outputs:
|
||||
RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }}
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
path: packages/frontend/apps/ios/dist
|
||||
|
||||
build-android-web:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- output-env
|
||||
environment: ${{ needs.output-env.outputs.ENVIRONMENT }}
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
path: packages/frontend/apps/android/dist
|
||||
|
||||
ios:
|
||||
runs-on: ${{ github.ref_name == 'canary' && 'macos-latest' || 'blaze/macos-14' }}
|
||||
runs-on: macos-latest
|
||||
needs:
|
||||
- build-ios-web
|
||||
steps:
|
||||
@@ -139,13 +139,11 @@ jobs:
|
||||
enableScripts: false
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: 16.2
|
||||
- name: Install Swiftformat
|
||||
run: brew install swiftformat
|
||||
xcode-version: latest-stable
|
||||
- name: Cap sync
|
||||
run: yarn workspace @affine/ios sync
|
||||
run: yarn workspace @affine/ios cap sync
|
||||
- name: Signing By Apple Developer ID
|
||||
uses: apple-actions/import-codesign-certs@v5
|
||||
uses: apple-actions/import-codesign-certs@v3
|
||||
id: import-codesign-certs
|
||||
with:
|
||||
p12-file-base64: ${{ secrets.CERTIFICATES_P12_MOBILE }}
|
||||
@@ -156,6 +154,11 @@ jobs:
|
||||
target: 'aarch64-apple-ios'
|
||||
package: 'affine_mobile_native'
|
||||
no-build: 'true'
|
||||
- name: Build Rust
|
||||
run: |
|
||||
brew install swiftformat
|
||||
cargo build -p affine_mobile_native --lib --release --target aarch64-apple-ios
|
||||
cargo run -p affine_mobile_native --bin uniffi-bindgen generate --library target/aarch64-apple-ios/release/libaffine_mobile_native.a --language swift --out-dir packages/frontend/apps/ios/App/App/uniffi
|
||||
- name: Testflight
|
||||
if: ${{ env.BUILD_TYPE != 'stable' }}
|
||||
working-directory: packages/frontend/apps/ios/App
|
||||
@@ -179,23 +182,16 @@ jobs:
|
||||
- build-android-web
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Version
|
||||
id: version
|
||||
uses: ./.github/actions/setup-version
|
||||
- name: Download mobile artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: android
|
||||
path: packages/frontend/apps/android/dist
|
||||
- name: Load Google Service file
|
||||
env:
|
||||
DATA: ${{ secrets.FIREBASE_ANDROID_GOOGLE_SERVICE_JSON }}
|
||||
run: echo $DATA | base64 -di > packages/frontend/apps/android/App/app/google-services.json
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
extra-flags: workspaces focus @affine/monorepo @affine-tools/cli @affine/android @affine/playstore-auto-bump
|
||||
extra-flags: workspaces focus @affine/android @affine/playstore-auto-bump
|
||||
playwright-install: false
|
||||
electron-install: false
|
||||
hard-link-nm: false
|
||||
@@ -210,7 +206,7 @@ jobs:
|
||||
run: yarn workspace @affine/android cap sync
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.12'
|
||||
- name: Auth gcloud
|
||||
id: auth
|
||||
uses: google-github-actions/auth@v2
|
||||
@@ -224,7 +220,7 @@ jobs:
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
java-version: '17'
|
||||
cache: 'gradle'
|
||||
- name: Auto increment version code
|
||||
id: bump
|
||||
@@ -235,20 +231,19 @@ jobs:
|
||||
- name: Build
|
||||
run: |
|
||||
echo -n "${{ env.AFFINE_ANDROID_SIGN_KEYSTORE }}" | base64 --decode > packages/frontend/apps/android/affine.keystore
|
||||
yarn workspace @affine/android cap build android --flavor ${{ env.BUILD_TYPE }} --androidreleasetype AAB
|
||||
yarn workspace @affine/android cap build android
|
||||
env:
|
||||
AFFINE_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.AFFINE_ANDROID_KEYSTORE_PASSWORD }}
|
||||
AFFINE_ANDROID_KEYSTORE_ALIAS_PASSWORD: ${{ secrets.AFFINE_ANDROID_KEYSTORE_ALIAS_PASSWORD }}
|
||||
AFFINE_ANDROID_SIGN_KEYSTORE: ${{ secrets.AFFINE_ANDROID_SIGN_KEYSTORE }}
|
||||
VERSION_NAME: ${{ steps.version.outputs.APP_VERSION }}
|
||||
|
||||
- name: Upload to Google Play
|
||||
uses: r0adkll/upload-google-play@v1
|
||||
if: ${{ env.BUILD_TARGET == 'distribution' }}
|
||||
with:
|
||||
serviceAccountJson: ${{ steps.auth.outputs.credentials_file_path }}
|
||||
packageName: app.affine.pro
|
||||
releaseName: ${{ steps.version.outputs.APP_VERSION }}
|
||||
releaseFiles: packages/frontend/apps/android/App/app/build/outputs/bundle/${{ env.BUILD_TYPE }}Release/app-${{ env.BUILD_TYPE }}-release-signed.aab
|
||||
releaseFiles: packages/frontend/apps/android/App/app/build/outputs/bundle/release/app-release-signed.aab
|
||||
track: internal
|
||||
status: draft
|
||||
existingEditId: ${{ steps.bump.outputs.EDIT_ID }}
|
||||
|
||||
34
.github/workflows/sync-i18n.yml
vendored
34
.github/workflows/sync-i18n.yml
vendored
@@ -11,6 +11,7 @@ on:
|
||||
jobs:
|
||||
synchronize-with-crowdin:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
@@ -20,11 +21,10 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Crowdin action
|
||||
id: crowdin
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
upload_translations: true
|
||||
download_translations: true
|
||||
auto_approve_imported: true
|
||||
import_eq_suggestions: true
|
||||
@@ -40,33 +40,3 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
i18n-codegen:
|
||||
needs: synchronize-with-crowdin
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: l10n_crowdin_translations
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
- name: Run i18n codegen
|
||||
run: yarn affine @affine/i18n build
|
||||
|
||||
- name: Commit changes
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add .
|
||||
git commit -m "chore(i18n): i18n codegen"
|
||||
git push origin l10n_crowdin_translations
|
||||
|
||||
23
.github/workflows/workers.yml
vendored
Normal file
23
.github/workflows/workers.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Deploy Cloudflare Worker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- canary
|
||||
paths:
|
||||
- tools/workers/**
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
environment: stable
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Publish
|
||||
uses: cloudflare/wrangler-action@v3.13.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: 'tools/workers'
|
||||
packageManager: 'yarn'
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -84,7 +84,3 @@ packages/frontend/core/public/static/templates
|
||||
# script
|
||||
af
|
||||
af.cmd
|
||||
*.resolved
|
||||
|
||||
# playwright
|
||||
storageState.json
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# we will make this file shared by prettier|eslint|oxlint
|
||||
**/node_modules
|
||||
.yarn
|
||||
.github/helm
|
||||
.github
|
||||
.vscode
|
||||
.yarnrc.yml
|
||||
.docker
|
||||
@@ -28,15 +28,9 @@ test-results
|
||||
# per files
|
||||
tools/cli/src/webpack/error-handler.js
|
||||
packages/backend/native/index.d.ts
|
||||
packages/backend/server/src/__tests__/__snapshots__
|
||||
packages/common/native/fixtures/**
|
||||
packages/common/graphql/src/graphql/index.ts
|
||||
packages/frontend/native/index.d.ts
|
||||
packages/frontend/native/index.js
|
||||
packages/frontend/apps/android/App/**
|
||||
packages/frontend/apps/ios/App/**
|
||||
tests/blocksuite/snapshots
|
||||
blocksuite/docs/api/**
|
||||
packages/frontend/admin/src/config.json
|
||||
**/test-docs.json
|
||||
**/test-blocks.json
|
||||
packages/frontend/graphql/src/graphql/index.ts
|
||||
packages/frontend/graphql/src/schema.ts
|
||||
packages/frontend/apps/android/App/app/build/**
|
||||
blocksuite/tests-legacy/snapshots
|
||||
|
||||
20
.vscode/launch.template.json
vendored
20
.vscode/launch.template.json
vendored
@@ -7,11 +7,7 @@
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "yarn",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"runtimeArgs": [
|
||||
"affine",
|
||||
"@affine/server",
|
||||
"dev"
|
||||
]
|
||||
"runtimeArgs": ["affine", "@affine/server", "dev"]
|
||||
},
|
||||
{
|
||||
"name": "Lanuch AFFiNE Web",
|
||||
@@ -19,17 +15,7 @@
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "yarn",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"runtimeArgs": [
|
||||
"affine",
|
||||
"@affine/web",
|
||||
"dev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "Debug AFFiNE Web",
|
||||
"url": "http://localhost:8080"
|
||||
"runtimeArgs": ["affine", "@affine/web", "dev"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
diff --git a/testing-module.d.ts b/testing-module.d.ts
|
||||
index 0b08dfe24534c605f58f2104255eb2a20c3fb566..8fad3ab267decccca2d4d9a8e208ace2cd811e92 100644
|
||||
--- a/testing-module.d.ts
|
||||
+++ b/testing-module.d.ts
|
||||
@@ -13,6 +13,7 @@ export declare class TestingModule extends NestApplicationContext {
|
||||
protected readonly graphInspector: GraphInspector;
|
||||
constructor(container: NestContainer, graphInspector: GraphInspector, contextModule: Module, applicationConfig: ApplicationConfig, scope?: Type<any>[]);
|
||||
private isHttpServer;
|
||||
+ useCustomApplicationConstructor(Ctor: Type<INestApplication>): void;
|
||||
createNestApplication<T extends INestApplication = INestApplication>(httpAdapter: HttpServer | AbstractHttpAdapter, options?: NestApplicationOptions): T;
|
||||
createNestApplication<T extends INestApplication = INestApplication>(options?: NestApplicationOptions): T;
|
||||
createNestMicroservice<T extends object>(options: NestMicroserviceOptions & T): INestMicroservice;
|
||||
diff --git a/testing-module.js b/testing-module.js
|
||||
index 17957b409b224bc43c7e40a1071cf08061366063..6bc4e8a694fdec02df91e512131ffd70259d8859 100644
|
||||
--- a/testing-module.js
|
||||
+++ b/testing-module.js
|
||||
@@ -15,6 +15,9 @@ class TestingModule extends core_1.NestApplicationContext {
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.graphInspector = graphInspector;
|
||||
}
|
||||
+ useCustomApplicationConstructor(Ctor) {
|
||||
+ this.applicationConstructor = Ctor;
|
||||
+ }
|
||||
isHttpServer(serverOrOptions) {
|
||||
return !!(serverOrOptions && serverOrOptions.patch);
|
||||
}
|
||||
@@ -24,7 +27,8 @@ class TestingModule extends core_1.NestApplicationContext {
|
||||
: [this.createHttpAdapter(), serverOrOptions];
|
||||
this.applyLogger(appOptions);
|
||||
this.container.setHttpAdapter(httpAdapter);
|
||||
- const instance = new core_1.NestApplication(this.container, httpAdapter, this.applicationConfig, this.graphInspector, appOptions);
|
||||
+ const Ctor = this.applicationConstructor || core_1.NestApplication;
|
||||
+ const instance = new Ctor(this.container, httpAdapter, this.applicationConfig, this.graphInspector, appOptions);
|
||||
return this.createAdapterProxy(instance, httpAdapter);
|
||||
}
|
||||
createNestMicroservice(options) {
|
||||
934
.yarn/releases/yarn-4.6.0.cjs
vendored
Executable file
934
.yarn/releases/yarn-4.6.0.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
948
.yarn/releases/yarn-4.9.1.cjs
vendored
948
.yarn/releases/yarn-4.9.1.cjs
vendored
File diff suppressed because one or more lines are too long
@@ -10,6 +10,6 @@ npmAuthToken: "${NPM_TOKEN:-NONE}"
|
||||
|
||||
npmPublishAccess: public
|
||||
|
||||
npmRegistryServer: "https://registry.npmjs.org"
|
||||
npmPublishRegistry: "https://registry.npmjs.org"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.9.1.cjs
|
||||
yarnPath: .yarn/releases/yarn-4.6.0.cjs
|
||||
|
||||
3167
Cargo.lock
generated
3167
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
127
Cargo.toml
127
Cargo.toml
@@ -2,104 +2,47 @@
|
||||
members = [
|
||||
"./packages/backend/native",
|
||||
"./packages/common/native",
|
||||
"./packages/common/y-octo/core",
|
||||
"./packages/common/y-octo/node",
|
||||
"./packages/common/y-octo/utils",
|
||||
"./packages/frontend/mobile-native",
|
||||
"./packages/frontend/native",
|
||||
"./packages/frontend/native/nbstore",
|
||||
"./packages/frontend/native/schema",
|
||||
"./packages/frontend/native/sqlite_v1",
|
||||
]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2024"
|
||||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
affine_common = { path = "./packages/common/native" }
|
||||
affine_nbstore = { path = "./packages/frontend/native/nbstore" }
|
||||
ahash = "0.8"
|
||||
anyhow = "1"
|
||||
arbitrary = { version = "1.3", features = ["derive"] }
|
||||
assert-json-diff = "2.0"
|
||||
async-lock = { version = "3.4.0", features = ["loom"] }
|
||||
base64-simd = "0.8"
|
||||
bitvec = "1.0"
|
||||
block2 = "0.6"
|
||||
byteorder = "1.5"
|
||||
chrono = "0.4"
|
||||
clap = { version = "4.4", features = ["derive"] }
|
||||
core-foundation = "0.10"
|
||||
coreaudio-rs = "0.12"
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
criterion2 = { version = "3", default-features = false }
|
||||
dispatch2 = "0.3"
|
||||
docx-parser = { git = "https://github.com/toeverything/docx-parser" }
|
||||
dotenvy = "0.15"
|
||||
file-format = { version = "0.26", features = ["reader"] }
|
||||
homedir = "0.3"
|
||||
infer = { version = "0.19.0" }
|
||||
lasso = { version = "0.7", features = ["multi-threaded"] }
|
||||
lib0 = { version = "0.16", features = ["lib0-serde"] }
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
loom = { version = "0.7", features = ["checkpoint"] }
|
||||
mimalloc = "0.1"
|
||||
nanoid = "0.4"
|
||||
napi = { version = "3.0.0-beta.3", features = ["async", "chrono_date", "error_anyhow", "napi9", "serde"] }
|
||||
napi-build = { version = "2" }
|
||||
napi-derive = { version = "3.0.0-beta.3" }
|
||||
nom = "8"
|
||||
notify = { version = "8", features = ["serde"] }
|
||||
objc2 = "0.6"
|
||||
objc2-foundation = "0.3"
|
||||
once_cell = "1"
|
||||
ordered-float = "5"
|
||||
parking_lot = "0.12"
|
||||
path-ext = "0.1.2"
|
||||
pdf-extract = { git = "https://github.com/toeverything/pdf-extract", branch = "darksky/improve-font-decoding" }
|
||||
phf = { version = "0.11", features = ["macros"] }
|
||||
proptest = "1.3"
|
||||
proptest-derive = "0.5"
|
||||
rand = "0.9"
|
||||
rand_chacha = "0.9"
|
||||
rand_distr = "0.5"
|
||||
rayon = "1.10"
|
||||
readability = { version = "0.3.0", default-features = false }
|
||||
regex = "1.10"
|
||||
rubato = "0.16"
|
||||
screencapturekit = "0.3"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
sha3 = "0.10"
|
||||
smol_str = "0.3"
|
||||
sqlx = { version = "0.8", default-features = false, features = ["chrono", "macros", "migrate", "runtime-tokio", "sqlite", "tls-rustls"] }
|
||||
strum_macros = "0.27.0"
|
||||
symphonia = { version = "0.5", features = ["all", "opt-simd"] }
|
||||
text-splitter = "0.27"
|
||||
thiserror = "2"
|
||||
tiktoken-rs = "0.7"
|
||||
tokio = "1.45"
|
||||
tree-sitter = { version = "0.25" }
|
||||
tree-sitter-c = { version = "0.24" }
|
||||
tree-sitter-c-sharp = { version = "0.23" }
|
||||
tree-sitter-cpp = { version = "0.23" }
|
||||
tree-sitter-go = { version = "0.23" }
|
||||
tree-sitter-java = { version = "0.23" }
|
||||
tree-sitter-javascript = { version = "0.23" }
|
||||
tree-sitter-kotlin-ng = { version = "1.1" }
|
||||
tree-sitter-python = { version = "0.23" }
|
||||
tree-sitter-rust = { version = "0.24" }
|
||||
tree-sitter-scala = { version = "0.23" }
|
||||
tree-sitter-typescript = { version = "0.23" }
|
||||
uniffi = "0.29"
|
||||
url = { version = "2.5" }
|
||||
uuid = "1.8"
|
||||
v_htmlescape = "0.15"
|
||||
y-octo = { path = "./packages/common/y-octo/core" }
|
||||
y-sync = { version = "0.4" }
|
||||
yrs = "0.23.0"
|
||||
affine_common = { path = "./packages/common/native" }
|
||||
affine_nbstore = { path = "./packages/frontend/native/nbstore" }
|
||||
anyhow = "1"
|
||||
base64-simd = "0.8"
|
||||
chrono = "0.4"
|
||||
criterion2 = { version = "2", default-features = false }
|
||||
dashmap = "6"
|
||||
dotenvy = "0.15"
|
||||
file-format = { version = "0.26", features = ["reader"] }
|
||||
mimalloc = "0.1"
|
||||
napi = { version = "3.0.0-alpha.12", features = ["async", "chrono_date", "error_anyhow", "napi9", "serde"] }
|
||||
napi-build = { version = "2" }
|
||||
napi-derive = { version = "3.0.0-alpha.12" }
|
||||
notify = { version = "7", features = ["serde"] }
|
||||
objc2 = "0.5.2"
|
||||
objc2-foundation = "0.2.2"
|
||||
once_cell = "1"
|
||||
parking_lot = "0.12"
|
||||
homedir = "0.3"
|
||||
rand = "0.8"
|
||||
rayon = "1.10"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
sha3 = "0.10"
|
||||
sqlx = { version = "0.8", default-features = false, features = ["chrono", "macros", "migrate", "runtime-tokio", "sqlite", "tls-rustls"] }
|
||||
thiserror = "2"
|
||||
tiktoken-rs = "0.6"
|
||||
tokio = "1.37"
|
||||
uniffi = "0.28"
|
||||
uuid = "1.8"
|
||||
v_htmlescape = "0.15"
|
||||
y-octo = { git = "https://github.com/y-crdt/y-octo.git", branch = "main" }
|
||||
|
||||
[profile.dev.package.sqlx-macros]
|
||||
opt-level = 3
|
||||
@@ -109,7 +52,3 @@ codegen-units = 1
|
||||
lto = true
|
||||
opt-level = 3
|
||||
strip = "symbols"
|
||||
|
||||
# android uniffi bindgen requires symbols
|
||||
[profile.release.package.affine_mobile_native]
|
||||
strip = "none"
|
||||
31
README.md
31
README.md
@@ -21,29 +21,12 @@
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div align="left" valign="middle">
|
||||
<a href="https://runblaze.dev">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://www.runblaze.dev/logo_dark.png">
|
||||
<img align="right" src="https://www.runblaze.dev/logo_light.png" height="102px"/>
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
<br style="display: none;"/>
|
||||
|
||||
_Special thanks to [Blaze](https://runblaze.dev) for their support of this project. They provide high-performance Apple Silicon macOS and Linux (AMD64 & ARM64) runners for GitHub Actions, greatly reducing our automated build times._
|
||||
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div align="center">
|
||||
<a href="https://affine.pro">Home Page</a> |
|
||||
<a href="https://affine.pro/redirect/discord">Discord</a> |
|
||||
<a href="https://discord.gg/whd5mjYqVw">Discord</a> |
|
||||
<a href="https://app.affine.pro">Live Demo</a> |
|
||||
<a href="https://affine.pro/blog/">Blog</a> |
|
||||
<a href="https://docs.affine.pro/">Documentation</a>
|
||||
<a href="https://docs.affine.pro/docs/">Documentation</a>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
@@ -89,7 +72,7 @@ Star us, and you will receive all release notifications from GitHub without any
|
||||
|
||||
**Self-host & Shape your own AFFiNE**
|
||||
|
||||
- You have the freedom to manage, self-host, fork and build your own AFFiNE. Plugin community and third-party blocks are coming soon. More tractions on [Blocksuite](https://blocksuite.io). Check there to learn how to [self-host AFFiNE](https://docs.affine.pro/self-host-affine).
|
||||
- You have the freedom to manage, self-host, fork and build your own AFFiNE. Plugin community and third-party blocks are coming soon. More tractions on [Blocksuite](https://blocksuite.io). Check there to learn how to [self-host AFFiNE](https://docs.affine.pro/docs/self-host-affine).
|
||||
|
||||
## Acknowledgement
|
||||
|
||||
@@ -144,8 +127,6 @@ AFFiNE now provides pre-built [templates](https://affine.pro/templates) from our
|
||||
Welcome to the AFFiNE blog section! Here, you’ll find the latest insights, tips, and guides on how to maximize your experience with AFFiNE and AFFiNE AI, the leading Canvas AI tool for flexible note-taking and creative organization.
|
||||
|
||||
- [vision board template](https://affine.pro/blog/8-free-printable-vision-board-templates-examples-2023)
|
||||
- [ai homework helper](https://affine.pro/blog/ai-homework-helper)
|
||||
- [vision board maker](https://affine.pro/blog/vision-board-maker)
|
||||
- [itinerary template](https://affine.pro/blog/free-customized-travel-itinerary-planner-templates)
|
||||
- [one pager template](https://affine.pro/blog/top-12-one-pager-examples-how-to-create-your-own)
|
||||
- [cornell notes template](https://affine.pro/blog/the-cornell-notes-template-and-system-learning-tips)
|
||||
@@ -191,13 +172,11 @@ We would like to express our gratitude to all the individuals who have already c
|
||||
|
||||
## Self-Host
|
||||
|
||||
Begin with Docker to deploy your own feature-rich, unrestricted version of AFFiNE. Our team is diligently updating to the latest version. For more information on how to self-host AFFiNE, please refer to our [documentation](https://docs.affine.pro/self-host-affine).
|
||||
|
||||
[](https://template.run.claw.cloud/?openapp=system-fastdeploy%3FtemplateName%3Daffine)
|
||||
Begin with Docker to deploy your own feature-rich, unrestricted version of AFFiNE. Our team is diligently updating to the latest version. For more information on how to self-host AFFiNE, please refer to our [documentation](https://docs.affine.pro/docs/self-host-affine).
|
||||
|
||||
## Hiring
|
||||
|
||||
Some amazing companies, including AFFiNE, are looking for developers! Are you interested in joining AFFiNE or its partners? Check out our [Discord channel](https://affine.pro/redirect/discord) for some of the latest jobs available.
|
||||
Some amazing companies, including AFFiNE, are looking for developers! Are you interested in joining AFFiNE or its partners? Check out our Discord channel for some of the latest jobs available.
|
||||
|
||||
## Feature Request
|
||||
|
||||
|
||||
@@ -3,288 +3,93 @@
|
||||
"description": "BlockSuite for Affine",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc --build --verbose"
|
||||
"build": "tsc --build --verbose",
|
||||
"test:unit": "nx vite:test --run --passWithNoTests",
|
||||
"test:unit:coverage": "nx vite:test --run --coverage",
|
||||
"test:e2e": "playwright test"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"keywords": [],
|
||||
"author": "toeverything",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-attachment": "workspace:*",
|
||||
"@blocksuite/affine-block-bookmark": "workspace:*",
|
||||
"@blocksuite/affine-block-callout": "workspace:*",
|
||||
"@blocksuite/affine-block-code": "workspace:*",
|
||||
"@blocksuite/affine-block-data-view": "workspace:*",
|
||||
"@blocksuite/affine-block-database": "workspace:*",
|
||||
"@blocksuite/affine-block-divider": "workspace:*",
|
||||
"@blocksuite/affine-block-edgeless-text": "workspace:*",
|
||||
"@blocksuite/affine-block-embed": "workspace:*",
|
||||
"@blocksuite/affine-block-embed-doc": "workspace:*",
|
||||
"@blocksuite/affine-block-frame": "workspace:*",
|
||||
"@blocksuite/affine-block-image": "workspace:*",
|
||||
"@blocksuite/affine-block-latex": "workspace:*",
|
||||
"@blocksuite/affine-block-list": "workspace:*",
|
||||
"@blocksuite/affine-block-note": "workspace:*",
|
||||
"@blocksuite/affine-block-paragraph": "workspace:*",
|
||||
"@blocksuite/affine-block-root": "workspace:*",
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-block-surface-ref": "workspace:*",
|
||||
"@blocksuite/affine-block-table": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-ext-loader": "workspace:*",
|
||||
"@blocksuite/affine-foundation": "workspace:*",
|
||||
"@blocksuite/affine-fragment-adapter-panel": "workspace:*",
|
||||
"@blocksuite/affine-fragment-doc-title": "workspace:*",
|
||||
"@blocksuite/affine-fragment-frame-panel": "workspace:*",
|
||||
"@blocksuite/affine-fragment-outline": "workspace:*",
|
||||
"@blocksuite/affine-gfx-brush": "workspace:*",
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*",
|
||||
"@blocksuite/affine-gfx-group": "workspace:*",
|
||||
"@blocksuite/affine-gfx-link": "workspace:*",
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*",
|
||||
"@blocksuite/affine-gfx-note": "workspace:*",
|
||||
"@blocksuite/affine-gfx-pointer": "workspace:*",
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*",
|
||||
"@blocksuite/affine-gfx-template": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-gfx-turbo-renderer": "workspace:*",
|
||||
"@blocksuite/affine-inline-footnote": "workspace:*",
|
||||
"@blocksuite/affine-inline-latex": "workspace:*",
|
||||
"@blocksuite/affine-inline-link": "workspace:*",
|
||||
"@blocksuite/affine-inline-mention": "workspace:*",
|
||||
"@blocksuite/affine-inline-preset": "workspace:*",
|
||||
"@blocksuite/affine-inline-reference": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
"@blocksuite/affine-widget-drag-handle": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-auto-connect": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-dragging-area": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-selected-rect": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-zoom-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-frame-title": "workspace:*",
|
||||
"@blocksuite/affine-widget-keyboard-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-linked-doc": "workspace:*",
|
||||
"@blocksuite/affine-widget-note-slicer": "workspace:*",
|
||||
"@blocksuite/affine-widget-page-dragging-area": "workspace:*",
|
||||
"@blocksuite/affine-widget-remote-selection": "workspace:*",
|
||||
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*",
|
||||
"@blocksuite/affine-widget-slash-menu": "workspace:*",
|
||||
"@blocksuite/affine-widget-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-viewport-overlay": "workspace:*",
|
||||
"@blocksuite/data-view": "workspace:*",
|
||||
"@blocksuite/block-std": "workspace:*",
|
||||
"@blocksuite/blocks": "workspace:*",
|
||||
"@blocksuite/global": "workspace:*",
|
||||
"@blocksuite/std": "workspace:*",
|
||||
"@blocksuite/store": "workspace:*",
|
||||
"@blocksuite/sync": "workspace:*",
|
||||
"rxjs": "^7.8.1"
|
||||
"@blocksuite/inline": "workspace:*",
|
||||
"@blocksuite/presets": "workspace:*",
|
||||
"@blocksuite/store": "workspace:*"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./effects": "./src/effects.ts",
|
||||
"./ext-loader": "./src/ext-loader/index.ts",
|
||||
"./std": "./src/std/index.ts",
|
||||
"./std/gfx": "./src/std/gfx.ts",
|
||||
"./std/inline": "./src/std/inline.ts",
|
||||
"./std/effects": "./src/std/effects.ts",
|
||||
"./block-std": "./src/block-std/index.ts",
|
||||
"./block-std/gfx": "./src/block-std/gfx.ts",
|
||||
"./global": "./src/global/index.ts",
|
||||
"./global/utils": "./src/global/utils.ts",
|
||||
"./global/env": "./src/global/env.ts",
|
||||
"./global/exceptions": "./src/global/exceptions.ts",
|
||||
"./global/di": "./src/global/di.ts",
|
||||
"./global/types": "./src/global/types.ts",
|
||||
"./global/gfx": "./src/global/gfx.ts",
|
||||
"./global/disposable": "./src/global/disposable.ts",
|
||||
"./global/lit": "./src/global/lit.ts",
|
||||
"./store": "./src/store/index.ts",
|
||||
"./store/test": "./src/store/test.ts",
|
||||
"./blocks/attachment": "./src/blocks/attachment/index.ts",
|
||||
"./blocks/attachment/store": "./src/blocks/attachment/store.ts",
|
||||
"./blocks/attachment/view": "./src/blocks/attachment/view.ts",
|
||||
"./blocks/bookmark": "./src/blocks/bookmark/index.ts",
|
||||
"./blocks/bookmark/store": "./src/blocks/bookmark/store.ts",
|
||||
"./blocks/bookmark/view": "./src/blocks/bookmark/view.ts",
|
||||
"./blocks/callout": "./src/blocks/callout/index.ts",
|
||||
"./blocks/callout/store": "./src/blocks/callout/store.ts",
|
||||
"./blocks/callout/view": "./src/blocks/callout/view.ts",
|
||||
"./blocks/code": "./src/blocks/code/index.ts",
|
||||
"./blocks/code/store": "./src/blocks/code/store.ts",
|
||||
"./blocks/code/view": "./src/blocks/code/view.ts",
|
||||
"./blocks/data-view": "./src/blocks/data-view/index.ts",
|
||||
"./blocks/data-view/store": "./src/blocks/data-view/store.ts",
|
||||
"./blocks/data-view/view": "./src/blocks/data-view/view.ts",
|
||||
"./blocks/database": "./src/blocks/database/index.ts",
|
||||
"./blocks/database/store": "./src/blocks/database/store.ts",
|
||||
"./blocks/database/view": "./src/blocks/database/view.ts",
|
||||
"./blocks/divider": "./src/blocks/divider/index.ts",
|
||||
"./blocks/divider/store": "./src/blocks/divider/store.ts",
|
||||
"./blocks/divider/view": "./src/blocks/divider/view.ts",
|
||||
"./blocks/edgeless-text": "./src/blocks/edgeless-text/index.ts",
|
||||
"./blocks/edgeless-text/store": "./src/blocks/edgeless-text/store.ts",
|
||||
"./blocks/edgeless-text/view": "./src/blocks/edgeless-text/view.ts",
|
||||
"./blocks/embed": "./src/blocks/embed/index.ts",
|
||||
"./blocks/embed/store": "./src/blocks/embed/store.ts",
|
||||
"./blocks/embed/view": "./src/blocks/embed/view.ts",
|
||||
"./blocks/embed-doc": "./src/blocks/embed-doc/index.ts",
|
||||
"./blocks/embed-doc/store": "./src/blocks/embed-doc/store.ts",
|
||||
"./blocks/embed-doc/view": "./src/blocks/embed-doc/view.ts",
|
||||
"./blocks/frame": "./src/blocks/frame/index.ts",
|
||||
"./blocks/frame/store": "./src/blocks/frame/store.ts",
|
||||
"./blocks/frame/view": "./src/blocks/frame/view.ts",
|
||||
"./blocks/image": "./src/blocks/image/index.ts",
|
||||
"./blocks/image/store": "./src/blocks/image/store.ts",
|
||||
"./blocks/image/view": "./src/blocks/image/view.ts",
|
||||
"./blocks/latex": "./src/blocks/latex/index.ts",
|
||||
"./blocks/latex/store": "./src/blocks/latex/store.ts",
|
||||
"./blocks/latex/view": "./src/blocks/latex/view.ts",
|
||||
"./blocks/list": "./src/blocks/list/index.ts",
|
||||
"./blocks/list/store": "./src/blocks/list/store.ts",
|
||||
"./blocks/list/view": "./src/blocks/list/view.ts",
|
||||
"./blocks/note": "./src/blocks/note/index.ts",
|
||||
"./blocks/note/store": "./src/blocks/note/store.ts",
|
||||
"./blocks/note/view": "./src/blocks/note/view.ts",
|
||||
"./blocks/paragraph": "./src/blocks/paragraph/index.ts",
|
||||
"./blocks/paragraph/store": "./src/blocks/paragraph/store.ts",
|
||||
"./blocks/paragraph/view": "./src/blocks/paragraph/view.ts",
|
||||
"./blocks/root": "./src/blocks/root/index.ts",
|
||||
"./blocks/root/store": "./src/blocks/root/store.ts",
|
||||
"./blocks/root/view": "./src/blocks/root/view.ts",
|
||||
"./blocks/surface": "./src/blocks/surface/index.ts",
|
||||
"./blocks/surface/store": "./src/blocks/surface/store.ts",
|
||||
"./blocks/surface/view": "./src/blocks/surface/view.ts",
|
||||
"./blocks/surface-ref": "./src/blocks/surface-ref/index.ts",
|
||||
"./blocks/surface-ref/store": "./src/blocks/surface-ref/store.ts",
|
||||
"./blocks/surface-ref/view": "./src/blocks/surface-ref/view.ts",
|
||||
"./blocks/table": "./src/blocks/table/index.ts",
|
||||
"./blocks/table/store": "./src/blocks/table/store.ts",
|
||||
"./blocks/table/view": "./src/blocks/table/view.ts",
|
||||
"./data-view": "./src/data-view/index.ts",
|
||||
"./data-view/effects": "./src/data-view/effects.ts",
|
||||
"./inlines/link": "./src/inlines/link/index.ts",
|
||||
"./inlines/link/store": "./src/inlines/link/store.ts",
|
||||
"./inlines/link/view": "./src/inlines/link/view.ts",
|
||||
"./inlines/reference": "./src/inlines/reference/index.ts",
|
||||
"./inlines/reference/store": "./src/inlines/reference/store.ts",
|
||||
"./inlines/reference/view": "./src/inlines/reference/view.ts",
|
||||
"./inlines/preset": "./src/inlines/preset/index.ts",
|
||||
"./inlines/preset/store": "./src/inlines/preset/store.ts",
|
||||
"./inlines/preset/view": "./src/inlines/preset/view.ts",
|
||||
"./inlines/footnote": "./src/inlines/footnote/index.ts",
|
||||
"./inlines/footnote/view": "./src/inlines/footnote/view.ts",
|
||||
"./inlines/footnote/store": "./src/inlines/footnote/store.ts",
|
||||
"./inlines/latex": "./src/inlines/latex/index.ts",
|
||||
"./inlines/latex/store": "./src/inlines/latex/store.ts",
|
||||
"./inlines/latex/view": "./src/inlines/latex/view.ts",
|
||||
"./inlines/mention": "./src/inlines/mention/index.ts",
|
||||
"./inlines/mention/view": "./src/inlines/mention/view.ts",
|
||||
"./widgets/drag-handle": "./src/widgets/drag-handle/index.ts",
|
||||
"./widgets/drag-handle/view": "./src/widgets/drag-handle/view.ts",
|
||||
"./widgets/edgeless-auto-connect": "./src/widgets/edgeless-auto-connect/index.ts",
|
||||
"./widgets/edgeless-auto-connect/view": "./src/widgets/edgeless-auto-connect/view.ts",
|
||||
"./widgets/edgeless-dragging-area": "./src/widgets/edgeless-dragging-area/index.ts",
|
||||
"./widgets/edgeless-dragging-area/view": "./src/widgets/edgeless-dragging-area/view.ts",
|
||||
"./widgets/edgeless-toolbar": "./src/widgets/edgeless-toolbar/index.ts",
|
||||
"./widgets/edgeless-toolbar/view": "./src/widgets/edgeless-toolbar/view.ts",
|
||||
"./widgets/frame-title": "./src/widgets/frame-title/index.ts",
|
||||
"./widgets/frame-title/view": "./src/widgets/frame-title/view.ts",
|
||||
"./widgets/linked-doc": "./src/widgets/linked-doc/index.ts",
|
||||
"./widgets/linked-doc/view": "./src/widgets/linked-doc/view.ts",
|
||||
"./widgets/remote-selection": "./src/widgets/remote-selection/index.ts",
|
||||
"./widgets/remote-selection/view": "./src/widgets/remote-selection/view.ts",
|
||||
"./widgets/scroll-anchoring": "./src/widgets/scroll-anchoring/index.ts",
|
||||
"./widgets/scroll-anchoring/view": "./src/widgets/scroll-anchoring/view.ts",
|
||||
"./widgets/slash-menu": "./src/widgets/slash-menu/index.ts",
|
||||
"./widgets/slash-menu/view": "./src/widgets/slash-menu/view.ts",
|
||||
"./widgets/toolbar": "./src/widgets/toolbar/index.ts",
|
||||
"./widgets/toolbar/view": "./src/widgets/toolbar/view.ts",
|
||||
"./widgets/keyboard-toolbar": "./src/widgets/keyboard-toolbar/index.ts",
|
||||
"./widgets/keyboard-toolbar/view": "./src/widgets/keyboard-toolbar/view.ts",
|
||||
"./widgets/viewport-overlay": "./src/widgets/viewport-overlay/index.ts",
|
||||
"./widgets/viewport-overlay/view": "./src/widgets/viewport-overlay/view.ts",
|
||||
"./widgets/page-dragging-area": "./src/widgets/page-dragging-area/index.ts",
|
||||
"./widgets/page-dragging-area/view": "./src/widgets/page-dragging-area/view.ts",
|
||||
"./fragments/doc-title": "./src/fragments/doc-title/index.ts",
|
||||
"./fragments/doc-title/view": "./src/fragments/doc-title/view.ts",
|
||||
"./fragments/frame-panel": "./src/fragments/frame-panel/index.ts",
|
||||
"./fragments/frame-panel/view": "./src/fragments/frame-panel/view.ts",
|
||||
"./fragments/outline": "./src/fragments/outline/index.ts",
|
||||
"./fragments/outline/view": "./src/fragments/outline/view.ts",
|
||||
"./fragments/adapter-panel": "./src/fragments/adapter-panel/index.ts",
|
||||
"./fragments/adapter-panel/view": "./src/fragments/adapter-panel/view.ts",
|
||||
"./gfx/text": "./src/gfx/text/index.ts",
|
||||
"./gfx/text/store": "./src/gfx/text/store.ts",
|
||||
"./gfx/text/view": "./src/gfx/text/view.ts",
|
||||
"./gfx/brush": "./src/gfx/brush/index.ts",
|
||||
"./gfx/brush/store": "./src/gfx/brush/store.ts",
|
||||
"./gfx/brush/view": "./src/gfx/brush/view.ts",
|
||||
"./gfx/pointer": "./src/gfx/pointer/index.ts",
|
||||
"./gfx/pointer/view": "./src/gfx/pointer/view.ts",
|
||||
"./gfx/shape": "./src/gfx/shape/index.ts",
|
||||
"./gfx/shape/store": "./src/gfx/shape/store.ts",
|
||||
"./gfx/shape/view": "./src/gfx/shape/view.ts",
|
||||
"./gfx/link": "./src/gfx/link/index.ts",
|
||||
"./gfx/link/view": "./src/gfx/link/view.ts",
|
||||
"./gfx/note": "./src/gfx/note/index.ts",
|
||||
"./gfx/note/view": "./src/gfx/note/view.ts",
|
||||
"./gfx/mindmap": "./src/gfx/mindmap/index.ts",
|
||||
"./gfx/mindmap/store": "./src/gfx/mindmap/store.ts",
|
||||
"./gfx/mindmap/view": "./src/gfx/mindmap/view.ts",
|
||||
"./gfx/connector": "./src/gfx/connector/index.ts",
|
||||
"./gfx/connector/store": "./src/gfx/connector/store.ts",
|
||||
"./gfx/connector/view": "./src/gfx/connector/view.ts",
|
||||
"./gfx/group": "./src/gfx/group/index.ts",
|
||||
"./gfx/group/store": "./src/gfx/group/store.ts",
|
||||
"./gfx/group/view": "./src/gfx/group/view.ts",
|
||||
"./gfx/template": "./src/gfx/template/index.ts",
|
||||
"./gfx/template/view": "./src/gfx/template/view.ts",
|
||||
"./gfx/turbo-renderer": "./src/gfx/turbo-renderer.ts",
|
||||
"./components/block-selection": "./src/components/block-selection.ts",
|
||||
"./components/block-zero-width": "./src/components/block-zero-width.ts",
|
||||
"./components/caption": "./src/components/caption.ts",
|
||||
"./components/card-style-dropdown-menu": "./src/components/card-style-dropdown-menu.ts",
|
||||
"./components/citation": "./src/components/citation.ts",
|
||||
"./components/color-picker": "./src/components/color-picker.ts",
|
||||
"./components/context-menu": "./src/components/context-menu.ts",
|
||||
"./components/date-picker": "./src/components/date-picker.ts",
|
||||
"./components/drop-indicator": "./src/components/drop-indicator.ts",
|
||||
"./components/embed-card-modal": "./src/components/embed-card-modal.ts",
|
||||
"./components/filterable-list": "./src/components/filterable-list.ts",
|
||||
"./components/highlight-dropdown-menu": "./src/components/highlight-dropdown-menu.ts",
|
||||
"./components/hover": "./src/components/hover.ts",
|
||||
"./components/icon-button": "./src/components/icon-button.ts",
|
||||
"./components/icons": "./src/components/icons.ts",
|
||||
"./components/link-preview": "./src/components/link-preview.ts",
|
||||
"./components/linked-doc-title": "./src/components/linked-doc-title.ts",
|
||||
"./components/notification": "./src/components/notification.ts",
|
||||
"./components/peek": "./src/components/peek.ts",
|
||||
"./components/portal": "./src/components/portal.ts",
|
||||
"./components/smooth-corner": "./src/components/smooth-corner.ts",
|
||||
"./components/toast": "./src/components/toast.ts",
|
||||
"./components/toggle-button": "./src/components/toggle-button.ts",
|
||||
"./components/toggle-switch": "./src/components/toggle-switch.ts",
|
||||
"./components/toolbar": "./src/components/toolbar.ts",
|
||||
"./components/view-dropdown-menu": "./src/components/view-dropdown-menu.ts",
|
||||
"./components/tooltip-content-with-shortcut": "./src/components/tooltip-content-with-shortcut.ts",
|
||||
"./components/resource": "./src/components/resource.ts",
|
||||
"./rich-text": "./src/rich-text/index.ts",
|
||||
"./rich-text/effects": "./src/rich-text/effects.ts",
|
||||
"./shared/adapters": "./src/shared/adapters.ts",
|
||||
"./shared/commands": "./src/shared/commands.ts",
|
||||
"./shared/consts": "./src/shared/consts.ts",
|
||||
"./shared/selection": "./src/shared/selection.ts",
|
||||
"./shared/services": "./src/shared/services.ts",
|
||||
"./shared/styles": "./src/shared/styles.ts",
|
||||
"./shared/theme": "./src/shared/theme.ts",
|
||||
"./shared/types": "./src/shared/types.ts",
|
||||
"./shared/utils": "./src/shared/utils.ts",
|
||||
"./schemas": "./src/schemas.ts",
|
||||
"./model": "./src/model/index.ts",
|
||||
"./sync": "./src/sync/index.ts",
|
||||
"./extensions/store": "./src/extensions/store.ts",
|
||||
"./extensions/view": "./src/extensions/view.ts",
|
||||
"./foundation/store": "./src/foundation/store.ts",
|
||||
"./foundation/view": "./src/foundation/view.ts"
|
||||
"./inline": "./src/inline/index.ts",
|
||||
"./inline/consts": "./src/inline/consts.ts",
|
||||
"./inline/types": "./src/inline/types.ts",
|
||||
"./presets": "./src/presets/index.ts",
|
||||
"./blocks": "./src/blocks/index.ts",
|
||||
"./blocks/schemas": "./src/blocks/schemas.ts"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"effects": [
|
||||
"dist/effects.d.ts"
|
||||
],
|
||||
"block-std": [
|
||||
"dist/block-std/index.d.ts"
|
||||
],
|
||||
"block-std/gfx": [
|
||||
"dist/block-std/gfx.d.ts"
|
||||
],
|
||||
"global": [
|
||||
"dist/global/index.d.ts"
|
||||
],
|
||||
"global/utils": [
|
||||
"dist/global/utils.d.ts"
|
||||
],
|
||||
"global/env": [
|
||||
"dist/global/env.d.ts"
|
||||
],
|
||||
"global/exceptions": [
|
||||
"dist/global/exceptions.d.ts"
|
||||
],
|
||||
"global/di": [
|
||||
"dist/global/di.d.ts"
|
||||
],
|
||||
"global/types": [
|
||||
"dist/global/types.d.ts"
|
||||
],
|
||||
"store": [
|
||||
"dist/store/index.d.ts"
|
||||
],
|
||||
"inline": [
|
||||
"dist/inline/index.d.ts"
|
||||
],
|
||||
"inline/consts": [
|
||||
"dist/inline/consts.d.ts"
|
||||
],
|
||||
"inline/types": [
|
||||
"dist/inline/types.d.ts"
|
||||
],
|
||||
"presets": [
|
||||
"dist/presets/index.d.ts"
|
||||
],
|
||||
"blocks": [
|
||||
"dist/blocks/index.d.ts"
|
||||
],
|
||||
"blocks/schemas": [
|
||||
"dist/blocks/schemas.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
@@ -292,10 +97,5 @@
|
||||
"!src/__tests__",
|
||||
"!dist/__tests__"
|
||||
],
|
||||
"version": "0.21.0",
|
||||
"devDependencies": {
|
||||
"@vanilla-extract/vite-plugin": "^5.0.0",
|
||||
"msw": "^2.8.4",
|
||||
"vitest": "3.1.3"
|
||||
}
|
||||
"version": "0.19.0"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,170 +0,0 @@
|
||||
import { DefaultTheme } from '@blocksuite/affine-model';
|
||||
import { NotionTextAdapter } from '@blocksuite/affine-shared/adapters';
|
||||
import type { SliceSnapshot } from '@blocksuite/store';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { createJob } from '../utils/create-job.js';
|
||||
import { getProvider } from '../utils/get-provider.js';
|
||||
import { nanoidReplacement } from '../utils/nanoid-replacement.js';
|
||||
|
||||
const provider = getProvider();
|
||||
|
||||
describe('notion-text to snapshot', () => {
|
||||
test('basic', () => {
|
||||
const notionText =
|
||||
'{"blockType":"text","editing":[["aaa ",[["_"],["b"],["i"]]],["nbbbb ",[["_"],["i"]]],["hjhj ",[["_"]]],["a",[["_"],["c"]]],[" ",[["_"]]],["ccc d",[["_"],["s"]]],["dd",[["_"],["s"]]]]}';
|
||||
|
||||
const sliceSnapshot: SliceSnapshot = {
|
||||
type: 'slice',
|
||||
content: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: 'both',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'aaa ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
bold: true,
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'nbbbb ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'hjhj ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'a',
|
||||
attributes: {
|
||||
underline: true,
|
||||
code: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: ' ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'ccc d',
|
||||
attributes: {
|
||||
underline: true,
|
||||
strike: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'dd',
|
||||
attributes: {
|
||||
underline: true,
|
||||
strike: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
};
|
||||
|
||||
const ntAdapter = new NotionTextAdapter(createJob(), provider);
|
||||
const target = ntAdapter.toSliceSnapshot({
|
||||
file: notionText,
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
});
|
||||
expect(nanoidReplacement(target!)).toEqual(sliceSnapshot);
|
||||
});
|
||||
|
||||
test('notion text with empty styles array', () => {
|
||||
const notionText =
|
||||
'{"blockType":"text","editing":[["a "],["bold text",[["b"]]],[" hello world"]],"selection":{"startIndex":0,"endIndex":23},"action":"copy"}';
|
||||
|
||||
const sliceSnapshot: SliceSnapshot = {
|
||||
type: 'slice',
|
||||
content: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: 'both',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'a ',
|
||||
},
|
||||
{
|
||||
insert: 'bold text',
|
||||
attributes: {
|
||||
bold: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: ' hello world',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
};
|
||||
|
||||
const ntAdapter = new NotionTextAdapter(createJob(), provider);
|
||||
const target = ntAdapter.toSliceSnapshot({
|
||||
file: notionText,
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
});
|
||||
expect(nanoidReplacement(target!)).toEqual(sliceSnapshot);
|
||||
});
|
||||
});
|
||||
@@ -1,236 +0,0 @@
|
||||
import {
|
||||
addProperty,
|
||||
copyCellsByProperty,
|
||||
databaseBlockProperties,
|
||||
deleteColumn,
|
||||
getCell,
|
||||
getProperty,
|
||||
updateCell,
|
||||
} from '@blocksuite/affine-block-database';
|
||||
import {
|
||||
type CellDataType,
|
||||
type ColumnDataType,
|
||||
type DatabaseBlockModel,
|
||||
DatabaseBlockSchemaExtension,
|
||||
NoteBlockSchemaExtension,
|
||||
ParagraphBlockSchemaExtension,
|
||||
RootBlockSchemaExtension,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { propertyModelPresets } from '@blocksuite/data-view/property-pure-presets';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
import { Text } from '@blocksuite/store';
|
||||
import {
|
||||
createAutoIncrementIdGenerator,
|
||||
TestWorkspace,
|
||||
} from '@blocksuite/store/test';
|
||||
import { beforeEach, describe, expect, test } from 'vitest';
|
||||
|
||||
const extensions = [
|
||||
RootBlockSchemaExtension,
|
||||
NoteBlockSchemaExtension,
|
||||
ParagraphBlockSchemaExtension,
|
||||
DatabaseBlockSchemaExtension,
|
||||
];
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
return { id: 'test-collection', idGenerator };
|
||||
}
|
||||
|
||||
function createTestDoc(docId = 'doc0') {
|
||||
const options = createTestOptions();
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc(docId);
|
||||
doc.load();
|
||||
return doc.getStore({ extensions });
|
||||
}
|
||||
|
||||
describe('DatabaseManager', () => {
|
||||
let doc: Store;
|
||||
let db: DatabaseBlockModel;
|
||||
|
||||
let rootId: BlockModel['id'];
|
||||
let noteBlockId: BlockModel['id'];
|
||||
let databaseBlockId: BlockModel['id'];
|
||||
let p1: BlockModel['id'];
|
||||
let p2: BlockModel['id'];
|
||||
let col1: ColumnDataType['id'];
|
||||
let col2: ColumnDataType['id'];
|
||||
let col3: ColumnDataType['id'];
|
||||
|
||||
const selection = [
|
||||
{ id: '1', value: 'Done', color: 'var(--affine-tag-white)' },
|
||||
{ id: '2', value: 'TODO', color: 'var(--affine-tag-pink)' },
|
||||
{ id: '3', value: 'WIP', color: 'var(--affine-tag-blue)' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
doc = createTestDoc();
|
||||
|
||||
rootId = doc.addBlock('affine:page', {
|
||||
title: new Text('database test'),
|
||||
});
|
||||
noteBlockId = doc.addBlock('affine:note', {}, rootId);
|
||||
|
||||
databaseBlockId = doc.addBlock(
|
||||
'affine:database',
|
||||
{
|
||||
columns: [],
|
||||
titleColumn: 'Title',
|
||||
},
|
||||
noteBlockId
|
||||
);
|
||||
|
||||
const databaseModel = doc.getModelById(
|
||||
databaseBlockId
|
||||
) as DatabaseBlockModel;
|
||||
db = databaseModel;
|
||||
|
||||
col1 = addProperty(
|
||||
db,
|
||||
'end',
|
||||
databaseBlockProperties.numberColumnConfig.create('Number')
|
||||
);
|
||||
col2 = addProperty(
|
||||
db,
|
||||
'end',
|
||||
propertyModelPresets.selectPropertyModelConfig.create('Single Select', {
|
||||
options: selection,
|
||||
})
|
||||
);
|
||||
col3 = addProperty(
|
||||
db,
|
||||
'end',
|
||||
databaseBlockProperties.richTextColumnConfig.create('Rich Text')
|
||||
);
|
||||
|
||||
doc.updateBlock(databaseModel, {
|
||||
columns: [col1, col2, col3],
|
||||
});
|
||||
|
||||
p1 = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('text1'),
|
||||
},
|
||||
databaseBlockId
|
||||
);
|
||||
p2 = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('text2'),
|
||||
},
|
||||
databaseBlockId
|
||||
);
|
||||
|
||||
updateCell(db, p1, {
|
||||
columnId: col1,
|
||||
value: 0.1,
|
||||
});
|
||||
updateCell(db, p2, {
|
||||
columnId: col2,
|
||||
value: [selection[1]],
|
||||
});
|
||||
});
|
||||
|
||||
test('getColumn', () => {
|
||||
const column = {
|
||||
...databaseBlockProperties.numberColumnConfig.create('testColumnId'),
|
||||
id: 'testColumnId',
|
||||
};
|
||||
addProperty(db, 'end', column);
|
||||
|
||||
const result = getProperty(db, column.id);
|
||||
expect(result).toEqual(column);
|
||||
});
|
||||
|
||||
test('addColumn', () => {
|
||||
const column =
|
||||
databaseBlockProperties.numberColumnConfig.create('Test Column');
|
||||
const id = addProperty(db, 'end', column);
|
||||
const result = getProperty(db, id);
|
||||
|
||||
expect(result).toMatchObject(column);
|
||||
expect(result).toHaveProperty('id');
|
||||
});
|
||||
|
||||
test('deleteColumn', () => {
|
||||
const column = {
|
||||
...databaseBlockProperties.numberColumnConfig.create('Test Column'),
|
||||
id: 'testColumnId',
|
||||
};
|
||||
addProperty(db, 'end', column);
|
||||
expect(getProperty(db, column.id)).toEqual(column);
|
||||
|
||||
deleteColumn(db, column.id);
|
||||
expect(getProperty(db, column.id)).toBeUndefined();
|
||||
});
|
||||
|
||||
test('getCell', () => {
|
||||
const modelId = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('paragraph'),
|
||||
},
|
||||
noteBlockId
|
||||
);
|
||||
const column = {
|
||||
...databaseBlockProperties.numberColumnConfig.create('Test Column'),
|
||||
id: 'testColumnId',
|
||||
};
|
||||
const cell: CellDataType = {
|
||||
columnId: column.id,
|
||||
value: 42,
|
||||
};
|
||||
|
||||
addProperty(db, 'end', column);
|
||||
updateCell(db, modelId, cell);
|
||||
|
||||
const model = doc.getModelById(modelId);
|
||||
|
||||
expect(model).not.toBeNull();
|
||||
|
||||
const result = getCell(db, model!.id, column.id);
|
||||
expect(result).toEqual(cell);
|
||||
});
|
||||
|
||||
test('updateCell', () => {
|
||||
const newRowId = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('text3'),
|
||||
},
|
||||
databaseBlockId
|
||||
);
|
||||
|
||||
updateCell(db, newRowId, {
|
||||
columnId: col2,
|
||||
value: [selection[2]],
|
||||
});
|
||||
|
||||
const cell = getCell(db, newRowId, col2);
|
||||
expect(cell).toEqual({
|
||||
columnId: col2,
|
||||
value: [selection[2]],
|
||||
});
|
||||
});
|
||||
|
||||
test('copyCellsByColumn', () => {
|
||||
const newColId = addProperty(
|
||||
db,
|
||||
'end',
|
||||
propertyModelPresets.selectPropertyModelConfig.create('Copied Select', {
|
||||
options: selection,
|
||||
})
|
||||
);
|
||||
|
||||
copyCellsByProperty(db, col2, newColId);
|
||||
|
||||
const cell = getCell(db, p2, newColId);
|
||||
expect(cell).toEqual({
|
||||
columnId: newColId,
|
||||
value: [selection[1]],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
import { defaultImageProxyMiddleware } from '@blocksuite/affine-shared/adapters';
|
||||
import {
|
||||
Schema,
|
||||
Transformer,
|
||||
type TransformerMiddleware,
|
||||
} from '@blocksuite/store';
|
||||
import { TestWorkspace } from '@blocksuite/store/test';
|
||||
|
||||
import { AffineSchemas } from '../../schemas.js';
|
||||
import { testStoreExtensions } from './store.js';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
happyDOM: {
|
||||
settings: {
|
||||
fetch: {
|
||||
disableSameOriginPolicy: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function createJob(middlewares?: TransformerMiddleware[]) {
|
||||
window.happyDOM.settings.fetch.disableSameOriginPolicy = true;
|
||||
const testMiddlewares = middlewares ?? [];
|
||||
testMiddlewares.push(defaultImageProxyMiddleware);
|
||||
const schema = new Schema().register(AffineSchemas);
|
||||
const docCollection = new TestWorkspace();
|
||||
docCollection.storeExtensions = testStoreExtensions;
|
||||
docCollection.meta.initialize();
|
||||
return new Transformer({
|
||||
schema,
|
||||
blobCRUD: docCollection.blobSync,
|
||||
middlewares: testMiddlewares,
|
||||
docCRUD: {
|
||||
create: (id: string) => docCollection.createDoc(id).getStore({ id }),
|
||||
get: (id: string) => docCollection.getDoc(id)?.getStore({ id }) ?? null,
|
||||
delete: (id: string) => docCollection.removeDoc(id),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Container } from '@blocksuite/global/di';
|
||||
|
||||
import { testStoreExtensions } from './store';
|
||||
|
||||
export function getProvider() {
|
||||
const container = new Container();
|
||||
const exts = testStoreExtensions;
|
||||
exts.forEach(ext => {
|
||||
ext.setup(container);
|
||||
});
|
||||
return container.provider();
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
import type { BlockSnapshot, SliceSnapshot } from '@blocksuite/store';
|
||||
|
||||
export function nanoidReplacement(snapshot: BlockSnapshot | SliceSnapshot) {
|
||||
return JSON.parse(nanoidReplacementString(JSON.stringify(snapshot)));
|
||||
}
|
||||
const escapedSnapshotAttributes = new Set([
|
||||
'"attributes"',
|
||||
'"conditions"',
|
||||
'"iconColumn"',
|
||||
'"background"',
|
||||
'"LinkedPage"',
|
||||
'"elementIds"',
|
||||
'"attachment"',
|
||||
]);
|
||||
|
||||
function nanoidReplacementString(snapshotString: string) {
|
||||
const re =
|
||||
/("block:[A-Za-z0-9-_]{10}")|("[A-Za-z0-9-_]{10}")|("[A-Za-z0-9-_]{35}")|("[A-Za-z0-9-_]{10}:[A-Za-z0-9-_]{10}")|("var\(--affine-v2-chip-label-[a-z]{3,10}\)")|("[A-Za-z0-9-_=]{44}")/g;
|
||||
const matches = snapshotString.matchAll(re);
|
||||
const matchesReplaceMap = new Map();
|
||||
let escapedNumber = 0;
|
||||
Array.from(matches).forEach((match, index) => {
|
||||
if (escapedSnapshotAttributes.has(match[0])) {
|
||||
matchesReplaceMap.set(match[0], match[0]);
|
||||
escapedNumber++;
|
||||
} else {
|
||||
matchesReplaceMap.set(
|
||||
match[0],
|
||||
`"matchesReplaceMap[${index - escapedNumber}]"`
|
||||
);
|
||||
}
|
||||
});
|
||||
return snapshotString.replace(re, match => matchesReplaceMap.get(match));
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { StoreExtensionManager } from '@blocksuite/affine-ext-loader';
|
||||
|
||||
import { getInternalStoreExtensions } from '../../extensions/store';
|
||||
|
||||
const manager = new StoreExtensionManager(getInternalStoreExtensions());
|
||||
|
||||
export const testStoreExtensions = manager.get('store');
|
||||
1
blocksuite/affine/all/src/block-std/gfx.ts
Normal file
1
blocksuite/affine/all/src/block-std/gfx.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/block-std/gfx';
|
||||
1
blocksuite/affine/all/src/block-std/index.ts
Normal file
1
blocksuite/affine/all/src/block-std/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/block-std';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-attachment';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-attachment/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-attachment/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-bookmark';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-bookmark/store';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user