iceshrimp-legacy/packages/backend/src/remote/activitypub/type.ts

296 lines
8.1 KiB
TypeScript
Raw Normal View History

2018-04-07 09:36:40 +02:00
export type obj = { [x: string]: any };
export type ApObject = IObject | string | (IObject | string)[];
export interface IObject {
2022-04-17 06:26:31 +02:00
'@context': string | string[] | obj | obj[];
2021-06-01 12:17:17 +02:00
type: string | string[];
id?: string;
summary?: string;
2018-04-07 23:55:26 +02:00
published?: string;
cc?: ApObject;
to?: ApObject;
attributedTo: ApObject;
2018-04-08 21:08:56 +02:00
attachment?: any[];
inReplyTo?: any;
Enhance poll (#4409) * Start working * WIP: Enhance poll * Fix bug * Use `name` in voting note refs: https://github.com/syuilo/misskey/issues/4407#issuecomment-469057296 * Fix style * Refactor Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com> * WIP: Update poll editor * Fix bug * Fix bug refs: https://github.com/syuilo/misskey/pull/4409#discussion_r * Fix typo * Better design * Beautify poll editor * Fix UI * Fix bug refs: https://github.com/syuilo/misskey/pull/4409#discussion_r262217524 * Add debug logging * Fix bug * Log deliver * fix vote * Update ap/show refs: https://github.com/syuilo/misskey/pull/4409#issuecomment-469652386 * Update poll view * Maybe done * Add tests * Fix path * Fix test * Fix test * Fix test * Fix expired check on AP * Update note.ts * Squashed commit of the following: commit d9a4beabf851893b8992a0f4568265eb9d4f0b8e Author: mei23 <m@m544.net> Date: Wed Mar 6 05:16:14 2019 +0900 tune commit 83ff421a6e978243f80ba9ec820189bc897e6e3b Author: mei23 <m@m544.net> Date: Wed Mar 6 05:01:14 2019 +0900 fallback commit 0b566af973b115ade9e75ea4b8094ee2b329dabc Author: mei23 <m@m544.net> Date: Wed Mar 6 04:40:12 2019 +0900 Note commit cc0296dd6127580ac584c40398db3f762a311f8b Author: mei23 <m@m544.net> Date: Wed Mar 6 04:33:58 2019 +0900 createで送る * Squashed commit of the following: commit ae696b1ed12568b27c27367ac5a77035c97c9a1f Author: mei23 <m@m544.net> Date: Wed Mar 6 06:11:17 2019 +0900 fix commit b735e354e7a9e64534c4f17d04ecbc65fb735c21 Author: mei23 <m@m544.net> Date: Wed Mar 6 06:08:33 2019 +0900 messge commit d9a4beabf851893b8992a0f4568265eb9d4f0b8e Author: mei23 <m@m544.net> Date: Wed Mar 6 05:16:14 2019 +0900 tune commit 83ff421a6e978243f80ba9ec820189bc897e6e3b Author: mei23 <m@m544.net> Date: Wed Mar 6 05:01:14 2019 +0900 fallback commit 0b566af973b115ade9e75ea4b8094ee2b329dabc Author: mei23 <m@m544.net> Date: Wed Mar 6 04:40:12 2019 +0900 Note commit cc0296dd6127580ac584c40398db3f762a311f8b Author: mei23 <m@m544.net> Date: Wed Mar 6 04:33:58 2019 +0900 createで送る * Fix typo * Update vote.ts * Update vote.ts * Update poll-editor.vue * Update tslint.json * Fix layout * Add note * Fix bug * Rename text key * 投票するときに投稿として扱わないように (#4425) * wip * 形式をMastodonと合わせた * Bye something * Use - instead of ~ * Redundancy * Yes! * Refactor * Use moment instead of Date * Fix indent * Refactor if (votes.length) は必要なさそう * Clean up * Bye Date * Clean * Fix timer is not displayed * Fix リモートから無期限pollにvoteできない * Fix vote actor
2019-03-06 14:55:47 +01:00
replies?: ICollection;
2019-04-13 11:58:29 +02:00
content?: string;
Enhance poll (#4409) * Start working * WIP: Enhance poll * Fix bug * Use `name` in voting note refs: https://github.com/syuilo/misskey/issues/4407#issuecomment-469057296 * Fix style * Refactor Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com> * WIP: Update poll editor * Fix bug * Fix bug refs: https://github.com/syuilo/misskey/pull/4409#discussion_r * Fix typo * Better design * Beautify poll editor * Fix UI * Fix bug refs: https://github.com/syuilo/misskey/pull/4409#discussion_r262217524 * Add debug logging * Fix bug * Log deliver * fix vote * Update ap/show refs: https://github.com/syuilo/misskey/pull/4409#issuecomment-469652386 * Update poll view * Maybe done * Add tests * Fix path * Fix test * Fix test * Fix test * Fix expired check on AP * Update note.ts * Squashed commit of the following: commit d9a4beabf851893b8992a0f4568265eb9d4f0b8e Author: mei23 <m@m544.net> Date: Wed Mar 6 05:16:14 2019 +0900 tune commit 83ff421a6e978243f80ba9ec820189bc897e6e3b Author: mei23 <m@m544.net> Date: Wed Mar 6 05:01:14 2019 +0900 fallback commit 0b566af973b115ade9e75ea4b8094ee2b329dabc Author: mei23 <m@m544.net> Date: Wed Mar 6 04:40:12 2019 +0900 Note commit cc0296dd6127580ac584c40398db3f762a311f8b Author: mei23 <m@m544.net> Date: Wed Mar 6 04:33:58 2019 +0900 createで送る * Squashed commit of the following: commit ae696b1ed12568b27c27367ac5a77035c97c9a1f Author: mei23 <m@m544.net> Date: Wed Mar 6 06:11:17 2019 +0900 fix commit b735e354e7a9e64534c4f17d04ecbc65fb735c21 Author: mei23 <m@m544.net> Date: Wed Mar 6 06:08:33 2019 +0900 messge commit d9a4beabf851893b8992a0f4568265eb9d4f0b8e Author: mei23 <m@m544.net> Date: Wed Mar 6 05:16:14 2019 +0900 tune commit 83ff421a6e978243f80ba9ec820189bc897e6e3b Author: mei23 <m@m544.net> Date: Wed Mar 6 05:01:14 2019 +0900 fallback commit 0b566af973b115ade9e75ea4b8094ee2b329dabc Author: mei23 <m@m544.net> Date: Wed Mar 6 04:40:12 2019 +0900 Note commit cc0296dd6127580ac584c40398db3f762a311f8b Author: mei23 <m@m544.net> Date: Wed Mar 6 04:33:58 2019 +0900 createで送る * Fix typo * Update vote.ts * Update vote.ts * Update poll-editor.vue * Update tslint.json * Fix layout * Add note * Fix bug * Rename text key * 投票するときに投稿として扱わないように (#4425) * wip * 形式をMastodonと合わせた * Bye something * Use - instead of ~ * Redundancy * Yes! * Refactor * Use moment instead of Date * Fix indent * Refactor if (votes.length) は必要なさそう * Clean up * Bye Date * Clean * Fix timer is not displayed * Fix リモートから無期限pollにvoteできない * Fix vote actor
2019-03-06 14:55:47 +01:00
name?: string;
startTime?: Date;
endTime?: Date;
2018-04-08 21:08:56 +02:00
icon?: any;
image?: any;
url?: ApObject;
href?: string;
tag?: IObject | IObject[];
2018-08-19 11:08:29 +02:00
sensitive?: boolean;
}
/**
* Get array of ActivityStreams Objects id
*/
export function getApIds(value: ApObject | undefined): string[] {
if (value == null) return [];
const array = Array.isArray(value) ? value : [value];
return array.map(x => getApId(x));
}
/**
* Get first ActivityStreams Object id
*/
export function getOneApId(value: ApObject): string {
const firstOne = Array.isArray(value) ? value[0] : value;
return getApId(firstOne);
}
/**
* Get ActivityStreams Object id
*/
export function getApId(value: string | IObject): string {
if (typeof value === 'string') return value;
if (typeof value.id === 'string') return value.id;
2022-04-17 06:14:29 +02:00
throw new Error('cannot detemine id');
}
/**
* Get ActivityStreams Object type
*/
export function getApType(value: IObject): string {
if (typeof value.type === 'string') return value.type;
if (Array.isArray(value.type) && typeof value.type[0] === 'string') return value.type[0];
2022-04-17 06:14:29 +02:00
throw new Error('cannot detect type');
}
export function getOneApHrefNullable(value: ApObject | undefined): string | undefined {
const firstOne = Array.isArray(value) ? value[0] : value;
return getApHrefNullable(firstOne);
}
export function getApHrefNullable(value: string | IObject | undefined): string | undefined {
if (typeof value === 'string') return value;
if (typeof value?.href === 'string') return value.href;
return undefined;
}
2018-04-07 09:14:35 +02:00
export interface IActivity extends IObject {
//type: 'Activity';
actor: IObject | string;
object: IObject | string;
target?: IObject | string;
/** LD-Signature */
signature?: {
type: string;
created: Date;
creator: string;
domain?: string;
nonce?: string;
signatureValue: string;
};
2018-04-07 09:14:35 +02:00
}
export interface ICollection extends IObject {
type: 'Collection';
totalItems: number;
items: ApObject;
}
export interface IOrderedCollection extends IObject {
type: 'OrderedCollection';
totalItems: number;
orderedItems: ApObject;
}
export const validPost = ['Note', 'Question', 'Article', 'Audio', 'Document', 'Image', 'Page', 'Video', 'Event'];
export const isPost = (object: IObject): object is IPost =>
validPost.includes(getApType(object));
export interface IPost extends IObject {
type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video' | 'Event';
source?: {
content: string;
mediaType: string;
};
2019-04-13 11:58:29 +02:00
_misskey_quote?: string;
quoteUrl?: string;
2019-10-28 22:01:14 +01:00
_misskey_talk: boolean;
2018-04-07 23:55:26 +02:00
}
export interface IQuestion extends IObject {
type: 'Note' | 'Question';
source?: {
content: string;
mediaType: string;
};
2019-04-13 11:58:29 +02:00
_misskey_quote?: string;
quoteUrl?: string;
oneOf?: IQuestionChoice[];
anyOf?: IQuestionChoice[];
endTime?: Date;
2019-07-19 20:20:06 +02:00
closed?: Date;
}
export const isQuestion = (object: IObject): object is IQuestion =>
getApType(object) === 'Note' || getApType(object) === 'Question';
interface IQuestionChoice {
name?: string;
replies?: ICollection;
_misskey_votes?: number;
}
2020-07-10 23:19:49 +02:00
export interface ITombstone extends IObject {
type: 'Tombstone';
formerType?: string;
deleted?: Date;
}
export const isTombstone = (object: IObject): object is ITombstone =>
getApType(object) === 'Tombstone';
2020-05-09 01:25:23 +02:00
export const validActor = ['Person', 'Service', 'Group', 'Organization', 'Application'];
export const isActor = (object: IObject): object is IActor =>
validActor.includes(getApType(object));
export interface IActor extends IObject {
2020-05-09 01:25:23 +02:00
type: 'Person' | 'Service' | 'Organization' | 'Group' | 'Application';
2019-10-28 12:34:01 +01:00
name?: string;
preferredUsername?: string;
manuallyApprovesFollowers?: boolean;
discoverable?: boolean;
inbox: string;
2019-10-28 12:34:01 +01:00
sharedInbox?: string; // 後方互換性のため
publicKey?: {
2019-10-28 12:34:01 +01:00
id: string;
publicKeyPem: string;
};
followers?: string | ICollection | IOrderedCollection;
following?: string | ICollection | IOrderedCollection;
featured?: string | IOrderedCollection;
outbox: string | IOrderedCollection;
2019-10-28 12:34:01 +01:00
endpoints?: {
sharedInbox?: string;
};
'vcard:bday'?: string;
'vcard:Address'?: string;
2018-04-08 21:08:56 +02:00
}
export const isCollection = (object: IObject): object is ICollection =>
getApType(object) === 'Collection';
export const isOrderedCollection = (object: IObject): object is IOrderedCollection =>
getApType(object) === 'OrderedCollection';
export const isCollectionOrOrderedCollection = (object: IObject): object is ICollection | IOrderedCollection =>
isCollection(object) || isOrderedCollection(object);
2018-04-07 09:14:35 +02:00
export interface IApPropertyValue extends IObject {
type: 'PropertyValue';
identifier: IApPropertyValue;
name: string;
value: string;
}
export const isPropertyValue = (object: IObject): object is IApPropertyValue =>
object &&
getApType(object) === 'PropertyValue' &&
typeof object.name === 'string' &&
typeof (object as any).value === 'string';
export interface IApMention extends IObject {
type: 'Mention';
href: string;
}
export const isMention = (object: IObject): object is IApMention=>
getApType(object) === 'Mention' &&
typeof object.href === 'string';
export interface IApHashtag extends IObject {
type: 'Hashtag';
name: string;
}
export const isHashtag = (object: IObject): object is IApHashtag =>
getApType(object) === 'Hashtag' &&
typeof object.name === 'string';
export interface IApEmoji extends IObject {
type: 'Emoji';
updated: Date;
}
export const isEmoji = (object: IObject): object is IApEmoji =>
getApType(object) === 'Emoji' && !Array.isArray(object.icon) && object.icon.url != null;
2018-04-07 09:14:35 +02:00
export interface ICreate extends IActivity {
type: 'Create';
}
2018-04-07 09:36:40 +02:00
export interface IDelete extends IActivity {
type: 'Delete';
}
export interface IUpdate extends IActivity {
type: 'Update';
}
export interface IRead extends IActivity {
type: 'Read';
}
2018-04-07 09:14:35 +02:00
export interface IUndo extends IActivity {
type: 'Undo';
}
export interface IFollow extends IActivity {
type: 'Follow';
}
2018-04-07 09:36:40 +02:00
export interface IAccept extends IActivity {
type: 'Accept';
}
2018-05-31 17:42:37 +02:00
export interface IReject extends IActivity {
type: 'Reject';
}
export interface IAdd extends IActivity {
type: 'Add';
}
export interface IRemove extends IActivity {
type: 'Remove';
}
2018-04-07 10:05:14 +02:00
export interface ILike extends IActivity {
2020-02-07 13:37:24 +01:00
type: 'Like' | 'EmojiReaction' | 'EmojiReact';
2019-04-13 11:58:29 +02:00
_misskey_reaction?: string;
2018-04-07 10:05:14 +02:00
}
2018-04-07 23:55:26 +02:00
export interface IAnnounce extends IActivity {
type: 'Announce';
}
export interface IBlock extends IActivity {
type: 'Block';
}
2020-05-09 01:25:23 +02:00
export interface IFlag extends IActivity {
type: 'Flag';
}
export const isCreate = (object: IObject): object is ICreate => getApType(object) === 'Create';
export const isDelete = (object: IObject): object is IDelete => getApType(object) === 'Delete';
export const isUpdate = (object: IObject): object is IUpdate => getApType(object) === 'Update';
export const isRead = (object: IObject): object is IRead => getApType(object) === 'Read';
export const isUndo = (object: IObject): object is IUndo => getApType(object) === 'Undo';
export const isFollow = (object: IObject): object is IFollow => getApType(object) === 'Follow';
export const isAccept = (object: IObject): object is IAccept => getApType(object) === 'Accept';
export const isReject = (object: IObject): object is IReject => getApType(object) === 'Reject';
export const isAdd = (object: IObject): object is IAdd => getApType(object) === 'Add';
export const isRemove = (object: IObject): object is IRemove => getApType(object) === 'Remove';
export const isLike = (object: IObject): object is ILike => getApType(object) === 'Like' || getApType(object) === 'EmojiReaction' || getApType(object) === 'EmojiReact';
export const isAnnounce = (object: IObject): object is IAnnounce => getApType(object) === 'Announce';
export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block';
export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag';