2021-08-30 21:35:22 +02:00
|
|
|
import { ApolloServer, gql, IResolvers, ApolloError, UserInputError } from "apollo-server-micro";
|
2021-03-28 23:17:47 +02:00
|
|
|
import { NextApiHandler } from "next";
|
|
|
|
|
import NextCors from "nextjs-cors";
|
2021-06-12 22:44:56 +02:00
|
|
|
import { googleScrape, textToSpeechScrape } from "@utils/translate";
|
2022-02-24 19:53:31 +01:00
|
|
|
import { retrieveFromType, getName, isValid } from "@utils/language";
|
2021-03-28 23:17:47 +02:00
|
|
|
|
|
|
|
|
export const typeDefs = gql`
|
2021-08-30 21:35:22 +02:00
|
|
|
enum LangType {
|
|
|
|
|
SOURCE,
|
|
|
|
|
TARGET
|
|
|
|
|
}
|
2021-03-28 23:17:47 +02:00
|
|
|
type Query {
|
|
|
|
|
translation(source: String="auto" target: String="en" query: String!): Translation!
|
|
|
|
|
audio(lang: String! query: String!): Entry!
|
2021-08-30 21:35:22 +02:00
|
|
|
languages(type: LangType): [Language]!
|
2021-03-28 23:17:47 +02:00
|
|
|
}
|
|
|
|
|
type Translation {
|
|
|
|
|
source: Entry!
|
|
|
|
|
target: Entry!
|
|
|
|
|
}
|
|
|
|
|
type Entry {
|
2021-08-30 21:35:22 +02:00
|
|
|
lang: Language!
|
|
|
|
|
text: String!
|
|
|
|
|
audio: [Int]!
|
|
|
|
|
}
|
|
|
|
|
type Language {
|
|
|
|
|
code: String!
|
|
|
|
|
name: String!
|
2021-03-28 23:17:47 +02:00
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
export const resolvers: IResolvers = {
|
|
|
|
|
Query: {
|
|
|
|
|
translation(_, args) {
|
|
|
|
|
const { source, target, query } = args;
|
2022-02-24 19:53:31 +01:00
|
|
|
|
|
|
|
|
if (!isValid(source) || !isValid(target))
|
|
|
|
|
throw new UserInputError("Invalid language code");
|
|
|
|
|
|
2021-03-28 23:17:47 +02:00
|
|
|
return {
|
|
|
|
|
source: {
|
2021-08-30 21:35:22 +02:00
|
|
|
lang: {
|
|
|
|
|
code: source
|
|
|
|
|
},
|
2021-03-28 23:17:47 +02:00
|
|
|
text: query
|
|
|
|
|
},
|
|
|
|
|
target: {
|
2021-08-30 21:35:22 +02:00
|
|
|
lang: {
|
|
|
|
|
code: target
|
|
|
|
|
}
|
2021-03-28 23:17:47 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
audio(_, args) {
|
2021-08-30 21:35:22 +02:00
|
|
|
const { lang, query } = args;
|
2022-02-24 19:53:31 +01:00
|
|
|
|
|
|
|
|
if (!isValid(lang))
|
|
|
|
|
throw new UserInputError("Invalid language code");
|
|
|
|
|
|
2021-03-28 23:17:47 +02:00
|
|
|
return {
|
2021-08-30 21:35:22 +02:00
|
|
|
lang: {
|
|
|
|
|
code: lang
|
|
|
|
|
},
|
|
|
|
|
text: query
|
2021-03-28 23:17:47 +02:00
|
|
|
};
|
2021-08-30 21:35:22 +02:00
|
|
|
},
|
|
|
|
|
languages(_, args) {
|
|
|
|
|
const { type } = args;
|
|
|
|
|
const langEntries = retrieveFromType(type?.toLocaleLowerCase());
|
|
|
|
|
return langEntries.map(([code, name]) => ({ code, name }));
|
2021-03-28 23:17:47 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
Translation: {
|
|
|
|
|
async target(parent) {
|
|
|
|
|
const { source, target } = parent;
|
2021-08-30 21:35:22 +02:00
|
|
|
const textScrape = await googleScrape(source.lang.code, target.lang.code, source.text);
|
|
|
|
|
|
|
|
|
|
if ("errorMsg" in textScrape)
|
|
|
|
|
throw new ApolloError(textScrape.errorMsg);
|
2021-03-28 23:17:47 +02:00
|
|
|
return {
|
|
|
|
|
lang: target.lang,
|
2021-08-30 21:35:22 +02:00
|
|
|
text: textScrape.translationRes
|
2021-03-28 23:17:47 +02:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
Entry: {
|
|
|
|
|
async audio(parent) {
|
|
|
|
|
const { lang, text } = parent;
|
2021-08-30 21:35:22 +02:00
|
|
|
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;
|
2022-02-24 19:53:31 +01:00
|
|
|
return name || getName(code);
|
2021-03-28 23:17:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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;
|