Skip to content

Commit

Permalink
Updated and clarified default values in the readme, small code refact…
Browse files Browse the repository at this point in the history
…ors (#11)
  • Loading branch information
NikkelM authored Mar 6, 2024
1 parent 512983f commit 19837e6
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 158 deletions.
178 changes: 103 additions & 75 deletions README.md

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions config.default.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
"keepCompleteProperties": false,
"includedProperties": {
"productTitle": true,
"productId": true,
"developerName": true,
"publisherName": true,
"categories": true,
"productId": false,
"developerName": false,
"publisherName": false,
"categories": false,
"productDescription": {
"enabled": true,
"enabled": false,
"preferShort": false
},
"images": {
"enabled": true,
"enabled": false,
"imageTypes": {
"TitledHeroArt": -1,
"SuperHeroArt": -1,
Expand All @@ -37,23 +37,23 @@
}
},
"releaseDate": {
"enabled": true,
"enabled": false,
"format": "date"
},
"userRating": {
"enabled": true,
"enabled": false,
"aggregationInterval": "AllTime",
"format": "percentage"
},
"pricing": {
"enabled": true,
"enabled": false,
"priceTypes": [
"ListPrice",
"MSRP",
"WholesalePrice"
],
"missingPricePolicy": "useNull"
},
"storePage": true
"storePage": false
}
}
95 changes: 47 additions & 48 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -369,59 +369,59 @@
]
},
"treatEmptyStringsAsNull": {
"description": "Whether or not to treat empty strings as null values.",
"description": "Whether to treat empty strings as null values.",
"type": "boolean",
"default": true
},
"keepCompleteProperties": {
"description": "Whether or not to keep the original, complete list of properties for the fetched games. Will be saved in a separate file per platform and market.",
"description": "Whether to keep the original, complete list of properties for the fetched games. Will be saved in a separate file per platform and market.",
"type": "boolean",
"default": false
},
"includedProperties": {
"description": "The properties that should be contained in the cleaned version of the API response.",
"description": "The properties that should be contained in the filtered version of the API response.",
"type": "object",
"properties": {
"productTitle": {
"description": "Whether or not to include the title of the game.",
"description": "Whether to include the title of the game.",
"type": "boolean",
"default": true
},
"productId": {
"description": "Whether or not to include the product ID of the game.",
"description": "Whether to include the product ID of the game.",
"type": "boolean",
"default": true
"default": false
},
"developerName": {
"description": "Whether or not to include the name of the developer of the game.",
"description": "Whether to include the name of the game's developer.",
"type": "boolean",
"default": true
"default": false
},
"publisherName": {
"description": "Whether or not to include the name of the publisher of the game.",
"description": "Whether to include the name of the game's publisher.",
"type": "boolean",
"default": true
"default": false
},
"categories": {
"description": "Whether or not to include the game's categories. This can be used as tags.",
"description": "Whether to include the game's categories.",
"type": "boolean",
"default": true
"default": false
},
"productDescription": {
"description": "The description of the game.",
"description": "Whether to include the description of the game.",
"type": "object",
"default": {
"enabled": true,
"enabled": false,
"preferShort": false
},
"properties": {
"enabled": {
"description": "Whether or not to include the description of the game.",
"description": "Whether to include the description of the game.",
"type": "boolean",
"default": true
"default": false
},
"preferShort": {
"description": "Whether or not to prefer the short description of the game, if one exists.",
"description": "Whether to prefer the short description of the game over the long description, if one exists.",
"type": "boolean",
"default": false
}
Expand All @@ -432,31 +432,30 @@
"additionalProperties": false
},
"images": {
"description": "Whether or not to include image URL's for the game.",
"description": "Whether to include image URL's for the game.",
"type": "object",
"default": {
"enabled": true,
"maxImages": 0,
"imageTypes": [
"TitledHeroArt",
"SuperHeroArt",
"Logo",
"Poster",
"Screenshot",
"BoxArt",
"Hero",
"BrandedKeyArt",
"FeaturePromotionalSquareArt"
]
"enabled": false,
"imageTypes": {
"TitledHeroArt": -1,
"SuperHeroArt": -1,
"Logo": -1,
"Poster": -1,
"Screenshot": -1,
"BoxArt": -1,
"Hero": -1,
"BrandedKeyArt": -1,
"FeaturePromotionalSquareArt": -1
}
},
"properties": {
"enabled": {
"description": "Whether or not to include any the images in the result.",
"description": "Whether to include image URL's for the game.",
"type": "boolean",
"default": true
"default": false
},
"imageTypes": {
"description": "What kinds of images should be considered, and a maximum of many of each type should be chosen. A value of -1 indicates no limit.",
"description": "What kinds of images should be included in the output, and a maximum of how many of each type should be chosen.",
"type": "object",
"default": {
"TitledHeroArt": -1,
Expand Down Expand Up @@ -527,17 +526,17 @@
"additionalProperties": false
},
"releaseDate": {
"description": "Whether or not to include the game's release date.",
"description": "Whether to include the game's release date.",
"type": "object",
"default": {
"enabled": true,
"enabled": false,
"format": "date"
},
"properties": {
"enabled": {
"description": "Whether or not to include the game's release date.",
"description": "Whether to include the game's release date.",
"type": "boolean",
"default": true
"default": false
},
"format": {
"description": "How to format the date string. Either the full dateTime (YYYY-MM-DDTHH:mm:ss.sssssssZ) or just the date (YYYY-MM-DD).",
Expand All @@ -556,18 +555,18 @@
"additionalProperties": false
},
"userRating": {
"description": "Whether or not to include the game's user rating.",
"description": "Whether to include the game's user rating.",
"type": "object",
"default": {
"enabled": true,
"enabled": false,
"aggregationInterval": "AllTime",
"format": "percentage"
},
"properties": {
"enabled": {
"description": "Whether or not to include the game's user rating.",
"description": "Whether to include the game's user rating.",
"type": "boolean",
"default": true
"default": false
},
"aggregationInterval": {
"description": "Which kind of interval to use for rating aggregation.",
Expand Down Expand Up @@ -597,10 +596,10 @@
"additionalProperties": false
},
"pricing": {
"description": "Whether or not to include the game's price information. The currency that is used is dependent on the chosen \"market\".",
"description": "Whether to include the game's price information. The currency that is used is dependent on the chosen \"market\".",
"type": "object",
"default": {
"enabled": true,
"enabled": false,
"priceTypes": [
"ListPrice",
"MSRP",
Expand All @@ -612,10 +611,10 @@
"enabled": {
"description": "Whether or not to include the game's price information. The currency that is used is dependent on the chosen \"market\".",
"type": "boolean",
"default": true
"default": false
},
"priceTypes": {
"description": "Which kinds of prices to include. Choose from ListPrice, MSRP and WholesalePrice (i.e. applied discounts).",
"description": "Which kinds of prices to include. Choose from \"ListPrice\", \"MSRP\" and \"WholesalePrice\" (i.e. with discounts applied).",
"type": "array",
"default": [
"ListPrice",
Expand Down Expand Up @@ -662,9 +661,9 @@
"additionalProperties": false
},
"storePage": {
"description": "Whether or not to include the game's store page URL. NOTE: THIS IS NOT GUARANTEED TO ALWAYS RESULT IN A WORKING URL, AS IT NEEDS TO BE INFERRED AND IS NOT AVAILABLE THROUGH THE API.",
"description": "Whether to include the game's store page URL. Note that this is not guaranteed to always result in a working URL, as it needs to be inferred and is not available through the API.",
"type": "boolean",
"default": true
"default": false
}
},
"additionalProperties": false,
Expand Down
27 changes: 5 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,20 @@ try {

// ----- Output -----

// Create the output directory if it doesn't exist
if (!fs.existsSync(__dirname + '/output')) {
fs.mkdirSync(__dirname + '/output');
}

// ---------- Main ----------

// If the user wants empty strings to be treated as null or not
const emptyValuePlaceholder = CONFIG.treatEmptyStringsAsNull ? null : "";

main();

async function main() {
// Fetch Game Pass game ID's and properties for each pass type and market specified in the configuration
// We do this in parallel to speed up the process
// While the functions do return the formatted properties, we currently do not use them here, as writing the output files is handled by the functions themselves
for (const market of CONFIG.markets) {
if (CONFIG.platformsToFetch.includes("console")) {
const consoleFormattedProperties = runScriptForPassTypeAndMarket("console", market);
Expand All @@ -75,14 +74,9 @@ async function main() {
}

async function runScriptForPassTypeAndMarket(passType, market) {
// Fetch Game Pass game ID's
const gameIds = await fetchGameIDs(passType, market);

// Fetch Game Pass game properties
const gameProperties = await fetchGameProperties(gameIds, passType, market);

// Format the data according to the configuration
const formattedData = formatData(gameProperties, passType, market);
const formattedData = formatData(gameProperties, passType);

fs.writeFileSync(`./output/formattedGameProperties_${passType}_${market}.json`, JSON.stringify(formattedData, null, 2));

Expand All @@ -91,9 +85,8 @@ async function runScriptForPassTypeAndMarket(passType, market) {

// ---------- Fetch game ID's & properties ----------

// Get all Game Pass Game ID's for this market
async function fetchGameIDs(passType, market) {
// Get all Game Pass Game ID's for this market

const APIIds = {
"console": "f6f1f99f-9b49-4ccd-b3bf-4d9767a77f5e",
"pc": "fdd9e2a7-0fee-49f6-ad69-4354098401ff",
Expand All @@ -114,27 +107,19 @@ async function fetchGameProperties(gameIds, passType, market) {
.then((response) => response.json())
.then((data) => {
if (CONFIG.keepCompleteProperties) {
// Write the data to a file
fs.writeFileSync(`./output/completeGameProperties_${passType}_${market}.json`, JSON.stringify(data, null, 2));
}
return data;
});
}

// Format the data according to the configuration
function formatData(gameProperties, passType, market) {
function formatData(gameProperties, passType) {
console.log(`Formatting game properties for ${gameProperties.Products.length} ${passType} games...`);

// Create a new object to store the formatted data
let formattedData = {};
// If the user wants the result to be an array
if (CONFIG.outputFormat === "array") {
formattedData = [];
}
let formattedData = CONFIG.outputFormat === "array" ? [] : {};

// Loop through each game
for (const game of gameProperties.Products) {
// Create a new object for this game
let index;
switch (CONFIG.outputFormat) {
case "array":
Expand All @@ -152,9 +137,7 @@ function formatData(gameProperties, passType, market) {
}
formattedData[index] = {};

// Loop through each property
for (const [property, propertyValue] of Object.entries(CONFIG.includedProperties)) {
// Get the value of the property
const result = getPropertyValue(game, property, propertyValue);

// Add the property to the object, only if it is not undefined. undefined indicates the property was present in the config, but disabled.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "game-pass-api",
"type": "module",
"version": "1.1.1",
"version": "1.2.0",
"description": "Get all games currently available for Xbox Game Pass on any platform, with their features and properties formatted just the way you need!",
"main": "index.js",
"dependencies": {
Expand Down

0 comments on commit 19837e6

Please sign in to comment.