diff --git a/dist/index.js b/dist/index.js index 5e3a2a9..58943d0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9719,6 +9719,16 @@ var external_https_ = __nccwpck_require__(5687); ;// CONCATENATED MODULE: ./postmanLibrary.js +/** + * Retrieves the workspace with the given workspaceId using the POSTMAN API + * + * You can find sample responses to the API in the samples/payloads folder + * + * @param {string} workspaceId the id of the workspace to retrieve + * @param {string} postmanApiKey the API key to use to access the POSTMAN API + * @returns {Promise} a promise containing the workspace + * {@link https://www.postman.com/postman/workspace/postman-public-workspace/documentation/12959542-c8142d51-e97c-46b6-bd77-52bb66712c9a POSTMAN API documentation} + */ async function getWorkspace(workspaceId, postmanApiKey) { const options = { hostname: 'api.getpostman.com', diff --git a/localRun.js b/localRun.js index ce7a5f7..6ff8ed4 100644 --- a/localRun.js +++ b/localRun.js @@ -1,24 +1,78 @@ import * as postman from './postmanLibrary.js'; import * as dotenv from 'dotenv'; -import * as util from 'util'; +import * as utils from './utils.js'; +import * as fs from 'fs'; dotenv.config(); const POSTMAN_API_KEY = process.env.POSTMAN_API_KEY; const POSTMAN_WORKSPACE_ID = process.env.POSTMAN_WORKSPACE_ID; -async function localRun() { +/** + * This function runs the same logic as the action, but locally. The inputs have to be provided manually + * + * warning : This function will use the POSTMAN API and run against your monthly quota. + * + * @param {string} filesToProcess space separated list of all files to process + * @returns {Promise} a promise that resolves when the function is done + */ +async function localRun(filesToProcess) { console.log(`Getting workspace ${POSTMAN_WORKSPACE_ID}!`); - const workspace = await postman.getWorkspace(POSTMAN_WORKSPACE_ID, POSTMAN_API_KEY); - console.log(`The workspace:`); - console.log(util.inspect(workspace, {showHidden: false, depth: null, colors: true})); - console.log("------"); - console.log(JSON.stringify(workspace, null, 4)); + // const workspace = await postman.getWorkspace(POSTMAN_WORKSPACE_ID, POSTMAN_API_KEY); + const workspace = JSON.parse(fs.readFileSync('./samples/payloads/workspace.json', 'utf8')); + const collections = workspace.workspace.collections; + const filesToProcessAsList = filesToProcess.split(' '); + const apisToProcess = utils.filenamesToSet(filesToProcessAsList); + + const apisToProcessStructures = apisToProcess.map((api) => { + console.log(`Processing ${api}`); + return { + "filepath": api, + "name" : utils.getNameOfApi(api) + } + }); + + // We go through each API to process and match it with an existing POSTMAN Collections + apisToProcessStructures.forEach((api) => { + + const noMatch = collections.find(collection => collection.name === api.name) === undefined; + const collectionVersion = collections.find( + collection => collection.name.split(" (")[0] === api.name.split(" (")[0] + && utils.extractVersionNumber(api.name) > utils.extractVersionNumber(collection.name) + ); + const collectionExactMatch = collections.find( + collection => collection.name.split(" (")[0] === api.name.split(" (")[0] + ); + + // We have a match and with a higher version, in which case we have to update the collection + if(collectionVersion){ + console.log(`Updating collection ${collectionVersion.name} with ${api.name}`); + // postman.updateCollection(collectionVersion.id, api.filepath, POSTMAN_API_KEY); + } + + // Or no match at all, in which case we should create a new collection + if(noMatch){ + console.log(`Creating collection ${api.name}`); + // postman.createCollection(api.name, api.filepath, POSTMAN_WORKSPACE_ID, POSTMAN_API_KEY); + } + // We have an exact match, not doing anything but logging it for safety + if(collectionExactMatch){ + console.log(`Collection ${api.name} already exists`); + } + else{ + console.log(`No action for ${api.name}. Shouldn't happen!`); + } + }); } -localRun() +const path = "../adyen-postman/postman"; +const apiFiles = await utils.getFilesInFolder(path, ".json"); +const apiFilesWithPath = apiFiles.map((file) => { return `${path}/${file}`; }); +const apiFilesWithPathAsString = apiFilesWithPath.join(" "); + +localRun(apiFilesWithPathAsString) .then( _ => { console.log("Finished processing!"); }) diff --git a/postmanLibrary.js b/postmanLibrary.js index c526911..ec5a86c 100644 --- a/postmanLibrary.js +++ b/postmanLibrary.js @@ -1,5 +1,15 @@ import * as https from 'https'; +/** + * Retrieves the workspace with the given workspaceId using the POSTMAN API + * + * You can find sample responses to the API in the samples/payloads folder + * + * @param {string} workspaceId the id of the workspace to retrieve + * @param {string} postmanApiKey the API key to use to access the POSTMAN API + * @returns {Promise} a promise containing the workspace + * {@link https://www.postman.com/postman/workspace/postman-public-workspace/documentation/12959542-c8142d51-e97c-46b6-bd77-52bb66712c9a POSTMAN API documentation} + */ export async function getWorkspace(workspaceId, postmanApiKey) { const options = { hostname: 'api.getpostman.com', diff --git a/tests/filterApis.js b/tests/utils.js similarity index 90% rename from tests/filterApis.js rename to tests/utils.js index 316ee4c..a333954 100644 --- a/tests/filterApis.js +++ b/tests/utils.js @@ -1,7 +1,7 @@ import { test } from 'uvu'; import * as assert from 'uvu/assert'; -import {filenamesToSet} from '../filterApis.js'; +import {filenamesToSet, extractVersionNumber} from '../utils.js'; const FULL_LIST = "../adyen-postman/postman/BalanceControlService-v1.json ../adyen-postman/postman/BalancePlatformService-v1.json ../adyen-postman/postman/BalancePlatformService-v2.json ../adyen-postman/postman/BinLookupService-v40.json ../adyen-postman/postman/BinLookupService-v50.json ../adyen-postman/postman/BinLookupService-v52.json ../adyen-postman/postman/BinLookupService-v53.json ../adyen-postman/postman/BinLookupService-v54.json ../adyen-postman/postman/CheckoutService-v37.json ../adyen-postman/postman/CheckoutService-v40.json ../adyen-postman/postman/CheckoutService-v41.json ../adyen-postman/postman/CheckoutService-v46.json ../adyen-postman/postman/CheckoutService-v49.json ../adyen-postman/postman/CheckoutService-v50.json ../adyen-postman/postman/CheckoutService-v51.json ../adyen-postman/postman/CheckoutService-v52.json ../adyen-postman/postman/CheckoutService-v53.json ../adyen-postman/postman/CheckoutService-v64.json ../adyen-postman/postman/CheckoutService-v65.json ../adyen-postman/postman/CheckoutService-v66.json ../adyen-postman/postman/CheckoutService-v67.json ../adyen-postman/postman/CheckoutService-v68.json ../adyen-postman/postman/CheckoutService-v69.json ../adyen-postman/postman/CheckoutService-v70.json ../adyen-postman/postman/DataProtectionService-v1.json ../adyen-postman/postman/LegalEntityService-v1.json ../adyen-postman/postman/LegalEntityService-v2.json ../adyen-postman/postman/LegalEntityService-v3.json ../adyen-postman/postman/ManagementService-v1.json ../adyen-postman/postman/PayoutService-v30.json ../adyen-postman/postman/PayoutService-v40.json ../adyen-postman/postman/PayoutService-v50.json ../adyen-postman/postman/PayoutService-v51.json ../adyen-postman/postman/PayoutService-v52.json ../adyen-postman/postman/PayoutService-v64.json ../adyen-postman/postman/PayoutService-v67.json ../adyen-postman/postman/PayoutService-v68.json ../adyen-postman/postman/RecurringService-v25.json ../adyen-postman/postman/RecurringService-v30.json ../adyen-postman/postman/RecurringService-v40.json ../adyen-postman/postman/RecurringService-v49.json ../adyen-postman/postman/RecurringService-v67.json ../adyen-postman/postman/RecurringService-v68.json ../adyen-postman/postman/StoredValueService-v46.json ../adyen-postman/postman/TestCardService-v1.json ../adyen-postman/postman/TfmAPIService-v1.json ../adyen-postman/postman/TransferService-v1.json ../adyen-postman/postman/TransferService-v2.json ../adyen-postman/postman/TransferService-v3.json" const FULL_FILENAMES = FULL_LIST.split(" "); @@ -31,6 +31,14 @@ test('filenamesToSet full', () => { assert.equal(filenamesToSet(FULL_FILENAMES), CLEAN_FILENAMES); }); +test('extractVersionNumber', () => { + assert.equal(extractVersionNumber("Adyen Checkout API (v70)"), 70); + assert.equal(extractVersionNumber("Adyen Checkout API (v1)"), 1); + assert.equal(extractVersionNumber("Adyen Checkout API (v)"), null); + assert.equal(extractVersionNumber("Adyen Checkout API"), null); + assert.equal(extractVersionNumber("Adyen Checkout API (vPlop)"), null); +}); + test.run(); diff --git a/filterApis.js b/utils.js similarity index 60% rename from filterApis.js rename to utils.js index 084ad66..e217413 100644 --- a/filterApis.js +++ b/utils.js @@ -1,4 +1,31 @@ import * as path from "path"; +import * as fs from 'fs'; + + +/** + * Given the filepath of a Postman API definition, returns the name of the API from the info section + * @param {string} filepath the path to the API file + * @returns {string} the name of the API + */ +export function getNameOfApi(filepath){ + const api = JSON.parse(fs.readFileSync(filepath, 'utf8')); + return api.info.name; +} + +/** + * Given a filepath and a file extension, returns all files with that extension in the given filepath + * @constructor + * @param {string} filepath a list of filenames, including path and extension + * @param {string} extension the extension to filter by + * @returns {Promise>} a promise containing a list of filenames with the given extension + */ +export async function getFilesInFolder(filepath, extension){ + return fs.promises.readdir(filepath).then((files) => { + return files.filter((file) => { + return path.extname(file) === extension; + }); + }); +} /** * This is a pretty specific function. @@ -39,10 +66,24 @@ export function filenamesToSet(filenames){ }); }); - return highestVersions.map((value) => { return value.path});; + return highestVersions.map((value) => { return value.path}); } +/** + * Given an API Name in the form APIName (vXX) where XX is the version number, extracts the version number + * @param {string} apiName the name of the API + * @returns {number|null} the version number, or null if no version number is found + * + * @example + * // returns "70" + * extractVersionNumber("Adyen Checkout API (v70)"); + */ +export function extractVersionNumber(apiName) { + const versionMatch = apiName.match(/\(v(\d+)\)/); + return versionMatch ? Number(versionMatch[1]) : null; +} + /** * Group an array of objects using the given key * @param {Array} xs an array of objects