mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-10-01 17:11:30 -04:00
81 lines
2.9 KiB
TypeScript
81 lines
2.9 KiB
TypeScript
import SQL from 'sql-template-strings';
|
|
import { ulid } from 'ulid';
|
|
|
|
import { PermissionAreas } from '#shared/helpers.ts';
|
|
import type { NounClassInstance, NounWord, NounWords, NounWordsRaw } from '#shared/nouns.ts';
|
|
import { auditLog } from '~~/server/audit.ts';
|
|
import { getLocale, loadConfig } from '~~/server/data.ts';
|
|
import { approveNounEntry } from '~~/server/nouns.ts';
|
|
import { isAllowedToPost } from '~~/server/user.ts';
|
|
|
|
const minimizeWords = (words: NounWords): NounWordsRaw => {
|
|
return Object.fromEntries(Object.entries(words)
|
|
.map(([gender, wordsOfGender]) => {
|
|
return [gender, Object.fromEntries(Object.entries(wordsOfGender)
|
|
.map(([numerus, wordsOfNumerus]) => {
|
|
return [numerus, wordsOfNumerus.map((word): NounWord | string => {
|
|
if (!word.convention && !word.declension) {
|
|
return word.spelling;
|
|
}
|
|
return word;
|
|
})] as const;
|
|
})
|
|
.filter(([_, wordsOfNumerus]) => wordsOfNumerus.length > 0))] as const;
|
|
})
|
|
.filter(([_, wordsOfGender]) => {
|
|
return Object.keys(wordsOfGender).length > 0;
|
|
}));
|
|
};
|
|
|
|
const generateKey = (words: NounWords, classInstance: NounClassInstance | null): string => {
|
|
const defaultStem = classInstance?.stems.default;
|
|
if (defaultStem) {
|
|
return defaultStem.toLowerCase();
|
|
}
|
|
const word = Object.values(words)
|
|
.map((wordsByNumerus) => wordsByNumerus.singular?.[0])
|
|
.find((word) => word !== undefined);
|
|
return word?.spelling.toLowerCase() ?? '';
|
|
};
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const locale = getLocale(event);
|
|
checkIsConfigEnabledOr404(await loadConfig(locale), 'nouns');
|
|
|
|
const { user, isGranted } = await useAuthentication(event);
|
|
const db = useDatabase();
|
|
|
|
if (!user || !await isAllowedToPost(db, user)) {
|
|
throw createError({
|
|
status: 401,
|
|
statusMessage: 'Unauthorised',
|
|
});
|
|
}
|
|
|
|
const body = await readBody(event);
|
|
|
|
const id = ulid();
|
|
await db.get(SQL`
|
|
INSERT INTO nouns (
|
|
id, key, words, classInstance, categories, sources, approved, base_id, locale, author_id
|
|
)
|
|
VALUES (
|
|
${id},
|
|
${generateKey(body.words, body.classInstance)},
|
|
${JSON.stringify(minimizeWords(body.words))},
|
|
${body.classInstance ? JSON.stringify(body.classInstance) : null},
|
|
${body.categories.join('|')},
|
|
${body.sources ? body.sources.join(',') : null},
|
|
0, ${body.base}, ${locale}, ${user.id}
|
|
)
|
|
`);
|
|
await auditLog({ user }, 'nouns/submitted', body);
|
|
|
|
if (isGranted(PermissionAreas.Nouns)) {
|
|
await approveNounEntry(db, id, locale);
|
|
await auditLog({ user }, 'nouns/approved', { id });
|
|
}
|
|
|
|
setResponseStatus(event, 201, 'Created');
|
|
});
|