mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 11:58:41 +00:00
ci: refactor workflow (#5139)
Merge tests job into single one, reuse job as much as possible
This commit is contained in:
48
.github/actions/build-rust/action.yml
vendored
48
.github/actions/build-rust/action.yml
vendored
@@ -29,6 +29,11 @@ runs:
|
||||
env:
|
||||
CARGO_INCREMENTAL: '1'
|
||||
|
||||
- name: Set CC
|
||||
if: ${{ contains(inputs.target, 'linux') && inputs.package != '@affine/native' }}
|
||||
shell: bash
|
||||
run: echo "CC=clang" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
@@ -36,51 +41,12 @@ runs:
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
.cargo-cache
|
||||
~/.napi-rs
|
||||
target/${{ inputs.target }}
|
||||
key: stable-${{ inputs.target }}-cargo-cache
|
||||
- name: Build
|
||||
if: ${{ inputs.target != 'x86_64-unknown-linux-gnu' && inputs.target != 'aarch64-unknown-linux-gnu' }}
|
||||
shell: bash
|
||||
run: |
|
||||
yarn workspace ${{ inputs.package }} nx build ${{ inputs.package }} --target ${{ inputs.target }}
|
||||
yarn workspace ${{ inputs.package }} nx build ${{ inputs.package }} --target ${{ inputs.target }} --use-napi-cross
|
||||
env:
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ inputs.nx_token }}
|
||||
|
||||
- name: Build
|
||||
if: ${{ inputs.target == 'x86_64-unknown-linux-gnu' }}
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build -e NX_CLOUD_ACCESS_TOKEN=${{ inputs.nx_token }}
|
||||
run: |
|
||||
export CC=x86_64-unknown-linux-gnu-gcc
|
||||
export CC_x86_64_unknown_linux_gnu=x86_64-unknown-linux-gnu-gcc
|
||||
rm -rf /usr/local/rustup/downloads/*
|
||||
rustup target add x86_64-unknown-linux-gnu
|
||||
export RUSTFLAGS="-C debuginfo=1"
|
||||
yarn workspace ${{ inputs.package }} nx build ${{ inputs.package }} --target ${{ inputs.target }}
|
||||
if [ -d "node_modules/.cache" ]; then
|
||||
chmod -R 777 node_modules/.cache
|
||||
fi
|
||||
if [ -d "target" ]; then
|
||||
chmod -R 777 target;
|
||||
fi
|
||||
|
||||
- name: Build
|
||||
if: ${{ inputs.target == 'aarch64-unknown-linux-gnu' }}
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
|
||||
options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build -e NX_CLOUD_ACCESS_TOKEN=${{ inputs.nx_token }}
|
||||
run: |
|
||||
export RUSTFLAGS="-C debuginfo=1"
|
||||
rm -rf /usr/local/rustup/downloads/*
|
||||
rustup target add aarch64-unknown-linux-gnu
|
||||
yarn workspace ${{ inputs.package }} nx build ${{ inputs.package }} --target ${{ inputs.target }}
|
||||
if [ -d "node_modules/.cache" ]; then
|
||||
chmod -R 777 node_modules/.cache
|
||||
fi
|
||||
if [ -d "target" ]; then
|
||||
chmod -R 777 target;
|
||||
fi
|
||||
|
||||
22
.github/actions/download-core/action.yml
vendored
Normal file
22
.github/actions/download-core/action.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: 'Download core artifacts'
|
||||
description: 'Download core artifacts and extract to dist'
|
||||
inputs:
|
||||
path:
|
||||
description: 'Path to extract'
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Download tar.gz
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: core
|
||||
path: .
|
||||
|
||||
- name: Extract core artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ${{ inputs.path }}
|
||||
tar -xvf dist.tar.gz --directory ${{ inputs.path }}
|
||||
rm dist.tar.gz
|
||||
41
.github/actions/setup-node/action.yml
vendored
41
.github/actions/setup-node/action.yml
vendored
@@ -36,6 +36,9 @@ inputs:
|
||||
description: 'Set enableScripts in .yarnrc.yml'
|
||||
required: false
|
||||
default: 'true'
|
||||
full-cache:
|
||||
description: 'Full installation cache'
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
@@ -46,7 +49,6 @@ runs:
|
||||
node-version-file: '.nvmrc'
|
||||
registry-url: https://npm.pkg.github.com
|
||||
scope: '@toeverything'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Set nmMode
|
||||
if: ${{ inputs.hard-link-nm == 'false' }}
|
||||
@@ -63,6 +65,29 @@ runs:
|
||||
shell: bash
|
||||
run: yarn config set enableScripts false
|
||||
|
||||
- name: Set yarn global cache path
|
||||
shell: bash
|
||||
id: yarn-cache
|
||||
run: node -e "const p = $(yarn config cacheFolder --json).effective; console.log('yarn_global_cache=' + p)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache non-full yarn cache
|
||||
uses: actions/cache@v3
|
||||
if: ${{ inputs.full-cache != 'true' }}
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
${{ steps.yarn-cache.outputs.yarn_global_cache }}
|
||||
key: node_modules-cache-${{ github.job }}-${{ runner.os }}
|
||||
|
||||
- name: Cache full yarn cache
|
||||
uses: actions/cache@v3
|
||||
if: ${{ inputs.full-cache == 'true' }}
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
${{ steps.yarn-cache.outputs.yarn_global_cache }}
|
||||
key: node_modules-cache-full-${{ runner.os }}
|
||||
|
||||
- name: yarn install
|
||||
if: ${{ inputs.package-install == 'true' }}
|
||||
continue-on-error: true
|
||||
@@ -102,8 +127,8 @@ runs:
|
||||
id: playwright-cache
|
||||
if: ${{ inputs.playwright-install == 'true' }}
|
||||
with:
|
||||
path: '~/.cache/ms-playwright'
|
||||
key: '${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright-version.outputs.version }}'
|
||||
path: ${{ github.workspace }}/node_modules/.cache/ms-playwright
|
||||
key: '${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}'
|
||||
# As a fallback, if the Playwright version has changed, try use the
|
||||
# most recently cached version. There's a good chance that at least one
|
||||
# of the browser binary versions haven't been updated, so Playwright can
|
||||
@@ -113,7 +138,7 @@ runs:
|
||||
# date cache, but still let Playwright decide if it needs to download
|
||||
# new binaries or not.
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ runner.arch }}-playwright-
|
||||
${{ runner.os }}-playwright-
|
||||
|
||||
# If the Playwright browser binaries weren't able to be restored, we tell
|
||||
# playwright to install everything for us.
|
||||
@@ -121,6 +146,8 @@ runs:
|
||||
shell: bash
|
||||
if: inputs.playwright-install == 'true'
|
||||
run: yarn playwright install --with-deps chromium
|
||||
env:
|
||||
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/node_modules/.cache/ms-playwright
|
||||
|
||||
- name: Get installed Electron version
|
||||
id: electron-version
|
||||
@@ -134,16 +161,16 @@ runs:
|
||||
if: ${{ inputs.electron-install == 'true' }}
|
||||
with:
|
||||
path: 'node_modules/.cache/electron'
|
||||
key: '${{ runner.os }}-{{ runner.arch }}-electron-${{ steps.electron-version.outputs.version }}'
|
||||
key: '${{ runner.os }}-electron-${{ steps.electron-version.outputs.version }}'
|
||||
restore-keys: |
|
||||
${{ runner.os }}-{{ runner.arch }}-electron-
|
||||
${{ runner.os }}-electron-
|
||||
|
||||
- name: Install Electron binary
|
||||
shell: bash
|
||||
if: inputs.electron-install == 'true'
|
||||
run: node ./node_modules/electron/install.js
|
||||
env:
|
||||
ELECTRON_OVERRIDE_DIST_PATH: ./node_modules/.cache/electron
|
||||
electron_config_cache: ./node_modules/.cache/electron
|
||||
|
||||
- name: Build Infra
|
||||
shell: bash
|
||||
|
||||
190
.github/workflows/build-desktop.yml
vendored
190
.github/workflows/build-desktop.yml
vendored
@@ -1,190 +0,0 @@
|
||||
name: Build(Desktop) & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- canary
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build-desktop.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
pull_request:
|
||||
merge_group:
|
||||
branches:
|
||||
- canary
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build-desktop.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
BUILD_TYPE: canary
|
||||
APP_NAME: affine
|
||||
COVERAGE: true
|
||||
DISTRIBUTION: desktop
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build-core:
|
||||
name: Build @affine/core
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
- name: Build Core
|
||||
run: yarn nx build @affine/core
|
||||
- name: Upload core artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: core
|
||||
path: ./packages/frontend/core/dist
|
||||
if-no-files-found: error
|
||||
|
||||
build-native:
|
||||
name: Build Native
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-core
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: x86_64-unknown-linux-gnu
|
||||
package: '@affine/native'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- name: Run tests
|
||||
run: yarn test
|
||||
working-directory: ./packages/frontend/native
|
||||
|
||||
desktop-test:
|
||||
name: Desktop Test
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# all combinations: macos-latest x64, macos-latest arm64, windows-latest x64, ubuntu-latest x64
|
||||
matrix:
|
||||
spec:
|
||||
- {
|
||||
os: macos-latest,
|
||||
platform: macos,
|
||||
arch: x64,
|
||||
target: x86_64-apple-darwin,
|
||||
test: true,
|
||||
}
|
||||
- {
|
||||
os: macos-latest,
|
||||
platform: macos,
|
||||
arch: arm64,
|
||||
target: aarch64-apple-darwin,
|
||||
test: false,
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
platform: linux,
|
||||
arch: x64,
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
test: true,
|
||||
}
|
||||
- {
|
||||
os: windows-latest,
|
||||
platform: windows,
|
||||
arch: x64,
|
||||
target: x86_64-pc-windows-msvc,
|
||||
test: true,
|
||||
}
|
||||
needs: build-core
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
extra-flags: workspaces focus @affine/electron @affine/monorepo @affine-test/affine-desktop
|
||||
playwright-install: true
|
||||
hard-link-nm: false
|
||||
enableScripts: false
|
||||
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: ${{ matrix.spec.target }}
|
||||
package: '@affine/native'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
- name: Run unit tests
|
||||
if: ${{ matrix.spec.test }}
|
||||
shell: bash
|
||||
run: yarn vitest
|
||||
working-directory: packages/frontend/electron
|
||||
|
||||
- name: Download core artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: core
|
||||
path: packages/frontend/electron/resources/web-static
|
||||
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os == 'ubuntu-latest' }}
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine-test/affine-desktop e2e
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os != 'ubuntu-latest' }}
|
||||
run: yarn workspace @affine-test/affine-desktop e2e
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
- name: Make bundle
|
||||
if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }}
|
||||
env:
|
||||
SKIP_BUNDLE: true
|
||||
SKIP_WEB_BUILD: true
|
||||
HOIST_NODE_MODULES: 1
|
||||
run: yarn workspace @affine/electron package --platform=darwin --arch=arm64
|
||||
|
||||
- name: Output check
|
||||
if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }}
|
||||
run: |
|
||||
yarn workspace @affine/electron ts-node ./scripts/macos-arm64-output-check.ts
|
||||
|
||||
- name: Collect code coverage report
|
||||
if: ${{ matrix.spec.test }}
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
|
||||
- name: Upload e2e test coverage results
|
||||
if: ${{ matrix.spec.test }}
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/lcov.info
|
||||
flags: e2etest-${{ matrix.spec.os }}-${{ matrix.spec.arch }}
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-${{ matrix.spec.os }}-${{ matrix.spec.arch }}
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
311
.github/workflows/build-server.yml
vendored
311
.github/workflows/build-server.yml
vendored
@@ -1,311 +0,0 @@
|
||||
name: Build(Server) & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- canary
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build-server.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
pull_request:
|
||||
merge_group:
|
||||
branches:
|
||||
- canary
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build-server.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
BUILD_TYPE: canary
|
||||
APP_NAME: affine
|
||||
COVERAGE: true
|
||||
DISTRIBUTION: browser
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build-storage:
|
||||
name: Build Storage
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUSTFLAGS: '-C debuginfo=1'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
extra-flags: workspaces focus @affine/storage
|
||||
electron-install: false
|
||||
build-infra: false
|
||||
build-plugins: false
|
||||
- name: Build Rust
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
package: '@affine/storage'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- name: Upload storage.node
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/backend/storage/storage.node
|
||||
if-no-files-found: error
|
||||
|
||||
server-test:
|
||||
name: Server Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-storage
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
mailer:
|
||||
image: mailhog/mailhog
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
|
||||
- name: Initialize database
|
||||
run: |
|
||||
psql -h localhost -U postgres -c "CREATE DATABASE affine;"
|
||||
psql -h localhost -U postgres -c "CREATE USER affine WITH PASSWORD 'affine';"
|
||||
psql -h localhost -U postgres -c "ALTER USER affine WITH SUPERUSER;"
|
||||
env:
|
||||
PGPASSWORD: affine
|
||||
|
||||
- name: Generate prisma client
|
||||
run: |
|
||||
yarn workspace @affine/server exec prisma generate
|
||||
yarn workspace @affine/server exec prisma db push
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Run init-db script
|
||||
run: yarn workspace @affine/server exec ts-node ./scripts/init-db.ts
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Download storage.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Run server tests
|
||||
run: yarn workspace @affine/server test:coverage
|
||||
env:
|
||||
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Upload server test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
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:
|
||||
name: Server E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-storage
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
mailer:
|
||||
image: mailhog/mailhog
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
|
||||
- name: Initialize database
|
||||
run: |
|
||||
psql -h localhost -U postgres -c "CREATE DATABASE affine;"
|
||||
psql -h localhost -U postgres -c "CREATE USER affine WITH PASSWORD 'affine';"
|
||||
psql -h localhost -U postgres -c "ALTER USER affine WITH SUPERUSER;"
|
||||
env:
|
||||
PGPASSWORD: affine
|
||||
|
||||
- name: Generate prisma client
|
||||
run: |
|
||||
yarn workspace @affine/server exec prisma generate
|
||||
yarn workspace @affine/server exec prisma db push
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Run init-db script
|
||||
run: yarn workspace @affine/server exec ts-node ./scripts/init-db.ts
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Download storage.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Run playwright tests
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine-test/affine-cloud e2e --forbid-only
|
||||
env:
|
||||
COVERAGE: true
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Collect code coverage report
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
|
||||
- name: Upload e2e test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/lcov.info
|
||||
flags: server-e2etest
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-server
|
||||
path: ./tests/affine-cloud/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
server-desktop-e2e-test:
|
||||
name: Server Desktop E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-storage
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
mailer:
|
||||
image: mailhog/mailhog
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
hard-link-nm: false
|
||||
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: x86_64-unknown-linux-gnu
|
||||
package: '@affine/native'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
- name: Initialize database
|
||||
run: |
|
||||
psql -h localhost -U postgres -c "CREATE DATABASE affine;"
|
||||
psql -h localhost -U postgres -c "CREATE USER affine WITH PASSWORD 'affine';"
|
||||
psql -h localhost -U postgres -c "ALTER USER affine WITH SUPERUSER;"
|
||||
env:
|
||||
PGPASSWORD: affine
|
||||
|
||||
- name: Generate prisma client
|
||||
run: |
|
||||
yarn workspace @affine/server exec prisma generate
|
||||
yarn workspace @affine/server prisma db push
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Run init-db script
|
||||
run: yarn workspace @affine/server exec ts-node ./scripts/init-db.ts
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Download storage.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Build Plugins
|
||||
run: yarn run build:plugins
|
||||
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build:dev
|
||||
|
||||
- name: Run playwright tests
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" yarn workspace @affine-test/affine-desktop-cloud e2e
|
||||
env:
|
||||
COVERAGE: true
|
||||
DEV_SERVER_URL: http://localhost:8080
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
ENABLE_LOCAL_EMAIL: true
|
||||
|
||||
- name: Collect code coverage report
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
|
||||
- name: Upload e2e test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/lcov.info
|
||||
flags: server-e2etest
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-server
|
||||
path: ./tests/affine-cloud/test-results
|
||||
if-no-files-found: ignore
|
||||
599
.github/workflows/build-test.yml
vendored
Normal file
599
.github/workflows/build-test.yml
vendored
Normal file
@@ -0,0 +1,599 @@
|
||||
name: Build & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- canary
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
BUILD_TYPE: canary
|
||||
APP_NAME: affine
|
||||
AFFINE_ENV: dev
|
||||
COVERAGE: true
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/node_modules/.cache/ms-playwright
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['javascript', 'typescript']
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run oxlint
|
||||
# oxlint is fast, so wrong code will fail quickly
|
||||
run: yarn dlx $(node -e "console.log(require('./package.json').scripts['lint:ox'])")
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
- name: Run i18n codegen
|
||||
run: yarn i18n-codegen gen
|
||||
- name: Run ESLint
|
||||
run: yarn lint:eslint --max-warnings=0
|
||||
- name: Run Prettier
|
||||
# Set nmMode in `actions/setup-node` will modify the .yarnrc.yml
|
||||
run: |
|
||||
git checkout .yarnrc.yml
|
||||
yarn lint:prettier
|
||||
- name: Run Type Check
|
||||
run: yarn typecheck
|
||||
|
||||
check-yarn-binary:
|
||||
name: Check yarn binary
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run check
|
||||
run: |
|
||||
yarn set version $(node -e "console.log(require('./package.json').packageManager.split('@')[1])")
|
||||
git diff --exit-code
|
||||
|
||||
e2e-plugin-test:
|
||||
name: E2E Plugin Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DISTRIBUTION: browser
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
- name: Run playwright tests
|
||||
run: yarn e2e --forbid-only
|
||||
working-directory: tests/affine-plugin
|
||||
env:
|
||||
COVERAGE: true
|
||||
- name: Collect code coverage report
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
|
||||
- name: Upload e2e test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/lcov.info
|
||||
flags: e2e-plugin-test
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-plugin
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
e2e-test:
|
||||
name: E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DISTRIBUTION: browser
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
- name: Run playwright tests
|
||||
run: yarn workspace @affine-test/affine-local e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-${{ matrix.shard }}
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
e2e-migration-test:
|
||||
name: E2E Migration Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DISTRIBUTION: browser
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
- name: Run playwright tests
|
||||
run: yarn workspace @affine-test/affine-migration e2e --forbid-only
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-migration
|
||||
path: ./tests/affine-migration/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
unit-test:
|
||||
name: Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build-native
|
||||
env:
|
||||
DISTRIBUTION: browser
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
- name: Download affine.linux-x64-gnu.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: affine.linux-x64-gnu.node
|
||||
path: ./packages/frontend/native
|
||||
|
||||
- name: Unit Test
|
||||
run: yarn nx test:coverage @affine/monorepo
|
||||
|
||||
- name: Upload unit test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/store/lcov.info
|
||||
flags: unittest
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
build-native:
|
||||
name: Build AFFiNE native (${{ matrix.spec.target }})
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_DEBUG: '1'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
spec:
|
||||
- { os: ubuntu-latest, target: x86_64-unknown-linux-gnu }
|
||||
- { os: windows-latest, target: x86_64-pc-windows-msvc }
|
||||
- { os: macos-latest, target: x86_64-apple-darwin }
|
||||
- { os: macos-latest, target: aarch64-apple-darwin }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
extra-flags: workspaces focus @affine/native
|
||||
electron-install: false
|
||||
build-infra: false
|
||||
build-plugins: false
|
||||
- name: Setup filename
|
||||
id: filename
|
||||
shell: bash
|
||||
run: |
|
||||
export PLATFORM_ARCH_ABI=$(node -e "console.log(require('@napi-rs/cli').parseTriple('${{ matrix.spec.target }}').platformArchABI)")
|
||||
echo "filename=affine.$PLATFORM_ARCH_ABI.node" >> "$GITHUB_OUTPUT"
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: ${{ matrix.spec.target }}
|
||||
package: '@affine/native'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- name: Upload ${{ steps.filename.outputs.filename }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.filename.outputs.filename }}
|
||||
path: ./packages/frontend/native/${{ steps.filename.outputs.filename }}
|
||||
if-no-files-found: error
|
||||
|
||||
build-storage:
|
||||
name: Build Storage
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_DEBUG: '1'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
extra-flags: workspaces focus @affine/storage
|
||||
electron-install: false
|
||||
build-infra: false
|
||||
build-plugins: false
|
||||
- name: Build Rust
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
package: '@affine/storage'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- name: Upload storage.node
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/backend/storage/storage.node
|
||||
if-no-files-found: error
|
||||
|
||||
build-core:
|
||||
name: Build @affine/core
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
build-plugins: false
|
||||
full-cache: true
|
||||
- name: Build Core
|
||||
# always skip cache because its fast, and cache configuration is always changing
|
||||
run: yarn nx build @affine/core --skip-nx-cache
|
||||
- name: zip core
|
||||
run: tar -czf dist.tar.gz --directory=packages/frontend/core/dist .
|
||||
- name: Upload core artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: core
|
||||
path: dist.tar.gz
|
||||
if-no-files-found: error
|
||||
|
||||
server-test:
|
||||
name: Server Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-storage
|
||||
env:
|
||||
DISTRIBUTION: browser
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
mailer:
|
||||
image: mailhog/mailhog
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
- name: Initialize database
|
||||
run: |
|
||||
psql -h localhost -U postgres -c "CREATE DATABASE affine;"
|
||||
psql -h localhost -U postgres -c "CREATE USER affine WITH PASSWORD 'affine';"
|
||||
psql -h localhost -U postgres -c "ALTER USER affine WITH SUPERUSER;"
|
||||
env:
|
||||
PGPASSWORD: affine
|
||||
|
||||
- name: Generate prisma client
|
||||
run: |
|
||||
yarn workspace @affine/server exec prisma generate
|
||||
yarn workspace @affine/server exec prisma db push
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Run init-db script
|
||||
run: yarn workspace @affine/server exec ts-node ./scripts/init-db.ts
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Download storage.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Run server tests
|
||||
run: yarn workspace @affine/server test:coverage
|
||||
env:
|
||||
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Upload server test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
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:
|
||||
name: ${{ matrix.tests.name }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DISTRIBUTION: browser
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tests:
|
||||
- name: 'Server E2E Test 1/3'
|
||||
script: yarn workspace @affine-test/affine-cloud e2e --forbid-only --shard=1/3
|
||||
- name: 'Server E2E Test 2/3'
|
||||
script: yarn workspace @affine-test/affine-cloud e2e --forbid-only --shard=2/3
|
||||
- name: 'Server E2E Test 3/3'
|
||||
script: yarn workspace @affine-test/affine-cloud e2e --forbid-only --shard=3/3
|
||||
- name: 'Server Desktop E2E Test'
|
||||
script: |
|
||||
yarn workspace @affine/electron build:dev
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine-test/affine-desktop-cloud e2e
|
||||
needs:
|
||||
- build-storage
|
||||
- build-native
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
mailer:
|
||||
image: mailhog/mailhog
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
hard-link-nm: false
|
||||
|
||||
- name: Initialize database
|
||||
run: |
|
||||
psql -h localhost -U postgres -c "CREATE DATABASE affine;"
|
||||
psql -h localhost -U postgres -c "CREATE USER affine WITH PASSWORD 'affine';"
|
||||
psql -h localhost -U postgres -c "ALTER USER affine WITH SUPERUSER;"
|
||||
env:
|
||||
PGPASSWORD: affine
|
||||
|
||||
- name: Generate prisma client
|
||||
run: |
|
||||
yarn workspace @affine/server exec prisma generate
|
||||
yarn workspace @affine/server exec prisma db push
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Run init-db script
|
||||
run: yarn workspace @affine/server exec ts-node ./scripts/init-db.ts
|
||||
- name: Download storage.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/backend/server
|
||||
|
||||
- name: Download affine.linux-x64-gnu.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: affine.linux-x64-gnu.node
|
||||
path: ./packages/frontend/native
|
||||
|
||||
- name: ${{ matrix.tests.name }}
|
||||
run: |
|
||||
${{ matrix.tests.script }}
|
||||
env:
|
||||
DEV_SERVER_URL: http://localhost:8080
|
||||
ENABLE_LOCAL_EMAIL: true
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-server
|
||||
path: ./tests/affine-cloud/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
desktop-test:
|
||||
name: Desktop Test (${{ matrix.spec.os }}, ${{ matrix.spec.platform }}, ${{ matrix.spec.arch }}, ${{ matrix.spec.target }}, ${{ matrix.spec.test }})
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# all combinations: macos-latest x64, macos-latest arm64, windows-latest x64, ubuntu-latest x64
|
||||
matrix:
|
||||
spec:
|
||||
- {
|
||||
os: macos-latest,
|
||||
platform: macos,
|
||||
arch: x64,
|
||||
target: x86_64-apple-darwin,
|
||||
test: true,
|
||||
}
|
||||
- {
|
||||
os: macos-latest,
|
||||
platform: macos,
|
||||
arch: arm64,
|
||||
target: aarch64-apple-darwin,
|
||||
test: false,
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
platform: linux,
|
||||
arch: x64,
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
test: true,
|
||||
}
|
||||
- {
|
||||
os: windows-latest,
|
||||
platform: windows,
|
||||
arch: x64,
|
||||
target: x86_64-pc-windows-msvc,
|
||||
test: true,
|
||||
}
|
||||
needs:
|
||||
- build-core
|
||||
- build-native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
extra-flags: workspaces focus @affine/electron @affine/monorepo @affine-test/affine-desktop
|
||||
playwright-install: true
|
||||
hard-link-nm: false
|
||||
enableScripts: false
|
||||
|
||||
- name: Setup filename
|
||||
id: filename
|
||||
shell: bash
|
||||
run: |
|
||||
export PLATFORM_ARCH_ABI=$(node -e "console.log(require('@napi-rs/cli').parseTriple('${{ matrix.spec.target }}').platformArchABI)")
|
||||
echo "filename=affine.$PLATFORM_ARCH_ABI.node" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Download ${{ steps.filename.outputs.filename }}
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.filename.outputs.filename }}
|
||||
path: ./packages/frontend/native
|
||||
|
||||
- name: Run unit tests
|
||||
if: ${{ matrix.spec.test }}
|
||||
shell: bash
|
||||
run: yarn vitest
|
||||
working-directory: packages/frontend/electron
|
||||
|
||||
- name: Download core artifact
|
||||
uses: ./.github/actions/download-core
|
||||
with:
|
||||
path: packages/frontend/electron/resources/web-static
|
||||
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os == 'ubuntu-latest' }}
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine-test/affine-desktop e2e
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os != 'ubuntu-latest' }}
|
||||
run: yarn workspace @affine-test/affine-desktop e2e
|
||||
|
||||
- name: Make bundle
|
||||
if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }}
|
||||
env:
|
||||
SKIP_BUNDLE: true
|
||||
SKIP_WEB_BUILD: true
|
||||
HOIST_NODE_MODULES: 1
|
||||
run: yarn workspace @affine/electron package --platform=darwin --arch=arm64
|
||||
|
||||
- name: Output check
|
||||
if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }}
|
||||
run: |
|
||||
yarn workspace @affine/electron ts-node ./scripts/macos-arm64-output-check.ts
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-${{ matrix.spec.os }}-${{ matrix.spec.arch }}
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
199
.github/workflows/build.yml
vendored
199
.github/workflows/build.yml
vendored
@@ -1,199 +0,0 @@
|
||||
name: Build & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- canary
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
pull_request:
|
||||
merge_group:
|
||||
branches:
|
||||
- canary
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
BUILD_TYPE: canary
|
||||
APP_NAME: affine
|
||||
AFFINE_ENV: dev
|
||||
COVERAGE: true
|
||||
DISTRIBUTION: browser
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run oxlint
|
||||
# oxlint is fast, so wrong code will fail quickly
|
||||
run: yarn dlx $(node -e "console.log(require('./package.json').scripts['lint:ox'])")
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
- name: Run i18n codegen
|
||||
run: yarn i18n-codegen gen
|
||||
- name: Run ESLint
|
||||
run: yarn lint:eslint --max-warnings=0
|
||||
- name: Run Prettier
|
||||
# Set nmMode in `actions/setup-node` will modify the .yarnrc.yml
|
||||
run: |
|
||||
git checkout .yarnrc.yml
|
||||
yarn lint:prettier
|
||||
- name: Run Type Check
|
||||
run: yarn typecheck
|
||||
|
||||
check-yarn-binary:
|
||||
name: Check yarn binary
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run check
|
||||
run: |
|
||||
yarn set version $(node -e "console.log(require('./package.json').packageManager.split('@')[1])")
|
||||
git diff --exit-code
|
||||
|
||||
e2e-plugin-test:
|
||||
name: E2E Plugin Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
- name: Run playwright tests
|
||||
run: yarn e2e --forbid-only
|
||||
working-directory: tests/affine-plugin
|
||||
env:
|
||||
COVERAGE: true
|
||||
- name: Collect code coverage report
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
|
||||
- name: Upload e2e test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/lcov.info
|
||||
flags: e2e-plugin-test
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-plugin
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
e2e-test:
|
||||
name: E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
|
||||
- name: Run playwright tests
|
||||
run: yarn e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||
working-directory: tests/affine-local
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
- name: Collect code coverage report
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
|
||||
- name: Upload e2e test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/lcov.info
|
||||
flags: e2etest
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-${{ matrix.shard }}
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
e2e-migration-test:
|
||||
name: E2E Migration Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
|
||||
- name: Run playwright tests
|
||||
run: yarn workspace @affine-test/affine-migration e2e --forbid-only
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-migration
|
||||
path: ./tests/affine-migration/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
unit-test:
|
||||
name: Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: x86_64-unknown-linux-gnu
|
||||
package: '@affine/native'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
- name: Unit Test
|
||||
run: yarn nx test:coverage @affine/monorepo
|
||||
|
||||
- name: Upload unit test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/store/lcov.info
|
||||
flags: unittest
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
18
.github/workflows/cancel.yml
vendored
18
.github/workflows/cancel.yml
vendored
@@ -1,18 +0,0 @@
|
||||
name: Cancel
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
cancel:
|
||||
name: 'Cancel Previous Runs'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- uses: styfle/cancel-workflow-action@0.12.0
|
||||
with:
|
||||
# See https://api.github.com/repos/toeverything/AFFiNE/actions/workflows
|
||||
workflow_id: 44038251, 61883931, 65188160, 66789140
|
||||
access_token: ${{ github.token }}
|
||||
70
.github/workflows/codeql.yml
vendored
70
.github/workflows/codeql.yml
vendored
@@ -1,70 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: 'CodeQL'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [canary]
|
||||
pull_request:
|
||||
merge_group:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [canary]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['javascript']
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
35
packages/backend/storage/index.d.ts
vendored
35
packages/backend/storage/index.d.ts
vendored
@@ -1,21 +1,6 @@
|
||||
/* tslint:disable */
|
||||
/* auto-generated by NAPI-RS */
|
||||
/* eslint-disable */
|
||||
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
export function verifyChallengeResponse(response: string, bits: number, resource: string): Promise<boolean>
|
||||
export function mintChallengeResponse(resource: string, bits?: number | undefined | null): Promise<string>
|
||||
export interface Blob {
|
||||
contentType: string
|
||||
lastModified: string
|
||||
size: number
|
||||
data: Buffer
|
||||
}
|
||||
/**
|
||||
* Merge updates in form like `Y.applyUpdate(doc, update)` way and return the
|
||||
* result binary.
|
||||
*/
|
||||
export function mergeUpdatesInApplyWay(updates: Array<Buffer>): Buffer
|
||||
export class Storage {
|
||||
/** Create a storage instance and establish connection to persist store. */
|
||||
static connect(database: string, debugOnlyAutoMigrate?: boolean | undefined | null): Promise<Storage>
|
||||
@@ -30,3 +15,21 @@ export class Storage {
|
||||
/** Workspace size taken by blobs. */
|
||||
blobsSize(workspaces: Array<string>): Promise<number>
|
||||
}
|
||||
|
||||
export interface Blob {
|
||||
contentType: string
|
||||
lastModified: string
|
||||
size: number
|
||||
data: Buffer
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge updates in form like `Y.applyUpdate(doc, update)` way and return the
|
||||
* result binary.
|
||||
*/
|
||||
export function mergeUpdatesInApplyWay(updates: Array<Buffer>): Buffer
|
||||
|
||||
export function mintChallengeResponse(resource: string, bits?: number | undefined | null): Promise<string>
|
||||
|
||||
export function verifyChallengeResponse(response: string, bits: number, resource: string): Promise<boolean>
|
||||
|
||||
|
||||
@@ -16,27 +16,26 @@
|
||||
}
|
||||
},
|
||||
"napi": {
|
||||
"name": "storage",
|
||||
"binaryName": "storage",
|
||||
"targets": [
|
||||
"aarch64-apple-darwin",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
"aarch64-pc-windows-msvc",
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-pc-windows-msvc",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"universal-apple-darwin"
|
||||
"x86_64-unknown-linux-gnu"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node --test ./__tests__/**/*.spec.js",
|
||||
"build": "napi build --release --strip",
|
||||
"build": "napi build --release --strip --no-const-enum",
|
||||
"build:debug": "napi build",
|
||||
"prepublishOnly": "napi prepublish -t npm",
|
||||
"artifacts": "napi artifacts",
|
||||
"version": "napi version"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.16.5",
|
||||
"@napi-rs/cli": "3.0.0-alpha.12",
|
||||
"lib0": "^0.2.87",
|
||||
"nx": "^17.1.3",
|
||||
"nx-cloud": "^16.5.2",
|
||||
|
||||
59
packages/frontend/native/index.d.ts
vendored
59
packages/frontend/native/index.d.ts
vendored
@@ -1,32 +1,6 @@
|
||||
/* tslint:disable */
|
||||
/* auto-generated by NAPI-RS */
|
||||
/* eslint-disable */
|
||||
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
export interface BlobRow {
|
||||
key: string
|
||||
data: Buffer
|
||||
timestamp: Date
|
||||
}
|
||||
export interface UpdateRow {
|
||||
id: number
|
||||
timestamp: Date
|
||||
data: Buffer
|
||||
docId?: string
|
||||
}
|
||||
export interface InsertRow {
|
||||
docId?: string
|
||||
data: Uint8Array
|
||||
}
|
||||
export enum ValidationResult {
|
||||
MissingTables = 0,
|
||||
MissingDocIdColumn = 1,
|
||||
MissingVersionColumn = 2,
|
||||
GeneralError = 3,
|
||||
Valid = 4
|
||||
}
|
||||
export function verifyChallengeResponse(response: string, bits: number, resource: string): Promise<boolean>
|
||||
export function mintChallengeResponse(resource: string, bits?: number | undefined | null): Promise<string>
|
||||
export class SqliteConnection {
|
||||
constructor(path: string)
|
||||
connect(): Promise<void>
|
||||
@@ -47,3 +21,34 @@ export class SqliteConnection {
|
||||
static validate(path: string): Promise<ValidationResult>
|
||||
migrateAddDocId(): Promise<void>
|
||||
}
|
||||
|
||||
export interface BlobRow {
|
||||
key: string
|
||||
data: Buffer
|
||||
timestamp: Date
|
||||
}
|
||||
|
||||
export interface InsertRow {
|
||||
docId?: string
|
||||
data: Uint8Array
|
||||
}
|
||||
|
||||
export function mintChallengeResponse(resource: string, bits?: number | undefined | null): Promise<string>
|
||||
|
||||
export interface UpdateRow {
|
||||
id: number
|
||||
timestamp: Date
|
||||
data: Buffer
|
||||
docId?: string
|
||||
}
|
||||
|
||||
export enum ValidationResult {
|
||||
MissingTables = 0,
|
||||
MissingDocIdColumn = 1,
|
||||
MissingVersionColumn = 2,
|
||||
GeneralError = 3,
|
||||
Valid = 4
|
||||
}
|
||||
|
||||
export function verifyChallengeResponse(response: string, bits: number, resource: string): Promise<boolean>
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* tslint:disable */
|
||||
// prettier-ignore
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
const { existsSync, readFileSync } = require('fs')
|
||||
@@ -13,18 +11,52 @@ let nativeBinding = null
|
||||
let localFileExisted = false
|
||||
let loadError = null
|
||||
|
||||
function isMusl() {
|
||||
// For Node 10
|
||||
if (!process.report || typeof process.report.getReport !== 'function') {
|
||||
try {
|
||||
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
||||
return readFileSync(lddPath, 'utf8').includes('musl')
|
||||
} catch (e) {
|
||||
const isMusl = () => {
|
||||
let musl = false
|
||||
if (process.platform === 'linux') {
|
||||
musl = isMuslFromFilesystem()
|
||||
if (musl === null) {
|
||||
musl = isMuslFromReport()
|
||||
}
|
||||
if (musl === null) {
|
||||
musl = isMuslFromChildProcess()
|
||||
}
|
||||
}
|
||||
return musl
|
||||
}
|
||||
|
||||
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
|
||||
|
||||
const isMuslFromFilesystem = () => {
|
||||
try {
|
||||
return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const isMuslFromReport = () => {
|
||||
const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null
|
||||
if (!report) {
|
||||
return null
|
||||
}
|
||||
if (report.header && report.header.glibcVersionRuntime) {
|
||||
return false
|
||||
}
|
||||
if (Array.isArray(report.sharedObjects)) {
|
||||
if (report.sharedObjects.some(isFileMusl)) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
const { glibcVersionRuntime } = process.report.getReport().header
|
||||
return !glibcVersionRuntime
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const isMuslFromChildProcess = () => {
|
||||
try {
|
||||
return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
|
||||
} catch (e) {
|
||||
// If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,9 +284,7 @@ if (!nativeBinding) {
|
||||
throw new Error(`Failed to load native binding`)
|
||||
}
|
||||
|
||||
const { SqliteConnection, ValidationResult, verifyChallengeResponse, mintChallengeResponse } = nativeBinding
|
||||
|
||||
module.exports.SqliteConnection = SqliteConnection
|
||||
module.exports.ValidationResult = ValidationResult
|
||||
module.exports.verifyChallengeResponse = verifyChallengeResponse
|
||||
module.exports.mintChallengeResponse = mintChallengeResponse
|
||||
module.exports.SqliteConnection = nativeBinding.SqliteConnection
|
||||
module.exports.mintChallengeResponse = nativeBinding.mintChallengeResponse
|
||||
module.exports.ValidationResult = nativeBinding.ValidationResult
|
||||
module.exports.verifyChallengeResponse = nativeBinding.verifyChallengeResponse
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"napi": {
|
||||
"name": "affine",
|
||||
"binaryName": "affine",
|
||||
"triples": {
|
||||
"additional": [
|
||||
"aarch64-apple-darwin",
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.16.5",
|
||||
"@napi-rs/cli": "3.0.0-alpha.12",
|
||||
"@types/node": "^20.9.3",
|
||||
"@types/uuid": "^9.0.7",
|
||||
"ava": "^6.0.0",
|
||||
@@ -53,7 +53,7 @@
|
||||
"scripts": {
|
||||
"artifacts": "napi artifacts",
|
||||
"build": "napi build --platform --release --no-const-enum",
|
||||
"build:debug": "napi build --platform --no-const-enum",
|
||||
"build:debug": "napi build --platform",
|
||||
"universal": "napi universal",
|
||||
"test": "ava",
|
||||
"version": "napi version"
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
import { test } from '@affine-test/kit/playwright';
|
||||
import {
|
||||
createRandomUser,
|
||||
deleteUser,
|
||||
enableCloudWorkspace,
|
||||
getLoginCookie,
|
||||
loginUser,
|
||||
runPrisma,
|
||||
} from '@affine-test/kit/utils/cloud';
|
||||
import { clickEdgelessModeButton } from '@affine-test/kit/utils/editor';
|
||||
import { coreUrl } from '@affine-test/kit/utils/load-page';
|
||||
import {
|
||||
clickNewPageButton,
|
||||
waitForEditorLoad,
|
||||
} from '@affine-test/kit/utils/page-logic';
|
||||
import { clickSideBarSettingButton } from '@affine-test/kit/utils/sidebar';
|
||||
import { createLocalWorkspace } from '@affine-test/kit/utils/workspace';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
let user: {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
test.beforeEach(async () => {
|
||||
user = await createRandomUser();
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page, context }) => {
|
||||
await loginUser(page, user.email, {
|
||||
beforeLogin: async () => {
|
||||
expect(await getLoginCookie(context)).toBeUndefined();
|
||||
},
|
||||
afterLogin: async () => {
|
||||
expect(await getLoginCookie(context)).toBeTruthy();
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
expect(await getLoginCookie(context)).toBeTruthy();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
// if you want to keep the user in the database for debugging,
|
||||
// comment this line
|
||||
await deleteUser(user.email);
|
||||
});
|
||||
|
||||
test.describe('basic', () => {
|
||||
test('migration', async ({ page, browser }) => {
|
||||
let workspaceId: string;
|
||||
{
|
||||
// create the old cloud workspace in another browser
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await loginUser(page, user.email);
|
||||
await page.reload();
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickNewPageButton(page);
|
||||
await waitForEditorLoad(page);
|
||||
// http://localhost:8080/workspace/2bc0b6c8-f68d-4dd3-98a8-be746754f9e1/xxx
|
||||
workspaceId = page.url().split('/')[4];
|
||||
await runPrisma(async client => {
|
||||
const sqls = (
|
||||
await readFile(
|
||||
resolve(__dirname, 'fixtures', '0.9.0-canary.9-snapshots.sql'),
|
||||
'utf-8'
|
||||
)
|
||||
)
|
||||
.replaceAll('2bc0b6c8-f68d-4dd3-98a8-be746754f9e1', workspaceId)
|
||||
.split('\n');
|
||||
await client.snapshot.deleteMany({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
for (const sql of sqls) {
|
||||
await client.$executeRawUnsafe(sql);
|
||||
}
|
||||
});
|
||||
await page.close();
|
||||
}
|
||||
await page.reload();
|
||||
await page.waitForTimeout(1000);
|
||||
await page.goto(`${coreUrl}/workspace/${workspaceId}/all`);
|
||||
await page.getByTestId('upgrade-workspace-button').click();
|
||||
await expect(page.getByText('Refresh Current Page')).toBeVisible({
|
||||
timeout: 60000,
|
||||
});
|
||||
await page.goto(
|
||||
// page 'F1SX6cgNxy' has edgeless mode
|
||||
`${coreUrl}/workspace/${workspaceId}/F1SX6cgNxy`
|
||||
);
|
||||
await page.waitForTimeout(5000);
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await clickEdgelessModeButton(page);
|
||||
await expect(page.locator('affine-edgeless-page')).toBeVisible({
|
||||
timeout: 1000,
|
||||
});
|
||||
});
|
||||
|
||||
test('can see and change email and password in setting panel', async ({
|
||||
page,
|
||||
}) => {
|
||||
const newName = 'test name';
|
||||
{
|
||||
await clickSideBarSettingButton(page);
|
||||
const locator = page.getByTestId('user-info-card');
|
||||
expect(locator.getByText(user.email)).toBeTruthy();
|
||||
expect(locator.getByText(user.name)).toBeTruthy();
|
||||
await locator.click({
|
||||
delay: 50,
|
||||
});
|
||||
const nameInput = page.getByPlaceholder('Input account name');
|
||||
await nameInput.clear();
|
||||
await nameInput.pressSequentially(newName, {
|
||||
delay: 50,
|
||||
});
|
||||
await page.getByTestId('save-user-name').click({
|
||||
delay: 50,
|
||||
});
|
||||
}
|
||||
await page.reload();
|
||||
{
|
||||
await clickSideBarSettingButton(page);
|
||||
const locator = page.getByTestId('user-info-card');
|
||||
expect(locator.getByText(user.email)).toBeTruthy();
|
||||
expect(locator.getByText(newName)).toBeTruthy();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -13,16 +13,8 @@ import {
|
||||
getBlockSuiteEditorTitle,
|
||||
waitForEditorLoad,
|
||||
} from '@affine-test/kit/utils/page-logic';
|
||||
import {
|
||||
clickUserInfoCard,
|
||||
openSettingModal,
|
||||
openWorkspaceSettingPanel,
|
||||
} from '@affine-test/kit/utils/setting';
|
||||
import {
|
||||
clickSideBarAllPageButton,
|
||||
clickSideBarCurrentWorkspaceBanner,
|
||||
clickSideBarSettingButton,
|
||||
} from '@affine-test/kit/utils/sidebar';
|
||||
import { clickUserInfoCard } from '@affine-test/kit/utils/setting';
|
||||
import { clickSideBarSettingButton } from '@affine-test/kit/utils/sidebar';
|
||||
import { createLocalWorkspace } from '@affine-test/kit/utils/workspace';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
@@ -41,298 +33,184 @@ test.beforeEach(async ({ page }) => {
|
||||
await loginUser(page, user.email);
|
||||
});
|
||||
|
||||
test.describe('collaboration', () => {
|
||||
test('can enable share page', async ({ page, browser }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspaceFromShareButton(page);
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.pressSequentially('TEST TITLE', {
|
||||
delay: 50,
|
||||
});
|
||||
await page.keyboard.press('Enter', { delay: 50 });
|
||||
await page.keyboard.type('TEST CONTENT', { delay: 50 });
|
||||
await page.getByTestId('cloud-share-menu-button').click();
|
||||
await page.getByTestId('share-menu-create-link-button').click();
|
||||
await page.getByTestId('share-menu-copy-link-button').click();
|
||||
|
||||
// check share page is accessible
|
||||
test('can enable share page', async ({ page, browser }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const url: string = await page.evaluate(() =>
|
||||
navigator.clipboard.readText()
|
||||
);
|
||||
const page2 = await context.newPage();
|
||||
await page2.goto(url);
|
||||
await waitForEditorLoad(page2);
|
||||
const title = getBlockSuiteEditorTitle(page2);
|
||||
expect(await title.innerText()).toBe('TEST TITLE');
|
||||
expect(await page2.textContent('affine-paragraph')).toContain(
|
||||
'TEST CONTENT'
|
||||
);
|
||||
}
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspaceFromShareButton(page);
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.pressSequentially('TEST TITLE', {
|
||||
delay: 50,
|
||||
});
|
||||
await page.keyboard.press('Enter', { delay: 50 });
|
||||
await page.keyboard.type('TEST CONTENT', { delay: 50 });
|
||||
await page.getByTestId('cloud-share-menu-button').click();
|
||||
await page.getByTestId('share-menu-create-link-button').click();
|
||||
await page.getByTestId('share-menu-copy-link-button').click();
|
||||
|
||||
test('share page with default edgeless', async ({ page, browser }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
// check share page is accessible
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const url: string = await page.evaluate(() =>
|
||||
navigator.clipboard.readText()
|
||||
);
|
||||
await enableCloudWorkspaceFromShareButton(page);
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.pressSequentially('TEST TITLE', {
|
||||
delay: 50,
|
||||
});
|
||||
await page.keyboard.press('Enter', { delay: 50 });
|
||||
await page.keyboard.type('TEST CONTENT', { delay: 50 });
|
||||
await clickEdgelessModeButton(page);
|
||||
const page2 = await context.newPage();
|
||||
await page2.goto(url);
|
||||
await waitForEditorLoad(page2);
|
||||
const title = getBlockSuiteEditorTitle(page2);
|
||||
expect(await title.innerText()).toBe('TEST TITLE');
|
||||
expect(await page2.textContent('affine-paragraph')).toContain(
|
||||
'TEST CONTENT'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('share page with default edgeless', async ({ page, browser }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspaceFromShareButton(page);
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.pressSequentially('TEST TITLE', {
|
||||
delay: 50,
|
||||
});
|
||||
await page.keyboard.press('Enter', { delay: 50 });
|
||||
await page.keyboard.type('TEST CONTENT', { delay: 50 });
|
||||
await clickEdgelessModeButton(page);
|
||||
await expect(page.locator('affine-edgeless-page')).toBeVisible({
|
||||
timeout: 1000,
|
||||
});
|
||||
await page.getByTestId('cloud-share-menu-button').click();
|
||||
await page.getByTestId('share-menu-create-link-button').click();
|
||||
await page.getByTestId('share-menu-copy-link-button').click();
|
||||
|
||||
// check share page is accessible
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const url: string = await page.evaluate(() =>
|
||||
navigator.clipboard.readText()
|
||||
);
|
||||
const page2 = await context.newPage();
|
||||
await page2.goto(url);
|
||||
await waitForEditorLoad(page2);
|
||||
await expect(page.locator('affine-edgeless-page')).toBeVisible({
|
||||
timeout: 1000,
|
||||
});
|
||||
await page.getByTestId('cloud-share-menu-button').click();
|
||||
await page.getByTestId('share-menu-create-link-button').click();
|
||||
await page.getByTestId('share-menu-copy-link-button').click();
|
||||
|
||||
// check share page is accessible
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const url: string = await page.evaluate(() =>
|
||||
navigator.clipboard.readText()
|
||||
);
|
||||
const page2 = await context.newPage();
|
||||
await page2.goto(url);
|
||||
await waitForEditorLoad(page2);
|
||||
await expect(page.locator('affine-edgeless-page')).toBeVisible({
|
||||
timeout: 1000,
|
||||
});
|
||||
expect(await page2.textContent('affine-paragraph')).toContain(
|
||||
'TEST CONTENT'
|
||||
);
|
||||
const logo = page2.getByTestId('share-page-logo');
|
||||
const editButton = page2.getByTestId('share-page-edit-button');
|
||||
await expect(editButton).not.toBeVisible();
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('can collaborate with other user and name should display when editing', async ({
|
||||
page,
|
||||
browser,
|
||||
}) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
expect(await page2.textContent('affine-paragraph')).toContain(
|
||||
'TEST CONTENT'
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickNewPageButton(page);
|
||||
const currentUrl = page.url();
|
||||
// format: http://localhost:8080/workspace/${workspaceId}/xxx
|
||||
const workspaceId = currentUrl.split('/')[4];
|
||||
const userB = await createRandomUser();
|
||||
const logo = page2.getByTestId('share-page-logo');
|
||||
const editButton = page2.getByTestId('share-page-edit-button');
|
||||
await expect(editButton).not.toBeVisible();
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('can collaborate with other user and name should display when editing', async ({
|
||||
page,
|
||||
browser,
|
||||
}) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickNewPageButton(page);
|
||||
const currentUrl = page.url();
|
||||
// format: http://localhost:8080/workspace/${workspaceId}/xxx
|
||||
const workspaceId = currentUrl.split('/')[4];
|
||||
const userB = await createRandomUser();
|
||||
const context = await browser.newContext();
|
||||
const page2 = await context.newPage();
|
||||
await loginUser(page2, userB.email);
|
||||
await addUserToWorkspace(workspaceId, userB.id, 1 /* READ */);
|
||||
await page2.reload();
|
||||
await waitForEditorLoad(page2);
|
||||
await page2.goto(currentUrl);
|
||||
{
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.pressSequentially('TEST TITLE', {
|
||||
delay: 50,
|
||||
});
|
||||
}
|
||||
await page2.waitForTimeout(200);
|
||||
{
|
||||
const title = getBlockSuiteEditorTitle(page2);
|
||||
expect(await title.innerText()).toBe('TEST TITLE');
|
||||
const typingPromise = Promise.all([
|
||||
page.keyboard.press('Enter', { delay: 50 }),
|
||||
page.keyboard.type('TEST CONTENT', { delay: 50 }),
|
||||
]);
|
||||
// username should be visible when editing
|
||||
await expect(page2.getByText(user.name)).toBeVisible();
|
||||
await typingPromise;
|
||||
}
|
||||
|
||||
// change username
|
||||
await clickSideBarSettingButton(page);
|
||||
await clickUserInfoCard(page);
|
||||
const input = page.getByTestId('user-name-input');
|
||||
await input.clear();
|
||||
await input.pressSequentially('TEST USER', {
|
||||
delay: 50,
|
||||
});
|
||||
await page.getByTestId('save-user-name').click({
|
||||
delay: 50,
|
||||
});
|
||||
await page.keyboard.press('Escape', {
|
||||
delay: 50,
|
||||
});
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.focus();
|
||||
|
||||
{
|
||||
await expect(page2.getByText('TEST USER')).toBeVisible({
|
||||
timeout: 2000,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('can sync collections between different browser', async ({
|
||||
page,
|
||||
browser,
|
||||
}) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await page.getByTestId('slider-bar-add-collection-button').click();
|
||||
const title = page.getByTestId('input-collection-title');
|
||||
await title.isVisible();
|
||||
await title.fill('test collection');
|
||||
await page.getByTestId('save-collection').click();
|
||||
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page2 = await context.newPage();
|
||||
await loginUser(page2, userB.email);
|
||||
await addUserToWorkspace(workspaceId, userB.id, 1 /* READ */);
|
||||
await page2.reload();
|
||||
await waitForEditorLoad(page2);
|
||||
await page2.goto(currentUrl);
|
||||
{
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.pressSequentially('TEST TITLE', {
|
||||
delay: 50,
|
||||
});
|
||||
}
|
||||
await page2.waitForTimeout(200);
|
||||
{
|
||||
const title = getBlockSuiteEditorTitle(page2);
|
||||
expect(await title.innerText()).toBe('TEST TITLE');
|
||||
const typingPromise = Promise.all([
|
||||
page.keyboard.press('Enter', { delay: 50 }),
|
||||
page.keyboard.type('TEST CONTENT', { delay: 50 }),
|
||||
]);
|
||||
// username should be visible when editing
|
||||
await expect(page2.getByText(user.name)).toBeVisible();
|
||||
await typingPromise;
|
||||
}
|
||||
|
||||
// change username
|
||||
await clickSideBarSettingButton(page);
|
||||
await clickUserInfoCard(page);
|
||||
const input = page.getByTestId('user-name-input');
|
||||
await input.clear();
|
||||
await input.pressSequentially('TEST USER', {
|
||||
delay: 50,
|
||||
});
|
||||
await page.getByTestId('save-user-name').click({
|
||||
delay: 50,
|
||||
});
|
||||
await page.keyboard.press('Escape', {
|
||||
delay: 50,
|
||||
});
|
||||
const title = getBlockSuiteEditorTitle(page);
|
||||
await title.focus();
|
||||
|
||||
{
|
||||
await expect(page2.getByText('TEST USER')).toBeVisible({
|
||||
timeout: 2000,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('can sync collections between different browser', async ({
|
||||
page,
|
||||
browser,
|
||||
}) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await page.getByTestId('slider-bar-add-collection-button').click();
|
||||
const title = page.getByTestId('input-collection-title');
|
||||
await title.isVisible();
|
||||
await title.fill('test collection');
|
||||
await page.getByTestId('save-collection').click();
|
||||
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page2 = await context.newPage();
|
||||
await loginUser(page2, user.email);
|
||||
await page2.goto(page.url());
|
||||
const collections = page2.getByTestId('collections');
|
||||
await expect(collections.getByText('test collection')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('exit successfully and re-login', async ({ page }) => {
|
||||
await page.reload();
|
||||
await clickSideBarAllPageButton(page);
|
||||
await page.waitForTimeout(200);
|
||||
const url = page.url();
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickSideBarSettingButton(page);
|
||||
await clickUserInfoCard(page);
|
||||
await page.getByTestId('sign-out-button').click();
|
||||
await page.getByTestId('confirm-sign-out-button').click();
|
||||
await page.waitForTimeout(5000);
|
||||
expect(page.url()).toBe(url);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('collaboration members', () => {
|
||||
test('should have pagination in member list', async ({ page }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickNewPageButton(page);
|
||||
const currentUrl = page.url();
|
||||
// format: http://localhost:8080/workspace/${workspaceId}/xxx
|
||||
const workspaceId = currentUrl.split('/')[4];
|
||||
|
||||
// create 10 user and add to workspace
|
||||
const createUserAndAddToWorkspace = async () => {
|
||||
const userB = await createRandomUser();
|
||||
await addUserToWorkspace(workspaceId, userB.id, 1 /* READ */);
|
||||
};
|
||||
await Promise.all(
|
||||
Array.from({ length: 10 })
|
||||
.fill(1)
|
||||
.map(() => createUserAndAddToWorkspace())
|
||||
);
|
||||
|
||||
await openSettingModal(page);
|
||||
await openWorkspaceSettingPanel(page, 'test');
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const firstPageMemberItemCount = await page
|
||||
.locator('[data-testid="member-item"]')
|
||||
.count();
|
||||
|
||||
expect(firstPageMemberItemCount).toBe(8);
|
||||
|
||||
const navigationItems = await page
|
||||
.getByRole('navigation')
|
||||
.getByRole('button')
|
||||
.all();
|
||||
|
||||
// make sure the first member is the owner
|
||||
await expect(page.getByTestId('member-item').first()).toContainText(
|
||||
'Workspace Owner'
|
||||
);
|
||||
|
||||
// There have four pagination items: < 1 2 >
|
||||
expect(navigationItems.length).toBe(4);
|
||||
// Click second page
|
||||
await navigationItems[2].click();
|
||||
await page.waitForTimeout(500);
|
||||
// There should have other three members in second page
|
||||
const secondPageMemberItemCount = await page
|
||||
.locator('[data-testid="member-item"]')
|
||||
.count();
|
||||
expect(secondPageMemberItemCount).toBe(3);
|
||||
// Click left arrow to back to first page
|
||||
await navigationItems[0].click();
|
||||
await page.waitForTimeout(500);
|
||||
expect(await page.locator('[data-testid="member-item"]').count()).toBe(8);
|
||||
// Click right arrow to second page
|
||||
await navigationItems[3].click();
|
||||
await page.waitForTimeout(500);
|
||||
expect(await page.locator('[data-testid="member-item"]').count()).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('sign out', () => {
|
||||
test('can sign out', async ({ page }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await clickSideBarAllPageButton(page);
|
||||
const currentUrl = page.url();
|
||||
await clickSideBarCurrentWorkspaceBanner(page);
|
||||
await page.getByTestId('workspace-modal-account-option').click();
|
||||
await page.getByTestId('workspace-modal-sign-out-option').click();
|
||||
await page.getByTestId('confirm-sign-out-button').click();
|
||||
await clickSideBarCurrentWorkspaceBanner(page);
|
||||
const signInButton = page.getByTestId('cloud-signin-button');
|
||||
await expect(signInButton).toBeVisible();
|
||||
expect(page.url()).toBe(currentUrl);
|
||||
});
|
||||
await loginUser(page2, user.email);
|
||||
await page2.goto(page.url());
|
||||
const collections = page2.getByTestId('collections');
|
||||
await expect(collections.getByText('test collection')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('can sync svg between different browsers', async ({ page, browser }) => {
|
||||
|
||||
@@ -1,17 +1,111 @@
|
||||
import { test } from '@affine-test/kit/playwright';
|
||||
import {
|
||||
createRandomUser,
|
||||
enableCloudWorkspace,
|
||||
loginUser,
|
||||
} from '@affine-test/kit/utils/cloud';
|
||||
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
||||
import { waitForEditorLoad } from '@affine-test/kit/utils/page-logic';
|
||||
import { clickSideBarCurrentWorkspaceBanner } from '@affine-test/kit/utils/sidebar';
|
||||
import { clickUserInfoCard } from '@affine-test/kit/utils/setting';
|
||||
import {
|
||||
clickSideBarAllPageButton,
|
||||
clickSideBarCurrentWorkspaceBanner,
|
||||
clickSideBarSettingButton,
|
||||
} from '@affine-test/kit/utils/sidebar';
|
||||
import { createLocalWorkspace } from '@affine-test/kit/utils/workspace';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
test.describe('login', () => {
|
||||
test('can open login modal in workspace list', async ({ page }) => {
|
||||
await openHomePage(page);
|
||||
test('can open login modal in workspace list', async ({ page }) => {
|
||||
await openHomePage(page);
|
||||
await waitForEditorLoad(page);
|
||||
await clickSideBarCurrentWorkspaceBanner(page);
|
||||
await page.getByTestId('cloud-signin-button').click({
|
||||
delay: 200,
|
||||
});
|
||||
await expect(page.getByTestId('auth-modal')).toBeVisible();
|
||||
});
|
||||
|
||||
test.describe('login first', () => {
|
||||
let user: {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
user = await createRandomUser();
|
||||
await loginUser(page, user.email);
|
||||
});
|
||||
|
||||
test('exit successfully and re-login', async ({ page }) => {
|
||||
await page.reload();
|
||||
await clickSideBarAllPageButton(page);
|
||||
await page.waitForTimeout(200);
|
||||
const url = page.url();
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickSideBarSettingButton(page);
|
||||
await clickUserInfoCard(page);
|
||||
await page.getByTestId('sign-out-button').click();
|
||||
await page.getByTestId('confirm-sign-out-button').click();
|
||||
await page.waitForTimeout(5000);
|
||||
expect(page.url()).toBe(url);
|
||||
});
|
||||
|
||||
test('can sign out', async ({ page }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await clickSideBarAllPageButton(page);
|
||||
const currentUrl = page.url();
|
||||
await clickSideBarCurrentWorkspaceBanner(page);
|
||||
await page.getByTestId('cloud-signin-button').click({
|
||||
delay: 200,
|
||||
});
|
||||
await expect(page.getByTestId('auth-modal')).toBeVisible();
|
||||
await page.getByTestId('workspace-modal-account-option').click();
|
||||
await page.getByTestId('workspace-modal-sign-out-option').click();
|
||||
await page.getByTestId('confirm-sign-out-button').click();
|
||||
await clickSideBarCurrentWorkspaceBanner(page);
|
||||
const signInButton = page.getByTestId('cloud-signin-button');
|
||||
await expect(signInButton).toBeVisible();
|
||||
expect(page.url()).toBe(currentUrl);
|
||||
});
|
||||
|
||||
test('can see and change email and password in setting panel', async ({
|
||||
page,
|
||||
}) => {
|
||||
const newName = 'test name';
|
||||
{
|
||||
await clickSideBarSettingButton(page);
|
||||
const locator = page.getByTestId('user-info-card');
|
||||
expect(locator.getByText(user.email)).toBeTruthy();
|
||||
expect(locator.getByText(user.name)).toBeTruthy();
|
||||
await locator.click({
|
||||
delay: 50,
|
||||
});
|
||||
const nameInput = page.getByPlaceholder('Input account name');
|
||||
await nameInput.clear();
|
||||
await nameInput.pressSequentially(newName, {
|
||||
delay: 50,
|
||||
});
|
||||
await page.getByTestId('save-user-name').click({
|
||||
delay: 50,
|
||||
});
|
||||
}
|
||||
await page.reload();
|
||||
{
|
||||
await clickSideBarSettingButton(page);
|
||||
const locator = page.getByTestId('user-info-card');
|
||||
expect(locator.getByText(user.email)).toBeTruthy();
|
||||
expect(locator.getByText(newName)).toBeTruthy();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
111
tests/affine-cloud/e2e/migration.spec.ts
Normal file
111
tests/affine-cloud/e2e/migration.spec.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
import { test } from '@affine-test/kit/playwright';
|
||||
import {
|
||||
createRandomUser,
|
||||
deleteUser,
|
||||
enableCloudWorkspace,
|
||||
getLoginCookie,
|
||||
loginUser,
|
||||
runPrisma,
|
||||
} from '@affine-test/kit/utils/cloud';
|
||||
import { clickEdgelessModeButton } from '@affine-test/kit/utils/editor';
|
||||
import { coreUrl } from '@affine-test/kit/utils/load-page';
|
||||
import {
|
||||
clickNewPageButton,
|
||||
waitForEditorLoad,
|
||||
} from '@affine-test/kit/utils/page-logic';
|
||||
import { createLocalWorkspace } from '@affine-test/kit/utils/workspace';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
let user: {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
test.beforeEach(async () => {
|
||||
user = await createRandomUser();
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page, context }) => {
|
||||
await loginUser(page, user.email, {
|
||||
beforeLogin: async () => {
|
||||
expect(await getLoginCookie(context)).toBeUndefined();
|
||||
},
|
||||
afterLogin: async () => {
|
||||
expect(await getLoginCookie(context)).toBeTruthy();
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
expect(await getLoginCookie(context)).toBeTruthy();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
// if you want to keep the user in the database for debugging,
|
||||
// comment this line
|
||||
await deleteUser(user.email);
|
||||
});
|
||||
|
||||
test('migration', async ({ page, browser }) => {
|
||||
let workspaceId: string;
|
||||
{
|
||||
// create the old cloud workspace in another browser
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await loginUser(page, user.email);
|
||||
await page.reload();
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickNewPageButton(page);
|
||||
await waitForEditorLoad(page);
|
||||
// http://localhost:8080/workspace/2bc0b6c8-f68d-4dd3-98a8-be746754f9e1/xxx
|
||||
workspaceId = page.url().split('/')[4];
|
||||
await runPrisma(async client => {
|
||||
const sqls = (
|
||||
await readFile(
|
||||
resolve(__dirname, 'fixtures', '0.9.0-canary.9-snapshots.sql'),
|
||||
'utf-8'
|
||||
)
|
||||
)
|
||||
.replaceAll('2bc0b6c8-f68d-4dd3-98a8-be746754f9e1', workspaceId)
|
||||
.split('\n');
|
||||
await client.snapshot.deleteMany({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
for (const sql of sqls) {
|
||||
await client.$executeRawUnsafe(sql);
|
||||
}
|
||||
});
|
||||
await page.close();
|
||||
}
|
||||
await page.reload();
|
||||
await page.waitForTimeout(1000);
|
||||
await page.goto(`${coreUrl}/workspace/${workspaceId}/all`);
|
||||
await page.getByTestId('upgrade-workspace-button').click();
|
||||
await expect(page.getByText('Refresh Current Page')).toBeVisible({
|
||||
timeout: 60000,
|
||||
});
|
||||
await page.goto(
|
||||
// page 'F1SX6cgNxy' has edgeless mode
|
||||
`${coreUrl}/workspace/${workspaceId}/F1SX6cgNxy`
|
||||
);
|
||||
await page.waitForTimeout(5000);
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await clickEdgelessModeButton(page);
|
||||
await expect(page.locator('affine-edgeless-page')).toBeVisible({
|
||||
timeout: 1000,
|
||||
});
|
||||
});
|
||||
96
tests/affine-cloud/e2e/workspace.spec.ts
Normal file
96
tests/affine-cloud/e2e/workspace.spec.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { test } from '@affine-test/kit/playwright';
|
||||
import {
|
||||
addUserToWorkspace,
|
||||
createRandomUser,
|
||||
enableCloudWorkspace,
|
||||
loginUser,
|
||||
} from '@affine-test/kit/utils/cloud';
|
||||
import {
|
||||
clickNewPageButton,
|
||||
waitForEditorLoad,
|
||||
} from '@affine-test/kit/utils/page-logic';
|
||||
import {
|
||||
openSettingModal,
|
||||
openWorkspaceSettingPanel,
|
||||
} from '@affine-test/kit/utils/setting';
|
||||
import { createLocalWorkspace } from '@affine-test/kit/utils/workspace';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
let user: {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
user = await createRandomUser();
|
||||
await loginUser(page, user.email);
|
||||
});
|
||||
|
||||
test('should have pagination in member list', async ({ page }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
await clickNewPageButton(page);
|
||||
const currentUrl = page.url();
|
||||
// format: http://localhost:8080/workspace/${workspaceId}/xxx
|
||||
const workspaceId = currentUrl.split('/')[4];
|
||||
|
||||
// create 10 user and add to workspace
|
||||
const createUserAndAddToWorkspace = async () => {
|
||||
const userB = await createRandomUser();
|
||||
await addUserToWorkspace(workspaceId, userB.id, 1 /* READ */);
|
||||
};
|
||||
await Promise.all(
|
||||
Array.from({ length: 10 })
|
||||
.fill(1)
|
||||
.map(() => createUserAndAddToWorkspace())
|
||||
);
|
||||
|
||||
await openSettingModal(page);
|
||||
await openWorkspaceSettingPanel(page, 'test');
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const firstPageMemberItemCount = await page
|
||||
.locator('[data-testid="member-item"]')
|
||||
.count();
|
||||
|
||||
expect(firstPageMemberItemCount).toBe(8);
|
||||
|
||||
const navigationItems = await page
|
||||
.getByRole('navigation')
|
||||
.getByRole('button')
|
||||
.all();
|
||||
|
||||
// make sure the first member is the owner
|
||||
await expect(page.getByTestId('member-item').first()).toContainText(
|
||||
'Workspace Owner'
|
||||
);
|
||||
|
||||
// There have four pagination items: < 1 2 >
|
||||
expect(navigationItems.length).toBe(4);
|
||||
// Click second page
|
||||
await navigationItems[2].click();
|
||||
await page.waitForTimeout(500);
|
||||
// There should have other three members in second page
|
||||
const secondPageMemberItemCount = await page
|
||||
.locator('[data-testid="member-item"]')
|
||||
.count();
|
||||
expect(secondPageMemberItemCount).toBe(3);
|
||||
// Click left arrow to back to first page
|
||||
await navigationItems[0].click();
|
||||
await page.waitForTimeout(500);
|
||||
expect(await page.locator('[data-testid="member-item"]').count()).toBe(8);
|
||||
// Click right arrow to second page
|
||||
await navigationItems[3].click();
|
||||
await page.waitForTimeout(500);
|
||||
expect(await page.locator('[data-testid="member-item"]').count()).toBe(3);
|
||||
});
|
||||
600
yarn.lock
600
yarn.lock
@@ -656,7 +656,7 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/native@workspace:packages/frontend/native"
|
||||
dependencies:
|
||||
"@napi-rs/cli": "npm:^2.16.5"
|
||||
"@napi-rs/cli": "npm:3.0.0-alpha.12"
|
||||
"@types/node": "npm:^20.9.3"
|
||||
"@types/uuid": "npm:^9.0.7"
|
||||
ava: "npm:^6.0.0"
|
||||
@@ -821,7 +821,7 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/storage@workspace:packages/backend/storage"
|
||||
dependencies:
|
||||
"@napi-rs/cli": "npm:^2.16.5"
|
||||
"@napi-rs/cli": "npm:3.0.0-alpha.12"
|
||||
lib0: "npm:^0.2.87"
|
||||
nx: "npm:^17.1.3"
|
||||
nx-cloud: "npm:^16.5.2"
|
||||
@@ -7175,6 +7175,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@ljharb/through@npm:^2.3.11":
|
||||
version: 2.3.11
|
||||
resolution: "@ljharb/through@npm:2.3.11"
|
||||
dependencies:
|
||||
call-bind: "npm:^1.0.2"
|
||||
checksum: 45bcc0681b89bbaf4c814473f3dcb89ba8c6d259becce36d21aafde8959c2fb0e3e640bd735fa00ac68b13e2947b165225bf56a70609f697b20c91a6982bfbd1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lukeed/csprng@npm:^1.0.0":
|
||||
version: 1.1.0
|
||||
resolution: "@lukeed/csprng@npm:1.1.0"
|
||||
@@ -7394,12 +7403,68 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/cli@npm:^2.16.5":
|
||||
version: 2.16.5
|
||||
resolution: "@napi-rs/cli@npm:2.16.5"
|
||||
"@napi-rs/cli@npm:3.0.0-alpha.12":
|
||||
version: 3.0.0-alpha.12
|
||||
resolution: "@napi-rs/cli@npm:3.0.0-alpha.12"
|
||||
dependencies:
|
||||
"@napi-rs/cross-toolchain": "npm:^0.0.12"
|
||||
"@octokit/rest": "npm:^20.0.2"
|
||||
"@tybys/wasm-util": "npm:0.8.0"
|
||||
clipanion: "npm:^3.2.1"
|
||||
colorette: "npm:^2.0.20"
|
||||
debug: "npm:^4.3.4"
|
||||
emnapi: "npm:0.44.0"
|
||||
inquirer: "npm:^9.2.12"
|
||||
js-yaml: "npm:^4.1.0"
|
||||
lodash-es: "npm:^4.17.21"
|
||||
toml: "npm:^3.0.0"
|
||||
typanion: "npm:^3.14.0"
|
||||
peerDependencies:
|
||||
"@emnapi/runtime": 0.44.0
|
||||
"@tybys/wasm-util": 0.8.0
|
||||
emnapi: 0.44.0
|
||||
peerDependenciesMeta:
|
||||
"@emnapi/runtime":
|
||||
optional: true
|
||||
"@tybys/wasm-util":
|
||||
optional: true
|
||||
emnapi:
|
||||
optional: true
|
||||
bin:
|
||||
napi: scripts/index.js
|
||||
checksum: 37c16d900887970d080e5a3dd5656463d27e5d4c78f3c50d8382af0b4c51752c705e4713c18b46a83ff54a3c58d5d146aabc82ac7b7bbda8134adb7325bb9fa1
|
||||
napi: dist/cli.js
|
||||
napi-raw: cli.mjs
|
||||
checksum: 50911df427f970f6926dc62e083c740b8b342e2181c65a56f4f0758d96995d110b5762fffafc1124628b6192987986b3bba93adf25921eda39c81034cd1dff54
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/cross-toolchain@npm:^0.0.12":
|
||||
version: 0.0.12
|
||||
resolution: "@napi-rs/cross-toolchain@npm:0.0.12"
|
||||
dependencies:
|
||||
"@napi-rs/lzma": "npm:^1.2.1"
|
||||
"@napi-rs/tar": "npm:^0.0.1"
|
||||
debug: "npm:^4.3.4"
|
||||
peerDependencies:
|
||||
"@napi-rs/cross-toolchain-arm64-target-aarch64": ^0.0.12
|
||||
"@napi-rs/cross-toolchain-arm64-target-armv7": ^0.0.12
|
||||
"@napi-rs/cross-toolchain-arm64-target-x86_64": ^0.0.12
|
||||
"@napi-rs/cross-toolchain-x64-target-aarch64": ^0.0.12
|
||||
"@napi-rs/cross-toolchain-x64-target-armv7": ^0.0.12
|
||||
"@napi-rs/cross-toolchain-x64-target-x86_64": ^0.0.12
|
||||
peerDependenciesMeta:
|
||||
"@napi-rs/cross-toolchain-arm64-target-aarch64":
|
||||
optional: true
|
||||
"@napi-rs/cross-toolchain-arm64-target-armv7":
|
||||
optional: true
|
||||
"@napi-rs/cross-toolchain-arm64-target-x86_64":
|
||||
optional: true
|
||||
"@napi-rs/cross-toolchain-x64-target-aarch64":
|
||||
optional: true
|
||||
"@napi-rs/cross-toolchain-x64-target-armv7":
|
||||
optional: true
|
||||
"@napi-rs/cross-toolchain-x64-target-x86_64":
|
||||
optional: true
|
||||
checksum: 7631a0d72f4264ab46b8792519284aa9f8dd6bf922a27dd598c4eec398c83730950454a5f36ceb502fe7c018e89d99f2186ed16416d21e35f6d120c2a6ea48fc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7532,6 +7597,145 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-android-arm-eabi@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-android-arm-eabi@npm:1.2.1"
|
||||
conditions: os=android & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-android-arm64@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-android-arm64@npm:1.2.1"
|
||||
conditions: os=android & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-darwin-arm64@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-darwin-arm64@npm:1.2.1"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-darwin-x64@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-darwin-x64@npm:1.2.1"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-freebsd-x64@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-freebsd-x64@npm:1.2.1"
|
||||
conditions: os=freebsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-linux-arm-gnueabihf@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-linux-arm-gnueabihf@npm:1.2.1"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-linux-arm64-gnu@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-linux-arm64-gnu@npm:1.2.1"
|
||||
conditions: os=linux & cpu=arm64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-linux-arm64-musl@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-linux-arm64-musl@npm:1.2.1"
|
||||
conditions: os=linux & cpu=arm64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-linux-x64-gnu@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-linux-x64-gnu@npm:1.2.1"
|
||||
conditions: os=linux & cpu=x64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-linux-x64-musl@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-linux-x64-musl@npm:1.2.1"
|
||||
conditions: os=linux & cpu=x64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-win32-arm64-msvc@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-win32-arm64-msvc@npm:1.2.1"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-win32-ia32-msvc@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-win32-ia32-msvc@npm:1.2.1"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma-win32-x64-msvc@npm:1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma-win32-x64-msvc@npm:1.2.1"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/lzma@npm:^1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@napi-rs/lzma@npm:1.2.1"
|
||||
dependencies:
|
||||
"@napi-rs/lzma-android-arm-eabi": "npm:1.2.1"
|
||||
"@napi-rs/lzma-android-arm64": "npm:1.2.1"
|
||||
"@napi-rs/lzma-darwin-arm64": "npm:1.2.1"
|
||||
"@napi-rs/lzma-darwin-x64": "npm:1.2.1"
|
||||
"@napi-rs/lzma-freebsd-x64": "npm:1.2.1"
|
||||
"@napi-rs/lzma-linux-arm-gnueabihf": "npm:1.2.1"
|
||||
"@napi-rs/lzma-linux-arm64-gnu": "npm:1.2.1"
|
||||
"@napi-rs/lzma-linux-arm64-musl": "npm:1.2.1"
|
||||
"@napi-rs/lzma-linux-x64-gnu": "npm:1.2.1"
|
||||
"@napi-rs/lzma-linux-x64-musl": "npm:1.2.1"
|
||||
"@napi-rs/lzma-win32-arm64-msvc": "npm:1.2.1"
|
||||
"@napi-rs/lzma-win32-ia32-msvc": "npm:1.2.1"
|
||||
"@napi-rs/lzma-win32-x64-msvc": "npm:1.2.1"
|
||||
dependenciesMeta:
|
||||
"@napi-rs/lzma-android-arm-eabi":
|
||||
optional: true
|
||||
"@napi-rs/lzma-android-arm64":
|
||||
optional: true
|
||||
"@napi-rs/lzma-darwin-arm64":
|
||||
optional: true
|
||||
"@napi-rs/lzma-darwin-x64":
|
||||
optional: true
|
||||
"@napi-rs/lzma-freebsd-x64":
|
||||
optional: true
|
||||
"@napi-rs/lzma-linux-arm-gnueabihf":
|
||||
optional: true
|
||||
"@napi-rs/lzma-linux-arm64-gnu":
|
||||
optional: true
|
||||
"@napi-rs/lzma-linux-arm64-musl":
|
||||
optional: true
|
||||
"@napi-rs/lzma-linux-x64-gnu":
|
||||
optional: true
|
||||
"@napi-rs/lzma-linux-x64-musl":
|
||||
optional: true
|
||||
"@napi-rs/lzma-win32-arm64-msvc":
|
||||
optional: true
|
||||
"@napi-rs/lzma-win32-ia32-msvc":
|
||||
optional: true
|
||||
"@napi-rs/lzma-win32-x64-msvc":
|
||||
optional: true
|
||||
checksum: 5e6d9bee5e359227f7bb3616b3b2a8b064bde0f5aebf4b885df23954cc2f35b1ae44595405733e54826ab9896c02309eac5ff2b340592b698ef2aa135a44288c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/magic-string-android-arm-eabi@npm:0.3.4":
|
||||
version: 0.3.4
|
||||
resolution: "@napi-rs/magic-string-android-arm-eabi@npm:0.3.4"
|
||||
@@ -7671,6 +7875,145 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-android-arm-eabi@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-android-arm-eabi@npm:0.0.1"
|
||||
conditions: os=android & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-android-arm64@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-android-arm64@npm:0.0.1"
|
||||
conditions: os=android & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-darwin-arm64@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-darwin-arm64@npm:0.0.1"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-darwin-x64@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-darwin-x64@npm:0.0.1"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-freebsd-x64@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-freebsd-x64@npm:0.0.1"
|
||||
conditions: os=freebsd & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-linux-arm-gnueabihf@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-linux-arm-gnueabihf@npm:0.0.1"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-linux-arm64-gnu@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-linux-arm64-gnu@npm:0.0.1"
|
||||
conditions: os=linux & cpu=arm64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-linux-arm64-musl@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-linux-arm64-musl@npm:0.0.1"
|
||||
conditions: os=linux & cpu=arm64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-linux-x64-gnu@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-linux-x64-gnu@npm:0.0.1"
|
||||
conditions: os=linux & cpu=x64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-linux-x64-musl@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-linux-x64-musl@npm:0.0.1"
|
||||
conditions: os=linux & cpu=x64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-win32-arm64-msvc@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-win32-arm64-msvc@npm:0.0.1"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-win32-ia32-msvc@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-win32-ia32-msvc@npm:0.0.1"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar-win32-x64-msvc@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar-win32-x64-msvc@npm:0.0.1"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/tar@npm:^0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "@napi-rs/tar@npm:0.0.1"
|
||||
dependencies:
|
||||
"@napi-rs/tar-android-arm-eabi": "npm:0.0.1"
|
||||
"@napi-rs/tar-android-arm64": "npm:0.0.1"
|
||||
"@napi-rs/tar-darwin-arm64": "npm:0.0.1"
|
||||
"@napi-rs/tar-darwin-x64": "npm:0.0.1"
|
||||
"@napi-rs/tar-freebsd-x64": "npm:0.0.1"
|
||||
"@napi-rs/tar-linux-arm-gnueabihf": "npm:0.0.1"
|
||||
"@napi-rs/tar-linux-arm64-gnu": "npm:0.0.1"
|
||||
"@napi-rs/tar-linux-arm64-musl": "npm:0.0.1"
|
||||
"@napi-rs/tar-linux-x64-gnu": "npm:0.0.1"
|
||||
"@napi-rs/tar-linux-x64-musl": "npm:0.0.1"
|
||||
"@napi-rs/tar-win32-arm64-msvc": "npm:0.0.1"
|
||||
"@napi-rs/tar-win32-ia32-msvc": "npm:0.0.1"
|
||||
"@napi-rs/tar-win32-x64-msvc": "npm:0.0.1"
|
||||
dependenciesMeta:
|
||||
"@napi-rs/tar-android-arm-eabi":
|
||||
optional: true
|
||||
"@napi-rs/tar-android-arm64":
|
||||
optional: true
|
||||
"@napi-rs/tar-darwin-arm64":
|
||||
optional: true
|
||||
"@napi-rs/tar-darwin-x64":
|
||||
optional: true
|
||||
"@napi-rs/tar-freebsd-x64":
|
||||
optional: true
|
||||
"@napi-rs/tar-linux-arm-gnueabihf":
|
||||
optional: true
|
||||
"@napi-rs/tar-linux-arm64-gnu":
|
||||
optional: true
|
||||
"@napi-rs/tar-linux-arm64-musl":
|
||||
optional: true
|
||||
"@napi-rs/tar-linux-x64-gnu":
|
||||
optional: true
|
||||
"@napi-rs/tar-linux-x64-musl":
|
||||
optional: true
|
||||
"@napi-rs/tar-win32-arm64-msvc":
|
||||
optional: true
|
||||
"@napi-rs/tar-win32-ia32-msvc":
|
||||
optional: true
|
||||
"@napi-rs/tar-win32-x64-msvc":
|
||||
optional: true
|
||||
checksum: b0a80a08641c05a2fa035cc8e8e642fad0c25e781f292fc541daecedde3921aa96c6ae7785aea733ab6a08983e740dff1b7eefc36546ad939fdaa23e0fab5d70
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/xattr-android-arm-eabi@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@napi-rs/xattr-android-arm-eabi@npm:1.0.1"
|
||||
@@ -8718,6 +9061,131 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/auth-token@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@octokit/auth-token@npm:4.0.0"
|
||||
checksum: 60e42701e341d700f73c518c7a35675d36d79fa9d5e838cc3ade96d147e49f5ba74db2e07b2337c2b95aaa540aa42088116df2122daa25633f9e70a2c8785c44
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/core@npm:^5.0.0":
|
||||
version: 5.0.2
|
||||
resolution: "@octokit/core@npm:5.0.2"
|
||||
dependencies:
|
||||
"@octokit/auth-token": "npm:^4.0.0"
|
||||
"@octokit/graphql": "npm:^7.0.0"
|
||||
"@octokit/request": "npm:^8.0.2"
|
||||
"@octokit/request-error": "npm:^5.0.0"
|
||||
"@octokit/types": "npm:^12.0.0"
|
||||
before-after-hook: "npm:^2.2.0"
|
||||
universal-user-agent: "npm:^6.0.0"
|
||||
checksum: bb991f88793fab043c4c09f9441432596fe0e6448caf42cd2209f52c1f26807418be488ad2cea7a8293e58e79e5c0019f38dda46e8cf96af5e89e43cca37ec3e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/endpoint@npm:^9.0.0":
|
||||
version: 9.0.4
|
||||
resolution: "@octokit/endpoint@npm:9.0.4"
|
||||
dependencies:
|
||||
"@octokit/types": "npm:^12.0.0"
|
||||
universal-user-agent: "npm:^6.0.0"
|
||||
checksum: 7df35c96f2b5628fe5b3f44a72614be9b439779c06b4dd1bb72283b3cb2ea53e59e1f9a108798efe5404b6856f4380a4c5be12d93255d854f0683cd6e22f3a27
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/graphql@npm:^7.0.0":
|
||||
version: 7.0.2
|
||||
resolution: "@octokit/graphql@npm:7.0.2"
|
||||
dependencies:
|
||||
"@octokit/request": "npm:^8.0.1"
|
||||
"@octokit/types": "npm:^12.0.0"
|
||||
universal-user-agent: "npm:^6.0.0"
|
||||
checksum: f5dcc51fed5304f65dab83fcea4c2a569107d3b71e8d084199dc44f0d0cfc852c9e1f341b06ae66601f9da4af3aad416b0c62dcd0567ac7568f072d8d90d502e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/openapi-types@npm:^19.0.2":
|
||||
version: 19.1.0
|
||||
resolution: "@octokit/openapi-types@npm:19.1.0"
|
||||
checksum: 3abedc09baa91bb4de00a2b82bf519401c2b6388913b7caa98541002c9e9612eba8256926323b1e40782ac700309a3373bb8c13520af325cef1accc40cb4566b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/plugin-paginate-rest@npm:^9.0.0":
|
||||
version: 9.1.4
|
||||
resolution: "@octokit/plugin-paginate-rest@npm:9.1.4"
|
||||
dependencies:
|
||||
"@octokit/types": "npm:^12.3.0"
|
||||
peerDependencies:
|
||||
"@octokit/core": ">=5"
|
||||
checksum: 1573934e0c2a99e3512cd21a0dbb17f6ca1d5faffdffb499cb80519b1219da4d56f814a30c68c0961fcccf152895bdced478709195f53a6e4c32e71a3235f888
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/plugin-request-log@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@octokit/plugin-request-log@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@octokit/core": ">=5"
|
||||
checksum: 2a8a6619640942092009a9248ceeb163ce01c978e2d7b2a7eb8686bd09a04b783c4cd9071eebb16652d233587abcde449a02ce4feabc652f0a171615fb3e9946
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@npm:^10.0.0":
|
||||
version: 10.2.0
|
||||
resolution: "@octokit/plugin-rest-endpoint-methods@npm:10.2.0"
|
||||
dependencies:
|
||||
"@octokit/types": "npm:^12.3.0"
|
||||
peerDependencies:
|
||||
"@octokit/core": ">=5"
|
||||
checksum: 0f8ca73b3e582b366b400278f19df6309f263efa3809a9d6ba613063e7a26f16d6f8d69c413bf9b23c2431ad4c795e4e06a43717b6acc1367186fb55347cfb69
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/request-error@npm:^5.0.0":
|
||||
version: 5.0.1
|
||||
resolution: "@octokit/request-error@npm:5.0.1"
|
||||
dependencies:
|
||||
"@octokit/types": "npm:^12.0.0"
|
||||
deprecation: "npm:^2.0.0"
|
||||
once: "npm:^1.4.0"
|
||||
checksum: a21a4614c46cb173e4ba73fa048576204f1ddc541dee3e7c938ef36088566e3b25e04ca1f96f375ec2e3cc29b7ba970b3b078a89a20bc50cdcdbed879db94573
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/request@npm:^8.0.1, @octokit/request@npm:^8.0.2":
|
||||
version: 8.1.6
|
||||
resolution: "@octokit/request@npm:8.1.6"
|
||||
dependencies:
|
||||
"@octokit/endpoint": "npm:^9.0.0"
|
||||
"@octokit/request-error": "npm:^5.0.0"
|
||||
"@octokit/types": "npm:^12.0.0"
|
||||
universal-user-agent: "npm:^6.0.0"
|
||||
checksum: aebea1c33d607d23c70f663cd5f8279a8bd932ab77b4ca5cca3b33968a347b4adb47476c886086f3a9aa1acefab3b79adac78ee7aa2dacd67eb1f2a05e272618
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/rest@npm:^20.0.2":
|
||||
version: 20.0.2
|
||||
resolution: "@octokit/rest@npm:20.0.2"
|
||||
dependencies:
|
||||
"@octokit/core": "npm:^5.0.0"
|
||||
"@octokit/plugin-paginate-rest": "npm:^9.0.0"
|
||||
"@octokit/plugin-request-log": "npm:^4.0.0"
|
||||
"@octokit/plugin-rest-endpoint-methods": "npm:^10.0.0"
|
||||
checksum: 527e1806ca274209a2a7daa485010dafb2ebb6c9b0b44c1d33a8f1f16f10e54a96386a4f642dc416160842a4b367d3953d27f8b827b9a94600709d2ac5e95d21
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/types@npm:^12.0.0, @octokit/types@npm:^12.3.0":
|
||||
version: 12.3.0
|
||||
resolution: "@octokit/types@npm:12.3.0"
|
||||
dependencies:
|
||||
"@octokit/openapi-types": "npm:^19.0.2"
|
||||
checksum: ab78fd25490f995f79e341b00c375bade64eedb44d4c76fa3da85961003ba1efcac3cf168ea221bf4f9f5761afe91738412737acf30f1f41f3f2dbad14b872e4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@open-draft/deferred-promise@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "@open-draft/deferred-promise@npm:2.2.0"
|
||||
@@ -13363,6 +13831,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tybys/wasm-util@npm:0.8.0":
|
||||
version: 0.8.0
|
||||
resolution: "@tybys/wasm-util@npm:0.8.0"
|
||||
dependencies:
|
||||
tslib: "npm:^2.4.0"
|
||||
checksum: 7fa650acfc3fdcaf103f0f7acdf6f4cf67125632eb0f91c92d826375e262547d69de28838cf7a4b69fb665d2fb6f153558528fa1fddd5615a5aa838a87ed7d16
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/accepts@npm:*":
|
||||
version: 1.3.7
|
||||
resolution: "@types/accepts@npm:1.3.7"
|
||||
@@ -15633,7 +16110,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0":
|
||||
"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2":
|
||||
version: 4.3.2
|
||||
resolution: "ansi-escapes@npm:4.3.2"
|
||||
dependencies:
|
||||
@@ -16509,6 +16986,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"before-after-hook@npm:^2.2.0":
|
||||
version: 2.2.3
|
||||
resolution: "before-after-hook@npm:2.2.3"
|
||||
checksum: e676f769dbc4abcf4b3317db2fd2badb4a92c0710e0a7da12cf14b59c3482d4febf835ad7de7874499060fd4e13adf0191628e504728b3c5bb4ec7a878c09940
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"better-opn@npm:^3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "better-opn@npm:3.0.2"
|
||||
@@ -17557,6 +18041,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cli-width@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "cli-width@npm:4.1.0"
|
||||
checksum: b58876fbf0310a8a35c79b72ecfcf579b354e18ad04e6b20588724ea2b522799a758507a37dfe132fafaf93a9922cafd9514d9e1598e6b2cd46694853aed099f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"client-only@npm:^0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "client-only@npm:0.0.1"
|
||||
@@ -17564,7 +18055,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"clipanion@npm:^3.1.0":
|
||||
"clipanion@npm:^3.1.0, clipanion@npm:^3.2.1":
|
||||
version: 3.2.1
|
||||
resolution: "clipanion@npm:3.2.1"
|
||||
dependencies:
|
||||
@@ -18982,6 +19473,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"deprecation@npm:^2.0.0":
|
||||
version: 2.3.1
|
||||
resolution: "deprecation@npm:2.3.1"
|
||||
checksum: f56a05e182c2c195071385455956b0c4106fe14e36245b00c689ceef8e8ab639235176a96977ba7c74afb173317fac2e0ec6ec7a1c6d1e6eaa401c586c714132
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dequal@npm:2.0.3, dequal@npm:^2.0.0, dequal@npm:^2.0.2, dequal@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "dequal@npm:2.0.3"
|
||||
@@ -19615,6 +20113,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"emnapi@npm:0.44.0":
|
||||
version: 0.44.0
|
||||
resolution: "emnapi@npm:0.44.0"
|
||||
peerDependencies:
|
||||
node-addon-api: ">= 6.1.0"
|
||||
peerDependenciesMeta:
|
||||
node-addon-api:
|
||||
optional: true
|
||||
checksum: c0177b08bbca8c815e5b15c544d431cd270975bc5831bad03691eba271de5ad7cff78be431ae1b5e3816a622951a9ed525b83a1a3707b9f9c70ecc8aece7344d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"emoji-regex@npm:^10.3.0":
|
||||
version: 10.3.0
|
||||
resolution: "emoji-regex@npm:10.3.0"
|
||||
@@ -20759,7 +21269,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"external-editor@npm:^3.0.3":
|
||||
"external-editor@npm:^3.0.3, external-editor@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "external-editor@npm:3.1.0"
|
||||
dependencies:
|
||||
@@ -21037,6 +21547,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"figures@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "figures@npm:5.0.0"
|
||||
dependencies:
|
||||
escape-string-regexp: "npm:^5.0.0"
|
||||
is-unicode-supported: "npm:^1.2.0"
|
||||
checksum: 951d18be2f450c90462c484eff9bda705293319bc2f17b250194a0cf1a291600db4cb283a6ce199d49380c95b08d85d822ce4b18d2f9242663fd5895476d667c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"figures@npm:^6.0.1":
|
||||
version: 6.0.1
|
||||
resolution: "figures@npm:6.0.1"
|
||||
@@ -23365,6 +23885,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"inquirer@npm:^9.2.12":
|
||||
version: 9.2.12
|
||||
resolution: "inquirer@npm:9.2.12"
|
||||
dependencies:
|
||||
"@ljharb/through": "npm:^2.3.11"
|
||||
ansi-escapes: "npm:^4.3.2"
|
||||
chalk: "npm:^5.3.0"
|
||||
cli-cursor: "npm:^3.1.0"
|
||||
cli-width: "npm:^4.1.0"
|
||||
external-editor: "npm:^3.1.0"
|
||||
figures: "npm:^5.0.0"
|
||||
lodash: "npm:^4.17.21"
|
||||
mute-stream: "npm:1.0.0"
|
||||
ora: "npm:^5.4.1"
|
||||
run-async: "npm:^3.0.0"
|
||||
rxjs: "npm:^7.8.1"
|
||||
string-width: "npm:^4.2.3"
|
||||
strip-ansi: "npm:^6.0.1"
|
||||
wrap-ansi: "npm:^6.2.0"
|
||||
checksum: 02b259c641fd6c6b88c0c530aced23389d586bd5360799bab0ae11d2a965ac5ce9c587402faefad70f08b8b56ccae56fb973da3a8deb6e17ba4577f803d427c5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"interpret@npm:^3.1.1":
|
||||
version: 3.1.1
|
||||
resolution: "interpret@npm:3.1.1"
|
||||
@@ -23850,6 +24393,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-unicode-supported@npm:^1.2.0":
|
||||
version: 1.3.0
|
||||
resolution: "is-unicode-supported@npm:1.3.0"
|
||||
checksum: 20a1fc161afafaf49243551a5ac33b6c4cf0bbcce369fcd8f2951fbdd000c30698ce320de3ee6830497310a8f41880f8066d440aa3eb0a853e2aa4836dd89abc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-upper-case@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "is-upper-case@npm:2.0.2"
|
||||
@@ -28125,6 +28675,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mute-stream@npm:1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "mute-stream@npm:1.0.0"
|
||||
checksum: 36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nanoid@npm:^3.3.3, nanoid@npm:^3.3.6":
|
||||
version: 3.3.7
|
||||
resolution: "nanoid@npm:3.3.7"
|
||||
@@ -32114,6 +32671,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"run-async@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "run-async@npm:3.0.0"
|
||||
checksum: 97fb8747f7765b77ebcd311d3a33548099336f04c6434e0763039b98c1de0f1b4421000695aff8751f309c0b995d8dfd620c1f1e4c35572da38c101488165305
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"run-parallel@npm:^1.1.9":
|
||||
version: 1.2.0
|
||||
resolution: "run-parallel@npm:1.2.0"
|
||||
@@ -34133,6 +34697,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"toml@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "toml@npm:3.0.0"
|
||||
checksum: cfef0966868d552bd02e741f30945a611f70841b7cddb07ea2b17441fe32543985bc0a7c0dcf7971af26fcaf8a17712a485d911f46bfe28644536e9a71a2bd09
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"totalist@npm:^3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "totalist@npm:3.0.1"
|
||||
@@ -34316,7 +34887,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typanion@npm:^3.8.0":
|
||||
"typanion@npm:^3.14.0, typanion@npm:^3.8.0":
|
||||
version: 3.14.0
|
||||
resolution: "typanion@npm:3.14.0"
|
||||
checksum: 5e88d9e6121ff0ec543f572152fdd1b70e9cca35406d79013ec8e08defa8ef96de5fec9e98da3afbd1eb4426b9e8e8fe423163d0b482e34a40103cab1ef29abd
|
||||
@@ -34772,6 +35343,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"universal-user-agent@npm:^6.0.0":
|
||||
version: 6.0.1
|
||||
resolution: "universal-user-agent@npm:6.0.1"
|
||||
checksum: fdc8e1ae48a05decfc7ded09b62071f571c7fe0bd793d700704c80cea316101d4eac15cc27ed2bb64f4ce166d2684777c3198b9ab16034f547abea0d3aa1c93c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"universalify@npm:^0.1.0":
|
||||
version: 0.1.2
|
||||
resolution: "universalify@npm:0.1.2"
|
||||
|
||||
Reference in New Issue
Block a user