UNPKG

@kenxirwin/alma-search

Version:
168 lines (153 loc) 4.75 kB
export default class SearchBibs { constructor(params) { const expectedKeys = ['baseUrl', 'apiKey']; for (const key of expectedKeys) { if (!params.hasOwnProperty(key)) { throw new Error(`Missing required option: ${key}`); } else if (typeof params[key] !== 'string') { throw new Error( `Option ${key} must be a string; received ${typeof params[key]}` ); } else if (params[key].trim() === '') { throw new Error(`Option ${key} cannot be an empty string`); } else { this[key] = params[key].trim(); } } } /* idLookup -- use any of these Alma Ids: 'mms_id', 'holdings_id', 'ie_id', 'representation_id', 'nz_mms_id', 'cz_mms_id', 'other_system_id', Accepts comma-separated values (no spaces) for multiple items */ async idLookup(searchParams = {}) { try { this.validateBibParams(searchParams); } catch (error) { throw new Error(`Validation failed: ${error.message}`); } const apiPath = '/almaws/v1/bibs'; const url = new URL(this.baseUrl + apiPath); for (const [key, value] of Object.entries(searchParams)) { if (value !== undefined && value !== null) { url.searchParams.set(key, value); } } console.log(`Request URL: ${url.toString()}`); return await this.executeFetch(url); } async holdingsByMmsId(mms_id) { const apiPath = `/almaws/v1/bibs/${mms_id}/holdings`; const url = new URL(this.baseUrl + apiPath); console.log(`Request URL: ${url.toString()}`); return this.executeFetch(url); } // this can be used for any Alma link -- the API key will be added async followLink(inputUrl) { const url = new URL(inputUrl); console.log(`Request URL: ${url.toString()}`); return this.executeFetch(url); } async holdingsItemsByMmsId(mms_id, options) { const holdingId = options.hasOwnProperty('holding_id') ? options.holding_id : 'all'; const apiPath = `/almaws/v1/bibs/${mms_id}/holdings/${holdingId}/items`; const queryStringParams = [ 'limit', 'offset', 'expand', 'user_id', 'current_library', 'current_location', 'q', 'order_by', 'direction', 'create_date_from', 'create_date_to', 'modify_date_from', 'modify_date_to', 'receive_date_from', 'receive_date_to', 'expected_receive_date_from', 'expected_receive_date_to', 'view', ]; const url = new URL(this.baseUrl + apiPath); queryStringParams.forEach((param) => { if (options.hasOwnProperty(param)) { for (const key in options) { if (queryStringParams.includes(key)) { url.searchParams.set(key, options[key]); } } } }); console.log(`Request URL: ${url.toString()}`); return this.executeFetch(url); } validateBibParams(params) { const expectOneOf = [ 'mms_id', 'holdings_id', 'ie_id', 'representation_id', 'nz_mms_id', 'cz_mms_id', 'other_system_id', ]; let count = 0; for (const key of expectOneOf) { if (params.hasOwnProperty(key)) { if (typeof params[key] !== 'string') { throw new Error( `Option ${key} must be a string; received ${typeof params[key]}` ); } else if (params[key].trim() === '') { throw new Error(`Option ${key} cannot be an empty string`); } else { this[key] = params[key].trim(); count++; } } } if (count === 0) { throw new Error( `At least one of the following options must be provided: ${expectOneOf.join( ', ' )}` ); } } async barcodeLookup(barcode) { //accept integer or string of integers if (barcode.toString().match(/^\d+$/) === null) { throw new Error( `Barcode must be a string of digits; received ${barcode}` ); } const apiPath = '/almaws/v1/items'; const url = new URL(this.baseUrl + apiPath); url.searchParams.set('item_barcode', barcode); console.log(`Request URL: ${url.toString()}`); return await this.executeFetch(url); } async executeFetch(url) { url.searchParams.set('apikey', this.apiKey); console.log(`Requesting: ${url.toString()}`); const response = await fetch(url.toString(), { method: 'GET', headers: { 'Content-Type': 'application/json', Accept: 'application/json', }, }); if (!response.ok) { const resString = JSON.stringify(response, null, 2); throw new Error(`Network response was not ok: (${resString})`); } const data = await response.json(); return data; } }