Merge branch 'develop' into fix/more-accessibility

This commit is contained in:
TalonTheDragon 2023-06-03 12:42:20 +02:00
commit 3d951c7f4b
304 changed files with 10206 additions and 2617 deletions

View file

@ -2,32 +2,31 @@
# Calckey configuration
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# After starting your server, please don't change the URL! Doing so will break federation.
# ┌─────┐
#───┘ URL └─────────────────────────────────────────────────────
# Final accessible URL seen by a user.
url: https://example.tld/
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# URL SETTINGS AFTER THAT!
url: https://example.com/
# ┌───────────────────────┐
#───┘ Port and TLS settings └───────────────────────────────────
#
# Misskey requires a reverse proxy to support HTTPS connections.
# Calckey requires a reverse proxy to support HTTPS connections.
#
# +----- https://example.tld/ ------------+
# +----- https://example.com/ ------------+
# +------+ |+-------------+ +----------------+|
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
# | User | ---> || Proxy (443) | ---> | Calckey (3000) ||
# +------+ |+-------------+ +----------------+|
# +---------------------------------------+
#
# You need to set up a reverse proxy. (e.g. nginx)
# You need to set up a reverse proxy. (e.g. nginx, caddy)
# An encrypted connection with HTTPS is highly recommended
# because tokens may be transferred in GET requests.
# The port that your Misskey server should listen on.
# The port that your Calckey server should listen on.
port: 3000
# ┌──────────────────────────┐
@ -62,6 +61,17 @@ redis:
#prefix: example-prefix
#db: 1
# Please configure either MeiliSearch *or* Sonic.
# If both MeiliSearch and Sonic configurations are present, MeiliSearch will take precedence.
# ┌───────────────────────────┐
#───┘ MeiliSearch configuration └─────────────────────────────────────
#meilisearch:
# host: meilisearch
# port: 7700
# ssl: false
# apiKey:
# ┌─────────────────────┐
#───┘ Sonic configuration └─────────────────────────────────────
@ -72,41 +82,29 @@ redis:
# collection: notes
# bucket: default
# ┌─────────────────────────────┐
#───┘ Elasticsearch configuration └─────────────────────────────
#elasticsearch:
# host: localhost
# port: 9200
# ssl: false
# user:
# pass:
# ┌───────────────┐
#───┘ ID generation └───────────────────────────────────────────
# You can select the ID generation method.
# You don't usually need to change this setting, but you can
# change it according to your preferences.
# No need to uncomment in most cases, but you may want to change
# these settings if you plan to run a large and/or distributed server.
# Available methods:
# aid ... Short, Millisecond accuracy
# meid ... Similar to ObjectID, Millisecond accuracy
# ulid ... Millisecond accuracy
# objectid ... This is left for backward compatibility
# cuid:
# # Min 16, Max 24
# length: 16
#
# # Set this to a unique string across workers (e.g., machine's hostname)
# # if your workers are running in multiple hosts.
# fingerprint: my-fingerprint
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# ID SETTINGS AFTER THAT!
id: 'aid'
# ┌─────────────────────┐
#───┘ Other configuration └─────────────────────────────────────
# Max note length, should be < 8000.
# Maximum length of a post (default 3000, max 8192)
#maxNoteLength: 3000
# Maximum lenght of an image caption or file comment (default 1500, max 8192)
# Maximum length of an image caption (default 1500, max 8192)
#maxCaptionLength: 1500
# Reserved usernames that only the administrator can register with
@ -180,13 +178,21 @@ reservedUsernames: [
# Upload or download file size limits (bytes)
#maxFileSize: 262144000
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Congrats, you've reached the end of the config file needed for most deployments!
# Enjoy your Calckey server!
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Managed hosting settings
# !!!!!!!!!!
# >>>>>> NORMAL SELF-HOSTERS, STAY AWAY! <<<<<<
# >>>>>> YOU DON'T NEED THIS! <<<<<<
# !!!!!!!!!!
# >>> NORMAL SELF-HOSTERS, STAY AWAY! <<<
# >>> YOU DON'T NEED THIS! <<<
# Each category is optional, but if each item in each category is mandatory!
# If you mess this up, that's on you, you've been warned...
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#maxUserSignups: 100
#isManagedHosting: true

4
.envrc
View file

@ -1,4 +1,4 @@
if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs="
if ! has nix_direnv_version || ! nix_direnv_version 2.3.0; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8="
fi
use flake . --impure

View file

@ -1 +1 @@
v16.15.0
v18.16.0

View file

@ -11,7 +11,7 @@
- Federate with note edits
- User "choices" (recommended users) like Mastodon and Soapbox
- Join Reason system like Mastodon/Pleroma
- Option to publicize instance blocks
- Option to publicize server blocks
- Build flag to remove NSFW/AI stuff
- Filter notifications by user
- Exclude self from antenna
@ -19,7 +19,7 @@
- MFM button
- Personal notes for all accounts
- Fully revamp non-logged-in screen
- Lookup/details for post/file/instance
- Lookup/details for post/file/server
- [Rat mode?](https://stop.voring.me/notes/933fx97bmd)
## Work in progress
@ -43,7 +43,7 @@
- Upgrade packages with security vunrabilities
- Saner defaults
- Fediverse account migration
- Recommended instances timeline
- Recommended servers timeline
- OCR image captioning
- Improve mobile UX
- Swipe through pages on mobile
@ -71,7 +71,7 @@
- Better welcome screen (not logged in)
- vue-plyr as video/audio player
- Ability to turn off "Connection lost" message
- Raw instance info only for moderators
- Raw server info only for moderators
- New spinner animation
- Spinner instead of "Loading..."
- SearchX instead of Google
@ -98,7 +98,7 @@
- Obliteration of Ai-chan
- Switch to [Calckey.js](https://codeberg.org/calckey/calckey.js)
- Woozy mode 🥴
- Improve blocking instances
- Improve blocking servers
- Release notes
- New post style
- Admins set default reaction emoji
@ -117,7 +117,7 @@
- Sonic search
- Popular color schemes, including Nord, Gruvbox, and Catppuccin
- Non-nyaify cat mode
- Post imports from other Calckey/Misskey/Mastodon/Pleroma/Akkoma instances
- Post imports from other Calckey/Misskey/Mastodon/Pleroma/Akkoma servers
- Improve Classic mode
- Proper Helm/Kubernetes config
- Multiple boost visibilities

View file

@ -3,6 +3,7 @@ FROM node:19-alpine as build
WORKDIR /calckey
# Install compilation dependencies
RUN apk update
RUN apk add --no-cache --no-progress git alpine-sdk python3 rust cargo vips
# Copy only the dependency-related files first, to cache efficiently

View file

@ -23,15 +23,15 @@
# ✨ About Calckey
- Calckey is based off of Misskey, a powerful microblogging server on ActivityPub with features such as emoji reactions, a customizable web UI, rich chatting, and much more!
- Calckey adds many quality of life changes and bug fixes for users and instance admins alike.
- Calckey adds many quality of life changes and bug fixes for users and server admins alike.
- Read **[this document](./CALCKEY.md)** all for current and future differences.
- Notable differences:
- Improved UI/UX (especially on mobile)
- Improved notifications
- Improved instance security
- Improved server security
- Improved accessibility
- Improved threads
- Recommended Instances timeline
- Recommended Servers timeline
- OCR image captioning
- New and improved Groups
- Better intro tutorial
@ -50,10 +50,10 @@
- 💸 OpenCollective: <https://opencollective.com/Calckey>
- 💸 Liberapay: <https://liberapay.com/ThatOneCalculator>
- Donate publicly to get your name on the Patron list!
- 🚢 Flagship instance: <https://calckey.social>
- 🚢 Flagship server: <https://calckey.social>
- 📣 Official account: <https://i.calckey.cloud/@calckey>
- 💁 Matrix support room: <https://matrix.to/#/#calckey:matrix.fedibird.com>
- 📜 Instance list: <https://calckey.fediverse.observer/list>
- 📜 Server list: <https://calckey.fediverse.observer/list>
- 📖 JoinFediverse Wiki: <https://joinfediverse.wiki/What_is_Calckey%3F>
- 🐋 Docker Hub: <https://hub.docker.com/r/thatonecalculator/calckey>
- ✍️ Weblate: <https://hosted.weblate.org/engage/calckey/>
@ -76,10 +76,10 @@ If you have access to a server that supports one of the sources below, I recomme
## 🧑‍💻 Dependencies
- 🐢 At least [NodeJS](https://nodejs.org/en/) v18.12.1 (v19 recommended)
- 🐢 At least [NodeJS](https://nodejs.org/en/) v18.16.0 (v20 recommended)
- Install with [nvm](https://github.com/nvm-sh/nvm)
- 🐘 At least [PostgreSQL](https://www.postgresql.org/) v12
- 🍱 At least [Redis](https://redis.io/) v6 (v7 recommend)
- 🐘 At least [PostgreSQL](https://www.postgresql.org/) v12 (v14 recommended)
- 🍱 At least [Redis](https://redis.io/) v6 (v7 recommended)
- Web Proxy (one of the following)
- 🍀 Nginx (recommended)
- 🦦 Caddy
@ -89,7 +89,8 @@ If you have access to a server that supports one of the sources below, I recomme
- [FFmpeg](https://ffmpeg.org/) for video transcoding
- Full text search (one of the following)
- 🦔 [Sonic](https://crates.io/crates/sonic-server) (recommended)
- 🦔 [Sonic](https://crates.io/crates/sonic-server)
- [MeiliSearch](https://www.meilisearch.com/)
- [ElasticSearch](https://www.elastic.co/elasticsearch/)
### 🏗️ Build dependencies
@ -103,7 +104,7 @@ If you have access to a server that supports one of the sources below, I recomme
## 👀 Get folder ready
```sh
git clone --depth 1 https://codeberg.org/calckey/calckey.git
git clone https://codeberg.org/calckey/calckey.git
cd calckey/
```
@ -148,7 +149,11 @@ psql postgres -c "create database calckey with encoding = 'UTF8';"
In Calckey's directory, fill out the `db` section of `.config/default.yml` with the correct information, where the `db` key is `calckey`.
## 🦔 Set up search
## 🔎 Set up search
### 🦔 Sonic
Sonic is better suited for self hosters with smaller deployments. It's easier to use, uses almost no resources, and takes barely any any disk space.
Follow sonic's [installation guide](https://github.com/valeriansaliou/sonic#installation)
@ -157,17 +162,28 @@ Follow sonic's [installation guide](https://github.com/valeriansaliou/sonic#inst
In Calckey's directory, fill out the `sonic` section of `.config/default.yml` with the correct information.
### Meilisearch
Meilisearch is better suited for larger deployments. It's faster but uses far more resources and disk space.
Follow Meilisearch's [quick start guide](https://www.meilisearch.com/docs/learn/getting_started/quick_start)
In Calckey's directory, fill out the `meilisearch` section of `.config/default.yml` with the correct information.
### ElasticSearch
Please don't use ElasticSearch unless you already have an ElasticSearch setup and want to continue using it for Calckey. ElasticSearch is slow, heavy, and offers very few benefits over Sonic/Meilisearch.
## 💅 Customize
- To add custom CSS for all users, edit `./custom/assets/instance.css`.
- To add static assets (such as images for the splash screen), place them in the `./custom/assets/` directory. They'll then be available on `https://yourinstance.tld/static-assets/filename.ext`.
- To add static assets (such as images for the splash screen), place them in the `./custom/assets/` directory. They'll then be available on `https://yourserver.tld/static-assets/filename.ext`.
- To add custom locales, place them in the `./custom/locales/` directory. If you name your custom locale the same as an existing locale, it will overwrite it. If you give it a unique name, it will be added to the list. Also make sure that the first part of the filename matches the locale you're basing it on. (Example: `en-FOO.yml`)
- To add custom error images, place them in the `./custom/assets/badges` directory, replacing the files already there.
- To add custom sounds, place only mp3 files in the `./custom/assets/sounds` directory.
- To update custom assets without rebuilding, just run `pnpm run gulp`.
## 🧑‍🔬 Configuring a new instance
## 🧑‍🔬 Configuring a new server
- Run `cp .config/example.yml .config/default.yml`
- Edit `.config/default.yml`, making sure to fill out required fields.
@ -182,7 +198,7 @@ For migrating from Misskey v13, Misskey v12, and Foundkey, read [this document](
### 🍀 Nginx (recommended)
- Run `sudo cp ./calckey.nginx.conf /etc/nginx/sites-available/ && cd /etc/nginx/sites-available/`
- Edit `calckey.nginx.conf` to reflect your instance properly
- Edit `calckey.nginx.conf` to reflect your server properly
- Run `sudo ln -s ./calckey.nginx.conf ../sites-enabled/calckey.nginx.conf`
- Run `sudo nginx -t` to validate that the config is valid, then restart the NGINX service.
@ -202,7 +218,7 @@ example.tld {
> Apache has some known problems with Calckey. Only use it if you have to.
- Run `sudo cp ./calckey.apache.conf /etc/apache2/sites-available/ && cd /etc/apache2/sites-available/`
- Edit `calckey.apache.conf` to reflect your instance properly
- Edit `calckey.apache.conf` to reflect your server properly
- Run `sudo a2ensite calckey.apache` to enable the site
- Run `sudo service apache2 restart` to reload apache2 configuration
## 🚀 Build and launch!

View file

@ -8,7 +8,7 @@ services:
depends_on:
- db
- redis
- sonic
- meilisearch
ports:
- "3000:3000"
networks:
@ -40,17 +40,33 @@ services:
volumes:
- ./db:/var/lib/postgresql/data
sonic:
restart: unless-stopped
image: docker.io/valeriansaliou/sonic:v1.4.0
networks:
- calcnet
volumes:
- ./sonic:/var/lib/sonic/store
- ./sonic/config.cfg:/etc/sonic.cfg
### Only one of the below should be used.
### Meilisearch is better overall, but resource-intensive. Sonic is a very light full text search engine.
# meilisearch:
# container_name: meilisearch
# image: getmeili/meilisearch:v1.1.1
# environment:
# - MEILI_ENV=${MEILI_ENV:-development}
# ports:
# - "7700:7700"
# networks:
# - calcnet
# volumes:
# - ./meili_data:/meili_data
# restart: unless-stopped
# sonic:
# restart: unless-stopped
# image: docker.io/valeriansaliou/sonic:v1.4.0
# networks:
# - calcnet
# volumes:
# - ./sonic:/var/lib/sonic/store
# - ./sonic/config.cfg:/etc/sonic.cfg
networks:
calcnet:
# web:
# external:
# name: web
# web:
# external:
# name: web

View file

@ -7,8 +7,8 @@ Please note, however, that this environment will not work on Windows outside of
### Prerequisites
- Installed the [Nix Package Manager](https://nixos.org/download.html)
- Installed [direnv](https://direnv.net/docs/installation.html) and added its hook to your shell.
- Installed the [Nix Package Manager](https://nixos.org/download.html) (use the comman on their website)
- Installed [direnv](https://direnv.net/docs/installation.html) and added its hook to your shell. (package manager)
Once the repo is cloned to your computer, follow these next few steps inside the Calckey folder:
@ -20,3 +20,89 @@ Once the repo is cloned to your computer, follow these next few steps inside the
- You should now see the admin user creation screen!
Note: When you want to restart a dev server, all you need to do is run `devenv up`, no other steps are necessary.
# Possible Troubles with the dev enviroment
(this doesn't have to be done under normal conditions, this is for future reference)
### direnv
If you have any trouble with `direnv allow`
Check that the contents of `.envrc` have the same version of nix-direnv that is specified here:
> nix-direnv under -> installation -> using direnv source url
> https://github.com/nix-community/nix-direnv#direnv-source_url
there should be no errors during `direnv allow`
### outdated nix packages
if `install-deps` or any subsequent command doesn't run due to versioning problems
`flake.nix` and `flake.lock` may be outdated
delete `flake.lock`, or better, run `nix flake update --extra-experimental-features flakes --extra-experimental-features nix-command`
after that, run `direnv rebuild`
if there are any errors, you might have to change `flake.nix`
(because the available options can change between versions - consider getting support in [the matrix channel](https://matrix.to/#/#calckey:matrix.fedibird.com))
### after changing a node version
in my case, i had to change the node version from 19, to 18
! before proceeding, make sure to delete all build artifacts!
remove `node_modules` and `built` folders, and maybe `.devenv` and `.direnv` as well
manually, or run `npm cache clean --force` and `pnpm cleanall`
### Windows Subsystem for Linux
if `devenv up` terminates because of wrong folder permissions,
create the file `/etc/wsl.conf` in your distro and add
```shell
[automount]
options = "metadata"
```
this allows `chmod` calls to actually have an effect.
the build scripts DO actually set the permissions, it just needs to work in wsl.
### devenv up
devenv up may take a looong time. (some say this is fake news, maybe it was bad luck in my case)
do not get spooked by this error:
```
> calckey@14.0.0-dev32 start /mnt/.../calckey
> pnpm --filter backend run start
> backend@ start /mnt/.../calckey/packages/backend
> pnpm node ./built/index.js
node:internal/modules/cjs/loader:1078
throw err;
^
Error: Cannot find module '/mnt/.../calckey/packages/backend/built/index.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
at Module._load (node:internal/modules/cjs/loader:920:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Node.js v18.16.0
undefined
/mnt/.../calckey/packages/backend:
ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL backend@ start: `pnpm node ./built/index.js`
Exit status 1
ELIFECYCLE Command failed with exit code 1.
```
the script is designed to constantly try to start the server, while the build is still running.
this just means that the build isn't finished yet.
at some point you should see a banner that says "Calckey" in big letters -
then you're good to go and can run `migrate` (in another terminal)!
if you don't see the banner,
and it's for some reason stuck on `Finished 'build' after 917 ms` for a view minutes,
just leave devenv running and open another terminal in the folder
run `migrate` and then `pnpm --filter backend run start` by yourself
the server should start

View file

@ -1,4 +1,4 @@
# 🐳 Running a Calckey instance with Docker
# 🐳 Running a Calckey server with Docker
## Pre-built docker container
[thatonecalculator/calckey](https://hub.docker.com/r/thatonecalculator/calckey)
@ -8,7 +8,7 @@
There is a `docker-compose.yml` in the root of the project that you can use to build the container from source
- .config/docker.env (**db config settings**)
- .config/default.yml (**calckey instance settings**)
- .config/default.yml (**calckey server settings**)
## Configuring
@ -20,7 +20,7 @@ Rename the files:
then edit them according to your environment.
You can configure `docker.env` with anything you like, but you will have to pay attention to the `default.yml` file:
- `url` should be set to the URL you will be hosting the web interface for the instance at.
- `url` should be set to the URL you will be hosting the web interface for the server at.
- `host`, `db`, `user`, `pass` will have to be configured in the `PostgreSQL configuration` section - `host` is the name of the postgres container (eg: *calckey_db_1*), and the others should match your `docker.env`.
- `host`will need to be configured in the *Redis configuration* section - it is the name of the redis container (eg: *calckey_redis_1*)
- `auth` will need to be configured in the *Sonic* section - cannot be the default `SecretPassword`
@ -36,7 +36,7 @@ Copy `docker-compose.yml` and the `config/` to a directory, then run the **docke
NOTE: This will take some time to come fully online, even after download and extracting the container images, and it may emit some error messages before completing successfully. Specifically, the `db` container needs to initialize and so isn't available to the `web` container right away. Only once the `db` container comes online does the `web` container start building and initializing the calckey tables.
Once the instance is up you can use a web browser to access the web interface at `http://serverip:3000` (where `serverip` is the IP of the server you are running the calckey instance on).
Once the server is up you can use a web browser to access the web interface at `http://serverip:3000` (where `serverip` is the IP of the server you are running the calckey server on).
## Docker for development

View file

@ -1,4 +1,4 @@
# Running a Calckey instance with Kubernetes and Helm
# Running a Calckey server with Kubernetes and Helm
This is a [Helm](https://helm.sh/) chart directory in the root of the project
that you can use to deploy calckey to a Kubernetes cluster
@ -27,7 +27,7 @@ helm upgrade \
-f .config/helm_values.yml
```
4. Watch your calckey instance spin up:
4. Watch your calckey server spin up:
```shell
kubectl -n calckey get po -w
```

View file

@ -8,11 +8,11 @@
"pre-commit-hooks": "pre-commit-hooks"
},
"locked": {
"lastModified": 1682953188,
"narHash": "sha256-MFH6yK7QnEV6+T96Pt++lH8ozDn4YqzaOXAS6u5h3mM=",
"lastModified": 1685521914,
"narHash": "sha256-0fdFP5IASLwJ0PSXrErW8PZon9TVYmi8VRF8OtjGkV4=",
"owner": "cachix",
"repo": "devenv",
"rev": "c388b8c57116a71174d26b09c0c38b4b6b5bac3a",
"rev": "e206d8f2e3e8d6aa943656052f15bdfea8146b8d",
"type": "github"
},
"original": {
@ -29,11 +29,11 @@
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1682922129,
"narHash": "sha256-qnhkfksuuSLbN5UJM+KSCMSRC13bXosr6Ed3NwerRno=",
"lastModified": 1685514167,
"narHash": "sha256-urRxF0ZGSNeZjM4kALNg3wTh7fBscbqQmS6S/HU7Wms=",
"owner": "nix-community",
"repo": "fenix",
"rev": "c1f90f80ba4d60bea60685dd4515fb22d53279cc",
"rev": "3abfea51663583186f687c49a157eab1639349ca",
"type": "github"
},
"original": {
@ -63,11 +63,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1680392223,
"narHash": "sha256-n3g7QFr85lDODKt250rkZj2IFS3i4/8HBU2yKHO3tqw=",
"lastModified": 1685457039,
"narHash": "sha256-bEFtQm+YyLxQjKQAaBHJyPN1z2wbhBnr2g1NJWSYjwM=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "dcc36e45d054d7bb554c9cdab69093debd91a0b5",
"rev": "80717d11615b6f42d1ad2e18ead51193fc15de69",
"type": "github"
},
"original": {
@ -155,11 +155,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1677534593,
"narHash": "sha256-PuZSAHeq4/9pP/uYH1FcagQ3nLm/DrDrvKi/xC9glvw=",
"lastModified": 1678875422,
"narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "3ad64d9e2d5bf80c877286102355b1625891ae9a",
"rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459",
"type": "github"
},
"original": {
@ -172,11 +172,11 @@
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1680213900,
"narHash": "sha256-cIDr5WZIj3EkKyCgj/6j3HBH4Jj1W296z7HTcWj1aMA=",
"lastModified": 1682879489,
"narHash": "sha256-sASwo8gBt7JDnOOstnps90K1wxmVfyhsTPPNTGBPjjg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e3652e0735fbec227f342712f180f4f21f0594f2",
"rev": "da45bf6ec7bbcc5d1e14d3795c025199f28e0de0",
"type": "github"
},
"original": {
@ -205,11 +205,11 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1673800717,
"narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
"lastModified": 1678872516,
"narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
"rev": "9b8e5abb18324c7fe9f07cb100c3cd4a29cda8b8",
"type": "github"
},
"original": {
@ -221,11 +221,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1682929865,
"narHash": "sha256-jxVrgnf5QNjO+XoxDxUWtN2G5xyJSGZ5SWDQFxMuHxc=",
"lastModified": 1685399834,
"narHash": "sha256-Lt7//5snriXSdJo5hlVcDkpERL1piiih0UXIz1RUcC4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "f2e9a130461950270f87630b11132323706b4d91",
"rev": "58c85835512b0db938600b6fe13cc3e3dc4b364e",
"type": "github"
},
"original": {
@ -250,11 +250,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1677160285,
"narHash": "sha256-tBzpCjMP+P3Y3nKLYvdBkXBg3KvTMo3gvi8tLQaqXVY=",
"lastModified": 1682596858,
"narHash": "sha256-Hf9XVpqaGqe/4oDGr30W8HlsWvJXtMsEPHDqHZA6dDg=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "2bd861ab81469428d9c823ef72c4bb08372dd2c4",
"rev": "fb58866e20af98779017134319b5663b8215d912",
"type": "github"
},
"original": {
@ -274,11 +274,11 @@
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1682886915,
"narHash": "sha256-FPQKPvlHIU2DsDF6GMoRtrZhil0vHi6MFd8vpKEx/n8=",
"lastModified": 1685465261,
"narHash": "sha256-aJ2nUinUrNcFi+pb47bS5IIAeSiUEEPLJY8W4Q8Pcjk=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "3a27518fee5a723005299cf49e2d58a842a261ca",
"rev": "d2b3caa5b5694125fad04a9699e919444439f6a2",
"type": "github"
},
"original": {

View file

@ -41,7 +41,7 @@
languages.typescript.enable = true;
# Enable javascript for NPM and PNPM
languages.javascript.enable = true;
languages.javascript.package = pkgs.nodejs_19;
languages.javascript.package = pkgs.nodejs_18;
# Enable stable Rust for the backend
languages.rust.enable = true;
languages.rust.version = "stable";

View file

@ -176,7 +176,6 @@ operations: "الإجراءات"
software: "البرمجية"
version: "الإصدار"
metadata: "البيانات الوصفية"
withNFiles: "{n} ملف (ملفات)"
monitor: "شاشة التحكم"
jobQueue: "قائمة الانتظار"
cpuAndMemory: "وحدة المعالجة المركزية والذاكرة"

View file

@ -177,7 +177,6 @@ operations: "ক্রিয়াকলাপ"
software: "সফটওয়্যার"
version: "সংস্করণ"
metadata: "মেটাডাটা"
withNFiles: "{n} টি ফাইল"
monitor: "মনিটর"
jobQueue: "জব কিউ"
cpuAndMemory: "সিপিউ এবং মেমরি"

View file

@ -791,7 +791,6 @@ selectUser: Selecciona un usuari
latestStatus: Últim estat
storageUsage: Ús del emmagatzematge
metadata: Metadades
withNFiles: '{n} fitxer(s)'
monitor: Seguiment
software: Programari
version: Versió
@ -1802,8 +1801,8 @@ pushNotificationNotSupported: El vostre navegador o servidor no admet notificaci
push
license: Llicència
indexPosts: Índex de notes
indexFrom: Índex a partir de l'ID de Publicacions (deixeu en blanc per indexar cada
publicació)
indexFrom: Índex a partir de l'ID de Publicacions
indexFromDescription: Deixeu en blanc per indexar cada publicació
indexNotice: Ara indexant. Això probablement trigarà una estona, si us plau, no reinicieu
el servidor durant almenys una hora.
_instanceTicker:

View file

@ -189,7 +189,6 @@ operations: "Operace"
software: "Software"
version: "Verze"
metadata: "Metadata"
withNFiles: "{n} soubor(ů)"
monitor: "Monitorovat"
jobQueue: "Fronta úloh"
cpuAndMemory: "CPU a paměť"

View file

@ -117,7 +117,6 @@ operations: Operationer
software: Software
metadata: Metadata
version: Version
withNFiles: '{n} fil(er)'
monitor: Vagt
jobQueue: Jobkø
statistics: Statistik

View file

@ -200,7 +200,6 @@ operations: "Tätigkeiten"
software: "Software"
version: "Version"
metadata: "Metadaten"
withNFiles: "{n} Datei(en)"
monitor: "Überwachung"
jobQueue: "Auftragswarteschlange"
cpuAndMemory: "CPU und Speicher"

View file

@ -435,7 +435,6 @@ nothing: Δεν υπάρχει τίποτα να δείτε εδώ
newNoteRecived: Υπάρχουν νέες δημοσιεύσεις
passwordMatched: Ταιριάζει
unmarkAsSensitive: Αναίρεση επισήμανσης ως Ευαίσθητο Περιεχόμενο (NSFW)
withNFiles: '{n} αρχείο(-α)'
blockedUsers: Μπλοκαρισμένα μέλη
noteDeleteConfirm: Θέλετε σίγουρα να διαγράψετε αυτή τη δημοσίευση;
preview: Προεπισκόπηση

View file

@ -5,6 +5,7 @@ introMisskey: "Welcome! Calckey is an open source, decentralized social media pl
\ that's free forever! \U0001F680"
monthAndDay: "{month}/{day}"
search: "Search"
searchPlaceholder: "Search Calckey"
notifications: "Notifications"
username: "Username"
password: "Password"
@ -82,6 +83,7 @@ exportRequested: "You've requested an export. This may take a while. It will be
\ to your Drive once completed."
importRequested: "You've requested an import. This may take a while."
lists: "Lists"
listsDesc: "Lists let you create timelines with specified users. They can be accessed from the timelines page."
noLists: "You don't have any lists"
note: "Post"
notes: "Posts"
@ -209,7 +211,6 @@ operations: "Operations"
software: "Software"
version: "Version"
metadata: "Metadata"
withNFiles: "{n} file(s)"
monitor: "Monitor"
jobQueue: "Job Queue"
cpuAndMemory: "CPU and Memory"
@ -404,6 +405,7 @@ avoidMultiCaptchaConfirm: "Using multiple Captcha systems may cause interference
\ them. Would you like to disable the other Captcha systems currently active? If\
\ you would like them to stay enabled, press cancel."
antennas: "Antennas"
antennasDesc: "Antennas display new posts matching the criteria you set!\n They can be accessed from the timelines page."
manageAntennas: "Manage Antennas"
name: "Name"
antennaSource: "Antenna source"
@ -595,6 +597,8 @@ scratchpadDescription: "The scratchpad provides an environment for AiScript expe
output: "Output"
script: "Script"
disablePagesScript: "Disable AiScript on Pages"
expandOnNoteClick: "Open post on click"
expandOnNoteClickDesc: "If disabled, you can still open posts in the right-click menu or by clicking the timestamp."
updateRemoteUser: "Update remote user information"
deleteAllFiles: "Delete all files"
deleteAllFilesConfirm: "Are you sure that you want to delete all files?"
@ -685,6 +689,7 @@ logs: "Logs"
delayed: "Delayed"
database: "Database"
channel: "Channels"
channelFederationWarn: "Channels do not yet federate to other servers"
create: "Create"
notificationSetting: "Notification settings"
notificationSettingDesc: "Select the types of notification to display."
@ -770,6 +775,7 @@ pageLikedCount: "Number of received Page likes"
contact: "Contact"
useSystemFont: "Use the system's default font"
clips: "Clips"
clipsDesc: "Clips are like share-able categorized bookmarks. You can create clips from the menu of individual posts."
experimentalFeatures: "Experimental features"
developer: "Developer"
makeExplorable: "Make account visible in \"Explore\""
@ -1064,7 +1070,8 @@ migrationConfirm: "Are you absolutely sure you want to migrate your account to {
defaultReaction: "Default emoji reaction for outgoing and incoming posts"
license: "License"
indexPosts: "Index Posts"
indexFrom: "Index from Post ID onwards (leave blank to index every post)"
indexFrom: "Index from Post ID onwards"
indexFromDescription: "Leave blank to index every post"
indexNotice: "Now indexing. This will probably take a while, please don't restart\
\ your server for at least an hour."
customKaTeXMacro: "Custom KaTeX macros"
@ -1445,7 +1452,7 @@ _tutorial:
\ you follow."
step5_4: "The Local {icon} timeline is where you can see posts from everyone else on this server."
step5_5: "The Social {icon} timeline is a combination of the Home and Local timelines."
step5_6: "The Recommended {icon} timeline is where you can see posts from server\
step5_6: "The Recommended {icon} timeline is where you can see posts from servers\
\ the admins recommend."
step5_7: "The Global {icon} timeline is where you can see posts from every other\
\ connected server."
@ -1526,30 +1533,35 @@ _weekday:
friday: "Friday"
saturday: "Saturday"
_widgets:
memo: "Sticky notes"
memo: "Sticky Notes"
notifications: "Notifications"
timeline: "Timeline"
calendar: "Calendar"
trends: "Trending"
clock: "Clock"
rss: "RSS reader"
rssTicker: "RSS-Ticker"
rss: "RSS Reader"
rssTicker: "RSS Ticker"
activity: "Activity"
photos: "Photos"
digitalClock: "Digital clock"
unixClock: "UNIX clock"
digitalClock: "Digital Clock"
unixClock: "UNIX Clock"
federation: "Federation"
instanceCloud: "Server cloud"
postForm: "Posting form"
instanceCloud: "Server Cloud"
postForm: "Posting Form"
slideshow: "Slideshow"
button: "Button"
onlineUsers: "Online users"
onlineUsers: "Online Users"
jobQueue: "Job Queue"
serverMetric: "Server metrics"
aiscript: "AiScript console"
userList: "User list"
serverMetric: "Server Metrics"
aiscript: "AiScript Console"
userList: "User List"
serverInfo: "Server Info"
_userList:
chooseList: "Select a list"
meiliStatus: "Server Status"
meiliSize: "Index size"
meiliIndexCount: "Indexed posts"
_cw:
hide: "Hide"
show: "Show content"
@ -2020,6 +2032,6 @@ _experiments:
postEditingCaption: "Shows the option for users to edit their existing posts via\
\ the post options menu."
enablePostImports: "Enable post imports"
postImportsDescription: "Allows users to import their posts from past Calckey,\
postImportsCaption: "Allows users to import their posts from past Calckey,\
\ Misskey, Mastodon, Akkoma, and Pleroma accounts. It may cause slowdowns during\
\ load if your queue is bottlenecked."

View file

@ -195,7 +195,6 @@ operations: "Operaciones"
software: "Software"
version: "Versión"
metadata: "Metadatos"
withNFiles: "{n} archivos"
monitor: "Monitor"
jobQueue: "Cola de trabajos"
cpuAndMemory: "CPU y Memoria"

View file

@ -182,7 +182,6 @@ followsYou: Seuraa sinua
pageLoadErrorDescription: Tämä yleensä johtuu verkkovirheistä tai selaimen välimuistista.
Kokeile tyhjentämällä välimuisti ja yritä sitten hetken kuluttua uudelleen.
enterListName: Anna listalle nimi
withNFiles: '{n} tiedosto(t)'
instanceInfo: Instanssin tiedot
clearQueue: Tyhjennä jono
suspendConfirm: Oletko varma, että haluat keskeyttää tämän tilin?

View file

@ -201,7 +201,6 @@ operations: "Opérations"
software: "Logiciel"
version: "Version"
metadata: "Métadonnées"
withNFiles: "{n} fichier(s)"
monitor: "Contrôle"
jobQueue: "File dattente"
cpuAndMemory: "Processeur et mémoire"

View file

@ -197,7 +197,6 @@ operations: "Tindakan"
software: "Perangkat lunak"
version: "Versi"
metadata: "Metadata"
withNFiles: "{n} berkas"
monitor: "Pantau"
jobQueue: "Antrian kerja"
cpuAndMemory: "CPU dan Memori"

View file

@ -175,7 +175,6 @@ operations: "Operazioni"
software: "Software"
version: "Versione"
metadata: "Metadato"
withNFiles: "{n} file in allegato"
monitor: "Monitorare"
jobQueue: "Coda di lavoro"
cpuAndMemory: "CPU e Memoria"

View file

@ -188,7 +188,6 @@ operations: "操作"
software: "ソフトウェア"
version: "バージョン"
metadata: "メタデータ"
withNFiles: "{n}つのファイル"
monitor: "モニター"
jobQueue: "ジョブキュー"
cpuAndMemory: "CPUとメモリ"
@ -966,7 +965,8 @@ migrationConfirm: "本当にこのアカウントを {account} に引っ越し
defaultReaction: "リモートとローカルの投稿に対するデフォルトの絵文字リアクション"
license: "ライセンス"
indexPosts: "投稿をインデックス"
indexFrom: "この投稿ID以降をインデックスする空白で全ての投稿を指定します"
indexFrom: "この投稿ID以降をインデックスする"
indexFromDescription: "空白で全ての投稿を指定します"
indexNotice: "インデックスを開始しました。完了まで時間がかかる場合があるため、少なくとも1時間はサーバーを再起動しないでください。"
customKaTeXMacro: "カスタムKaTeXマクロ"
customKaTeXMacroDescription: "数式入力を楽にするためのマクロを設定しましょう記法はLaTeXにおけるコマンドの定義と同様に \\newcommand{\\\

View file

@ -177,7 +177,6 @@ operations: "操作"
software: "ソフトウェア"
version: "バージョン"
metadata: "メタデータ"
withNFiles: "{n}個のファイル"
monitor: "モニター"
jobQueue: "ジョブキュー"
cpuAndMemory: "CPUとメモリ"

View file

@ -177,7 +177,6 @@ operations: "작업"
software: "소프트웨어"
version: "버전"
metadata: "메타데이터"
withNFiles: "{n}개의 파일"
monitor: "모니터"
jobQueue: "작업 대기열"
cpuAndMemory: "CPU와 메모리"

View file

@ -179,7 +179,6 @@ operations: "Verwerkingen"
software: "Software"
version: "Versie"
metadata: "Metadata"
withNFiles: "{n} bestand(en)"
monitor: "Monitor"
jobQueue: "Job Queue"
cpuAndMemory: "CPU en geheugen"

View file

@ -187,7 +187,6 @@ operations: "Działania"
software: "Oprogramowanie"
version: "Wersja"
metadata: "Metadane"
withNFiles: "{n} plik(i/ów)"
monitor: "Monitor"
jobQueue: "Kolejka zadań"
cpuAndMemory: "CPU i pamięć"
@ -1898,7 +1897,8 @@ sendPushNotificationReadMessageCaption: Powiadomienie zawierające tekst "{empty
defaultReaction: Domyślna reakcja emoji dla wychodzących i przychodzących wpisów
license: Licencja
indexPosts: Indeksuj wpisy
indexFrom: Indeksuj wpisy od ID (zostaw puste dla indeksowania wszystkich wpisów)
indexFrom: Indeksuj wpisy od ID
indexFromDescription: Zostaw puste dla indeksowania wszystkich wpisów
indexNotice: Indeksuję. Zapewne zajmie to chwilę, nie restartuj serwera przez co najmniej
godzinę.
customKaTeXMacro: Niestandardowe makra KaTeX

View file

@ -177,7 +177,6 @@ operations: "operar"
software: "Programas"
version: "versão"
metadata: "Metadados"
withNFiles: "{n} Um arquivo"
monitor: "monitor"
jobQueue: "Fila de trabalhos"
cpuAndMemory: "CPU e memória"

View file

@ -177,7 +177,6 @@ operations: "Operațiuni"
software: "Software"
version: "Versiune"
metadata: "Metadata"
withNFiles: "{n} fișier(e)"
monitor: "Monitor"
jobQueue: "coada de job-uri"
cpuAndMemory: "CPU și memorie"

View file

@ -192,7 +192,6 @@ operations: "Операции"
software: "Программы"
version: "Версия"
metadata: "Метаданные"
withNFiles: "Файлы, {n} шт"
monitor: "Монитор"
jobQueue: "Очередь заданий"
cpuAndMemory: "Процессор и память"
@ -1909,8 +1908,8 @@ recommendedInstances: Рекомендованные инстансы
defaultReaction: Эмодзи реакция по умолчанию для выходящих и исходящих постов
license: Лицензия
indexPosts: Индексировать посты
indexFrom: Индексировать начиная с идентификатора поста и далее (оставьте пустым для
индексации каждого поста)
indexFrom: Индексировать начиная с идентификатора поста и далее
indexFromDescription: оставьте пустым для индексации каждого поста
indexNotice: Теперь индексирование. Вероятно, это займет некоторое время, пожалуйста,
не перезагружайте свой сервер по крайней мере в течение часа.
customKaTeXMacro: Кастомные KaTex макросы

View file

@ -177,7 +177,6 @@ operations: "Operácie"
software: "Softvér"
version: "Verzia"
metadata: "Metadáta"
withNFiles: "{n} súbor(ov)"
monitor: "Monitor"
jobQueue: "Fronta úloh"
cpuAndMemory: "CPU a pamäť"

View file

@ -176,7 +176,6 @@ operations: "Operationer"
software: "Mjukvara"
version: "Version"
metadata: "Metadata"
withNFiles: "{n} fil(er)"
monitor: "Övervakning"
jobQueue: "Jobbkö"
cpuAndMemory: "CPU och minne"

View file

@ -177,7 +177,6 @@ operations: "ดำเนินการ"
software: "ซอฟต์แวร์"
version: "เวอร์ชั่น"
metadata: "ข้อมูลเมตา"
withNFiles: "{n} ไฟล์(s)"
monitor: "มอนิเตอร์"
jobQueue: "คิวงาน"
cpuAndMemory: "ซีพียู และ หน่วยความจำ"

View file

@ -177,7 +177,6 @@ operations: "Операції"
software: "Програмне забезпечення"
version: "Версія"
metadata: "Метадані"
withNFiles: "файли: {n}"
monitor: "Монітор"
jobQueue: "Черга завдань"
cpuAndMemory: "ЦП та пам'ять"

View file

@ -177,7 +177,6 @@ operations: "Vận hành"
software: "Phần mềm"
version: "Phiên bản"
metadata: "Metadata"
withNFiles: "{n} tập tin"
monitor: "Giám sát"
jobQueue: "Công việc chờ xử lý"
cpuAndMemory: "CPU và Dung lượng"

View file

@ -181,7 +181,6 @@ operations: "操作"
software: "软件"
version: "版本"
metadata: "元数据"
withNFiles: "{n}个文件"
monitor: "服务器状态"
jobQueue: "作业队列"
cpuAndMemory: "CPU和内存"

View file

@ -180,7 +180,6 @@ operations: "操作"
software: "軟體"
version: "版本"
metadata: "元資料"
withNFiles: "{n}個檔案"
monitor: "監視器"
jobQueue: "佇列"
cpuAndMemory: "CPU及記憶體用量"

View file

@ -1,12 +1,12 @@
{
"name": "calckey",
"version": "14.0.0-dev26",
"version": "14.0.0-dev40",
"codename": "aqua",
"repository": {
"type": "git",
"url": "https://codeberg.org/calckey/calckey.git"
},
"packageManager": "pnpm@8.5.1",
"packageManager": "pnpm@8.6.0",
"private": true,
"scripts": {
"rebuild": "pnpm run clean && pnpm -r run build && pnpm run gulp",
@ -27,7 +27,7 @@
"e2e": "start-server-and-test start:test http://localhost:61812 cy:run",
"mocha": "pnpm --filter backend run mocha",
"test": "pnpm run mocha",
"format": "pnpm rome format packages/**/* --write && pnpm --filter client run format",
"format": "pnpm rome format packages/**/* --write && pnpm -r run format",
"clean": "pnpm node ./scripts/clean.js",
"clean-all": "pnpm node ./scripts/clean-all.js",
"cleanall": "pnpm run clean-all"
@ -36,9 +36,9 @@
"chokidar": "^3.3.1"
},
"dependencies": {
"@bull-board/api": "^4.10.2",
"@bull-board/ui": "^4.10.2",
"@napi-rs/cli": "^2.15.0",
"@bull-board/api": "5.2.0",
"@bull-board/ui": "5.2.0",
"@napi-rs/cli": "^2.16.1",
"@tensorflow/tfjs": "^3.21.0",
"focus-trap": "^7.2.0",
"focus-trap-vue": "^4.0.1",

View file

@ -4,10 +4,5 @@
"module": "commonjs",
"allowSyntheticDefaultImports": true
},
"exclude": [
"node_modules",
"jspm_packages",
"tmp",
"temp"
]
"exclude": ["node_modules", "jspm_packages", "tmp", "temp"]
}

View file

@ -220,7 +220,7 @@ export class Init1000000000000 {
`CREATE INDEX "IDX_3c601b70a1066d2c8b517094cb" ON "notification" ("notifieeId") `,
);
await queryRunner.query(
`CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/assets/ai.png', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT 'https://xn--931a.moe/aiart/yubitun.png', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT true, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`,
`CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/static-assets/badges/info.png', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT '/static-assets/badges/error.png', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT true, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_c76c6e044bdf76ecf8bfb82a645" PRIMARY KEY ("id"))`,

View file

@ -0,0 +1,3 @@
[*.rs]
indent_style = space
indent_size = 4

View file

@ -3,13 +3,42 @@ edition = "2021"
name = "native-utils"
version = "0.0.0"
[workspace]
members = ["migration"]
[features]
default = []
noarray = []
napi = ["dep:napi", "dep:napi-derive", "dep:radix_fmt"]
[lib]
crate-type = ["cdylib"]
crate-type = ["cdylib", "lib"]
[dependencies]
async-trait = "0.1.68"
cfg-if = "1.0.0"
chrono = "0.4.24"
cuid2 = "0.1.0"
derive_more = "0.99.17"
jsonschema = "0.17.0"
once_cell = "1.17.1"
parse-display = "0.8.0"
rand = "0.8.5"
schemars = { version = "0.8.12", features = ["chrono"] }
sea-orm = { version = "0.11.3", features = ["sqlx-postgres", "postgres-array", "sqlx-sqlite", "runtime-tokio-rustls"] }
serde = { version = "1.0.163", features = ["derive"] }
serde_json = "1.0.96"
thiserror = "1.0.40"
tokio = { version = "1.28.1", features = ["full"] }
utoipa = "3.3.0"
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "2.12.0", default-features = false, features = ["napi4"] }
napi-derive = "2.12.0"
napi = { version = "2.13.1", default-features = false, features = ["napi6", "tokio_rt"], optional = true }
napi-derive = { version = "2.12.0", optional = true }
radix_fmt = { version = "1.0.0", optional = true }
[dev-dependencies]
pretty_assertions = "1.3.0"
[build-dependencies]
napi-build = "2.0.1"

View file

@ -1,7 +1,32 @@
import test from "ava";
import { sum } from "../index.js";
import {
convertId,
IdConvertType,
nativeInitIdGenerator,
nativeCreateId,
nativeRandomStr,
} from "../built/index.js";
test("sum from native", (t) => {
t.is(sum(1, 2), 3);
test("convert to mastodon id", (t) => {
t.is(convertId("9gf61ehcxv", IdConvertType.MastodonId), "960365976481219");
t.is(
convertId("9fbr9z0wbrjqyd3u", IdConvertType.MastodonId),
"3954607381600562394",
);
t.is(
convertId("9fbs680oyviiqrol9md73p8g", IdConvertType.MastodonId),
"3494513243013053824",
);
});
test("create cuid2 with timestamp prefix", (t) => {
nativeInitIdGenerator(16, "");
t.not(nativeCreateId(BigInt(Date.now())), nativeCreateId(BigInt(Date.now())));
t.is(nativeCreateId(BigInt(Date.now())).length, 16);
});
test("create random string", (t) => {
t.not(nativeRandomStr(16), nativeRandomStr(16));
t.is(nativeRandomStr(24).length, 24);
});

View file

@ -1,5 +1,5 @@
extern crate napi_build;
fn main() {
napi_build::setup();
napi_build::setup();
}

View file

@ -0,0 +1,34 @@
[package]
name = "migration"
version = "0.1.0"
edition = "2021"
publish = false
[lib]
name = "migration"
path = "src/lib.rs"
[features]
default = []
convert = ["dep:native-utils"]
[dependencies]
async-std = { version = "1", features = ["attributes", "tokio1"] }
serde_json = "1.0.96"
native-utils = { path = "../", optional = true }
indicatif = { version = "0.17.4", features = ["tokio"] }
tokio = { version = "1.28.2", features = ["full"] }
futures = "0.3.28"
serde_yaml = "0.9.21"
serde = { version = "1.0.163", features = ["derive"] }
[dependencies.sea-orm-migration]
version = "0.11.0"
features = [
# Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
# View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
# e.g.
"runtime-tokio-rustls", # `ASYNC_RUNTIME` feature
"sqlx-postgres", # `DATABASE_DRIVER` feature
"sqlx-sqlite",
]

View file

@ -0,0 +1,41 @@
# Running Migrator CLI
- Generate a new migration file
```sh
cargo run -- migrate generate MIGRATION_NAME
```
- Apply all pending migrations
```sh
cargo run
```
```sh
cargo run -- up
```
- Apply first 10 pending migrations
```sh
cargo run -- up -n 10
```
- Rollback last applied migrations
```sh
cargo run -- down
```
- Rollback last 10 applied migrations
```sh
cargo run -- down -n 10
```
- Drop all tables from the database, then reapply all migrations
```sh
cargo run -- fresh
```
- Rollback all applied migrations, then reapply all migrations
```sh
cargo run -- refresh
```
- Rollback all applied migrations
```sh
cargo run -- reset
```
- Check the status of all migrations
```sh
cargo run -- status
```

View file

@ -0,0 +1,12 @@
pub use sea_orm_migration::prelude::*;
mod m20230531_180824_drop_reversi;
pub struct Migrator;
#[async_trait::async_trait]
impl MigratorTrait for Migrator {
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![Box::new(m20230531_180824_drop_reversi::Migration)]
}
}

View file

@ -0,0 +1,51 @@
use sea_orm_migration::{
prelude::*,
sea_orm::{DbBackend, Statement},
};
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
if manager.get_database_backend() == DbBackend::Sqlite {
return Ok(());
}
let db = manager.get_connection();
db.query_one(Statement::from_string(
DbBackend::Postgres,
Table::drop()
.table(ReversiGame::Table)
.if_exists()
.to_string(PostgresQueryBuilder),
))
.await?;
db.query_one(Statement::from_string(
DbBackend::Postgres,
Table::drop()
.table(ReversiMatching::Table)
.if_exists()
.to_string(PostgresQueryBuilder),
))
.await?;
Ok(())
}
async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> {
// Replace the sample below with your own migration scripts
Ok(())
}
}
/// Learn more at https://docs.rs/sea-query#iden
#[derive(Iden)]
enum ReversiGame {
Table,
}
#[derive(Iden)]
enum ReversiMatching {
Table,
}

View file

@ -0,0 +1,45 @@
use serde::Deserialize;
use std::env;
use std::fs;
use sea_orm_migration::prelude::*;
#[cfg(feature = "convert")]
mod vec_to_json;
#[async_std::main]
async fn main() {
let cwd = env::current_dir().unwrap();
let yml = fs::File::open(cwd.join("../../.config/default.yml"))
.expect("Unable to read '.config/default.yml'");
let config: Config = serde_yaml::from_reader(yml).expect("Unable to parse");
env::set_var(
"DATABASE_URL",
format!(
"postgres://{}:{}@{}:{}/{}",
config.db.user, config.db.pass, config.db.host, config.db.port, config.db.db
),
);
cli::run_cli(migration::Migrator).await;
#[cfg(feature = "convert")]
vec_to_json::convert().await;
}
#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename = "camelCase")]
pub struct Config {
pub db: DbConfig,
}
#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename = "camelCase")]
pub struct DbConfig {
pub host: String,
pub port: u32,
pub db: String,
pub user: String,
pub pass: String,
}

View file

@ -0,0 +1,498 @@
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use native_utils::model::entity::newtype::{I32Vec, StringVec};
use sea_orm_migration::{
prelude::*,
sea_orm::{Database, DbBackend, DbConn, Statement, TryGetable},
};
use serde_json::json;
use std::env;
use std::time::Duration;
pub async fn convert() {
let uri = env::var("DATABASE_URL").expect("Environment variable 'DATABASE_URL' not set");
let db = Database::connect(uri).await.expect("Unable to connect");
let mp = MultiProgress::new();
let handlers = vec![
tokio::spawn(to_json::<AccessToken, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
AccessToken::Table,
AccessToken::Id,
AccessToken::Permission,
)),
tokio::spawn(to_json::<Antenna, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Antenna::Table,
Antenna::Id,
Antenna::Users,
)),
tokio::spawn(to_json::<App, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
App::Table,
App::Id,
App::Permission,
)),
tokio::spawn(to_json::<Emoji, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Emoji::Table,
Emoji::Id,
Emoji::Aliases,
)),
tokio::spawn(to_json::<GalleryPost, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
GalleryPost::Table,
GalleryPost::Id,
GalleryPost::FileIds,
)),
tokio::spawn(to_json::<GalleryPost, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
GalleryPost::Table,
GalleryPost::Id,
GalleryPost::Tags,
)),
tokio::spawn(to_json::<Hashtag, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Hashtag::Table,
Hashtag::Id,
Hashtag::MentionedUserIds,
)),
tokio::spawn(to_json::<Hashtag, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Hashtag::Table,
Hashtag::Id,
Hashtag::MentionedLocalUserIds,
)),
tokio::spawn(to_json::<Hashtag, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Hashtag::Table,
Hashtag::Id,
Hashtag::MentionedRemoteUserIds,
)),
tokio::spawn(to_json::<Hashtag, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Hashtag::Table,
Hashtag::Id,
Hashtag::AttachedUserIds,
)),
tokio::spawn(to_json::<Hashtag, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Hashtag::Table,
Hashtag::Id,
Hashtag::AttachedLocalUserIds,
)),
tokio::spawn(to_json::<Hashtag, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Hashtag::Table,
Hashtag::Id,
Hashtag::AttachedRemoteUserIds,
)),
tokio::spawn(to_json::<MessagingMessage, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
MessagingMessage::Table,
MessagingMessage::Id,
MessagingMessage::Reads,
)),
tokio::spawn(to_json::<Meta, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Meta::Table,
Meta::Id,
Meta::Langs,
)),
tokio::spawn(to_json::<Meta, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Meta::Table,
Meta::Id,
Meta::BlockedHosts,
)),
tokio::spawn(to_json::<Meta, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Meta::Table,
Meta::Id,
Meta::HiddenTags,
)),
tokio::spawn(to_json::<Meta, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Meta::Table,
Meta::Id,
Meta::PinnedUsers,
)),
tokio::spawn(to_json::<Meta, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Meta::Table,
Meta::Id,
Meta::PinnedPages,
)),
tokio::spawn(to_json::<Meta, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Meta::Table,
Meta::Id,
Meta::RecommendedInstances,
)),
tokio::spawn(to_json::<Meta, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Meta::Table,
Meta::Id,
Meta::SilencedHosts,
)),
tokio::spawn(to_json::<Note, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Note::Table,
Note::Id,
Note::FileIds,
)),
tokio::spawn(to_json::<Note, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Note::Table,
Note::Id,
Note::AttachedFileTypes,
)),
tokio::spawn(to_json::<Note, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Note::Table,
Note::Id,
Note::VisibleUserIds,
)),
tokio::spawn(to_json::<Note, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Note::Table,
Note::Id,
Note::Mentions,
)),
tokio::spawn(to_json::<Note, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Note::Table,
Note::Id,
Note::Emojis,
)),
tokio::spawn(to_json::<Note, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Note::Table,
Note::Id,
Note::Tags,
)),
tokio::spawn(to_json::<NoteEdit, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
NoteEdit::Table,
NoteEdit::Id,
NoteEdit::FileIds,
)),
tokio::spawn(to_json::<Page, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Page::Table,
Page::Id,
Page::VisibleUserIds,
)),
tokio::spawn(to_json::<RegistryItem, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
RegistryItem::Table,
RegistryItem::Id,
RegistryItem::Scope,
)),
tokio::spawn(to_json::<User, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
User::Table,
User::Id,
User::Tags,
)),
tokio::spawn(to_json::<User, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
User::Table,
User::Id,
User::Emojis,
)),
tokio::spawn(to_json::<Webhook, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Webhook::Table,
Webhook::Id,
Webhook::On,
)),
tokio::spawn(to_json::<Poll, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
Poll::Table,
Poll::NoteId,
Poll::Choices,
)),
tokio::spawn(to_json::<Poll, Vec<i32>, I32Vec>(
db.clone(),
mp.clone(),
Poll::Table,
Poll::NoteId,
Poll::Votes,
)),
tokio::spawn(to_json::<UserProfile, Vec<String>, StringVec>(
db.clone(),
mp.clone(),
UserProfile::Table,
UserProfile::UserId,
UserProfile::MutingNotificationTypes,
)),
];
futures::future::join_all(handlers).await;
}
fn select_query<T: Iden + 'static>(table: T, id: T, col: T) -> String {
Query::select()
.column(id)
.column(col)
.from(table)
.to_string(PostgresQueryBuilder)
}
async fn get_vec<T: TryGetable>(db: &DbConn, query: String) -> Result<Vec<(String, T)>, DbErr> {
let res: Vec<(String, T)> = db
.query_all(Statement::from_string(DbBackend::Postgres, query))
.await?
.iter()
.filter_map(|r| r.try_get_many_by_index().ok())
.collect();
Ok(res)
}
async fn convert_col<T: Iden + Clone + 'static>(
db: &DbConn,
table: T,
col: T,
) -> Result<(), DbErr> {
let stmt = Table::alter()
.table(table)
.drop_column(col.to_owned())
.add_column(
ColumnDef::new(col.to_owned())
.json_binary()
.not_null()
.default(json!([])),
)
.to_string(PostgresQueryBuilder);
db.query_one(Statement::from_string(DbBackend::Postgres, stmt))
.await?;
Ok(())
}
async fn to_json<T, U, V>(
db: DbConn,
mp: MultiProgress,
table: T,
id: T,
col: T,
) -> Result<(), DbErr>
where
T: Iden + Clone + 'static,
U: TryGetable + IntoIterator + Clone,
V: From<U> + Into<SimpleExpr>,
{
let query = select_query(table.clone(), id.clone(), col.clone());
let loading = ProgressBar::new_spinner()
.with_style(ProgressStyle::with_template("{prefix} {msg} {spinner}").unwrap())
.with_prefix("[-]")
.with_message(format!(
"Loading data from {}.{}",
table.to_string(),
col.to_string()
));
let loading = mp.add(loading);
loading.enable_steady_tick(Duration::from_millis(100));
let res = get_vec::<U>(&db, query).await?;
let models: Vec<(String, V)> = res
.iter()
.filter(|(_, r)| r.clone().into_iter().count() > 0)
.map(|(id, r)| (id.clone(), <V>::from(r.clone())))
.collect();
loading.finish_and_clear();
convert_col(&db, table.clone(), col.clone()).await?;
let progress = ProgressBar::new(models.len() as u64)
.with_style(
ProgressStyle::with_template("{prefix} {msg} {wide_bar} {pos}/{len}")
.unwrap()
.progress_chars("##-"),
)
.with_prefix("[*]")
.with_message(format!("Copying {}.{}", table.to_string(), col.to_string()));
let progress = mp.add(progress);
for model in models {
progress.inc(1);
let q = Query::update()
.table(table.clone())
.values([(col.clone(), model.1.into())])
.and_where(Expr::col(id.clone()).eq(model.0))
.to_string(PostgresQueryBuilder);
db.query_one(Statement::from_string(DbBackend::Postgres, q))
.await?;
}
progress.finish_with_message(format!("Done {}.{}", table.to_string(), col.to_string()));
Ok(())
}
#[derive(Iden, Clone)]
enum AccessToken {
Table,
Id,
Permission,
}
#[derive(Iden, Clone)]
enum Antenna {
Table,
Id,
Users,
}
#[derive(Iden, Clone)]
enum App {
Table,
Id,
Permission,
}
#[derive(Iden, Clone)]
enum Emoji {
Table,
Id,
Aliases,
}
#[derive(Iden, Clone)]
enum GalleryPost {
Table,
Id,
#[iden = "fileIds"]
FileIds,
Tags,
}
#[derive(Iden, Clone)]
enum Hashtag {
Table,
Id,
#[iden = "mentionedUserIds"]
MentionedUserIds,
#[iden = "mentionedLocalUserIds"]
MentionedLocalUserIds,
#[iden = "mentionedRemoteUserIds"]
MentionedRemoteUserIds,
#[iden = "attachedUserIds"]
AttachedUserIds,
#[iden = "attachedLocalUserIds"]
AttachedLocalUserIds,
#[iden = "attachedRemoteUserIds"]
AttachedRemoteUserIds,
}
#[derive(Iden, Clone)]
enum MessagingMessage {
Table,
Id,
Reads,
}
#[derive(Iden, Clone)]
enum Meta {
Table,
Id,
Langs,
#[iden = "hiddenTags"]
HiddenTags,
#[iden = "blockedHosts"]
BlockedHosts,
#[iden = "pinnedUsers"]
PinnedUsers,
#[iden = "pinnedPages"]
PinnedPages,
#[iden = "recommendedInstances"]
RecommendedInstances,
#[iden = "silencedHosts"]
SilencedHosts,
}
#[derive(Iden, Clone)]
enum Note {
Table,
Id,
#[iden = "fileIds"]
FileIds,
#[iden = "attachedFileTypes"]
AttachedFileTypes,
#[iden = "visibleUserIds"]
VisibleUserIds,
Mentions,
Emojis,
Tags,
}
#[derive(Iden, Clone)]
enum NoteEdit {
Table,
Id,
#[iden = "fileIds"]
FileIds,
}
#[derive(Iden, Clone)]
enum Page {
Table,
Id,
#[iden = "visibleUserIds"]
VisibleUserIds,
}
#[derive(Iden, Clone)]
enum Poll {
Table,
#[iden = "noteId"]
NoteId,
Choices,
Votes, // I32Vec
}
#[derive(Iden, Clone)]
enum RegistryItem {
Table,
Id,
Scope,
}
#[derive(Iden, Clone)]
enum User {
Table,
Id,
Tags,
Emojis,
}
#[derive(Iden, Clone)]
enum UserProfile {
Table,
#[iden = "userId"]
UserId,
#[iden = "mutingNotificationTypes"]
MutingNotificationTypes,
}
#[derive(Iden, Clone)]
enum Webhook {
Table,
Id,
On,
}

