UNPKG

@digital-passports/javascript-sdk

Version:

JavaScript SDK for interacting with the Digital Passport Hub REST API.

144 lines (131 loc) 4.36 kB
// Digital Passport Hub JavaScript SDK // For more information, see: https://digitalpassporthub.com/api-documentation const { version } = require('./package.json'); /** * Custom error for Digital Passport SDK */ class DigitalPassportError extends Error { /** * @param {string} message * @param {number} [status] * @param {any} [details] */ constructor(message, status, details) { super(message); this.name = 'DigitalPassportError'; this.status = status; this.details = details; } } const BASE_URL = 'https://api.digitalpassporthub.com/v1/'; /** * @typedef {Object} DigitalPassportOptions * @property {string} [apiKey] - API key for authentication * @property {string} [environment] - Environment (default: 'production') * @property {Function} [fetch] - Custom fetch implementation */ let fetchDefault = undefined; /** * Digital Passport SDK */ class DigitalPassport { /** * @param {DigitalPassportOptions} options */ constructor({ apiKey, environment = 'production', fetch } = {}) { this.apiKey = apiKey || (typeof process !== 'undefined' ? process.env.DIGITAL_PASSPORT_API_KEY : undefined); if (!this.apiKey) throw new DigitalPassportError('API key is required'); this.environment = environment; if (fetch) { this._fetch = fetch; } else if (typeof window === 'undefined' && typeof require === 'function') { // Only require node-fetch in Node.js at runtime if (!fetchDefault) { try { fetchDefault = require('node-fetch'); } catch (e) { fetchDefault = undefined; } } this._fetch = fetchDefault; } else if (typeof fetch === 'function') { this._fetch = fetch.bind(globalThis); } else { this._fetch = undefined; } if (!this._fetch) { throw new DigitalPassportError('No fetch implementation found. Please provide a fetch function in the options.'); } } async _request(path, options = {}) { const url = BASE_URL + path; const headers = { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json', ...(options.headers || {}) }; try { const response = await this._fetch(url, { ...options, headers }); const contentType = response.headers.get('content-type'); let data; if (contentType && contentType.includes('application/json')) { data = await response.json(); } else { data = await response.text(); } if (!response.ok) { throw new DigitalPassportError( `HTTP ${response.status}: ${data && data.message ? data.message : data}`, response.status, data ); } return data; } catch (err) { if (err instanceof DigitalPassportError) throw err; throw new DigitalPassportError(`Failed to fetch ${url}: ${err.message}`); } } /** * List all Digital Product Passports * @returns {Promise<object>} Paginated list of passports */ async listPassports() { return this._request('passports', { method: 'GET' }); } /** * Create a new Digital Product Passport * @param {object} data - Passport data (sku, name, etc.) * @returns {Promise<object>} Created passport object */ async createPassport(data) { if (!data || !data.sku || !data.name) { throw new DigitalPassportError('Passport data with sku and name is required'); } return this._request('passports', { method: 'POST', body: JSON.stringify(data) }); } /** * Generate a QR code for a specific passport * @param {string} passportId - ID of the passport * @param {object} options - QR code options (size, format) * @returns {Promise<object>} QR code data */ async generateQRCode(passportId, options = {}) { if (!passportId) throw new DigitalPassportError('passportId is required'); const params = new URLSearchParams(options).toString(); const path = `passports/${passportId}/qrcode${params ? '?' + params : ''}`; return this._request(path, { method: 'GET' }); } } module.exports = { DigitalPassport, DigitalPassportError, version, default: DigitalPassport };