server can read outfit data
This commit is contained in:
parent
ad947985ea
commit
ade563ddcd
9 changed files with 531 additions and 90 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
-- Public data tables
|
||||||
GRANT SELECT ON openneo_impress.colors TO impress2020;
|
GRANT SELECT ON openneo_impress.colors TO impress2020;
|
||||||
GRANT SELECT ON openneo_impress.color_translations TO impress2020;
|
GRANT SELECT ON openneo_impress.color_translations TO impress2020;
|
||||||
GRANT SELECT ON openneo_impress.items TO impress2020;
|
GRANT SELECT ON openneo_impress.items TO impress2020;
|
||||||
|
@ -10,3 +11,7 @@ GRANT SELECT ON openneo_impress.species_translations TO impress2020;
|
||||||
GRANT SELECT ON openneo_impress.swf_assets TO impress2020;
|
GRANT SELECT ON openneo_impress.swf_assets TO impress2020;
|
||||||
GRANT SELECT ON openneo_impress.zones TO impress2020;
|
GRANT SELECT ON openneo_impress.zones TO impress2020;
|
||||||
GRANT SELECT ON openneo_impress.zone_translations TO impress2020;
|
GRANT SELECT ON openneo_impress.zone_translations TO impress2020;
|
||||||
|
|
||||||
|
-- User data tables
|
||||||
|
GRANT SELECT ON openneo_impress.item_outfit_relationships TO impress2020;
|
||||||
|
GRANT SELECT ON openneo_impress.outfits TO impress2020;
|
||||||
|
|
|
@ -2341,7 +2341,7 @@ exports[`getValidPetPoses gets them and writes them to a buffer 1`] = `
|
||||||
10000000
|
10000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
10000000
|
||||||
10011011
|
10011011
|
||||||
00000000
|
00000000
|
||||||
10000000
|
10000000
|
||||||
|
@ -2555,7 +2555,7 @@ exports[`getValidPetPoses gets them and writes them to a buffer 1`] = `
|
||||||
00000000
|
00000000
|
||||||
10111111
|
10111111
|
||||||
00000000
|
00000000
|
||||||
00000000
|
10000000
|
||||||
10000000
|
10000000
|
||||||
00111111
|
00111111
|
||||||
00000000
|
00000000
|
||||||
|
@ -2797,7 +2797,7 @@ exports[`getValidPetPoses gets them and writes them to a buffer 1`] = `
|
||||||
10000000
|
10000000
|
||||||
10000000
|
10000000
|
||||||
10000000
|
10000000
|
||||||
00000000
|
10000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
10000000
|
10000000
|
||||||
|
@ -3936,7 +3936,7 @@ exports[`getValidPetPoses gets them and writes them to a buffer 1`] = `
|
||||||
10011011
|
10011011
|
||||||
00000000
|
00000000
|
||||||
10011011
|
10011011
|
||||||
00000000
|
10000000
|
||||||
00000000
|
00000000
|
||||||
00111111
|
00111111
|
||||||
00000000
|
00000000
|
||||||
|
@ -4575,7 +4575,7 @@ exports[`getValidPetPoses gets them and writes them to a buffer 1`] = `
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00111111
|
00111111
|
||||||
00000000
|
10000000
|
||||||
00111111
|
00111111
|
||||||
10000000
|
10000000
|
||||||
10011011
|
10011011
|
||||||
|
@ -5937,7 +5937,7 @@ exports[`getValidPetPoses gets them and writes them to a buffer 1`] = `
|
||||||
10000000
|
10000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
10000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
|
|
|
@ -70,13 +70,13 @@ const typeDefs = gql`
|
||||||
|
|
||||||
type PetAppearance {
|
type PetAppearance {
|
||||||
id: ID!
|
id: ID!
|
||||||
petStateId: ID!
|
species: Species!
|
||||||
bodyId: ID!
|
color: Color!
|
||||||
pose: Pose!
|
pose: Pose!
|
||||||
genderPresentation: GenderPresentation # deprecated
|
bodyId: ID!
|
||||||
emotion: Emotion # deprecated
|
|
||||||
approximateThumbnailUrl: String! # deprecated
|
|
||||||
layers: [AppearanceLayer!]!
|
layers: [AppearanceLayer!]!
|
||||||
|
petStateId: ID! # Convenience field for developers
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemAppearance {
|
type ItemAppearance {
|
||||||
|
@ -125,10 +125,16 @@ const typeDefs = gql`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Outfit {
|
type Outfit {
|
||||||
species: Species!
|
id: ID!
|
||||||
color: Color!
|
name: String!
|
||||||
pose: Pose!
|
petAppearance: PetAppearance!
|
||||||
items: [Item!]!
|
wornItems: [Item!]!
|
||||||
|
closetedItems: [Item!]!
|
||||||
|
|
||||||
|
species: Species! # to be deprecated? can use petAppearance? 🤔
|
||||||
|
color: Color! # to be deprecated? can use petAppearance? 🤔
|
||||||
|
pose: Pose! # to be deprecated? can use petAppearance? 🤔
|
||||||
|
items: [Item!]! # deprecated alias for wornItems
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
|
@ -147,6 +153,8 @@ const typeDefs = gql`
|
||||||
petAppearance(speciesId: ID!, colorId: ID!, pose: Pose!): PetAppearance
|
petAppearance(speciesId: ID!, colorId: ID!, pose: Pose!): PetAppearance
|
||||||
petAppearances(speciesId: ID!, colorId: ID!): [PetAppearance!]!
|
petAppearances(speciesId: ID!, colorId: ID!): [PetAppearance!]!
|
||||||
|
|
||||||
|
outfit(id: ID!): Outfit
|
||||||
|
|
||||||
petOnNeopetsDotCom(petName: String!): Outfit
|
petOnNeopetsDotCom(petName: String!): Outfit
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -168,9 +176,9 @@ const resolvers = {
|
||||||
appearanceOn: async (
|
appearanceOn: async (
|
||||||
item,
|
item,
|
||||||
{ speciesId, colorId },
|
{ speciesId, colorId },
|
||||||
{ petTypeLoader, itemSwfAssetLoader }
|
{ petTypeBySpeciesAndColorLoader, itemSwfAssetLoader }
|
||||||
) => {
|
) => {
|
||||||
const petType = await petTypeLoader.load({
|
const petType = await petTypeBySpeciesAndColorLoader.load({
|
||||||
speciesId: speciesId,
|
speciesId: speciesId,
|
||||||
colorId: colorId,
|
colorId: colorId,
|
||||||
});
|
});
|
||||||
|
@ -199,22 +207,33 @@ const resolvers = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PetAppearance: {
|
PetAppearance: {
|
||||||
id: ({ petType, petState }) => {
|
id: async ({ petStateId }, _, { petStateLoader, petTypeLoader }) => {
|
||||||
const { speciesId, colorId } = petType;
|
const petState = await petStateLoader.load(petStateId);
|
||||||
|
const petType = await petTypeLoader.load(petState.petTypeId);
|
||||||
const pose = getPoseFromPetState(petState);
|
const pose = getPoseFromPetState(petState);
|
||||||
return `${speciesId}-${colorId}-${pose}`;
|
return `${petType.speciesId}-${petType.colorId}-${pose}`;
|
||||||
},
|
},
|
||||||
petStateId: ({ petState }) => petState.id,
|
color: async ({ petStateId }, _, { petStateLoader, petTypeLoader }) => {
|
||||||
bodyId: ({ petType }) => petType.bodyId,
|
const petState = await petStateLoader.load(petStateId);
|
||||||
pose: ({ petState }) => getPoseFromPetState(petState),
|
const petType = await petTypeLoader.load(petState.petTypeId);
|
||||||
genderPresentation: ({ petState }) =>
|
return { id: petType.colorId };
|
||||||
getGenderPresentation(getPoseFromPetState(petState)),
|
|
||||||
emotion: ({ petState }) => getEmotion(getPoseFromPetState(petState)),
|
|
||||||
approximateThumbnailUrl: ({ petType, petState }) => {
|
|
||||||
return `http://pets.neopets.com/cp/${petType.basicImageHash}/${petState.moodId}/1.png`;
|
|
||||||
},
|
},
|
||||||
layers: async ({ petState }, _, { petSwfAssetLoader }) => {
|
species: async ({ petStateId }, _, { petStateLoader, petTypeLoader }) => {
|
||||||
const swfAssets = await petSwfAssetLoader.load(petState.id);
|
const petState = await petStateLoader.load(petStateId);
|
||||||
|
const petType = await petTypeLoader.load(petState.petTypeId);
|
||||||
|
return { id: petType.speciesId };
|
||||||
|
},
|
||||||
|
bodyId: async ({ petStateId }, _, { petStateLoader, petTypeLoader }) => {
|
||||||
|
const petState = await petStateLoader.load(petStateId);
|
||||||
|
const petType = await petTypeLoader.load(petState.petTypeId);
|
||||||
|
return petType.bodyId;
|
||||||
|
},
|
||||||
|
pose: async ({ petStateId }, _, { petStateLoader }) => {
|
||||||
|
const petState = await petStateLoader.load(petStateId);
|
||||||
|
return getPoseFromPetState(petState);
|
||||||
|
},
|
||||||
|
layers: async ({ petStateId }, _, { petSwfAssetLoader }) => {
|
||||||
|
const swfAssets = await petSwfAssetLoader.load(petStateId);
|
||||||
return swfAssets;
|
return swfAssets;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -285,19 +304,39 @@ const resolvers = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Color: {
|
Color: {
|
||||||
name: async (color, _, { colorTranslationLoader }) => {
|
name: async ({ id }, _, { colorTranslationLoader }) => {
|
||||||
const colorTranslation = await colorTranslationLoader.load(color.id);
|
const colorTranslation = await colorTranslationLoader.load(id);
|
||||||
return capitalize(colorTranslation.name);
|
return capitalize(colorTranslation.name);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Species: {
|
Species: {
|
||||||
name: async (species, _, { speciesTranslationLoader }) => {
|
name: async ({ id }, _, { speciesTranslationLoader }) => {
|
||||||
const speciesTranslation = await speciesTranslationLoader.load(
|
const speciesTranslation = await speciesTranslationLoader.load(id);
|
||||||
species.id
|
|
||||||
);
|
|
||||||
return capitalize(speciesTranslation.name);
|
return capitalize(speciesTranslation.name);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Outfit: {
|
||||||
|
name: async ({ id }, _, { outfitLoader }) => {
|
||||||
|
const outfit = await outfitLoader.load(id);
|
||||||
|
return outfit.name;
|
||||||
|
},
|
||||||
|
petAppearance: async ({ id }, _, { outfitLoader }) => {
|
||||||
|
const outfit = await outfitLoader.load(id);
|
||||||
|
return { petStateId: outfit.petStateId };
|
||||||
|
},
|
||||||
|
wornItems: async ({ id }, _, { itemOutfitRelationshipsLoader }) => {
|
||||||
|
const relationships = await itemOutfitRelationshipsLoader.load(id);
|
||||||
|
return relationships
|
||||||
|
.filter((oir) => oir.isWorn)
|
||||||
|
.map((oir) => ({ id: oir.itemId }));
|
||||||
|
},
|
||||||
|
closetedItems: async ({ id }, _, { itemOutfitRelationshipsLoader }) => {
|
||||||
|
const relationships = await itemOutfitRelationshipsLoader.load(id);
|
||||||
|
return relationships
|
||||||
|
.filter((oir) => !oir.isWorn)
|
||||||
|
.map((oir) => ({ id: oir.itemId }));
|
||||||
|
},
|
||||||
|
},
|
||||||
Query: {
|
Query: {
|
||||||
allColors: async (_, { ids }, { loadAllColors }) => {
|
allColors: async (_, { ids }, { loadAllColors }) => {
|
||||||
const allColors = await loadAllColors();
|
const allColors = await loadAllColors();
|
||||||
|
@ -326,9 +365,12 @@ const resolvers = {
|
||||||
itemSearchToFit: async (
|
itemSearchToFit: async (
|
||||||
_,
|
_,
|
||||||
{ query, speciesId, colorId, offset, limit },
|
{ query, speciesId, colorId, offset, limit },
|
||||||
{ petTypeLoader, itemSearchToFitLoader }
|
{ petTypeBySpeciesAndColorLoader, itemSearchToFitLoader }
|
||||||
) => {
|
) => {
|
||||||
const petType = await petTypeLoader.load({ speciesId, colorId });
|
const petType = await petTypeBySpeciesAndColorLoader.load({
|
||||||
|
speciesId,
|
||||||
|
colorId,
|
||||||
|
});
|
||||||
const { bodyId } = petType;
|
const { bodyId } = petType;
|
||||||
const items = await itemSearchToFitLoader.load({
|
const items = await itemSearchToFitLoader.load({
|
||||||
query: query.trim(),
|
query: query.trim(),
|
||||||
|
@ -341,40 +383,44 @@ const resolvers = {
|
||||||
petAppearance: async (
|
petAppearance: async (
|
||||||
_,
|
_,
|
||||||
{ speciesId, colorId, pose },
|
{ speciesId, colorId, pose },
|
||||||
{ petTypeLoader, petStateLoader }
|
{ petTypeBySpeciesAndColorLoader, petStatesForPetTypeLoader }
|
||||||
) => {
|
) => {
|
||||||
const petType = await petTypeLoader.load({
|
const petType = await petTypeBySpeciesAndColorLoader.load({
|
||||||
speciesId,
|
speciesId,
|
||||||
colorId,
|
colorId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const petStates = await petStateLoader.load(petType.id);
|
const petStates = await petStatesForPetTypeLoader.load(petType.id);
|
||||||
// TODO: This could be optimized into the query condition 🤔
|
// TODO: This could be optimized into the query condition 🤔
|
||||||
const petState = petStates.find((ps) => getPoseFromPetState(ps) === pose);
|
const petState = petStates.find((ps) => getPoseFromPetState(ps) === pose);
|
||||||
if (!petState) {
|
if (!petState) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { petType, petState };
|
return { petStateId: petState.id };
|
||||||
},
|
},
|
||||||
petAppearances: async (
|
petAppearances: async (
|
||||||
_,
|
_,
|
||||||
{ speciesId, colorId },
|
{ speciesId, colorId },
|
||||||
{ petTypeLoader, petStateLoader }
|
{ petTypeBySpeciesAndColorLoader, petStatesForPetTypeLoader }
|
||||||
) => {
|
) => {
|
||||||
const petType = await petTypeLoader.load({
|
const petType = await petTypeBySpeciesAndColorLoader.load({
|
||||||
speciesId,
|
speciesId,
|
||||||
colorId,
|
colorId,
|
||||||
});
|
});
|
||||||
const petStates = await petStateLoader.load(petType.id);
|
const petStates = await petStatesForPetTypeLoader.load(petType.id);
|
||||||
return petStates.map((petState) => ({ petType, petState }));
|
return petStates.map((petState) => ({ petStateId: petState.id }));
|
||||||
},
|
},
|
||||||
|
outfit: (_, { id }) => ({ id }),
|
||||||
petOnNeopetsDotCom: async (_, { petName }) => {
|
petOnNeopetsDotCom: async (_, { petName }) => {
|
||||||
const [petMetaData, customPetData] = await Promise.all([
|
const [petMetaData, customPetData] = await Promise.all([
|
||||||
neopets.loadPetMetaData(petName),
|
neopets.loadPetMetaData(petName),
|
||||||
neopets.loadCustomPetData(petName),
|
neopets.loadCustomPetData(petName),
|
||||||
]);
|
]);
|
||||||
const outfit = {
|
const outfit = {
|
||||||
|
// TODO: This isn't a fully-working Outfit object. It works for the
|
||||||
|
// client as currently implemented, but we'll probably want to
|
||||||
|
// move the client and this onto our more generic fields!
|
||||||
species: { id: customPetData.custom_pet.species_id },
|
species: { id: customPetData.custom_pet.species_id },
|
||||||
color: { id: customPetData.custom_pet.color_id },
|
color: { id: customPetData.custom_pet.color_id },
|
||||||
pose: getPoseFromPetData(petMetaData, customPetData),
|
pose: getPoseFromPetData(petMetaData, customPetData),
|
||||||
|
|
|
@ -154,6 +154,21 @@ const buildItemSearchToFitLoader = (db) =>
|
||||||
});
|
});
|
||||||
|
|
||||||
const buildPetTypeLoader = (db) =>
|
const buildPetTypeLoader = (db) =>
|
||||||
|
new DataLoader(async (petTypeIds) => {
|
||||||
|
const qs = petTypeIds.map((_) => "?").join(",");
|
||||||
|
const [rows, _] = await db.execute(
|
||||||
|
`SELECT * FROM pet_types WHERE id IN (${qs})`,
|
||||||
|
petTypeIds
|
||||||
|
);
|
||||||
|
|
||||||
|
const entities = rows.map(normalizeRow);
|
||||||
|
|
||||||
|
return petTypeIds.map((petTypeId) =>
|
||||||
|
entities.find((e) => e.id === petTypeId)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const buildPetTypeBySpeciesAndColorLoader = (db, loaders) =>
|
||||||
new DataLoader(async (speciesAndColorPairs) => {
|
new DataLoader(async (speciesAndColorPairs) => {
|
||||||
const conditions = [];
|
const conditions = [];
|
||||||
const values = [];
|
const values = [];
|
||||||
|
@ -172,6 +187,10 @@ const buildPetTypeLoader = (db) =>
|
||||||
entities.map((e) => [`${e.speciesId},${e.colorId}`, e])
|
entities.map((e) => [`${e.speciesId},${e.colorId}`, e])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (const petType of entities) {
|
||||||
|
loaders.petTypeLoader.prime(petType.id, petType);
|
||||||
|
}
|
||||||
|
|
||||||
return speciesAndColorPairs.map(({ speciesId, colorId }) =>
|
return speciesAndColorPairs.map(({ speciesId, colorId }) =>
|
||||||
entitiesBySpeciesAndColorPair.get(`${speciesId},${colorId}`)
|
entitiesBySpeciesAndColorPair.get(`${speciesId},${colorId}`)
|
||||||
);
|
);
|
||||||
|
@ -226,7 +245,50 @@ const buildPetSwfAssetLoader = (db) =>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const buildOutfitLoader = (db) =>
|
||||||
|
new DataLoader(async (outfitIds) => {
|
||||||
|
const qs = outfitIds.map((_) => "?").join(",");
|
||||||
|
const [rows, _] = await db.execute(
|
||||||
|
`SELECT * FROM outfits WHERE id IN (${qs})`,
|
||||||
|
outfitIds
|
||||||
|
);
|
||||||
|
|
||||||
|
const entities = rows.map(normalizeRow);
|
||||||
|
|
||||||
|
return outfitIds.map((outfitId) => entities.find((e) => e.id === outfitId));
|
||||||
|
});
|
||||||
|
|
||||||
|
const buildItemOutfitRelationshipsLoader = (db) =>
|
||||||
|
new DataLoader(async (outfitIds) => {
|
||||||
|
const qs = outfitIds.map((_) => "?").join(",");
|
||||||
|
const [rows, _] = await db.execute(
|
||||||
|
`SELECT * FROM item_outfit_relationships WHERE outfit_id IN (${qs})`,
|
||||||
|
outfitIds
|
||||||
|
);
|
||||||
|
|
||||||
|
const entities = rows.map(normalizeRow);
|
||||||
|
|
||||||
|
return outfitIds.map((outfitId) =>
|
||||||
|
entities.filter((e) => e.outfitId === outfitId)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const buildPetStateLoader = (db) =>
|
const buildPetStateLoader = (db) =>
|
||||||
|
new DataLoader(async (petStateIds) => {
|
||||||
|
const qs = petStateIds.map((_) => "?").join(",");
|
||||||
|
const [rows, _] = await db.execute(
|
||||||
|
`SELECT * FROM pet_states WHERE id IN (${qs})`,
|
||||||
|
petStateIds
|
||||||
|
);
|
||||||
|
|
||||||
|
const entities = rows.map(normalizeRow);
|
||||||
|
|
||||||
|
return petStateIds.map((petStateId) =>
|
||||||
|
entities.find((e) => e.id === petStateId)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const buildPetStatesForPetTypeLoader = (db, loaders) =>
|
||||||
new DataLoader(async (petTypeIds) => {
|
new DataLoader(async (petTypeIds) => {
|
||||||
const qs = petTypeIds.map((_) => "?").join(",");
|
const qs = petTypeIds.map((_) => "?").join(",");
|
||||||
const [rows, _] = await db.execute(
|
const [rows, _] = await db.execute(
|
||||||
|
@ -238,6 +300,10 @@ const buildPetStateLoader = (db) =>
|
||||||
|
|
||||||
const entities = rows.map(normalizeRow);
|
const entities = rows.map(normalizeRow);
|
||||||
|
|
||||||
|
for (const petState of entities) {
|
||||||
|
loaders.petStateLoader.prime(petState.id, petState);
|
||||||
|
}
|
||||||
|
|
||||||
return petTypeIds.map((petTypeId) =>
|
return petTypeIds.map((petTypeId) =>
|
||||||
entities.filter((e) => e.petTypeId === petTypeId)
|
entities.filter((e) => e.petTypeId === petTypeId)
|
||||||
);
|
);
|
||||||
|
@ -280,24 +346,37 @@ const buildZoneTranslationLoader = (db) =>
|
||||||
});
|
});
|
||||||
|
|
||||||
function buildLoaders(db) {
|
function buildLoaders(db) {
|
||||||
return {
|
const loaders = {};
|
||||||
loadAllColors: loadAllColors(db),
|
loaders.loadAllColors = loadAllColors(db);
|
||||||
loadAllSpecies: loadAllSpecies(db),
|
loaders.loadAllSpecies = loadAllSpecies(db);
|
||||||
loadAllPetTypes: loadAllPetTypes(db),
|
loaders.loadAllPetTypes = loadAllPetTypes(db);
|
||||||
|
|
||||||
colorTranslationLoader: buildColorTranslationLoader(db),
|
loaders.colorTranslationLoader = buildColorTranslationLoader(db);
|
||||||
itemLoader: buildItemsLoader(db),
|
loaders.itemLoader = buildItemsLoader(db);
|
||||||
itemTranslationLoader: buildItemTranslationLoader(db),
|
loaders.itemTranslationLoader = buildItemTranslationLoader(db);
|
||||||
itemSearchLoader: buildItemSearchLoader(db),
|
loaders.itemSearchLoader = buildItemSearchLoader(db);
|
||||||
itemSearchToFitLoader: buildItemSearchToFitLoader(db),
|
loaders.itemSearchToFitLoader = buildItemSearchToFitLoader(db);
|
||||||
petTypeLoader: buildPetTypeLoader(db),
|
loaders.petTypeLoader = buildPetTypeLoader(db);
|
||||||
itemSwfAssetLoader: buildItemSwfAssetLoader(db),
|
loaders.petTypeBySpeciesAndColorLoader = buildPetTypeBySpeciesAndColorLoader(
|
||||||
petSwfAssetLoader: buildPetSwfAssetLoader(db),
|
db,
|
||||||
petStateLoader: buildPetStateLoader(db),
|
loaders
|
||||||
speciesTranslationLoader: buildSpeciesTranslationLoader(db),
|
);
|
||||||
zoneLoader: buildZoneLoader(db),
|
loaders.itemSwfAssetLoader = buildItemSwfAssetLoader(db);
|
||||||
zoneTranslationLoader: buildZoneTranslationLoader(db),
|
loaders.petSwfAssetLoader = buildPetSwfAssetLoader(db);
|
||||||
};
|
loaders.outfitLoader = buildOutfitLoader(db);
|
||||||
|
loaders.itemOutfitRelationshipsLoader = buildItemOutfitRelationshipsLoader(
|
||||||
|
db
|
||||||
|
);
|
||||||
|
loaders.petStateLoader = buildPetStateLoader(db);
|
||||||
|
loaders.petStatesForPetTypeLoader = buildPetStatesForPetTypeLoader(
|
||||||
|
db,
|
||||||
|
loaders
|
||||||
|
);
|
||||||
|
loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db);
|
||||||
|
loaders.zoneLoader = buildZoneLoader(db);
|
||||||
|
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);
|
||||||
|
|
||||||
|
return loaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = buildLoaders;
|
module.exports = buildLoaders;
|
||||||
|
|
104
src/server/query-tests/Outfit.test.js
Normal file
104
src/server/query-tests/Outfit.test.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
const gql = require("graphql-tag");
|
||||||
|
const { query, getDbCalls } = require("./setup.js");
|
||||||
|
|
||||||
|
describe("Outfit", () => {
|
||||||
|
it("loads an outfit by ID", async () => {
|
||||||
|
const res = await query({
|
||||||
|
query: gql`
|
||||||
|
query {
|
||||||
|
outfit(id: "31856") {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
|
||||||
|
petAppearance {
|
||||||
|
id
|
||||||
|
|
||||||
|
color {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
species {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
pose
|
||||||
|
}
|
||||||
|
|
||||||
|
wornItems {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
closetedItems {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res).toHaveNoErrors();
|
||||||
|
expect(res.data).toMatchSnapshot();
|
||||||
|
expect(getDbCalls()).toMatchInlineSnapshot(`
|
||||||
|
Array [
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM outfits WHERE id IN (?)",
|
||||||
|
Array [
|
||||||
|
"31856",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM item_outfit_relationships WHERE outfit_id IN (?)",
|
||||||
|
Array [
|
||||||
|
"31856",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM item_translations WHERE item_id IN (?,?,?,?,?,?,?,?,?,?,?) AND locale = \\"en\\"",
|
||||||
|
Array [
|
||||||
|
"38916",
|
||||||
|
"51054",
|
||||||
|
"38914",
|
||||||
|
"36125",
|
||||||
|
"36467",
|
||||||
|
"47075",
|
||||||
|
"47056",
|
||||||
|
"39662",
|
||||||
|
"56706",
|
||||||
|
"38915",
|
||||||
|
"56398",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM pet_states WHERE id IN (?)",
|
||||||
|
Array [
|
||||||
|
"3951",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM pet_types WHERE id IN (?)",
|
||||||
|
Array [
|
||||||
|
"33",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM color_translations
|
||||||
|
WHERE color_id IN (?) AND locale = \\"en\\"",
|
||||||
|
Array [
|
||||||
|
"34",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM species_translations
|
||||||
|
WHERE species_id IN (?) AND locale = \\"en\\"",
|
||||||
|
Array [
|
||||||
|
"54",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
|
@ -7,6 +7,18 @@ describe("PetAppearance", () => {
|
||||||
query: gql`
|
query: gql`
|
||||||
query {
|
query {
|
||||||
petAppearance(speciesId: "54", colorId: "75", pose: HAPPY_FEM) {
|
petAppearance(speciesId: "54", colorId: "75", pose: HAPPY_FEM) {
|
||||||
|
id
|
||||||
|
|
||||||
|
species {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
color {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
layers {
|
layers {
|
||||||
id
|
id
|
||||||
imageUrl(size: SIZE_600)
|
imageUrl(size: SIZE_600)
|
||||||
|
@ -49,6 +61,20 @@ describe("PetAppearance", () => {
|
||||||
"17723",
|
"17723",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM species_translations
|
||||||
|
WHERE species_id IN (?) AND locale = \\"en\\"",
|
||||||
|
Array [
|
||||||
|
"54",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM color_translations
|
||||||
|
WHERE color_id IN (?) AND locale = \\"en\\"",
|
||||||
|
Array [
|
||||||
|
"75",
|
||||||
|
],
|
||||||
|
],
|
||||||
Array [
|
Array [
|
||||||
"SELECT * FROM zones WHERE id IN (?,?,?,?,?,?)",
|
"SELECT * FROM zones WHERE id IN (?,?,?,?,?,?)",
|
||||||
Array [
|
Array [
|
||||||
|
@ -70,12 +96,20 @@ describe("PetAppearance", () => {
|
||||||
query {
|
query {
|
||||||
petAppearances(speciesId: "54", colorId: "75") {
|
petAppearances(speciesId: "54", colorId: "75") {
|
||||||
id
|
id
|
||||||
|
|
||||||
|
species {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
color {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
bodyId
|
bodyId
|
||||||
petStateId
|
petStateId
|
||||||
pose
|
pose
|
||||||
genderPresentation
|
|
||||||
emotion
|
|
||||||
approximateThumbnailUrl
|
|
||||||
layers {
|
layers {
|
||||||
id
|
id
|
||||||
imageUrl(size: SIZE_600)
|
imageUrl(size: SIZE_600)
|
||||||
|
@ -124,6 +158,20 @@ describe("PetAppearance", () => {
|
||||||
"4751",
|
"4751",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM species_translations
|
||||||
|
WHERE species_id IN (?) AND locale = \\"en\\"",
|
||||||
|
Array [
|
||||||
|
"54",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
"SELECT * FROM color_translations
|
||||||
|
WHERE color_id IN (?) AND locale = \\"en\\"",
|
||||||
|
Array [
|
||||||
|
"75",
|
||||||
|
],
|
||||||
|
],
|
||||||
Array [
|
Array [
|
||||||
"SELECT * FROM zones WHERE id IN (?,?,?,?,?,?)",
|
"SELECT * FROM zones WHERE id IN (?,?,?,?,?,?)",
|
||||||
Array [
|
Array [
|
||||||
|
|
70
src/server/query-tests/__snapshots__/Outfit.test.js.snap
Normal file
70
src/server/query-tests/__snapshots__/Outfit.test.js.snap
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Outfit loads an outfit by ID 1`] = `
|
||||||
|
Object {
|
||||||
|
"outfit": Object {
|
||||||
|
"closetedItems": Array [
|
||||||
|
Object {
|
||||||
|
"id": "36125",
|
||||||
|
"name": "Blue Newsboy Hat",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "36467",
|
||||||
|
"name": "Daring Adventurer Hat",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "47075",
|
||||||
|
"name": "Jordies Adventure Hat",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "47056",
|
||||||
|
"name": "Moltara Inventor Hat and Goggles",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "39662",
|
||||||
|
"name": "Simple Sun Hat",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "56706",
|
||||||
|
"name": "Super Sleuth Hat and Wig",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "38915",
|
||||||
|
"name": "Zafara Tourist Shirt",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "56398",
|
||||||
|
"name": "Altador Cup Kreludor Frame",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"id": "31856",
|
||||||
|
"name": "Zafara Tourist",
|
||||||
|
"petAppearance": Object {
|
||||||
|
"color": Object {
|
||||||
|
"id": "34",
|
||||||
|
"name": "Green",
|
||||||
|
},
|
||||||
|
"id": "54-34-UNKNOWN",
|
||||||
|
"pose": "UNKNOWN",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"wornItems": Array [
|
||||||
|
Object {
|
||||||
|
"id": "38916",
|
||||||
|
"name": "Zafara Tourist Camera",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "51054",
|
||||||
|
"name": "Summer Fun Beach Background",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"id": "38914",
|
||||||
|
"name": "Zafara Tourist Hat",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
|
@ -3,6 +3,11 @@
|
||||||
exports[`PetAppearance loads for species and color 1`] = `
|
exports[`PetAppearance loads for species and color 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"petAppearance": Object {
|
"petAppearance": Object {
|
||||||
|
"color": Object {
|
||||||
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
|
"id": "54-75-HAPPY_FEM",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "5995",
|
"id": "5995",
|
||||||
|
@ -53,6 +58,10 @@ Object {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -61,10 +70,11 @@ exports[`PetAppearance loads multiple for species and color 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"petAppearances": Array [
|
"petAppearances": Array [
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/1/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": "HAPPY",
|
"color": Object {
|
||||||
"genderPresentation": "MASCULINE",
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-HAPPY_FEM",
|
"id": "54-75-HAPPY_FEM",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -112,12 +122,17 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "17723",
|
"petStateId": "17723",
|
||||||
"pose": "HAPPY_FEM",
|
"pose": "HAPPY_FEM",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/1/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": "HAPPY",
|
"color": Object {
|
||||||
"genderPresentation": "MASCULINE",
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-HAPPY_MASC",
|
"id": "54-75-HAPPY_MASC",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -165,12 +180,17 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "17742",
|
"petStateId": "17742",
|
||||||
"pose": "HAPPY_MASC",
|
"pose": "HAPPY_MASC",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/4/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": "SICK",
|
"color": Object {
|
||||||
"genderPresentation": "MASCULINE",
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-SICK_FEM",
|
"id": "54-75-SICK_FEM",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -218,12 +238,17 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "10014",
|
"petStateId": "10014",
|
||||||
"pose": "SICK_FEM",
|
"pose": "SICK_FEM",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/4/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": "SICK",
|
"color": Object {
|
||||||
"genderPresentation": "MASCULINE",
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-SICK_MASC",
|
"id": "54-75-SICK_MASC",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -271,12 +296,17 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "11089",
|
"petStateId": "11089",
|
||||||
"pose": "SICK_MASC",
|
"pose": "SICK_MASC",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/2/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": "SAD",
|
"color": Object {
|
||||||
"genderPresentation": "MASCULINE",
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-SAD_FEM",
|
"id": "54-75-SAD_FEM",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -324,12 +354,17 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "5991",
|
"petStateId": "5991",
|
||||||
"pose": "SAD_FEM",
|
"pose": "SAD_FEM",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/2/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": "SAD",
|
"color": Object {
|
||||||
"genderPresentation": "MASCULINE",
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-SAD_MASC",
|
"id": "54-75-SAD_MASC",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -377,12 +412,17 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "436",
|
"petStateId": "436",
|
||||||
"pose": "SAD_MASC",
|
"pose": "SAD_MASC",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/null/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": null,
|
"color": Object {
|
||||||
"genderPresentation": null,
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-UNKNOWN",
|
"id": "54-75-UNKNOWN",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -437,12 +477,17 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "2",
|
"petStateId": "2",
|
||||||
"pose": "UNKNOWN",
|
"pose": "UNKNOWN",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"approximateThumbnailUrl": "http://pets.neopets.com/cp/vghhzlgf/null/1.png",
|
|
||||||
"bodyId": "180",
|
"bodyId": "180",
|
||||||
"emotion": null,
|
"color": Object {
|
||||||
"genderPresentation": null,
|
"id": "75",
|
||||||
|
"name": "Starry",
|
||||||
|
},
|
||||||
"id": "54-75-UNKNOWN",
|
"id": "54-75-UNKNOWN",
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
@ -497,6 +542,10 @@ Object {
|
||||||
],
|
],
|
||||||
"petStateId": "4751",
|
"petStateId": "4751",
|
||||||
"pose": "UNKNOWN",
|
"pose": "UNKNOWN",
|
||||||
|
"species": Object {
|
||||||
|
"id": "54",
|
||||||
|
"name": "Zafara",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -11235,6 +11235,14 @@ Object {
|
||||||
"id": "21",
|
"id": "21",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"color": Object {
|
||||||
|
"id": "99",
|
||||||
|
},
|
||||||
|
"species": Object {
|
||||||
|
"id": "21",
|
||||||
|
},
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"color": Object {
|
"color": Object {
|
||||||
"id": "100",
|
"id": "100",
|
||||||
|
@ -12243,6 +12251,14 @@ Object {
|
||||||
"id": "23",
|
"id": "23",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"color": Object {
|
||||||
|
"id": "89",
|
||||||
|
},
|
||||||
|
"species": Object {
|
||||||
|
"id": "23",
|
||||||
|
},
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"color": Object {
|
"color": Object {
|
||||||
"id": "90",
|
"id": "90",
|
||||||
|
@ -18635,6 +18651,14 @@ Object {
|
||||||
"id": "36",
|
"id": "36",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"color": Object {
|
||||||
|
"id": "14",
|
||||||
|
},
|
||||||
|
"species": Object {
|
||||||
|
"id": "36",
|
||||||
|
},
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"color": Object {
|
"color": Object {
|
||||||
"id": "16",
|
"id": "16",
|
||||||
|
@ -21523,6 +21547,14 @@ Object {
|
||||||
"id": "41",
|
"id": "41",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"color": Object {
|
||||||
|
"id": "93",
|
||||||
|
},
|
||||||
|
"species": Object {
|
||||||
|
"id": "41",
|
||||||
|
},
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"color": Object {
|
"color": Object {
|
||||||
"id": "94",
|
"id": "94",
|
||||||
|
@ -27859,6 +27891,14 @@ Object {
|
||||||
"id": "53",
|
"id": "53",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"color": Object {
|
||||||
|
"id": "111",
|
||||||
|
},
|
||||||
|
"species": Object {
|
||||||
|
"id": "53",
|
||||||
|
},
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"color": Object {
|
"color": Object {
|
||||||
"id": "6",
|
"id": "6",
|
||||||
|
|
Loading…
Reference in a new issue