mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-04 16:44:56 +00:00
Compare commits
18 Commits
06-18-feat
...
v0.21.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e043ecfd60 | ||
|
|
113c501e94 | ||
|
|
0ab86552f2 | ||
|
|
c34d7dc679 | ||
|
|
d5a45c6770 | ||
|
|
743e2eb8d2 | ||
|
|
a8c2ba81d4 | ||
|
|
bb606ac3e5 | ||
|
|
851111e1e4 | ||
|
|
9982e0ea45 | ||
|
|
58f7a6166c | ||
|
|
07d7a62071 | ||
|
|
ab3f056927 | ||
|
|
61e3364717 | ||
|
|
e32d6b9347 | ||
|
|
075a2e9f99 | ||
|
|
8b486b4833 | ||
|
|
21b7f02b0f |
@@ -6,7 +6,6 @@ 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
|
||||
|
||||
@@ -10,7 +10,6 @@ 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
|
||||
@@ -24,19 +23,5 @@ services:
|
||||
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
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
manticoresearch_data:
|
||||
|
||||
@@ -3,13 +3,4 @@ DB_VERSION=16
|
||||
# database credentials
|
||||
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
|
||||
```
|
||||
@@ -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
|
||||
@@ -55,7 +53,7 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
postgres:
|
||||
image: pgvector/pgvector:pg16
|
||||
image: postgres:16
|
||||
container_name: affine_postgres
|
||||
volumes:
|
||||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||
|
||||
@@ -31,13 +31,9 @@
|
||||
"properties": {
|
||||
"queue": {
|
||||
"type": "object",
|
||||
"description": "The config for job queues\n@default {\"attempts\":5,\"backoff\":{\"type\":\"exponential\",\"delay\":1000},\"removeOnComplete\":true,\"removeOnFail\":{\"age\":86400,\"count\":500}}\n@link https://api.docs.bullmq.io/interfaces/v5.QueueOptions.html",
|
||||
"description": "The config for job queues\n@default {\"attempts\":5,\"removeOnComplete\":true,\"removeOnFail\":{\"age\":86400,\"count\":500}}\n@link https://api.docs.bullmq.io/interfaces/v5.QueueOptions.html",
|
||||
"default": {
|
||||
"attempts": 5,
|
||||
"backoff": {
|
||||
"type": "exponential",
|
||||
"delay": 1000
|
||||
},
|
||||
"removeOnComplete": true,
|
||||
"removeOnFail": {
|
||||
"age": 86400,
|
||||
@@ -52,19 +48,7 @@
|
||||
},
|
||||
"queues.copilot": {
|
||||
"type": "object",
|
||||
"description": "The config for copilot job queue\n@default {\"concurrency\":10}",
|
||||
"properties": {
|
||||
"concurrency": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"concurrency": 10
|
||||
}
|
||||
},
|
||||
"queues.doc": {
|
||||
"type": "object",
|
||||
"description": "The config for doc job queue\n@default {\"concurrency\":1}",
|
||||
"description": "The config for copilot job queue\n@default {\"concurrency\":1}",
|
||||
"properties": {
|
||||
"concurrency": {
|
||||
"type": "number"
|
||||
@@ -74,9 +58,9 @@
|
||||
"concurrency": 1
|
||||
}
|
||||
},
|
||||
"queues.indexer": {
|
||||
"queues.doc": {
|
||||
"type": "object",
|
||||
"description": "The config for indexer job queue\n@default {\"concurrency\":1}",
|
||||
"description": "The config for doc job queue\n@default {\"concurrency\":1}",
|
||||
"properties": {
|
||||
"concurrency": {
|
||||
"type": "number"
|
||||
@@ -139,6 +123,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"websocket": {
|
||||
"type": "object",
|
||||
"description": "Configuration for websocket module",
|
||||
"properties": {
|
||||
"transports": {
|
||||
"type": "array",
|
||||
"description": "The enabled transports for accepting websocket traffics.\n@default [\"websocket\",\"polling\"]\n@link https://docs.nestjs.com/websockets/gateways#transports",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"websocket",
|
||||
"polling"
|
||||
]
|
||||
},
|
||||
"default": [
|
||||
"websocket",
|
||||
"polling"
|
||||
]
|
||||
},
|
||||
"maxHttpBufferSize": {
|
||||
"type": "number",
|
||||
"description": "How many bytes or characters a message can be, before closing the session (to avoid DoS).\n@default 100000000",
|
||||
"default": 100000000
|
||||
}
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"type": "object",
|
||||
"description": "Configuration for auth module",
|
||||
@@ -491,39 +501,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"websocket": {
|
||||
"type": "object",
|
||||
"description": "Configuration for websocket module",
|
||||
"properties": {
|
||||
"transports": {
|
||||
"type": "array",
|
||||
"description": "The enabled transports for accepting websocket traffics.\n@default [\"websocket\",\"polling\"]\n@link https://docs.nestjs.com/websockets/gateways#transports",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"websocket",
|
||||
"polling"
|
||||
]
|
||||
},
|
||||
"default": [
|
||||
"websocket",
|
||||
"polling"
|
||||
]
|
||||
},
|
||||
"maxHttpBufferSize": {
|
||||
"type": "number",
|
||||
"description": "How many bytes or characters a message can be, before closing the session (to avoid DoS).\n@default 100000000",
|
||||
"default": 100000000
|
||||
}
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"type": "object",
|
||||
"description": "Configuration for server module",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A recognizable name for the server. Will be shown when connected with AFFiNE Desktop.\n@default undefined"
|
||||
"description": "A recognizable name for the server. Will be shown when connected with AFFiNE Desktop.\n@default \"AFFiNE Cloud\"",
|
||||
"default": "AFFiNE Cloud"
|
||||
},
|
||||
"externalUrl": {
|
||||
"type": "string",
|
||||
@@ -547,7 +532,7 @@
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "Subpath where the server get deployed if there is one.(e.g. /affine)\n@default \"\"\n@environment `AFFINE_SERVER_SUB_PATH`",
|
||||
"description": "Subpath where the server get deployed if there is.\n@default \"\"\n@environment `AFFINE_SERVER_SUB_PATH`",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
@@ -643,41 +628,6 @@
|
||||
"apiKey": ""
|
||||
}
|
||||
},
|
||||
"providers.geminiVertex": {
|
||||
"type": "object",
|
||||
"description": "The config for the google vertex provider.\n@default {}",
|
||||
"properties": {
|
||||
"location": {
|
||||
"type": "string",
|
||||
"description": "The location of the google vertex provider."
|
||||
},
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The project name of the google vertex provider."
|
||||
},
|
||||
"googleAuthOptions": {
|
||||
"type": "object",
|
||||
"description": "The google auth options for the google vertex provider.",
|
||||
"properties": {
|
||||
"credentials": {
|
||||
"type": "object",
|
||||
"description": "The credentials for the google vertex provider.",
|
||||
"properties": {
|
||||
"client_email": {
|
||||
"type": "string",
|
||||
"description": "The client email for the google vertex provider."
|
||||
},
|
||||
"private_key": {
|
||||
"type": "string",
|
||||
"description": "The private key for the google vertex provider."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {}
|
||||
},
|
||||
"providers.perplexity": {
|
||||
"type": "object",
|
||||
"description": "The config for the perplexity provider.\n@default {\"apiKey\":\"\"}",
|
||||
@@ -685,48 +635,6 @@
|
||||
"apiKey": ""
|
||||
}
|
||||
},
|
||||
"providers.anthropic": {
|
||||
"type": "object",
|
||||
"description": "The config for the anthropic provider.\n@default {\"apiKey\":\"\"}",
|
||||
"default": {
|
||||
"apiKey": ""
|
||||
}
|
||||
},
|
||||
"providers.anthropicVertex": {
|
||||
"type": "object",
|
||||
"description": "The config for the google vertex provider.\n@default {}",
|
||||
"properties": {
|
||||
"location": {
|
||||
"type": "string",
|
||||
"description": "The location of the google vertex provider."
|
||||
},
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The project name of the google vertex provider."
|
||||
},
|
||||
"googleAuthOptions": {
|
||||
"type": "object",
|
||||
"description": "The google auth options for the google vertex provider.",
|
||||
"properties": {
|
||||
"credentials": {
|
||||
"type": "object",
|
||||
"description": "The credentials for the google vertex provider.",
|
||||
"properties": {
|
||||
"client_email": {
|
||||
"type": "string",
|
||||
"description": "The client email for the google vertex provider."
|
||||
},
|
||||
"private_key": {
|
||||
"type": "string",
|
||||
"description": "The private key for the google vertex provider."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {}
|
||||
},
|
||||
"unsplash": {
|
||||
"type": "object",
|
||||
"description": "The config for the unsplash key.\n@default {\"key\":\"\"}",
|
||||
@@ -734,13 +642,6 @@
|
||||
"key": ""
|
||||
}
|
||||
},
|
||||
"exa": {
|
||||
"type": "object",
|
||||
"description": "The config for the exa web search key.\n@default {\"key\":\"\"}",
|
||||
"default": {
|
||||
"key": ""
|
||||
}
|
||||
},
|
||||
"storage": {
|
||||
"type": "object",
|
||||
"description": "The config for the storage provider.\n@default {\"provider\":\"fs\",\"bucket\":\"copilot\",\"config\":{\"path\":\"~/.affine/storage\"}}",
|
||||
@@ -880,47 +781,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"indexer": {
|
||||
"type": "object",
|
||||
"description": "Configuration for indexer module",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable indexer plugin\n@default false\n@environment `AFFINE_INDEXER_ENABLED`",
|
||||
"default": false
|
||||
},
|
||||
"provider.type": {
|
||||
"type": "string",
|
||||
"description": "Indexer search service provider name\n@default \"manticoresearch\"\n@environment `AFFINE_INDEXER_SEARCH_PROVIDER`",
|
||||
"default": "manticoresearch"
|
||||
},
|
||||
"provider.endpoint": {
|
||||
"type": "string",
|
||||
"description": "Indexer search service endpoint\n@default \"http://localhost:9308\"\n@environment `AFFINE_INDEXER_SEARCH_ENDPOINT`",
|
||||
"default": "http://localhost:9308"
|
||||
},
|
||||
"provider.apiKey": {
|
||||
"type": "string",
|
||||
"description": "Indexer search service api key. Optional for elasticsearch\n@default \"\"\n@environment `AFFINE_INDEXER_SEARCH_API_KEY`\n@link https://www.elastic.co/guide/server/current/api-key.html",
|
||||
"default": ""
|
||||
},
|
||||
"provider.username": {
|
||||
"type": "string",
|
||||
"description": "Indexer search service auth username, if not set, basic auth will be disabled. Optional for elasticsearch\n@default \"\"\n@environment `AFFINE_INDEXER_SEARCH_USERNAME`\n@link https://www.elastic.co/guide/en/elasticsearch/reference/current/http-clients.html",
|
||||
"default": ""
|
||||
},
|
||||
"provider.password": {
|
||||
"type": "string",
|
||||
"description": "Indexer search service auth password, if not set, basic auth will be disabled. Optional for elasticsearch\n@default \"\"\n@environment `AFFINE_INDEXER_SEARCH_PASSWORD`",
|
||||
"default": ""
|
||||
},
|
||||
"autoIndex.batchSize": {
|
||||
"type": "number",
|
||||
"description": "Number of workspaces automatically indexed per batch\n@default 10",
|
||||
"default": 10
|
||||
}
|
||||
}
|
||||
},
|
||||
"oauth": {
|
||||
"type": "object",
|
||||
"description": "Configuration for oauth module",
|
||||
@@ -965,43 +825,13 @@
|
||||
},
|
||||
"providers.oidc": {
|
||||
"type": "object",
|
||||
"description": "OIDC OAuth provider config\n@default {\"clientId\":\"\",\"clientSecret\":\"\",\"issuer\":\"\",\"args\":{}}\n@link https://openid.net/specs/openid-connect-core-1_0.html",
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": "string"
|
||||
},
|
||||
"clientSecret": {
|
||||
"type": "string"
|
||||
},
|
||||
"args": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"description": "OIDC OAuth provider config\n@default {\"clientId\":\"\",\"clientSecret\":\"\",\"issuer\":\"\",\"args\":{}}",
|
||||
"default": {
|
||||
"clientId": "",
|
||||
"clientSecret": "",
|
||||
"issuer": "",
|
||||
"args": {}
|
||||
}
|
||||
},
|
||||
"providers.apple": {
|
||||
"type": "object",
|
||||
"description": "Apple OAuth provider config\n@default {\"clientId\":\"\",\"clientSecret\":\"\"}\n@link https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/implementing_sign_in_with_apple_in_your_app",
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": "string"
|
||||
},
|
||||
"clientSecret": {
|
||||
"type": "string"
|
||||
},
|
||||
"args": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"clientId": "",
|
||||
"clientSecret": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
9
.github/actions/deploy/deploy.mjs
vendored
9
.github/actions/deploy/deploy.mjs
vendored
@@ -16,9 +16,6 @@ const {
|
||||
REDIS_SERVER_HOST,
|
||||
REDIS_SERVER_PASSWORD,
|
||||
STATIC_IP_NAME,
|
||||
AFFINE_INDEXER_SEARCH_PROVIDER,
|
||||
AFFINE_INDEXER_SEARCH_ENDPOINT,
|
||||
AFFINE_INDEXER_SEARCH_API_KEY,
|
||||
} = process.env;
|
||||
|
||||
const buildType = BUILD_TYPE || 'canary';
|
||||
@@ -84,11 +81,6 @@ const createHelmCommand = ({ isDryRun }) => {
|
||||
`--set-string global.redis.password="${REDIS_SERVER_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}\\" }"`,
|
||||
@@ -138,7 +130,6 @@ const createHelmCommand = ({ isDryRun }) => {
|
||||
`--set-string global.ingress.host="${host}"`,
|
||||
`--set-string global.version="${APP_VERSION}"`,
|
||||
...redisAndPostgres,
|
||||
...indexerOptions,
|
||||
`--set web.replicaCount=${replica.web}`,
|
||||
`--set-string web.image.tag="${imageTag}"`,
|
||||
`--set graphql.replicaCount=${replica.graphql}`,
|
||||
|
||||
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: |
|
||||
@@ -26,10 +21,11 @@ runs:
|
||||
yarn affine @affine/server prisma generate
|
||||
yarn affine @affine/server prisma migrate deploy
|
||||
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
|
||||
printf '{"copilot":{"enabled":true,"providers.fal":{"apiKey":"%s"},"providers.gemini":{"apiKey":"%s"},"providers.openai":{"apiKey":"%s"},"providers.perplexity":{"apiKey":"%s"}}}' \
|
||||
"$COPILOT_FAL_API_KEY" \
|
||||
"$COPILOT_GOOGLE_API_KEY" \
|
||||
"$COPILOT_OPENAI_API_KEY" \
|
||||
"$COPILOT_PERPLEXITY_API_KEY" > ./packages/backend/server/config.json
|
||||
|
||||
2
.github/deployment/node/Dockerfile
vendored
2
.github/deployment/node/Dockerfile
vendored
@@ -10,4 +10,4 @@ RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends openssl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
CMD ["node", "./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
|
||||
@@ -69,15 +69,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.global.docService.port }}"
|
||||
- name: AFFINE_SERVER_SUB_PATH
|
||||
@@ -95,13 +86,11 @@ spec:
|
||||
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 }}
|
||||
|
||||
1
.github/helm/affine/charts/doc/values.yaml
vendored
1
.github/helm/affine/charts/doc/values.yaml
vendored
@@ -36,7 +36,6 @@ resources:
|
||||
|
||||
probe:
|
||||
initialDelaySeconds: 20
|
||||
timeoutSeconds: 5
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -44,15 +44,6 @@ spec:
|
||||
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
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: indexer
|
||||
key: indexer-apiKey
|
||||
resources:
|
||||
requests:
|
||||
cpu: '100m'
|
||||
|
||||
@@ -69,15 +69,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
|
||||
|
||||
@@ -69,15 +69,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_HOST
|
||||
|
||||
@@ -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 }}
|
||||
5
.github/helm/affine/values.yaml
vendored
5
.github/helm/affine/values.yaml
vendored
@@ -21,11 +21,6 @@ global:
|
||||
username: ''
|
||||
password: ''
|
||||
database: 0
|
||||
indexer:
|
||||
provider: ''
|
||||
endpoint: ''
|
||||
username: ''
|
||||
password: ''
|
||||
docService:
|
||||
name: 'affine-doc'
|
||||
port: 3020
|
||||
|
||||
28
.github/renovate.json
vendored
28
.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",
|
||||
|
||||
95
.github/workflows/build-images.yml
vendored
95
.github/workflows/build-images.yml
vendored
@@ -13,6 +13,31 @@ permissions:
|
||||
packages: 'write'
|
||||
|
||||
jobs:
|
||||
build-server:
|
||||
name: Build Server
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Version
|
||||
id: version
|
||||
uses: ./.github/actions/setup-version
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
extra-flags: workspaces focus @affine/server @types/affine__env
|
||||
- name: Build Server
|
||||
run: |
|
||||
find packages/backend/server/src -type d -name "__tests__" -exec rm -rf {} +
|
||||
rm -rf packages/backend/server/src/seed
|
||||
yarn workspace @affine/server build
|
||||
- name: Upload server dist
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: server-dist
|
||||
path: ./packages/backend/server/dist
|
||||
if-no-files-found: error
|
||||
|
||||
build-web:
|
||||
name: Build @affine/web
|
||||
runs-on: ubuntu-latest
|
||||
@@ -113,13 +138,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 +161,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 +179,7 @@ jobs:
|
||||
- build-web
|
||||
- build-mobile
|
||||
- build-admin
|
||||
- build-server-native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download server dist
|
||||
@@ -202,6 +187,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 +263,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
|
||||
|
||||
306
.github/workflows/build-test.yml
vendored
306
.github/workflows/build-test.yml
vendored
@@ -20,7 +20,6 @@ env:
|
||||
COVERAGE: true
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
DEPLOYMENT_TYPE: affine
|
||||
AFFINE_INDEXER_ENABLED: true
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -126,7 +125,6 @@ jobs:
|
||||
- name: Run BS Docs Build
|
||||
run: |
|
||||
yarn affine bs-docs build
|
||||
git checkout packages/frontend/i18n/src/i18n-completenesses.json
|
||||
git status --porcelain | grep . && {
|
||||
echo "Run 'yarn typecheck && yarn affine bs-docs build' and make sure all changes are submitted"
|
||||
exit 1
|
||||
@@ -152,15 +150,13 @@ jobs:
|
||||
- name: Clippy
|
||||
run: |
|
||||
rustup component add clippy
|
||||
cargo clippy --workspace --exclude affine_server_native --all-targets --all-features -- -D warnings
|
||||
cargo clippy -p affine_server_native --all-targets --all-features -- -D warnings
|
||||
cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
check-git-status:
|
||||
name: Check Git Status
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -169,26 +165,13 @@ jobs:
|
||||
with:
|
||||
full-cache: true
|
||||
|
||||
- name: Download server-native.node
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Bundle @affine/reader
|
||||
shell: bash
|
||||
run: |
|
||||
yarn workspace @affine/reader build
|
||||
|
||||
- name: Run Check
|
||||
run: |
|
||||
yarn affine init
|
||||
yarn affine gql build
|
||||
yarn affine i18n build
|
||||
yarn affine server genconfig
|
||||
git checkout packages/frontend/i18n/src/i18n-completenesses.json
|
||||
git status --porcelain | grep . && {
|
||||
echo "Run 'yarn affine init && yarn affine gql build && yarn affine i18n build && yarn affine server genconfig' and make sure all changes are submitted"
|
||||
echo "Run 'yarn affine init && yarn affine gql build && yarn affine i18n build' and make sure all changes are submitted"
|
||||
exit 1
|
||||
} || {
|
||||
echo "All changes are submitted"
|
||||
@@ -586,10 +569,6 @@ jobs:
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -603,7 +582,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
uses: ./.github/actions/server-test-env
|
||||
@@ -624,90 +603,6 @@ jobs:
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
server-test-elasticsearch:
|
||||
name: Server Test with Elasticsearch
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
- build-server-native
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
env:
|
||||
NODE_ENV: test
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
REDIS_SERVER_HOST: localhost
|
||||
AFFINE_INDEXER_SEARCH_PROVIDER: elasticsearch
|
||||
AFFINE_INDEXER_SEARCH_ENDPOINT: http://localhost:9200
|
||||
services:
|
||||
postgres:
|
||||
image: pgvector/pgvector:pg16
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
mailer:
|
||||
image: mailhog/mailhog
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
steps:
|
||||
# https://github.com/elastic/elastic-github-actions/blob/master/elasticsearch/README.md
|
||||
- name: Configure sysctl limits for Elasticsearch
|
||||
run: |
|
||||
sudo swapoff -a
|
||||
sudo sysctl -w vm.swappiness=1
|
||||
sudo sysctl -w fs.file-max=262144
|
||||
sudo sysctl -w vm.max_map_count=262144
|
||||
|
||||
- name: Runs Elasticsearch
|
||||
uses: elastic/elastic-github-actions/elasticsearch@master
|
||||
with:
|
||||
stack-version: 9.0.1
|
||||
security-enabled: false
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
- name: Download server-native.node
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
uses: ./.github/actions/server-test-env
|
||||
|
||||
- name: Run server tests with elasticsearch only
|
||||
run: yarn affine @affine/server test:coverage "**/*/*elasticsearch.spec.ts" --forbid-only
|
||||
env:
|
||||
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
|
||||
CI_NODE_INDEX: ${{ matrix.node_index }}
|
||||
CI_NODE_TOTAL: ${{ matrix.total_nodes }}
|
||||
|
||||
- name: Upload server test coverage results
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/backend/server/.coverage/lcov.info
|
||||
flags: server-test
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
server-e2e-test:
|
||||
# the new version of server e2e test should be super fast, so sharding testing is not needed
|
||||
name: Server E2E Test
|
||||
@@ -736,10 +631,6 @@ jobs:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -753,7 +644,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
uses: ./.github/actions/server-test-env
|
||||
@@ -770,141 +661,6 @@ jobs:
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
miri:
|
||||
name: miri code check
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
RUST_BACKTRACE: full
|
||||
CARGO_TERM_COLOR: always
|
||||
MIRIFLAGS: -Zmiri-backtrace=full -Zmiri-tree-borrows
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly
|
||||
components: miri
|
||||
- name: Install latest nextest release
|
||||
uses: taiki-e/install-action@nextest
|
||||
|
||||
- name: Miri Code Check
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cargo +nightly miri nextest run -p y-octo -j4
|
||||
|
||||
loom:
|
||||
name: loom thread test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
RUSTFLAGS: --cfg loom
|
||||
RUST_BACKTRACE: full
|
||||
CARGO_TERM_COLOR: always
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: stable
|
||||
- name: Install latest nextest release
|
||||
uses: taiki-e/install-action@nextest
|
||||
|
||||
- name: Loom Thread Test
|
||||
run: |
|
||||
cargo nextest run -p y-octo --lib
|
||||
|
||||
fuzzing:
|
||||
name: fuzzing
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly
|
||||
|
||||
- name: fuzzing
|
||||
working-directory: ./packages/common/y-octo/utils
|
||||
run: |
|
||||
cargo install cargo-fuzz
|
||||
cargo +nightly fuzz run apply_update -- -max_total_time=30
|
||||
cargo +nightly fuzz run codec_doc_any_struct -- -max_total_time=30
|
||||
cargo +nightly fuzz run codec_doc_any -- -max_total_time=30
|
||||
cargo +nightly fuzz run decode_bytes -- -max_total_time=30
|
||||
cargo +nightly fuzz run i32_decode -- -max_total_time=30
|
||||
cargo +nightly fuzz run i32_encode -- -max_total_time=30
|
||||
cargo +nightly fuzz run ins_del_text -- -max_total_time=30
|
||||
cargo +nightly fuzz run sync_message -- -max_total_time=30
|
||||
cargo +nightly fuzz run u64_decode -- -max_total_time=30
|
||||
cargo +nightly fuzz run u64_encode -- -max_total_time=30
|
||||
cargo +nightly fuzz run apply_update -- -max_total_time=30
|
||||
|
||||
- name: upload fuzz artifacts
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fuzz-artifact
|
||||
path: packages/common/y-octo/utils/fuzz/artifacts/**/*
|
||||
|
||||
y-octo-binding-test:
|
||||
name: y-octo binding test on ${{ matrix.settings.target }}
|
||||
runs-on: ${{ matrix.settings.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
settings:
|
||||
- { target: 'x86_64-unknown-linux-gnu', os: 'ubuntu-latest' }
|
||||
- { target: 'aarch64-unknown-linux-gnu', os: 'ubuntu-24.04-arm' }
|
||||
- { target: 'x86_64-apple-darwin', os: 'macos-13' }
|
||||
- { target: 'aarch64-apple-darwin', os: 'macos-latest' }
|
||||
- { target: 'x86_64-pc-windows-msvc', os: 'windows-latest' }
|
||||
- { target: 'aarch64-pc-windows-msvc', os: 'windows-11-arm' }
|
||||
needs:
|
||||
- optimize_ci
|
||||
if: needs.optimize_ci.outputs.skip == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
extra-flags: workspaces focus @affine-tools/cli @affine/monorepo @y-octo/node
|
||||
electron-install: false
|
||||
- name: Install rustup (Windows 11 ARM)
|
||||
if: matrix.settings.os == 'windows-11-arm'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Invoke-WebRequest -Uri "https://static.rust-lang.org/rustup/dist/aarch64-pc-windows-msvc/rustup-init.exe" -OutFile rustup-init.exe
|
||||
.\rustup-init.exe --default-toolchain none -y
|
||||
"$env:USERPROFILE\.cargo\bin" | Out-File -Append -Encoding ascii $env:GITHUB_PATH
|
||||
"CARGO_HOME=$env:USERPROFILE\.cargo" | Out-File -Append -Encoding ascii $env:GITHUB_ENV
|
||||
- name: Install Rust (Windows 11 ARM)
|
||||
if: matrix.settings.os == 'windows-11-arm'
|
||||
shell: pwsh
|
||||
run: |
|
||||
rustup install stable
|
||||
rustup target add ${{ matrix.settings.target }}
|
||||
cargo --version
|
||||
- name: Build Rust
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: ${{ matrix.settings.target }}
|
||||
package: '@y-octo/node'
|
||||
- name: Run tests
|
||||
run: yarn affine @y-octo/node test
|
||||
|
||||
rust-test:
|
||||
name: Run native tests
|
||||
runs-on: ubuntu-latest
|
||||
@@ -924,7 +680,7 @@ jobs:
|
||||
uses: taiki-e/install-action@nextest
|
||||
|
||||
- name: Run tests
|
||||
run: cargo nextest run --workspace --exclude affine_server_native --features use-as-lib --release --no-fail-fast
|
||||
run: cargo nextest run --release --no-fail-fast
|
||||
|
||||
copilot-api-test:
|
||||
name: Server Copilot Api Test
|
||||
@@ -959,10 +715,6 @@ jobs:
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -997,12 +749,15 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
if: ${{ steps.check-blocksuite-update.outputs.skip != 'true' || steps.apifilter.outputs.changed == 'true' }}
|
||||
env:
|
||||
SERVER_CONFIG: ${{ secrets.TEST_SERVER_CONFIG }}
|
||||
COPILOT_OPENAI_API_KEY: ${{ secrets.COPILOT_OPENAI_API_KEY }}
|
||||
COPILOT_GOOGLE_API_KEY: ${{ secrets.COPILOT_GOOGLE_API_KEY }}
|
||||
COPILOT_FAL_API_KEY: ${{ secrets.COPILOT_FAL_API_KEY }}
|
||||
COPILOT_PERPLEXITY_API_KEY: ${{ secrets.COPILOT_PERPLEXITY_API_KEY }}
|
||||
uses: ./.github/actions/server-test-env
|
||||
|
||||
- name: Run server tests
|
||||
@@ -1053,10 +808,6 @@ jobs:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -1079,7 +830,6 @@ jobs:
|
||||
- 'packages/backend/server/src/plugins/copilot/**'
|
||||
- 'packages/backend/server/tests/copilot.*'
|
||||
- 'packages/frontend/core/src/blocksuite/ai/**'
|
||||
- 'packages/frontend/core/src/modules/workspace-indexer-embedding/**'
|
||||
- 'tests/affine-cloud-copilot/**'
|
||||
|
||||
- name: Setup Node.js
|
||||
@@ -1096,12 +846,15 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Prepare Server Test Environment
|
||||
if: ${{ steps.check-blocksuite-update.outputs.skip != 'true' || steps.e2efilter.outputs.changed == 'true' }}
|
||||
env:
|
||||
SERVER_CONFIG: ${{ secrets.TEST_SERVER_CONFIG }}
|
||||
COPILOT_OPENAI_API_KEY: ${{ secrets.COPILOT_OPENAI_API_KEY }}
|
||||
COPILOT_GOOGLE_API_KEY: ${{ secrets.COPILOT_GOOGLE_API_KEY }}
|
||||
COPILOT_FAL_API_KEY: ${{ secrets.COPILOT_FAL_API_KEY }}
|
||||
COPILOT_PERPLEXITY_API_KEY: ${{ secrets.COPILOT_PERPLEXITY_API_KEY }}
|
||||
uses: ./.github/actions/server-test-env
|
||||
|
||||
- name: Run Copilot E2E Test ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
@@ -1175,10 +928,6 @@ jobs:
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -1192,7 +941,7 @@ jobs:
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: server-native.node
|
||||
path: ./packages/backend/native
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Download affine.linux-x64-gnu.node
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -1348,13 +1097,6 @@ jobs:
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
test: true,
|
||||
}
|
||||
- {
|
||||
os: windows-latest,
|
||||
platform: windows,
|
||||
arch: x64,
|
||||
target: x86_64-pc-windows-msvc,
|
||||
test: true,
|
||||
}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
@@ -1395,18 +1137,6 @@ jobs:
|
||||
HOIST_NODE_MODULES: 1
|
||||
run: yarn affine @affine/electron package --platform=darwin --arch=arm64
|
||||
|
||||
- name: Make Bundle (Windows)
|
||||
if: ${{ matrix.spec.target == 'x86_64-pc-windows-msvc' }}
|
||||
shell: bash
|
||||
env:
|
||||
SKIP_BUNDLE: true
|
||||
SKIP_WEB_BUILD: true
|
||||
HOIST_NODE_MODULES: 1
|
||||
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
|
||||
yarn affine @affine/electron package --platform=win32 --arch=x64
|
||||
|
||||
- name: Make Bundle (Linux)
|
||||
run: |
|
||||
sudo add-apt-repository universe
|
||||
@@ -1455,10 +1185,6 @@ jobs:
|
||||
- build-server-native
|
||||
- build-electron-renderer
|
||||
- native-unit-test
|
||||
- miri
|
||||
- loom
|
||||
- fuzzing
|
||||
- y-octo-binding-test
|
||||
- server-test
|
||||
- server-e2e-test
|
||||
- rust-test
|
||||
|
||||
22
.github/workflows/copilot-test.yml
vendored
22
.github/workflows/copilot-test.yml
vendored
@@ -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,11 +73,14 @@ 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 }}
|
||||
COPILOT_OPENAI_API_KEY: ${{ secrets.COPILOT_OPENAI_API_KEY }}
|
||||
COPILOT_FAL_API_KEY: ${{ secrets.COPILOT_FAL_API_KEY }}
|
||||
COPILOT_GOOGLE_API_KEY: ${{ secrets.COPILOT_GOOGLE_API_KEY }}
|
||||
COPILOT_PERPLEXITY_API_KEY: ${{ secrets.COPILOT_PERPLEXITY_API_KEY }}
|
||||
uses: ./.github/actions/server-test-env
|
||||
|
||||
- name: Run server tests
|
||||
@@ -129,10 +128,6 @@ jobs:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
indexer:
|
||||
image: manticoresearch/manticore:9.3.2
|
||||
ports:
|
||||
- 9308:9308
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -147,11 +142,14 @@ 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 }}
|
||||
COPILOT_OPENAI_API_KEY: ${{ secrets.COPILOT_OPENAI_API_KEY }}
|
||||
COPILOT_FAL_API_KEY: ${{ secrets.COPILOT_FAL_API_KEY }}
|
||||
COPILOT_GOOGLE_API_KEY: ${{ secrets.COPILOT_GOOGLE_API_KEY }}
|
||||
COPILOT_PERPLEXITY_API_KEY: ${{ secrets.COPILOT_PERPLEXITY_API_KEY }}
|
||||
uses: ./.github/actions/server-test-env
|
||||
|
||||
- name: Run Copilot E2E Test ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
|
||||
7
.github/workflows/deploy.yml
vendored
7
.github/workflows/deploy.yml
vendored
@@ -103,9 +103,6 @@ jobs:
|
||||
CLOUD_SQL_IAM_ACCOUNT: ${{ secrets.CLOUD_SQL_IAM_ACCOUNT }}
|
||||
APP_IAM_ACCOUNT: ${{ secrets.APP_IAM_ACCOUNT }}
|
||||
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 +156,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 +171,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 }}
|
||||
|
||||
2
.github/workflows/release-desktop.yml
vendored
2
.github/workflows/release-desktop.yml
vendored
@@ -252,7 +252,7 @@ jobs:
|
||||
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/nbstore/node_modules/@blocksuite
|
||||
rm -rf packages/frontend/apps/electron/node_modules/@affine/native/node_modules
|
||||
|
||||
- name: package
|
||||
|
||||
35
.github/workflows/release-mobile.yml
vendored
35
.github/workflows/release-mobile.yml
vendored
@@ -117,10 +117,31 @@ jobs:
|
||||
name: android
|
||||
path: packages/frontend/apps/android/dist
|
||||
|
||||
ios:
|
||||
runs-on: ${{ github.ref_name == 'canary' && 'macos-latest' || 'blaze/macos-14' }}
|
||||
determine-ios-runner:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build-ios-web
|
||||
outputs:
|
||||
RUNNER: ${{ steps.runner.outputs.RUNNER }}
|
||||
steps:
|
||||
- name: Determine Runner
|
||||
id: runner
|
||||
# Randomly pick runner with 80% chance for blaze/macos-14 and 20% chance for namespace-profile-macos
|
||||
# blaze/macos-14 is free but has limited concurrency
|
||||
run: |
|
||||
RANDOM_NUMBER=$(( $RANDOM % 100 + 1 ))
|
||||
if [ $RANDOM_NUMBER -le 20 ]; then
|
||||
echo "Selected namespace-profile-macos (20% probability)"
|
||||
echo "RUNNER=namespace-profile-macos" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Selected blaze/macos-14 (80% probability)"
|
||||
echo "RUNNER=blaze/macos-14" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
ios:
|
||||
runs-on: ${{ github.ref_name == 'canary' && 'macos-latest' || needs.determine-ios-runner.outputs.RUNNER }}
|
||||
needs:
|
||||
- determine-ios-runner
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download mobile artifact
|
||||
@@ -179,18 +200,11 @@ 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
|
||||
@@ -240,14 +254,13 @@ jobs:
|
||||
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
|
||||
track: internal
|
||||
status: draft
|
||||
|
||||
@@ -38,5 +38,3 @@ packages/frontend/apps/ios/App/**
|
||||
tests/blocksuite/snapshots
|
||||
blocksuite/docs/api/**
|
||||
packages/frontend/admin/src/config.json
|
||||
**/test-docs.json
|
||||
**/test-blocks.json
|
||||
|
||||
@@ -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
|
||||
|
||||
1449
Cargo.lock
generated
1449
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
45
Cargo.toml
45
Cargo.toml
@@ -2,9 +2,6 @@
|
||||
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",
|
||||
@@ -19,70 +16,48 @@ edition = "2024"
|
||||
[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"
|
||||
dispatch2 = "0.2"
|
||||
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 = { version = "3.0.0-alpha.31", features = ["async", "chrono_date", "error_anyhow", "napi9", "serde"] }
|
||||
napi-build = { version = "2" }
|
||||
napi-derive = { version = "3.0.0-beta.3" }
|
||||
nom = "8"
|
||||
napi-derive = { version = "3.0.0-alpha.28" }
|
||||
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"
|
||||
path-ext = "0.1.1"
|
||||
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"
|
||||
text-splitter = "0.25"
|
||||
thiserror = "2"
|
||||
tiktoken-rs = "0.7"
|
||||
tokio = "1.45"
|
||||
tiktoken-rs = "0.6"
|
||||
tokio = "1.37"
|
||||
tree-sitter = { version = "0.25" }
|
||||
tree-sitter-c = { version = "0.24" }
|
||||
tree-sitter-c = { version = "0.23" }
|
||||
tree-sitter-c-sharp = { version = "0.23" }
|
||||
tree-sitter-cpp = { version = "0.23" }
|
||||
tree-sitter-go = { version = "0.23" }
|
||||
@@ -97,9 +72,7 @@ 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"
|
||||
y-octo = { git = "https://github.com/y-crdt/y-octo.git", branch = "main" }
|
||||
|
||||
[profile.dev.package.sqlx-macros]
|
||||
opt-level = 3
|
||||
|
||||
@@ -43,7 +43,7 @@ _Special thanks to [Blaze](https://runblaze.dev) for their support of this proje
|
||||
<a href="https://affine.pro/redirect/discord">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 +89,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
|
||||
|
||||
@@ -191,9 +191,7 @@ 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
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
"@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:*",
|
||||
@@ -31,19 +30,14 @@
|
||||
"@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:*",
|
||||
@@ -59,20 +53,14 @@
|
||||
"@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/global": "workspace:*",
|
||||
"@blocksuite/std": "workspace:*",
|
||||
@@ -83,7 +71,6 @@
|
||||
"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",
|
||||
@@ -99,151 +86,59 @@
|
||||
"./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",
|
||||
"./blocks/attachment": "./src/blocks/attachment.ts",
|
||||
"./blocks/bookmark": "./src/blocks/bookmark.ts",
|
||||
"./blocks/callout": "./src/blocks/callout.ts",
|
||||
"./blocks/code": "./src/blocks/code.ts",
|
||||
"./blocks/data-view": "./src/blocks/data-view.ts",
|
||||
"./blocks/database": "./src/blocks/database.ts",
|
||||
"./blocks/divider": "./src/blocks/divider.ts",
|
||||
"./blocks/edgeless-text": "./src/blocks/edgeless-text.ts",
|
||||
"./blocks/embed": "./src/blocks/embed.ts",
|
||||
"./blocks/frame": "./src/blocks/frame.ts",
|
||||
"./blocks/image": "./src/blocks/image.ts",
|
||||
"./blocks/latex": "./src/blocks/latex.ts",
|
||||
"./blocks/list": "./src/blocks/list.ts",
|
||||
"./blocks/note": "./src/blocks/note.ts",
|
||||
"./blocks/paragraph": "./src/blocks/paragraph.ts",
|
||||
"./blocks/root": "./src/blocks/root.ts",
|
||||
"./blocks/surface": "./src/blocks/surface.ts",
|
||||
"./blocks/surface-ref": "./src/blocks/surface-ref.ts",
|
||||
"./blocks/table": "./src/blocks/table.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",
|
||||
"./inlines/link": "./src/inlines/link.ts",
|
||||
"./inlines/reference": "./src/inlines/reference.ts",
|
||||
"./inlines/preset": "./src/inlines/preset.ts",
|
||||
"./inlines/footnote": "./src/inlines/footnote.ts",
|
||||
"./inlines/latex": "./src/inlines/latex.ts",
|
||||
"./inlines/mention": "./src/inlines/mention.ts",
|
||||
"./widgets/drag-handle": "./src/widgets/drag-handle.ts",
|
||||
"./widgets/edgeless-auto-connect": "./src/widgets/edgeless-auto-connect.ts",
|
||||
"./widgets/edgeless-toolbar": "./src/widgets/edgeless-toolbar.ts",
|
||||
"./widgets/frame-title": "./src/widgets/frame-title.ts",
|
||||
"./widgets/linked-doc": "./src/widgets/linked-doc.ts",
|
||||
"./widgets/remote-selection": "./src/widgets/remote-selection.ts",
|
||||
"./widgets/scroll-anchoring": "./src/widgets/scroll-anchoring.ts",
|
||||
"./widgets/slash-menu": "./src/widgets/slash-menu.ts",
|
||||
"./widgets/toolbar": "./src/widgets/toolbar.ts",
|
||||
"./widgets/keyboard-toolbar": "./src/widgets/keyboard-toolbar.ts",
|
||||
"./fragments/doc-title": "./src/fragments/doc-title.ts",
|
||||
"./fragments/frame-panel": "./src/fragments/frame-panel.ts",
|
||||
"./fragments/outline": "./src/fragments/outline.ts",
|
||||
"./gfx/text": "./src/gfx/text.ts",
|
||||
"./gfx/brush": "./src/gfx/brush.ts",
|
||||
"./gfx/shape": "./src/gfx/shape.ts",
|
||||
"./gfx/note": "./src/gfx/note.ts",
|
||||
"./gfx/mindmap": "./src/gfx/mindmap.ts",
|
||||
"./gfx/connector": "./src/gfx/connector.ts",
|
||||
"./gfx/group": "./src/gfx/group.ts",
|
||||
"./gfx/template": "./src/gfx/template.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",
|
||||
@@ -266,7 +161,6 @@
|
||||
"./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",
|
||||
@@ -281,10 +175,8 @@
|
||||
"./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"
|
||||
"./adapters": "./src/adapters/index.ts",
|
||||
"./extensions": "./src/extensions/index.ts"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
@@ -295,7 +187,6 @@
|
||||
"version": "0.21.0",
|
||||
"devDependencies": {
|
||||
"@vanilla-extract/vite-plugin": "^5.0.0",
|
||||
"msw": "^2.8.4",
|
||||
"vitest": "3.1.3"
|
||||
"vitest": "3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ describe('snapshot to html', () => {
|
||||
};
|
||||
|
||||
const html = template(
|
||||
`<pre><code class="code-python">import this</code></pre>`
|
||||
`<pre class="shiki light-plus" style="background-color:#FFFFFF;color:#000000" tabindex="0"><code><span class="line"><span style="color:#AF00DB">import</span><span style="color:#000000"> this</span></span></code></pre>`
|
||||
);
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
@@ -191,7 +191,7 @@ describe('snapshot to html', () => {
|
||||
};
|
||||
|
||||
const html = template(
|
||||
`<pre><code class="code-PYTHON">import this</code></pre>`
|
||||
`<pre class="shiki light-plus" style="background-color:#FFFFFF;color:#000000" tabindex="0"><code><span class="line"><span>import this</span></span></code></pre>`
|
||||
);
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
@@ -257,7 +257,7 @@ describe('snapshot to html', () => {
|
||||
};
|
||||
|
||||
const html = template(
|
||||
`<pre><code class="code-unknown">import this</code></pre>`
|
||||
`<pre class="shiki light-plus" style="background-color:#FFFFFF;color:#000000" tabindex="0"><code><span class="line"><span>import this</span></span></code></pre>`
|
||||
);
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
@@ -2360,65 +2360,6 @@ describe('html to snapshot', () => {
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('should preserve space in p', async () => {
|
||||
const html = template(
|
||||
`<p>A <b>bold text</b> followed by a <i>italic text</i></p>`
|
||||
);
|
||||
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
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: ' followed by a ',
|
||||
},
|
||||
{
|
||||
insert: 'italic text',
|
||||
attributes: {
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
|
||||
file: html,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('span nested in p', async () => {
|
||||
const html = template(
|
||||
`<p><span>aaa</span><span>bbb</span><span>ccc</span></p>`
|
||||
@@ -2697,335 +2638,4 @@ describe('html to snapshot', () => {
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('block level element in b should not be treated as inline', async () => {
|
||||
const html = template(`<b><p><span>aaa</span></p></b>`);
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'aaa',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
|
||||
file: html,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
describe('strong element', () => {
|
||||
test('should not be bold when font-weight is normal', async () => {
|
||||
const html = template(`<span style="font-weight: normal;">aaa</span>`);
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'aaa',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
|
||||
file: html,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('should be bold when font-weight is bold or 500-900 ', async () => {
|
||||
const html = template(
|
||||
`<p><span style="font-weight: bold;">aaa</span><span style="font-weight: 100;">aaa</span><span style="font-weight: 500;">bbb</span><span style="font-weight: 200;">bbb</span><span style="font-weight: 600;">ccc</span><span style="font-weight: 300;">ccc</span><span style="font-weight: 700;">ddd</span></p>`
|
||||
);
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
attributes: {
|
||||
bold: true,
|
||||
},
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
bold: true,
|
||||
},
|
||||
insert: 'bbb',
|
||||
},
|
||||
{
|
||||
insert: 'bbb',
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
bold: true,
|
||||
},
|
||||
insert: 'ccc',
|
||||
},
|
||||
{
|
||||
insert: 'ccc',
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
bold: true,
|
||||
},
|
||||
insert: 'ddd',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
|
||||
file: html,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
});
|
||||
|
||||
test('should be italic when tag is i or em or span with style font-style: italic', async () => {
|
||||
const html = template(
|
||||
`<p><i>aaa</i><span>aaa</span><em>bbb</em><span>bbb</span><span style="font-style: italic;">ccc</span></p>`
|
||||
);
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
attributes: {
|
||||
italic: true,
|
||||
},
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
italic: true,
|
||||
},
|
||||
insert: 'bbb',
|
||||
},
|
||||
{
|
||||
insert: 'bbb',
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
italic: true,
|
||||
},
|
||||
insert: 'ccc',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
|
||||
file: html,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('should be underline when tag is u or span with style text-decoration: underline', async () => {
|
||||
const html = template(
|
||||
`<p><u>aaa</u><span>aaa</span><span style="text-decoration: underline;">bbb</span></p>`
|
||||
);
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
attributes: {
|
||||
underline: true,
|
||||
},
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
underline: true,
|
||||
},
|
||||
insert: 'bbb',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
|
||||
file: html,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('should be strike when tag is del or span with style text-decoration: line-through', async () => {
|
||||
const html = template(
|
||||
`<p><del>aaa</del><span>aaa</span><span style="text-decoration: line-through;">bbb</span></p>`
|
||||
);
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
attributes: {
|
||||
strike: true,
|
||||
},
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
insert: 'aaa',
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
strike: true,
|
||||
},
|
||||
insert: 'bbb',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const htmlAdapter = new HtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
|
||||
file: html,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,9 +4,6 @@ import {
|
||||
TableModelFlavour,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
CalloutAdmonitionType,
|
||||
CalloutExportStyle,
|
||||
calloutMarkdownExportMiddleware,
|
||||
embedSyncedDocMiddleware,
|
||||
MarkdownAdapter,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
@@ -2399,9 +2396,6 @@ World!
|
||||
reference: {
|
||||
type: 'url',
|
||||
url: 'https://www.example.com',
|
||||
favicon: 'https://www.example.com/favicon.ico',
|
||||
title: 'Example Domain',
|
||||
description: 'Example Domain',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2443,7 +2437,7 @@ World!
|
||||
};
|
||||
|
||||
const markdown =
|
||||
'aaa[^1][^2][^3]\n\n[^1]: {"type":"url","url":"https%3A%2F%2Fwww.example.com","favicon":"https%3A%2F%2Fwww.example.com%2Ffavicon.ico","title":"Example Domain","description":"Example Domain"}\n\n[^2]: {"type":"doc","docId":"deadbeef"}\n\n[^3]: {"type":"attachment","blobId":"abcdefg","fileName":"test.txt","fileType":"text/plain"}\n';
|
||||
'aaa[^1][^2][^3]\n\n[^1]: {"type":"url","url":"https%3A%2F%2Fwww.example.com"}\n\n[^2]: {"type":"doc","docId":"deadbeef"}\n\n[^3]: {"type":"attachment","blobId":"abcdefg","fileName":"test.txt","fileType":"text/plain"}\n';
|
||||
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const target = await mdAdapter.fromBlockSnapshot({
|
||||
@@ -2451,290 +2445,6 @@ World!
|
||||
});
|
||||
expect(target.file).toBe(markdown);
|
||||
});
|
||||
|
||||
describe('callout', () => {
|
||||
test('without export middleware', async () => {
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'block:vu6SK6WJpW',
|
||||
flavour: 'affine:page',
|
||||
props: {
|
||||
title: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [],
|
||||
},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:Tk4gSPocAt',
|
||||
flavour: 'affine:surface',
|
||||
props: {
|
||||
elements: {},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:WfnS5ZDCJT',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:callout',
|
||||
props: {
|
||||
emoji: '💡',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [{ insert: 'First callout' }],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxadvdv',
|
||||
flavour: 'affine:callout',
|
||||
props: {
|
||||
emoji: '',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{ insert: 'Warning second callout without emoji' },
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [{ insert: 'Text in second callout' }],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const markdown = `> \\[!💡]
|
||||
>
|
||||
> First callout
|
||||
|
||||
> \\[!]
|
||||
>
|
||||
> Warning second callout without emoji
|
||||
>
|
||||
> Text in second callout
|
||||
`;
|
||||
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const target = await mdAdapter.fromBlockSnapshot({
|
||||
snapshot: blockSnapshot,
|
||||
});
|
||||
expect(target.file).toBe(markdown);
|
||||
});
|
||||
|
||||
test('with export middleware', async () => {
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'block:vu6SK6WJpW',
|
||||
flavour: 'affine:page',
|
||||
props: {
|
||||
title: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [],
|
||||
},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:Tk4gSPocAt',
|
||||
flavour: 'affine:surface',
|
||||
props: {
|
||||
elements: {},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:WfnS5ZDCJT',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:callout',
|
||||
props: {
|
||||
emoji: '💡',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{ insert: 'Callout that does not have a title' },
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxadvdv',
|
||||
flavour: 'affine:callout',
|
||||
props: {
|
||||
emoji: '',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert:
|
||||
'Warning callout with custom title and multiple paragraphs',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [{ insert: 'Text in second callout' }],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:callout',
|
||||
props: {
|
||||
emoji: '💡',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'block:8hOLxad5Fv',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{ insert: 'details' },
|
||||
{ insert: ' ' },
|
||||
{ insert: '\nText in details callout with new line' },
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const markdown = `::: info
|
||||
|
||||
Callout that does not have a title
|
||||
|
||||
:::
|
||||
|
||||
::: warning callout with custom title and multiple paragraphs
|
||||
|
||||
Text in second callout
|
||||
|
||||
:::
|
||||
|
||||
::: details
|
||||
|
||||
Text in details callout with new line
|
||||
|
||||
:::
|
||||
`;
|
||||
|
||||
const mdAdapter = new MarkdownAdapter(
|
||||
createJob([
|
||||
calloutMarkdownExportMiddleware({
|
||||
style: CalloutExportStyle.Admonitions,
|
||||
admonitionType: CalloutAdmonitionType.Info,
|
||||
}),
|
||||
]),
|
||||
provider
|
||||
);
|
||||
const target = await mdAdapter.fromBlockSnapshot({
|
||||
snapshot: blockSnapshot,
|
||||
});
|
||||
expect(target.file).toBe(markdown);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('markdown to snapshot', () => {
|
||||
@@ -3875,7 +3585,7 @@ bbb
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: {
|
||||
dark: '#252525',
|
||||
dark: '#000000',
|
||||
light: '#ffffff',
|
||||
},
|
||||
index: 'a0',
|
||||
@@ -4318,12 +4028,11 @@ hhh
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
describe('footnote', () => {
|
||||
const url = 'https://www.example.com';
|
||||
const favicon = 'https://www.example.com/favicon.ico';
|
||||
const title = 'Example Domain';
|
||||
const description = 'Example Domain';
|
||||
const blockSnapshot = {
|
||||
test('without footnote middleware', async () => {
|
||||
const markdown =
|
||||
'aaa[^1][^2][^3]\n\n[^1]: {"type":"url","url":"https%3A%2F%2Fwww.example.com"}\n\n[^2]: {"type":"doc","docId":"deadbeef"}\n\n[^3]: {"type":"attachment","blobId":"abcdefg","fileName":"test.txt","fileType":"text/plain"}\n';
|
||||
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
@@ -4354,10 +4063,7 @@ hhh
|
||||
label: '1',
|
||||
reference: {
|
||||
type: 'url',
|
||||
url,
|
||||
favicon,
|
||||
title,
|
||||
description,
|
||||
url: 'https://www.example.com',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -4393,180 +4099,14 @@ hhh
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[2]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'h6',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'Sources',
|
||||
},
|
||||
],
|
||||
},
|
||||
collapsed: true,
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[3]',
|
||||
flavour: 'affine:bookmark',
|
||||
props: {
|
||||
style: 'citation',
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
icon: favicon,
|
||||
footnoteIdentifier: '1',
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[4]',
|
||||
flavour: 'affine:embed-linked-doc',
|
||||
props: {
|
||||
style: 'citation',
|
||||
pageId: 'deadbeef',
|
||||
footnoteIdentifier: '2',
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[5]',
|
||||
flavour: 'affine:attachment',
|
||||
props: {
|
||||
name: 'test.txt',
|
||||
sourceId: 'abcdefg',
|
||||
footnoteIdentifier: '3',
|
||||
style: 'citation',
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
test('with encoded url and favicon', async () => {
|
||||
const encodedUrl = encodeURIComponent(url);
|
||||
const encodedFavicon = encodeURIComponent(favicon);
|
||||
const markdown = `aaa[^1][^2][^3]\n\n[^1]: {"type":"url","url":"${encodedUrl}","favicon":"${encodedFavicon}","title":"${title}","description":"${description}"}\n\n[^2]: {"type":"doc","docId":"deadbeef"}\n\n[^3]: {"type":"attachment","blobId":"abcdefg","fileName":"test.txt","fileType":"text/plain"}\n`;
|
||||
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await mdAdapter.toBlockSnapshot({
|
||||
file: markdown,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('with unencoded url and favicon', async () => {
|
||||
const markdown = `aaa[^1][^2][^3]\n\n[^1]: {"type":"url","url":"${url}","favicon":"${favicon}","title":"${title}","description":"${description}"}\n\n[^2]: {"type":"doc","docId":"deadbeef"}\n\n[^3]: {"type":"attachment","blobId":"abcdefg","fileName":"test.txt","fileType":"text/plain"}\n`;
|
||||
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await mdAdapter.toBlockSnapshot({
|
||||
file: markdown,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('should handle footnote reference with url prefix', async () => {
|
||||
const blockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'https://example.com',
|
||||
attributes: {
|
||||
link: 'https://example.com',
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: ' ',
|
||||
},
|
||||
{
|
||||
insert: ' ',
|
||||
attributes: {
|
||||
footnote: {
|
||||
label: '1',
|
||||
reference: {
|
||||
type: 'url',
|
||||
url,
|
||||
favicon,
|
||||
title,
|
||||
description,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[2]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'h6',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'Sources',
|
||||
},
|
||||
],
|
||||
},
|
||||
collapsed: true,
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[3]',
|
||||
flavour: 'affine:bookmark',
|
||||
props: {
|
||||
style: 'citation',
|
||||
url,
|
||||
title,
|
||||
description,
|
||||
icon: favicon,
|
||||
footnoteIdentifier: '1',
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const markdown = `https://example.com[^1]\n\n[^1]: {"type":"url","url":"${url}","favicon":"${favicon}","title":"${title}","description":"${description}"}\n`;
|
||||
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await mdAdapter.toBlockSnapshot({
|
||||
file: markdown,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await mdAdapter.toBlockSnapshot({
|
||||
file: markdown,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('should not wrap url with angle brackets if it is not a url', async () => {
|
||||
@@ -4619,62 +4159,4 @@ hhh
|
||||
});
|
||||
expect(nanoidReplacement(rawSliceSnapshot!)).toEqual(sliceSnapshot);
|
||||
});
|
||||
|
||||
describe('callout', () => {
|
||||
const calloutBlockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:callout',
|
||||
props: {
|
||||
emoji: '💬',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[2]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [{ insert: 'This is a callout' }],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
test('callout start with escape character', async () => {
|
||||
const markdown = '> \\[!💬]\n> This is a callout';
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await mdAdapter.toBlockSnapshot({
|
||||
file: markdown,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(calloutBlockSnapshot);
|
||||
});
|
||||
|
||||
test('callout start without escape character', async () => {
|
||||
const markdown = '> [!💬]\n> This is a callout';
|
||||
const mdAdapter = new MarkdownAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await mdAdapter.toBlockSnapshot({
|
||||
file: markdown,
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(calloutBlockSnapshot);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters';
|
||||
import { DEFAULT_IMAGE_PROXY_ENDPOINT } from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
AssetsManager,
|
||||
type BlockSnapshot,
|
||||
MemoryBlobCRUD,
|
||||
} from '@blocksuite/store';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { createJob } from '../utils/create-job.js';
|
||||
import { getProvider } from '../utils/get-provider.js';
|
||||
@@ -1198,71 +1195,43 @@ describe('notion html to snapshot', () => {
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
describe('image', () => {
|
||||
const originalUrl =
|
||||
'https://raw.githubusercontent.com/toeverything/blocksuite/master/assets/logo.svg';
|
||||
test('image', async () => {
|
||||
const html = `<div class="page-body">
|
||||
<figure id="ed3d2ae9-62f5-433a-9049-9ddbd1c81ac5" class="image"><a
|
||||
href="https://raw.githubusercontent.com/toeverything/blocksuite/master/assets/logo.svg"><img src="https://raw.githubusercontent.com/toeverything/blocksuite/master/assets/logo.svg" /></a>
|
||||
</figure>
|
||||
</div>`;
|
||||
|
||||
const imageProxy = DEFAULT_IMAGE_PROXY_ENDPOINT;
|
||||
const imageUrl = `${imageProxy}?url=${encodeURIComponent(originalUrl)}`;
|
||||
|
||||
// Mock the image request
|
||||
const imageRequestHandlers = [
|
||||
http.get(imageUrl.toString(), async () => {
|
||||
// Return a mock image blob
|
||||
const mockImageBlob = new Blob(['mock image data'], {
|
||||
type: 'image/svg+xml',
|
||||
});
|
||||
return new HttpResponse(mockImageBlob, {
|
||||
headers: {
|
||||
'Content-Type': 'image/svg+xml',
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:image',
|
||||
props: {
|
||||
sourceId: 'matchesReplaceMap[2]',
|
||||
},
|
||||
});
|
||||
}),
|
||||
];
|
||||
|
||||
const server = setupServer(...imageRequestHandlers);
|
||||
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
|
||||
afterAll(() => server.close());
|
||||
afterEach(() => server.resetHandlers());
|
||||
|
||||
test('network image resource', async () => {
|
||||
const html = `<div class="page-body">
|
||||
<figure id="ed3d2ae9-62f5-433a-9049-9ddbd1c81ac5" class="image"><a
|
||||
href="${originalUrl}"><img src="${originalUrl}" /></a>
|
||||
</figure>
|
||||
</div>`;
|
||||
|
||||
const blockSnapshot: BlockSnapshot = {
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: NoteDisplayMode.DocAndEdgeless,
|
||||
children: [],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:image',
|
||||
props: {
|
||||
sourceId: 'matchesReplaceMap[2]',
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
],
|
||||
};
|
||||
|
||||
const adapter = new NotionHtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await adapter.toBlockSnapshot({
|
||||
file: html,
|
||||
assets: new AssetsManager({ blob: new MemoryBlobCRUD() }),
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
const adapter = new NotionHtmlAdapter(createJob(), provider);
|
||||
const rawBlockSnapshot = await adapter.toBlockSnapshot({
|
||||
file: html,
|
||||
assets: new AssetsManager({ blob: new MemoryBlobCRUD() }),
|
||||
});
|
||||
expect(nanoidReplacement(rawBlockSnapshot)).toEqual(blockSnapshot);
|
||||
});
|
||||
|
||||
test('bookmark', async () => {
|
||||
|
||||
@@ -106,65 +106,4 @@ describe('notion-text to snapshot', () => {
|
||||
});
|
||||
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,4 +1,5 @@
|
||||
import { defaultImageProxyMiddleware } from '@blocksuite/affine-shared/adapters';
|
||||
import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image';
|
||||
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
Schema,
|
||||
Transformer,
|
||||
@@ -7,7 +8,6 @@ import {
|
||||
import { TestWorkspace } from '@blocksuite/store/test';
|
||||
|
||||
import { AffineSchemas } from '../../schemas.js';
|
||||
import { testStoreExtensions } from './store.js';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@@ -27,7 +27,7 @@ export function createJob(middlewares?: TransformerMiddleware[]) {
|
||||
testMiddlewares.push(defaultImageProxyMiddleware);
|
||||
const schema = new Schema().register(AffineSchemas);
|
||||
const docCollection = new TestWorkspace();
|
||||
docCollection.storeExtensions = testStoreExtensions;
|
||||
docCollection.storeExtensions = SpecProvider._.getSpec('store').value;
|
||||
docCollection.meta.initialize();
|
||||
return new Transformer({
|
||||
schema,
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||
import { Container } from '@blocksuite/global/di';
|
||||
|
||||
import { testStoreExtensions } from './store';
|
||||
import {
|
||||
registerBlockSpecs,
|
||||
registerStoreSpecs,
|
||||
} from '../../extensions/register';
|
||||
|
||||
registerStoreSpecs();
|
||||
registerBlockSpecs();
|
||||
|
||||
export function getProvider() {
|
||||
const container = new Container();
|
||||
const exts = testStoreExtensions;
|
||||
const exts = SpecProvider._.getSpec('store').value;
|
||||
exts.forEach(ext => {
|
||||
ext.setup(container);
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
69
blocksuite/affine/all/src/adapters/extension.ts
Normal file
69
blocksuite/affine/all/src/adapters/extension.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import {
|
||||
HtmlInlineToDeltaAdapterExtensions,
|
||||
InlineDeltaToHtmlAdapterExtensions,
|
||||
InlineDeltaToMarkdownAdapterExtensions,
|
||||
InlineDeltaToPlainTextAdapterExtensions,
|
||||
MarkdownInlineToDeltaAdapterExtensions,
|
||||
NotionHtmlInlineToDeltaAdapterExtensions,
|
||||
} from '@blocksuite/affine-inline-preset';
|
||||
import {
|
||||
AttachmentAdapterFactoryExtension,
|
||||
HtmlAdapterFactoryExtension,
|
||||
ImageAdapterFactoryExtension,
|
||||
MarkdownAdapterFactoryExtension,
|
||||
MixTextAdapterFactoryExtension,
|
||||
NotionHtmlAdapterFactoryExtension,
|
||||
NotionTextAdapterFactoryExtension,
|
||||
PlainTextAdapterFactoryExtension,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import { defaultBlockHtmlAdapterMatchers } from './html/block-matcher';
|
||||
import { defaultBlockMarkdownAdapterMatchers } from './markdown/block-matcher';
|
||||
import { defaultMarkdownPreprocessors } from './markdown/preprocessor';
|
||||
import { defaultBlockNotionHtmlAdapterMatchers } from './notion-html/block-matcher';
|
||||
import { defaultBlockPlainTextAdapterMatchers } from './plain-text/block-matcher';
|
||||
|
||||
export function getAdapterFactoryExtensions(): ExtensionType[] {
|
||||
return [
|
||||
AttachmentAdapterFactoryExtension,
|
||||
ImageAdapterFactoryExtension,
|
||||
MarkdownAdapterFactoryExtension,
|
||||
PlainTextAdapterFactoryExtension,
|
||||
HtmlAdapterFactoryExtension,
|
||||
NotionTextAdapterFactoryExtension,
|
||||
NotionHtmlAdapterFactoryExtension,
|
||||
MixTextAdapterFactoryExtension,
|
||||
];
|
||||
}
|
||||
|
||||
export function getHtmlAdapterExtensions(): ExtensionType[] {
|
||||
return [
|
||||
...HtmlInlineToDeltaAdapterExtensions,
|
||||
...defaultBlockHtmlAdapterMatchers,
|
||||
...InlineDeltaToHtmlAdapterExtensions,
|
||||
];
|
||||
}
|
||||
|
||||
export function getMarkdownAdapterExtensions(): ExtensionType[] {
|
||||
return [
|
||||
...MarkdownInlineToDeltaAdapterExtensions,
|
||||
...defaultBlockMarkdownAdapterMatchers,
|
||||
...InlineDeltaToMarkdownAdapterExtensions,
|
||||
...defaultMarkdownPreprocessors,
|
||||
];
|
||||
}
|
||||
|
||||
export function getNotionHtmlAdapterExtensions(): ExtensionType[] {
|
||||
return [
|
||||
...NotionHtmlInlineToDeltaAdapterExtensions,
|
||||
...defaultBlockNotionHtmlAdapterMatchers,
|
||||
];
|
||||
}
|
||||
|
||||
export function getPlainTextAdapterExtensions(): ExtensionType[] {
|
||||
return [
|
||||
...defaultBlockPlainTextAdapterMatchers,
|
||||
...InlineDeltaToPlainTextAdapterExtensions,
|
||||
];
|
||||
}
|
||||
37
blocksuite/affine/all/src/adapters/html/block-matcher.ts
Normal file
37
blocksuite/affine/all/src/adapters/html/block-matcher.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { BookmarkBlockHtmlAdapterExtension } from '@blocksuite/affine-block-bookmark';
|
||||
import { CodeBlockHtmlAdapterExtension } from '@blocksuite/affine-block-code';
|
||||
import { DatabaseBlockHtmlAdapterExtension } from '@blocksuite/affine-block-database';
|
||||
import { DividerBlockHtmlAdapterExtension } from '@blocksuite/affine-block-divider';
|
||||
import {
|
||||
EmbedFigmaBlockHtmlAdapterExtension,
|
||||
EmbedGithubBlockHtmlAdapterExtension,
|
||||
EmbedIframeBlockHtmlAdapterExtension,
|
||||
EmbedLinkedDocHtmlAdapterExtension,
|
||||
EmbedLoomBlockHtmlAdapterExtension,
|
||||
EmbedSyncedDocBlockHtmlAdapterExtension,
|
||||
EmbedYoutubeBlockHtmlAdapterExtension,
|
||||
} from '@blocksuite/affine-block-embed';
|
||||
import { ImageBlockHtmlAdapterExtension } from '@blocksuite/affine-block-image';
|
||||
import { ListBlockHtmlAdapterExtension } from '@blocksuite/affine-block-list';
|
||||
import { ParagraphBlockHtmlAdapterExtension } from '@blocksuite/affine-block-paragraph';
|
||||
import { RootBlockHtmlAdapterExtension } from '@blocksuite/affine-block-root';
|
||||
import { TableBlockHtmlAdapterExtension } from '@blocksuite/affine-block-table';
|
||||
|
||||
export const defaultBlockHtmlAdapterMatchers = [
|
||||
ListBlockHtmlAdapterExtension,
|
||||
ParagraphBlockHtmlAdapterExtension,
|
||||
CodeBlockHtmlAdapterExtension,
|
||||
DividerBlockHtmlAdapterExtension,
|
||||
ImageBlockHtmlAdapterExtension,
|
||||
RootBlockHtmlAdapterExtension,
|
||||
EmbedYoutubeBlockHtmlAdapterExtension,
|
||||
EmbedFigmaBlockHtmlAdapterExtension,
|
||||
EmbedLoomBlockHtmlAdapterExtension,
|
||||
EmbedGithubBlockHtmlAdapterExtension,
|
||||
EmbedIframeBlockHtmlAdapterExtension,
|
||||
BookmarkBlockHtmlAdapterExtension,
|
||||
DatabaseBlockHtmlAdapterExtension,
|
||||
TableBlockHtmlAdapterExtension,
|
||||
EmbedLinkedDocHtmlAdapterExtension,
|
||||
EmbedSyncedDocBlockHtmlAdapterExtension,
|
||||
];
|
||||
6
blocksuite/affine/all/src/adapters/index.ts
Normal file
6
blocksuite/affine/all/src/adapters/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from './extension.js';
|
||||
export * from './html/block-matcher.js';
|
||||
export * from './markdown/block-matcher.js';
|
||||
export * from './markdown/preprocessor.js';
|
||||
export * from './notion-html/block-matcher.js';
|
||||
export * from './plain-text/block-matcher.js';
|
||||
41
blocksuite/affine/all/src/adapters/markdown/block-matcher.ts
Normal file
41
blocksuite/affine/all/src/adapters/markdown/block-matcher.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { BookmarkBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-bookmark';
|
||||
import { CodeBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-code';
|
||||
import { DatabaseBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-database';
|
||||
import { DividerBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-divider';
|
||||
import {
|
||||
EmbedFigmaMarkdownAdapterExtension,
|
||||
EmbedGithubMarkdownAdapterExtension,
|
||||
EmbedIframeBlockMarkdownAdapterExtension,
|
||||
EmbedLinkedDocMarkdownAdapterExtension,
|
||||
EmbedLoomMarkdownAdapterExtension,
|
||||
EmbedSyncedDocMarkdownAdapterExtension,
|
||||
EmbedYoutubeMarkdownAdapterExtension,
|
||||
} from '@blocksuite/affine-block-embed';
|
||||
import { ImageBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-image';
|
||||
import { LatexBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-latex';
|
||||
import { ListBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-list';
|
||||
import { DocNoteBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-note';
|
||||
import { ParagraphBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-paragraph';
|
||||
import { RootBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-root';
|
||||
import { TableBlockMarkdownAdapterExtension } from '@blocksuite/affine-block-table';
|
||||
|
||||
export const defaultBlockMarkdownAdapterMatchers = [
|
||||
RootBlockMarkdownAdapterExtension,
|
||||
DocNoteBlockMarkdownAdapterExtension,
|
||||
EmbedFigmaMarkdownAdapterExtension,
|
||||
EmbedGithubMarkdownAdapterExtension,
|
||||
EmbedLinkedDocMarkdownAdapterExtension,
|
||||
EmbedLoomMarkdownAdapterExtension,
|
||||
EmbedSyncedDocMarkdownAdapterExtension,
|
||||
EmbedYoutubeMarkdownAdapterExtension,
|
||||
EmbedIframeBlockMarkdownAdapterExtension,
|
||||
ListBlockMarkdownAdapterExtension,
|
||||
ParagraphBlockMarkdownAdapterExtension,
|
||||
BookmarkBlockMarkdownAdapterExtension,
|
||||
CodeBlockMarkdownAdapterExtension,
|
||||
DatabaseBlockMarkdownAdapterExtension,
|
||||
TableBlockMarkdownAdapterExtension,
|
||||
DividerBlockMarkdownAdapterExtension,
|
||||
ImageBlockMarkdownAdapterExtension,
|
||||
LatexBlockMarkdownAdapterExtension,
|
||||
];
|
||||
@@ -0,0 +1,7 @@
|
||||
import { CodeMarkdownPreprocessorExtension } from '@blocksuite/affine-block-code';
|
||||
import { LatexMarkdownPreprocessorExtension } from '@blocksuite/affine-block-latex';
|
||||
|
||||
export const defaultMarkdownPreprocessors = [
|
||||
LatexMarkdownPreprocessorExtension,
|
||||
CodeMarkdownPreprocessorExtension,
|
||||
];
|
||||
@@ -0,0 +1,34 @@
|
||||
import { AttachmentBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-attachment';
|
||||
import { BookmarkBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-bookmark';
|
||||
import { CodeBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-code';
|
||||
import { DatabaseBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-database';
|
||||
import { DividerBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-divider';
|
||||
import {
|
||||
EmbedFigmaBlockNotionHtmlAdapterExtension,
|
||||
EmbedGithubBlockNotionHtmlAdapterExtension,
|
||||
EmbedLoomBlockNotionHtmlAdapterExtension,
|
||||
EmbedYoutubeBlockNotionHtmlAdapterExtension,
|
||||
} from '@blocksuite/affine-block-embed';
|
||||
import { ImageBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-image';
|
||||
import { LatexBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-latex';
|
||||
import { ListBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-list';
|
||||
import { ParagraphBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-paragraph';
|
||||
import { RootBlockNotionHtmlAdapterExtension } from '@blocksuite/affine-block-root';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
export const defaultBlockNotionHtmlAdapterMatchers: ExtensionType[] = [
|
||||
ListBlockNotionHtmlAdapterExtension,
|
||||
ParagraphBlockNotionHtmlAdapterExtension,
|
||||
CodeBlockNotionHtmlAdapterExtension,
|
||||
DividerBlockNotionHtmlAdapterExtension,
|
||||
ImageBlockNotionHtmlAdapterExtension,
|
||||
RootBlockNotionHtmlAdapterExtension,
|
||||
BookmarkBlockNotionHtmlAdapterExtension,
|
||||
DatabaseBlockNotionHtmlAdapterExtension,
|
||||
LatexBlockNotionHtmlAdapterExtension,
|
||||
EmbedYoutubeBlockNotionHtmlAdapterExtension,
|
||||
EmbedFigmaBlockNotionHtmlAdapterExtension,
|
||||
EmbedGithubBlockNotionHtmlAdapterExtension,
|
||||
EmbedLoomBlockNotionHtmlAdapterExtension,
|
||||
AttachmentBlockNotionHtmlAdapterExtension,
|
||||
];
|
||||
@@ -0,0 +1,34 @@
|
||||
import { BookmarkBlockPlainTextAdapterExtension } from '@blocksuite/affine-block-bookmark';
|
||||
import { CodeBlockPlainTextAdapterExtension } from '@blocksuite/affine-block-code';
|
||||
import { DatabaseBlockPlainTextAdapterExtension } from '@blocksuite/affine-block-database';
|
||||
import { DividerBlockPlainTextAdapterExtension } from '@blocksuite/affine-block-divider';
|
||||
import {
|
||||
EmbedFigmaBlockPlainTextAdapterExtension,
|
||||
EmbedGithubBlockPlainTextAdapterExtension,
|
||||
EmbedIframeBlockPlainTextAdapterExtension,
|
||||
EmbedLinkedDocBlockPlainTextAdapterExtension,
|
||||
EmbedLoomBlockPlainTextAdapterExtension,
|
||||
EmbedSyncedDocBlockPlainTextAdapterExtension,
|
||||
EmbedYoutubeBlockPlainTextAdapterExtension,
|
||||
} from '@blocksuite/affine-block-embed';
|
||||
import { LatexBlockPlainTextAdapterExtension } from '@blocksuite/affine-block-latex';
|
||||
import { ListBlockPlainTextAdapterExtension } from '@blocksuite/affine-block-list';
|
||||
import { ParagraphBlockPlainTextAdapterExtension } from '@blocksuite/affine-block-paragraph';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
export const defaultBlockPlainTextAdapterMatchers: ExtensionType[] = [
|
||||
ParagraphBlockPlainTextAdapterExtension,
|
||||
ListBlockPlainTextAdapterExtension,
|
||||
DividerBlockPlainTextAdapterExtension,
|
||||
CodeBlockPlainTextAdapterExtension,
|
||||
BookmarkBlockPlainTextAdapterExtension,
|
||||
EmbedFigmaBlockPlainTextAdapterExtension,
|
||||
EmbedGithubBlockPlainTextAdapterExtension,
|
||||
EmbedLoomBlockPlainTextAdapterExtension,
|
||||
EmbedYoutubeBlockPlainTextAdapterExtension,
|
||||
EmbedLinkedDocBlockPlainTextAdapterExtension,
|
||||
EmbedSyncedDocBlockPlainTextAdapterExtension,
|
||||
EmbedIframeBlockPlainTextAdapterExtension,
|
||||
LatexBlockPlainTextAdapterExtension,
|
||||
DatabaseBlockPlainTextAdapterExtension,
|
||||
];
|
||||
@@ -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/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-bookmark/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-callout/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-callout/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-code/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-code/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-data-view/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-data-view/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-database/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-database/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-divider/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-divider/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-edgeless-text/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-edgeless-text/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-embed-doc';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-embed-doc/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-embed-doc/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-embed/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-embed/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-frame/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-frame/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-image/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-image/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-latex/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-latex/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-list/store';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-list/view';
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-block-note/store';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user