Compare commits
122 commits
ed4d4e6897
...
2bfe7a15d5
Author | SHA1 | Date | |
---|---|---|---|
vib | 2bfe7a15d5 | ||
Norm | e58c940d6f | ||
Johann150 | 08af6fda37 | ||
Johann150 | 0c8a3cfeec | ||
Johann150 | 8bc366fde0 | ||
Johann150 | 417d252e9d | ||
Johann150 | b54e07caec | ||
Johann150 | e0560dbe9e | ||
Johann150 | 5b898c6c82 | ||
Johann150 | 6010884e62 | ||
Johann150 | b423d23cf6 | ||
Johann150 | 29714d1ae0 | ||
Johann150 | 7bf4d4426a | ||
Johann150 | d28931bf00 | ||
Johann150 | 2a46719f31 | ||
Johann150 | 7f564431be | ||
Johann150 | 0fbd7fa492 | ||
Johann150 | 3aaa9facc6 | ||
Johann150 | 8f09b05e7c | ||
Johann150 | 8b0b7ff525 | ||
Johann150 | 0b7c9095bf | ||
Johann150 | 338e898f56 | ||
Puniko | 3a9d283630 | ||
Johann150 | ed27f61a4d | ||
Chloe Kudryavtsev | ed9d4023d4 | ||
Johann150 | 76a8e000a3 | ||
Johann150 | a673647fba | ||
Johann150 | eea2eb4919 | ||
Johann150 | 114d416de0 | ||
Johann150 | c2372315f7 | ||
Norm | 09bc3cf95a | ||
Johann150 | de3cdb5833 | ||
Norm | a732cdc1ad | ||
Norm | a8f82050c8 | ||
Norm | 8e12b9a33e | ||
Norm | 6583d0c43d | ||
Johann150 | c02a03168d | ||
Johann150 | 85419326f8 | ||
Johann150 | eaa11647f0 | ||
Johann150 | 61a2db49df | ||
Johann150 | 79ddbafd0d | ||
Norm | 0e1459e5cf | ||
Johann150 | e8e82dac82 | ||
Norm | 9690244848 | ||
Norm | 4db25e4b1f | ||
Norm | 549302e9c0 | ||
Norm | a3354904af | ||
Norm | 28f65bebfc | ||
Norm | 2204adc657 | ||
Norm | b11e4053db | ||
Johann150 | e2ef800708 | ||
Johann150 | a7048f17f7 | ||
Johann150 | ddf3e2c3db | ||
Johann150 | 52afff800a | ||
Johann150 | 33f0b24c56 | ||
Andy | 7685b92511 | ||
Andy | 8276bd3bdc | ||
Andy | aed2752470 | ||
Andy | 4a3b91d658 | ||
Johann150 | 9317d25078 | ||
Johann150 | fc36bb8880 | ||
Johann150 | 711bb8be7d | ||
Johann150 | 275136cf8b | ||
Johann150 | aa33708b90 | ||
Norm | d75e295ee8 | ||
Norm | 766ab1c4c4 | ||
Johann150 | 99c459a21a | ||
Johann150 | bd68096ea9 | ||
Johann150 | c411669133 | ||
Johann150 | 639fa74d43 | ||
Johann150 | 3bf7deb233 | ||
Johann150 | 2520633210 | ||
Johann150 | 4574db523a | ||
Johann150 | 263fb94f3f | ||
Johann150 | 0e3321c106 | ||
Johann150 | 677ee537d1 | ||
Johann150 | 1e539e6af5 | ||
Johann150 | 0e5f744560 | ||
Norm | 8f782f8ce5 | ||
Johann150 | 6c7f1774e3 | ||
Johann150 | af43df15ca | ||
Johann150 | 5f83383ab8 | ||
Johann150 | 8c759dde6c | ||
Johann150 | 84d83d908a | ||
Johann150 | 16d091497a | ||
Johann150 | ef53ec276a | ||
Johann150 | 3582fd8260 | ||
Johann150 | 6256ddbd30 | ||
Johann150 | 00fcc238f7 | ||
Johann150 | 9f1670d5fd | ||
Norm | ff31b8b06d | ||
Johann150 | e317a771b3 | ||
Johann150 | 398ee6435b | ||
Johann150 | ffff2ae5ef | ||
Johann150 | ccc8bf0289 | ||
Johann150 | a231b36d59 | ||
Johann150 | 8e9c65fab0 | ||
Norm | 78a3051313 | ||
Norm | 78717e85d3 | ||
Norm | a9d3cae511 | ||
Norm | bd27b7ca3a | ||
Norm | e28a9eb8e8 | ||
Norm | e5a4c5d2d0 | ||
Norm | 6bba55c196 | ||
Norm | 1d469f3c34 | ||
Norm | 3f0228e14c | ||
Johann150 | 73f81177b4 | ||
Johann150 | 6a26da3516 | ||
Johann150 | 5ea744b1b2 | ||
Johann150 | ae6ba05306 | ||
21069223e3 | |||
Johann150 | d4d1e03479 | ||
Norm | 5513a3eb3a | ||
Johann150 | d5dd7c1ef5 | ||
Johann150 | a80521b6a8 | ||
Norm | 030394b30d | ||
Johann150 | 768d9bbdfb | ||
Johann150 | 3ef1a4b0f9 | ||
Johann150 | ae59ce51b0 | ||
Johann150 | 14a9b9bedd | ||
Johann150 | 985a13f47f | ||
Norm | 3e46433ede |
|
@ -133,3 +133,10 @@ redis:
|
||||||
#allowedPrivateNetworks: [
|
#allowedPrivateNetworks: [
|
||||||
# '127.0.0.1/32'
|
# '127.0.0.1/32'
|
||||||
#]
|
#]
|
||||||
|
|
||||||
|
# images used on error screens. You can use absolute or relative URLs.
|
||||||
|
# If you use relative URLs, be aware that the URL may be used on different pages/paths, so the path component should be absolute.
|
||||||
|
#images:
|
||||||
|
# info: /twemoji/1f440.svg
|
||||||
|
# notFound: /twemoji/2049.svg
|
||||||
|
# error: /twemoji/1f480.svg
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.autogen
|
.autogen
|
||||||
.vscode
|
|
||||||
.config
|
.config
|
||||||
|
.woodpecker
|
||||||
Dockerfile
|
Dockerfile
|
||||||
build/
|
build/
|
||||||
built/
|
built/
|
||||||
|
|
|
@ -2,9 +2,10 @@ root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 2
|
indent_size = 4
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.yml]
|
[*.yml]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
6
.gitattributes
vendored
|
@ -1,7 +1 @@
|
||||||
*.svg -diff -text
|
*.svg -diff -text
|
||||||
*.psd -diff -text
|
|
||||||
*.ai -diff -text
|
|
||||||
*.mqo -diff -text
|
|
||||||
*.glb -diff -text
|
|
||||||
*.blend -diff -text
|
|
||||||
*.afdesign -diff -text
|
|
||||||
|
|
5
.gitignore
vendored
|
@ -1,6 +1,6 @@
|
||||||
# Visual Studio Code
|
# Visual Studio Code
|
||||||
/.vscode
|
/.vscode
|
||||||
!/.vscode/extensions.json
|
/.vsls.json
|
||||||
|
|
||||||
# Intelij-IDEA
|
# Intelij-IDEA
|
||||||
/.idea
|
/.idea
|
||||||
|
@ -11,6 +11,9 @@
|
||||||
# nano
|
# nano
|
||||||
.swp
|
.swp
|
||||||
|
|
||||||
|
# vimlocal
|
||||||
|
.vimlocal
|
||||||
|
|
||||||
# Node.js
|
# Node.js
|
||||||
node_modules
|
node_modules
|
||||||
report.*.json
|
report.*.json
|
||||||
|
|
8
.vscode/extensions.json
vendored
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"editorconfig.editorconfig",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"Vue.volar",
|
|
||||||
"Vue.vscode-typescript-vue-plugin"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "http://json.schemastore.org/vsls",
|
|
||||||
"gitignore": "exclude"
|
|
||||||
}
|
|
22
.woodpecker/lint-sw.yml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
clone:
|
||||||
|
git:
|
||||||
|
image: woodpeckerci/plugin-git
|
||||||
|
settings:
|
||||||
|
depth: 1 # CI does not need commit history
|
||||||
|
recursive: true
|
||||||
|
|
||||||
|
pipeline:
|
||||||
|
install:
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
image: node:18.6.0
|
||||||
|
commands:
|
||||||
|
- yarn install
|
||||||
|
lint:
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
image: node:18.6.0
|
||||||
|
commands:
|
||||||
|
- yarn workspace sw run lint
|
|
@ -316,8 +316,8 @@ This does not apply when using the Composition API since reactivation is manual.
|
||||||
If you import json in TypeScript, the json file will be spit out together with the TypeScript file into the dist directory when compiling with tsc. This behavior may cause unintentional rewriting of files, so when importing json files, be sure to check whether the files are allowed to be rewritten or not. If you do not want the file to be rewritten, you should make sure that the file can be rewritten by importing the json file. If you do not want the file to be rewritten, use functions such as `fs.readFileSync` to read the file instead of importing it.
|
If you import json in TypeScript, the json file will be spit out together with the TypeScript file into the dist directory when compiling with tsc. This behavior may cause unintentional rewriting of files, so when importing json files, be sure to check whether the files are allowed to be rewritten or not. If you do not want the file to be rewritten, you should make sure that the file can be rewritten by importing the json file. If you do not want the file to be rewritten, use functions such as `fs.readFileSync` to read the file instead of importing it.
|
||||||
|
|
||||||
### Component style definitions do not have a `margin`
|
### Component style definitions do not have a `margin`
|
||||||
Setting the `margin` of a component may be confusing.
|
~~Setting the `margin` of a component may be confusing. Instead, it should always be the user of a component that sets a `margin`.~~
|
||||||
Instead, it should always be the user of a component that sets a `margin`.
|
This was a philosophy used previously. Hoever it now seems a better idea to add a default margin to the top level element of a component which can be easily overwritten on the usage of that component with a `style` attribute.
|
||||||
|
|
||||||
### Do not use the word "follow" in HTML class names
|
### Do not use the word "follow" in HTML class names
|
||||||
This has caused things to be blocked by an ad blocker in the past.
|
This has caused things to be blocked by an ad blocker in the past.
|
||||||
|
|
10
COPYING
|
@ -1,6 +1,6 @@
|
||||||
Unless otherwise stated this repository is
|
Unless otherwise stated this repository is
|
||||||
Copyright © 2014-2022 syuilo and contributors
|
Copyright © 2014-2022 syuilo and contributors
|
||||||
Copyright © 2022 FoundKey contributors
|
Copyright © 2022-2023 FoundKey contributors
|
||||||
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
|
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
|
||||||
(You may be able to run `git shortlog -se` to see a full list of authors.)
|
(You may be able to run `git shortlog -se` to see a full list of authors.)
|
||||||
|
|
||||||
|
@ -13,3 +13,11 @@ https://github.com/muan/emojilib/blob/master/LICENSE
|
||||||
RsaSignature2017 implementation by Transmute Industries Inc
|
RsaSignature2017 implementation by Transmute Industries Inc
|
||||||
License: MIT
|
License: MIT
|
||||||
https://github.com/transmute-industries/RsaSignature2017/blob/master/LICENSE
|
https://github.com/transmute-industries/RsaSignature2017/blob/master/LICENSE
|
||||||
|
|
||||||
|
Chiptune2.js by Simon Gündling
|
||||||
|
License: MIT
|
||||||
|
https://github.com/deskjet/chiptune2.js#license
|
||||||
|
|
||||||
|
libopenmpt (as part of openmpt) by OpenMPT
|
||||||
|
License: BSD 3-Clause
|
||||||
|
https://github.com/OpenMPT/openmpt/blob/master/LICENSE
|
||||||
|
|
Before Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 317 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 200 KiB |
BIN
assets/ai.png
Before Width: | Height: | Size: 235 KiB |
Before Width: | Height: | Size: 238 KiB |
Before Width: | Height: | Size: 148 KiB |
BIN
assets/title.png
Before Width: | Height: | Size: 3.8 KiB |
|
@ -36,7 +36,7 @@ gulp.task('copy:client:locales', cb => {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('build:backend:script', () => {
|
gulp.task('build:backend:script', () => {
|
||||||
return gulp.src(['./packages/backend/src/server/web/boot.js', './packages/backend/src/server/web/bios.js', './packages/backend/src/server/web/cli.js'])
|
return gulp.src(['./packages/backend/src/server/web/boot.js'])
|
||||||
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
|
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
|
||||||
.pipe(terser({
|
.pipe(terser({
|
||||||
toplevel: true
|
toplevel: true
|
||||||
|
@ -45,7 +45,7 @@ gulp.task('build:backend:script', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('build:backend:style', () => {
|
gulp.task('build:backend:style', () => {
|
||||||
return gulp.src(['./packages/backend/src/server/web/style.css', './packages/backend/src/server/web/bios.css', './packages/backend/src/server/web/cli.css'])
|
return gulp.src(['./packages/backend/src/server/web/style.css'])
|
||||||
.pipe(cssnano({
|
.pipe(cssnano({
|
||||||
zindex: false
|
zindex: false
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -96,6 +96,8 @@ unfollow: "Unfollow"
|
||||||
followRequestPending: "Follow request pending"
|
followRequestPending: "Follow request pending"
|
||||||
renote: "Renote"
|
renote: "Renote"
|
||||||
unrenote: "Take back renote"
|
unrenote: "Take back renote"
|
||||||
|
unrenoteAll: "Take back all renotes"
|
||||||
|
unrenoteAllConfirm: "Are you sure that you want to take back all renotes of this note?"
|
||||||
quote: "Quote"
|
quote: "Quote"
|
||||||
pinnedNote: "Pinned note"
|
pinnedNote: "Pinned note"
|
||||||
you: "You"
|
you: "You"
|
||||||
|
@ -1095,6 +1097,7 @@ _permissions:
|
||||||
"write:notes": "Create and delete notes"
|
"write:notes": "Create and delete notes"
|
||||||
"read:notifications": "Read notifications"
|
"read:notifications": "Read notifications"
|
||||||
"write:notifications": "Mark notifications as read and create custom notifications"
|
"write:notifications": "Mark notifications as read and create custom notifications"
|
||||||
|
"read:reactions": "View reactions"
|
||||||
"write:reactions": "Create and delete reactions"
|
"write:reactions": "Create and delete reactions"
|
||||||
"write:votes": "Vote in polls"
|
"write:votes": "Vote in polls"
|
||||||
"read:pages": "List and read pages"
|
"read:pages": "List and read pages"
|
||||||
|
|
11
package.json
|
@ -18,7 +18,7 @@
|
||||||
"migrateandstart": "yarn migrate && yarn start",
|
"migrateandstart": "yarn migrate && yarn start",
|
||||||
"gulp": "gulp build",
|
"gulp": "gulp build",
|
||||||
"watch": "yarn dev",
|
"watch": "yarn dev",
|
||||||
"dev": "node ./scripts/dev.js",
|
"dev": "node ./scripts/dev.mjs",
|
||||||
"lint": "yarn workspaces foreach run lint",
|
"lint": "yarn workspaces foreach run lint",
|
||||||
"cy:open": "cypress open --browser --e2e --config-file=cypress.config.ts",
|
"cy:open": "cypress open --browser --e2e --config-file=cypress.config.ts",
|
||||||
"cy:run": "cypress run",
|
"cy:run": "cypress run",
|
||||||
|
@ -26,8 +26,8 @@
|
||||||
"mocha": "yarn workspace backend run mocha",
|
"mocha": "yarn workspace backend run mocha",
|
||||||
"test": "yarn mocha",
|
"test": "yarn mocha",
|
||||||
"format": "gulp format",
|
"format": "gulp format",
|
||||||
"clean": "node ./scripts/clean.js",
|
"clean": "node ./scripts/clean.mjs",
|
||||||
"clean-all": "node ./scripts/clean-all.js",
|
"clean-all": "node ./scripts/clean-all.mjs",
|
||||||
"cleanall": "yarn clean-all"
|
"cleanall": "yarn clean-all"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"argon2": "^0.30.2",
|
||||||
"execa": "5.1.1",
|
"execa": "5.1.1",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"gulp-cssnano": "2.1.3",
|
"gulp-cssnano": "2.1.3",
|
||||||
|
@ -46,11 +47,11 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/gulp": "4.0.9",
|
"@types/gulp": "4.0.9",
|
||||||
"@types/gulp-rename": "2.0.1",
|
"@types/gulp-rename": "2.0.1",
|
||||||
"@typescript-eslint/parser": "^5.44.0",
|
"@typescript-eslint/parser": "^5.46.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cypress": "10.3.0",
|
"cypress": "10.3.0",
|
||||||
"start-server-and-test": "1.14.0",
|
"start-server-and-test": "1.14.0",
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.4"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@3.3.0"
|
"packageManager": "yarn@3.3.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,11 @@ module.exports = {
|
||||||
extends: [
|
extends: [
|
||||||
'../shared/.eslintrc.js',
|
'../shared/.eslintrc.js',
|
||||||
],
|
],
|
||||||
|
plugins: [
|
||||||
|
'foundkey-custom-rules',
|
||||||
|
],
|
||||||
rules: {
|
rules: {
|
||||||
|
'foundkey-custom-rules/typeorm-prefer-count': 'error',
|
||||||
'import/order': ['warn', {
|
'import/order': ['warn', {
|
||||||
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
|
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
|
||||||
'pathGroups': [
|
'pathGroups': [
|
||||||
|
|
21
packages/backend/migration/1672607891750-remove-reversi.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export class removeReversi1672607891750 {
|
||||||
|
name = 'removeReversi1672607891750';
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`DROP TABLE "reversi_matching"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "reversi_game"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`CREATE TABLE "reversi_game" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "startedAt" TIMESTAMP WITH TIME ZONE, "user1Id" character varying(32) NOT NULL, "user2Id" character varying(32) NOT NULL, "user1Accepted" boolean NOT NULL DEFAULT false, "user2Accepted" boolean NOT NULL DEFAULT false, "black" integer, "isStarted" boolean NOT NULL DEFAULT false, "isEnded" boolean NOT NULL DEFAULT false, "winnerId" character varying(32), "surrendered" character varying(32), "logs" jsonb NOT NULL DEFAULT '[]', "map" character varying(64) array NOT NULL, "bw" character varying(32) NOT NULL, "isLlotheo" boolean NOT NULL DEFAULT false, "canPutEverywhere" boolean NOT NULL DEFAULT false, "loopedBoard" boolean NOT NULL DEFAULT false, "form1" jsonb DEFAULT null, "form2" jsonb DEFAULT null, "crc32" character varying(32), CONSTRAINT "PK_76b30eeba71b1193ad7c5311c3f" PRIMARY KEY ("id"))`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_b46ec40746efceac604142be1c" ON "reversi_game" ("createdAt")`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "reversi_matching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "parentId" character varying(32) NOT NULL, "childId" character varying(32) NOT NULL, CONSTRAINT "PK_880bd0afbab232f21c8b9d146cf" PRIMARY KEY ("id"))`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_b604d92d6c7aec38627f6eaf16" ON "reversi_matching" ("createdAt")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_3b25402709dd9882048c2bbade" ON "reversi_matching" ("parentId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_e247b23a3c9b45f89ec1299d06" ON "reversi_matching" ("childId")`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_f7467510c60a45ce5aca6292743" FOREIGN KEY ("user1Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_6649a4e8c5d5cf32fb03b5da9f6" FOREIGN KEY ("user2Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_3b25402709dd9882048c2bbade0" FOREIGN KEY ("parentId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_e247b23a3c9b45f89ec1299d066" FOREIGN KEY ("childId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
|
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
|
||||||
"watch": "node watch.mjs",
|
"watch": "node watch.mjs",
|
||||||
"lint": "eslint src --ext .ts",
|
"lint": "tsc --noEmit && eslint src --ext .ts",
|
||||||
"mocha": "cross-env NODE_ENV=test TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
"mocha": "cross-env NODE_ENV=test TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
||||||
"migrate": "npx typeorm migration:run -d ormconfig.js",
|
"migrate": "npx typeorm migration:run -d ormconfig.js",
|
||||||
"start": "node --experimental-json-modules ./built/index.js",
|
"start": "node --experimental-json-modules ./built/index.js",
|
||||||
|
@ -166,14 +166,15 @@
|
||||||
"@types/web-push": "3.3.2",
|
"@types/web-push": "3.3.2",
|
||||||
"@types/websocket": "1.0.5",
|
"@types/websocket": "1.0.5",
|
||||||
"@types/ws": "8.5.3",
|
"@types/ws": "8.5.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
"@typescript-eslint/eslint-plugin": "^5.46.1",
|
||||||
"@typescript-eslint/parser": "^5.44.0",
|
"@typescript-eslint/parser": "^5.46.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"eslint": "^8.29.0",
|
"eslint": "^8.29.0",
|
||||||
|
"eslint-plugin-foundkey-custom-rules": "file:../shared/custom-rules",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"execa": "6.1.0",
|
"execa": "6.1.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"sinon": "^14.0.2",
|
"sinon": "^14.0.2",
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ const ev = new Xev();
|
||||||
/**
|
/**
|
||||||
* Init process
|
* Init process
|
||||||
*/
|
*/
|
||||||
export default async function(): Promise<void> {
|
export async function boot(): Promise<void> {
|
||||||
process.title = `FoundKey (${cluster.isPrimary ? 'master' : 'worker'})`;
|
process.title = `FoundKey (${cluster.isPrimary ? 'master' : 'worker'})`;
|
||||||
|
|
||||||
if (cluster.isPrimary || envOption.disableClustering) {
|
if (cluster.isPrimary || envOption.disableClustering) {
|
||||||
|
|
|
@ -140,7 +140,7 @@ async function connectDb(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function spawnWorkers(clusterLimits: Required<Config['clusterLimits']>): Promise<void> {
|
async function spawnWorkers(clusterLimits: Required<Config['clusterLimits']>): Promise<void> {
|
||||||
const modes = ['web', 'queue'];
|
const modes = ['web' as const, 'queue' as const];
|
||||||
const cpus = os.cpus().length;
|
const cpus = os.cpus().length;
|
||||||
for (const mode of modes.filter(mode => clusterLimits[mode] > cpus)) {
|
for (const mode of modes.filter(mode => clusterLimits[mode] > cpus)) {
|
||||||
bootLogger.warn(`configuration warning: cluster limit for ${mode} exceeds number of cores (${cpus})`);
|
bootLogger.warn(`configuration warning: cluster limit for ${mode} exceeds number of cores (${cpus})`);
|
||||||
|
|
|
@ -38,6 +38,12 @@ export default function load(): Config {
|
||||||
|
|
||||||
config.port = config.port || parseInt(process.env.PORT || '', 10);
|
config.port = config.port || parseInt(process.env.PORT || '', 10);
|
||||||
|
|
||||||
|
config.images = Object.assign({
|
||||||
|
info: '/twemoji/1f440.svg',
|
||||||
|
notFound: '/twemoji/2049.svg',
|
||||||
|
error: '/twemoji/1f480.svg',
|
||||||
|
}, config.images ?? {});
|
||||||
|
|
||||||
if (!config.maxNoteTextLength) config.maxNoteTextLength = 3000;
|
if (!config.maxNoteTextLength) config.maxNoteTextLength = 3000;
|
||||||
|
|
||||||
mixin.version = meta.version;
|
mixin.version = meta.version;
|
||||||
|
|
|
@ -67,6 +67,12 @@ export type Source = {
|
||||||
mediaProxy?: string;
|
mediaProxy?: string;
|
||||||
proxyRemoteFiles?: boolean;
|
proxyRemoteFiles?: boolean;
|
||||||
internalStoragePath?: string;
|
internalStoragePath?: string;
|
||||||
|
|
||||||
|
images?: {
|
||||||
|
info?: string;
|
||||||
|
notFound?: string;
|
||||||
|
error?: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// https://github.com/typeorm/typeorm/issues/2400
|
// https://github.com/typeorm/typeorm/issues/2400
|
||||||
import pg from 'pg';
|
import pg from 'pg';
|
||||||
import { SECOND } from '@/const.js';
|
|
||||||
|
|
||||||
pg.types.setTypeParser(20, Number);
|
pg.types.setTypeParser(20, Number);
|
||||||
|
|
||||||
|
@ -8,6 +7,7 @@ import { Logger, DataSource } from 'typeorm';
|
||||||
import * as highlight from 'cli-highlight';
|
import * as highlight from 'cli-highlight';
|
||||||
import config from '@/config/index.js';
|
import config from '@/config/index.js';
|
||||||
|
|
||||||
|
import { SECOND } from '@/const.js';
|
||||||
import { User } from '@/models/entities/user.js';
|
import { User } from '@/models/entities/user.js';
|
||||||
import { DriveFile } from '@/models/entities/drive-file.js';
|
import { DriveFile } from '@/models/entities/drive-file.js';
|
||||||
import { DriveFolder } from '@/models/entities/drive-folder.js';
|
import { DriveFolder } from '@/models/entities/drive-folder.js';
|
||||||
|
@ -78,33 +78,33 @@ import { redisClient } from './redis.js';
|
||||||
const sqlLogger = dbLogger.createSubLogger('sql', 'gray', false);
|
const sqlLogger = dbLogger.createSubLogger('sql', 'gray', false);
|
||||||
|
|
||||||
class MyCustomLogger implements Logger {
|
class MyCustomLogger implements Logger {
|
||||||
private highlight(sql: string) {
|
private highlight(sql: string): string {
|
||||||
return highlight.highlight(sql, {
|
return highlight.highlight(sql, {
|
||||||
language: 'sql', ignoreIllegals: true,
|
language: 'sql', ignoreIllegals: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public logQuery(query: string, parameters?: any[]) {
|
public logQuery(query: string): void {
|
||||||
sqlLogger.info(this.highlight(query).substring(0, 100));
|
sqlLogger.info(this.highlight(query).substring(0, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
public logQueryError(error: string, query: string, parameters?: any[]) {
|
public logQueryError(error: string, query: string): void {
|
||||||
sqlLogger.error(this.highlight(query));
|
sqlLogger.error(this.highlight(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
public logQuerySlow(time: number, query: string, parameters?: any[]) {
|
public logQuerySlow(time: number, query: string): void {
|
||||||
sqlLogger.warn(this.highlight(query));
|
sqlLogger.warn(this.highlight(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
public logSchemaBuild(message: string) {
|
public logSchemaBuild(message: string): void {
|
||||||
sqlLogger.info(message);
|
sqlLogger.info(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public log(message: string) {
|
public log(message: string): void {
|
||||||
sqlLogger.info(message);
|
sqlLogger.info(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public logMigration(message: string) {
|
public logMigration(message: string): void {
|
||||||
sqlLogger.info(message);
|
sqlLogger.info(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import boot from '@/boot/index.js';
|
import { boot } from '@/boot/index.js';
|
||||||
|
|
||||||
Error.stackTraceLimit = Infinity;
|
Error.stackTraceLimit = Infinity;
|
||||||
EventEmitter.defaultMaxListeners = 128;
|
EventEmitter.defaultMaxListeners = 128;
|
||||||
|
|
|
@ -8,10 +8,7 @@ import { SECOND } from '@/const.js';
|
||||||
*/
|
*/
|
||||||
const retryDelay = 100;
|
const retryDelay = 100;
|
||||||
|
|
||||||
const lock: (key: string, timeout?: number) => Promise<() => void>
|
const lock: (key: string, timeout?: number) => Promise<() => void> = promisify(redisLock(redisClient, retryDelay));
|
||||||
= redisClient
|
|
||||||
? promisify(redisLock(redisClient, retryDelay))
|
|
||||||
: async () => () => { };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get AP Object lock
|
* Get AP Object lock
|
||||||
|
|
|
@ -22,7 +22,7 @@ export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'No
|
||||||
if (note.visibility === 'specified') return false;
|
if (note.visibility === 'specified') return false;
|
||||||
|
|
||||||
// skip if the antenna creator is blocked by the note author
|
// skip if the antenna creator is blocked by the note author
|
||||||
const blockings = await blockingCache.fetch(noteUser.id);
|
const blockings = (await blockingCache.fetch(noteUser.id)) ?? [];
|
||||||
if (blockings.some(blocking => blocking === antenna.userId)) return false;
|
if (blockings.some(blocking => blocking === antenna.userId)) return false;
|
||||||
|
|
||||||
if (note.visibility === 'followers') {
|
if (note.visibility === 'followers') {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { db } from '@/db/postgre.js';
|
||||||
import { Meta } from '@/models/entities/meta.js';
|
import { Meta } from '@/models/entities/meta.js';
|
||||||
import { getFetchInstanceMetadataLock } from '@/misc/app-lock.js';
|
import { getFetchInstanceMetadataLock } from '@/misc/app-lock.js';
|
||||||
|
|
||||||
let cache: Meta;
|
let cache: Meta | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the primitive database operation to set the server configuration
|
* Performs the primitive database operation to set the server configuration
|
||||||
|
@ -57,5 +57,5 @@ export async function fetchMeta(noCache = false): Promise<Meta> {
|
||||||
|
|
||||||
await getMeta();
|
await getMeta();
|
||||||
|
|
||||||
return cache;
|
return cache!;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ export async function getHtml(url: string, accept = 'text/html, */*', timeout =
|
||||||
return await res.text();
|
return await res.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getResponse(args: { url: string, method: string, body?: string, headers: Record<string, string>, timeout?: number, size?: number }) {
|
export async function getResponse(args: { url: string, method: string, body?: string, headers: Record<string, string>, timeout?: number, size?: number, redirect: 'follow' | 'manual' | 'error' = 'follow' }) {
|
||||||
const timeout = args.timeout || 10 * SECOND;
|
const timeout = args.timeout || 10 * SECOND;
|
||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
@ -47,8 +47,9 @@ export async function getResponse(args: { url: string, method: string, body?: st
|
||||||
method: args.method,
|
method: args.method,
|
||||||
headers: args.headers,
|
headers: args.headers,
|
||||||
body: args.body,
|
body: args.body,
|
||||||
|
redirect: args.redirect,
|
||||||
timeout,
|
timeout,
|
||||||
size: args.size || 10 * 1024 * 1024,
|
size: args.size || 10 * 1024 * 1024, // 10 MiB
|
||||||
agent: getAgentByUrl,
|
agent: getAgentByUrl,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
});
|
});
|
||||||
|
|
17
packages/backend/src/misc/password.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import bcrypt from 'bcryptjs';
|
||||||
|
import * as argon2 from 'argon2';
|
||||||
|
|
||||||
|
export async function hashPassword(password: string): Promise<string> {
|
||||||
|
return argon2.hash(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function comparePassword(password: string, hash: string): Promise<boolean> {
|
||||||
|
if (isOldAlgorithm(hash)) return bcrypt.compare(password, hash);
|
||||||
|
|
||||||
|
return argon2.verify(hash, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isOldAlgorithm(hash: string): boolean {
|
||||||
|
// bcrypt hashes start with $2[ab]$
|
||||||
|
return hash.startsWith('$2');
|
||||||
|
}
|
|
@ -75,7 +75,7 @@ export async function toDbReaction(reaction?: string | null, idnReacterHost?: st
|
||||||
const custom = reaction.match(/^:([\w+-]+)(?:@\.)?:$/);
|
const custom = reaction.match(/^:([\w+-]+)(?:@\.)?:$/);
|
||||||
if (custom) {
|
if (custom) {
|
||||||
const name = custom[1];
|
const name = custom[1];
|
||||||
const emoji = await Emojis.findOneBy({
|
const emoji = await Emojis.countBy({
|
||||||
host: reacterHost ?? IsNull(),
|
host: reacterHost ?? IsNull(),
|
||||||
name,
|
name,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import { Note } from '@/models/entities/note.js';
|
import { Note } from '@/models/entities/note.js';
|
||||||
|
|
||||||
export function isPureRenote(note: Note): note is Note & { renoteId: string, text: null, fileIds: null | never[], hasPoll: false } {
|
export function isPureRenote(note: Note): note is Note & { renoteId: string, text: null, fileIds: null | never[], hasPoll: false } {
|
||||||
return note.renoteId != null && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !note.hasPoll;
|
return note.renoteId != null
|
||||||
|
&& note.text == null
|
||||||
|
&& (
|
||||||
|
note.fileIds == null
|
||||||
|
|| note.fileIds.length === 0
|
||||||
|
)
|
||||||
|
&& !note.hasPoll;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as crypto from 'node:crypto';
|
import * as crypto from 'node:crypto';
|
||||||
|
|
||||||
const L_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz';
|
const L_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||||
const LU_CHARS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
const LU_CHARS = L_CHARS + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
|
||||||
export function secureRndstrCustom(length = 32, chars: string): string {
|
export function secureRndstrCustom(length = 32, chars: string): string {
|
||||||
const chars_len = chars.length;
|
const chars_len = chars.length;
|
||||||
|
|
|
@ -6,11 +6,10 @@ import { Meta } from '@/models/entities/meta.js';
|
||||||
* Returns whether a specific host (punycoded) should be blocked.
|
* Returns whether a specific host (punycoded) should be blocked.
|
||||||
*
|
*
|
||||||
* @param host punycoded instance host
|
* @param host punycoded instance host
|
||||||
* @param meta a Promise contatining the information from the meta table (optional)
|
* @param meta a resolved Meta table
|
||||||
* @returns whether the given host should be blocked
|
* @returns whether the given host should be blocked
|
||||||
*/
|
*/
|
||||||
|
export async function shouldBlockInstance(host: Instance['host'], meta?: Meta): Promise<boolean> {
|
||||||
export async function shouldBlockInstance(host: Instance['host'], meta: Promise<Meta> = fetchMeta()): Promise<boolean> {
|
const { blockedHosts } = meta ?? await fetchMeta();
|
||||||
const { blockedHosts } = await meta;
|
|
||||||
return blockedHosts.some(blockedHost => host === blockedHost || host.endsWith('.' + blockedHost));
|
return blockedHosts.some(blockedHost => host === blockedHost || host.endsWith('.' + blockedHost));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@ const deadThreshold = 7 * DAY;
|
||||||
* @returns array of punycoded instance hosts that should be skipped (subset of hosts parameter)
|
* @returns array of punycoded instance hosts that should be skipped (subset of hosts parameter)
|
||||||
*/
|
*/
|
||||||
export async function skippedInstances(hosts: Array<Instance['host']>): Promise<Array<Instance['host']>> {
|
export async function skippedInstances(hosts: Array<Instance['host']>): Promise<Array<Instance['host']>> {
|
||||||
// Resolve the boolean promises before filtering
|
// first check for blocked instances since that info may already be in memory
|
||||||
const meta = fetchMeta();
|
const meta = await fetchMeta();
|
||||||
const shouldSkip = await Promise.all(hosts.map(host => shouldBlockInstance(host, meta)));
|
const shouldSkip = await Promise.all(hosts.map(host => shouldBlockInstance(host, meta)));
|
||||||
const skipped = hosts.filter((_, i) => shouldSkip[i]);
|
const skipped = hosts.filter((_, i) => shouldSkip[i]);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ export class AbuseUserReport {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public targetUserId: User['id'];
|
public targetUserId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -27,7 +27,7 @@ export class AbuseUserReport {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public reporterId: User['id'];
|
public reporterId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -39,7 +39,7 @@ export class AbuseUserReport {
|
||||||
})
|
})
|
||||||
public assigneeId: User['id'] | null;
|
public assigneeId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -41,7 +41,7 @@ export class AccessToken {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -53,7 +53,7 @@ export class AccessToken {
|
||||||
})
|
})
|
||||||
public appId: App['id'] | null;
|
public appId: App['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => App, {
|
@ManyToOne(() => App, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class AnnouncementRead {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -28,7 +28,7 @@ export class AnnouncementRead {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public announcementId: Announcement['id'];
|
public announcementId: Announcement['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Announcement, {
|
@ManyToOne(() => Announcement, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -32,12 +32,4 @@ export class Announcement {
|
||||||
length: 1024, nullable: true,
|
length: 1024, nullable: true,
|
||||||
})
|
})
|
||||||
public imageUrl: string | null;
|
public imageUrl: string | null;
|
||||||
|
|
||||||
constructor(data: Partial<Announcement>) {
|
|
||||||
if (data == null) return;
|
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(data)) {
|
|
||||||
(this as any)[k] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class AntennaNote {
|
||||||
})
|
})
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -29,7 +29,7 @@ export class AntennaNote {
|
||||||
})
|
})
|
||||||
public antennaId: Antenna['id'];
|
public antennaId: Antenna['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Antenna, {
|
@ManyToOne(() => Antenna, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class Antenna {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -42,7 +42,7 @@ export class Antenna {
|
||||||
})
|
})
|
||||||
public userListId: UserList['id'] | null;
|
public userListId: UserList['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => UserList, {
|
@ManyToOne(() => UserList, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -54,7 +54,7 @@ export class Antenna {
|
||||||
})
|
})
|
||||||
public userGroupJoiningId: UserGroupJoining['id'] | null;
|
public userGroupJoiningId: UserGroupJoining['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => UserGroupJoining, {
|
@ManyToOne(() => UserGroupJoining, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class App {
|
||||||
})
|
})
|
||||||
public userId: User['id'] | null;
|
public userId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,7 +11,7 @@ export class AttestationChallenge {
|
||||||
@PrimaryColumn(id())
|
@PrimaryColumn(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -35,12 +35,4 @@ export class AttestationChallenge {
|
||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
public registrationChallenge: boolean;
|
public registrationChallenge: boolean;
|
||||||
|
|
||||||
constructor(data: Partial<AttestationChallenge>) {
|
|
||||||
if (data == null) return;
|
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(data)) {
|
|
||||||
(this as any)[k] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Entity, PrimaryColumn, Index, Column, ManyToOne, OneToOne, JoinColumn } from 'typeorm';
|
import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn } from 'typeorm';
|
||||||
import { id } from '../id.js';
|
import { id } from '../id.js';
|
||||||
import { AccessToken } from './access-token.js';
|
import { AccessToken } from './access-token.js';
|
||||||
import { App } from './app.js';
|
import { App } from './app.js';
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class Blocking {
|
||||||
})
|
})
|
||||||
public blockeeId: User['id'];
|
public blockeeId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -34,7 +34,7 @@ export class Blocking {
|
||||||
})
|
})
|
||||||
public blockerId: User['id'];
|
public blockerId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class ChannelFollowing {
|
||||||
})
|
})
|
||||||
public followeeId: Channel['id'];
|
public followeeId: Channel['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Channel, {
|
@ManyToOne(() => Channel, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -35,7 +35,7 @@ export class ChannelFollowing {
|
||||||
})
|
})
|
||||||
public followerId: User['id'];
|
public followerId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class ChannelNotePining {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public channelId: Channel['id'];
|
public channelId: Channel['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Channel, {
|
@ManyToOne(() => Channel, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -27,7 +27,7 @@ export class ChannelNotePining {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -28,7 +28,7 @@ export class Channel {
|
||||||
})
|
})
|
||||||
public userId: User['id'] | null;
|
public userId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -53,7 +53,7 @@ export class Channel {
|
||||||
})
|
})
|
||||||
public bannerId: DriveFile['id'] | null;
|
public bannerId: DriveFile['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => DriveFile, {
|
@ManyToOne(() => DriveFile, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class ClipNote {
|
||||||
})
|
})
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -29,7 +29,7 @@ export class ClipNote {
|
||||||
})
|
})
|
||||||
public clipId: Clip['id'];
|
public clipId: Clip['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Clip, {
|
@ManyToOne(() => Clip, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class Clip {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -23,7 +23,7 @@ export class DriveFile {
|
||||||
})
|
})
|
||||||
public userId: User['id'] | null;
|
public userId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'RESTRICT',
|
onDelete: 'RESTRICT',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -144,7 +144,7 @@ export class DriveFile {
|
||||||
})
|
})
|
||||||
public folderId: DriveFolder['id'] | null;
|
public folderId: DriveFolder['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => DriveFolder, {
|
@ManyToOne(() => DriveFolder, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class DriveFolder {
|
||||||
})
|
})
|
||||||
public userId: User['id'] | null;
|
public userId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -41,7 +41,7 @@ export class DriveFolder {
|
||||||
})
|
})
|
||||||
public parentId: DriveFolder['id'] | null;
|
public parentId: DriveFolder['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => DriveFolder, {
|
@ManyToOne(() => DriveFolder, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -20,7 +20,7 @@ export class FollowRequest {
|
||||||
})
|
})
|
||||||
public followeeId: User['id'];
|
public followeeId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -33,7 +33,7 @@ export class FollowRequest {
|
||||||
})
|
})
|
||||||
public followerId: User['id'];
|
public followerId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class Following {
|
||||||
})
|
})
|
||||||
public followeeId: User['id'];
|
public followeeId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -34,7 +34,7 @@ export class Following {
|
||||||
})
|
})
|
||||||
public followerId: User['id'];
|
public followerId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class GalleryLike {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -25,7 +25,7 @@ export class GalleryLike {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public postId: GalleryPost['id'];
|
public postId: GalleryPost['id'];
|
||||||
|
|
||||||
@ManyToOne(type => GalleryPost, {
|
@ManyToOne(() => GalleryPost, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -37,7 +37,7 @@ export class GalleryPost {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class MessagingMessage {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -35,7 +35,7 @@ export class MessagingMessage {
|
||||||
})
|
})
|
||||||
public recipientId: User['id'] | null;
|
public recipientId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -48,7 +48,7 @@ export class MessagingMessage {
|
||||||
})
|
})
|
||||||
public groupId: UserGroup['id'] | null;
|
public groupId: UserGroup['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => UserGroup, {
|
@ManyToOne(() => UserGroup, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -81,7 +81,7 @@ export class MessagingMessage {
|
||||||
})
|
})
|
||||||
public fileId: DriveFile['id'] | null;
|
public fileId: DriveFile['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => DriveFile, {
|
@ManyToOne(() => DriveFile, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -134,7 +134,7 @@ export class Meta {
|
||||||
})
|
})
|
||||||
public proxyAccountId: User['id'] | null;
|
public proxyAccountId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class ModerationLog {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -17,7 +17,7 @@ export class MutedNote {
|
||||||
})
|
})
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -30,7 +30,7 @@ export class MutedNote {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class Muting {
|
||||||
})
|
})
|
||||||
public muteeId: User['id'];
|
public muteeId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -40,7 +40,7 @@ export class Muting {
|
||||||
})
|
})
|
||||||
public muterId: User['id'];
|
public muterId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class NoteFavorite {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -27,7 +27,7 @@ export class NoteFavorite {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class NoteReaction {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -29,7 +29,7 @@ export class NoteReaction {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typ
|
||||||
import { noteNotificationTypes } from 'foundkey-js';
|
import { noteNotificationTypes } from 'foundkey-js';
|
||||||
import { id } from '../id.js';
|
import { id } from '../id.js';
|
||||||
import { User } from './user.js';
|
import { User } from './user.js';
|
||||||
import { Note } from './note.js';
|
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Index(['userId', 'threadId'], { unique: true })
|
@Index(['userId', 'threadId'], { unique: true })
|
||||||
|
@ -20,7 +19,7 @@ export class NoteThreadMuting {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -14,7 +14,7 @@ export class NoteUnread {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -24,7 +24,7 @@ export class NoteUnread {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class NoteWatching {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -35,7 +35,7 @@ export class NoteWatching {
|
||||||
})
|
})
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class Note {
|
||||||
})
|
})
|
||||||
public replyId: Note['id'] | null;
|
public replyId: Note['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -41,7 +41,7 @@ export class Note {
|
||||||
})
|
})
|
||||||
public renoteId: Note['id'] | null;
|
public renoteId: Note['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -75,7 +75,7 @@ export class Note {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -179,7 +179,7 @@ export class Note {
|
||||||
})
|
})
|
||||||
public channelId: Channel['id'] | null;
|
public channelId: Channel['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => Channel, {
|
@ManyToOne(() => Channel, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -28,7 +28,7 @@ export class Notification {
|
||||||
})
|
})
|
||||||
public notifieeId: User['id'];
|
public notifieeId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -45,7 +45,7 @@ export class Notification {
|
||||||
})
|
})
|
||||||
public notifierId: User['id'] | null;
|
public notifierId: User['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -89,7 +89,7 @@ export class Notification {
|
||||||
})
|
})
|
||||||
public noteId: Note['id'] | null;
|
public noteId: Note['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -101,7 +101,7 @@ export class Notification {
|
||||||
})
|
})
|
||||||
public followRequestId: FollowRequest['id'] | null;
|
public followRequestId: FollowRequest['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => FollowRequest, {
|
@ManyToOne(() => FollowRequest, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -113,7 +113,7 @@ export class Notification {
|
||||||
})
|
})
|
||||||
public userGroupInvitationId: UserGroupInvitation['id'] | null;
|
public userGroupInvitationId: UserGroupInvitation['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => UserGroupInvitation, {
|
@ManyToOne(() => UserGroupInvitation, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -165,7 +165,7 @@ export class Notification {
|
||||||
})
|
})
|
||||||
public appAccessTokenId: AccessToken['id'] | null;
|
public appAccessTokenId: AccessToken['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => AccessToken, {
|
@ManyToOne(() => AccessToken, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class PageLike {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -25,7 +25,7 @@ export class PageLike {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public pageId: Page['id'];
|
public pageId: Page['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Page, {
|
@ManyToOne(() => Page, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -57,7 +57,7 @@ export class Page {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -69,7 +69,7 @@ export class Page {
|
||||||
})
|
})
|
||||||
public eyeCatchingImageId: DriveFile['id'] | null;
|
public eyeCatchingImageId: DriveFile['id'] | null;
|
||||||
|
|
||||||
@ManyToOne(type => DriveFile, {
|
@ManyToOne(() => DriveFile, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class PasswordResetRequest {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class PollVote {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -29,7 +29,7 @@ export class PollVote {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -9,7 +9,7 @@ export class Poll {
|
||||||
@PrimaryColumn(id())
|
@PrimaryColumn(id())
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@OneToOne(type => Note, {
|
@OneToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -25,7 +25,7 @@ export class RegistryItem {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class RenoteMuting {
|
||||||
})
|
})
|
||||||
public muteeId: User['id'];
|
public muteeId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -34,7 +34,7 @@ export class RenoteMuting {
|
||||||
})
|
})
|
||||||
public muterId: User['id'];
|
public muterId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class Signin {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -14,7 +14,7 @@ export class SwSubscription {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class UserGroupInvitation {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -34,7 +34,7 @@ export class UserGroupInvitation {
|
||||||
})
|
})
|
||||||
public userGroupId: UserGroup['id'];
|
public userGroupId: UserGroup['id'];
|
||||||
|
|
||||||
@ManyToOne(type => UserGroup, {
|
@ManyToOne(() => UserGroup, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class UserGroupJoining {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -34,7 +34,7 @@ export class UserGroupJoining {
|
||||||
})
|
})
|
||||||
public userGroupId: UserGroup['id'];
|
public userGroupId: UserGroup['id'];
|
||||||
|
|
||||||
@ManyToOne(type => UserGroup, {
|
@ManyToOne(() => UserGroup, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -25,7 +25,7 @@ export class UserGroup {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -7,7 +7,7 @@ export class UserKeypair {
|
||||||
@PrimaryColumn(id())
|
@PrimaryColumn(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@OneToOne(type => User, {
|
@OneToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class UserListJoining {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -34,7 +34,7 @@ export class UserListJoining {
|
||||||
})
|
})
|
||||||
public userListId: UserList['id'];
|
public userListId: UserList['id'];
|
||||||
|
|
||||||
@ManyToOne(type => UserList, {
|
@ManyToOne(() => UserList, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class UserList {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class UserNotePining {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -27,7 +27,7 @@ export class UserNotePining {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public noteId: Note['id'];
|
public noteId: Note['id'];
|
||||||
|
|
||||||
@ManyToOne(type => Note, {
|
@ManyToOne(() => Note, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -11,7 +11,7 @@ export class UserProfile {
|
||||||
@PrimaryColumn(id())
|
@PrimaryColumn(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@OneToOne(type => User, {
|
@OneToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -161,7 +161,7 @@ export class UserProfile {
|
||||||
})
|
})
|
||||||
public pinnedPageId: Page['id'] | null;
|
public pinnedPageId: Page['id'] | null;
|
||||||
|
|
||||||
@OneToOne(type => Page, {
|
@OneToOne(() => Page, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -7,7 +7,7 @@ export class UserPublickey {
|
||||||
@PrimaryColumn(id())
|
@PrimaryColumn(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@OneToOne(type => User, {
|
@OneToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -13,7 +13,7 @@ export class UserSecurityKey {
|
||||||
@Column(id())
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -81,7 +81,7 @@ export class User {
|
||||||
})
|
})
|
||||||
public avatarId: DriveFile['id'] | null;
|
public avatarId: DriveFile['id'] | null;
|
||||||
|
|
||||||
@OneToOne(type => DriveFile, {
|
@OneToOne(() => DriveFile, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
@ -94,7 +94,7 @@ export class User {
|
||||||
})
|
})
|
||||||
public bannerId: DriveFile['id'] | null;
|
public bannerId: DriveFile['id'] | null;
|
||||||
|
|
||||||
@OneToOne(type => DriveFile, {
|
@OneToOne(() => DriveFile, {
|
||||||
onDelete: 'SET NULL',
|
onDelete: 'SET NULL',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class Webhook {
|
||||||
})
|
})
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|
|
@ -27,9 +27,7 @@ export const DriveFileRepository = db.getRepository(DriveFile).extend({
|
||||||
|
|
||||||
getPublicProperties(file: DriveFile): DriveFile['properties'] {
|
getPublicProperties(file: DriveFile): DriveFile['properties'] {
|
||||||
if (file.properties.orientation != null) {
|
if (file.properties.orientation != null) {
|
||||||
// TODO
|
const properties = structuredClone(file.properties);
|
||||||
//const properties = structuredClone(file.properties);
|
|
||||||
const properties = JSON.parse(JSON.stringify(file.properties));
|
|
||||||
if (file.properties.orientation >= 5) {
|
if (file.properties.orientation >= 5) {
|
||||||
[properties.width, properties.height] = [properties.height, properties.width];
|
[properties.width, properties.height] = [properties.height, properties.width];
|
||||||
}
|
}
|
||||||
|
@ -63,50 +61,24 @@ export const DriveFileRepository = db.getRepository(DriveFile).extend({
|
||||||
return thumbnail ? (file.thumbnailUrl || (isImage ? (file.webpublicUrl || file.url) : null)) : (file.webpublicUrl || file.url);
|
return thumbnail ? (file.thumbnailUrl || (isImage ? (file.webpublicUrl || file.url) : null)) : (file.webpublicUrl || file.url);
|
||||||
},
|
},
|
||||||
|
|
||||||
async calcDriveUsageOf(user: User['id'] | { id: User['id'] }): Promise<number> {
|
calcDriveUsageOf(id: User['id']): Promise<number> {
|
||||||
const id = typeof user === 'object' ? user.id : user;
|
return db.query('SELECT SUM(size) AS sum FROM drive_file WHERE "userId" = $1 AND NOT "isLink"', [id])
|
||||||
|
.then(res => res[0].sum as number ?? 0);
|
||||||
const { sum } = await this
|
|
||||||
.createQueryBuilder('file')
|
|
||||||
.where('file.userId = :id', { id })
|
|
||||||
.andWhere('file.isLink = FALSE')
|
|
||||||
.select('SUM(file.size)', 'sum')
|
|
||||||
.getRawOne();
|
|
||||||
|
|
||||||
return parseInt(sum, 10) || 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async calcDriveUsageOfHost(host: string): Promise<number> {
|
calcDriveUsageOfHost(host: string): Promise<number> {
|
||||||
const { sum } = await this
|
return db.query('SELECT SUM(size) AS sum FROM drive_file WHERE "userHost" = $1 AND NOT "isLink"', [toPuny(host)])
|
||||||
.createQueryBuilder('file')
|
.then(res => res[0].sum as number ?? 0);
|
||||||
.where('file.userHost = :host', { host: toPuny(host) })
|
|
||||||
.andWhere('file.isLink = FALSE')
|
|
||||||
.select('SUM(file.size)', 'sum')
|
|
||||||
.getRawOne();
|
|
||||||
|
|
||||||
return parseInt(sum, 10) || 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async calcDriveUsageOfLocal(): Promise<number> {
|
calcDriveUsageOfLocal(): Promise<number> {
|
||||||
const { sum } = await this
|
return db.query('SELECT SUM(size) AS sum FROM drive_file WHERE "userHost" IS NULL AND NOT "isLink"')
|
||||||
.createQueryBuilder('file')
|
.then(res => res[0].sum as number ?? 0);
|
||||||
.where('file.userHost IS NULL')
|
|
||||||
.andWhere('file.isLink = FALSE')
|
|
||||||
.select('SUM(file.size)', 'sum')
|
|
||||||
.getRawOne();
|
|
||||||
|
|
||||||
return parseInt(sum, 10) || 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async calcDriveUsageOfRemote(): Promise<number> {
|
calcDriveUsageOfRemote(): Promise<number> {
|
||||||
const { sum } = await this
|
return db.query('SELECT SUM(size) AS sum FROM drive_file WHERE "userHost" IS NOT NULL AND NOT "isLink"')
|
||||||
.createQueryBuilder('file')
|
.then(res => res[0].sum as number ?? 0);
|
||||||
.where('file.userHost IS NOT NULL')
|
|
||||||
.andWhere('file.isLink = FALSE')
|
|
||||||
.select('SUM(file.size)', 'sum')
|
|
||||||
.getRawOne();
|
|
||||||
|
|
||||||
return parseInt(sum, 10) || 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async pack(
|
async pack(
|
||||||
|
@ -154,26 +126,7 @@ export const DriveFileRepository = db.getRepository(DriveFile).extend({
|
||||||
const file = typeof src === 'object' ? src : await this.findOneBy({ id: src });
|
const file = typeof src === 'object' ? src : await this.findOneBy({ id: src });
|
||||||
if (file == null) return null;
|
if (file == null) return null;
|
||||||
|
|
||||||
return await awaitAll<Packed<'DriveFile'>>({
|
return await this.pack(file, opts);
|
||||||
id: file.id,
|
|
||||||
createdAt: file.createdAt.toISOString(),
|
|
||||||
name: file.name,
|
|
||||||
type: file.type,
|
|
||||||
md5: file.md5,
|
|
||||||
size: file.size,
|
|
||||||
isSensitive: file.isSensitive,
|
|
||||||
blurhash: file.blurhash,
|
|
||||||
properties: opts.self ? file.properties : this.getPublicProperties(file),
|
|
||||||
url: opts.self ? file.url : this.getPublicUrl(file, false),
|
|
||||||
thumbnailUrl: this.getPublicUrl(file, true),
|
|
||||||
comment: file.comment,
|
|
||||||
folderId: file.folderId,
|
|
||||||
folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, {
|
|
||||||
detail: true,
|
|
||||||
}) : null,
|
|
||||||
userId: opts.withUser ? file.userId : null,
|
|
||||||
user: (opts.withUser && file.userId) ? Users.pack(file.userId) : null,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async packMany(
|
async packMany(
|
||||||
|
|
|
@ -307,7 +307,6 @@ export const UserRepository = db.getRepository(User).extend({
|
||||||
host: user.host,
|
host: user.host,
|
||||||
avatarUrl: this.getAvatarUrlSync(user),
|
avatarUrl: this.getAvatarUrlSync(user),
|
||||||
avatarBlurhash: user.avatar?.blurhash || null,
|
avatarBlurhash: user.avatar?.blurhash || null,
|
||||||
avatarColor: null, // 後方互換性のため
|
|
||||||
isAdmin: user.isAdmin || falsy,
|
isAdmin: user.isAdmin || falsy,
|
||||||
isModerator: user.isModerator || falsy,
|
isModerator: user.isModerator || falsy,
|
||||||
isBot: user.isBot || falsy,
|
isBot: user.isBot || falsy,
|
||||||
|
@ -332,7 +331,6 @@ export const UserRepository = db.getRepository(User).extend({
|
||||||
lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
|
lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
|
||||||
bannerUrl: user.banner ? DriveFiles.getPublicUrl(user.banner, false) : null,
|
bannerUrl: user.banner ? DriveFiles.getPublicUrl(user.banner, false) : null,
|
||||||
bannerBlurhash: user.banner?.blurhash || null,
|
bannerBlurhash: user.banner?.blurhash || null,
|
||||||
bannerColor: null, // 後方互換性のため
|
|
||||||
isLocked: user.isLocked,
|
isLocked: user.isLocked,
|
||||||
isSilenced: user.isSilenced || falsy,
|
isSilenced: user.isSilenced || falsy,
|
||||||
isSuspended: user.isSuspended || falsy,
|
isSuspended: user.isSuspended || falsy,
|
||||||
|
|