Files
2026-03-04 23:36:10 -05:00

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;
},
},
};