View file

@ -23,8 +23,8 @@
},
"license": "MIT",
"devDependencies": {
"@napi-rs/cli": "^2.15.0",
"ava": "^5.1.1"
"@napi-rs/cli": "2.16.1",
"ava": "5.1.1"
},
"ava": {
"timeout": "3m"
@ -34,11 +34,15 @@
},
"scripts": {
"artifacts": "napi artifacts",
"build": "napi build --platform --release ./built/",
"build": "napi build --features napi --platform --release ./built/",
"build:debug": "napi build --platform",
"prepublishOnly": "napi prepublish -t npm",
"test": "ava",
"test": "pnpm run cargo:test && pnpm run build && ava",
"universal": "napi universal",
"version": "napi version"
"version": "napi version",
"format": "cargo fmt --all",
"cargo:test": "pnpm run cargo:unit && pnpm run cargo:integration",
"cargo:unit": "cargo test unit_test && cargo test -F napi unit_test",
"cargo:integration": "cargo test -F noarray int_test -- --test-threads=1"
}
}

View file

@ -1,2 +0,0 @@
tab_spaces = 2
edition = "2021"

View file

@ -0,0 +1,13 @@
use sea_orm::error::DbErr;
use crate::impl_into_napi_error;
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
pub enum Error {
#[error("The database connections have not been initialized yet")]
Uninitialized,
#[error("ORM error: {0}")]
OrmError(#[from] DbErr),
}
impl_into_napi_error!(Error);

View file

@ -0,0 +1,38 @@
pub mod error;
use cfg_if::cfg_if;
use error::Error;
use sea_orm::{Database, DbConn};
static DB_CONN: once_cell::sync::OnceCell<DbConn> = once_cell::sync::OnceCell::new();
pub async fn init_database(conn_uri: impl Into<String>) -> Result<(), Error> {
let conn = Database::connect(conn_uri.into()).await?;
DB_CONN.get_or_init(move || conn);
Ok(())
}
pub fn get_database() -> Result<&'static DbConn, Error> {
DB_CONN.get().ok_or(Error::Uninitialized)
}
cfg_if! {
if #[cfg(feature = "napi")] {
use napi_derive::napi;
#[napi]
pub async fn native_init_database(conn_uri: String) -> napi::Result<()> {
init_database(conn_uri).await.map_err(Into::into)
}
}
}
#[cfg(test)]
mod unit_test {
use super::{error::Error, get_database};
#[test]
fn error_uninitialized() {
assert_eq!(get_database().unwrap_err(), Error::Uninitialized);
}
}

