mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Merge branch 'replaceable-update' into 'main'
Throw when creating a replaceable event that doesn't exist yet See merge request soapbox-pub/ditto!458
This commit is contained in:
commit
b6f32c4d0f
3 changed files with 64 additions and 45 deletions
|
|
@ -9,7 +9,7 @@ import { booleanParamSchema, fileSchema } from '@/schema.ts';
|
||||||
import { Storages } from '@/storages.ts';
|
import { Storages } from '@/storages.ts';
|
||||||
import { uploadFile } from '@/utils/upload.ts';
|
import { uploadFile } from '@/utils/upload.ts';
|
||||||
import { nostrNow } from '@/utils.ts';
|
import { nostrNow } from '@/utils.ts';
|
||||||
import { createEvent, paginated, parseBody, updateListEvent } from '@/utils/api.ts';
|
import { createEvent, paginated, parseBody, updateEvent, updateListEvent } from '@/utils/api.ts';
|
||||||
import { extractIdentifier, lookupAccount, lookupPubkey } from '@/utils/lookup.ts';
|
import { extractIdentifier, lookupAccount, lookupPubkey } from '@/utils/lookup.ts';
|
||||||
import { renderAccounts, renderEventAccounts, renderStatuses } from '@/views.ts';
|
import { renderAccounts, renderEventAccounts, renderStatuses } from '@/views.ts';
|
||||||
import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts';
|
import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts';
|
||||||
|
|
@ -269,9 +269,10 @@ const updateCredentialsController: AppController = async (c) => {
|
||||||
return c.json(result.error, 422);
|
return c.json(result.error, 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
const author = await getAuthor(pubkey);
|
const event = await updateEvent(
|
||||||
const meta = author ? n.json().pipe(n.metadata()).catch({}).parse(author.content) : {};
|
{ kinds: [0], authors: [pubkey], limit: 1 },
|
||||||
|
async (prev) => {
|
||||||
|
const meta = n.json().pipe(n.metadata()).catch({}).parse(prev.content);
|
||||||
const {
|
const {
|
||||||
avatar: avatarFile,
|
avatar: avatarFile,
|
||||||
header: headerFile,
|
header: headerFile,
|
||||||
|
|
@ -303,11 +304,14 @@ const updateCredentialsController: AppController = async (c) => {
|
||||||
if (lud16 === '') delete meta.lud16;
|
if (lud16 === '') delete meta.lud16;
|
||||||
if (website === '') delete meta.website;
|
if (website === '') delete meta.website;
|
||||||
|
|
||||||
const event = await createEvent({
|
return {
|
||||||
kind: 0,
|
kind: 0,
|
||||||
content: JSON.stringify(meta),
|
content: JSON.stringify(meta),
|
||||||
tags: [],
|
tags: [],
|
||||||
}, c);
|
};
|
||||||
|
},
|
||||||
|
c,
|
||||||
|
);
|
||||||
|
|
||||||
const account = await renderAccount(event, { withSource: true });
|
const account = await renderAccount(event, { withSource: true });
|
||||||
const settingsStore = result.data.pleroma_settings_store;
|
const settingsStore = result.data.pleroma_settings_store;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,12 @@ import { HTTPException } from '@hono/hono/http-exception';
|
||||||
|
|
||||||
export const errorHandler: ErrorHandler = (err, c) => {
|
export const errorHandler: ErrorHandler = (err, c) => {
|
||||||
if (err instanceof HTTPException) {
|
if (err instanceof HTTPException) {
|
||||||
|
if (err.res) {
|
||||||
|
return err.res;
|
||||||
|
} else {
|
||||||
return c.json({ error: err.message }, err.status);
|
return c.json({ error: err.message }, err.status);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (err.message === 'canceling statement due to statement timeout') {
|
if (err.message === 'canceling statement due to statement timeout') {
|
||||||
return c.json({ error: 'The server was unable to respond in a timely manner' }, 500);
|
return c.json({ error: 'The server was unable to respond in a timely manner' }, 500);
|
||||||
|
|
|
||||||
|
|
@ -46,27 +46,38 @@ interface UpdateEventFilter extends NostrFilter {
|
||||||
limit: 1;
|
limit: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fetch existing event, update it, then publish the new event. */
|
/** Update a replaceable event, or throw if no event exists yet. */
|
||||||
async function updateEvent<E extends EventStub>(
|
async function updateEvent<E extends EventStub>(
|
||||||
filter: UpdateEventFilter,
|
filter: UpdateEventFilter,
|
||||||
fn: (prev: NostrEvent | undefined) => E,
|
fn: (prev: NostrEvent) => E | Promise<E>,
|
||||||
c: AppContext,
|
c: AppContext,
|
||||||
): Promise<NostrEvent> {
|
): Promise<NostrEvent> {
|
||||||
const store = await Storages.db();
|
const store = await Storages.db();
|
||||||
const [prev] = await store.query([filter], { signal: c.req.raw.signal });
|
|
||||||
return createEvent(fn(prev), c);
|
const [prev] = await store.query(
|
||||||
|
[filter],
|
||||||
|
{ signal: c.req.raw.signal },
|
||||||
|
);
|
||||||
|
|
||||||
|
if (prev) {
|
||||||
|
return createEvent(await fn(prev), c);
|
||||||
|
} else {
|
||||||
|
throw new HTTPException(422, {
|
||||||
|
message: 'No event to update',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fetch existing event, update its tags, then publish the new event. */
|
/** Update a replaceable list event, or throw if no event exists yet. */
|
||||||
function updateListEvent(
|
function updateListEvent(
|
||||||
filter: UpdateEventFilter,
|
filter: UpdateEventFilter,
|
||||||
fn: (tags: string[][]) => string[][],
|
fn: (tags: string[][]) => string[][],
|
||||||
c: AppContext,
|
c: AppContext,
|
||||||
): Promise<NostrEvent> {
|
): Promise<NostrEvent> {
|
||||||
return updateEvent(filter, (prev) => ({
|
return updateEvent(filter, ({ content, tags }) => ({
|
||||||
kind: filter.kinds[0],
|
kind: filter.kinds[0],
|
||||||
content: prev?.content ?? '',
|
content,
|
||||||
tags: fn(prev?.tags ?? []),
|
tags: fn(tags),
|
||||||
}), c);
|
}), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue