Compare commits

..

66 Commits

Author SHA1 Message Date
Peng Xiao
a709624ebf feat(core): page preview ui optimize (#5442)
![CleanShot 2023-12-28 at 23.42.44@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/16b66e74-4b0d-48a5-9062-c86c94f6b065.png)
fix TOV-92

No animations right now.
2024-01-03 03:30:43 +00:00
Peng Xiao
6cb62ed25d feat: bump blocksuite (#5453)
Change history: https://github.com/toeverything/blocksuite/compare/e3abcbb...master
2024-01-03 02:10:19 +00:00
Peng Xiao
8dc3e3d65c fix(core): add free plan prompt (#5441)
fix TOV-91

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/e209abd9-8831-46a4-a00e-fe4bef627d2f.png)
2024-01-03 01:50:32 +00:00
Peng Xiao
444de6d4ac fix(core): adjust error boundary level (#5493)
Allowing showing page title for page detail when page throws error.

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/398bef13-c52d-40b4-bf53-5157582d030a.png)
2024-01-02 22:48:19 +08:00
Peng Xiao
922bc11f16 test(core): fix selectMonthFromMonthPicker logic (#5498) 2024-01-02 14:21:14 +00:00
LongYinan
53c76ae2e2 chore: bump up vitest version to v1.1.1 (#5495)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [vitest](https://togithub.com/vitest-dev/vitest) ([source](https://togithub.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | [`1.1.0` -> `1.1.1`](https://renovatebot.com/diffs/npm/vitest/1.1.0/1.1.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vitest/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vitest/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>vitest-dev/vitest (vitest)</summary>

### [`v1.1.1`](https://togithub.com/vitest-dev/vitest/releases/tag/v1.1.1)

[Compare Source](https://togithub.com/vitest-dev/vitest/compare/v1.1.0...v1.1.1)

#####    🐞 Bug Fixes

-   Don't crash when using happy-dom or jsdom environment on Yarn PnP workspaces  -  by [@&#8203;wojtekmaj](https://togithub.com/wojtekmaj) and [@&#8203;sheremet-va](https://togithub.com/sheremet-va) in [https://github.com/vitest-dev/vitest/issues/4698](https://togithub.com/vitest-dev/vitest/issues/4698) [<samp>(ee8b4)</samp>](https://togithub.com/vitest-dev/vitest/commit/ee8b46db)
-   Don't fail if `inline: true` is set  -  by [@&#8203;sheremet-va](https://togithub.com/sheremet-va) in [https://github.com/vitest-dev/vitest/issues/4815](https://togithub.com/vitest-dev/vitest/issues/4815) [<samp>(8f622)</samp>](https://togithub.com/vitest-dev/vitest/commit/8f6225b8)
-   Correct option name `--no-parallelism`  -  by [@&#8203;bonyuta0204](https://togithub.com/bonyuta0204) in [https://github.com/vitest-dev/vitest/issues/4831](https://togithub.com/vitest-dev/vitest/issues/4831) [<samp>(5053a)</samp>](https://togithub.com/vitest-dev/vitest/commit/5053a5dd)
-   Match jest json output by making json reporter output ndjson-compatible  -  by [@&#8203;bard](https://togithub.com/bard) in [https://github.com/vitest-dev/vitest/issues/4824](https://togithub.com/vitest-dev/vitest/issues/4824) [<samp>(7e6a6)</samp>](https://togithub.com/vitest-dev/vitest/commit/7e6a62af)
-   **runner**:
    -   Reset "current test" state on dynamic `skip`  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4814](https://togithub.com/vitest-dev/vitest/issues/4814) [<samp>(19faf)</samp>](https://togithub.com/vitest-dev/vitest/commit/19faf00e)
-   **vitest**:
    -   Don't hang when mocking files with cyclic dependencies  -  by [@&#8203;sheremet-va](https://togithub.com/sheremet-va) in [https://github.com/vitest-dev/vitest/issues/4811](https://togithub.com/vitest-dev/vitest/issues/4811) [<samp>(e8ca6)</samp>](https://togithub.com/vitest-dev/vitest/commit/e8ca6437)
    -   Initialize snapshot state only once for each file suite  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4796](https://togithub.com/vitest-dev/vitest/issues/4796) [<samp>(957da)</samp>](https://togithub.com/vitest-dev/vitest/commit/957daa32)
    -   Fix file snapshots in skipped suites considered obsolete  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4795](https://togithub.com/vitest-dev/vitest/issues/4795) [<samp>(06c14)</samp>](https://togithub.com/vitest-dev/vitest/commit/06c14f7d)
    -   Show `beforeAll/afterAll` errors in junit reporter  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4819](https://togithub.com/vitest-dev/vitest/issues/4819) [<samp>(2baea)</samp>](https://togithub.com/vitest-dev/vitest/commit/2baea35e)
-   **vm-threads**:
    -   Tests not cancelled on key press, cancelled tests shown twice  -  by [@&#8203;AriPerkkio](https://togithub.com/AriPerkkio) in [https://github.com/vitest-dev/vitest/issues/4781](https://togithub.com/vitest-dev/vitest/issues/4781) [<samp>(cf53d)</samp>](https://togithub.com/vitest-dev/vitest/commit/cf53d4be)

#####     [View changes on GitHub](https://togithub.com/vitest-dev/vitest/compare/v1.1.0...v1.1.1)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5In0=-->
2024-01-02 13:46:17 +00:00
EYHN
4aae3cbba3 docs: initial api reference docs (#5352) 2024-01-02 12:46:27 +00:00
DarkSky
44eb7b97f4 chore: bump vulnerable deps (#5494) 2024-01-02 12:32:47 +00:00
EYHN
54c6b445ea fix(workspace): make ci stable (#5496) 2024-01-02 12:21:35 +00:00
EYHN
104c21d84c refactor(workspace): split workspace interface and implementation (#5463)
@affine/workspace -> (@affine/workspace, @affine/workspace-impl)
2024-01-02 10:58:01 +00:00
EYHN
9d0b3b4947 refactor(core): move workspace atoms to core (#5459)
@affine/workspace/atom -> @affine/core/modules/workspace
2024-01-02 10:06:48 +00:00
EYHN
4b217e6b89 refactor(core): move hooks to core (#5458)
* move @toeverything/hooks -> @affine/core/hooks
* delete @toeverything/hooks

hooks are all business-related logic and are deeply coupled with other parts.

Move them into the core and then reconstruct them by feature.
2024-01-02 08:05:46 +00:00
LongYinan
6862b7deaf chore: bump up @napi-rs/cli version to v3.0.0-alpha.29 (#5492)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@napi-rs/cli](https://togithub.com/napi-rs/napi-rs) | [`3.0.0-alpha.28` -> `3.0.0-alpha.29`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.0.0-alpha.28/3.0.0-alpha.29) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@napi-rs%2fcli/3.0.0-alpha.29?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@napi-rs%2fcli/3.0.0-alpha.29?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@napi-rs%2fcli/3.0.0-alpha.28/3.0.0-alpha.29?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@napi-rs%2fcli/3.0.0-alpha.28/3.0.0-alpha.29?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>napi-rs/napi-rs (@&#8203;napi-rs/cli)</summary>

### [`v3.0.0-alpha.29`](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.28...@napi-rs/cli@3.0.0-alpha.29)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.28...@napi-rs/cli@3.0.0-alpha.29)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5In0=-->
2024-01-02 07:39:44 +00:00
EYHN
6844b282ac refactor(component): adjust active editor atom (#5457)
before:

set global `blocksuiteEditorAtom` state in `<BlocksuiteEditorImpl />`

after:

Rename `blocksuiteEditorAtom` to `activeBlocksuiteEditorAtom`

And move the logic of setting this atom to `<PageDetailEditor />`.

benefit:

* make BlocksuiteEditor pure
* keep @toeverything/component clear
* Clarify the purpose of `activeBlocksuiteEditorAtom`
2024-01-02 07:30:09 +00:00
liuyi
1eefd712dd feat(server): new storage provider (#5410) 2024-01-02 07:21:01 +00:00
liuyi
abcca8b09e refactor(server): object storages (#5405) 2024-01-02 07:01:25 +00:00
Peng Xiao
b84494ef86 feat(core): optimize history list item ui (#5440)
![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/fa1b3626-4c07-411a-ae15-680b1ad70522.png)

fix TOV-90
2024-01-02 05:46:56 +00:00
LongYinan
b92f2cb29a chore: bump up all non-major dependencies (#5488)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@aws-sdk/client-s3](https://togithub.com/aws/aws-sdk-js-v3/tree/main/clients/client-s3) ([source](https://togithub.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)) | [`3.481.0` -> `3.484.0`](https://renovatebot.com/diffs/npm/@aws-sdk%2fclient-s3/3.481.0/3.484.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@aws-sdk%2fclient-s3/3.484.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@aws-sdk%2fclient-s3/3.484.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@aws-sdk%2fclient-s3/3.481.0/3.484.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@aws-sdk%2fclient-s3/3.481.0/3.484.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@napi-rs/cli](https://togithub.com/napi-rs/napi-rs) | [`3.0.0-alpha.25` -> `3.0.0-alpha.28`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.0.0-alpha.25/3.0.0-alpha.28) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@napi-rs%2fcli/3.0.0-alpha.28?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@napi-rs%2fcli/3.0.0-alpha.28?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@napi-rs%2fcli/3.0.0-alpha.25/3.0.0-alpha.28?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@napi-rs%2fcli/3.0.0-alpha.25/3.0.0-alpha.28?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@vitest/coverage-istanbul](https://togithub.com/vitest-dev/vitest/tree/main/packages/coverage-istanbul#readme) ([source](https://togithub.com/vitest-dev/vitest/tree/HEAD/packages/coverage-istanbul)) | [`1.1.0` -> `1.1.1`](https://renovatebot.com/diffs/npm/@vitest%2fcoverage-istanbul/1.1.0/1.1.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitest%2fcoverage-istanbul/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitest%2fcoverage-istanbul/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitest%2fcoverage-istanbul/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitest%2fcoverage-istanbul/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@vitest/ui](https://togithub.com/vitest-dev/vitest/tree/main/packages/ui#readme) ([source](https://togithub.com/vitest-dev/vitest/tree/HEAD/packages/ui)) | [`1.1.0` -> `1.1.1`](https://renovatebot.com/diffs/npm/@vitest%2fui/1.1.0/1.1.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitest%2fui/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitest%2fui/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitest%2fui/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitest%2fui/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [fake-indexeddb](https://togithub.com/dumbmatter/fakeIndexedDB) | [`5.0.1` -> `5.0.2`](https://renovatebot.com/diffs/npm/fake-indexeddb/5.0.1/5.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/fake-indexeddb/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/fake-indexeddb/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/fake-indexeddb/5.0.1/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/fake-indexeddb/5.0.1/5.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [vitest](https://togithub.com/vitest-dev/vitest) ([source](https://togithub.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | [`1.1.0` -> `1.1.1`](https://renovatebot.com/diffs/npm/vitest/1.1.0/1.1.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vitest/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vitest/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/1.1.0/1.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>aws/aws-sdk-js-v3 (@&#8203;aws-sdk/client-s3)</summary>

### [`v3.484.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34840-2023-12-29)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.481.0...v3.484.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

</details>

<details>
<summary>napi-rs/napi-rs (@&#8203;napi-rs/cli)</summary>

### [`v3.0.0-alpha.28`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.28)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.27...@napi-rs/cli@3.0.0-alpha.28)

##### What's Changed

-   fix(cli): copy binding files into wasi packages by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1881](https://togithub.com/napi-rs/napi-rs/pull/1881)

**Full Changelog**: https://github.com/napi-rs/napi-rs/compare/[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.27...[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.28

### [`v3.0.0-alpha.27`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.27)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.25...@napi-rs/cli@3.0.0-alpha.27)

##### What's Changed

-   fix(deps): update dependency emnapi to v0.45.0 by [@&#8203;renovate](https://togithub.com/renovate) in [https://github.com/napi-rs/napi-rs/pull/1879](https://togithub.com/napi-rs/napi-rs/pull/1879)

**Full Changelog**: https://github.com/napi-rs/napi-rs/compare/[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.26...[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.27

</details>

<details>
<summary>vitest-dev/vitest (@&#8203;vitest/coverage-istanbul)</summary>

### [`v1.1.1`](https://togithub.com/vitest-dev/vitest/releases/tag/v1.1.1)

[Compare Source](https://togithub.com/vitest-dev/vitest/compare/v1.1.0...v1.1.1)

#####    🐞 Bug Fixes

-   Don't crash when using happy-dom or jsdom environment on Yarn PnP workspaces  -  by [@&#8203;wojtekmaj](https://togithub.com/wojtekmaj) and [@&#8203;sheremet-va](https://togithub.com/sheremet-va) in [https://github.com/vitest-dev/vitest/issues/4698](https://togithub.com/vitest-dev/vitest/issues/4698) [<samp>(ee8b4)</samp>](https://togithub.com/vitest-dev/vitest/commit/ee8b46db)
-   Don't fail if `inline: true` is set  -  by [@&#8203;sheremet-va](https://togithub.com/sheremet-va) in [https://github.com/vitest-dev/vitest/issues/4815](https://togithub.com/vitest-dev/vitest/issues/4815) [<samp>(8f622)</samp>](https://togithub.com/vitest-dev/vitest/commit/8f6225b8)
-   Correct option name `--no-parallelism`  -  by [@&#8203;bonyuta0204](https://togithub.com/bonyuta0204) in [https://github.com/vitest-dev/vitest/issues/4831](https://togithub.com/vitest-dev/vitest/issues/4831) [<samp>(5053a)</samp>](https://togithub.com/vitest-dev/vitest/commit/5053a5dd)
-   Match jest json output by making json reporter output ndjson-compatible  -  by [@&#8203;bard](https://togithub.com/bard) in [https://github.com/vitest-dev/vitest/issues/4824](https://togithub.com/vitest-dev/vitest/issues/4824) [<samp>(7e6a6)</samp>](https://togithub.com/vitest-dev/vitest/commit/7e6a62af)
-   **runner**:
    -   Reset "current test" state on dynamic `skip`  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4814](https://togithub.com/vitest-dev/vitest/issues/4814) [<samp>(19faf)</samp>](https://togithub.com/vitest-dev/vitest/commit/19faf00e)
-   **vitest**:
    -   Don't hang when mocking files with cyclic dependencies  -  by [@&#8203;sheremet-va](https://togithub.com/sheremet-va) in [https://github.com/vitest-dev/vitest/issues/4811](https://togithub.com/vitest-dev/vitest/issues/4811) [<samp>(e8ca6)</samp>](https://togithub.com/vitest-dev/vitest/commit/e8ca6437)
    -   Initialize snapshot state only once for each file suite  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4796](https://togithub.com/vitest-dev/vitest/issues/4796) [<samp>(957da)</samp>](https://togithub.com/vitest-dev/vitest/commit/957daa32)
    -   Fix file snapshots in skipped suites considered obsolete  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4795](https://togithub.com/vitest-dev/vitest/issues/4795) [<samp>(06c14)</samp>](https://togithub.com/vitest-dev/vitest/commit/06c14f7d)
    -   Show `beforeAll/afterAll` errors in junit reporter  -  by [@&#8203;hi-ogawa](https://togithub.com/hi-ogawa) in [https://github.com/vitest-dev/vitest/issues/4819](https://togithub.com/vitest-dev/vitest/issues/4819) [<samp>(2baea)</samp>](https://togithub.com/vitest-dev/vitest/commit/2baea35e)
-   **vm-threads**:
    -   Tests not cancelled on key press, cancelled tests shown twice  -  by [@&#8203;AriPerkkio](https://togithub.com/AriPerkkio) in [https://github.com/vitest-dev/vitest/issues/4781](https://togithub.com/vitest-dev/vitest/issues/4781) [<samp>(cf53d)</samp>](https://togithub.com/vitest-dev/vitest/commit/cf53d4be)

#####     [View changes on GitHub](https://togithub.com/vitest-dev/vitest/compare/v1.1.0...v1.1.1)

</details>

<details>
<summary>dumbmatter/fakeIndexedDB (fake-indexeddb)</summary>

### [`v5.0.2`](https://togithub.com/dumbmatter/fakeIndexedDB/blob/HEAD/CHANGELOG.md#502-2023-12-30)

[Compare Source](https://togithub.com/dumbmatter/fakeIndexedDB/compare/v5.0.1...v5.0.2)

-   [#&#8203;94](https://togithub.com/dumbmatter/fakeIndexedDB/issues/94) - Improved performance of `IDBObjectStore.count` and `IDBIndex.count`.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5In0=-->
2024-01-02 04:51:44 +00:00
LongYinan
986860070b fix: renovate preserveSemverRanges rule should not be in group 2024-01-02 12:19:55 +08:00
LongYinan
ae3afccdb2 fix: renovate config 2024-01-02 12:13:37 +08:00
LongYinan
b0d90c26d3 ci: fix invalid renovate config (#5470)
- Close https://github.com/toeverything/AFFiNE/issues/5469
2024-01-02 03:37:22 +00:00
Peng Xiao
da5ac224ca test(core): select monthpicker issue when crossing different years (#5478) 2024-01-02 03:28:38 +00:00
LongYinan
10aeefe36d ci: prevent @blocksuite/* packages upgraded without group (#5467) 2023-12-29 10:23:56 +00:00
LongYinan
8eda42c57f chore: remove abbey-wood helm chart (#5464) 2023-12-29 17:51:23 +08:00
Joooye_34
d668016e4c feat(electron): use release api to filter draft release (#5443) 2023-12-29 09:01:35 +00:00
Joooye_34
3341295fc1 ci: temporarily save release from branch to affine-releases (#5455) 2023-12-29 17:00:10 +08:00
Peng Xiao
9e092b9c15 fix(core): long page title issue in page history (#5436)
![CleanShot 2023-12-28 at 18.17.50@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/43733a5b-d1b4-40d5-b9d4-f86896cc0598.png)
2023-12-29 07:27:02 +00:00
Peng Xiao
f65c5dbfa7 fix(core): upgrade page when previewing/reverting page snapshot (#5435) 2023-12-29 07:26:58 +00:00
DarkSky
3082d63948 fix: use absolute path in gql client (#5454) 2023-12-29 06:48:04 +00:00
Joooye_34
5a1065c646 test(electron): add unit tests for updater (#5439) 2023-12-29 04:39:29 +00:00
LongYinan
15566d8507 chore: bump up @nx/vite version to v17.2.8 (#5425)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@nx/vite](https://nx.dev) ([source](https://togithub.com/nrwl/nx/tree/HEAD/packages/vite)) | [`17.2.7` -> `17.2.8`](https://renovatebot.com/diffs/npm/@nx%2fvite/17.2.7/17.2.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@nx%2fvite/17.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nx%2fvite/17.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nx%2fvite/17.2.7/17.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nx%2fvite/17.2.7/17.2.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>nrwl/nx (@&#8203;nx/vite)</summary>

### [`v17.2.8`](https://togithub.com/nrwl/nx/releases/tag/17.2.8)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.7...17.2.8)

#### 17.2.8

##### 🚀 Features

-   **remix:** add remix

##### 🩹 Fixes

-   **linter:** flat config should always set path to config when using API
-   **nextjs:** update migration to handle projects without eslintrc

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5In0=-->
2023-12-29 04:10:19 +00:00
Peng Xiao
3978b2dfd2 refactor(core): onboarding using new transformer api (#5412)
Use new `transformer` to import onboarding json templates.

The json files are generated via this gist
https://gist.github.com/pengx17/ef92c305ac23123803a1a6a20e31f822

Not using the all-in-one `ZipTransformer` to import onboarding via a zip file.
1. The main concerns is that we still need to serve the blob resources via CDN to reduce user's blob usage. Otherwise the user will get the onboarding images being uploaded to cloud server every time he creates a new workspace. In this PR we extracted parts of the code from `ZipTransformer` in blocksuite and mute some code for uploading blobs.
2. it maybe not necessary to use zip for loading snapshots.

This PR is a short term solution. whether or not to tune the transformer api design may need further discussions.

fix TOV-264
2023-12-28 13:59:21 +00:00
JimmFly
954b751e7c chore: adjust side bar empty item color (#5422) 2023-12-28 13:49:14 +00:00
DarkSky
b3dbac3d4c feat: add migration for rename unamed accounts (#5434)
fix TOV-130
2023-12-28 12:20:00 +00:00
Peng Xiao
6fefe4ec71 fix(storybook): storybook flaky (#5430)
should add additional wait timeout for every story.play

I think this is a storybook issue. It seems that it starts to run the plays as soon as the following shows up:

![CleanShot 2023-12-28 at 17.32.49@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/33d5e49d-a2fd-46c5-9f31-0f7cc14c3acf.png)
2023-12-28 10:07:05 +00:00
EYHN
9d51f9596f refactor(component): make component pure (#5427) 2023-12-28 09:57:26 +00:00
JimmFly
e11e8277ca feat: add useBlocksuiteEditor hooks (#5366) 2023-12-28 08:36:36 +00:00
LongYinan
431f7cfac9 ci: exclude blocksuite from auto update group (#5424) 2023-12-28 08:22:20 +00:00
LongYinan
2f45200542 feat(server): upgrade prisma to use native relation joins and distinct (#5420)
https://github.com/prisma/prisma/releases/tag/5.7.0
2023-12-28 08:09:11 +00:00
LongYinan
07c63703b1 chore: bump up all non-major dependencies (#5187)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence | Type | Update |
|---|---|---|---|---|---|---|---|
| [@aws-sdk/client-s3](https://togithub.com/aws/aws-sdk-js-v3/tree/main/clients/client-s3) ([source](https://togithub.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)) | [`3.433.0` -> `3.481.0`](https://renovatebot.com/diffs/npm/@aws-sdk%2fclient-s3/3.433.0/3.481.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@aws-sdk%2fclient-s3/3.481.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@aws-sdk%2fclient-s3/3.481.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@aws-sdk%2fclient-s3/3.433.0/3.481.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@aws-sdk%2fclient-s3/3.433.0/3.481.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@blocksuite/block-std](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@blocksuite/block-std](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fblock-std/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@blocksuite/blocks](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fblocks/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fblocks/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fblocks/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fblocks/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fblocks/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@blocksuite/blocks](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fblocks/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fblocks/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fblocks/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fblocks/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fblocks/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@blocksuite/global](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fglobal/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fglobal/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fglobal/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fglobal/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fglobal/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@blocksuite/global](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fglobal/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fglobal/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fglobal/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fglobal/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fglobal/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@blocksuite/icons](https://togithub.com/toeverything/icons) | [`2.1.36` -> `2.1.39`](https://renovatebot.com/diffs/npm/@blocksuite%2ficons/2.1.36/2.1.39) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2ficons/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2ficons/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2ficons/2.1.36/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2ficons/2.1.36/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@blocksuite/icons](https://togithub.com/toeverything/icons) | [`2.1.36` -> `2.1.39`](https://renovatebot.com/diffs/npm/@blocksuite%2ficons/2.1.36/2.1.39) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2ficons/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2ficons/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2ficons/2.1.36/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2ficons/2.1.36/2.1.39?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@blocksuite/inline](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2finline/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2finline/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2finline/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2finline/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2finline/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@blocksuite/lit](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2flit/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2flit/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2flit/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2flit/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2flit/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@blocksuite/lit](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2flit/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2flit/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2flit/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2flit/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2flit/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@blocksuite/presets](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fpresets/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fpresets/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fpresets/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fpresets/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fpresets/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@blocksuite/presets](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fpresets/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fpresets/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fpresets/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fpresets/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fpresets/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@blocksuite/store](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fstore/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fstore/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fstore/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fstore/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fstore/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@blocksuite/store](https://togithub.com/toeverything/blocksuite) | [`0.11.0-nightly-202312220916-e3abcbb` -> `0.11.0-nightly-202312270831-214616d`](https://renovatebot.com/diffs/npm/@blocksuite%2fstore/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2fstore/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2fstore/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2fstore/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2fstore/0.11.0-nightly-202312220916-e3abcbb/0.11.0-nightly-202312270831-214616d?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@electron/remote](https://togithub.com/electron/remote) | [`2.1.0` -> `2.1.1`](https://renovatebot.com/diffs/npm/@electron%2fremote/2.1.0/2.1.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron%2fremote/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron%2fremote/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron%2fremote/2.1.0/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron%2fremote/2.1.0/2.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@marsidev/react-turnstile](https://togithub.com/marsidev/react-turnstile) | [`^0.3.1` -> `^0.4.0`](https://renovatebot.com/diffs/npm/@marsidev%2freact-turnstile/0.3.2/0.4.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@marsidev%2freact-turnstile/0.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@marsidev%2freact-turnstile/0.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@marsidev%2freact-turnstile/0.3.2/0.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@marsidev%2freact-turnstile/0.3.2/0.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [@napi-rs/cli](https://togithub.com/napi-rs/napi-rs) | [`3.0.0-alpha.15` -> `3.0.0-alpha.25`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.0.0-alpha.15/3.0.0-alpha.25) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@napi-rs%2fcli/3.0.0-alpha.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@napi-rs%2fcli/3.0.0-alpha.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@napi-rs%2fcli/3.0.0-alpha.15/3.0.0-alpha.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@napi-rs%2fcli/3.0.0-alpha.15/3.0.0-alpha.25?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@nx/vite](https://nx.dev) ([source](https://togithub.com/nrwl/nx/tree/HEAD/packages/vite)) | [`17.1.3` -> `17.2.7`](https://renovatebot.com/diffs/npm/@nx%2fvite/17.1.3/17.2.7) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@nx%2fvite/17.2.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nx%2fvite/17.2.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nx%2fvite/17.1.3/17.2.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nx%2fvite/17.1.3/17.2.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@storybook/test-runner](https://togithub.com/storybookjs/test-runner) | [`^0.15.2` -> `^0.16.0`](https://renovatebot.com/diffs/npm/@storybook%2ftest-runner/0.15.2/0.16.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2ftest-runner/0.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2ftest-runner/0.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2ftest-runner/0.15.2/0.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2ftest-runner/0.15.2/0.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@vitest/coverage-istanbul](https://togithub.com/vitest-dev/vitest/tree/main/packages/coverage-istanbul#readme) ([source](https://togithub.com/vitest-dev/vitest/tree/HEAD/packages/coverage-istanbul)) | [`1.0.4` -> `1.1.0`](https://renovatebot.com/diffs/npm/@vitest%2fcoverage-istanbul/1.0.4/1.1.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitest%2fcoverage-istanbul/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitest%2fcoverage-istanbul/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitest%2fcoverage-istanbul/1.0.4/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitest%2fcoverage-istanbul/1.0.4/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@vitest/ui](https://togithub.com/vitest-dev/vitest/tree/main/packages/ui#readme) ([source](https://togithub.com/vitest-dev/vitest/tree/HEAD/packages/ui)) | [`1.0.4` -> `1.1.0`](https://renovatebot.com/diffs/npm/@vitest%2fui/1.0.4/1.1.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitest%2fui/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitest%2fui/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitest%2fui/1.0.4/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitest%2fui/1.0.4/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [cloudflare/wrangler-action](https://togithub.com/cloudflare/wrangler-action) | `v3.3.2` -> `v3.4.0` | [![age](https://developer.mend.io/api/mc/badges/age/github-tags/cloudflare%2fwrangler-action/v3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/github-tags/cloudflare%2fwrangler-action/v3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/github-tags/cloudflare%2fwrangler-action/v3.3.2/v3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/cloudflare%2fwrangler-action/v3.3.2/v3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | action | minor |
| openresty/openresty | `1.21.4.1-0-buster` -> `1.21.4.3-0-buster` | [![age](https://developer.mend.io/api/mc/badges/age/docker/openresty%2fopenresty/1.21.4.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/docker/openresty%2fopenresty/1.21.4.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/docker/openresty%2fopenresty/1.21.4.1/1.21.4.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/docker/openresty%2fopenresty/1.21.4.1/1.21.4.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | final | patch |
| [postgresql](https://bitnami.com) ([source](https://togithub.com/bitnami/charts/tree/HEAD/bitnami/postgresql)) | `13.2.23` -> `13.2.26` | [![age](https://developer.mend.io/api/mc/badges/age/helm/postgresql/13.2.26?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/helm/postgresql/13.2.26?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/helm/postgresql/13.2.23/13.2.26?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/helm/postgresql/13.2.23/13.2.26?slim=true)](https://docs.renovatebot.com/merge-confidence/) |  | patch |
| [reflect-metadata](http://rbuckton.github.io/reflect-metadata) ([source](https://togithub.com/rbuckton/reflect-metadata)) | [`^0.1.13` -> `^0.2.0`](https://renovatebot.com/diffs/npm/reflect-metadata/0.1.13/0.2.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/reflect-metadata/0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/reflect-metadata/0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/reflect-metadata/0.1.13/0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/reflect-metadata/0.1.13/0.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [vite-plugin-dts](https://togithub.com/qmhc/vite-plugin-dts) | [`3.6.0` -> `3.7.0`](https://renovatebot.com/diffs/npm/vite-plugin-dts/3.6.0/3.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/vite-plugin-dts/3.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vite-plugin-dts/3.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vite-plugin-dts/3.6.0/3.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vite-plugin-dts/3.6.0/3.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [vitest](https://togithub.com/vitest-dev/vitest) ([source](https://togithub.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | [`1.0.4` -> `1.1.0`](https://renovatebot.com/diffs/npm/vitest/1.0.4/1.1.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vitest/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vitest/1.0.4/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/1.0.4/1.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |

---

### Release Notes

<details>
<summary>aws/aws-sdk-js-v3 (@&#8203;aws-sdk/client-s3)</summary>

### [`v3.481.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34810-2023-12-26)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.478.0...v3.481.0)

##### Features

-   codegen for command class builder ([#&#8203;5604](https://togithub.com/aws/aws-sdk-js-v3/issues/5604)) ([4835de4](4835de4ebb))

### [`v3.478.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34780-2023-12-20)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.477.0...v3.478.0)

##### Features

-   codegen for paginator factory ([#&#8203;5590](https://togithub.com/aws/aws-sdk-js-v3/issues/5590)) ([e54099b](e54099b7c1))

### [`v3.477.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34770-2023-12-19)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.476.0...v3.477.0)

##### Features

-   xml codegen reduction ([#&#8203;5566](https://togithub.com/aws/aws-sdk-js-v3/issues/5566)) ([3ed7c81](3ed7c81f91))

### [`v3.476.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34760-2023-12-18)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.474.0...v3.476.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.474.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34740-2023-12-14)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.473.0...v3.474.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.473.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34730-2023-12-13)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.472.0...v3.473.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.472.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34720-2023-12-12)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.470.0...v3.472.0)

##### Bug Fixes

-   **codegen:** dedupe `[@aws](https://togithub.com/aws).protocols#restXml` serialization ([#&#8203;5568](https://togithub.com/aws/aws-sdk-js-v3/issues/5568)) ([7df7325](7df73259b6))

### [`v3.470.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34700-2023-12-08)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.468.0...v3.470.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.468.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34680-2023-12-06)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.465.0...v3.468.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.465.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34650-2023-12-01)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.462.0...v3.465.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.462.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34620-2023-11-29)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.461.0...v3.462.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.461.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34610-2023-11-28)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.460.0...v3.461.0)

##### Features

-   **client-s3:** Adds support for S3 Express One Zone. ([1dcc776](1dcc776322))

### [`v3.460.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34600-2023-11-28)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.458.0...v3.460.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.458.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34580-2023-11-27)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.456.0...v3.458.0)

##### Features

-   **client-s3:** Adding new params - Key and Prefix, to S3 API operations for supporting S3 Access Grants. Note - These updates will not change any of the existing S3 API functionality. ([ba36517](ba365170a0))

### [`v3.456.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34560-2023-11-21)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.454.0...v3.456.0)

##### Features

-   **client-s3:** Add support for automatic date based partitioning in S3 Server Access Logs. ([06ee66a](06ee66ae3b))

### [`v3.454.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34540-2023-11-17)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.451.0...v3.454.0)

##### Features

-   **client-s3:** Removes all default 0 values for numbers and false values for booleans ([61b32fe](61b32fe67a))

### [`v3.451.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34510-2023-11-14)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.450.0...v3.451.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.450.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34500-2023-11-13)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.449.0...v3.450.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.449.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34490-2023-11-10)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.445.0...v3.449.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.445.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34450-2023-11-07)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.441.0...v3.445.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.441.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34410-2023-11-01)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.440.0...v3.441.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.440.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34400-2023-10-31)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.438.0...v3.440.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.438.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34380-2023-10-27)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.437.0...v3.438.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.437.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34370-2023-10-26)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.436.0...v3.437.0)

##### Bug Fixes

-   **signature-v4-crt:** remove dynamic imports (!) ([#&#8203;5225](https://togithub.com/aws/aws-sdk-js-v3/issues/5225)) ([89f97b5](89f97b5cea))

### [`v3.436.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34360-2023-10-25)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.435.0...v3.436.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

### [`v3.435.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#34350-2023-10-24)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.433.0...v3.435.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

</details>

<details>
<summary>toeverything/icons (@&#8203;blocksuite/icons)</summary>

### [`v2.1.39`](83cf4ea106...e255947e4e)

[Compare Source](83cf4ea106...e255947e4e)

### [`v2.1.38`](1c26e8f533...83cf4ea106)

[Compare Source](1c26e8f533...83cf4ea106)

### [`v2.1.37`](310adb0b9f...1c26e8f533)

[Compare Source](310adb0b9f...1c26e8f533)

</details>

<details>
<summary>electron/remote (@&#8203;electron/remote)</summary>

### [`v2.1.1`](https://togithub.com/electron/remote/releases/tag/v2.1.1)

[Compare Source](https://togithub.com/electron/remote/compare/v2.1.0...v2.1.1)

##### Bug Fixes

-   senderId removed in Electron 28 ([#&#8203;171](https://togithub.com/electron/remote/issues/171)) ([51ff1b4](51ff1b432f))

</details>

<details>
<summary>marsidev/react-turnstile (@&#8203;marsidev/react-turnstile)</summary>

### [`v0.4.0`](https://togithub.com/marsidev/react-turnstile/releases/tag/v0.4.0)

[Compare Source](https://togithub.com/marsidev/react-turnstile/compare/v0.3.2...v0.4.0)

#####    🚀 Features

-   Add `crossOrigin` to `scriptOptions`  -  by [@&#8203;kaichii](https://togithub.com/kaichii) [<samp>(a588b)</samp>](https://togithub.com/marsidev/react-turnstile/commit/a588b72)
-   Add `onLoadScript` callback  -  by [@&#8203;marsidev](https://togithub.com/marsidev) [<samp>(4e5bc)</samp>](https://togithub.com/marsidev/react-turnstile/commit/4e5bcc3)
-   Add support for `isExpired()` method  -  by [@&#8203;marsidev](https://togithub.com/marsidev) [<samp>(7daca)</samp>](https://togithub.com/marsidev/react-turnstile/commit/7daca97)

#####     [View changes on GitHub](https://togithub.com/marsidev/react-turnstile/compare/v0.3.2...v0.4.0)

</details>

<details>
<summary>napi-rs/napi-rs (@&#8203;napi-rs/cli)</summary>

### [`v3.0.0-alpha.25`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.25)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.24...@napi-rs/cli@3.0.0-alpha.25)

##### What's Changed

-   fix(cli): compatible with napi artifacts -d option by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1872](https://togithub.com/napi-rs/napi-rs/pull/1872)

**Full Changelog**: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.14.6...[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.25

### [`v3.0.0-alpha.24`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.24)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.23...@napi-rs/cli@3.0.0-alpha.24)

##### What's Changed

-   fix(cli): prepublish tagstyle flag by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1863](https://togithub.com/napi-rs/napi-rs/pull/1863)
-   chore(cli): root directory access permissions by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1864](https://togithub.com/napi-rs/napi-rs/pull/1864)
-   feat(cli): support wasi target test & release workflow by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1867](https://togithub.com/napi-rs/napi-rs/pull/1867)

**Full Changelog**: https://github.com/napi-rs/napi-rs/compare/[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.20...[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.24

### [`v3.0.0-alpha.23`](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.22...@napi-rs/cli@3.0.0-alpha.23)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.22...@napi-rs/cli@3.0.0-alpha.23)

### [`v3.0.0-alpha.22`](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.21...@napi-rs/cli@3.0.0-alpha.22)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.21...@napi-rs/cli@3.0.0-alpha.22)

### [`v3.0.0-alpha.21`](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.20...@napi-rs/cli@3.0.0-alpha.21)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.20...@napi-rs/cli@3.0.0-alpha.21)

### [`v3.0.0-alpha.20`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.20)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.19...@napi-rs/cli@3.0.0-alpha.20)

#### What's Changed

-   chore(deps): update actions/download-artifact action to v4 by [@&#8203;renovate](https://togithub.com/renovate) in [https://github.com/napi-rs/napi-rs/pull/1856](https://togithub.com/napi-rs/napi-rs/pull/1856)
-   fix(cli): make prepublish as pre-publish alias by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1861](https://togithub.com/napi-rs/napi-rs/pull/1861)

**Full Changelog**: https://github.com/napi-rs/napi-rs/compare/[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.19...[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.20

### [`v3.0.0-alpha.19`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.19)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.18...@napi-rs/cli@3.0.0-alpha.19)

##### What's Changed

-   fix(cli): artifacts default option value by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1853](https://togithub.com/napi-rs/napi-rs/pull/1853)
-   fix: more accurate napi expanding error by [@&#8203;forehalo](https://togithub.com/forehalo) in [https://github.com/napi-rs/napi-rs/pull/1854](https://togithub.com/napi-rs/napi-rs/pull/1854)
-   feat(cli): support read config from the given config file by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1859](https://togithub.com/napi-rs/napi-rs/pull/1859)
-   fix(cli): prepublish command by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1860](https://togithub.com/napi-rs/napi-rs/pull/1860)

**Full Changelog**: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.14.4...[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.19

### [`v3.0.0-alpha.18`](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.17...@napi-rs/cli@3.0.0-alpha.18)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.17...@napi-rs/cli@3.0.0-alpha.18)

### [`v3.0.0-alpha.17`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.17)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.16...@napi-rs/cli@3.0.0-alpha.17)

##### What's Changed

-   fix(cli): make outputDir option of artifacts command compatible with v2 by [@&#8203;Brooooooklyn](https://togithub.com/Brooooooklyn) in [https://github.com/napi-rs/napi-rs/pull/1850](https://togithub.com/napi-rs/napi-rs/pull/1850)
-   fix(binding): add riscv64 linux binding by [@&#8203;kxxt](https://togithub.com/kxxt) in [https://github.com/napi-rs/napi-rs/pull/1851](https://togithub.com/napi-rs/napi-rs/pull/1851)

**Full Changelog**: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.14.3...[@&#8203;napi-rs/cli](https://togithub.com/napi-rs/cli)[@&#8203;3](https://togithub.com/3).0.0-alpha.17

### [`v3.0.0-alpha.16`](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.15...@napi-rs/cli@3.0.0-alpha.16)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.15...@napi-rs/cli@3.0.0-alpha.16)

</details>

<details>
<summary>nrwl/nx (@&#8203;nx/vite)</summary>

### [`v17.2.7`](https://togithub.com/nrwl/nx/releases/tag/17.2.7)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.6...17.2.7)

##### 17.2.7

##### 🩹 Fixes

-   **angular:** fix standalone eslint config generation
-   **bundling:** added back code to handle skipTypeField option of rollup executor options + tests
-   **linter:** ensure angular entry point checks are correct
-   **nextjs:** enhance page generator to work when --project is not supplied
-   **nextjs:** remove temporary patch for next eslint rules
-   **nextjs:** correct inferred outputs for root Next.js projects
-   **node:** E2E test port conflicts
-   **release:** add overall nx release command
-   **release:** publish error handling, dry-run in dependsOn
-   **release:** capture all release titles during parse
-   **testing:** run playwright with the correct project option for multiple values
-   **testing:** safely handle circular deps in component testing plugin
-   **testing:** set correct type for ignoreTestFiles option in cypress executor
-   **vite:** vitest migration add reporters
-   **vite:** more properly resolve arguments from configurations
-   **vite:** dist and coverage paths for root projects

### [`v17.2.6`](https://togithub.com/nrwl/nx/releases/tag/17.2.6)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.5...17.2.6)

##### 17.2.6

##### 🚀 Features

-   **release:** support Revert commits in changelog renderer ([#&#8203;20663](https://togithub.com/nrwl/nx/pull/20663))

##### 🩹 Fixes

-   **js:** fixing output based on test runner selection ([#&#8203;20788](https://togithub.com/nrwl/nx/pull/20788))
-   **linter:** fix workspace-rule naming with flat config ([#&#8203;20782](https://togithub.com/nrwl/nx/pull/20782))
-   **module-federation:** support buildable libs ([#&#8203;20786](https://togithub.com/nrwl/nx/pull/20786))
-   **nextjs:** Page generator should work out of the box ([#&#8203;20775](https://togithub.com/nrwl/nx/pull/20775))
-   **nx-dev:** dynamic classes not allowed ([#&#8203;20800](https://togithub.com/nrwl/nx/pull/20800))
-   **release:** changelog renderer should prefer breaking change explanation text ([#&#8203;20798](https://togithub.com/nrwl/nx/pull/20798))
-   **release:** ensure leading v is stripped from provided semver version ([#&#8203;20815](https://togithub.com/nrwl/nx/pull/20815))
-   **vite:** only dynamically import vite ([#&#8203;20774](https://togithub.com/nrwl/nx/pull/20774))

##### ❤️  Thank You

-   Colum Ferry [@&#8203;Coly010](https://togithub.com/Coly010)
-   Isaac Mann [@&#8203;isaacplmann](https://togithub.com/isaacplmann)
-   James Henry [@&#8203;JamesHenry](https://togithub.com/JamesHenry)
-   Katerina Skroumpelou [@&#8203;mandarini](https://togithub.com/mandarini)
-   Miroslav Jonaš [@&#8203;meeroslav](https://togithub.com/meeroslav)
-   Nicholas Cunningham [@&#8203;ndcunningham](https://togithub.com/ndcunningham)

### [`v17.2.5`](https://togithub.com/nrwl/nx/releases/tag/17.2.5)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.4...17.2.5)

#### 17.2.5

##### 🩹 Fixes

-   **angular:** safely update task runner cacheable operations when setting up ssr ([#&#8203;20736](https://togithub.com/nrwl/nx/pull/20736))
-   **core:** fallback to checking stderr if stdout is empty on publish executor ([#&#8203;20737](https://togithub.com/nrwl/nx/pull/20737))
-   **core:** correctly move project and target strings ([#&#8203;20726](https://togithub.com/nrwl/nx/pull/20726))
-   **linter:** move should migrate all eslint configs ([#&#8203;20709](https://togithub.com/nrwl/nx/pull/20709))
-   **misc:** disallow path segments and allow scoped package name in --newProjectName option of move generator ([#&#8203;20768](https://togithub.com/nrwl/nx/pull/20768))
-   **module-federation:** allow relative remote paths ([#&#8203;20763](https://togithub.com/nrwl/nx/pull/20763))
-   **nextjs:** empty port should not overwrite env port ([#&#8203;20751](https://togithub.com/nrwl/nx/pull/20751))
-   **nextjs:** Add missing setParserOptionProject ([#&#8203;20754](https://togithub.com/nrwl/nx/pull/20754))
-   **react:** remove <base> tag from generated index.html ([#&#8203;20750](https://togithub.com/nrwl/nx/pull/20750))
-   **react:** update default webpack config for component testing ([#&#8203;20749](https://togithub.com/nrwl/nx/pull/20749))
-   **storybook:** do not throw for versions >=7 ([#&#8203;20770](https://togithub.com/nrwl/nx/pull/20770))
-   **testing:** avoid overwriting environment variables in nx cypress preset ([#&#8203;20748](https://togithub.com/nrwl/nx/pull/20748))
-   **vite:** allow vitest to be v1 ([#&#8203;20760](https://togithub.com/nrwl/nx/pull/20760))

##### ❤️  Thank You

-   Colum Ferry [@&#8203;Coly010](https://togithub.com/Coly010)
-   Craigory Coppola [@&#8203;AgentEnder](https://togithub.com/AgentEnder)
-   Jack Hsu [@&#8203;jaysoo](https://togithub.com/jaysoo)
-   Katerina Skroumpelou [@&#8203;mandarini](https://togithub.com/mandarini)
-   Leosvel Pérez Espinosa [@&#8203;leosvelperez](https://togithub.com/leosvelperez)
-   Miroslav Jonaš [@&#8203;meeroslav](https://togithub.com/meeroslav)
-   Nicholas Cunningham [@&#8203;ndcunningham](https://togithub.com/ndcunningham)

### [`v17.2.4`](https://togithub.com/nrwl/nx/releases/tag/17.2.4)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.3...17.2.4)

#### 17.2.4

##### 🩹 Fixes

-   **webpack:** fix check for standardWebpackConfigFunction ([#&#8203;20728](https://togithub.com/nrwl/nx/pull/20728))

##### ❤️  Thank You

-   Jack Hsu [@&#8203;jaysoo](https://togithub.com/jaysoo)

### [`v17.2.3`](https://togithub.com/nrwl/nx/releases/tag/17.2.3)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.2...17.2.3)

#### 17.2.3

##### 🩹 Fixes

-   **react:** skip adding comma to config when adding remote to host if… ([#&#8203;20620](https://togithub.com/nrwl/nx/pull/20620))

##### ❤️  Thank You

-   Tórur Zachariasen [@&#8203;torurz](https://togithub.com/torurz)

### [`v17.2.2`](https://togithub.com/nrwl/nx/releases/tag/17.2.2)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.1...17.2.2)

#### 17.2.2

##### 🩹 Fixes

-   **core:** show warning if workspaceRoot starts with ! ([#&#8203;20705](https://togithub.com/nrwl/nx/pull/20705))
-   **core:** properly handle negated paths in cache outputs ([#&#8203;20661](https://togithub.com/nrwl/nx/pull/20661))
-   **react:** skip adding comma to config when adding remote to host if… ([#&#8203;20620](https://togithub.com/nrwl/nx/pull/20620))
-   **vite:** ignore CJS build deprecated warning ([#&#8203;20719](https://togithub.com/nrwl/nx/pull/20719))
-   **vite:** better extra args resolution ([#&#8203;20708](https://togithub.com/nrwl/nx/pull/20708))
-   **webpack:** add standardWebpackConfigFunction option when users opts for a standard config function ([#&#8203;20702](https://togithub.com/nrwl/nx/pull/20702))
-   **webpack:** handle both nx and nrwl scoped executors when migrating config ([#&#8203;20714](https://togithub.com/nrwl/nx/pull/20714))

##### ❤️  Thank You

-   Jack Hsu [@&#8203;jaysoo](https://togithub.com/jaysoo)
-   Jonathan Cammisuli
-   Katerina Skroumpelou [@&#8203;mandarini](https://togithub.com/mandarini)
-   Tórur Zachariasen [@&#8203;torurz](https://togithub.com/torurz)

### [`v17.2.1`](https://togithub.com/nrwl/nx/releases/tag/17.2.1)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.2.0...17.2.1)

#### 17.2.1

##### 🩹 Fixes

-   **angular:** add missing package update for [@&#8203;angular/pwa](https://togithub.com/angular/pwa) ([#&#8203;20690](https://togithub.com/nrwl/nx/pull/20690))
-   **react:** webpack backwards compat for `@nx/react/plugin/webpack` ([#&#8203;20697](https://togithub.com/nrwl/nx/pull/20697))
-   **vite:** config migration account for other syntaxes ([#&#8203;20693](https://togithub.com/nrwl/nx/pull/20693))
-   **webpack:** migrate projects without webpackConfig to use webpack.config.js ([#&#8203;20699](https://togithub.com/nrwl/nx/pull/20699))
-   **webpack:** fixed `isolatedConfig: false` option not composing plugins ([#&#8203;20678](https://togithub.com/nrwl/nx/pull/20678))

##### ❤️  Thank You

-   Jack Hsu [@&#8203;jaysoo](https://togithub.com/jaysoo)
-   Katerina Skroumpelou [@&#8203;mandarini](https://togithub.com/mandarini)
-   Leosvel Pérez Espinosa [@&#8203;leosvelperez](https://togithub.com/leosvelperez)
-   Tycho Bokdam [@&#8203;TriPSs](https://togithub.com/TriPSs)

### [`v17.2.0`](https://togithub.com/nrwl/nx/releases/tag/17.2.0)

[Compare Source](https://togithub.com/nrwl/nx/compare/17.1.3...17.2.0)

#### 17.2.0

##### 🚀 Features

-   **angular:** update component generator to use a single string `styles` or `styleUrl` property ([#&#8203;20146](https://togithub.com/nrwl/nx/pull/20146))
-   **angular:** support application builder for cypress component testing ([#&#8203;20214](https://togithub.com/nrwl/nx/pull/20214))
-   **angular:** update ngrx to v17 ([#&#8203;20247](https://togithub.com/nrwl/nx/pull/20247))
-   **angular:** support esbuild-based executors/builders in [@&#8203;nx/angular](https://togithub.com/nx/angular):dev-server ([#&#8203;20311](https://togithub.com/nrwl/nx/pull/20311))
-   **angular:** convert module-federation-dev-server to executor ([#&#8203;20252](https://togithub.com/nrwl/nx/pull/20252))
-   **angular:** support providing esbuild plugins to [@&#8203;nx/angular](https://togithub.com/nx/angular):browser-esbuild ([#&#8203;20504](https://togithub.com/nrwl/nx/pull/20504))
-   **angular:** add application executor ([#&#8203;20529](https://togithub.com/nrwl/nx/pull/20529))
-   **core:** extglob to standard glob parser ([#&#8203;20089](https://togithub.com/nrwl/nx/pull/20089))
-   **core:** make createNodes async ([#&#8203;20195](https://togithub.com/nrwl/nx/pull/20195))
-   **core:** track project changes in source map when applying plugins ([#&#8203;19955](https://togithub.com/nrwl/nx/pull/19955))
-   **core:** independent nx releases and automated git operations ([#&#8203;20191](https://togithub.com/nrwl/nx/pull/20191))
-   **core:** rust task hasher ([#&#8203;19617](https://togithub.com/nrwl/nx/pull/19617))
-   **core:** programmatic API for nx release ([#&#8203;20371](https://togithub.com/nrwl/nx/pull/20371))
-   **core:** allow setting true for changelog config to enable with defaults ([#&#8203;20376](https://togithub.com/nrwl/nx/pull/20376))
-   **core:** add env parameter to run-commands ([#&#8203;20440](https://togithub.com/nrwl/nx/pull/20440))
-   **core:** introduce workspace file archive ([#&#8203;20471](https://togithub.com/nrwl/nx/pull/20471))
-   **core:** targets inferred from plugins override targetDefaults ([#&#8203;20586](https://togithub.com/nrwl/nx/pull/20586))
-   **core:** add task plans to `--graph=file.json` argument ([#&#8203;20643](https://togithub.com/nrwl/nx/pull/20643))
-   **graph:** add project details view ([#&#8203;20466](https://togithub.com/nrwl/nx/pull/20466))
-   **linter:** update eslint to next minor version ([#&#8203;20351](https://togithub.com/nrwl/nx/pull/20351))
-   **linter:** support yaml for flat config conversion ([#&#8203;20022](https://togithub.com/nrwl/nx/pull/20022))
-   **linter:** default lintFilePatterns to {projectRoot} ([#&#8203;20313](https://togithub.com/nrwl/nx/pull/20313))
-   **linter:** add create-nodes plugin ([#&#8203;20264](https://togithub.com/nrwl/nx/pull/20264))
-   **misc:** allow providing a path in the name option of project generators ([#&#8203;20274](https://togithub.com/nrwl/nx/pull/20274))
-   **module-federation:** use single file-server for static remotes ([#&#8203;20006](https://togithub.com/nrwl/nx/pull/20006))
-   **module-federation:** add comment to generated module federation config explaining usage of external remotes ([#&#8203;20177](https://togithub.com/nrwl/nx/pull/20177))
-   **module-federation:** Add react support for  dynamic federation ([#&#8203;20024](https://togithub.com/nrwl/nx/pull/20024))
-   **nextjs:** Add support for create nodes for nextjs ([#&#8203;20193](https://togithub.com/nrwl/nx/pull/20193))
-   **nuxt:** load nuxt config programmatically ([#&#8203;20185](https://togithub.com/nrwl/nx/pull/20185))
-   **nuxt:** nodes for build, serve, test targets ([#&#8203;20145](https://togithub.com/nrwl/nx/pull/20145))
-   **nx-dev:** call to action button ([b9e02d152b](https://togithub.com/nrwl/nx/commit/b9e02d152b))
-   **nx-dev:** move Twitter pixel to site-level ([059b061bfe](https://togithub.com/nrwl/nx/commit/059b061bfe))
-   **nx-dev:** allow ranges in fences highlighting ([#&#8203;20202](https://togithub.com/nrwl/nx/pull/20202))
-   **nx-dev:** rename nx-cloud tab to CI ([#&#8203;20476](https://togithub.com/nrwl/nx/pull/20476))
-   **nx-dev:** improve advent of code page ([#&#8203;20517](https://togithub.com/nrwl/nx/pull/20517))
-   **nx-dev:** allow custom media images ([#&#8203;20561](https://togithub.com/nrwl/nx/pull/20561))
-   **release:** update dist-tags when publishing a package version that already exists ([#&#8203;20316](

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy44MS4zIiwidXBkYXRlZEluVmVyIjoiMzcuMTAzLjEiLCJ0YXJnZXRCcmFuY2giOiJjYW5hcnkifQ==-->
2023-12-28 08:00:13 +00:00
EYHN
0b9cd00fd3 refactor(core): adjust graphql hook (#5339) 2023-12-28 07:43:25 +00:00
Cats Juice
7e75e19d04 style(core): add font smoothing and optimize legibility globally (#5417)
![Frame 629667](https://github.com/toeverything/AFFiNE/assets/39363750/857a2c8d-6a75-43b2-a92f-eaf24c996d8b)
2023-12-28 07:34:20 +00:00
LongYinan
3148f93ee7 style: add perf rules (#5413) 2023-12-28 05:09:30 +00:00
LongYinan
4fcf589fe7 chore: bump up opentelemetry to ^0.46.0 (#5305)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@opentelemetry/exporter-prometheus](https://togithub.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-prometheus) ([source](https://togithub.com/open-telemetry/opentelemetry-js)) | [`^0.45.1` -> `^0.46.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2fexporter-prometheus/0.45.1/0.46.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fexporter-prometheus/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2fexporter-prometheus/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2fexporter-prometheus/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fexporter-prometheus/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@opentelemetry/instrumentation](https://togithub.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation) ([source](https://togithub.com/open-telemetry/opentelemetry-js)) | [`^0.45.1` -> `^0.46.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation/0.45.1/0.46.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2finstrumentation/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2finstrumentation/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@opentelemetry/instrumentation-http](https://togithub.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http) ([source](https://togithub.com/open-telemetry/opentelemetry-js)) | [`^0.45.1` -> `^0.46.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-http/0.45.1/0.46.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-http/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2finstrumentation-http/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2finstrumentation-http/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-http/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@opentelemetry/sdk-node](https://togithub.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-node) ([source](https://togithub.com/open-telemetry/opentelemetry-js)) | [`^0.45.1` -> `^0.46.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2fsdk-node/0.45.1/0.46.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2fsdk-node/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2fsdk-node/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2fsdk-node/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2fsdk-node/0.45.1/0.46.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>open-telemetry/opentelemetry-js (@&#8203;opentelemetry/exporter-prometheus)</summary>

### [`v0.46.0`](f665499096...d3c311aec2)

[Compare Source](f665499096...d3c311aec2)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy45My4xIiwidXBkYXRlZEluVmVyIjoiMzcuOTMuMSIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSJ9-->
2023-12-27 15:35:17 +00:00
Joooye_34
6b9f77f511 feat(core): set document title when detail page render (#5418) 2023-12-27 15:25:26 +00:00
DarkSky
a6f5a03b8a docs: update guide for build in windows (#5416) 2023-12-27 09:21:32 +00:00
Peng Xiao
0c64535e41 fix(infra): remove unused svg loader (#5398) 2023-12-27 09:00:37 +00:00
EYHN
86bd2a7d72 refactor(infra): no bundle infra (#5414) 2023-12-27 06:54:24 +00:00
EYHN
4e861d8118 refactor(electron): create electron api package (#5334) 2023-12-27 06:38:37 +00:00
Peng Xiao
ce17daba42 fix(core): enable page history for beta/stable (#5415) 2023-12-27 06:30:29 +00:00
EYHN
7a770f9672 fix(component): fix font display on safari (#5393)
before

![CleanShot 2023-12-25 at 13.09.26.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/g3jz87HxbjOJpXV3FPT7/4fe08951-67bb-4050-ba14-94391db1cac1.png)

after

![CleanShot 2023-12-25 at 13.09.13.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/g3jz87HxbjOJpXV3FPT7/fbfb17ec-b871-4746-9d3c-d24f850ecca1.png)
2023-12-27 04:37:30 +00:00
EYHN
265ee81666 refactor(infra): remove old plugin system (#5411)
plugin system need redesign
2023-12-27 02:49:59 +00:00
LongYinan
3903a1c1d6 ci: update actions/upload-artifact and actions/download-artifact (#5408) 2023-12-26 12:40:10 +00:00
Peng Xiao
c02ec5f7b9 fix(infra): workaround for self-referencing in storybook (#5406) 2023-12-26 20:27:20 +08:00
JimmFly
62fbab4f78 fix(core): avatars are not aligned (#5404) 2023-12-26 20:23:28 +08:00
LongYinan
cb4f6d30af chore: bump up react-i18next version to v14 (#5375)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [react-i18next](https://togithub.com/i18next/react-i18next) | [`^13.3.0` -> `^14.0.0`](https://renovatebot.com/diffs/npm/react-i18next/13.5.0/14.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/react-i18next/14.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/react-i18next/14.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/react-i18next/13.5.0/14.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/react-i18next/13.5.0/14.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>i18next/react-i18next (react-i18next)</summary>

### [`v14.0.0`](https://togithub.com/i18next/react-i18next/blob/HEAD/CHANGELOG.md#1400)

[Compare Source](https://togithub.com/i18next/react-i18next/compare/v13.5.0...v14.0.0)

-   types: reportNamespaces is now optional, should fix [1693](https://togithub.com/i18next/react-i18next/issues/1693)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5In0=-->
2023-12-26 08:32:07 +00:00
LongYinan
8042140fe8 chore: bump up @types/supertest version to v6 (#5376)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@types/supertest](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/supertest) ([source](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/supertest)) | [`^2.0.16` -> `^6.0.0`](https://renovatebot.com/diffs/npm/@types%2fsupertest/2.0.16/6.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fsupertest/6.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fsupertest/6.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fsupertest/2.0.16/6.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fsupertest/2.0.16/6.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5In0=-->
2023-12-26 08:20:35 +00:00
Peng Xiao
285d2a7219 fix(core): trash page footer display issue (#5402)
Before

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/eb5e5b18-c4a2-469b-8763-be34c39ba736.png)

After

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/7b3ef339-0cb5-44fe-9e75-cec0e97d28b7.png)
2023-12-26 08:07:17 +00:00
Joooye_34
60fe5f0e87 fix(electron): set stable base url to app.affine.pro (#5401)
close TOV-282
2023-12-26 07:57:03 +00:00
Peng Xiao
fafcfbce6d fix(core): about setting blink issue (#5399) 2023-12-26 07:47:11 +00:00
Peng Xiao
c59a6a833c fix(core): workpace list blink issue on open (#5400) 2023-12-26 07:37:41 +00:00
Joooye_34
3024b5cc63 ci: define tag name to fix nightly release failing (#5397) 2023-12-26 07:24:30 +00:00
JimmFly
f25814b31c chore(core): add background color to questionnaire (#5396) 2023-12-26 07:13:44 +00:00
Cats Juice
080f636c1f fix(core): correct title of onboarding article-2 (#5387) 2023-12-26 07:01:34 +00:00
LongYinan
03b68e2654 chore: bump up @vitejs/plugin-vue version to v5 (#5394)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@vitejs/plugin-vue](https://togithub.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#readme) ([source](https://togithub.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue)) | [`^4.4.0` -> `^5.0.0`](https://renovatebot.com/diffs/npm/@vitejs%2fplugin-vue/4.5.0/5.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitejs%2fplugin-vue/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitejs%2fplugin-vue/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitejs%2fplugin-vue/4.5.0/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitejs%2fplugin-vue/4.5.0/5.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>vitejs/vite-plugin-vue (@&#8203;vitejs/plugin-vue)</summary>

### [`v5.0.0`](https://togithub.com/vitejs/vite-plugin-vue/blob/HEAD/packages/plugin-vue/CHANGELOG.md#500-2023-12-25)

-   **Breaking:** drop `reactivityTransform` support
-   **Breaking:** drop Node 14/16 support
-   **Breaking:** drop Vite 4.x support
-   Vue 3.4 template AST reuse support
-   Vue 3.4 compile-time flag `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__` support
-   Added `customElement` option
-   Deprecated `defineModel` option

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5In0=-->
2023-12-26 06:50:27 +00:00
Peng Xiao
972de52833 fix(core): remove plugins settings (#5337)
depend on https://github.com/toeverything/AFFiNE/pull/5324
2023-12-26 06:21:59 +00:00
481 changed files with 29061 additions and 19539 deletions

View File

@@ -11,6 +11,4 @@ e2e-dist-*
static
web-static
public
packages/common/sdk/src/*.d.ts
packages/common/sdk/src/*.js
packages/frontend/i18n/src/i18n-generated.ts

View File

@@ -61,7 +61,6 @@ const allPackages = [
'packages/frontend/core',
'packages/frontend/electron',
'packages/frontend/graphql',
'packages/frontend/hooks',
'packages/frontend/i18n',
'packages/frontend/native',
'packages/frontend/templates',
@@ -69,10 +68,8 @@ const allPackages = [
'packages/common/debug',
'packages/common/env',
'packages/common/infra',
'packages/common/sdk',
'packages/common/theme',
'packages/common/y-indexeddb',
'packages/plugins/copilot',
'tools/cli',
'tests/storybook',
];

View File

@@ -9,7 +9,7 @@ runs:
using: 'composite'
steps:
- name: Download tar.gz
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: core
path: .

View File

@@ -21,14 +21,6 @@ inputs:
description: 'set nmMode to hardlinks-local in .yarnrc.yml'
required: false
default: 'true'
build-infra:
description: 'Build infra'
required: false
default: 'true'
build-plugins:
description: 'Build plugins'
required: false
default: 'true'
nmHoistingLimits:
description: 'Set nmHoistingLimits in .yarnrc.yml'
required: false
@@ -190,13 +182,3 @@ runs:
run: node ./node_modules/electron/install.js
env:
electron_config_cache: ./node_modules/.cache/electron
- name: Build Infra
shell: bash
if: inputs.build-infra == 'true'
run: yarn run build:infra
- name: Build Plugins
if: inputs.build-plugins == 'true'
shell: bash
run: yarn run build:plugins

View File

@@ -1,4 +1,4 @@
FROM openresty/openresty:1.21.4.1-0-buster
FROM openresty/openresty:1.21.4.3-0-buster
WORKDIR /app
COPY ./packages/frontend/core/dist ./dist
COPY ./.github/deployment/front/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf

View File

@@ -1 +0,0 @@
charts/

View File

@@ -1,23 +0,0 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@@ -1,6 +0,0 @@
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 13.2.23
digest: sha256:5b64538509bd067bb0f67bf082847a2c5d66dc37d0b9d7948a40405d9c446400
generated: "2023-12-05T03:04:57.997927753Z"

View File

@@ -1,12 +0,0 @@
apiVersion: v2
name: affine-cloud
description: A Helm chart for AFFiNE Cloud
type: application
version: 0.6.1
appVersion: '0.6.1'
dependencies:
- name: postgresql
version: 13.2.23
repository: https://charts.bitnami.com/bitnami

View File

@@ -1,30 +0,0 @@
# Helm Chart Configuration
The following table lists the configurable parameters of this Helm chart and their default values.
## AFFiNE Cloud Server parameters
| Parameter | Description | Default |
| ------------------------------ | -------------------------------------------------- | ------------------ |
| `affineCloud.tag` | The Docker tag of the AffineCloud image to be used | `'nightly-latest'` |
| `affineCloud.resources.cpu` | The CPU resources allocated for AffineCloud | `'250m'` |
| `affineCloud.resources.memory` | The memory resources allocated for AffineCloud | `'0.5Gi'` |
| `affineCloud.signKey` | The key used to sign the JWT tokens | `'c2VjcmV0'` |
| `affineCloud.service.type` | The type of the Kubernetes service | `'ClusterIP'` |
| `affineCloud.service.port` | The port of the Kubernetes service | `'http'` |
| `affineCloud.mail.account` | The email account used to send emails | `''` |
| `affineCloud.mail.password` | The password of the email account | `''` |
## PostgreSQL parameters
| Parameter | Description | Default |
| -------------------------------------------- | ------------------------------------------------------------------------------------- | ------------ |
| `postgresql.auth.username` | Username for the PostgreSQL database | `'affine'` |
| `postgresql.auth.password` | Password for the PostgreSQL database. Please change this for production environments. | `'password'` |
| `postgresql.auth.database` | The name of the default database that will be created on image startup | `'affine'` |
| `postgresql.primary.resources.limits.cpu` | The CPU resources allocated for the PostgreSQL primary node | `'500m'` |
| `postgresql.primary.resources.limits.memory` | The memory resources allocated for the PostgreSQL primary node | `'0.5Gi'` |
For more postgres parameters, please refer to: https://artifacthub.io/packages/helm/bitnami/postgresql
Please note that for the `postgresql.auth.password`, you should provide your own password for production environments. The default value is provided only for demonstration purposes.

View File

@@ -1,51 +0,0 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "affine-cloud.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "affine-cloud.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "affine-cloud.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "affine-cloud.labels" -}}
helm.sh/chart: {{ include "affine-cloud.chart" . }}
{{ include "affine-cloud.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "affine-cloud.selectorLabels" -}}
app.kubernetes.io/name: {{ include "affine-cloud.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

View File

@@ -1,51 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ include "affine-cloud.fullname" . }}"
labels:
{{- include "affine-cloud.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
{{- include "affine-cloud.selectorLabels" . | nindent 6 }}
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 2
template:
metadata:
labels:
{{- include "affine-cloud.selectorLabels" . | nindent 8 }}
spec:
restartPolicy: Always
containers:
- name: affine-cloud
image: "ghcr.io/toeverything/cloud-self-hosted:{{ .Values.affineCloud.tag | default .Chart.AppVersion }}"
env:
- name: PG_USER
value: "{{ .Values.postgresql.auth.username }}"
- name: PG_PASS
value: "{{ .Values.postgresql.auth.password }}"
- name: PG_DATABASE
value: "{{ .Values.postgresql.auth.database }}"
- name: PG_HOST
value: "{{ .Values.postgresql.fullnameOverride | default (printf "%s-postgresql" .Release.Name) }}"
- name: DATABASE_URL
value: "{{ .Values.affineCloud.databaseUrl | default "postgresql://$(PG_USER):$(PG_PASS)@$(PG_HOST)/$(PG_DATABASE)" }}"
envFrom:
- secretRef:
name: affine-cloud-secret
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /api/healthz
port: 3000
failureThreshold: 1
initialDelaySeconds: 10
periodSeconds: 10
resources:
limits:
cpu: "{{ .Values.affineCloud.resources.cpu }}"
memory: "{{ .Values.affineCloud.resources.memory }}"

View File

@@ -1,9 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: affine-cloud-secret
type: Opaque
data:
SIGN_KEY: "{{ .Values.affineCloud.signKey }}"
MAIL_ACCOUNT: "{{ .Values.affineCloud.mail.account }}"
MAIL_PASSWORD: "{{ .Values.affineCloud.mail.password }}"

View File

@@ -1,15 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ include "affine-cloud.fullname" . }}"
labels:
{{- include "affine-cloud.labels" . | nindent 4 }}
spec:
type: "{{ .Values.affineCloud.service.type }}"
ports:
- name: http
protocol: TCP
port: {{ .Values.affineCloud.service.port }}
targetPort: 3000
selector:
{{- include "affine-cloud.selectorLabels" . | nindent 4 }}

View File

@@ -1,30 +0,0 @@
affineCloud:
tag: 'canary-5e0d5e0cc65ea46f326fdde12658bfac59b38c9f-0949'
# databaseUrl: 'postgresql://affine:password@affine-cloud-postgresql:5432/affine'
signKey: TUFtdFdzQTJhdGJuem01TA==
mail:
account: ''
password: ''
service:
type: ClusterIP
port: 80
resources:
cpu: '250m'
memory: 0.5Gi
postgresql:
fullnameOverride: tcp-postgresql
auth:
# only for demo, please modify it at prod env
username: affine
password: password
database: affine
primary:
initdb:
scripts:
01-init.sql: |
CREATE DATABASE affine_binary;
GRANT ALL PRIVILEGES ON DATABASE affine_binary TO affine;
resources:
limits:
cpu: '500m'
memory: 0.5Gi

View File

@@ -1,60 +0,0 @@
# Cluster Deployment Guide
This document provides a step-by-step guide for developers on how to deploy services in a Kubernetes cluster. The following content assumes that the reader already has a basic understanding of Kubernetes concepts and operations.
### 1. Configure Service Mesh (Optional)
In the Kubernetes cluster, we optionally use Service Mesh (like Istio and Anthos Service Mesh) to manage the network interactions of microservices. If Service Mesh is already deployed on your cluster or do not need to use the service network, you can skip this step. In this step, we assume that you are using Google Kubernetes Engine (GKE) and have already installed Anthos Service Mesh on your cluster, if you wish to use another Ingress Controller, please refer to the relevant documentation.
To configure your kubectl context to interact with your Kubernetes cluster using the gcloud tool, you need to execute the following commands:
```sh
export CLUSTER_NAME=your_cluster_name
export REGION=your_cluster_region
export PROJECT=your_project_id
gcloud container clusters get-credentials $CLUSTER_NAME --region $REGION --project $PROJECT
```
In this command, you should replace `CLUSTER_NAME`, `REGION` and `PROJECT` with the actual name, region and project id of your Kubernetes cluster. This command retrieves the access credentials for your Kubernetes cluster and automatically configures kubectl to use these credentials.
Now, to inject Service Mesh for a specific Namespace, first, set the environment variable `NAMESPACE` that should correspond to your target Kubernetes Namespace. In this example, we use `prod` as the target Namespace:
```sh
export NAMESPACE=prod
```
Then, we label the Namespace which will enable Istio to automatically inject the sidecar container for all new Pods under this Namespace:
```sh
kubectl label namespace $NAMESPACE istio-injection- istio.io/rev=asm-managed --overwrite
```
Finally, we trigger the Kubernetes Deployment restart mechanism to allow existing Pods to also obtain sidecar container injection:
```sh
kubectl rollout restart deployment -n $NAMESPACE
```
### 2. Deploying the Application
Next, we will deploy our application in the Kubernetes cluster through Helm. First, set relevant environment variables:
```sh
export NAMESPACE=prod
export RELEASE=affine-cloud-prod
export PATH=.github/helm/affine-cloud
```
- `NAMESPACE` should be consistent with the first step, indicating your target Kubernetes Namespace.
- `RELEASE` is the name of your Helm release.
- `PATH` is the location of your Helm chart in your file system.
Finally, use the `helm upgrade --install` command to deploy or upgrade your application:
```sh
helm upgrade --namespace $NAMESPACE --create-namespace --install $RELEASE $PATH
```
This command creates (if it doesn't already exist) and deploys your Helm chart in the specified Namespace. If the release already exists, it will be upgraded.
The above are the complete steps for deploying an application in a Kubernetes cluster. Make sure all prerequisites are met before deploying, and also ensure that you have the correct permissions for operations in Kubernetes.

27
.github/labeler.yml vendored
View File

@@ -19,26 +19,11 @@ mod:dev:
- 'tools/cli/**/*'
- 'packages/common/debug/**/*'
mod:plugin:
- changed-files:
- any-glob-to-any-file:
- 'packages/plugins/**/*'
plugin:copilot:
- changed-files:
- any-glob-to-any-file:
- 'packages/plugins/copilot/**/*'
mod:infra:
- changed-files:
- any-glob-to-any-file:
- 'packages/common/infra/**/*'
mod:sdk:
- changed-files:
- any-glob-to-any-file:
- 'packages/common/sdk/**/*'
mod:plugin-cli:
- changed-files:
- any-glob-to-any-file:
@@ -47,7 +32,12 @@ mod:plugin-cli:
mod:workspace:
- changed-files:
- any-glob-to-any-file:
- 'packages/frontend/workspace/**/*'
- 'packages/common/workspace/**/*'
mod:workspace-impl:
- changed-files:
- any-glob-to-any-file:
- 'packages/frontend/workspace-impl/**/*'
mod:i18n:
- changed-files:
@@ -59,11 +49,6 @@ mod:env:
- any-glob-to-any-file:
- 'packages/common/env/**/*'
mod:hooks:
- changed-files:
- any-glob-to-any-file:
- 'packages/frontend/hooks/**/*'
mod:component:
- changed-files:
- any-glob-to-any-file:

27
.github/renovate.json vendored
View File

@@ -1,27 +1,26 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
"group:allNonMajor",
":preserveSemverRanges",
":disablePeerDependencies"
],
"extends": ["config:base", ":disablePeerDependencies"],
"labels": ["dependencies"],
"packageRules": [
{
"matchPackageNames": ["napi", "napi-build", "napi-derive"],
"rangeStrategy": "replace",
"groupName": "napi-rs"
},
{
"matchPackagePatterns": ["^eslint", "^@typescript-eslint"],
"rangeStrategy": "replace",
"groupName": "linter"
},
{
"matchPackagePatterns": ["^@nestjs"],
"rangeStrategy": "replace",
"groupName": "nestjs"
},
{
"matchPackagePatterns": ["^@opentelemetry"],
"rangeStrategy": "replace",
"groupName": "opentelemetry"
},
{
@@ -30,16 +29,32 @@
"@prisma/instrumentation",
"prisma"
],
"rangeStrategy": "replace",
"groupName": "prisma"
},
{
"matchPackagePatterns": ["^@electron-forge"],
"rangeStrategy": "replace",
"groupName": "electron-forge"
},
{
"groupName": "blocksuite-nightly",
"matchPackagePatterns": ["^@blocksuite"],
"excludePackageNames": ["@blocksuite/icons"],
"rangeStrategy": "replace",
"followTag": "nightly"
},
{
"groupName": "all non-major dependencies",
"groupSlug": "all-minor-patch",
"matchPackagePatterns": ["*"],
"excludePackagePatterns": ["^@blocksuite/"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"matchPackagePatterns": ["*"],
"rangeStrategy": "replace",
"excludePackagePatterns": ["^@blocksuite/"]
}
],
"commitMessagePrefix": "chore: ",

View File

@@ -108,44 +108,6 @@ jobs:
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
@@ -169,7 +131,7 @@ jobs:
- name: Upload test results
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: test-results-e2e-${{ matrix.shard }}
path: ./test-results
@@ -194,7 +156,7 @@ jobs:
- name: Upload test results
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: test-results-e2e-migration
path: ./tests/affine-migration/test-results
@@ -216,7 +178,7 @@ jobs:
full-cache: true
- name: Download affine.linux-x64-gnu.node
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: affine.linux-x64-gnu.node
path: ./packages/frontend/native
@@ -254,8 +216,6 @@ jobs:
with:
extra-flags: workspaces focus @affine/native
electron-install: false
build-infra: false
build-plugins: false
- name: Setup filename
id: filename
shell: bash
@@ -269,7 +229,7 @@ jobs:
package: '@affine/native'
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- name: Upload ${{ steps.filename.outputs.filename }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ steps.filename.outputs.filename }}
path: ./packages/frontend/native/${{ steps.filename.outputs.filename }}
@@ -287,8 +247,6 @@ jobs:
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:
@@ -296,7 +254,7 @@ jobs:
package: '@affine/storage'
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- name: Upload storage.node
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: storage.node
path: ./packages/backend/storage/storage.node
@@ -312,7 +270,6 @@ jobs:
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
@@ -320,7 +277,7 @@ jobs:
- name: zip core
run: tar -czf dist.tar.gz --directory=packages/frontend/core/dist .
- name: Upload core artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: core
path: dist.tar.gz
@@ -381,7 +338,7 @@ jobs:
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
- name: Download storage.node
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: storage.node
path: ./packages/backend/server
@@ -470,13 +427,13 @@ jobs:
yarn workspace @affine/server data-migration run
yarn workspace @affine/server exec node --loader ts-node/esm/transpile-only ./scripts/init-db.ts
- name: Download storage.node
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: storage.node
path: ./packages/backend/server
- name: Download affine.linux-x64-gnu.node
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: affine.linux-x64-gnu.node
path: ./packages/frontend/native
@@ -490,7 +447,7 @@ jobs:
- name: Upload test results
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: test-results-e2e-server
path: ./tests/affine-cloud/test-results
@@ -554,7 +511,7 @@ jobs:
echo "filename=affine.$PLATFORM_ARCH_ABI.node" >> "$GITHUB_OUTPUT"
- name: Download ${{ steps.filename.outputs.filename }}
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: ${{ steps.filename.outputs.filename }}
path: ./packages/frontend/native
@@ -596,7 +553,7 @@ jobs:
- name: Upload test results
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: test-results-e2e-${{ matrix.spec.os }}-${{ matrix.spec.arch }}
path: ./test-results

View File

@@ -32,7 +32,7 @@ jobs:
- name: Build Server
run: yarn workspace @affine/server build
- name: Upload server dist
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: server-dist
path: ./packages/backend/server/dist
@@ -48,8 +48,6 @@ jobs:
uses: ./.github/actions/setup-version
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Build Plugins
run: yarn run build:plugins
- name: Build Core
run: yarn nx build @affine/core --skip-nx-cache
env:
@@ -65,7 +63,7 @@ jobs:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
- name: Upload core artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: core
path: ./packages/frontend/core/dist
@@ -89,7 +87,7 @@ jobs:
package: '@affine/storage'
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- name: Upload storage.node
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: storage.node
path: ./packages/backend/storage/storage.node
@@ -113,7 +111,7 @@ jobs:
package: '@affine/storage'
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- name: Upload storage.node
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: storage.arm64.node
path: ./packages/backend/storage/storage.node
@@ -130,22 +128,22 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Download core artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: core
path: ./packages/frontend/core/dist
- name: Download server dist
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: server-dist
path: ./packages/backend/server/dist
- name: Download storage.node
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: storage.node
path: ./packages/backend/server
- name: Download storage.node arm64
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: storage.arm64.node
path: ./packages/backend/storage

View File

@@ -32,8 +32,6 @@ jobs:
uses: ./.github/actions/setup-node
with:
electron-install: false
- name: Build Plugins
run: yarn run build:plugins
- uses: chromaui/action-next@v1
with:
workingDir: tests/storybook
@@ -44,7 +42,7 @@ jobs:
env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
NODE_OPTIONS: ${{ env.NODE_OPTIONS }}
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
if: always()
with:
name: chromatic-build-artifacts-${{ github.run_id }}

View File

@@ -61,7 +61,7 @@ jobs:
SKIP_NX_CACHE: 'true'
- name: Upload core artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: core
path: packages/frontend/electron/resources/web-static
@@ -102,7 +102,6 @@ jobs:
with:
extra-flags: workspaces focus @affine/electron @affine/monorepo
hard-link-nm: false
build-plugins: false
nmHoistingLimits: workspaces
enableScripts: false
- name: Build AFFiNE native
@@ -111,7 +110,7 @@ jobs:
target: ${{ matrix.spec.target }}
package: '@affine/native'
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: core
path: packages/frontend/electron/resources/web-static
@@ -147,7 +146,7 @@ jobs:
mv packages/frontend/electron/out/*/make/AppImage/x64/*.AppImage ./builds/affine-${{ env.BUILD_TYPE }}-linux-x64.AppImage
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: affine-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}-builds
path: builds
@@ -179,7 +178,6 @@ jobs:
with:
extra-flags: workspaces focus @affine/electron @affine/monorepo
hard-link-nm: false
build-plugins: false
nmHoistingLimits: workspaces
- name: Build AFFiNE native
uses: ./.github/actions/build-rust
@@ -187,14 +185,11 @@ jobs:
target: ${{ matrix.spec.target }}
package: '@affine/native'
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: core
path: packages/frontend/electron/resources/web-static
- name: Build Plugins
run: yarn run build:plugins
- name: Build Desktop Layers
run: yarn workspace @affine/electron build
@@ -216,7 +211,7 @@ jobs:
run: Compress-Archive -CompressionLevel Fastest -Path packages/frontend/electron/out/* -DestinationPath archive.zip
- name: Save packaged artifacts for signing
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: |
@@ -250,7 +245,7 @@ jobs:
timeout-minutes: 10
uses: ./.github/actions/setup-node
- name: Download and overwrite packaged artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: signed-packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: .
@@ -271,7 +266,7 @@ jobs:
echo $FILES_TO_BE_SIGNED
- name: Save installer for signing
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: archive.zip
@@ -297,7 +292,7 @@ jobs:
runs-on: ${{ matrix.spec.runner }}
steps:
- name: Download and overwrite installer artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: signed-installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: .
@@ -312,7 +307,7 @@ jobs:
mv packages/frontend/electron/out/*/make/squirrel.windows/x64/*.msi ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.msi
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: affine-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}-builds
path: builds
@@ -323,29 +318,29 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: core
path: web-static
- name: Zip web-static
run: zip -r web-static.zip web-static
- name: Download Artifacts (macos-x64)
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: affine-darwin-x64-builds
path: ./
- name: Download Artifacts (macos-arm64)
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: affine-darwin-arm64-builds
path: ./
- name: Download Artifacts (windows-x64)
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: affine-win32-x64-builds
path: ./
- name: Download Artifacts (linux-x64)
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: affine-linux-x64-builds
path: ./
@@ -358,10 +353,10 @@ jobs:
env:
RELEASE_VERSION: ${{ needs.before-make.outputs.RELEASE_VERSION }}
- name: Create Release Draft
if: ${{ github.ref_type == 'tag' }}
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.before-make.outputs.RELEASE_VERSION }}
tag_name: ${{ (github.ref_type == 'tag' && github.ref_name) || needs.before-make.outputs.RELEASE_VERSION }}
body: ''
draft: ${{ github.event.inputs.is-draft }}
prerelease: ${{ github.event.inputs.is-pre-release }}
@@ -373,3 +368,25 @@ jobs:
./*.AppImage
./*.apk
./*.yml
- name: Create Nightly Release Draft
if: ${{ github.ref_type == 'branch' }}
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
with:
# Temporarily, treat release from branch as nightly release, artifact saved to AFFiNE-Releases.
# Need to improve internal build and nightly release logic.
repository: 'toeverything/AFFiNE-Releases'
name: ${{ needs.before-make.outputs.RELEASE_VERSION }}
tag_name: ${{ needs.before-make.outputs.RELEASE_VERSION }}
body: ''
draft: false
prerelease: true
files: |
./VERSION
./*.zip
./*.dmg
./*.exe
./*.AppImage
./*.apk
./*.yml

View File

@@ -14,7 +14,7 @@ jobs:
env:
ARCHIVE_DIR: ${{ github.run_id }}-${{ github.run_attempt }}-${{ inputs.artifact-name }}
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifact-name }}
path: ${{ env.ARCHIVE_DIR }}
@@ -36,7 +36,7 @@ jobs:
cd ${{ env.ARCHIVE_DIR }}
7za a signed.zip .\out\*
- name: upload
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: signed-${{ inputs.artifact-name }}
path: ${{ env.ARCHIVE_DIR }}/signed.zip

View File

@@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Publish
uses: cloudflare/wrangler-action@v3.3.2
uses: cloudflare/wrangler-action@v3.4.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}

View File

@@ -16,6 +16,8 @@ packages/frontend/i18n/src/i18n-generated.ts
packages/frontend/graphql/src/graphql/index.ts
tests/affine-legacy/**/static
.yarnrc.yml
packages/frontend/templates/templates.gen.ts
packages/frontend/templates/onboarding
# auto-generated by NAPI-RS
# fixme(@joooye34): need script to check and generate ignore list here

10
Cargo.lock generated
View File

@@ -2024,16 +2024,14 @@ dependencies = [
[[package]]
name = "rsa"
version = "0.9.2"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8"
checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc"
dependencies = [
"byteorder",
"const-oid",
"digest",
"num-bigint-dig",
"num-integer",
"num-iter",
"num-traits",
"pkcs1",
"pkcs8",
@@ -2462,9 +2460,9 @@ dependencies = [
[[package]]
name = "spki"
version = "0.7.2"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",

View File

@@ -113,20 +113,6 @@ If you have questions, you are welcome to contact us. One of the best places to
| [@toeverything/y-indexeddb](packages/common/y-indexeddb) | IndexedDB database adapter for Yjs | [![](https://img.shields.io/npm/dm/@toeverything/y-indexeddb?style=flat-square&color=eee)](https://www.npmjs.com/package/@toeverything/y-indexeddb) |
| [@toeverything/theme](packages/common/theme) | AFFiNE theme | [![](https://img.shields.io/npm/dm/@toeverything/theme?style=flat-square&color=eee)](https://www.npmjs.com/package/@toeverything/theme) |
## Plugins
> Plugins are a way to extend the functionality of AFFiNE. You can use plugins to add new blocks, new features, and even new ways to edit content.
>
> (Currently, the plugin system is under heavy development. You will see the plugin system in the canary release.)
- [@affine/sdk](./packages/common/sdk) - SDK for developing plugins
- [@affine/plugin-cli](./tools/plugin-cli) - CLI for developing plugins
| Official Plugin | Description | Status |
| ---------------------------------------------------------------- | ----------------------------------------- | ------ |
| [@affine/copilot-plugin](./packages/plugins/copilot) | AI Copilot that help you document writing | 🚧 |
| [@affine/image-preview-plugin](./packages/plugins/image-preview) | Component for previewing an image | ✅ |
## Upstreams
We would also like to give thanks to open-source projects that make AFFiNE possible:

View File

@@ -57,6 +57,29 @@ corepack prepare yarn@stable --activate
yarn install
```
### Clone repository
#### Linux & MacOS
```sh
git clone https://github.com/toeverything/AFFiNE
```
#### Windows
In our codebase, we use symbolic links. Due to the security design of Windows, the creation of symbolic links requires administrator privileges. This is part of the security policy settings of Windows, and more information can be found at [Security Policy Settings for Creating Symbolic Links](https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links).
For detailed guidance on enabling this feature, please refer to the official documentation: [Enable Developer Mode on Windows](https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development).
Once Developer Mode is enabled, execute the following command with administrator privileges:
```sh
# Enable symbolic links
git config --global core.symlinks true
# Clone the repository, also need to be run with administrator privileges
git clone https://github.com/toeverything/AFFiNE
```
### Build Native Dependencies
Run the following script. It will build the native module at [`/packages/frontend/native`](/packages/frontend/native) and build Node.js binding using [NAPI.rs](https://napi.rs/).
@@ -67,18 +90,6 @@ Note: use `strip` from system instead of `binutils` if you are running MacOS. [s
yarn workspace @affine/native build
```
### Build Infra
```sh
yarn run build:infra
```
### Build Plugins
```sh
yarn run build:plugins
```
### Build Server Dependencies
```sh
@@ -102,7 +113,7 @@ yarn test
### E2E Test
```shell
# there are `affine-local`, `affine-migration`, `affine-local`, `affine-plugin`, `affine-prototype` e2e tests,
# there are `affine-local`, `affine-migration`, `affine-local`, `affine-prototype` e2e tests,
# which are run under different situations.
cd tests/affine-local
yarn e2e

View File

@@ -17,7 +17,6 @@ The codebase is organized as follows:
- `packages/` contains all code running in production.
- `backend/` contains backend code, more information from <https://github.com/toeverything/OctoBase>.
- `frontend/` contains frontend code, including the web app, the electron app and business libraries.
- `plugins/` contains all build-in plugins.
- `common` contains the isomorphic code or basic libraries without business.
- `tools/` contains tools to help developing or CI, not used in production.
- `tests/` contains testings across different libraries, including e2e testings and integration testings.

View File

@@ -0,0 +1,23 @@
{
"name": "@affine/docs",
"type": "module",
"private": true,
"scripts": {
"build": "typedoc --options ../../typedoc.json",
"dev": "nodemon --exec 'typedoc --options ../../typedoc.json' & serve dist/"
},
"devDependencies": {
"nodemon": "^3.0.1",
"serve": "^14.2.1",
"typedoc": "^0.25.4"
},
"nodemonConfig": {
"watch": [
"./readme.md",
"../../packages/*/*/src/*.ts",
"../../**/typedoc{.base,}.json"
],
"ext": "ts,md,json"
},
"version": "0.10.3-canary.2"
}

7
docs/reference/readme.md Normal file
View File

@@ -0,0 +1,7 @@
Welcome to AFFiNE development reference.
This document is intended for developers who want to contribute to AFFiNE. It contains information about the architecture of AFFiNE, how to build it, and how to contribute to it.
### The Infrastructure of AFFiNE
see {@link @toeverything/infra!}

View File

@@ -8,6 +8,7 @@
".",
"packages/*/*",
"tools/*",
"docs/reference",
"!tools/@types",
"tools/@types/*",
"tests/*",
@@ -23,8 +24,6 @@
"build": "yarn nx build @affine/core",
"build:electron": "yarn nx build @affine/electron",
"build:storage": "yarn nx run-many -t build -p @affine/storage",
"build:infra": "yarn nx run-many -t build --projects=tag:infra",
"build:plugins": "yarn nx run-many -t build --projects=tag:plugin",
"build:storybook": "yarn nx build @affine/storybook",
"start:web-static": "yarn workspace @affine/core static-server",
"start:storybook": "yarn exec serve tests/storybook/storybook-static -l 6006",
@@ -33,7 +32,7 @@
"lint:eslint:fix": "yarn lint:eslint --fix",
"lint:prettier": "prettier --ignore-unknown --cache --check .",
"lint:prettier:fix": "prettier --ignore-unknown --cache --write .",
"lint:ox": "oxlint --deny-warnings -D correctness -D nursery -D prefer-array-some -D no-useless-promise-resolve-reject -A no-undef -A consistent-type-exports -A default -A named -A ban-ts-comment",
"lint:ox": "oxlint --import-plugin --deny-warnings -D correctness -D nursery -D prefer-array-some -D no-useless-promise-resolve-reject -D perf -A no-undef -A consistent-type-exports -A default -A named -A ban-ts-comment -A export",
"lint": "yarn lint:eslint && yarn lint:prettier",
"lint:fix": "yarn lint:eslint:fix && yarn lint:prettier:fix",
"test": "vitest --run",
@@ -58,13 +57,12 @@
"devDependencies": {
"@affine-test/kit": "workspace:*",
"@affine/cli": "workspace:*",
"@affine/plugin-cli": "workspace:*",
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3",
"@faker-js/faker": "^8.3.1",
"@istanbuljs/schema": "^0.1.3",
"@magic-works/i18n-codegen": "^0.5.0",
"@nx/vite": "17.1.3",
"@nx/vite": "17.2.8",
"@perfsee/sdk": "^1.9.0",
"@playwright/test": "^1.40.0",
"@taplo/cli": "^0.5.2",
@@ -78,8 +76,8 @@
"@vanilla-extract/vite-plugin": "^3.9.2",
"@vanilla-extract/webpack-plugin": "^2.3.1",
"@vitejs/plugin-react-swc": "^3.5.0",
"@vitest/coverage-istanbul": "1.0.4",
"@vitest/ui": "1.0.4",
"@vitest/coverage-istanbul": "1.1.1",
"@vitest/ui": "1.1.1",
"electron": "^27.1.0",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
@@ -91,7 +89,7 @@
"eslint-plugin-unicorn": "^50.0.0",
"eslint-plugin-unused-imports": "^3.0.0",
"eslint-plugin-vue": "^9.18.1",
"fake-indexeddb": "5.0.1",
"fake-indexeddb": "5.0.2",
"happy-dom": "^12.10.3",
"husky": "^8.0.3",
"lint-staged": "^15.1.0",
@@ -100,7 +98,7 @@
"nx": "^17.1.3",
"nx-cloud": "^16.5.2",
"nyc": "^15.1.0",
"oxlint": "0.0.21",
"oxlint": "0.0.22",
"prettier": "^3.1.0",
"semver": "^7.5.4",
"serve": "^14.2.1",
@@ -111,7 +109,7 @@
"vite-plugin-istanbul": "^5.0.0",
"vite-plugin-static-copy": "^1.0.0",
"vite-tsconfig-paths": "^4.2.1",
"vitest": "1.0.4",
"vitest": "1.1.1",
"vitest-fetch-mock": "^0.2.2",
"vitest-mock-extended": "^1.3.1"
},

View File

@@ -38,22 +38,22 @@
"@node-rs/crc32": "^1.7.2",
"@node-rs/jsonwebtoken": "^0.2.3",
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/core": "^1.18.1",
"@opentelemetry/exporter-prometheus": "^0.45.1",
"@opentelemetry/exporter-zipkin": "^1.18.1",
"@opentelemetry/core": "^1.19.0",
"@opentelemetry/exporter-prometheus": "^0.46.0",
"@opentelemetry/exporter-zipkin": "^1.19.0",
"@opentelemetry/host-metrics": "^0.34.0",
"@opentelemetry/instrumentation": "^0.45.1",
"@opentelemetry/instrumentation": "^0.46.0",
"@opentelemetry/instrumentation-graphql": "^0.36.0",
"@opentelemetry/instrumentation-http": "^0.45.1",
"@opentelemetry/instrumentation-http": "^0.46.0",
"@opentelemetry/instrumentation-ioredis": "^0.36.0",
"@opentelemetry/instrumentation-nestjs-core": "^0.33.3",
"@opentelemetry/instrumentation-socket.io": "^0.34.3",
"@opentelemetry/resources": "^1.18.1",
"@opentelemetry/sdk-metrics": "^1.18.1",
"@opentelemetry/sdk-node": "^0.45.1",
"@opentelemetry/sdk-trace-node": "^1.18.1",
"@prisma/client": "^5.6.0",
"@prisma/instrumentation": "^5.6.0",
"@opentelemetry/instrumentation-socket.io": "^0.34.4",
"@opentelemetry/resources": "^1.19.0",
"@opentelemetry/sdk-metrics": "^1.19.0",
"@opentelemetry/sdk-node": "^0.46.0",
"@opentelemetry/sdk-trace-node": "^1.19.0",
"@prisma/client": "^5.7.1",
"@prisma/instrumentation": "^5.7.1",
"@socket.io/redis-adapter": "^8.2.1",
"cookie-parser": "^1.4.6",
"dotenv": "^16.3.1",
@@ -74,9 +74,9 @@
"on-headers": "^1.0.2",
"parse-duration": "^1.1.0",
"pretty-time": "^1.1.0",
"prisma": "^5.6.0",
"prisma": "^5.7.1",
"prom-client": "^15.0.0",
"reflect-metadata": "^0.1.13",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"semver": "^7.5.4",
"socket.io": "^4.7.2",
@@ -101,7 +101,7 @@
"@types/on-headers": "^1.0.3",
"@types/pretty-time": "^1.1.5",
"@types/sinon": "^17.0.2",
"@types/supertest": "^2.0.16",
"@types/supertest": "^6.0.0",
"@types/ws": "^8.5.10",
"ava": "^6.0.0",
"c8": "^8.0.1",

View File

@@ -1,7 +1,7 @@
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-3.0.x", "linux-arm64-openssl-3.0.x"]
previewFeatures = ["metrics", "tracing"]
previewFeatures = ["metrics", "tracing", "relationJoins", "nativeDistinct"]
}
datasource db {

View File

@@ -0,0 +1,21 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
// Custom configurations
const env = process.env;
const node = AFFiNE.node;
// TODO: may be separate config overring in `affine.[env].config`?
if (node.prod && env.R2_OBJECT_STORAGE_ACCOUNT_ID) {
AFFiNE.storage.providers.r2 = {
accountId: env.R2_OBJECT_STORAGE_ACCOUNT_ID,
credentials: {
accessKeyId: env.R2_OBJECT_STORAGE_ACCESS_KEY_ID!,
secretAccessKey: env.R2_OBJECT_STORAGE_SECRET_ACCESS_KEY!,
},
};
AFFiNE.storage.storages.avatar.provider = 'r2';
AFFiNE.storage.storages.avatar.bucket = 'account-avatar';
AFFiNE.storage.storages.blob.provider = 'r2';
AFFiNE.storage.storages.blob.bucket = 'workspace-blobs';
}

View File

@@ -0,0 +1,3 @@
import { getDefaultAFFiNEConfig } from './config/default';
globalThis.AFFiNE = getDefaultAFFiNEConfig();

View File

@@ -1,6 +1,7 @@
import type { ApolloDriverConfig } from '@nestjs/apollo';
import type { LeafPaths } from '../utils/types';
import type { AFFiNEStorageConfig } from './storage';
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
@@ -165,11 +166,18 @@ export interface AFFiNEConfig {
featureFlags: {
earlyAccessPreview: boolean;
};
/**
* Configuration for Object Storage, which defines how blobs and avatar assets are stored.
*/
storage: AFFiNEStorageConfig;
/**
* object storage Config
*
* all artifacts and logs will be stored on instance disk,
* and can not shared between instances if not configured
* @deprecated use `storage` instead
*/
objectStorage: {
/**

View File

@@ -9,6 +9,7 @@ import parse from 'parse-duration';
import pkg from '../../package.json' assert { type: 'json' };
import type { AFFiNEConfig, ServerFlavor } from './def';
import { applyEnvToConfig } from './env';
import { getDefaultAFFiNEStorageConfig } from './storage';
export const SERVER_FLAVOR = (process.env.SERVER_FLAVOR ??
'allinone') as ServerFlavor;
@@ -59,11 +60,6 @@ export const getDefaultAFFiNEConfig: () => AFFiNEConfig = () => {
AFFINE_SERVER_SUB_PATH: 'path',
AFFINE_ENV: 'affineEnv',
DATABASE_URL: 'db.url',
ENABLE_R2_OBJECT_STORAGE: ['objectStorage.r2.enabled', 'boolean'],
R2_OBJECT_STORAGE_ACCOUNT_ID: 'objectStorage.r2.accountId',
R2_OBJECT_STORAGE_ACCESS_KEY_ID: 'objectStorage.r2.accessKeyId',
R2_OBJECT_STORAGE_SECRET_ACCESS_KEY: 'objectStorage.r2.secretAccessKey',
R2_OBJECT_STORAGE_BUCKET: 'objectStorage.r2.bucket',
ENABLE_CAPTCHA: ['auth.captcha.enable', 'boolean'],
CAPTCHA_TURNSTILE_SECRET: ['auth.captcha.turnstile.secret', 'string'],
OAUTH_GOOGLE_ENABLED: ['auth.oauthProviders.google.enabled', 'boolean'],
@@ -180,6 +176,7 @@ export const getDefaultAFFiNEConfig: () => AFFiNEConfig = () => {
password: '',
},
},
storage: getDefaultAFFiNEStorageConfig(),
objectStorage: {
r2: {
enabled: false,

View File

@@ -74,3 +74,4 @@ export class ConfigModule {
export type { AFFiNEConfig } from './def';
export { SERVER_FLAVOR } from './default';
export * from './storage';

View File

@@ -0,0 +1,58 @@
import { homedir } from 'node:os';
import { join } from 'node:path';
import { S3ClientConfigType } from '@aws-sdk/client-s3';
export type StorageProviderType = 'fs' | 'r2' | 's3';
export interface FsStorageConfig {
path: string;
}
export type R2StorageConfig = S3ClientConfigType & {
accountId: string;
};
export type S3StorageConfig = S3ClientConfigType;
export type StorageTargetConfig = {
provider: StorageProviderType;
bucket: string;
};
export interface AFFiNEStorageConfig {
/**
* All providers for object storage
*
* Support different providers for different usage at the same time.
*/
providers: {
fs?: FsStorageConfig;
s3?: S3StorageConfig;
r2?: R2StorageConfig;
};
storages: {
avatar: StorageTargetConfig;
blob: StorageTargetConfig;
};
}
export type StorageProviders = AFFiNEStorageConfig['providers'];
export type Storages = keyof AFFiNEStorageConfig['storages'];
export function getDefaultAFFiNEStorageConfig(): AFFiNEStorageConfig {
return {
providers: {
fs: {
path: join(homedir(), '.affine/storage'),
},
},
storages: {
avatar: {
provider: 'fs',
bucket: 'avatars',
},
blob: {
provider: 'fs',
bucket: 'blobs',
},
},
};
}

View File

@@ -0,0 +1,31 @@
import type { UserType } from '../../modules/users';
import { PrismaService } from '../../prisma';
export class UnamedAccount1703756315970 {
// do the migration
static async up(db: PrismaService) {
await db.$transaction(async tx => {
// only find users with empty names
const users = await db.$queryRaw<
UserType[]
>`SELECT * FROM users WHERE name ~ E'^[\\s\\u2000-\\u200F]*$';`;
console.log(
`renaming ${users.map(({ email }) => email).join('|')} users`
);
await Promise.all(
users.map(({ id, email }) =>
tx.user.update({
where: { id },
data: {
name: email.split('@')[0],
},
})
)
);
});
}
// revert the migration
static async down(_db: PrismaService) {}
}

View File

@@ -29,7 +29,9 @@ import {
SpanExporter,
TraceIdRatioBasedSampler,
} from '@opentelemetry/sdk-trace-node';
import { PrismaInstrumentation } from '@prisma/instrumentation';
import prismaInstrument from '@prisma/instrumentation';
const { PrismaInstrumentation } = prismaInstrument;
import { PrismaMetricProducer } from './prisma';

View File

@@ -0,0 +1,113 @@
import { promises as fs } from 'node:fs';
import { join } from 'node:path';
import test from 'ava';
import { getStreamAsBuffer } from 'get-stream';
import { ListObjectsMetadata } from '../providers';
import { FsStorageProvider } from '../providers/fs';
const config = {
path: join(process.cwd(), 'node_modules', '.cache/affine-test-storage'),
};
function createProvider() {
return new FsStorageProvider(
config,
'test' + Math.random().toString(16).substring(2, 8)
);
}
function keys(list: ListObjectsMetadata[]) {
return list.map(i => i.key);
}
async function randomPut(
provider: FsStorageProvider,
prefix = ''
): Promise<string> {
const key = prefix + 'test-key-' + Math.random().toString(16).substring(2, 8);
const body = Buffer.from(key);
provider.put(key, body);
return key;
}
test.after.always(() => {
fs.rm(config.path, { recursive: true });
});
test('put & get', async t => {
const provider = createProvider();
const key = 'testKey';
const body = Buffer.from('testBody');
await provider.put(key, body);
const result = await provider.get(key);
t.deepEqual(await getStreamAsBuffer(result.body!), body);
t.is(result.metadata?.contentLength, body.length);
});
test('list - one level', async t => {
const provider = createProvider();
const list = await Promise.all(
Array.from({ length: 100 }).map(() => randomPut(provider))
);
list.sort();
// random order, use set
const result = await provider.list();
t.deepEqual(keys(result), list);
const result2 = await provider.list('test-key');
t.deepEqual(keys(result2), list);
const result3 = await provider.list('testKey');
t.is(result3.length, 0);
});
test('list recursively', async t => {
const provider = createProvider();
await Promise.all([
Promise.all(Array.from({ length: 10 }).map(() => randomPut(provider))),
Promise.all(
Array.from({ length: 10 }).map(() => randomPut(provider, 'a/'))
),
Promise.all(
Array.from({ length: 10 }).map(() => randomPut(provider, 'a/b/'))
),
Promise.all(
Array.from({ length: 10 }).map(() => randomPut(provider, 'a/b/t/'))
),
]);
const r1 = await provider.list();
t.is(r1.length, 40);
// contains all `a/xxx` and `a/b/xxx` and `a/b/c/xxx`
const r2 = await provider.list('a');
t.is(r2.length, 30);
// contains only `a/b/xxx`
const r3 = await provider.list('a/b');
const r4 = await provider.list('a/b/');
t.is(r3.length, 20);
t.deepEqual(r3, r4);
// prefix is not ended with '/', it's open to all files and sub dirs
// contains all `a/b/t/xxx` and `a/b/t{xxxx}`
const r5 = await provider.list('a/b/t');
t.is(r5.length, 20);
});
test.only('delete', async t => {
const provider = createProvider();
const key = 'testKey';
const body = Buffer.from('testBody');
await provider.put(key, body);
await provider.delete(key);
await t.throwsAsync(() => fs.access(join(config.path, provider.bucket, key)));
});

View File

@@ -0,0 +1,256 @@
import {
accessSync,
constants,
createReadStream,
Dirent,
mkdirSync,
readdirSync,
readFileSync,
rmSync,
statSync,
writeFileSync,
} from 'node:fs';
import { join, parse, resolve } from 'node:path';
import { Logger } from '@nestjs/common';
import { Readable } from 'stream';
import { FsStorageConfig } from '../../../config/storage';
import {
BlobInputType,
GetObjectMetadata,
ListObjectsMetadata,
PutObjectMetadata,
StorageProvider,
} from './provider';
import { autoMetadata, toBuffer } from './utils';
function escapeKey(key: string): string {
// avoid '../' and './' in key
return key.replace(/\.?\.[/\\]/g, '%');
}
export class FsStorageProvider implements StorageProvider {
private readonly path: string;
private readonly logger: Logger;
constructor(
config: FsStorageConfig,
public readonly bucket: string
) {
this.path = resolve(config.path, bucket);
this.ensureAvailability();
this.logger = new Logger(`${FsStorageProvider.name}:${bucket}`);
}
async put(
key: string,
body: BlobInputType,
metadata: PutObjectMetadata = {}
): Promise<void> {
key = escapeKey(key);
const blob = await toBuffer(body);
// write object
this.writeObject(key, blob);
// write metadata
await this.writeMetadata(key, blob, metadata);
this.logger.verbose(`Object \`${key}\` put`);
}
async get(key: string): Promise<{
body?: Readable;
metadata?: GetObjectMetadata;
}> {
key = escapeKey(key);
try {
const metadata = this.readMetadata(key);
const stream = this.readObject(this.join(key));
this.logger.verbose(`Read object \`${key}\``);
return {
body: stream,
metadata,
};
} catch (e) {
this.logger.error(`Failed to read object \`${key}\``, e);
return {};
}
}
async list(prefix?: string): Promise<ListObjectsMetadata[]> {
// prefix cases:
// - `undefined`: list all objects
// - `a/b`: list objects under dir `a` with prefix `b`, `b` might be a dir under `a` as well.
// - `a/b/` list objects under dir `a/b`
// read dir recursively and filter out '.metadata.json' files
let dir = this.path;
if (prefix) {
prefix = escapeKey(prefix);
const parts = prefix.split(/[/\\]/);
// for prefix `a/b/c`, move `a/b` to dir and `c` to key prefix
if (parts.length > 1) {
dir = join(dir, ...parts.slice(0, -1));
prefix = parts[parts.length - 1];
}
}
const results: ListObjectsMetadata[] = [];
async function getFiles(dir: string, prefix?: string): Promise<void> {
try {
const entries: Dirent[] = readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const res = join(dir, entry.name);
if (entry.isDirectory()) {
if (!prefix || entry.name.startsWith(prefix)) {
await getFiles(res);
}
} else if (
(!prefix || entry.name.startsWith(prefix)) &&
!entry.name.endsWith('.metadata.json')
) {
const stat = statSync(res);
results.push({
key: res,
lastModified: stat.mtime,
size: stat.size,
});
}
}
} catch (e) {
// failed to read dir, stop recursion
}
}
await getFiles(dir, prefix);
// trim path with `this.path` prefix
results.forEach(r => (r.key = r.key.slice(this.path.length + 1)));
return results;
}
delete(key: string): Promise<void> {
key = escapeKey(key);
try {
rmSync(this.join(key), { force: true });
rmSync(this.join(`${key}.metadata.json`), { force: true });
} catch (e) {
throw new Error(`Failed to delete object \`${key}\``, {
cause: e,
});
}
this.logger.verbose(`Object \`${key}\` deleted`);
return Promise.resolve();
}
ensureAvailability() {
// check stats
const stats = statSync(this.path, {
throwIfNoEntry: false,
});
// not existing, create it
if (!stats) {
try {
mkdirSync(this.path, { recursive: true });
} catch (e) {
throw new Error(
`Failed to create target directory for fs storage provider: ${this.path}`,
{
cause: e,
}
);
}
} else if (stats.isDirectory()) {
// the target directory has already existed, check if it is readable & writable
try {
accessSync(this.path, constants.W_OK | constants.R_OK);
} catch (e) {
throw new Error(
`The target directory for fs storage provider has already existed, but it is not readable & writable: ${this.path}`,
{
cause: e,
}
);
}
} else if (stats.isFile()) {
throw new Error(
`The target directory for fs storage provider is a file: ${this.path}`
);
}
}
private join(...paths: string[]) {
return join(this.path, ...paths);
}
private readObject(file: string): Readable | undefined {
const state = statSync(file, { throwIfNoEntry: false });
if (state?.isFile()) {
return createReadStream(file);
}
return undefined;
}
private writeObject(key: string, blob: Buffer) {
const path = this.join(key);
mkdirSync(parse(path).dir, { recursive: true });
writeFileSync(path, blob);
}
private async writeMetadata(
key: string,
blob: Buffer,
raw: PutObjectMetadata
) {
try {
const metadata = await autoMetadata(blob, raw);
if (raw.checksumCRC32 && metadata.checksumCRC32 !== raw.checksumCRC32) {
throw new Error(
'The checksum of the uploaded file is not matched with the one you provide, the file may be corrupted and the uploading will not be processed.'
);
}
writeFileSync(
this.join(`${key}.metadata.json`),
JSON.stringify({
...metadata,
lastModified: Date.now(),
})
);
} catch (e) {
this.logger.warn(`Failed to write metadata of object \`${key}\``, e);
}
}
private readMetadata(key: string): GetObjectMetadata | undefined {
try {
const raw = JSON.parse(
readFileSync(this.join(`${key}.metadata.json`), {
encoding: 'utf-8',
})
);
return {
...raw,
lastModified: new Date(raw.lastModified),
expires: raw.expires ? new Date(raw.expires) : undefined,
};
} catch (e) {
this.logger.warn(`Failed to read metadata of object \`${key}\``, e);
return;
}
}
}

View File

@@ -0,0 +1,34 @@
import { AFFiNEStorageConfig, Storages } from '../../../config/storage';
import { FsStorageProvider } from './fs';
import type { StorageProvider } from './provider';
import { R2StorageProvider } from './r2';
import { S3StorageProvider } from './s3';
export function createStorageProvider(
config: AFFiNEStorageConfig,
storage: Storages
): StorageProvider {
const storageConfig = config.storages[storage];
const providerConfig = config.providers[storageConfig.provider] as any;
if (!providerConfig) {
throw new Error(
`Failed to create ${storageConfig.provider} storage, configuration not correctly set`
);
}
if (storageConfig.provider === 's3') {
return new S3StorageProvider(providerConfig, storageConfig.bucket);
}
if (storageConfig.provider === 'r2') {
return new R2StorageProvider(providerConfig, storageConfig.bucket);
}
if (storageConfig.provider === 'fs') {
return new FsStorageProvider(providerConfig, storageConfig.bucket);
}
throw new Error(`Unknown storage provider type: ${storageConfig.provider}`);
}
export type * from './provider';

View File

@@ -0,0 +1,39 @@
import type { Readable } from 'node:stream';
export interface GetObjectMetadata {
/**
* @default 'application/octet-stream'
*/
contentType: string;
contentLength: number;
lastModified: Date;
checksumCRC32: string;
}
export interface PutObjectMetadata {
contentType?: string;
contentLength?: number;
checksumCRC32?: string;
}
export interface ListObjectsMetadata {
key: string;
lastModified: Date;
size: number;
}
export type BlobInputType = Buffer | Readable | string;
export type BlobOutputType = Readable;
export interface StorageProvider {
put(
key: string,
body: BlobInputType,
metadata?: PutObjectMetadata
): Promise<void>;
get(
key: string
): Promise<{ body?: BlobOutputType; metadata?: GetObjectMetadata }>;
list(prefix?: string): Promise<ListObjectsMetadata[]>;
delete(key: string): Promise<void>;
}

View File

@@ -0,0 +1,14 @@
import { R2StorageConfig } from '../../../config/storage';
import { S3StorageProvider } from './s3';
export class R2StorageProvider extends S3StorageProvider {
constructor(config: R2StorageConfig, bucket: string) {
super(
{
...config,
endpoint: `https://${config.accountId}.r2.cloudflarestorage.com`,
},
bucket
);
}
}

View File

@@ -0,0 +1,159 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { Readable } from 'node:stream';
import {
DeleteObjectCommand,
GetObjectCommand,
ListObjectsV2Command,
PutObjectCommand,
S3Client,
} from '@aws-sdk/client-s3';
import { Logger } from '@nestjs/common';
import { S3StorageConfig } from '../../../config/storage';
import {
BlobInputType,
GetObjectMetadata,
ListObjectsMetadata,
PutObjectMetadata,
StorageProvider,
} from './provider';
import { autoMetadata, toBuffer } from './utils';
export class S3StorageProvider implements StorageProvider {
logger: Logger;
client: S3Client;
constructor(
config: S3StorageConfig,
public readonly bucket: string
) {
this.client = new S3Client(config);
this.logger = new Logger(`${S3StorageProvider.name}:${bucket}`);
}
async put(
key: string,
body: BlobInputType,
metadata: PutObjectMetadata = {}
): Promise<void> {
const blob = await toBuffer(body);
metadata = await autoMetadata(blob, metadata);
try {
await this.client.send(
new PutObjectCommand({
Bucket: this.bucket,
Key: key,
Body: body,
// metadata
ContentType: metadata.contentType,
ContentLength: metadata.contentLength,
ChecksumCRC32: metadata.checksumCRC32,
})
);
this.logger.verbose(`Object \`${key}\` put`);
} catch (e) {
throw new Error(`Failed to put object \`${key}\``, {
cause: e,
});
}
}
async get(key: string): Promise<{
body?: Readable;
metadata?: GetObjectMetadata;
}> {
try {
const obj = await this.client.send(
new GetObjectCommand({
Bucket: this.bucket,
Key: key,
})
);
if (!obj.Body) {
this.logger.verbose(`Object \`${key}\` not found`);
return {};
}
this.logger.verbose(`Read object \`${key}\``);
return {
// @ts-expect-errors ignore browser response type `Blob`
body: obj.Body,
metadata: {
// always set when putting object
contentType: obj.ContentType!,
contentLength: obj.ContentLength!,
checksumCRC32: obj.ChecksumCRC32!,
lastModified: obj.LastModified!,
},
};
} catch (e) {
throw new Error(`Failed to read object \`${key}\``, {
cause: e,
});
}
}
async list(prefix?: string): Promise<ListObjectsMetadata[]> {
// continuationToken should be `string | undefined`,
// but TypeScript will fail on type infer in the code below.
// Seems to be a bug in TypeScript
let continuationToken: any = undefined;
let hasMore = true;
let result: ListObjectsMetadata[] = [];
try {
while (hasMore) {
const listResult = await this.client.send(
new ListObjectsV2Command({
Bucket: this.bucket,
Prefix: prefix,
ContinuationToken: continuationToken,
})
);
if (listResult.Contents?.length) {
result = result.concat(
listResult.Contents.map(r => ({
key: r.Key!,
lastModified: r.LastModified!,
size: r.Size!,
}))
);
}
// has more items not listed
hasMore = !!listResult.IsTruncated;
continuationToken = listResult.NextContinuationToken;
}
this.logger.verbose(
`List ${result.length} objects with prefix \`${prefix}\``
);
return result;
} catch (e) {
throw new Error(`Failed to list objects with prefix \`${prefix}\``, {
cause: e,
});
}
}
async delete(key: string): Promise<void> {
try {
await this.client.send(
new DeleteObjectCommand({
Bucket: this.bucket,
Key: key,
})
);
} catch (e) {
throw new Error(`Failed to delete object \`${key}\``, {
cause: e,
});
}
}
}

View File

@@ -0,0 +1,49 @@
import { Readable } from 'node:stream';
import { crc32 } from '@node-rs/crc32';
import { fileTypeFromBuffer } from 'file-type';
import { getStreamAsBuffer } from 'get-stream';
import { BlobInputType, PutObjectMetadata } from './provider';
export async function toBuffer(input: BlobInputType): Promise<Buffer> {
return input instanceof Readable
? await getStreamAsBuffer(input)
: input instanceof Buffer
? input
: Buffer.from(input);
}
export async function autoMetadata(
blob: Buffer,
raw: PutObjectMetadata
): Promise<PutObjectMetadata> {
const metadata = {
...raw,
};
try {
// length
if (!metadata.contentLength) {
metadata.contentLength = blob.length;
}
// checksum
if (!metadata.checksumCRC32) {
metadata.checksumCRC32 = crc32(blob).toString(16);
}
// mime type
if (!metadata.contentType) {
try {
const typeResult = await fileTypeFromBuffer(blob);
metadata.contentType = typeResult?.mime ?? 'application/octet-stream';
} catch {
// ignore
}
}
return metadata;
} catch (e) {
return metadata;
}
}

View File

@@ -0,0 +1,30 @@
import { Injectable } from '@nestjs/common';
import { Config } from '../../../config';
import {
BlobInputType,
createStorageProvider,
PutObjectMetadata,
StorageProvider,
} from '../providers';
@Injectable()
export class AvatarStorage {
public readonly provider: StorageProvider;
constructor({ storage }: Config) {
this.provider = createStorageProvider(storage, 'avatar');
}
put(key: string, blob: BlobInputType, metadata?: PutObjectMetadata) {
return this.provider.put(key, blob, metadata);
}
get(key: string) {
return this.provider.get(key);
}
async delete(key: string) {
return this.provider.delete(key);
}
}

View File

@@ -0,0 +1,45 @@
import { Injectable } from '@nestjs/common';
import { Config } from '../../../config';
import {
BlobInputType,
createStorageProvider,
StorageProvider,
} from '../providers';
@Injectable()
export class WorkspaceBlobStorage {
public readonly provider: StorageProvider;
constructor({ storage }: Config) {
this.provider = createStorageProvider(storage, 'blob');
}
put(workspaceId: string, key: string, blob: BlobInputType) {
return this.provider.put(`${workspaceId}/${key}`, blob);
}
get(workspaceId: string, key: string) {
return this.provider.get(`${workspaceId}/${key}`);
}
async list(workspaceId: string) {
const blobs = await this.provider.list(workspaceId + '/');
blobs.forEach(item => {
// trim workspace prefix
item.key = item.key.slice(workspaceId.length + 1);
});
return blobs;
}
async delete(workspaceId: string, key: string) {
return this.provider.delete(`${workspaceId}/${key}`);
}
async totalSize(workspaceId: string) {
const blobs = await this.list(workspaceId);
// how could we ignore the ones get soft-deleted?
return blobs.reduce((acc, item) => acc + item.size, 0);
}
}

View File

@@ -0,0 +1,2 @@
export { AvatarStorage } from './avatar';
export { WorkspaceBlobStorage } from './blob';

View File

@@ -1,9 +1,7 @@
import 'reflect-metadata';
import 'dotenv/config';
import { getDefaultAFFiNEConfig } from './config/default';
globalThis.AFFiNE = getDefaultAFFiNEConfig();
import './affine';
import './affine.config';
if (process.env.NODE_ENV === 'development') {
console.log('AFFiNE Config:', globalThis.AFFiNE);

View File

@@ -35,7 +35,7 @@
"version": "napi version"
},
"devDependencies": {
"@napi-rs/cli": "3.0.0-alpha.15",
"@napi-rs/cli": "3.0.0-alpha.29",
"lib0": "^0.2.87",
"nx": "^17.1.3",
"nx-cloud": "^16.5.2",

View File

@@ -7,7 +7,7 @@
},
"devDependencies": {
"@types/debug": "^4.1.9",
"vitest": "1.0.4"
"vitest": "1.1.1"
},
"version": "0.11.0"
}

View File

@@ -3,11 +3,11 @@
"private": true,
"type": "module",
"devDependencies": {
"@blocksuite/global": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/store": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/global": "0.11.0-nightly-202401020419-752a5b8",
"@blocksuite/store": "0.11.0-nightly-202401020419-752a5b8",
"react": "18.2.0",
"react-dom": "18.2.0",
"vitest": "1.0.4",
"vitest": "1.1.1",
"zod": "^3.22.4"
},
"exports": {

View File

@@ -12,8 +12,6 @@ export const blockSuiteFeatureFlags = z.object({
});
export const runtimeFlagsSchema = z.object({
enablePlugin: z.boolean(),
builtinPlugins: z.array(z.string()),
enableTestProperties: z.boolean(),
enableBroadcastChannelProvider: z.boolean(),
enableDebugPage: z.boolean(),

View File

@@ -1,70 +1,21 @@
{
"name": "@toeverything/infra",
"type": "module",
"module": "./dist/index.js",
"main": "./dist/index.cjs",
"types": "./dist/src/index.d.ts",
"private": true,
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./blocksuite": {
"types": "./dist/src/blocksuite/index.d.ts",
"import": "./dist/blocksuite.js",
"require": "./dist/blocksuite.cjs"
},
"./command": {
"types": "./dist/src/command/index.d.ts",
"import": "./dist/command.js",
"require": "./dist/command.cjs"
},
"./core/*": {
"types": "./dist/src/core/*.d.ts",
"import": "./dist/core/*.js",
"require": "./dist/core/*.cjs"
},
"./preload/*": {
"types": "./dist/src/preload/*.d.ts",
"import": "./dist/preload/*.js",
"require": "./dist/preload/*.cjs"
},
"./atom": {
"type": "./dist/src/atom.d.ts",
"import": "./dist/atom.js",
"require": "./dist/atom.cjs"
},
"./type": {
"type": "./dist/src/type.d.ts",
"import": "./dist/type.js",
"require": "./dist/type.cjs"
},
"./app-config-storage": {
"type": "./dist/src/app-config-storage.d.ts",
"import": "./dist/app-config-storage.js",
"require": "./dist/app-config-storage.cjs"
},
"./__internal__/*": {
"type": "./dist/src/__internal__/*.d.ts",
"import": "./dist/__internal__/*.js",
"require": "./dist/__internal__/*.cjs"
}
},
"files": [
"dist"
],
"scripts": {
"build": "vite build",
"dev": "vite build --watch"
"./blocksuite": "./src/blocksuite/index.ts",
"./command": "./src/command/index.ts",
"./atom": "./src/atom/index.ts",
"./app-config-storage": "./src/app-config-storage.ts",
".": "./src/index.ts"
},
"dependencies": {
"@affine/debug": "workspace:*",
"@affine/env": "workspace:*",
"@affine/sdk": "workspace:*",
"@blocksuite/blocks": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/global": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/store": "0.11.0-nightly-202312220916-e3abcbb",
"@affine/templates": "workspace:*",
"@blocksuite/blocks": "0.11.0-nightly-202401020419-752a5b8",
"@blocksuite/global": "0.11.0-nightly-202401020419-752a5b8",
"@blocksuite/store": "0.11.0-nightly-202401020419-752a5b8",
"jotai": "^2.5.1",
"jotai-effect": "^0.2.3",
"tinykeys": "^2.1.0",
@@ -73,17 +24,15 @@
"devDependencies": {
"@affine-test/fixtures": "workspace:*",
"@affine/templates": "workspace:*",
"@blocksuite/lit": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/presets": "0.11.0-nightly-202312220916-e3abcbb",
"@testing-library/react": "^14.0.0",
"@blocksuite/lit": "0.11.0-nightly-202401020419-752a5b8",
"@blocksuite/presets": "0.11.0-nightly-202401020419-752a5b8",
"async-call-rpc": "^6.3.1",
"electron": "link:../../frontend/electron/node_modules/electron",
"nanoid": "^5.0.3",
"react": "^18.2.0",
"rxjs": "^7.8.1",
"vite": "^5.0.6",
"vite-plugin-dts": "3.6.0",
"vitest": "1.0.4",
"vite-plugin-dts": "3.7.0",
"vitest": "1.1.1",
"yjs": "^13.6.10"
},
"peerDependencies": {

View File

@@ -1,3 +0,0 @@
/* eslint-disable */
// @ts-ignore
export * from '../dist/src/preload/electron';

View File

@@ -1,3 +0,0 @@
/* eslint-disable */
/// <reference types="../dist/preload/electron.d.ts" />
export * from '../dist/preload/electron.js';

View File

@@ -1,18 +0,0 @@
{
"name": "infra",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"sourceRoot": "packages/common/src",
"targets": {
"build": {
"executor": "nx:run-script",
"dependsOn": ["^build"],
"inputs": ["{projectRoot}/**/*"],
"options": {
"script": "build"
},
"outputs": ["{projectRoot}/dist"]
}
},
"tags": ["infra"]
}

View File

@@ -1,53 +0,0 @@
import type { CallbackMap } from '@affine/sdk/entry';
import { assertExists } from '@blocksuite/global/utils';
import { atomWithStorage } from 'jotai/utils';
import { atom } from 'jotai/vanilla';
import type { z } from 'zod';
import type { packageJsonOutputSchema } from '../type.js';
export const builtinPluginPaths = new Set(runtimeConfig.builtinPlugins);
const pluginCleanupMap = new Map<string, Set<() => void>>();
export function addCleanup(
pluginName: string,
cleanup: () => void
): () => void {
if (!pluginCleanupMap.has(pluginName)) {
pluginCleanupMap.set(pluginName, new Set());
}
const cleanupSet = pluginCleanupMap.get(pluginName);
assertExists(cleanupSet);
cleanupSet.add(cleanup);
return () => {
cleanupSet.delete(cleanup);
};
}
export function invokeCleanup(pluginName: string) {
pluginCleanupMap.get(pluginName)?.forEach(cleanup => cleanup());
pluginCleanupMap.delete(pluginName);
}
export const pluginPackageJson = atom<
z.infer<typeof packageJsonOutputSchema>[]
>([]);
export const enabledPluginAtom = atomWithStorage('affine-enabled-plugin', [
'@affine/image-preview-plugin',
]);
export const pluginHeaderItemAtom = atom<
Record<string, CallbackMap['headerItem']>
>({});
export const pluginSettingAtom = atom<Record<string, CallbackMap['setting']>>(
{}
);
export const pluginEditorAtom = atom<Record<string, CallbackMap['editor']>>({});
export const pluginWindowAtom = atom<
Record<string, (root: HTMLElement) => () => void>
>({});

View File

@@ -1,6 +1,2 @@
import { atom } from 'jotai';
export const loadedPluginNameAtom = atom<string[]>([]);
export * from './root-store';
export * from './settings';

View File

@@ -72,12 +72,13 @@ const appSettingEffect = atomEffect(get => {
// some values in settings should be synced into electron side
if (environment.isDesktop) {
console.log('set config', settings);
window.apis?.updater
// this api type in @affine/electron-api, but it is circular dependency this package, use any here
(window as any).apis?.updater
.setConfig({
autoCheckUpdate: settings.autoCheckUpdate,
autoDownloadUpdate: settings.autoDownloadUpdate,
})
.catch(err => {
.catch((err: any) => {
console.error(err);
});
}

View File

@@ -1,10 +1,17 @@
import { assertExists } from '@blocksuite/global/utils';
import type { Page, PageMeta, Workspace } from '@blocksuite/store';
import type {
JobMiddleware,
Page,
PageMeta,
PageSnapshot,
Workspace,
WorkspaceInfoSnapshot,
} from '@blocksuite/store';
import { Job } from '@blocksuite/store';
import type { createStore, WritableAtom } from 'jotai/vanilla';
import { nanoid } from 'nanoid';
import { Map as YMap } from 'yjs';
import { getLatestVersions } from '../migration/blocksuite';
import { replaceIdMiddleware } from './middleware';
export async function initEmptyPage(page: Page, title?: string) {
await page.load(() => {
@@ -22,7 +29,10 @@ export async function initEmptyPage(page: Page, title?: string) {
*/
export async function buildShowcaseWorkspace(
workspace: Workspace,
options: {
{
store,
atoms,
}: {
atoms: {
pageMode: WritableAtom<
undefined,
@@ -33,239 +43,72 @@ export async function buildShowcaseWorkspace(
store: ReturnType<typeof createStore>;
}
) {
const prototypes = {
tags: {
options: [
{
id: 'icg1n5UdkP',
value: 'Travel',
color: 'var(--affine-tag-gray)',
},
{
id: 'Oe5dSe1DDJ',
value: 'Quick summary',
color: 'var(--affine-tag-green)',
},
{
id: 'g1L5dXKctL',
value: 'OKR',
color: 'var(--affine-tag-purple)',
},
{
id: 'q3mceOl_zi',
value: 'Streamline your workflow',
color: 'var(--affine-tag-teal)',
},
{
id: 'ze07JVwBu4',
value: 'Plan',
color: 'var(--affine-tag-teal)',
},
{
id: '8qcYPCTK0h',
value: 'Review',
color: 'var(--affine-tag-orange)',
},
{
id: 'wg-fBtd2eI',
value: 'Engage',
color: 'var(--affine-tag-pink)',
},
{
id: 'QYFD_HeQc-',
value: 'Create',
color: 'var(--affine-tag-blue)',
},
{
id: 'ZHBa2NtdSo',
value: 'Learn',
color: 'var(--affine-tag-yellow)',
},
],
},
};
workspace.meta.setProperties(prototypes);
const edgelessPage1 = nanoid();
const { store, atoms } = options;
store.set(atoms.pageMode, edgelessPage1, 'edgeless');
const { onboarding } = await import('@affine/templates');
const pageMetas = {
'9f6f3c04-cf32-470c-9648-479dc838f10e': {
createDate: 1691548231530,
tags: ['ZHBa2NtdSo', 'QYFD_HeQc-', 'wg-fBtd2eI'],
updatedDate: 1691676331623,
favorite: true,
jumpOnce: true,
},
'0773e198-5de0-45d4-a35e-de22ea72b96b': {
createDate: 1691548220794,
tags: [],
updatedDate: 1691676775642,
favorite: false,
},
'59b140eb-4449-488f-9eeb-42412dcc044e': {
createDate: 1691551731225,
tags: [],
updatedDate: 1691654611175,
favorite: false,
},
'7217fbe2-61db-4a91-93c6-ad5c800e5a43': {
createDate: 1691552082822,
tags: [],
updatedDate: 1691654606912,
favorite: false,
},
'6eb43ea8-8c11-456d-bb1d-5193937961ab': {
createDate: 1691552090989,
tags: [],
updatedDate: 1691646748171,
favorite: false,
},
'3ddc8a4f-62c7-4fd4-8064-9ed9f61e437a': {
createDate: 1691564303138,
tags: [],
updatedDate: 1691646845195,
},
'22163830-8252-43fe-b62d-fd9bbeaa4caa': {
createDate: 1691574859042,
tags: [],
updatedDate: 1691648159371,
},
'b7a9e1bc-e205-44aa-8dad-7e328269d00b': {
createDate: 1691575011078,
tags: ['8qcYPCTK0h'],
updatedDate: 1691645074511,
favorite: false,
},
'646305d9-93e0-48df-bb92-d82944ceb5a3': {
createDate: 1691634722239,
tags: ['ze07JVwBu4'],
updatedDate: 1691647069662,
favorite: false,
},
'0350509d-8702-4797-b4d7-168f5e9359c7': {
createDate: 1691635388447,
tags: ['Oe5dSe1DDJ'],
updatedDate: 1691645873930,
},
'aa02af3c-5c5c-4856-b7ce-947ad17331f3': {
createDate: 1691636192263,
tags: ['q3mceOl_zi', 'g1L5dXKctL'],
updatedDate: 1691645102104,
},
} satisfies Record<string, Partial<PageMeta>>;
const data = [
[
'9f6f3c04-cf32-470c-9648-479dc838f10e',
import('@affine/templates/v1/getting-started.json'),
nanoid(),
],
[
'0773e198-5de0-45d4-a35e-de22ea72b96b',
import('@affine/templates/v1/preloading.json'),
edgelessPage1,
],
[
'59b140eb-4449-488f-9eeb-42412dcc044e',
import('@affine/templates/v1/template-galleries.json'),
nanoid(),
],
[
'7217fbe2-61db-4a91-93c6-ad5c800e5a43',
import('@affine/templates/v1/personal-home.json'),
nanoid(),
],
[
'6eb43ea8-8c11-456d-bb1d-5193937961ab',
import('@affine/templates/v1/working-home.json'),
nanoid(),
],
[
'3ddc8a4f-62c7-4fd4-8064-9ed9f61e437a',
import('@affine/templates/v1/personal-project-management.json'),
nanoid(),
],
[
'22163830-8252-43fe-b62d-fd9bbeaa4caa',
import('@affine/templates/v1/personal-knowledge-management.json'),
nanoid(),
],
[
'b7a9e1bc-e205-44aa-8dad-7e328269d00b',
import('@affine/templates/v1/annual-performance-review.json'),
nanoid(),
],
[
'646305d9-93e0-48df-bb92-d82944ceb5a3',
import('@affine/templates/v1/brief-event-planning.json'),
nanoid(),
],
[
'0350509d-8702-4797-b4d7-168f5e9359c7',
import('@affine/templates/v1/meeting-summary.json'),
nanoid(),
],
[
'aa02af3c-5c5c-4856-b7ce-947ad17331f3',
import('@affine/templates/v1/okr-template.json'),
nanoid(),
],
] as const;
const idMap = await Promise.all(data).then(async data => {
return data.reduce<Record<string, string>>(
(record, currentValue) => {
const [oldId, _, newId] = currentValue;
record[oldId] = newId;
return record;
},
{} as Record<string, string>
);
const info = onboarding['info.json'] as WorkspaceInfoSnapshot;
const migrationMiddleware: JobMiddleware = ({ slots, workspace }) => {
slots.afterImport.on(payload => {
if (payload.type === 'page') {
workspace.schema.upgradePage(
info?.pageVersion ?? 0,
info?.blockVersions ?? {},
payload.page.spaceDoc
);
}
});
};
const job = new Job({
workspace,
middlewares: [replaceIdMiddleware, migrationMiddleware],
});
// Import page one by one to prevent workspace meta race condition problem.
for (const [id, promise, newId] of data) {
const { default: template } = await promise;
let json = JSON.stringify(template);
Object.entries(idMap).forEach(([oldId, newId]) => {
json = json.replaceAll(oldId, newId);
});
json = JSON.parse(json);
await workspace
.importPageSnapshot(structuredClone(json), newId)
.catch(error => {
console.error('error importing page', id, error);
});
const page = workspace.getPage(newId);
assertExists(page);
await page.load();
workspace.schema.upgradePage(
0,
{
'affine:note': 1,
'affine:bookmark': 1,
'affine:database': 2,
'affine:divider': 1,
'affine:image': 1,
'affine:list': 1,
'affine:code': 1,
'affine:page': 2,
'affine:paragraph': 1,
'affine:surface': 3,
},
page.spaceDoc
);
}
job.snapshotToWorkspaceInfo(info);
// for now all onboarding assets are considered served via CDN
// hack assets so that every blob exists
// @ts-expect-error - rethinking API
job._assetsManager.writeToBlob = async () => {};
const pageSnapshots: PageSnapshot[] = Object.entries(onboarding)
.filter(([key]) => {
return key.endsWith('snapshot.json');
})
.map(([_, value]) => value as unknown as PageSnapshot);
await Promise.all(
pageSnapshots.map(snapshot => {
return job.snapshotToPage(snapshot);
})
);
// The showcase building will create multiple pages once, and may skip the version writing.
// https://github.com/toeverything/blocksuite/blob/master/packages/store/src/workspace/page.ts#L662
workspace.doc.getMap('meta').set('pageVersion', 2);
const newVersions = getLatestVersions(workspace.schema);
workspace.doc
.getMap('meta')
.set('blockVersions', new YMap(Object.entries(newVersions)));
Object.entries(pageMetas).forEach(([oldId, meta]) => {
const newId = idMap[oldId];
workspace.setPageMeta(newId, meta);
});
// todo: find better way to do the following
// perhaps put them into middleware?
{
// the "AFFiNE - not just a note-taking app" page should be set to edgeless mode
const edgelessPage1 = (workspace.meta.pages as PageMeta[])?.find(
p => p.title === 'AFFiNE - not just a note-taking app'
)?.id;
if (edgelessPage1) {
store.set(atoms.pageMode, edgelessPage1, 'edgeless');
}
// should jump to "Getting Started" by default
const gettingStartedPage = (workspace.meta.pages as PageMeta[])?.find(p =>
p.title.startsWith('Getting Started')
)?.id;
if (gettingStartedPage) {
workspace.setPageMeta(gettingStartedPage, {
jumpOnce: true,
});
}
}
}

View File

@@ -0,0 +1,142 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-restricted-imports */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
// @ts-nocheck
// TODO: remove this file after blocksuite exposed it
import type {
DatabaseBlockModel,
ListBlockModel,
ParagraphBlockModel,
} from '@blocksuite/blocks/dist/models.js';
import { assertExists } from '@blocksuite/global/utils';
import type { DeltaOperation, JobMiddleware } from '@blocksuite/store';
export const replaceIdMiddleware: JobMiddleware = ({ slots, workspace }) => {
const idMap = new Map<string, string>();
slots.afterImport.on(payload => {
if (
payload.type === 'block' &&
payload.snapshot.flavour === 'affine:database'
) {
const model = payload.model as DatabaseBlockModel;
Object.keys(model.cells).forEach(cellId => {
if (idMap.has(cellId)) {
model.cells[idMap.get(cellId)!] = model.cells[cellId];
delete model.cells[cellId];
}
});
}
// replace LinkedPage pageId with new id in paragraph blocks
if (
payload.type === 'block' &&
['affine:paragraph', 'affine:list'].includes(payload.snapshot.flavour)
) {
const model = payload.model as ParagraphBlockModel | ListBlockModel;
let prev = 0;
const delta: DeltaOperation[] = [];
for (const d of model.text.toDelta()) {
if (d.attributes?.reference?.pageId) {
if (prev > 0) {
delta.push({ retain: prev });
}
delta.push({
retain: d.insert.length,
attributes: {
reference: {
...d.attributes.reference,
pageId: idMap.get(d.attributes.reference.pageId)!,
},
},
});
prev = 0;
} else {
prev += d.insert.length;
}
}
if (delta.length > 0) {
model.text.applyDelta(delta);
}
}
});
slots.beforeImport.on(payload => {
if (payload.type === 'page') {
const newId = workspace.idGenerator('page');
idMap.set(payload.snapshot.meta.id, newId);
payload.snapshot.meta.id = newId;
return;
}
if (payload.type === 'block') {
const { snapshot } = payload;
if (snapshot.flavour === 'affine:page') {
const index = snapshot.children.findIndex(
c => c.flavour === 'affine:surface'
);
if (index !== -1) {
const [surface] = snapshot.children.splice(index, 1);
snapshot.children.push(surface);
}
}
const original = snapshot.id;
let newId: string;
if (idMap.has(original)) {
newId = idMap.get(original)!;
} else {
newId = workspace.idGenerator('block');
idMap.set(original, newId);
}
snapshot.id = newId;
if (snapshot.flavour === 'affine:surface') {
// Generate new IDs for images and frames in advance.
snapshot.children.forEach(child => {
const original = child.id;
if (idMap.has(original)) {
newId = idMap.get(original)!;
} else {
newId = workspace.idGenerator('block');
idMap.set(original, newId);
}
});
Object.entries(
snapshot.props.elements as Record<string, Record<string, unknown>>
).forEach(([_, value]) => {
switch (value.type) {
case 'connector': {
let connection = value.source as Record<string, string>;
if (idMap.has(connection.id)) {
const newId = idMap.get(connection.id);
assertExists(newId, 'reference id must exist');
connection.id = newId;
}
connection = value.target as Record<string, string>;
if (idMap.has(connection.id)) {
const newId = idMap.get(connection.id);
assertExists(newId, 'reference id must exist');
connection.id = newId;
}
break;
}
case 'group': {
const json = value.children.json as Record<string, unknown>;
Object.entries(json).forEach(([key, value]) => {
if (idMap.has(key)) {
delete json[key];
const newKey = idMap.get(key);
assertExists(newKey, 'reference id must exist');
json[newKey] = value;
}
});
break;
}
default:
break;
}
});
}
}
});
};

View File

@@ -1,74 +0,0 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 Andy Wermke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
export type EventMap = {
[key: string]: (...args: any[]) => void;
};
/**
* Type-safe event emitter.
*
* Use it like this:
*
* ```typescript
* type MyEvents = {
* error: (error: Error) => void;
* message: (from: string, content: string) => void;
* }
*
* const myEmitter = new EventEmitter() as TypedEmitter<MyEvents>;
*
* myEmitter.emit("error", "x") // <- Will catch this type error;
* ```
*
* Lifecycle:
* invoke -> handle -> emit -> on/once
*/
export interface TypedEventEmitter<Events extends EventMap> {
addListener<E extends keyof Events>(event: E, listener: Events[E]): this;
on<E extends keyof Events>(event: E, listener: Events[E]): this;
once<E extends keyof Events>(event: E, listener: Events[E]): this;
off<E extends keyof Events>(event: E, listener: Events[E]): this;
removeAllListeners<E extends keyof Events>(event?: E): this;
removeListener<E extends keyof Events>(event: E, listener: Events[E]): this;
emit<E extends keyof Events>(
event: E,
...args: Parameters<Events[E]>
): boolean;
// The sloppy `eventNames()` return type is to mitigate type incompatibilities - see #5
eventNames(): (keyof Events | string | symbol)[];
rawListeners<E extends keyof Events>(event: E): Events[E][];
listeners<E extends keyof Events>(event: E): Events[E][];
listenerCount<E extends keyof Events>(event: E): number;
handle<E extends keyof Events>(event: E, handler: Events[E]): this;
invoke<E extends keyof Events>(
event: E,
...args: Parameters<Events[E]>
): Promise<ReturnType<Events[E]>>;
getMaxListeners(): number;
setMaxListeners(maxListeners: number): this;
}

View File

@@ -1,57 +0,0 @@
import type {
ClipboardHandlers,
ConfigStorageHandlers,
DBHandlers,
DebugHandlers,
DialogHandlers,
ExportHandlers,
UIHandlers,
UpdaterHandlers,
WorkspaceHandlers,
} from './type.js';
import { HandlerManager } from './type.js';
export abstract class DBHandlerManager extends HandlerManager<
'db',
DBHandlers
> {}
export abstract class DebugHandlerManager extends HandlerManager<
'debug',
DebugHandlers
> {}
export abstract class DialogHandlerManager extends HandlerManager<
'dialog',
DialogHandlers
> {}
export abstract class UIHandlerManager extends HandlerManager<
'ui',
UIHandlers
> {}
export abstract class ClipboardHandlerManager extends HandlerManager<
'clipboard',
ClipboardHandlers
> {}
export abstract class ExportHandlerManager extends HandlerManager<
'export',
ExportHandlers
> {}
export abstract class UpdaterHandlerManager extends HandlerManager<
'updater',
UpdaterHandlers
> {}
export abstract class WorkspaceHandlerManager extends HandlerManager<
'workspace',
WorkspaceHandlers
> {}
export abstract class ConfigStorageHandlerManager extends HandlerManager<
'configStorage',
ConfigStorageHandlers
> {}

View File

@@ -1,2 +1,4 @@
export * from './handler.js';
export * from './type.js';
export * from './app-config-storage';
export * from './atom';
export * from './blocksuite';
export * from './command';

View File

@@ -1,285 +0,0 @@
import type Buffer from 'buffer';
import { z } from 'zod';
import type { AppConfigSchema } from './app-config-storage.js';
import type { TypedEventEmitter } from './core/event-emitter.js';
type Buffer = Buffer.Buffer;
export const packageJsonInputSchema = z.object({
name: z.string(),
version: z.string(),
description: z.string(),
affinePlugin: z.object({
release: z.union([z.boolean(), z.enum(['development'])]),
entry: z.object({
core: z.string(),
}),
}),
});
export const packageJsonOutputSchema = z.object({
name: z.string(),
version: z.string(),
description: z.string(),
affinePlugin: z.object({
release: z.union([z.boolean(), z.enum(['development'])]),
entry: z.object({
core: z.string(),
}),
assets: z.array(z.string()),
}),
});
export abstract class HandlerManager<
Namespace extends string,
Handlers extends Record<string, PrimitiveHandlers>,
> {
static instance: HandlerManager<string, Record<string, PrimitiveHandlers>>;
private readonly _app: App<Namespace, Handlers>;
private readonly _namespace: Namespace;
private _handlers: Handlers;
constructor() {
throw new Error('Method not implemented.');
}
private _initialized = false;
registerHandlers(handlers: Handlers) {
if (this._initialized) {
throw new Error('Already initialized');
}
this._handlers = handlers;
for (const [name, handler] of Object.entries(this._handlers)) {
this._app.handle(`${this._namespace}:${name}`, (async (...args: any[]) =>
handler(...args)) as any);
}
this._initialized = true;
}
invokeHandler<K extends keyof Handlers>(
name: K,
...args: Parameters<Handlers[K]>
): Promise<ReturnType<Handlers[K]>> {
return this._handlers[name](...args);
}
static getInstance(): HandlerManager<
string,
Record<string, PrimitiveHandlers>
> {
throw new Error('Method not implemented.');
}
}
export interface WorkspaceMeta {
id: string;
mainDBPath: string;
secondaryDBPath?: string; // assume there will be only one
}
export type PrimitiveHandlers = (...args: any[]) => Promise<any>;
export type DBHandlers = {
getDocAsUpdates: (
workspaceId: string,
subdocId?: string
) => Promise<Uint8Array | false>;
applyDocUpdate: (
id: string,
update: Uint8Array,
subdocId?: string
) => Promise<void>;
addBlob: (
workspaceId: string,
key: string,
data: Uint8Array
) => Promise<void>;
getBlob: (workspaceId: string, key: string) => Promise<Buffer | null>;
deleteBlob: (workspaceId: string, key: string) => Promise<void>;
getBlobKeys: (workspaceId: string) => Promise<string[]>;
getDefaultStorageLocation: () => Promise<string>;
};
export type DebugHandlers = {
revealLogFile: () => Promise<string>;
logFilePath: () => Promise<string>;
};
export type ErrorMessage =
| 'DB_FILE_ALREADY_LOADED'
| 'DB_FILE_PATH_INVALID'
| 'DB_FILE_INVALID'
| 'DB_FILE_MIGRATION_FAILED'
| 'FILE_ALREADY_EXISTS'
| 'UNKNOWN_ERROR';
export interface LoadDBFileResult {
workspaceId?: string;
error?: ErrorMessage;
canceled?: boolean;
}
export interface SaveDBFileResult {
filePath?: string;
canceled?: boolean;
error?: ErrorMessage;
}
export interface SelectDBFileLocationResult {
filePath?: string;
error?: ErrorMessage;
canceled?: boolean;
}
export interface MoveDBFileResult {
filePath?: string;
error?: ErrorMessage;
canceled?: boolean;
}
// provide a backdoor to set dialog path for testing in playwright
export interface FakeDialogResult {
canceled?: boolean;
filePath?: string;
filePaths?: string[];
}
export type DialogHandlers = {
revealDBFile: (workspaceId: string) => Promise<void>;
loadDBFile: () => Promise<LoadDBFileResult>;
saveDBFileAs: (workspaceId: string) => Promise<SaveDBFileResult>;
moveDBFile: (
workspaceId: string,
dbFileLocation?: string
) => Promise<MoveDBFileResult>;
selectDBFileLocation: () => Promise<SelectDBFileLocationResult>;
setFakeDialogResult: (result: any) => Promise<void>;
};
export type UIHandlers = {
handleThemeChange: (theme: 'system' | 'light' | 'dark') => Promise<any>;
handleSidebarVisibilityChange: (visible: boolean) => Promise<any>;
handleMinimizeApp: () => Promise<any>;
handleMaximizeApp: () => Promise<any>;
handleCloseApp: () => Promise<any>;
getGoogleOauthCode: () => Promise<any>;
getChallengeResponse: (resource: string) => Promise<string>;
handleOpenMainApp: () => Promise<any>;
};
export type ClipboardHandlers = {
copyAsImageFromString: (dataURL: string) => Promise<void>;
};
export type ExportHandlers = {
savePDFFileAs: (title: string) => Promise<any>;
};
export interface UpdateMeta {
version: string;
allowAutoUpdate: boolean;
}
export type UpdaterConfig = {
autoCheckUpdate: boolean;
autoDownloadUpdate: boolean;
};
export type UpdaterHandlers = {
currentVersion: () => Promise<string>;
quitAndInstall: () => Promise<void>;
downloadUpdate: () => Promise<void>;
getConfig: () => Promise<UpdaterConfig>;
setConfig: (newConfig: Partial<UpdaterConfig>) => Promise<void>;
checkForUpdates: () => Promise<{ version: string } | null>;
};
export type WorkspaceHandlers = {
list: () => Promise<[workspaceId: string, meta: WorkspaceMeta][]>;
delete: (id: string) => Promise<void>;
getMeta: (id: string) => Promise<WorkspaceMeta>;
clone: (id: string, newId: string) => Promise<void>;
};
export type ConfigStorageHandlers = {
set: (config: AppConfigSchema | Partial<AppConfigSchema>) => Promise<void>;
get: () => Promise<AppConfigSchema>;
};
export type UnwrapManagerHandlerToServerSide<
ElectronEvent extends {
frameId: number;
processId: number;
},
Manager extends HandlerManager<string, Record<string, PrimitiveHandlers>>,
> = Manager extends HandlerManager<infer _, infer Handlers>
? {
[K in keyof Handlers]: Handlers[K] extends (
...args: infer Args
) => Promise<infer R>
? (event: ElectronEvent, ...args: Args) => Promise<R>
: never;
}
: never;
export type UnwrapManagerHandlerToClientSide<
Manager extends HandlerManager<string, Record<string, PrimitiveHandlers>>,
> = Manager extends HandlerManager<infer _, infer Handlers>
? {
[K in keyof Handlers]: Handlers[K] extends (
...args: infer Args
) => Promise<infer R>
? (...args: Args) => Promise<R>
: never;
}
: never;
/**
* @internal
*/
export type App<
Namespace extends string,
Handlers extends Record<string, PrimitiveHandlers>,
> = TypedEventEmitter<{
[K in keyof Handlers as `${Namespace}:${K & string}`]: Handlers[K];
}>;
export interface UpdaterEvents {
onUpdateAvailable: (fn: (versionMeta: UpdateMeta) => void) => () => void;
onUpdateReady: (fn: (versionMeta: UpdateMeta) => void) => () => void;
onDownloadProgress: (fn: (progress: number) => void) => () => void;
}
export interface ApplicationMenuEvents {
onNewPageAction: (fn: () => void) => () => void;
}
export interface DBEvents {
onExternalUpdate: (
fn: (update: {
workspaceId: string;
update: Uint8Array;
docId?: string;
}) => void
) => () => void;
}
export interface WorkspaceEvents {
onMetaChange: (
fn: (workspaceId: string, meta: WorkspaceMeta) => void
) => () => void;
}
export interface UIEvents {
onMaximized: (fn: (maximized: boolean) => void) => () => void;
}
export interface EventMap {
updater: UpdaterEvents;
applicationMenu: ApplicationMenuEvents;
db: DBEvents;
ui: UIEvents;
workspace: WorkspaceEvents;
}

View File

@@ -4,13 +4,9 @@
"compilerOptions": {
"composite": true,
"noEmit": false,
"moduleResolution": "bundler",
"outDir": "lib"
},
"references": [
{
"path": "../sdk"
},
{
"path": "../env"
},

View File

@@ -0,0 +1,4 @@
{
"extends": ["../../../typedoc.base.json"],
"entryPoints": ["src/index.ts"]
}

View File

@@ -1,43 +0,0 @@
import { resolve } from 'node:path';
import { fileURLToPath } from 'url';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
const root = fileURLToPath(new URL('.', import.meta.url));
export default defineConfig({
build: {
minify: false,
lib: {
entry: {
blocksuite: resolve(root, 'src/blocksuite/index.ts'),
index: resolve(root, 'src/index.ts'),
atom: resolve(root, 'src/atom/index.ts'),
command: resolve(root, 'src/command/index.ts'),
type: resolve(root, 'src/type.ts'),
'core/event-emitter': resolve(root, 'src/core/event-emitter.ts'),
'preload/electron': resolve(root, 'src/preload/electron.ts'),
'app-config-storage': resolve(root, 'src/app-config-storage.ts'),
'__internal__/plugin': resolve(root, 'src/__internal__/plugin.ts'),
},
formats: ['es', 'cjs'],
name: 'AffineInfra',
},
rollupOptions: {
external: [
'electron',
'async-call-rpc',
'rxjs',
'zod',
'react',
'yjs',
'nanoid',
/^jotai/,
/^@blocksuite/,
/^@affine\/templates/,
],
},
},
plugins: [dts()],
});

View File

@@ -1,4 +0,0 @@
src/entry.d.ts
src/entry.d.ts.map
src/entry.js
src/entry.js.map

View File

@@ -1,37 +0,0 @@
{
"name": "@affine/sdk",
"version": "0.11.0",
"type": "module",
"scripts": {
"build": "vite build",
"dev": "vite build --watch"
},
"exports": {
"./entry": {
"types": "./dist/src/entry.d.ts",
"import": "./dist/entry.js",
"require": "./dist/entry.cjs"
},
"./server": {
"types": "./dist/src/server.d.ts",
"import": "./dist/server.js",
"require": "./dist/server.cjs"
}
},
"files": [
"dist"
],
"dependencies": {
"@blocksuite/block-std": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/blocks": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/global": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/presets": "0.11.0-nightly-202312220916-e3abcbb",
"@blocksuite/store": "0.11.0-nightly-202312220916-e3abcbb",
"jotai": "^2.5.1",
"zod": "^3.22.4"
},
"devDependencies": {
"vite": "^5.0.6",
"vite-plugin-dts": "3.6.0"
}
}

View File

@@ -1,22 +0,0 @@
{
"name": "sdk",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"sourceRoot": "packages/common/sdk/src",
"targets": {
"build": {
"executor": "@nx/vite:build",
"options": {
"outputPath": "packages/common/sdk/dist"
}
},
"serve": {
"executor": "@nx/vite:build",
"options": {
"outputPath": "packages/common/sdk/dist",
"watch": true
}
}
},
"tags": ["infra"]
}

View File

@@ -1,64 +0,0 @@
import type { BaseSelection } from '@blocksuite/block-std';
import type { AffineEditorContainer } from '@blocksuite/presets';
import type { Page } from '@blocksuite/store';
import type { Workspace } from '@blocksuite/store';
import type { Atom, getDefaultStore } from 'jotai/vanilla';
import type { WritableAtom } from 'jotai/vanilla/atom';
import type { FunctionComponent } from 'react';
export type Part = 'headerItem' | 'editor' | 'setting' | 'formatBar';
export type CallbackMap = {
headerItem: (root: HTMLElement) => () => void;
editor: (root: HTMLElement, editor: AffineEditorContainer) => () => void;
setting: (root: HTMLElement) => () => void;
formatBar: (
root: HTMLElement,
page: Page,
getBlockRange: () => BaseSelection[]
) => () => void;
};
export interface PluginContext {
register: <T extends Part>(part: T, callback: CallbackMap[T]) => void;
utils: {
PluginProvider: FunctionComponent; // make more clear
};
}
export type LayoutDirection = 'horizontal' | 'vertical';
export type LayoutNode = LayoutParentNode | string;
export type LayoutParentNode = {
direction: LayoutDirection;
splitPercentage: number; // 0 - 100
first: string;
second: LayoutNode;
maxWidth?: (number | undefined)[];
};
export type ExpectedLayout =
| {
direction: 'horizontal';
// the first element is always the editor
first: 'editor';
second: LayoutNode;
// the percentage should be greater than 70
splitPercentage: number;
}
| 'editor';
export declare const pushLayoutAtom: WritableAtom<
null,
| [
string,
(div: HTMLDivElement) => () => void,
{
maxWidth: (number | undefined)[];
},
]
| [string, (div: HTMLDivElement) => () => void],
void
>;
export declare const deleteLayoutAtom: WritableAtom<null, [string], void>;
export declare const currentWorkspaceAtom: Atom<Promise<Workspace>>;
export declare const rootStore: ReturnType<typeof getDefaultStore>;

View File

@@ -1,4 +0,0 @@
export interface ServerContext {
registerCommand: (command: string, fn: (...args: any[]) => any) => void;
unregisterCommand: (command: string) => void;
}

View File

@@ -1,12 +0,0 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true,
"outDir": "lib",
"noEmit": false
},
"include": ["vite.config.ts"]
}

View File

@@ -1,23 +0,0 @@
import { resolve } from 'node:path';
import { fileURLToPath } from 'url';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
const root = fileURLToPath(new URL('.', import.meta.url));
export default defineConfig({
build: {
minify: false,
lib: {
entry: {
entry: resolve(root, 'src/entry.ts'),
server: resolve(root, 'src/server.ts'),
},
},
rollupOptions: {
external: [/^jotai/, /^@blocksuite/, 'zod'],
},
},
plugins: [dts()],
});

View File

@@ -0,0 +1,24 @@
{
"name": "@affine/workspace",
"private": true,
"main": "./src/index.ts",
"exports": {
".": "./src/index.ts"
},
"peerDependencies": {
"@blocksuite/blocks": "*",
"@blocksuite/global": "*",
"@blocksuite/store": "*"
},
"dependencies": {
"@affine/debug": "workspace:*",
"@affine/env": "workspace:*",
"@toeverything/infra": "workspace:*",
"lodash-es": "^4.17.21",
"yjs": "^13.6.10"
},
"devDependencies": {
"vitest": "1.1.1"
},
"version": "0.11.0"
}

View File

@@ -0,0 +1,7 @@
export * from './engine';
export * from './factory';
export * from './global-schema';
export * from './list';
export * from './manager';
export * from './metadata';
export * from './workspace';

View File

@@ -7,7 +7,6 @@ import { applyUpdate, encodeStateAsUpdate } from 'yjs';
import type { BlobStorage } from '.';
import type { WorkspaceFactory } from './factory';
import { LOCAL_WORKSPACE_LOCAL_STORAGE_KEY } from './impl/local/consts';
import type { WorkspaceList } from './list';
import type { WorkspaceMetadata } from './metadata';
import { WorkspacePool } from './pool';
@@ -151,21 +150,6 @@ export class WorkspaceManager {
return factory.getWorkspaceBlob(metadata.id, blobKey);
}
/**
* a hack for directly add local workspace to workspace list
* Used after copying sqlite database file to appdata folder
*/
_addLocalWorkspace(id: string) {
const allWorkspaceIDs: string[] = JSON.parse(
localStorage.getItem(LOCAL_WORKSPACE_LOCAL_STORAGE_KEY) ?? '[]'
);
allWorkspaceIDs.push(id);
localStorage.setItem(
LOCAL_WORKSPACE_LOCAL_STORAGE_KEY,
JSON.stringify(allWorkspaceIDs)
);
}
private open(metadata: WorkspaceMetadata) {
logger.info(`open workspace [${metadata.flavour}] ${metadata.id} `);
const factory = this.factories.find(x => x.name === metadata.flavour);

Some files were not shown because too many files have changed in this diff Show More