View file

@ -1,2 +1,7 @@
pub mod database;
pub mod macros;
pub mod model;
pub mod util;
#[cfg(feature = "napi")]
pub mod mastodon_api;

View file

@ -0,0 +1,11 @@
#[macro_export]
macro_rules! impl_into_napi_error {
($a:ty) => {
#[cfg(feature = "napi")]
impl Into<napi::Error> for $a {
fn into(self) -> napi::Error {
napi::Error::from_reason(self.to_string())
}
}
};
}

View file

@ -7,64 +7,64 @@ static CHAR_COLLECTION: &str = "0123456789abcdefghijklmnopqrstuvwxyz";
#[napi]
pub enum IdConvertType {
MastodonId,
CalckeyId,
MastodonId,
CalckeyId,
}
#[napi]
pub fn convert_id(in_id: String, id_convert_type: IdConvertType) -> napi::Result<String> {
use IdConvertType::*;
match id_convert_type {
MastodonId => {
let mut out: i64 = 0;
for (i, c) in in_id.to_lowercase().chars().rev().enumerate() {
out += num_from_char(c)? as i64 * 36_i64.pow(i as u32);
}
use IdConvertType::*;
match id_convert_type {
MastodonId => {
let mut out: i64 = 0;
for (i, c) in in_id.to_lowercase().chars().rev().enumerate() {
out += num_from_char(c)? as i64 * 36_i64.pow(i as u32);
}
Ok(out.to_string())
}
CalckeyId => {
let mut input: i64 = match in_id.parse() {
Ok(s) => s,
Err(_) => {
return Err(Error::new(
Status::InvalidArg,
"Unable to parse ID as MasstodonId",
))
Ok(out.to_string())
}
};
let mut out = String::new();
CalckeyId => {
let mut input: i64 = match in_id.parse() {
Ok(s) => s,
Err(_) => {
return Err(Error::new(
Status::InvalidArg,
"Unable to parse ID as MasstodonId",
))
}
};
let mut out = String::new();
while input != 0 {
out.insert(0, char_from_num((input % 36) as u8)?);
input /= 36;
}
while input != 0 {
out.insert(0, char_from_num((input % 36) as u8)?);
input /= 36;
}
Ok(out)
Ok(out)
}
}
}
}
// -- end --
#[inline(always)]
fn num_from_char(character: char) -> napi::Result<u8> {
for (i, c) in CHAR_COLLECTION.chars().enumerate() {
if c == character {
return Ok(i as u8);
for (i, c) in CHAR_COLLECTION.chars().enumerate() {
if c == character {
return Ok(i as u8);
}
}
}
Err(Error::new(
Status::InvalidArg,
"Invalid character in parsed base36 id",
))
Err(Error::new(
Status::InvalidArg,
"Invalid character in parsed base36 id",
))
}
#[inline(always)]
fn char_from_num(number: u8) -> napi::Result<char> {
CHAR_COLLECTION
.chars()
.nth(number as usize)
.ok_or(Error::from_status(Status::Unknown))
CHAR_COLLECTION
.chars()
.nth(number as usize)
.ok_or(Error::from_status(Status::Unknown))
}

View file

@ -0,0 +1,74 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
pub mod prelude;
pub mod abuse_user_report;
pub mod access_token;
pub mod ad;
pub mod announcement;
pub mod announcement_read;
pub mod antenna;
pub mod antenna_note;
pub mod app;
pub mod attestation_challenge;
pub mod auth_session;
pub mod blocking;
pub mod channel;
pub mod channel_following;
pub mod channel_note_pining;
pub mod clip;
pub mod clip_note;
pub mod drive_file;
pub mod drive_folder;
pub mod emoji;
pub mod follow_request;
pub mod following;
pub mod gallery_like;
pub mod gallery_post;
pub mod hashtag;
pub mod instance;
pub mod messaging_message;
pub mod meta;
pub mod migrations;
pub mod moderation_log;
pub mod muted_note;
pub mod muting;
pub mod newtype;
pub mod note;
pub mod note_edit;
pub mod note_favorite;
pub mod note_reaction;
pub mod note_thread_muting;
pub mod note_unread;
pub mod note_watching;
pub mod notification;
pub mod page;
pub mod page_like;
pub mod password_reset_request;
pub mod poll;
pub mod poll_vote;
pub mod promo_note;
pub mod promo_read;
pub mod registration_ticket;
pub mod registry_item;
pub mod relay;
pub mod renote_muting;
pub mod sea_orm_active_enums;
pub mod signin;
pub mod sw_subscription;
pub mod used_username;
pub mod user;
pub mod user_group;
pub mod user_group_invitation;
pub mod user_group_invite;
pub mod user_group_joining;
pub mod user_ip;
pub mod user_keypair;
pub mod user_list;
pub mod user_list_joining;
pub mod user_note_pining;
pub mod user_pending;
pub mod user_profile;
pub mod user_publickey;
pub mod user_security_key;
pub mod webhook;

View file

@ -0,0 +1,55 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "abuse_user_report")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "targetUserId")]
pub target_user_id: String,
#[sea_orm(column_name = "reporterId")]
pub reporter_id: String,
#[sea_orm(column_name = "assigneeId")]
pub assignee_id: Option<String>,
pub resolved: bool,
pub comment: String,
#[sea_orm(column_name = "targetUserHost")]
pub target_user_host: Option<String>,
#[sea_orm(column_name = "reporterHost")]
pub reporter_host: Option<String>,
pub forwarded: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::ReporterId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User3,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::AssigneeId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
User2,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::TargetUserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User1,
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,71 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "access_token")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
pub token: String,
pub hash: String,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "appId")]
pub app_id: Option<String>,
#[sea_orm(column_name = "lastUsedAt")]
pub last_used_at: Option<DateTimeWithTimeZone>,
pub session: Option<String>,
pub name: Option<String>,
pub description: Option<String>,
#[sea_orm(column_name = "iconUrl")]
pub icon_url: Option<String>,
pub permission: StringVec,
pub fetched: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::app::Entity",
from = "Column::AppId",
to = "super::app::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
App,
#[sea_orm(has_many = "super::notification::Entity")]
Notification,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::app::Entity> for Entity {
fn to() -> RelationDef {
Relation::App.def()
}
}
impl Related<super::notification::Entity> for Entity {
fn to() -> RelationDef {
Relation::Notification.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,26 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "ad")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "expiresAt")]
pub expires_at: DateTimeWithTimeZone,
pub place: String,
pub priority: String,
pub url: String,
#[sea_orm(column_name = "imageUrl")]
pub image_url: String,
pub memo: String,
pub ratio: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,32 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "announcement")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
pub text: String,
pub title: String,
#[sea_orm(column_name = "imageUrl")]
pub image_url: Option<String>,
#[sea_orm(column_name = "updatedAt")]
pub updated_at: Option<DateTimeWithTimeZone>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::announcement_read::Entity")]
AnnouncementRead,
}
impl Related<super::announcement_read::Entity> for Entity {
fn to() -> RelationDef {
Relation::AnnouncementRead.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,50 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "announcement_read")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "announcementId")]
pub announcement_id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::announcement::Entity",
from = "Column::AnnouncementId",
to = "super::announcement::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Announcement,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::announcement::Entity> for Entity {
fn to() -> RelationDef {
Relation::Announcement.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,92 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use super::{newtype, sea_orm_active_enums::AntennaSrcEnum};
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "antenna")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
pub name: String,
pub src: AntennaSrcEnum,
#[sea_orm(column_name = "userListId")]
pub user_list_id: Option<String>,
#[sea_orm(column_type = "JsonBinary")]
pub keywords: newtype::JsonKeyword,
#[sea_orm(column_name = "withFile")]
pub with_file: bool,
pub expression: Option<String>,
pub notify: bool,
#[sea_orm(column_name = "caseSensitive")]
pub case_sensitive: bool,
#[sea_orm(column_name = "withReplies")]
pub with_replies: bool,
#[sea_orm(column_name = "userGroupJoiningId")]
pub user_group_joining_id: Option<String>,
pub users: newtype::StringVec,
#[sea_orm(column_name = "excludeKeywords", column_type = "JsonBinary")]
pub exclude_keywords: newtype::JsonKeyword,
#[sea_orm(column_type = "JsonBinary")]
pub instances: newtype::JsonStringVec,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::antenna_note::Entity")]
AntennaNote,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
#[sea_orm(
belongs_to = "super::user_group_joining::Entity",
from = "Column::UserGroupJoiningId",
to = "super::user_group_joining::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserGroupJoining,
#[sea_orm(
belongs_to = "super::user_list::Entity",
from = "Column::UserListId",
to = "super::user_list::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserList,
}
impl Related<super::antenna_note::Entity> for Entity {
fn to() -> RelationDef {
Relation::AntennaNote.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::user_group_joining::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupJoining.def()
}
}
impl Related<super::user_list::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserList.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,49 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "antenna_note")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
#[sea_orm(column_name = "antennaId")]
pub antenna_id: String,
pub read: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::antenna::Entity",
from = "Column::AntennaId",
to = "super::antenna::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Antenna,
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
}
impl Related<super::antenna::Entity> for Entity {
fn to() -> RelationDef {
Relation::Antenna.def()
}
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,58 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "app")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: Option<String>,
pub secret: String,
pub name: String,
pub description: String,
pub permission: StringVec,
#[sea_orm(column_name = "callbackUrl")]
pub callback_url: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::access_token::Entity")]
AccessToken,
#[sea_orm(has_many = "super::auth_session::Entity")]
AuthSession,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
User,
}
impl Related<super::access_token::Entity> for Entity {
fn to() -> RelationDef {
Relation::AccessToken.def()
}
}
impl Related<super::auth_session::Entity> for Entity {
fn to() -> RelationDef {
Relation::AuthSession.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,37 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "attestation_challenge")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "userId", primary_key, auto_increment = false)]
pub user_id: String,
pub challenge: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "registrationChallenge")]
pub registration_challenge: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,51 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "auth_session")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
pub token: String,
#[sea_orm(column_name = "userId")]
pub user_id: Option<String>,
#[sea_orm(column_name = "appId")]
pub app_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::app::Entity",
from = "Column::AppId",
to = "super::app::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
App,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::app::Entity> for Entity {
fn to() -> RelationDef {
Relation::App.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,38 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "blocking")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "blockeeId")]
pub blockee_id: String,
#[sea_orm(column_name = "blockerId")]
pub blocker_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::BlockerId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User2,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::BlockeeId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User1,
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,82 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "channel")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "lastNotedAt")]
pub last_noted_at: Option<DateTimeWithTimeZone>,
#[sea_orm(column_name = "userId")]
pub user_id: Option<String>,
pub name: String,
pub description: Option<String>,
#[sea_orm(column_name = "bannerId")]
pub banner_id: Option<String>,
#[sea_orm(column_name = "notesCount")]
pub notes_count: i32,
#[sea_orm(column_name = "usersCount")]
pub users_count: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::channel_following::Entity")]
ChannelFollowing,
#[sea_orm(has_many = "super::channel_note_pining::Entity")]
ChannelNotePining,
#[sea_orm(
belongs_to = "super::drive_file::Entity",
from = "Column::BannerId",
to = "super::drive_file::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
DriveFile,
#[sea_orm(has_many = "super::note::Entity")]
Note,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
User,
}
impl Related<super::channel_following::Entity> for Entity {
fn to() -> RelationDef {
Relation::ChannelFollowing.def()
}
}
impl Related<super::channel_note_pining::Entity> for Entity {
fn to() -> RelationDef {
Relation::ChannelNotePining.def()
}
}
impl Related<super::drive_file::Entity> for Entity {
fn to() -> RelationDef {
Relation::DriveFile.def()
}
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,50 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "channel_following")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "followeeId")]
pub followee_id: String,
#[sea_orm(column_name = "followerId")]
pub follower_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::channel::Entity",
from = "Column::FolloweeId",
to = "super::channel::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Channel,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::FollowerId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::channel::Entity> for Entity {
fn to() -> RelationDef {
Relation::Channel.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,50 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "channel_note_pining")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "channelId")]
pub channel_id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::channel::Entity",
from = "Column::ChannelId",
to = "super::channel::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Channel,
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
}
impl Related<super::channel::Entity> for Entity {
fn to() -> RelationDef {
Relation::Channel.def()
}
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,46 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "clip")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
pub name: String,
#[sea_orm(column_name = "isPublic")]
pub is_public: bool,
pub description: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::clip_note::Entity")]
ClipNote,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::clip_note::Entity> for Entity {
fn to() -> RelationDef {
Relation::ClipNote.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,48 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "clip_note")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
#[sea_orm(column_name = "clipId")]
pub clip_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::clip::Entity",
from = "Column::ClipId",
to = "super::clip::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Clip,
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
}
impl Related<super::clip::Entity> for Entity {
fn to() -> RelationDef {
Relation::Clip.def()
}
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,113 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "drive_file")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: Option<String>,
#[sea_orm(column_name = "userHost")]
pub user_host: Option<String>,
pub md5: String,
pub name: String,
pub r#type: String,
pub size: i32,
pub comment: Option<String>,
#[sea_orm(column_type = "JsonBinary")]
pub properties: Json,
#[sea_orm(column_name = "storedInternal")]
pub stored_internal: bool,
pub url: String,
#[sea_orm(column_name = "thumbnailUrl")]
pub thumbnail_url: Option<String>,
#[sea_orm(column_name = "webpublicUrl")]
pub webpublic_url: Option<String>,
#[sea_orm(column_name = "accessKey")]
pub access_key: Option<String>,
#[sea_orm(column_name = "thumbnailAccessKey")]
pub thumbnail_access_key: Option<String>,
#[sea_orm(column_name = "webpublicAccessKey")]
pub webpublic_access_key: Option<String>,
pub uri: Option<String>,
pub src: Option<String>,
#[sea_orm(column_name = "folderId")]
pub folder_id: Option<String>,
#[sea_orm(column_name = "isSensitive")]
pub is_sensitive: bool,
#[sea_orm(column_name = "isLink")]
pub is_link: bool,
pub blurhash: Option<String>,
#[sea_orm(column_name = "webpublicType")]
pub webpublic_type: Option<String>,
#[sea_orm(column_name = "requestHeaders", column_type = "JsonBinary", nullable)]
pub request_headers: Option<Json>,
#[sea_orm(column_name = "requestIp")]
pub request_ip: Option<String>,
#[sea_orm(column_name = "maybeSensitive")]
pub maybe_sensitive: bool,
#[sea_orm(column_name = "maybePorn")]
pub maybe_porn: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::channel::Entity")]
Channel,
#[sea_orm(
belongs_to = "super::drive_folder::Entity",
from = "Column::FolderId",
to = "super::drive_folder::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
DriveFolder,
#[sea_orm(has_many = "super::messaging_message::Entity")]
MessagingMessage,
#[sea_orm(has_many = "super::page::Entity")]
Page,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
User,
}
impl Related<super::channel::Entity> for Entity {
fn to() -> RelationDef {
Relation::Channel.def()
}
}
impl Related<super::drive_folder::Entity> for Entity {
fn to() -> RelationDef {
Relation::DriveFolder.def()
}
}
impl Related<super::messaging_message::Entity> for Entity {
fn to() -> RelationDef {
Relation::MessagingMessage.def()
}
}
impl Related<super::page::Entity> for Entity {
fn to() -> RelationDef {
Relation::Page.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,53 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "drive_folder")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
pub name: String,
#[sea_orm(column_name = "userId")]
pub user_id: Option<String>,
#[sea_orm(column_name = "parentId")]
pub parent_id: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::drive_file::Entity")]
DriveFile,
#[sea_orm(
belongs_to = "Entity",
from = "Column::ParentId",
to = "Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
SelfRef,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::drive_file::Entity> for Entity {
fn to() -> RelationDef {
Relation::DriveFile.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,32 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "emoji")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "updatedAt")]
pub updated_at: Option<DateTimeWithTimeZone>,
pub name: String,
pub host: Option<String>,
#[sea_orm(column_name = "originalUrl")]
pub original_url: String,
pub uri: Option<String>,
pub r#type: Option<String>,
pub aliases: StringVec,
pub category: Option<String>,
#[sea_orm(column_name = "publicUrl")]
pub public_url: String,
pub license: Option<String>,
pub width: Option<i32>,
pub height: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,60 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "follow_request")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "followeeId")]
pub followee_id: String,
#[sea_orm(column_name = "followerId")]
pub follower_id: String,
#[sea_orm(column_name = "requestId")]
pub request_id: Option<String>,
#[sea_orm(column_name = "followerHost")]
pub follower_host: Option<String>,
#[sea_orm(column_name = "followerInbox")]
pub follower_inbox: Option<String>,
#[sea_orm(column_name = "followerSharedInbox")]
pub follower_shared_inbox: Option<String>,
#[sea_orm(column_name = "followeeHost")]
pub followee_host: Option<String>,
#[sea_orm(column_name = "followeeInbox")]
pub followee_inbox: Option<String>,
#[sea_orm(column_name = "followeeSharedInbox")]
pub followee_shared_inbox: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::notification::Entity")]
Notification,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::FolloweeId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User2,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::FollowerId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User1,
}
impl Related<super::notification::Entity> for Entity {
fn to() -> RelationDef {
Relation::Notification.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,50 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "following")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "followeeId")]
pub followee_id: String,
#[sea_orm(column_name = "followerId")]
pub follower_id: String,
#[sea_orm(column_name = "followerHost")]
pub follower_host: Option<String>,
#[sea_orm(column_name = "followerInbox")]
pub follower_inbox: Option<String>,
#[sea_orm(column_name = "followerSharedInbox")]
pub follower_shared_inbox: Option<String>,
#[sea_orm(column_name = "followeeHost")]
pub followee_host: Option<String>,
#[sea_orm(column_name = "followeeInbox")]
pub followee_inbox: Option<String>,
#[sea_orm(column_name = "followeeSharedInbox")]
pub followee_shared_inbox: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::FolloweeId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User2,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::FollowerId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User1,
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,50 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "gallery_like")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "postId")]
pub post_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::gallery_post::Entity",
from = "Column::PostId",
to = "super::gallery_post::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
GalleryPost,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::gallery_post::Entity> for Entity {
fn to() -> RelationDef {
Relation::GalleryPost.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,55 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "gallery_post")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "updatedAt")]
pub updated_at: DateTimeWithTimeZone,
pub title: String,
pub description: Option<String>,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "fileIds")]
pub file_ids: StringVec,
#[sea_orm(column_name = "isSensitive")]
pub is_sensitive: bool,
#[sea_orm(column_name = "likedCount")]
pub liked_count: i32,
pub tags: StringVec,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::gallery_like::Entity")]
GalleryLike,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::gallery_like::Entity> for Entity {
fn to() -> RelationDef {
Relation::GalleryLike.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,42 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "hashtag")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
pub name: String,
#[sea_orm(column_name = "mentionedUserIds")]
pub mentioned_user_ids: StringVec,
#[sea_orm(column_name = "mentionedUsersCount")]
pub mentioned_users_count: i32,
#[sea_orm(column_name = "mentionedLocalUserIds")]
pub mentioned_local_user_ids: StringVec,
#[sea_orm(column_name = "mentionedLocalUsersCount")]
pub mentioned_local_users_count: i32,
#[sea_orm(column_name = "mentionedRemoteUserIds")]
pub mentioned_remote_user_ids: StringVec,
#[sea_orm(column_name = "mentionedRemoteUsersCount")]
pub mentioned_remote_users_count: i32,
#[sea_orm(column_name = "attachedUserIds")]
pub attached_user_ids: StringVec,
#[sea_orm(column_name = "attachedUsersCount")]
pub attached_users_count: i32,
#[sea_orm(column_name = "attachedLocalUserIds")]
pub attached_local_user_ids: StringVec,
#[sea_orm(column_name = "attachedLocalUsersCount")]
pub attached_local_users_count: i32,
#[sea_orm(column_name = "attachedRemoteUserIds")]
pub attached_remote_user_ids: StringVec,
#[sea_orm(column_name = "attachedRemoteUsersCount")]
pub attached_remote_users_count: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,58 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "instance")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "caughtAt")]
pub caught_at: DateTimeWithTimeZone,
pub host: String,
#[sea_orm(column_name = "usersCount")]
pub users_count: i32,
#[sea_orm(column_name = "notesCount")]
pub notes_count: i32,
#[sea_orm(column_name = "followingCount")]
pub following_count: i32,
#[sea_orm(column_name = "followersCount")]
pub followers_count: i32,
#[sea_orm(column_name = "latestRequestSentAt")]
pub latest_request_sent_at: Option<DateTimeWithTimeZone>,
#[sea_orm(column_name = "latestStatus")]
pub latest_status: Option<i32>,
#[sea_orm(column_name = "latestRequestReceivedAt")]
pub latest_request_received_at: Option<DateTimeWithTimeZone>,
#[sea_orm(column_name = "lastCommunicatedAt")]
pub last_communicated_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "isNotResponding")]
pub is_not_responding: bool,
#[sea_orm(column_name = "softwareName")]
pub software_name: Option<String>,
#[sea_orm(column_name = "softwareVersion")]
pub software_version: Option<String>,
#[sea_orm(column_name = "openRegistrations")]
pub open_registrations: Option<bool>,
pub name: Option<String>,
pub description: Option<String>,
#[sea_orm(column_name = "maintainerName")]
pub maintainer_name: Option<String>,
#[sea_orm(column_name = "maintainerEmail")]
pub maintainer_email: Option<String>,
#[sea_orm(column_name = "infoUpdatedAt")]
pub info_updated_at: Option<DateTimeWithTimeZone>,
#[sea_orm(column_name = "isSuspended")]
pub is_suspended: bool,
#[sea_orm(column_name = "iconUrl")]
pub icon_url: Option<String>,
#[sea_orm(column_name = "themeColor")]
pub theme_color: Option<String>,
#[sea_orm(column_name = "faviconUrl")]
pub favicon_url: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,77 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "messaging_message")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "recipientId")]
pub recipient_id: Option<String>,
pub text: Option<String>,
#[sea_orm(column_name = "isRead")]
pub is_read: bool,
#[sea_orm(column_name = "fileId")]
pub file_id: Option<String>,
#[sea_orm(column_name = "groupId")]
pub group_id: Option<String>,
pub reads: StringVec,
pub uri: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::drive_file::Entity",
from = "Column::FileId",
to = "super::drive_file::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
DriveFile,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User2,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::RecipientId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User1,
#[sea_orm(
belongs_to = "super::user_group::Entity",
from = "Column::GroupId",
to = "super::user_group::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserGroup,
}
impl Related<super::drive_file::Entity> for Entity {
fn to() -> RelationDef {
Relation::DriveFile.def()
}
}
impl Related<super::user_group::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroup.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,212 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use super::sea_orm_active_enums::MetaSensitivemediadetectionEnum;
use super::sea_orm_active_enums::MetaSensitivemediadetectionsensitivityEnum;
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "meta")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
pub name: Option<String>,
pub description: Option<String>,
#[sea_orm(column_name = "maintainerName")]
pub maintainer_name: Option<String>,
#[sea_orm(column_name = "maintainerEmail")]
pub maintainer_email: Option<String>,
#[sea_orm(column_name = "disableRegistration")]
pub disable_registration: bool,
#[sea_orm(column_name = "disableLocalTimeline")]
pub disable_local_timeline: bool,
#[sea_orm(column_name = "disableGlobalTimeline")]
pub disable_global_timeline: bool,
#[sea_orm(column_name = "useStarForReactionFallback")]
pub use_star_for_reaction_fallback: bool,
pub langs: StringVec,
#[sea_orm(column_name = "hiddenTags")]
pub hidden_tags: StringVec,
#[sea_orm(column_name = "blockedHosts")]
pub blocked_hosts: StringVec,
#[sea_orm(column_name = "mascotImageUrl")]
pub mascot_image_url: Option<String>,
#[sea_orm(column_name = "bannerUrl")]
pub banner_url: Option<String>,
#[sea_orm(column_name = "errorImageUrl")]
pub error_image_url: Option<String>,
#[sea_orm(column_name = "iconUrl")]
pub icon_url: Option<String>,
#[sea_orm(column_name = "cacheRemoteFiles")]
pub cache_remote_files: bool,
#[sea_orm(column_name = "enableRecaptcha")]
pub enable_recaptcha: bool,
#[sea_orm(column_name = "recaptchaSiteKey")]
pub recaptcha_site_key: Option<String>,
#[sea_orm(column_name = "recaptchaSecretKey")]
pub recaptcha_secret_key: Option<String>,
#[sea_orm(column_name = "localDriveCapacityMb")]
pub local_drive_capacity_mb: i32,
#[sea_orm(column_name = "remoteDriveCapacityMb")]
pub remote_drive_capacity_mb: i32,
#[sea_orm(column_name = "summalyProxy")]
pub summaly_proxy: Option<String>,
#[sea_orm(column_name = "enableEmail")]
pub enable_email: bool,
pub email: Option<String>,
#[sea_orm(column_name = "smtpSecure")]
pub smtp_secure: bool,
#[sea_orm(column_name = "smtpHost")]
pub smtp_host: Option<String>,
#[sea_orm(column_name = "smtpPort")]
pub smtp_port: Option<i32>,
#[sea_orm(column_name = "smtpUser")]
pub smtp_user: Option<String>,
#[sea_orm(column_name = "smtpPass")]
pub smtp_pass: Option<String>,
#[sea_orm(column_name = "enableServiceWorker")]
pub enable_service_worker: bool,
#[sea_orm(column_name = "swPublicKey")]
pub sw_public_key: Option<String>,
#[sea_orm(column_name = "swPrivateKey")]
pub sw_private_key: Option<String>,
#[sea_orm(column_name = "enableTwitterIntegration")]
pub enable_twitter_integration: bool,
#[sea_orm(column_name = "twitterConsumerKey")]
pub twitter_consumer_key: Option<String>,
#[sea_orm(column_name = "twitterConsumerSecret")]
pub twitter_consumer_secret: Option<String>,
#[sea_orm(column_name = "enableGithubIntegration")]
pub enable_github_integration: bool,
#[sea_orm(column_name = "githubClientId")]
pub github_client_id: Option<String>,
#[sea_orm(column_name = "githubClientSecret")]
pub github_client_secret: Option<String>,
#[sea_orm(column_name = "enableDiscordIntegration")]
pub enable_discord_integration: bool,
#[sea_orm(column_name = "discordClientId")]
pub discord_client_id: Option<String>,
#[sea_orm(column_name = "discordClientSecret")]
pub discord_client_secret: Option<String>,
#[sea_orm(column_name = "pinnedUsers")]
pub pinned_users: StringVec,
#[sea_orm(column_name = "ToSUrl")]
pub to_s_url: Option<String>,
#[sea_orm(column_name = "repositoryUrl")]
pub repository_url: String,
#[sea_orm(column_name = "feedbackUrl")]
pub feedback_url: Option<String>,
#[sea_orm(column_name = "useObjectStorage")]
pub use_object_storage: bool,
#[sea_orm(column_name = "objectStorageBucket")]
pub object_storage_bucket: Option<String>,
#[sea_orm(column_name = "objectStoragePrefix")]
pub object_storage_prefix: Option<String>,
#[sea_orm(column_name = "objectStorageBaseUrl")]
pub object_storage_base_url: Option<String>,
#[sea_orm(column_name = "objectStorageEndpoint")]
pub object_storage_endpoint: Option<String>,
#[sea_orm(column_name = "objectStorageRegion")]
pub object_storage_region: Option<String>,
#[sea_orm(column_name = "objectStorageAccessKey")]
pub object_storage_access_key: Option<String>,
#[sea_orm(column_name = "objectStorageSecretKey")]
pub object_storage_secret_key: Option<String>,
#[sea_orm(column_name = "objectStoragePort")]
pub object_storage_port: Option<i32>,
#[sea_orm(column_name = "objectStorageUseSSL")]
pub object_storage_use_ssl: bool,
#[sea_orm(column_name = "proxyAccountId")]
pub proxy_account_id: Option<String>,
#[sea_orm(column_name = "objectStorageUseProxy")]
pub object_storage_use_proxy: bool,
#[sea_orm(column_name = "enableHcaptcha")]
pub enable_hcaptcha: bool,
#[sea_orm(column_name = "hcaptchaSiteKey")]
pub hcaptcha_site_key: Option<String>,
#[sea_orm(column_name = "hcaptchaSecretKey")]
pub hcaptcha_secret_key: Option<String>,
#[sea_orm(column_name = "objectStorageSetPublicRead")]
pub object_storage_set_public_read: bool,
#[sea_orm(column_name = "pinnedPages")]
pub pinned_pages: StringVec,
#[sea_orm(column_name = "backgroundImageUrl")]
pub background_image_url: Option<String>,
#[sea_orm(column_name = "logoImageUrl")]
pub logo_image_url: Option<String>,
#[sea_orm(column_name = "pinnedClipId")]
pub pinned_clip_id: Option<String>,
#[sea_orm(column_name = "objectStorageS3ForcePathStyle")]
pub object_storage_s3_force_path_style: bool,
#[sea_orm(column_name = "allowedHosts")]
pub allowed_hosts: Option<StringVec>,
#[sea_orm(column_name = "secureMode")]
pub secure_mode: Option<bool>,
#[sea_orm(column_name = "privateMode")]
pub private_mode: Option<bool>,
#[sea_orm(column_name = "deeplAuthKey")]
pub deepl_auth_key: Option<String>,
#[sea_orm(column_name = "deeplIsPro")]
pub deepl_is_pro: bool,
#[sea_orm(column_name = "emailRequiredForSignup")]
pub email_required_for_signup: bool,
#[sea_orm(column_name = "themeColor")]
pub theme_color: Option<String>,
#[sea_orm(column_name = "defaultLightTheme")]
pub default_light_theme: Option<String>,
#[sea_orm(column_name = "defaultDarkTheme")]
pub default_dark_theme: Option<String>,
#[sea_orm(column_name = "sensitiveMediaDetection")]
pub sensitive_media_detection: MetaSensitivemediadetectionEnum,
#[sea_orm(column_name = "sensitiveMediaDetectionSensitivity")]
pub sensitive_media_detection_sensitivity: MetaSensitivemediadetectionsensitivityEnum,
#[sea_orm(column_name = "setSensitiveFlagAutomatically")]
pub set_sensitive_flag_automatically: bool,
#[sea_orm(column_name = "enableIpLogging")]
pub enable_ip_logging: bool,
#[sea_orm(column_name = "enableSensitiveMediaDetectionForVideos")]
pub enable_sensitive_media_detection_for_videos: bool,
#[sea_orm(column_name = "enableActiveEmailValidation")]
pub enable_active_email_validation: bool,
#[sea_orm(column_name = "customMOTD")]
pub custom_motd: StringVec,
#[sea_orm(column_name = "customSplashIcons")]
pub custom_splash_icons: StringVec,
#[sea_orm(column_name = "disableRecommendedTimeline")]
pub disable_recommended_timeline: bool,
#[sea_orm(column_name = "recommendedInstances")]
pub recommended_instances: StringVec,
#[sea_orm(column_name = "enableGuestTimeline")]
pub enable_guest_timeline: bool,
#[sea_orm(column_name = "defaultReaction")]
pub default_reaction: String,
#[sea_orm(column_name = "libreTranslateApiUrl")]
pub libre_translate_api_url: Option<String>,
#[sea_orm(column_name = "libreTranslateApiKey")]
pub libre_translate_api_key: Option<String>,
#[sea_orm(column_name = "silencedHosts")]
pub silenced_hosts: StringVec,
#[sea_orm(column_name = "experimentalFeatures", column_type = "JsonBinary")]
pub experimental_features: Json,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::ProxyAccountId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,17 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "migrations")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub timestamp: i64,
pub name: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,37 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "moderation_log")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
pub r#type: String,
#[sea_orm(column_type = "JsonBinary")]
pub info: Json,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,50 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use super::sea_orm_active_enums::MutedNoteReasonEnum;
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "muted_note")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
#[sea_orm(column_name = "userId")]
pub user_id: String,
pub reason: MutedNoteReasonEnum,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,40 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "muting")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "muteeId")]
pub mutee_id: String,
#[sea_orm(column_name = "muterId")]
pub muter_id: String,
#[sea_orm(column_name = "expiresAt")]
pub expires_at: Option<DateTimeWithTimeZone>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::MuterId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User2,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::MuteeId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User1,
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,51 @@
#[macro_export]
macro_rules! impl_json_newtype {
($a:tt) => {
impl From<$a> for Value {
fn from(source: $a) -> Self {
Value::Json(serde_json::to_value(source).ok().map(Box::new))
}
}
impl TryGetable for $a {
fn try_get_by<I: sea_orm::ColIdx>(
res: &QueryResult,
idx: I,
) -> Result<Self, TryGetError> {
let json_value: serde_json::Value =
res.try_get_by(idx).map_err(TryGetError::DbErr)?;
serde_json::from_value(json_value)
.map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string())))
}
}
impl sea_query::ValueType for $a {
fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {
match v {
Value::Json(Some(x)) => Ok($a(
serde_json::from_value(*x).map_err(|_| sea_query::ValueTypeErr)?
)),
_ => Err(sea_query::ValueTypeErr),
}
}
fn type_name() -> String {
stringify!($a).to_owned()
}
fn array_type() -> sea_query::ArrayType {
sea_query::ArrayType::Json
}
fn column_type() -> sea_query::ColumnType {
sea_query::ColumnType::JsonBinary
}
}
impl sea_query::Nullable for $a {
fn null() -> Value {
Value::Json(None)
}
}
};
}

