update backend to the new templates
This commit is contained in:
parent
4e30986cda
commit
05be2596ea
44 changed files with 156 additions and 111 deletions
|
|
@ -151,7 +151,7 @@ export default [
|
|||
},
|
||||
parserOptions: {
|
||||
parser: tsParser,
|
||||
project: ['./jsconfig.frontend.json'],
|
||||
project: ['./tsconfig.frontend.json'],
|
||||
sourceType: 'module',
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
"typecheck": "pnpm --filter megalodon build && pnpm run typecheck:scripts && pnpm run typecheck:backend && pnpm run typecheck:frontend && pnpm run typecheck:test && pnpm run typecheck:test-federation && pnpm run typecheck:test-server",
|
||||
"typecheck:scripts": "tsc -p tsconfig.scripts.json --noEmit",
|
||||
"typecheck:backend": "tsc -p tsconfig.backend.json --noEmit",
|
||||
"typecheck:frontend": "tsc -p jsconfig.frontend.json --noEmit",
|
||||
"typecheck:frontend": "tsc -p tsconfig.frontend.json --noEmit",
|
||||
"typecheck:test": "tsc -p test/tsconfig.json --noEmit",
|
||||
"typecheck:test-federation": "tsc -p test-federation/tsconfig.json --noEmit",
|
||||
"typecheck:test-server": "tsc -p test-server/tsconfig.json --noEmit",
|
||||
|
|
|
|||
|
|
@ -767,7 +767,7 @@ export class DriveService {
|
|||
|
||||
@bindThis
|
||||
public async deleteFileSync(file: MiDriveFile, isExpired = false, deleter?: { id: string }) {
|
||||
const promises = [];
|
||||
const promises: Promise<void>[] = [];
|
||||
|
||||
if (file.storedInternal) {
|
||||
promises.push(this.deleteLocalFile(file.accessKey!));
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ export class MfmService {
|
|||
(note that the `rp` are to be ignored, they only exist
|
||||
for browsers who don't understand ruby)
|
||||
*/
|
||||
let nonRtNodes = [];
|
||||
let nonRtNodes: ChildNode[] = [];
|
||||
// scan children, ignore `rp`, split on `rt`
|
||||
for (const child of node.childNodes) {
|
||||
if (isText(child)) {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ export class ReactionsBufferingService implements OnApplicationShutdown {
|
|||
// TODO: scanは重い可能性があるので、別途 bufferedNoteIds を直接Redis上に持っておいてもいいかもしれない
|
||||
@bindThis
|
||||
public async bake(): Promise<void> {
|
||||
const bufferedNoteIds = [];
|
||||
const bufferedNoteIds: string[] = [];
|
||||
let cursor = '0';
|
||||
do {
|
||||
// https://github.com/redis/ioredis#transparent-key-prefixing
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export class FlashEntityService {
|
|||
// { schema: 'UserDetailed' } すると無限ループするので注意
|
||||
const user = hint?.packedUser ?? await this.userEntityService.pack(flash.user ?? flash.userId, me);
|
||||
|
||||
let isLiked = undefined;
|
||||
let isLiked: boolean | undefined = undefined;
|
||||
if (meId) {
|
||||
isLiked = hint?.likedFlashIds
|
||||
? hint.likedFlashIds.includes(flash.id)
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ export class MetaEntityService {
|
|||
.getMany();
|
||||
|
||||
// クライアントの手間を減らすためあらかじめJSONに変換しておく
|
||||
let defaultLightTheme = null;
|
||||
let defaultDarkTheme = null;
|
||||
let defaultLightTheme: string | null = null;
|
||||
let defaultDarkTheme: string | null = null;
|
||||
if (instance.defaultLightTheme) {
|
||||
try {
|
||||
defaultLightTheme = JSON.stringify(JSON5.parse(instance.defaultLightTheme));
|
||||
|
|
|
|||
|
|
@ -491,7 +491,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
|
||||
@bindThis
|
||||
public async packAttachedFiles(fileIds: MiNote['fileIds'], packedFiles: Map<MiNote['fileIds'][number], Packed<'DriveFile'> | null>): Promise<Packed<'DriveFile'>[]> {
|
||||
const missingIds = [];
|
||||
const missingIds: string[] = [];
|
||||
for (const id of fileIds) {
|
||||
if (!packedFiles.has(id)) missingIds.push(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
|
||||
validNotifications = validNotifications.filter(x => !('noteId' in x) || packedNotes.has(x.noteId));
|
||||
|
||||
const userIds = [];
|
||||
const userIds: string[] = [];
|
||||
for (const notification of validNotifications) {
|
||||
if ('notifierId' in notification) userIds.push(notification.notifierId);
|
||||
if (notification.type === 'reaction:grouped') userIds.push(...notification.reactions.map(x => x.userId));
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
function parseBigIntChunked(str: string, base: number, chunkSize: number, powerOfChunkSize: bigint): bigint {
|
||||
const chunks = [];
|
||||
const chunks: string[] = [];
|
||||
while (str.length > 0) {
|
||||
chunks.unshift(str.slice(-chunkSize));
|
||||
str = str.slice(0, -chunkSize);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export function generateInviteCode(now: number): string {
|
|||
chars: CHARS,
|
||||
});
|
||||
|
||||
const uniqueId = [];
|
||||
const uniqueId: string[] = [];
|
||||
let n = Math.floor(now / 1000 / 60);
|
||||
while (true) {
|
||||
uniqueId.push(CHARS[n % CHARS.length]);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ export function lessThan(xs: number[], ys: number[]): boolean {
|
|||
* Returns the longest prefix of elements that satisfy the predicate
|
||||
*/
|
||||
export function takeWhile<T>(f: Predicate<T>, xs: T[]): T[] {
|
||||
const ys = [];
|
||||
const ys: T[] = [];
|
||||
for (const x of xs) {
|
||||
if (f(x)) {
|
||||
ys.push(x);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type { HttpRequestService } from '@/core/HttpRequestService.js';
|
|||
type Field = { name: string, value: string };
|
||||
|
||||
export async function verifyFieldLinks(fields: Field[], profileUrls: string[], httpRequestService: HttpRequestService): Promise<string[]> {
|
||||
const verified_links = [];
|
||||
const verified_links: string[] = [];
|
||||
for (const field_url of fields) {
|
||||
try {
|
||||
// getHtml validates the input URL, so we can safely pass in untrusted values
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ class TypeORMLogger implements Logger {
|
|||
@bindThis
|
||||
private transformParameters(parameters?: unknown[]): Data | undefined {
|
||||
if (this.props.enableQueryParamLogging && parameters && parameters.length > 0) {
|
||||
return parameters.reduce((params: Record<string, string>, p, i) => {
|
||||
return parameters.reduce<Record<string, string>>((params: Record<string, string>, p, i) => {
|
||||
params[`$${i + 1}`] = stringifyParameter(p);
|
||||
return params;
|
||||
}, {} as Record<string, string>);
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ export class ImportNotesProcessorService {
|
|||
const visibility = followers ? toot.cc.includes('https://www.w3.org/ns/activitystreams#Public') ? 'home' : 'followers' : 'public';
|
||||
|
||||
const date = new Date(toot.object.published);
|
||||
let text = undefined;
|
||||
let text: string | undefined = undefined;
|
||||
const files: MiDriveFile[] = [];
|
||||
let reply: MiNote | null = null;
|
||||
|
||||
|
|
@ -464,7 +464,7 @@ export class ImportNotesProcessorService {
|
|||
}
|
||||
|
||||
const date = new Date(post.object.published);
|
||||
let text = undefined;
|
||||
let text: string | undefined = undefined;
|
||||
const files: MiDriveFile[] = [];
|
||||
let reply: MiNote | null = null;
|
||||
|
||||
|
|
@ -547,7 +547,7 @@ export class ImportNotesProcessorService {
|
|||
const files: MiDriveFile[] = [];
|
||||
|
||||
function decodeIGString(str: string) {
|
||||
const arr = [];
|
||||
const arr: number[] = [];
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
arr.push(str.charCodeAt(i));
|
||||
}
|
||||
|
|
@ -700,7 +700,7 @@ export class ImportNotesProcessorService {
|
|||
const files: MiDriveFile[] = [];
|
||||
|
||||
function decodeFBString(str: string) {
|
||||
const arr = [];
|
||||
const arr: number[] = [];
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
arr.push(str.charCodeAt(i));
|
||||
}
|
||||
|
|
@ -708,7 +708,7 @@ export class ImportNotesProcessorService {
|
|||
}
|
||||
|
||||
if (post.attachments && this.isIterable(post.attachments)) {
|
||||
const media = [];
|
||||
const media: any[] = [];
|
||||
for await (const data of post.attachments[0].data) {
|
||||
if (data.media) {
|
||||
media.push(data.media);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,11 @@ export const meta = {
|
|||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {} as const;
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
kind: 'write:admin:cw-instance',
|
||||
|
||||
res: {},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
kind: 'write:admin:cw-note',
|
||||
|
||||
res: {},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
kind: 'write:admin:cw-user',
|
||||
|
||||
res: {},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
@ -63,6 +61,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
userUsername: user.username,
|
||||
userHost: user.host,
|
||||
});
|
||||
|
||||
return {};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ export const paramDef = {
|
|||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
url: { type: 'string' },
|
||||
},
|
||||
// TODO it chokes on this
|
||||
anyOf: [
|
||||
{ required: ['fileId'] },
|
||||
{ required: ['url'] },
|
||||
|
|
|
|||
|
|
@ -102,8 +102,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
case 'NO_SUCH_EMOJI': throw new ApiError(meta.errors.noSuchEmoji);
|
||||
case 'SAME_NAME_EMOJI_EXISTS': throw new ApiError(meta.errors.sameNameEmojiExists);
|
||||
}
|
||||
// 網羅性チェック
|
||||
const mustBeNever: never = error;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@ export const meta = {
|
|||
kind: 'write:admin:meta',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {} as const;
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { RegistrationTicketsRepository } from '@/models/_.js';
|
||||
import type { RegistrationTicketsRepository, MiRegistrationTicket } from '@/models/_.js';
|
||||
import { InviteCodeEntityService } from '@/core/entities/InviteCodeEntityService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
|
@ -65,7 +65,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new ApiError(meta.errors.invalidDateTime);
|
||||
}
|
||||
|
||||
const ticketsPromises = [];
|
||||
const ticketsPromises: Promise<MiRegistrationTicket>[] = [];
|
||||
|
||||
for (let i = 0; i < ps.count; i++) {
|
||||
ticketsPromises.push(this.registrationTicketsRepository.insertOne({
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { ChannelsRepository, DriveFilesRepository } from '@/models/_.js';
|
||||
import type { ChannelsRepository, DriveFilesRepository, MiDriveFile } from '@/models/_.js';
|
||||
import type { MiChannel } from '@/models/Channel.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
|
||||
|
|
@ -68,7 +68,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private channelEntityService: ChannelEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
let banner = null;
|
||||
let banner: MiDriveFile | null = null;
|
||||
if (ps.bannerId != null) {
|
||||
banner = await this.driveFilesRepository.findOneBy({
|
||||
id: ps.bannerId,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { DriveFilesRepository, ChannelsRepository } from '@/models/_.js';
|
||||
import type { DriveFilesRepository, ChannelsRepository, MiDriveFile } from '@/models/_.js';
|
||||
import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
|
|
@ -99,8 +99,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new ApiError(meta.errors.accessDenied);
|
||||
}
|
||||
|
||||
// eslint:disable-next-line:no-unnecessary-initializer
|
||||
let banner = undefined;
|
||||
let banner: MiDriveFile | null = null;
|
||||
if (ps.bannerId != null) {
|
||||
banner = await this.driveFilesRepository.findOneBy({
|
||||
id: ps.bannerId,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { GetterService } from '@/server/api/GetterService.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { ChatService } from '@/core/ChatService.js';
|
||||
import type { DriveFilesRepository, MiUser } from '@/models/_.js';
|
||||
import type { DriveFilesRepository, MiUser, MiDriveFile } from '@/models/_.js';
|
||||
import type { Config } from '@/config.js';
|
||||
|
||||
export const meta = {
|
||||
|
|
@ -96,7 +96,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
}
|
||||
|
||||
let file = null;
|
||||
let file: MiDriveFile | null = null;
|
||||
if (ps.fileId != null) {
|
||||
file = await this.driveFilesRepository.findOneBy({
|
||||
id: ps.fileId,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { GetterService } from '@/server/api/GetterService.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { ChatService } from '@/core/ChatService.js';
|
||||
import type { DriveFilesRepository, MiUser } from '@/models/_.js';
|
||||
import type { DriveFilesRepository, MiUser, MiDriveFile } from '@/models/_.js';
|
||||
import type { Config } from '@/config.js';
|
||||
|
||||
export const meta = {
|
||||
|
|
@ -103,7 +103,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new ApiError(meta.errors.maxLength);
|
||||
}
|
||||
|
||||
let file = null;
|
||||
let file: MiDriveFile | null = null;
|
||||
if (ps.fileId != null) {
|
||||
file = await this.driveFilesRepository.findOneBy({
|
||||
id: ps.fileId,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { DriveFoldersRepository } from '@/models/_.js';
|
||||
import type { DriveFoldersRepository, MiDriveFolder } from '@/models/_.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { DriveFolderEntityService } from '@/core/entities/DriveFolderEntityService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
|
|
@ -61,7 +61,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
// If the parent folder is specified
|
||||
let parent = null;
|
||||
let parent: MiDriveFolder | null = null;
|
||||
if (ps.parentId) {
|
||||
// Fetch parent folder
|
||||
parent = await this.driveFoldersRepository.findOneBy({
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ export const meta = {
|
|||
},
|
||||
},
|
||||
|
||||
res: {},
|
||||
|
||||
// 10 calls per 5 seconds
|
||||
limit: {
|
||||
duration: 1000 * 5,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import ms from 'ms';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { DriveFilesRepository, PagesRepository } from '@/models/_.js';
|
||||
import type { DriveFilesRepository, PagesRepository, MiDriveFile } from '@/models/_.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { MiPage, pageNameSchema } from '@/models/Page.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
|
|
@ -83,7 +83,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private readonly timeService: TimeService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
let eyeCatchingImage = null;
|
||||
let eyeCatchingImage: MiDriveFile | null = null;
|
||||
if (ps.eyeCatchingImageId != null) {
|
||||
eyeCatchingImage = await this.driveFilesRepository.findOneBy({
|
||||
id: ps.eyeCatchingImageId,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { createReadStream } from 'node:fs';
|
||||
import { Readable } from 'node:stream';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { getErrorData, getErrorException, getErrorStatus, MastodonLogger } from '@/server/api/mastodon/MastodonLogger.js';
|
||||
|
|
@ -118,7 +120,10 @@ export class MastodonApiServerService {
|
|||
}
|
||||
|
||||
const client = this.clientService.getClient(_request);
|
||||
const data = await client.uploadMedia(multipartData);
|
||||
const data = await client.uploadMedia({
|
||||
...multipartData,
|
||||
stream: Readable.toWeb(createReadStream(multipartData.filepath)),
|
||||
});
|
||||
const response = convertAttachment(data.data as Entity.Attachment);
|
||||
|
||||
return reply.send(response);
|
||||
|
|
@ -131,7 +136,10 @@ export class MastodonApiServerService {
|
|||
}
|
||||
|
||||
const client = this.clientService.getClient(_request);
|
||||
const data = await client.uploadMedia(multipartData, _request.body);
|
||||
const data = await client.uploadMedia({
|
||||
...multipartData,
|
||||
stream: Readable.toWeb(createReadStream(multipartData.filepath)),
|
||||
}, _request.body);
|
||||
const response = convertAttachment(data.data as Entity.Attachment);
|
||||
|
||||
return reply.send(response);
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Entity, MastodonEntity, MisskeyEntity } from 'megalodon';
|
||||
import * as mfm from 'mfm-js';
|
||||
import { MastodonNotificationType } from 'megalodon/lib/src/mastodon/notification.js';
|
||||
import { NotificationType } from 'megalodon/lib/src/notification.js';
|
||||
import { MastodonNotificationType } from 'megalodon/built/lib/mastodon/notification.js';
|
||||
import { NotificationType } from 'megalodon/built/lib/notification.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { MfmService } from '@/core/MfmService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
window.onload = async () => {
|
||||
const content = document.getElementById('content');
|
||||
|
||||
document.getElementById('ls').addEventListener('click', () => {
|
||||
content.innerHTML = '';
|
||||
document.getElementById('ls')?.addEventListener('click', () => {
|
||||
if (content) content.innerHTML = '';
|
||||
|
||||
const lsEditor = document.createElement('div');
|
||||
lsEditor.id = 'lsEditor';
|
||||
|
|
@ -31,7 +31,7 @@ window.onload = async () => {
|
|||
lsEditor.appendChild(adder);
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const k = localStorage.key(i);
|
||||
const k = /** @type {string} */ (localStorage.key(i));
|
||||
const record = document.createElement('div');
|
||||
record.classList.add('record');
|
||||
const header = document.createElement('header');
|
||||
|
|
@ -57,6 +57,6 @@ window.onload = async () => {
|
|||
lsEditor.appendChild(record);
|
||||
}
|
||||
|
||||
content.appendChild(lsEditor);
|
||||
content?.appendChild(lsEditor);
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
//#region Detect language & fetch translations
|
||||
if (!localStorage.getItem('locale')) {
|
||||
const supportedLangs = LANGS;
|
||||
/** @type {string | null | undefined} */
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (lang == null || !supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
|
|
@ -92,12 +93,20 @@
|
|||
}
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* @param {string} styleText
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function addStyle(styleText) {
|
||||
let css = document.createElement('style');
|
||||
css.appendChild(document.createTextNode(styleText));
|
||||
document.head.appendChild(css);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function renderError(code) {
|
||||
// Cannot set property 'innerHTML' of null を回避
|
||||
if (document.readyState === 'loading') {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
//#region Detect language & fetch translations
|
||||
if (!localStorage.getItem('locale')) {
|
||||
const supportedLangs = LANGS;
|
||||
/** @type {string | null | undefined} */
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (lang == null || !supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
|
|
@ -154,12 +155,21 @@
|
|||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} styleText
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function addStyle(styleText) {
|
||||
let css = document.createElement('style');
|
||||
css.appendChild(document.createTextNode(styleText));
|
||||
document.head.appendChild(css);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @param {any} [details]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function renderError(code, details) {
|
||||
// Cannot set property 'innerHTML' of null を回避
|
||||
if (document.readyState === 'loading') {
|
||||
|
|
@ -233,7 +243,7 @@
|
|||
<code>ERROR CODE: ${code}</code>
|
||||
</summary>
|
||||
<code>${details.toString()} ${JSON.stringify(details)}</code>`;
|
||||
errorsElement.appendChild(detailsElement);
|
||||
errorsElement?.appendChild(detailsElement);
|
||||
addStyle(`
|
||||
* {
|
||||
font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
|
||||
|
|
|
|||
|
|
@ -6,9 +6,15 @@
|
|||
'use strict';
|
||||
|
||||
window.onload = async () => {
|
||||
const account = JSON.parse(localStorage.getItem('account'));
|
||||
const i = account.token;
|
||||
const accountRaw = localStorage.getItem('account');
|
||||
const account = accountRaw ? JSON.parse(accountRaw) : null;
|
||||
const i = account?.token;
|
||||
|
||||
/**
|
||||
* @param {string} endpoint
|
||||
* @param {Record<string, unknown>} data
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
const api = (endpoint, data = {}) => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
// Append a credential
|
||||
|
|
@ -17,19 +23,19 @@ window.onload = async () => {
|
|||
// Send request
|
||||
fetch(endpoint.indexOf('://') > -1 ? endpoint : `/api/${endpoint}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'omit',
|
||||
cache: 'no-cache'
|
||||
cache: 'no-cache',
|
||||
}).then(async (res) => {
|
||||
const body = res.status === 204 ? null : await res.json();
|
||||
|
||||
if (res.status === 200) {
|
||||
resolve(body);
|
||||
} else if (res.status === 204) {
|
||||
resolve();
|
||||
resolve({});
|
||||
} else {
|
||||
reject(body.error);
|
||||
}
|
||||
|
|
@ -39,7 +45,7 @@ window.onload = async () => {
|
|||
return promise;
|
||||
};
|
||||
|
||||
document.getElementById('submit').addEventListener('click', () => {
|
||||
document.getElementById('submit')?.addEventListener('click', () => {
|
||||
api('notes/create', {
|
||||
text: (/** @type {HTMLInputElement} */(document.getElementById('text'))).value
|
||||
}).then(() => {
|
||||
|
|
@ -49,6 +55,7 @@ window.onload = async () => {
|
|||
|
||||
api('notes/timeline').then(notes => {
|
||||
const tl = document.getElementById('tl');
|
||||
if (!tl) return;
|
||||
for (const note of notes) {
|
||||
const el = document.createElement('div');
|
||||
const name = document.createElement('header');
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
{
|
||||
"extends": "../../shared/tsconfig.node.json",
|
||||
"extends": "../../shared/tsconfig.node.jsonc",
|
||||
"compilerOptions": {
|
||||
// Checking
|
||||
"types": ["jest", "node"],
|
||||
"verbatimModuleSyntax": false,
|
||||
"outDir": "./built",
|
||||
"noImplicitOverride": false,
|
||||
"noImplicitAny": false,
|
||||
"strictFunctionTypes": false,
|
||||
"strictPropertyInitialization": false,
|
||||
"paths": {
|
||||
"@/*": ["../src/*"]
|
||||
},
|
||||
"typeRoots": [
|
||||
"../node_modules/@types"
|
||||
]
|
||||
|
||||
// Output
|
||||
"outDir": "./built"
|
||||
},
|
||||
"include": [
|
||||
"daemon.ts",
|
||||
|
|
|
|||
|
|
@ -5,12 +5,7 @@
|
|||
"paths": {
|
||||
"@/*": ["../src/*"]
|
||||
},
|
||||
"outDir": "../built-test",
|
||||
"typeRoots": [
|
||||
"../src/@types",
|
||||
"../node_modules/@types",
|
||||
"../node_modules"
|
||||
]
|
||||
"outDir": "../built-test"
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts",
|
||||
|
|
|
|||
|
|
@ -153,13 +153,14 @@ async function assertDirectError(response: Response, status: number, error: stri
|
|||
}
|
||||
|
||||
describe('OAuth', () => {
|
||||
test('fake pass', () => {
|
||||
assert.ok(true, 'fake pass');
|
||||
});
|
||||
test('fake pass', () => {
|
||||
assert.ok(true, 'fake pass');
|
||||
});
|
||||
});
|
||||
|
||||
// these tests won't pass until we integrate Misskey's OAuth code with ours
|
||||
if (false) describe('OAuth', () => {
|
||||
/*
|
||||
describe('OAuth', () => {
|
||||
let fastify: FastifyInstance;
|
||||
|
||||
let alice: misskey.entities.SignupResponse;
|
||||
|
|
@ -1025,3 +1026,4 @@ if (false) describe('OAuth', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
{
|
||||
"extends": "../../shared/tsconfig.node.json",
|
||||
"extends": "../../shared/tsconfig.node.jsonc",
|
||||
"compilerOptions": {
|
||||
// Checking
|
||||
"types": ["jest", "node"],
|
||||
"outDir": "./built",
|
||||
"sourceMap": true,
|
||||
"verbatimModuleSyntax": false,
|
||||
"removeComments": false,
|
||||
"noImplicitOverride": false,
|
||||
"noImplicitAny": false,
|
||||
"strictFunctionTypes": false,
|
||||
"strictPropertyInitialization": false,
|
||||
"paths": {
|
||||
"@/*": ["../src/*"]
|
||||
},
|
||||
"typeRoots": [
|
||||
"../node_modules/@types",
|
||||
"../src/@types"
|
||||
]
|
||||
|
||||
// Output
|
||||
"outDir": "./built"
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts",
|
||||
|
|
|
|||
|
|
@ -1,19 +1,24 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../shared/tsconfig.node.json",
|
||||
"extends": "../shared/tsconfig.node.jsonc",
|
||||
"compilerOptions": {
|
||||
"removeComments": false,
|
||||
"verbatimModuleSyntax": false,
|
||||
// Input
|
||||
"rootDir": "./src",
|
||||
"outDir": "./built",
|
||||
|
||||
// Checking
|
||||
"verbatimModuleSyntax": false,
|
||||
"noImplicitOverride": false,
|
||||
"noImplicitAny": false,
|
||||
"strictFunctionTypes": false,
|
||||
"strictPropertyInitialization": false,
|
||||
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"typeRoots": [
|
||||
"./src/@types",
|
||||
"./node_modules/@types",
|
||||
"./node_modules"
|
||||
],
|
||||
|
||||
// Output
|
||||
"removeComments": false,
|
||||
"outDir": "./built"
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*.ts"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
"extends": "../shared/jsconfig.web.json",
|
||||
"extends": "../shared/tsconfig.web.jsonc",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
},
|
||||
"include": [
|
||||
"./assets/**/*.js",
|
||||
"./assets/**/*.mjs",
|
||||
|
|
@ -11,14 +14,14 @@
|
|||
"./src/server/web/**/*.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**/*",
|
||||
"**/built/**/*",
|
||||
"./jspm_packages",
|
||||
"./tmp",
|
||||
"./temp",
|
||||
"./test",
|
||||
"./test-federation",
|
||||
"./test-server",
|
||||
"**/coverage/**/*"
|
||||
"node_modules",
|
||||
"built",
|
||||
"built-test",
|
||||
"js-built",
|
||||
"temp",
|
||||
"coverage",
|
||||
"test",
|
||||
"test-federation",
|
||||
"test-server"
|
||||
]
|
||||
}
|
||||
|
|
@ -5,6 +5,6 @@
|
|||
"references": [
|
||||
{ "path": "./tsconfig.scripts.json" },
|
||||
{ "path": "./tsconfig.backend.json" },
|
||||
{ "path": "./jsconfig.frontend.json" }
|
||||
{ "path": "./tsconfig.frontend.json" }
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../shared/tsconfig.node.json",
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": false,
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
},
|
||||
"extends": "../shared/tsconfig.scripts.jsonc",
|
||||
"include": [
|
||||
"jest.*",
|
||||
"eslint.*",
|
||||
"scripts/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"built",
|
||||
"built-test",
|
||||
"js-built",
|
||||
"temp",
|
||||
"coverage",
|
||||
"ormconfig.js",
|
||||
"scripts/check_connect.js",
|
||||
"scripts/generate_api_json.js"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue