ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m17s
ci / ts / ts (packages + web) (push) Successful in 3m13s
ci / api / api (push) Successful in 59s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m31s
ci / db / db (push) Successful in 2m50s
30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
import type { components } from '@pipu/api-client';
|
|
|
|
export type UserArchive = components['schemas']['UserArchive'];
|
|
export const MAX_ARCHIVE_BYTES = 16 * 1024 * 1024;
|
|
|
|
/** Only previews metadata; the server validates every account before writing. */
|
|
export function parseUserArchive(text: string): UserArchive {
|
|
const data: unknown = JSON.parse(text.replace(/^\uFEFF/, ''));
|
|
if (!data || typeof data !== 'object' || !('version' in data) || data.version !== 1 ||
|
|
!('users' in data) || !Array.isArray(data.users) || data.users.length > 10000) throw new Error('archive');
|
|
for (const entry of data.users) {
|
|
if (!entry || typeof entry !== 'object' || typeof entry.username !== 'string' ||
|
|
!['admin', 'moderator', 'user'].includes(entry.role) || typeof entry.password_hash !== 'string') {
|
|
throw new Error('archive');
|
|
}
|
|
}
|
|
return data as UserArchive;
|
|
}
|
|
|
|
export function downloadUserArchive(archive: UserArchive) {
|
|
const url = URL.createObjectURL(new Blob([JSON.stringify(archive, null, 2)], { type: 'application/json' }));
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = 'pipu-users.json';
|
|
document.body.append(link);
|
|
link.click();
|
|
link.remove();
|
|
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
}
|