View file

@ -0,0 +1,30 @@
mod macros;
use cfg_if::cfg_if;
use derive_more::{From, Into};
use sea_orm::{sea_query, DbErr, QueryResult, TryGetError, TryGetable, Value};
use serde::{Deserialize, Serialize};
use crate::impl_json_newtype;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, From, Into, Default)]
pub struct JsonKeyword(pub Vec<Vec<String>>);
impl_json_newtype!(JsonKeyword);
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, From, Into, Default)]
pub struct JsonStringVec(pub Vec<String>);
impl_json_newtype!(JsonStringVec);
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, From, Into, Default)]
pub struct JsonI32Vec(pub Vec<i32>);
impl_json_newtype!(JsonI32Vec);
cfg_if! {
if #[cfg(feature = "noarray")] {
pub type StringVec = JsonStringVec;
pub type I32Vec = JsonI32Vec;
} else {
pub type StringVec = Vec<String>;
pub type I32Vec = Vec<i32>;
}
}

View file

@ -0,0 +1,236 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use super::sea_orm_active_enums::NoteVisibilityEnum;
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "note")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "replyId")]
pub reply_id: Option<String>,
#[sea_orm(column_name = "renoteId")]
pub renote_id: Option<String>,
#[sea_orm(column_type = "Text", nullable)]
pub text: Option<String>,
pub name: Option<String>,
pub cw: Option<String>,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "localOnly")]
pub local_only: bool,
#[sea_orm(column_name = "renoteCount")]
pub renote_count: i16,
#[sea_orm(column_name = "repliesCount")]
pub replies_count: i16,
#[sea_orm(column_type = "JsonBinary")]
pub reactions: Json,
pub visibility: NoteVisibilityEnum,
pub uri: Option<String>,
pub score: i32,
#[sea_orm(column_name = "fileIds")]
pub file_ids: StringVec,
#[sea_orm(column_name = "attachedFileTypes")]
pub attached_file_types: StringVec,
#[sea_orm(column_name = "visibleUserIds")]
pub visible_user_ids: StringVec,
pub mentions: StringVec,
#[sea_orm(column_name = "mentionedRemoteUsers", column_type = "Text")]
pub mentioned_remote_users: String,
pub emojis: StringVec,
pub tags: StringVec,
#[sea_orm(column_name = "hasPoll")]
pub has_poll: bool,
#[sea_orm(column_name = "userHost")]
pub user_host: Option<String>,
#[sea_orm(column_name = "replyUserId")]
pub reply_user_id: Option<String>,
#[sea_orm(column_name = "replyUserHost")]
pub reply_user_host: Option<String>,
#[sea_orm(column_name = "renoteUserId")]
pub renote_user_id: Option<String>,
#[sea_orm(column_name = "renoteUserHost")]
pub renote_user_host: Option<String>,
pub url: Option<String>,
#[sea_orm(column_name = "channelId")]
pub channel_id: Option<String>,
#[sea_orm(column_name = "threadId")]
pub thread_id: Option<String>,
#[sea_orm(column_name = "updatedAt")]
pub updated_at: Option<DateTimeWithTimeZone>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::antenna_note::Entity")]
AntennaNote,
#[sea_orm(
belongs_to = "super::channel::Entity",
from = "Column::ChannelId",
to = "super::channel::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Channel,
#[sea_orm(has_many = "super::channel_note_pining::Entity")]
ChannelNotePining,
#[sea_orm(has_many = "super::clip_note::Entity")]
ClipNote,
#[sea_orm(has_many = "super::muted_note::Entity")]
MutedNote,
#[sea_orm(
belongs_to = "Entity",
from = "Column::ReplyId",
to = "Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
SelfRef2,
#[sea_orm(
belongs_to = "Entity",
from = "Column::RenoteId",
to = "Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
SelfRef1,
#[sea_orm(has_many = "super::note_edit::Entity")]
NoteEdit,
#[sea_orm(has_many = "super::note_favorite::Entity")]
NoteFavorite,
#[sea_orm(has_many = "super::note_reaction::Entity")]
NoteReaction,
#[sea_orm(has_many = "super::note_unread::Entity")]
NoteUnread,
#[sea_orm(has_many = "super::note_watching::Entity")]
NoteWatching,
#[sea_orm(has_many = "super::notification::Entity")]
Notification,
#[sea_orm(has_one = "super::poll::Entity")]
Poll,
#[sea_orm(has_many = "super::poll_vote::Entity")]
PollVote,
#[sea_orm(has_one = "super::promo_note::Entity")]
PromoNote,
#[sea_orm(has_many = "super::promo_read::Entity")]
PromoRead,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
#[sea_orm(has_many = "super::user_note_pining::Entity")]
UserNotePining,
}
impl Related<super::antenna_note::Entity> for Entity {
fn to() -> RelationDef {
Relation::AntennaNote.def()
}
}
impl Related<super::channel::Entity> for Entity {
fn to() -> RelationDef {
Relation::Channel.def()
}
}
impl Related<super::channel_note_pining::Entity> for Entity {
fn to() -> RelationDef {
Relation::ChannelNotePining.def()
}
}
impl Related<super::clip_note::Entity> for Entity {
fn to() -> RelationDef {
Relation::ClipNote.def()
}
}
impl Related<super::muted_note::Entity> for Entity {
fn to() -> RelationDef {
Relation::MutedNote.def()
}
}
impl Related<super::note_edit::Entity> for Entity {
fn to() -> RelationDef {
Relation::NoteEdit.def()
}
}
impl Related<super::note_favorite::Entity> for Entity {
fn to() -> RelationDef {
Relation::NoteFavorite.def()
}
}
impl Related<super::note_reaction::Entity> for Entity {
fn to() -> RelationDef {
Relation::NoteReaction.def()
}
}
impl Related<super::note_unread::Entity> for Entity {
fn to() -> RelationDef {
Relation::NoteUnread.def()
}
}
impl Related<super::note_watching::Entity> for Entity {
fn to() -> RelationDef {
Relation::NoteWatching.def()
}
}
impl Related<super::notification::Entity> for Entity {
fn to() -> RelationDef {
Relation::Notification.def()
}
}
impl Related<super::poll::Entity> for Entity {
fn to() -> RelationDef {
Relation::Poll.def()
}
}
impl Related<super::poll_vote::Entity> for Entity {
fn to() -> RelationDef {
Relation::PollVote.def()
}
}
impl Related<super::promo_note::Entity> for Entity {
fn to() -> RelationDef {
Relation::PromoNote.def()
}
}
impl Related<super::promo_read::Entity> for Entity {
fn to() -> RelationDef {
Relation::PromoRead.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::user_note_pining::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserNotePining.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,41 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
use super::newtype::StringVec;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "note_edit")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
#[sea_orm(column_type = "Text", nullable)]
pub text: Option<String>,
pub cw: Option<String>,
#[sea_orm(column_name = "fileIds")]
pub file_ids: StringVec,
#[sea_orm(column_name = "updatedAt")]
pub updated_at: DateTimeWithTimeZone,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,50 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "note_favorite")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,51 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "note_reaction")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
pub reaction: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,36 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "note_thread_muting")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "threadId")]
pub thread_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,56 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)]
#[sea_orm(table_name = "note_unread")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "noteId")]
pub note_id: String,
#[sea_orm(column_name = "noteUserId")]
pub note_user_id: String,
#[sea_orm(column_name = "isSpecified")]
pub is_specified: bool,
#[sea_orm(column_name = "isMentioned")]
pub is_mentioned: bool,
#[sea_orm(column_name = "noteChannelId")]
pub note_channel_id: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::note::Entity",
from = "Column::NoteId",
to = "super::note::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Note,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
}
impl Related<super::note::Entity> for Entity {
fn to() -> RelationDef {
Relation::Note.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

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