Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 69 additions & 92 deletions api/response.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { Omit } from "../utils.ts";
import { Line } from "../base.ts";
import { NotFoundError, NotMemberError } from "./error.ts";
import {
CommitId,
Line,
Page as PageBase,
PageId,
ProjectId,
StringLc,
UserId,
} from "../base.ts";

/** 関連ページのメタデータ */
export interface RelatedPage {
/** ページのid */ id: string;
/** ページのタイトル */ title: string;
/** ページのタイトルを小文字にして、` `を`_`に変換したもの */ titleLc: string;
/** ページのサムネイル画像 */ image: string;
/** ページのサムネイル本文。最大5行 */ descriptions: string[];
/** ページ内のリンク */ linksLc: string[];
export interface RelatedPage extends PageBase {
/** ページ内のリンク */ linksLc: StringLc[];
/** おそらく被リンク数 */ linked: number;
/** ページの最終更新日時 */ updated: number;
/** おそらくページの閲覧日時 */ accessed: number;
}

/** user information */
export interface User {
/** user id */ id: string;
id: UserId;
/** user name */ name: string;
/** user display name */ displayName: string;
/** profile image URL */ photo: string;
Expand All @@ -33,21 +33,12 @@ export interface UserInfo extends User {
}

/** summary of page information */
export interface PageSummary {
/** ページのid */ id: string;
/** ページのタイトル */ title: string;
/** ページのサムネイル画像
* 存在しなければ`null`
*/
image: string | null;
/** ページのサムネイル本文。最大5行 */ descriptions: string[];
export interface PageSummary extends PageBase {
/** ピン留めされていたら1, されていなかったら0 */ pin: 0 | 1;
/** ページの閲覧回数 */ views: number;
/** おそらく被リンク数 */ linked: number;
/** 最新の編集コミットid */ commitId: string;
/** 最新の編集コミットid */ commitId: CommitId;
/** ページの作成日時 */ created: number;
/** ページの最終更新日時 */ updated: number;
/** Date last visitedに使われる最終アクセス日時 */ accessed: number;
/** page rank */ pageRank: number;
/** Page historyの最終生成日時 */ snapshotCreated: number | null;
}
Expand All @@ -74,20 +65,17 @@ export interface Page extends PageSummary {
}

/** the response type of https://scrpabox.io/api/pages/:projectname */
export type PageListResponse =
| NotFoundError
| NotMemberError
| {
/** data取得先のproject名 */ projectName: string;
/** parameterに渡したskipと同じ */ skip: number;
/** parameterに渡したlimitと同じ */ limit: number;
/** projectの全ページ数 (中身のないページを除く) */ count: number;
/** 取得できたページ情報 */ pages: PageSummary[];
};
export interface PageList {
/** data取得先のproject名 */ projectName: string;
/** parameterに渡したskipと同じ */ skip: number;
/** parameterに渡したlimitと同じ */ limit: number;
/** projectの全ページ数 (中身のないページを除く) */ count: number;
/** 取得できたページ情報 */ pages: PageSummary[];
}

/** project basic information */
export interface Project {
id: string;
/** project information which isn't joined */
export interface NotMemberProject {
id: ProjectId;
name: string;
displayName: string;
publicVisible: boolean;
Expand All @@ -98,83 +86,72 @@ export interface Project {
image?: string;
created: number;
updated: number;
isMember: boolean;
plan?: string;
isMember: false;
}

/** project information which is joined */
export interface MemberProject extends Omit<NotMemberProject, "isMember"> {
isMember: true;
plan?: string | null;
users: UserInfo[];
admins: UserId[];
owner: UserId;
trialing: boolean;
trialMaxPages: number;
skipPayment: boolean;
uploadFileTo: "gcs";
uploadImaegTo: "gyazo" | "gcs";
emailAddressPatterns: string[];
backuped: number | null;
}

export interface GuestUser {
isGuest: true;
csrfToken: string;
}

/** the response type of https://scrpabox.io/api/projects/:projectname */
export type ProjectResponse =
| NotFoundError
| NotMemberError
| (
& Omit<Omit<Project, "isMember">, "plan">
& ({ isMember: false } | {
isMember: true;
plan?: string | null;
users: UserInfo[];
admins: string[];
owner: string;
trialing: boolean;
trialMaxPages: number;
skipPayment: boolean;
uploadFileTo: "gcs";
uploadImaegTo: "gyazo" | "gcs";
emailAddressPatterns: string[];
backuped: number | null;
})
);
export interface MemberUser extends UserInfo {
isGuest: false;
csrfToken: string;
config: {
userScript: boolean;
emacsBinding: boolean;
};
}

/** the response type of https://scrapbox.io/api/users/me */
export type UserResponse =
| {
isGuest: true;
csrfToken: string;
}
| ({
isGuest: false;
csrfToken: string;
config: {
userScript: boolean;
emacsBinding: boolean;
};
} & UserInfo);
export type UserResponse = GuestUser | MemberUser;

/** the response type of https://scrapbox.io/api/pages/:projectname/search/titles */
export type LinksResponse =
| NotFoundError
| NotMemberError
| {
message: "Invalid pageId";
}
| {
/** page id */ id: string;
/** page title */ title: string;
/** 画像が存在するかどうか */ hasIcon: boolean;
/** ページの更新日時 */ updated: number;
/** ページ内のリンク */ links: string[];
}[];
export interface SearchedTitle {
id: PageId;
/** page title */ title: string;
/** 画像が存在するかどうか */ hasIcon: boolean;
/** ページの更新日時 */ updated: number;
/** ページ内のリンク */ links: string[];
}

export type ProjectBackup = {
export interface ProjectBackup {
name: string;
displayName: string;
exported: number;
pages: {
id: string;
id: PageId;
title: string;
created: number;
updated: number;
lines: string[];
};
};
export type ProjectBackupWithMetadata = {
}
export interface ProjectBackupWithMetadata {
name: string;
displayName: string;
exported: number;
pages: {
id: string;
id: PageId;
title: string;
created: number;
updated: number;
lines: { text: string; updated: number; created: number }[];
lines: Omit<Line, "id" | "userId">[];
};
};
}
37 changes: 35 additions & 2 deletions base.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
/** scrapboxの行のメタデータ */
export interface Line {
/** 行のid */ id: string;
/** 行のid */ id: LineId;
/** 行のテキスト */ text: string;
/** 一番最後に行を編集した人のid */ userId: string;
/** 一番最後に行を編集した人のid */ userId: UserId;
/** 行の作成日時 */ created: number;
/** 行の最終更新日時 */ updated: number;
}

/** basic information about a page */
export interface Page {
/** the id of a page */ id: PageId;
/** the title of a page */ title: string;
/** the thumbnail URL of a page if exists
*
* set to `null` if not exists
*/
image: string | null;
/** the thumbnail text of a page.
* the maximum number of lines is 5.
* */ descriptions: string[];
/** ページの最終更新日時 */ updated: number;
/** Date last visitedに使われる最終アクセス日時 */ accessed: number;
}

/** the user id */
export type UserId = string;
/** the line id */
export type LineId = string;
/** the commit id */
export type CommitId = string;
/** the page id */
export type PageId = string;
/** the project id */
export type ProjectId = string;
/** the formatted string
*
* format rule:
* - UPPER CASE -> upper_case
*/
export type StringLc = string;
80 changes: 50 additions & 30 deletions userscript.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ParsedLine } from "./userscript/blocks.ts";
import { StringLc } from "./base.ts";

export type Layout =
| "list"
Expand Down Expand Up @@ -33,22 +34,8 @@ export type Scrapbox =
addSeparator: () => void;
removeAllItems: () => void;
};
addListener: (type: string, listener: () => void) => void;
on: (type: string, listener: () => void) => void;
removeListener: (type: string, listener: () => void) => void;
off: (type: string, listener: () => void) => void;
removeAllListeners: (type?: string) => void;
once: (type: string, listener: () => void) => void;
prependListener: (type: string, listener: () => void) => void;
prependOnceListener: (type: string, listener: () => void) => void;
listeners: (type: string) => (() => void)[];
rawListeners: (type: string) => (() => void)[];
listenerCount: (type: string) => number;
emit: (type: string) => void;
eventNames: () => string[];
getMexListeners: () => number;
setMexListeners: (length: number) => void;
}
& UserScriptEvents
& ({
Layout:
| "list"
Expand All @@ -73,29 +60,61 @@ export type Scrapbox =
};
});

export type PageBrief = {
exists: boolean;
hasIcon?: boolean;
id: string;
title: string;
titleLc: string;
updated: number;
};
export interface UserScriptEvents {
addListener: (type: string, listener: () => void) => void;
on: (type: string, listener: () => void) => void;
removeListener: (type: string, listener: () => void) => void;
off: (type: string, listener: () => void) => void;
removeAllListeners: (type?: string) => void;
once: (type: string, listener: () => void) => void;
prependListener: (type: string, listener: () => void) => void;
prependOnceListener: (type: string, listener: () => void) => void;
listeners: (type: string) => (() => void)[];
rawListeners: (type: string) => (() => void)[];
listenerCount: (type: string) => number;
emit: (type: string) => void;
eventNames: () => string[];
getMexListeners: () => number;
setMexListeners: (length: number) => void;
}
export interface PageBrief {
/** true when the page has contents */ exists: boolean;
/** whether the page contains any image */ hasIcon?: boolean;
/** the page id */ id: string;
/** the page title */ title: string;
titleLc: StringLc;
/** updated time */ updated: number;
}

type TimeStamp = {
export interface TimeStamp {
/** Add a timestamp format to Scrapbox
*
* @param format a format of timestamp. this follow the moment.js format. You can set a function which returns any string
*/
addFormat: (format: string | (() => string)) => void;
/** Remove all timestamp formats from Scrapbox
*
* These include default formats
*/
removeAllFormat: () => void;
};
}

type AddItemProps = {
title: string | (() => string);
export interface AddItemProps {
/** the title of a menu item */ title: string | (() => string);
/** the URL of an image which views on the left of the title */
image?: string;
/** the event listener which is executed when the menu item is clicked */
onClick: () => void;
};
type PageMenu = {
}
export interface PageMenu {
/** Add a menu item to a particular Page Menu button
*
* @param props information used for a menu item
*/
addItem: (
props: AddItemProps,
) => void;
/** Add a separator to a particular Page Menu button */
addSeparator: () => void;
removeAllItems: () => void;
menuName: string;
Expand All @@ -109,8 +128,9 @@ type PageMenu = {
items: (AddItemProps & { separator: boolean })[];
}
>;
};
}

/** built-in UserScript events */
export type eventName =
| "lines:changed"
| "page:changed"
Expand Down
Loading