custom css works now

This commit is contained in:
Moon.eth
2026-07-29 16:03:12 +09:00
parent f51c576952
commit 81176654ba
11 changed files with 777 additions and 35 deletions
+40
View File
@@ -0,0 +1,40 @@
import { afterEach, describe, expect, it, vi } from 'vitest'
import { ApiClient } from './client'
import { updateProfileFields } from './endpoints'
afterEach(() => {
vi.unstubAllGlobals()
})
describe('updateProfileFields', () => {
it('uses the Pleroma/Mastodon indexed multipart representation', async () => {
const fetchMock = vi.fn(async (_url: string, init?: RequestInit) => {
expect(init?.method).toBe('PATCH')
expect(init?.headers).toBeInstanceOf(Headers)
expect((init?.headers as Headers).get('Authorization')).toBe('Bearer token')
expect(init?.body).toBeInstanceOf(FormData)
const form = init?.body as FormData
expect([...form.entries()]).toEqual([
['fields_attributes[0][name]', 'Website'],
['fields_attributes[0][value]', 'https://example.test'],
['fields_attributes[1][name]', 'plspace:css1'],
['fields_attributes[1][value]', 'body { color: pink; }'],
])
return new Response(JSON.stringify({ id: 'account-1', fields: [] }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
})
})
vi.stubGlobal('fetch', fetchMock)
await updateProfileFields(new ApiClient('example.test', 'token'), [
{ name: 'Website', value: 'https://example.test' },
{ name: 'plspace:css1', value: 'body { color: pink; }' },
])
expect(fetchMock).toHaveBeenCalledWith(
'https://example.test/api/v1/accounts/update_credentials',
expect.any(Object),
)
})
})
+21
View File
@@ -85,6 +85,27 @@ export function verifyCredentials(api: ApiClient): Promise<CredentialAccount> {
return api.get<CredentialAccount>('/api/v1/accounts/verify_credentials')
}
/**
* Replace the signed-in account's profile fields while leaving every other
* credential untouched. Mastodon and Pleroma both accept this indexed
* multipart shape; Pleroma-FE uses the same representation.
*/
export async function updateProfileFields(
api: ApiClient,
fields: Array<{ name: string; value: string }>,
): Promise<CredentialAccount> {
const form = new FormData()
fields.forEach((field, index) => {
form.append(`fields_attributes[${index}][name]`, field.name)
form.append(`fields_attributes[${index}][value]`, field.value)
})
const { data } = await api.raw<CredentialAccount>('/api/v1/accounts/update_credentials', {
method: 'PATCH',
form,
})
return data
}
export function fetchAccount(api: ApiClient, id: string): Promise<Account> {
return api.get<Account>(`/api/v1/accounts/${encodeURIComponent(id)}`)
}
+21 -2
View File
@@ -266,11 +266,30 @@ export interface InstanceInfo {
max_characters?: number
max_media_attachments?: number
}
accounts?: {
max_profile_fields?: number
/** Pleroma v2 names. */
profile_field_name_limit?: number
profile_field_value_limit?: number
/** Mastodon-compatible aliases used by some implementations. */
max_profile_field_name_length?: number
max_profile_field_value_length?: number
}
}
registrations?: boolean | { enabled?: boolean }
contact_account?: Account | null
/** Pleroma reports its "real" upstream here. */
pleroma?: unknown
/** Pleroma reports its "real" upstream and field limits here. */
pleroma?: {
metadata?: {
fields_limits?: {
max_fields?: number
name_length?: number
value_length?: number
}
[key: string]: unknown
}
[key: string]: unknown
}
}
export interface SearchResults {