Files
LingvAI/pages/api/graphql.ts

123 lines
3.3 KiB
TypeScript

import { ApolloServer, gql, IResolvers, ApolloError, UserInputError } from "apollo-server-micro";
import { NextApiHandler } from "next";
import NextCors from "nextjs-cors";
import { googleScrape, textToSpeechScrape } from "@utils/translate";
import { retrieveFromType, getName, isValid } from "@utils/language";
export const typeDefs = gql`
enum LangType {
SOURCE,
TARGET
}
type Query {
translation(source: String="auto" target: String="en" query: String!): Translation!
audio(lang: String! query: String!): Entry!
languages(type: LangType): [Language]!
}
type Translation {
source: Entry!
target: Entry!
}
type Entry {
lang: Language!
text: String!
audio: [Int]!
}
type Language {
code: String!
name: String!
}
`;
export const resolvers: IResolvers = {
Query: {
translation(_, args) {
const { source, target, query } = args;
if (!isValid(source) || !isValid(target))
throw new UserInputError("Invalid language code");
return {
source: {
lang: {
code: source
},
text: query
},
target: {
lang: {
code: target
}
}
};
},
audio(_, args) {
const { lang, query } = args;
if (!isValid(lang))
throw new UserInputError("Invalid language code");
return {
lang: {
code: lang
},
text: query
};
},
languages(_, args) {
const { type } = args;
const langEntries = retrieveFromType(type?.toLocaleLowerCase());
return langEntries.map(([code, name]) => ({ code, name }));
}
},
Translation: {
async target(parent) {
const { source, target } = parent;
const textScrape = await googleScrape(source.lang.code, target.lang.code, source.text);
if ("errorMsg" in textScrape)
throw new ApolloError(textScrape.errorMsg);
return {
lang: target.lang,
text: textScrape.translationRes
};
}
},
Entry: {
async audio(parent) {
const { lang, text } = parent;
const audio = await textToSpeechScrape(lang.code, text);
if (!audio)
throw new ApolloError("An error occurred while retrieving the audio");
return audio;
}
},
Language: {
name(parent) {
const { code, name } = parent;
return name || getName(code);
}
}
};
export const config = {
api: {
bodyParser: false
}
};
const apolloHandler = new ApolloServer({ typeDefs, resolvers }).createHandler({ path: "/api/graphql" });
const handler: NextApiHandler = async (req, res) => {
await NextCors(req, res, {
methods: ["GET", "POST"],
origin: "*"
});
return req.method !== "OPTIONS"
? apolloHandler(req, res)
: res.end();
};
export default handler;