Removed all references to user pages
ci/woodpecker/tag/ociImageTag Pipeline was successful
Details
ci/woodpecker/tag/ociImageTag Pipeline was successful
Details
This commit is contained in:
parent
da04190d47
commit
8654fe13a6
|
@ -41,8 +41,6 @@ import {UserPublickey} from "@/models/entities/user-publickey.js";
|
||||||
import {UserProfile} from "@/models/entities/user-profile.js";
|
import {UserProfile} from "@/models/entities/user-profile.js";
|
||||||
import {UserSecurityKey} from "@/models/entities/user-security-key.js";
|
import {UserSecurityKey} from "@/models/entities/user-security-key.js";
|
||||||
import {AttestationChallenge} from "@/models/entities/attestation-challenge.js";
|
import {AttestationChallenge} from "@/models/entities/attestation-challenge.js";
|
||||||
import {Page} from "@/models/entities/page.js";
|
|
||||||
import {PageLike} from "@/models/entities/page-like.js";
|
|
||||||
import {GalleryPost} from "@/models/entities/gallery-post.js";
|
import {GalleryPost} from "@/models/entities/gallery-post.js";
|
||||||
import {GalleryLike} from "@/models/entities/gallery-like.js";
|
import {GalleryLike} from "@/models/entities/gallery-like.js";
|
||||||
import {ModerationLog} from "@/models/entities/moderation-log.js";
|
import {ModerationLog} from "@/models/entities/moderation-log.js";
|
||||||
|
@ -136,8 +134,6 @@ export const entities = [
|
||||||
NoteWatching,
|
NoteWatching,
|
||||||
NoteThreadMuting,
|
NoteThreadMuting,
|
||||||
NoteUnread,
|
NoteUnread,
|
||||||
Page,
|
|
||||||
PageLike,
|
|
||||||
GalleryPost,
|
GalleryPost,
|
||||||
GalleryLike,
|
GalleryLike,
|
||||||
DriveFile,
|
DriveFile,
|
||||||
|
|
|
@ -17,10 +17,6 @@ export const kinds = [
|
||||||
"read:reactions",
|
"read:reactions",
|
||||||
"write:reactions",
|
"write:reactions",
|
||||||
"write:votes",
|
"write:votes",
|
||||||
"read:pages",
|
|
||||||
"write:pages",
|
|
||||||
"write:page-likes",
|
|
||||||
"read:page-likes",
|
|
||||||
"read:gallery",
|
"read:gallery",
|
||||||
"write:gallery",
|
"write:gallery",
|
||||||
"read:gallery-likes",
|
"read:gallery-likes",
|
||||||
|
|
|
@ -143,7 +143,7 @@ export class Meta {
|
||||||
@Column("varchar", {
|
@Column("varchar", {
|
||||||
length: 512,
|
length: 512,
|
||||||
array: true,
|
array: true,
|
||||||
default: "{/featured,/explore,/pages,/about-calckey}",
|
default: "{/featured,/explore,/about-calckey}",
|
||||||
})
|
})
|
||||||
public pinnedPages: string[];
|
public pinnedPages: string[];
|
||||||
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
import {
|
|
||||||
PrimaryColumn,
|
|
||||||
Entity,
|
|
||||||
Index,
|
|
||||||
JoinColumn,
|
|
||||||
Column,
|
|
||||||
ManyToOne,
|
|
||||||
} from "typeorm";
|
|
||||||
import { User } from "./user.js";
|
|
||||||
import { id } from "../id.js";
|
|
||||||
import { Page } from "./page.js";
|
|
||||||
|
|
||||||
@Entity()
|
|
||||||
@Index(["userId", "pageId"], { unique: true })
|
|
||||||
export class PageLike {
|
|
||||||
@PrimaryColumn(id())
|
|
||||||
public id: string;
|
|
||||||
|
|
||||||
@Column("timestamp with time zone")
|
|
||||||
public createdAt: Date;
|
|
||||||
|
|
||||||
@Index()
|
|
||||||
@Column(id())
|
|
||||||
public userId: User["id"];
|
|
||||||
|
|
||||||
@ManyToOne((type) => User, {
|
|
||||||
onDelete: "CASCADE",
|
|
||||||
})
|
|
||||||
@JoinColumn()
|
|
||||||
public user: User | null;
|
|
||||||
|
|
||||||
@Column(id())
|
|
||||||
public pageId: Page["id"];
|
|
||||||
|
|
||||||
@ManyToOne((type) => Page, {
|
|
||||||
onDelete: "CASCADE",
|
|
||||||
})
|
|
||||||
@JoinColumn()
|
|
||||||
public page: Page | null;
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
import {
|
|
||||||
Entity,
|
|
||||||
Index,
|
|
||||||
JoinColumn,
|
|
||||||
Column,
|
|
||||||
PrimaryColumn,
|
|
||||||
ManyToOne,
|
|
||||||
} from "typeorm";
|
|
||||||
import { User } from "./user.js";
|
|
||||||
import { id } from "../id.js";
|
|
||||||
import { DriveFile } from "./drive-file.js";
|
|
||||||
|
|
||||||
@Entity()
|
|
||||||
@Index(["userId", "name"], { unique: true })
|
|
||||||
export class Page {
|
|
||||||
@PrimaryColumn(id())
|
|
||||||
public id: string;
|
|
||||||
|
|
||||||
@Index()
|
|
||||||
@Column("timestamp with time zone", {
|
|
||||||
comment: "The created date of the Page.",
|
|
||||||
})
|
|
||||||
public createdAt: Date;
|
|
||||||
|
|
||||||
@Index()
|
|
||||||
@Column("timestamp with time zone", {
|
|
||||||
comment: "The updated date of the Page.",
|
|
||||||
})
|
|
||||||
public updatedAt: Date;
|
|
||||||
|
|
||||||
@Column("varchar", {
|
|
||||||
length: 256,
|
|
||||||
})
|
|
||||||
public title: string;
|
|
||||||
|
|
||||||
@Index()
|
|
||||||
@Column("varchar", {
|
|
||||||
length: 256,
|
|
||||||
})
|
|
||||||
public name: string;
|
|
||||||
|
|
||||||
@Column("varchar", {
|
|
||||||
length: 256,
|
|
||||||
nullable: true,
|
|
||||||
})
|
|
||||||
public summary: string | null;
|
|
||||||
|
|
||||||
@Column("boolean")
|
|
||||||
public alignCenter: boolean;
|
|
||||||
|
|
||||||
@Column("boolean")
|
|
||||||
public isPublic: boolean;
|
|
||||||
|
|
||||||
@Column("boolean", {
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
public hideTitleWhenPinned: boolean;
|
|
||||||
|
|
||||||
@Column("varchar", {
|
|
||||||
length: 32,
|
|
||||||
})
|
|
||||||
public font: string;
|
|
||||||
|
|
||||||
@Index()
|
|
||||||
@Column({
|
|
||||||
...id(),
|
|
||||||
comment: "The ID of author.",
|
|
||||||
})
|
|
||||||
public userId: User["id"];
|
|
||||||
|
|
||||||
@ManyToOne((type) => User, {
|
|
||||||
onDelete: "CASCADE",
|
|
||||||
})
|
|
||||||
@JoinColumn()
|
|
||||||
public user: User | null;
|
|
||||||
|
|
||||||
@Column({
|
|
||||||
...id(),
|
|
||||||
nullable: true,
|
|
||||||
})
|
|
||||||
public eyeCatchingImageId: DriveFile["id"] | null;
|
|
||||||
|
|
||||||
@ManyToOne((type) => DriveFile, {
|
|
||||||
onDelete: "CASCADE",
|
|
||||||
})
|
|
||||||
@JoinColumn()
|
|
||||||
public eyeCatchingImage: DriveFile | null;
|
|
||||||
|
|
||||||
@Column("jsonb", {
|
|
||||||
default: [],
|
|
||||||
})
|
|
||||||
public content: Record<string, any>[];
|
|
||||||
|
|
||||||
@Column("jsonb", {
|
|
||||||
default: [],
|
|
||||||
})
|
|
||||||
public variables: Record<string, any>[];
|
|
||||||
|
|
||||||
@Column("varchar", {
|
|
||||||
length: 16384,
|
|
||||||
default: "",
|
|
||||||
})
|
|
||||||
public script: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* public ... 公開
|
|
||||||
* followers ... フォロワーのみ
|
|
||||||
* specified ... visibleUserIds で指定したユーザーのみ
|
|
||||||
*/
|
|
||||||
@Column("enum", { enum: ["public", "followers", "specified"] })
|
|
||||||
public visibility: "public" | "followers" | "specified";
|
|
||||||
|
|
||||||
@Index()
|
|
||||||
@Column({
|
|
||||||
...id(),
|
|
||||||
array: true,
|
|
||||||
default: "{}",
|
|
||||||
})
|
|
||||||
public visibleUserIds: User["id"][];
|
|
||||||
|
|
||||||
@Column("integer", {
|
|
||||||
default: 0,
|
|
||||||
})
|
|
||||||
public likedCount: number;
|
|
||||||
|
|
||||||
constructor(data: Partial<Page>) {
|
|
||||||
if (data == null) return;
|
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(data)) {
|
|
||||||
(this as any)[k] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@ import {Column, Entity, Index, JoinColumn, OneToOne, PrimaryColumn,} from "typeo
|
||||||
import {ffVisibility, notificationTypes} from "@/types.js";
|
import {ffVisibility, notificationTypes} from "@/types.js";
|
||||||
import {id} from "../id.js";
|
import {id} from "../id.js";
|
||||||
import {User} from "./user.js";
|
import {User} from "./user.js";
|
||||||
import {Page} from "./page.js";
|
|
||||||
|
|
||||||
// TODO: このテーブルで管理している情報すべてレジストリで管理するようにしても良いかも
|
// TODO: このテーブルで管理している情報すべてレジストリで管理するようにしても良いかも
|
||||||
// ただ、「emailVerified が true なユーザーを find する」のようなクエリは書けなくなるからウーン
|
// ただ、「emailVerified が true なユーザーを find する」のようなクエリは書けなくなるからウーン
|
||||||
|
@ -184,18 +183,6 @@ export class UserProfile {
|
||||||
})
|
})
|
||||||
public receiveAnnouncementEmail: boolean;
|
public receiveAnnouncementEmail: boolean;
|
||||||
|
|
||||||
@Column({
|
|
||||||
...id(),
|
|
||||||
nullable: true,
|
|
||||||
})
|
|
||||||
public pinnedPageId: Page["id"] | null;
|
|
||||||
|
|
||||||
@OneToOne((type) => Page, {
|
|
||||||
onDelete: "SET NULL",
|
|
||||||
})
|
|
||||||
@JoinColumn()
|
|
||||||
public pinnedPage: Page | null;
|
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column("boolean", {
|
@Column("boolean", {
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {Announcement} from "./entities/announcement.js";
|
||||||
import {AnnouncementRead} from "./entities/announcement-read.js";
|
import {AnnouncementRead} from "./entities/announcement-read.js";
|
||||||
import {Poll} from "./entities/poll.js";
|
import {Poll} from "./entities/poll.js";
|
||||||
import {PollVote} from "./entities/poll-vote.js";
|
import {PollVote} from "./entities/poll-vote.js";
|
||||||
import {Meta} from "./entities/meta.js";
|
|
||||||
import {SwSubscription} from "./entities/sw-subscription.js";
|
import {SwSubscription} from "./entities/sw-subscription.js";
|
||||||
import {NoteWatching} from "./entities/note-watching.js";
|
import {NoteWatching} from "./entities/note-watching.js";
|
||||||
import {NoteThreadMuting} from "./entities/note-thread-muting.js";
|
import {NoteThreadMuting} from "./entities/note-thread-muting.js";
|
||||||
|
@ -36,8 +35,6 @@ import {UserProfile} from "./entities/user-profile.js";
|
||||||
import {AttestationChallenge} from "./entities/attestation-challenge.js";
|
import {AttestationChallenge} from "./entities/attestation-challenge.js";
|
||||||
import {UserSecurityKey} from "./entities/user-security-key.js";
|
import {UserSecurityKey} from "./entities/user-security-key.js";
|
||||||
import {HashtagRepository} from "./repositories/hashtag.js";
|
import {HashtagRepository} from "./repositories/hashtag.js";
|
||||||
import {PageRepository} from "./repositories/page.js";
|
|
||||||
import {PageLikeRepository} from "./repositories/page-like.js";
|
|
||||||
import {GalleryPostRepository} from "./repositories/gallery-post.js";
|
import {GalleryPostRepository} from "./repositories/gallery-post.js";
|
||||||
import {GalleryLikeRepository} from "./repositories/gallery-like.js";
|
import {GalleryLikeRepository} from "./repositories/gallery-like.js";
|
||||||
import {ModerationLogRepository} from "./repositories/moderation-logs.js";
|
import {ModerationLogRepository} from "./repositories/moderation-logs.js";
|
||||||
|
@ -91,7 +88,6 @@ export const Emojis = EmojiRepository;
|
||||||
export const DriveFiles = DriveFileRepository;
|
export const DriveFiles = DriveFileRepository;
|
||||||
export const DriveFolders = DriveFolderRepository;
|
export const DriveFolders = DriveFolderRepository;
|
||||||
export const Notifications = NotificationRepository;
|
export const Notifications = NotificationRepository;
|
||||||
export const Metas = db.getRepository(Meta);
|
|
||||||
export const Mutings = MutingRepository;
|
export const Mutings = MutingRepository;
|
||||||
export const RenoteMutings = RenoteMutingRepository;
|
export const RenoteMutings = RenoteMutingRepository;
|
||||||
export const Blockings = BlockingRepository;
|
export const Blockings = BlockingRepository;
|
||||||
|
@ -102,8 +98,6 @@ export const RegistrationTickets = db.getRepository(RegistrationTicket);
|
||||||
export const AuthSessions = AuthSessionRepository;
|
export const AuthSessions = AuthSessionRepository;
|
||||||
export const AccessTokens = db.getRepository(AccessToken);
|
export const AccessTokens = db.getRepository(AccessToken);
|
||||||
export const Signins = SigninRepository;
|
export const Signins = SigninRepository;
|
||||||
export const Pages = PageRepository;
|
|
||||||
export const PageLikes = PageLikeRepository;
|
|
||||||
export const GalleryPosts = GalleryPostRepository;
|
export const GalleryPosts = GalleryPostRepository;
|
||||||
export const GalleryLikes = GalleryLikeRepository;
|
export const GalleryLikes = GalleryLikeRepository;
|
||||||
export const ModerationLogs = ModerationLogRepository;
|
export const ModerationLogs = ModerationLogRepository;
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { db } from "@/db/postgre.js";
|
|
||||||
import { PageLike } from "@/models/entities/page-like.js";
|
|
||||||
import type { User } from "@/models/entities/user.js";
|
|
||||||
import { Pages } from "../index.js";
|
|
||||||
|
|
||||||
export const PageLikeRepository = db.getRepository(PageLike).extend({
|
|
||||||
async pack(
|
|
||||||
src: PageLike["id"] | PageLike,
|
|
||||||
me?: { id: User["id"] } | null | undefined,
|
|
||||||
) {
|
|
||||||
const like =
|
|
||||||
typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: like.id,
|
|
||||||
page: await Pages.pack(like.page || like.pageId, me),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
packMany(likes: PageLike[], me: { id: User["id"] }) {
|
|
||||||
return Promise.all(likes.map((x) => this.pack(x, me)));
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -1,99 +0,0 @@
|
||||||
import { db } from "@/db/postgre.js";
|
|
||||||
import { Page } from "@/models/entities/page.js";
|
|
||||||
import type { Packed } from "@/misc/schema.js";
|
|
||||||
import { awaitAll } from "@/prelude/await-all.js";
|
|
||||||
import type { DriveFile } from "@/models/entities/drive-file.js";
|
|
||||||
import type { User } from "@/models/entities/user.js";
|
|
||||||
import { Users, DriveFiles, PageLikes } from "../index.js";
|
|
||||||
|
|
||||||
export const PageRepository = db.getRepository(Page).extend({
|
|
||||||
async pack(
|
|
||||||
src: Page["id"] | Page,
|
|
||||||
me?: { id: User["id"] } | null | undefined,
|
|
||||||
): Promise<Packed<"Page">> {
|
|
||||||
const meId = me ? me.id : null;
|
|
||||||
const page =
|
|
||||||
typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
|
|
||||||
|
|
||||||
const attachedFiles: Promise<DriveFile | null>[] = [];
|
|
||||||
const collectFile = (xs: any[]) => {
|
|
||||||
for (const x of xs) {
|
|
||||||
if (x.type === "image") {
|
|
||||||
attachedFiles.push(
|
|
||||||
DriveFiles.findOneBy({
|
|
||||||
id: x.fileId,
|
|
||||||
userId: page.userId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (x.children) {
|
|
||||||
collectFile(x.children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
collectFile(page.content);
|
|
||||||
|
|
||||||
// 後方互換性のため
|
|
||||||
let migrated = false;
|
|
||||||
const migrate = (xs: any[]) => {
|
|
||||||
for (const x of xs) {
|
|
||||||
if (x.type === "input") {
|
|
||||||
if (x.inputType === "text") {
|
|
||||||
x.type = "textInput";
|
|
||||||
}
|
|
||||||
if (x.inputType === "number") {
|
|
||||||
x.type = "numberInput";
|
|
||||||
if (x.default) x.default = parseInt(x.default, 10);
|
|
||||||
}
|
|
||||||
migrated = true;
|
|
||||||
}
|
|
||||||
if (x.children) {
|
|
||||||
migrate(x.children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
migrate(page.content);
|
|
||||||
if (migrated) {
|
|
||||||
this.update(page.id, {
|
|
||||||
content: page.content,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return await awaitAll({
|
|
||||||
id: page.id,
|
|
||||||
createdAt: page.createdAt.toISOString(),
|
|
||||||
updatedAt: page.updatedAt.toISOString(),
|
|
||||||
userId: page.userId,
|
|
||||||
user: Users.pack(page.user || page.userId, me), // { detail: true } すると無限ループするので注意
|
|
||||||
content: page.content,
|
|
||||||
variables: page.variables,
|
|
||||||
title: page.title,
|
|
||||||
isPublic: page.isPublic,
|
|
||||||
name: page.name,
|
|
||||||
summary: page.summary,
|
|
||||||
hideTitleWhenPinned: page.hideTitleWhenPinned,
|
|
||||||
alignCenter: page.alignCenter,
|
|
||||||
font: page.font,
|
|
||||||
script: page.script,
|
|
||||||
eyeCatchingImageId: page.eyeCatchingImageId,
|
|
||||||
eyeCatchingImage: page.eyeCatchingImageId
|
|
||||||
? await DriveFiles.pack(page.eyeCatchingImageId)
|
|
||||||
: null,
|
|
||||||
attachedFiles: DriveFiles.packMany(
|
|
||||||
(
|
|
||||||
await Promise.all(attachedFiles)
|
|
||||||
).filter((x): x is DriveFile => x != null),
|
|
||||||
),
|
|
||||||
likedCount: page.likedCount,
|
|
||||||
isLiked: meId
|
|
||||||
? await PageLikes.findOneBy({ pageId: page.id, userId: meId }).then(
|
|
||||||
(x) => x != null,
|
|
||||||
)
|
|
||||||
: undefined,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
packMany(pages: Page[], me?: { id: User["id"] } | null | undefined) {
|
|
||||||
return Promise.all(pages.map((x) => this.pack(x, me)));
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -27,7 +27,6 @@ import {
|
||||||
Mutings,
|
Mutings,
|
||||||
NoteUnreads,
|
NoteUnreads,
|
||||||
Notifications,
|
Notifications,
|
||||||
Pages,
|
|
||||||
RenoteMutings,
|
RenoteMutings,
|
||||||
UserNotePinings,
|
UserNotePinings,
|
||||||
UserProfiles,
|
UserProfiles,
|
||||||
|
@ -420,10 +419,6 @@ export const UserRepository = db.getRepository(User).extend({
|
||||||
followingCount: followingCount || 0,
|
followingCount: followingCount || 0,
|
||||||
notesCount: user.notesCount,
|
notesCount: user.notesCount,
|
||||||
pinnedNoteIds: pins.map((pin) => pin.noteId),
|
pinnedNoteIds: pins.map((pin) => pin.noteId),
|
||||||
pinnedPageId: profile!.pinnedPageId,
|
|
||||||
pinnedPage: profile!.pinnedPageId
|
|
||||||
? Pages.pack(profile!.pinnedPageId, me)
|
|
||||||
: null,
|
|
||||||
publicReactions: profile!.publicReactions,
|
publicReactions: profile!.publicReactions,
|
||||||
ffVisibility: profile!.ffVisibility,
|
ffVisibility: profile!.ffVisibility,
|
||||||
twoFactorEnabled: profile!.twoFactorEnabled,
|
twoFactorEnabled: profile!.twoFactorEnabled,
|
||||||
|
|
|
@ -220,17 +220,6 @@ export const packedUserDetailedNotMeOnlySchema = {
|
||||||
format: "id",
|
format: "id",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pinnedPageId: {
|
|
||||||
type: "string",
|
|
||||||
nullable: true,
|
|
||||||
optional: false,
|
|
||||||
},
|
|
||||||
pinnedPage: {
|
|
||||||
type: "object",
|
|
||||||
nullable: true,
|
|
||||||
optional: false,
|
|
||||||
ref: "Page",
|
|
||||||
},
|
|
||||||
publicReactions: {
|
publicReactions: {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
|
|
@ -183,8 +183,6 @@ import * as ep___i_importFollowing from "./endpoints/i/import-following.js";
|
||||||
import * as ep___i_importMuting from "./endpoints/i/import-muting.js";
|
import * as ep___i_importMuting from "./endpoints/i/import-muting.js";
|
||||||
import * as ep___i_importUserLists from "./endpoints/i/import-user-lists.js";
|
import * as ep___i_importUserLists from "./endpoints/i/import-user-lists.js";
|
||||||
import * as ep___i_notifications from "./endpoints/i/notifications.js";
|
import * as ep___i_notifications from "./endpoints/i/notifications.js";
|
||||||
import * as ep___i_pageLikes from "./endpoints/i/page-likes.js";
|
|
||||||
import * as ep___i_pages from "./endpoints/i/pages.js";
|
|
||||||
import * as ep___i_pin from "./endpoints/i/pin.js";
|
import * as ep___i_pin from "./endpoints/i/pin.js";
|
||||||
import * as ep___i_readAllUnreadNotes from "./endpoints/i/read-all-unread-notes.js";
|
import * as ep___i_readAllUnreadNotes from "./endpoints/i/read-all-unread-notes.js";
|
||||||
import * as ep___i_readAnnouncement from "./endpoints/i/read-announcement.js";
|
import * as ep___i_readAnnouncement from "./endpoints/i/read-announcement.js";
|
||||||
|
@ -251,14 +249,6 @@ import * as ep___notes_watching_delete from "./endpoints/notes/watching/delete.j
|
||||||
import * as ep___notifications_create from "./endpoints/notifications/create.js";
|
import * as ep___notifications_create from "./endpoints/notifications/create.js";
|
||||||
import * as ep___notifications_markAllAsRead from "./endpoints/notifications/mark-all-as-read.js";
|
import * as ep___notifications_markAllAsRead from "./endpoints/notifications/mark-all-as-read.js";
|
||||||
import * as ep___notifications_read from "./endpoints/notifications/read.js";
|
import * as ep___notifications_read from "./endpoints/notifications/read.js";
|
||||||
import * as ep___pagePush from "./endpoints/page-push.js";
|
|
||||||
import * as ep___pages_create from "./endpoints/pages/create.js";
|
|
||||||
import * as ep___pages_delete from "./endpoints/pages/delete.js";
|
|
||||||
import * as ep___pages_featured from "./endpoints/pages/featured.js";
|
|
||||||
import * as ep___pages_like from "./endpoints/pages/like.js";
|
|
||||||
import * as ep___pages_show from "./endpoints/pages/show.js";
|
|
||||||
import * as ep___pages_unlike from "./endpoints/pages/unlike.js";
|
|
||||||
import * as ep___pages_update from "./endpoints/pages/update.js";
|
|
||||||
import * as ep___ping from "./endpoints/ping.js";
|
import * as ep___ping from "./endpoints/ping.js";
|
||||||
import * as ep___recommendedInstances from "./endpoints/recommended-instances.js";
|
import * as ep___recommendedInstances from "./endpoints/recommended-instances.js";
|
||||||
import * as ep___pinnedUsers from "./endpoints/pinned-users.js";
|
import * as ep___pinnedUsers from "./endpoints/pinned-users.js";
|
||||||
|
@ -292,7 +282,6 @@ import * as ep___users_lists_push from "./endpoints/users/lists/push.js";
|
||||||
import * as ep___users_lists_show from "./endpoints/users/lists/show.js";
|
import * as ep___users_lists_show from "./endpoints/users/lists/show.js";
|
||||||
import * as ep___users_lists_update from "./endpoints/users/lists/update.js";
|
import * as ep___users_lists_update from "./endpoints/users/lists/update.js";
|
||||||
import * as ep___users_notes from "./endpoints/users/notes.js";
|
import * as ep___users_notes from "./endpoints/users/notes.js";
|
||||||
import * as ep___users_pages from "./endpoints/users/pages.js";
|
|
||||||
import * as ep___users_reactions from "./endpoints/users/reactions.js";
|
import * as ep___users_reactions from "./endpoints/users/reactions.js";
|
||||||
import * as ep___users_recommendation from "./endpoints/users/recommendation.js";
|
import * as ep___users_recommendation from "./endpoints/users/recommendation.js";
|
||||||
import * as ep___users_relation from "./endpoints/users/relation.js";
|
import * as ep___users_relation from "./endpoints/users/relation.js";
|
||||||
|
@ -499,8 +488,6 @@ const eps = [
|
||||||
["i/import-muting", ep___i_importMuting],
|
["i/import-muting", ep___i_importMuting],
|
||||||
["i/import-user-lists", ep___i_importUserLists],
|
["i/import-user-lists", ep___i_importUserLists],
|
||||||
["i/notifications", ep___i_notifications],
|
["i/notifications", ep___i_notifications],
|
||||||
["i/page-likes", ep___i_pageLikes],
|
|
||||||
["i/pages", ep___i_pages],
|
|
||||||
["i/pin", ep___i_pin],
|
["i/pin", ep___i_pin],
|
||||||
["i/read-all-unread-notes", ep___i_readAllUnreadNotes],
|
["i/read-all-unread-notes", ep___i_readAllUnreadNotes],
|
||||||
["i/read-announcement", ep___i_readAnnouncement],
|
["i/read-announcement", ep___i_readAnnouncement],
|
||||||
|
@ -564,14 +551,6 @@ const eps = [
|
||||||
["notifications/create", ep___notifications_create],
|
["notifications/create", ep___notifications_create],
|
||||||
["notifications/mark-all-as-read", ep___notifications_markAllAsRead],
|
["notifications/mark-all-as-read", ep___notifications_markAllAsRead],
|
||||||
["notifications/read", ep___notifications_read],
|
["notifications/read", ep___notifications_read],
|
||||||
["page-push", ep___pagePush],
|
|
||||||
["pages/create", ep___pages_create],
|
|
||||||
["pages/delete", ep___pages_delete],
|
|
||||||
["pages/featured", ep___pages_featured],
|
|
||||||
["pages/like", ep___pages_like],
|
|
||||||
["pages/show", ep___pages_show],
|
|
||||||
["pages/unlike", ep___pages_unlike],
|
|
||||||
["pages/update", ep___pages_update],
|
|
||||||
["ping", ep___ping],
|
["ping", ep___ping],
|
||||||
["pinned-users", ep___pinnedUsers],
|
["pinned-users", ep___pinnedUsers],
|
||||||
["recommended-instances", ep___recommendedInstances],
|
["recommended-instances", ep___recommendedInstances],
|
||||||
|
@ -608,7 +587,6 @@ const eps = [
|
||||||
["users/lists/show", ep___users_lists_show],
|
["users/lists/show", ep___users_lists_show],
|
||||||
["users/lists/update", ep___users_lists_update],
|
["users/lists/update", ep___users_lists_update],
|
||||||
["users/notes", ep___users_notes],
|
["users/notes", ep___users_notes],
|
||||||
["users/pages", ep___users_pages],
|
|
||||||
["users/reactions", ep___users_reactions],
|
["users/reactions", ep___users_reactions],
|
||||||
["users/recommendation", ep___users_recommendation],
|
["users/recommendation", ep___users_recommendation],
|
||||||
["users/relation", ep___users_relation],
|
["users/relation", ep___users_relation],
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
import { PageLikes } from "@/models/index.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { makePaginationQuery } from "../../common/make-pagination-query.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["account", "pages"],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
|
|
||||||
kind: "read:page-likes",
|
|
||||||
|
|
||||||
res: {
|
|
||||||
type: "array",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
id: {
|
|
||||||
type: "string",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
format: "id",
|
|
||||||
},
|
|
||||||
page: {
|
|
||||||
type: "object",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
ref: "Page",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
|
|
||||||
sinceId: { type: "string", format: "misskey:id" },
|
|
||||||
untilId: { type: "string", format: "misskey:id" },
|
|
||||||
},
|
|
||||||
required: [],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const query = makePaginationQuery(
|
|
||||||
PageLikes.createQueryBuilder("like"),
|
|
||||||
ps.sinceId,
|
|
||||||
ps.untilId,
|
|
||||||
)
|
|
||||||
.andWhere("like.userId = :meId", { meId: user.id })
|
|
||||||
.leftJoinAndSelect("like.page", "page");
|
|
||||||
|
|
||||||
const likes = await query.take(ps.limit).getMany();
|
|
||||||
|
|
||||||
return PageLikes.packMany(likes, user);
|
|
||||||
});
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { Pages } from "@/models/index.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { makePaginationQuery } from "../../common/make-pagination-query.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["account", "pages"],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
|
|
||||||
kind: "read:pages",
|
|
||||||
|
|
||||||
res: {
|
|
||||||
type: "array",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
ref: "Page",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
|
|
||||||
sinceId: { type: "string", format: "misskey:id" },
|
|
||||||
untilId: { type: "string", format: "misskey:id" },
|
|
||||||
},
|
|
||||||
required: [],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const query = makePaginationQuery(
|
|
||||||
Pages.createQueryBuilder("page"),
|
|
||||||
ps.sinceId,
|
|
||||||
ps.untilId,
|
|
||||||
).andWhere("page.userId = :meId", { meId: user.id });
|
|
||||||
|
|
||||||
const pages = await query.take(ps.limit).getMany();
|
|
||||||
|
|
||||||
return await Pages.packMany(pages);
|
|
||||||
});
|
|
|
@ -6,7 +6,7 @@ import {publishToFollowers} from "@/services/i/update.js";
|
||||||
import {extractCustomEmojisFromMfm} from "@/misc/extract-custom-emojis-from-mfm.js";
|
import {extractCustomEmojisFromMfm} from "@/misc/extract-custom-emojis-from-mfm.js";
|
||||||
import {extractHashtags} from "@/misc/extract-hashtags.js";
|
import {extractHashtags} from "@/misc/extract-hashtags.js";
|
||||||
import {updateUsertags} from "@/services/update-hashtag.js";
|
import {updateUsertags} from "@/services/update-hashtag.js";
|
||||||
import {DriveFiles, Pages, UserProfiles, Users} from "@/models/index.js";
|
import {DriveFiles, UserProfiles, Users} from "@/models/index.js";
|
||||||
import type {User} from "@/models/entities/user.js";
|
import type {User} from "@/models/entities/user.js";
|
||||||
import type {UserProfile} from "@/models/entities/user-profile.js";
|
import type {UserProfile} from "@/models/entities/user-profile.js";
|
||||||
import {notificationTypes} from "@/types.js";
|
import {notificationTypes} from "@/types.js";
|
||||||
|
@ -219,17 +219,6 @@ export default define(meta, paramDef, async (ps, _user, token) => {
|
||||||
throw new ApiError(meta.errors.bannerNotAnImage);
|
throw new ApiError(meta.errors.bannerNotAnImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.pinnedPageId) {
|
|
||||||
const page = await Pages.findOneBy({ id: ps.pinnedPageId });
|
|
||||||
|
|
||||||
if (page == null || page.userId !== user.id)
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
|
|
||||||
profileUpdates.pinnedPageId = page.id;
|
|
||||||
} else if (ps.pinnedPageId === null) {
|
|
||||||
profileUpdates.pinnedPageId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.fields) {
|
if (ps.fields) {
|
||||||
profileUpdates.fields = ps.fields
|
profileUpdates.fields = ps.fields
|
||||||
.filter(
|
.filter(
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import { publishMainStream } from "@/services/stream.js";
|
|
||||||
import { Users, Pages } from "@/models/index.js";
|
|
||||||
import define from "../define.js";
|
|
||||||
import { ApiError } from "../error.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
requireCredential: true,
|
|
||||||
secure: true,
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchPage: {
|
|
||||||
message: "No such page.",
|
|
||||||
code: "NO_SUCH_PAGE",
|
|
||||||
id: "4a13ad31-6729-46b4-b9af-e86b265c2e74",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
pageId: { type: "string", format: "misskey:id" },
|
|
||||||
event: { type: "string" },
|
|
||||||
var: {},
|
|
||||||
},
|
|
||||||
required: ["pageId", "event"],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const page = await Pages.findOneBy({ id: ps.pageId });
|
|
||||||
if (page == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
publishMainStream(page.userId, "pageEvent", {
|
|
||||||
pageId: ps.pageId,
|
|
||||||
event: ps.event,
|
|
||||||
var: ps.var,
|
|
||||||
userId: user.id,
|
|
||||||
user: await Users.pack(
|
|
||||||
user.id,
|
|
||||||
{ id: page.userId },
|
|
||||||
{
|
|
||||||
detail: true,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,123 +0,0 @@
|
||||||
import { Pages, DriveFiles } from "@/models/index.js";
|
|
||||||
import { genId } from "@/misc/gen-id.js";
|
|
||||||
import { Page } from "@/models/entities/page.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { ApiError } from "../../error.js";
|
|
||||||
import { HOUR } from "@/const.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["pages"],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
|
|
||||||
kind: "write:pages",
|
|
||||||
|
|
||||||
limit: {
|
|
||||||
duration: HOUR,
|
|
||||||
max: 300,
|
|
||||||
},
|
|
||||||
|
|
||||||
res: {
|
|
||||||
type: "object",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
ref: "Page",
|
|
||||||
},
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchFile: {
|
|
||||||
message: "No such file.",
|
|
||||||
code: "NO_SUCH_FILE",
|
|
||||||
id: "b7b97489-0f66-4b12-a5ff-b21bd63f6e1c",
|
|
||||||
},
|
|
||||||
nameAlreadyExists: {
|
|
||||||
message: "Specified name already exists.",
|
|
||||||
code: "NAME_ALREADY_EXISTS",
|
|
||||||
id: "4650348e-301c-499a-83c9-6aa988c66bc1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
title: { type: "string" },
|
|
||||||
name: { type: "string", minLength: 1 },
|
|
||||||
summary: { type: "string", nullable: true },
|
|
||||||
content: {
|
|
||||||
type: "array",
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
variables: {
|
|
||||||
type: "array",
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
script: { type: "string" },
|
|
||||||
eyeCatchingImageId: {
|
|
||||||
type: "string",
|
|
||||||
format: "misskey:id",
|
|
||||||
nullable: true,
|
|
||||||
},
|
|
||||||
font: {
|
|
||||||
type: "string",
|
|
||||||
enum: ["serif", "sans-serif"],
|
|
||||||
default: "sans-serif",
|
|
||||||
},
|
|
||||||
alignCenter: { type: "boolean", default: false },
|
|
||||||
isPublic: { type: "boolean", default: true },
|
|
||||||
hideTitleWhenPinned: { type: "boolean", default: false },
|
|
||||||
},
|
|
||||||
required: ["title", "name", "content", "variables", "script"],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
let eyeCatchingImage = null;
|
|
||||||
if (ps.eyeCatchingImageId != null) {
|
|
||||||
eyeCatchingImage = await DriveFiles.findOneBy({
|
|
||||||
id: ps.eyeCatchingImageId,
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (eyeCatchingImage == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await Pages.findBy({
|
|
||||||
userId: user.id,
|
|
||||||
name: ps.name,
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.length > 0) {
|
|
||||||
throw new ApiError(meta.errors.nameAlreadyExists);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const page = await Pages.insert(
|
|
||||||
new Page({
|
|
||||||
id: genId(),
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date(),
|
|
||||||
title: ps.title,
|
|
||||||
name: ps.name,
|
|
||||||
summary: ps.summary,
|
|
||||||
content: ps.content,
|
|
||||||
variables: ps.variables,
|
|
||||||
script: ps.script,
|
|
||||||
eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null,
|
|
||||||
userId: user.id,
|
|
||||||
visibility: "public",
|
|
||||||
alignCenter: ps.alignCenter,
|
|
||||||
hideTitleWhenPinned: ps.hideTitleWhenPinned,
|
|
||||||
font: ps.font,
|
|
||||||
isPublic: ps.isPublic,
|
|
||||||
}),
|
|
||||||
).then((x) => Pages.findOneByOrFail(x.identifiers[0]));
|
|
||||||
|
|
||||||
return await Pages.pack(page);
|
|
||||||
});
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { Pages } from "@/models/index.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { ApiError } from "../../error.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["pages"],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
|
|
||||||
kind: "write:pages",
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchPage: {
|
|
||||||
message: "No such page.",
|
|
||||||
code: "NO_SUCH_PAGE",
|
|
||||||
id: "eb0c6e1d-d519-4764-9486-52a7e1c6392a",
|
|
||||||
},
|
|
||||||
|
|
||||||
accessDenied: {
|
|
||||||
message: "Access denied.",
|
|
||||||
code: "ACCESS_DENIED",
|
|
||||||
id: "8b741b3e-2c22-44b3-a15f-29949aa1601e",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
pageId: { type: "string", format: "misskey:id" },
|
|
||||||
},
|
|
||||||
required: ["pageId"],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const page = await Pages.findOneBy({ id: ps.pageId });
|
|
||||||
if (page == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
}
|
|
||||||
if (page.userId !== user.id) {
|
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Pages.delete(page.id);
|
|
||||||
});
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { Pages } from "@/models/index.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["pages"],
|
|
||||||
|
|
||||||
requireCredential: false,
|
|
||||||
requireCredentialPrivateMode: true,
|
|
||||||
|
|
||||||
res: {
|
|
||||||
type: "array",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
ref: "Page",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {},
|
|
||||||
required: [],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, me) => {
|
|
||||||
const query = Pages.createQueryBuilder("page")
|
|
||||||
.where("page.visibility = 'public'")
|
|
||||||
.andWhere("page.likedCount > 0")
|
|
||||||
.orderBy("page.likedCount", "DESC");
|
|
||||||
|
|
||||||
const pages = await query.take(10).getMany();
|
|
||||||
|
|
||||||
return await Pages.packMany(pages, me);
|
|
||||||
});
|
|
|
@ -1,61 +0,0 @@
|
||||||
import { Pages, PageLikes } from "@/models/index.js";
|
|
||||||
import { genId } from "@/misc/gen-id.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { ApiError } from "../../error.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["pages"],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
|
|
||||||
kind: "write:page-likes",
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchPage: {
|
|
||||||
message: "No such page.",
|
|
||||||
code: "NO_SUCH_PAGE",
|
|
||||||
id: "cc98a8a2-0dc3-4123-b198-62c71df18ed3",
|
|
||||||
},
|
|
||||||
|
|
||||||
alreadyLiked: {
|
|
||||||
message: "The page has already been liked.",
|
|
||||||
code: "ALREADY_LIKED",
|
|
||||||
id: "cc98a8a2-0dc3-4123-b198-62c71df18ed3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
pageId: { type: "string", format: "misskey:id" },
|
|
||||||
},
|
|
||||||
required: ["pageId"],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const page = await Pages.findOneBy({ id: ps.pageId });
|
|
||||||
if (page == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if already liked
|
|
||||||
const exist = await PageLikes.findOneBy({
|
|
||||||
pageId: page.id,
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (exist != null) {
|
|
||||||
throw new ApiError(meta.errors.alreadyLiked);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create like
|
|
||||||
await PageLikes.insert({
|
|
||||||
id: genId(),
|
|
||||||
createdAt: new Date(),
|
|
||||||
pageId: page.id,
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
Pages.increment({ id: page.id }, "likedCount", 1);
|
|
||||||
});
|
|
|
@ -1,75 +0,0 @@
|
||||||
import { IsNull } from "typeorm";
|
|
||||||
import { Pages, Users } from "@/models/index.js";
|
|
||||||
import type { Page } from "@/models/entities/page.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { ApiError } from "../../error.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["pages"],
|
|
||||||
|
|
||||||
requireCredential: false,
|
|
||||||
requireCredentialPrivateMode: true,
|
|
||||||
|
|
||||||
res: {
|
|
||||||
type: "object",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
ref: "Page",
|
|
||||||
},
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchPage: {
|
|
||||||
message: "No such page.",
|
|
||||||
code: "NO_SUCH_PAGE",
|
|
||||||
id: "222120c0-3ead-4528-811b-b96f233388d7",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
properties: {
|
|
||||||
pageId: { type: "string", format: "misskey:id" },
|
|
||||||
},
|
|
||||||
required: ["pageId"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
properties: {
|
|
||||||
name: { type: "string" },
|
|
||||||
username: { type: "string" },
|
|
||||||
},
|
|
||||||
required: ["name", "username"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
let page: Page | null = null;
|
|
||||||
|
|
||||||
if (ps.pageId) {
|
|
||||||
page = await Pages.findOneBy({ id: ps.pageId });
|
|
||||||
} else if (ps.name && ps.username) {
|
|
||||||
const author = await Users.findOneBy({
|
|
||||||
host: IsNull(),
|
|
||||||
usernameLower: ps.username.toLowerCase(),
|
|
||||||
});
|
|
||||||
if (author) {
|
|
||||||
page = await Pages.findOneBy({
|
|
||||||
name: ps.name,
|
|
||||||
userId: author.id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (page == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!page.isPublic && (user == null || page.userId !== user.id)) {
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Pages.pack(page, user);
|
|
||||||
});
|
|
|
@ -1,54 +0,0 @@
|
||||||
import { Pages, PageLikes } from "@/models/index.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { ApiError } from "../../error.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["pages"],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
|
|
||||||
kind: "write:page-likes",
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchPage: {
|
|
||||||
message: "No such page.",
|
|
||||||
code: "NO_SUCH_PAGE",
|
|
||||||
id: "a0d41e20-1993-40bd-890e-f6e560ae648e",
|
|
||||||
},
|
|
||||||
|
|
||||||
notLiked: {
|
|
||||||
message: "You have not liked that page.",
|
|
||||||
code: "NOT_LIKED",
|
|
||||||
id: "f5e586b0-ce93-4050-b0e3-7f31af5259ee",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
pageId: { type: "string", format: "misskey:id" },
|
|
||||||
},
|
|
||||||
required: ["pageId"],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const page = await Pages.findOneBy({ id: ps.pageId });
|
|
||||||
if (page == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
const exist = await PageLikes.findOneBy({
|
|
||||||
pageId: page.id,
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (exist == null) {
|
|
||||||
throw new ApiError(meta.errors.notLiked);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete like
|
|
||||||
await PageLikes.delete(exist.id);
|
|
||||||
|
|
||||||
Pages.decrement({ id: page.id }, "likedCount", 1);
|
|
||||||
});
|
|
|
@ -1,134 +0,0 @@
|
||||||
import { Not } from "typeorm";
|
|
||||||
import { Pages, DriveFiles } from "@/models/index.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { ApiError } from "../../error.js";
|
|
||||||
import { HOUR } from "@/const.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["pages"],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
|
|
||||||
kind: "write:pages",
|
|
||||||
|
|
||||||
limit: {
|
|
||||||
duration: HOUR,
|
|
||||||
max: 300,
|
|
||||||
},
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchPage: {
|
|
||||||
message: "No such page.",
|
|
||||||
code: "NO_SUCH_PAGE",
|
|
||||||
id: "21149b9e-3616-4778-9592-c4ce89f5a864",
|
|
||||||
},
|
|
||||||
|
|
||||||
accessDenied: {
|
|
||||||
message: "Access denied.",
|
|
||||||
code: "ACCESS_DENIED",
|
|
||||||
id: "3c15cd52-3b4b-4274-967d-6456fc4f792b",
|
|
||||||
},
|
|
||||||
|
|
||||||
noSuchFile: {
|
|
||||||
message: "No such file.",
|
|
||||||
code: "NO_SUCH_FILE",
|
|
||||||
id: "cfc23c7c-3887-490e-af30-0ed576703c82",
|
|
||||||
},
|
|
||||||
nameAlreadyExists: {
|
|
||||||
message: "Specified name already exists.",
|
|
||||||
code: "NAME_ALREADY_EXISTS",
|
|
||||||
id: "2298a392-d4a1-44c5-9ebb-ac1aeaa5a9ab",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
pageId: { type: "string", format: "misskey:id" },
|
|
||||||
title: { type: "string" },
|
|
||||||
name: { type: "string", minLength: 1 },
|
|
||||||
summary: { type: "string", nullable: true },
|
|
||||||
content: {
|
|
||||||
type: "array",
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
variables: {
|
|
||||||
type: "array",
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
script: { type: "string" },
|
|
||||||
eyeCatchingImageId: {
|
|
||||||
type: "string",
|
|
||||||
format: "misskey:id",
|
|
||||||
nullable: true,
|
|
||||||
},
|
|
||||||
font: { type: "string", enum: ["serif", "sans-serif"] },
|
|
||||||
alignCenter: { type: "boolean" },
|
|
||||||
hideTitleWhenPinned: { type: "boolean" },
|
|
||||||
isPublic: { type: "boolean" },
|
|
||||||
},
|
|
||||||
required: ["pageId", "title", "name", "content", "variables", "script"],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const page = await Pages.findOneBy({ id: ps.pageId });
|
|
||||||
if (page == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchPage);
|
|
||||||
}
|
|
||||||
if (page.userId !== user.id) {
|
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
|
||||||
}
|
|
||||||
|
|
||||||
let eyeCatchingImage = null;
|
|
||||||
if (ps.eyeCatchingImageId != null) {
|
|
||||||
eyeCatchingImage = await DriveFiles.findOneBy({
|
|
||||||
id: ps.eyeCatchingImageId,
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (eyeCatchingImage == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await Pages.findBy({
|
|
||||||
id: Not(ps.pageId),
|
|
||||||
userId: user.id,
|
|
||||||
name: ps.name,
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.length > 0) {
|
|
||||||
throw new ApiError(meta.errors.nameAlreadyExists);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await Pages.update(page.id, {
|
|
||||||
updatedAt: new Date(),
|
|
||||||
title: ps.title,
|
|
||||||
name: ps.name === undefined ? page.name : ps.name,
|
|
||||||
summary: ps.name === undefined ? page.summary : ps.summary,
|
|
||||||
content: ps.content,
|
|
||||||
variables: ps.variables,
|
|
||||||
script: ps.script,
|
|
||||||
isPublic: ps.isPublic,
|
|
||||||
alignCenter:
|
|
||||||
ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter,
|
|
||||||
hideTitleWhenPinned:
|
|
||||||
ps.hideTitleWhenPinned === undefined
|
|
||||||
? page.hideTitleWhenPinned
|
|
||||||
: ps.hideTitleWhenPinned,
|
|
||||||
font: ps.font === undefined ? page.font : ps.font,
|
|
||||||
eyeCatchingImageId:
|
|
||||||
ps.eyeCatchingImageId === null
|
|
||||||
? null
|
|
||||||
: ps.eyeCatchingImageId === undefined
|
|
||||||
? page.eyeCatchingImageId
|
|
||||||
: eyeCatchingImage!.id,
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,48 +0,0 @@
|
||||||
import { Pages } from "@/models/index.js";
|
|
||||||
import define from "../../define.js";
|
|
||||||
import { makePaginationQuery } from "../../common/make-pagination-query.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["users", "pages"],
|
|
||||||
requireCredentialPrivateMode: true,
|
|
||||||
|
|
||||||
description: "Show all pages this user created.",
|
|
||||||
|
|
||||||
res: {
|
|
||||||
type: "array",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
ref: "Page",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
userId: { type: "string", format: "misskey:id" },
|
|
||||||
limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
|
|
||||||
sinceId: { type: "string", format: "misskey:id" },
|
|
||||||
untilId: { type: "string", format: "misskey:id" },
|
|
||||||
},
|
|
||||||
required: ["userId"],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
|
||||||
const query = makePaginationQuery(
|
|
||||||
Pages.createQueryBuilder("page"),
|
|
||||||
ps.sinceId,
|
|
||||||
ps.untilId,
|
|
||||||
)
|
|
||||||
.andWhere("page.userId = :userId", { userId: ps.userId })
|
|
||||||
.andWhere("page.visibility = 'public'")
|
|
||||||
.andWhere("page.isPublic = true");
|
|
||||||
|
|
||||||
const pages = await query.take(ps.limit).getMany();
|
|
||||||
|
|
||||||
return await Pages.packMany(pages);
|
|
||||||
});
|
|
|
@ -1,13 +1,4 @@
|
||||||
import {
|
import {DriveFiles, Followings, NoteFavorites, NoteReactions, Notes, PollVotes, Users,} from "@/models/index.js";
|
||||||
DriveFiles,
|
|
||||||
Followings,
|
|
||||||
NoteFavorites,
|
|
||||||
NoteReactions,
|
|
||||||
Notes,
|
|
||||||
PageLikes,
|
|
||||||
PollVotes,
|
|
||||||
Users,
|
|
||||||
} from "@/models/index.js";
|
|
||||||
import {awaitAll} from "@/prelude/await-all.js";
|
import {awaitAll} from "@/prelude/await-all.js";
|
||||||
import define from "../../define.js";
|
import define from "../../define.js";
|
||||||
import {ApiError} from "../../error.js";
|
import {ApiError} from "../../error.js";
|
||||||
|
@ -113,16 +104,6 @@ export const meta = {
|
||||||
optional: false,
|
optional: false,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
},
|
},
|
||||||
pageLikesCount: {
|
|
||||||
type: "integer",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
},
|
|
||||||
pageLikedCount: {
|
|
||||||
type: "integer",
|
|
||||||
optional: false,
|
|
||||||
nullable: false,
|
|
||||||
},
|
|
||||||
driveFilesCount: {
|
driveFilesCount: {
|
||||||
type: "integer",
|
type: "integer",
|
||||||
optional: false,
|
optional: false,
|
||||||
|
@ -203,13 +184,6 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
noteFavoritesCount: NoteFavorites.createQueryBuilder("favorite")
|
noteFavoritesCount: NoteFavorites.createQueryBuilder("favorite")
|
||||||
.where("favorite.userId = :userId", { userId: user.id })
|
.where("favorite.userId = :userId", { userId: user.id })
|
||||||
.getCount(),
|
.getCount(),
|
||||||
pageLikesCount: PageLikes.createQueryBuilder("like")
|
|
||||||
.where("like.userId = :userId", { userId: user.id })
|
|
||||||
.getCount(),
|
|
||||||
pageLikedCount: PageLikes.createQueryBuilder("like")
|
|
||||||
.innerJoin("like.page", "page")
|
|
||||||
.where("page.userId = :userId", { userId: user.id })
|
|
||||||
.getCount(),
|
|
||||||
driveFilesCount: DriveFiles.createQueryBuilder("file")
|
driveFilesCount: DriveFiles.createQueryBuilder("file")
|
||||||
.where("file.userId = :userId", { userId: user.id })
|
.where("file.userId = :userId", { userId: user.id })
|
||||||
.getCount(),
|
.getCount(),
|
||||||
|
|
|
@ -9,7 +9,6 @@ import type {DriveFolder} from "@/models/entities/drive-folder.js";
|
||||||
import type {UserList} from "@/models/entities/user-list.js";
|
import type {UserList} from "@/models/entities/user-list.js";
|
||||||
import type {AbuseUserReport} from "@/models/entities/abuse-user-report.js";
|
import type {AbuseUserReport} from "@/models/entities/abuse-user-report.js";
|
||||||
import type {Signin} from "@/models/entities/signin.js";
|
import type {Signin} from "@/models/entities/signin.js";
|
||||||
import type {Page} from "@/models/entities/page.js";
|
|
||||||
import type {Packed} from "@/misc/schema.js";
|
import type {Packed} from "@/misc/schema.js";
|
||||||
import type {Webhook} from "@/models/entities/webhook";
|
import type {Webhook} from "@/models/entities/webhook";
|
||||||
|
|
||||||
|
@ -71,13 +70,6 @@ export interface MainStreamTypes {
|
||||||
followed: Packed<"User">;
|
followed: Packed<"User">;
|
||||||
unfollow: Packed<"User">;
|
unfollow: Packed<"User">;
|
||||||
meUpdated: Packed<"User">;
|
meUpdated: Packed<"User">;
|
||||||
pageEvent: {
|
|
||||||
pageId: Page["id"];
|
|
||||||
event: string;
|
|
||||||
var: any;
|
|
||||||
userId: User["id"];
|
|
||||||
user: Packed<"User">;
|
|
||||||
};
|
|
||||||
urlUploadFinished: {
|
urlUploadFinished: {
|
||||||
marker?: string | null;
|
marker?: string | null;
|
||||||
file: Packed<"DriveFile">;
|
file: Packed<"DriveFile">;
|
||||||
|
|
Loading…
Reference in New Issue