197 lines
4.5 KiB
TypeScript
197 lines
4.5 KiB
TypeScript
/**
|
|
* GraphQL Resolvers for ThreeTwo Metadata Service
|
|
* Maps GraphQL queries to Moleculer service actions
|
|
*/
|
|
|
|
export const resolvers = {
|
|
Query: {
|
|
/**
|
|
* Search ComicVine for volumes, issues, characters, etc.
|
|
*/
|
|
searchComicVine: async (_: any, { input }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
return broker.call("comicvine.search", {
|
|
query: input.query,
|
|
resources: input.resources,
|
|
format: input.format || "json",
|
|
sort: input.sort,
|
|
field_list: input.field_list,
|
|
limit: input.limit?.toString(),
|
|
offset: input.offset?.toString(),
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Advanced volume-based search with scoring and filtering
|
|
*/
|
|
volumeBasedSearch: async (_: any, { input }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
const result = await broker.call("comicvine.volumeBasedSearch", {
|
|
query: input.query,
|
|
resources: input.resources,
|
|
format: input.format || "json",
|
|
limit: input.limit,
|
|
offset: input.offset,
|
|
fieldList: input.fieldList,
|
|
scorerConfiguration: input.scorerConfiguration,
|
|
rawFileDetails: input.rawFileDetails,
|
|
});
|
|
|
|
// Transform the result to match GraphQL schema
|
|
return {
|
|
results: result.results || result,
|
|
totalResults: result.totalResults || result.length || 0,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Get volume details by URI
|
|
*/
|
|
getVolume: async (_: any, { input }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
return broker.call("comicvine.getVolumes", {
|
|
volumeURI: input.volumeURI,
|
|
fieldList: input.fieldList,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get all issues for a series by comic object ID
|
|
*/
|
|
getIssuesForSeries: async (_: any, { comicObjectId }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
return broker.call("comicvine.getIssuesForSeries", {
|
|
comicObjectId,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get generic ComicVine resource (issues, volumes, etc.)
|
|
*/
|
|
getComicVineResource: async (_: any, { input }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
return broker.call("comicvine.getResource", {
|
|
resources: input.resources,
|
|
filter: input.filter,
|
|
fieldList: input.fieldList,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get story arcs for a volume
|
|
*/
|
|
getStoryArcs: async (_: any, { volumeId }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
return broker.call("comicvine.getStoryArcs", {
|
|
volumeId,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get weekly pull list from League of Comic Geeks
|
|
*/
|
|
getWeeklyPullList: async (_: any, { input }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
const locgResponse = await broker.call("comicvine.getWeeklyPullList", {
|
|
startDate: input.startDate,
|
|
currentPage: input.currentPage.toString(),
|
|
pageSize: input.pageSize.toString(),
|
|
});
|
|
|
|
// Transform LOCG response to match GraphQL schema
|
|
return {
|
|
result: locgResponse.result.map((item: any) => ({
|
|
name: item.issueName,
|
|
publisher: item.publisher,
|
|
url: item.issueUrl,
|
|
cover: item.coverImageUrl,
|
|
description: item.description || null,
|
|
price: item.price || null,
|
|
rating: item.rating || null,
|
|
pulls: item.pulls || null,
|
|
potw: item.potw || null,
|
|
publicationDate: item.publicationDate || null,
|
|
})),
|
|
meta: locgResponse.meta,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Fetch resource from Metron API
|
|
*/
|
|
fetchMetronResource: async (_: any, { input }: any, context: any) => {
|
|
const { broker } = context;
|
|
|
|
if (!broker) {
|
|
throw new Error("Broker not available in context");
|
|
}
|
|
|
|
const result = await broker.call("metron.fetchResource", {
|
|
resource: input.resource,
|
|
method: input.method,
|
|
query: input.query,
|
|
});
|
|
|
|
return {
|
|
data: result,
|
|
status: 200,
|
|
};
|
|
},
|
|
},
|
|
|
|
Mutation: {
|
|
/**
|
|
* Placeholder for future mutations
|
|
*/
|
|
_empty: (): null => null,
|
|
},
|
|
|
|
// Custom scalar resolver for JSON
|
|
JSON: {
|
|
__parseValue(value: any): any {
|
|
return value;
|
|
},
|
|
__serialize(value: any): any {
|
|
return value;
|
|
},
|
|
__parseLiteral(ast: any): any {
|
|
return ast.value;
|
|
},
|
|
},
|
|
};
|