/** * Models resource module for IT Glue API * * Provides methods to interact with the /models endpoint. * Models represent specific product models from manufacturers, such as hardware devices, * software applications, or other technology products tracked in IT Glue. Each model * is associated with a manufacturer and provides detailed specifications and information * about the product. Examples include "Dell PowerEdge R740", "iPhone 13 Pro", or "Windows Server 2022". * * Models are typically associated with: * - Manufacturers (the company that produces the model) * - Configurations (specific instances of the model in use) * - Assets (physical or virtual items based on the model) * - Operating Systems (for software models or compatible OS versions) * * ## Related Resources * Models are commonly used with: * - {@link Manufacturers} - Companies that produce the models * - {@link Configurations} - Specific instances of models deployed in organizations * - {@link ConfigurationTypes} - Categories that models belong to (server, workstation, etc.) * - {@link Organizations} - Organizations that own configurations based on models * - {@link OperatingSystems} - Operating systems that run on model configurations * - {@link FlexibleAssets} - Custom tracking of model specifications and warranties * - {@link Documents} - Technical documentation and manuals for models * - {@link RelatedItems} - Create relationships between models and other resources * - {@link Tags} - Categorize models by features, generation, or purpose * - {@link Attachments} - Store datasheets, manuals, and specifications for models * * @see {@link Manufacturers#list} for retrieving manufacturers of models * @see {@link Configurations#list} for retrieving configurations based on models * @see {@link ConfigurationTypes#list} for retrieving model categories * @see {@link OperatingSystems#list} for retrieving compatible operating systems * * @example * import { ITGlueClient } from '../client'; * import { Models } from './resources/models'; * * const client = new ITGlueClient({ apiKey: 'your-api-key' }); * const models = new Models(client); * * // List models * const list = await models.list(); * * // Get a single model * const model = await models.get('123'); * * // Create a model * const created = await models.create({ * data: { * type: 'models', * attributes: { * name: 'PowerEdge R750' * }, * relationships: { * manufacturer: { * data: { type: 'manufacturers', id: '456' } * } * } * } * }); * * // Update a model * const updated = await models.update('123', { * data: { * type: 'models', * attributes: { * name: 'Updated Model Name' * } * } * }); * * // Delete a model * await models.delete('123'); * * @category Reference Data */ import { ITGlueClient } from '../client'; import { QueryUtilOptions, QueryParams, RequestBody, BaseListResponse, BaseItemResponse, ModelResource } from '../types'; export declare class Models { private client; private basePath; private paginationUtil; /** * Create a Models resource instance * @param {ITGlueClient} client - ITGlueClient instance */ constructor(client: ITGlueClient); /** * List all models * @param {QueryUtilOptions} [options] - Optional query parameters (filter, sort, page, etc.) * @param {boolean} [allPages=false] - If true, fetches all pages automatically * @returns {Promise>} List of models and pagination metadata * @example * // Basic usage - get first page of models * const results = await client.models.list(); * console.log(`Found ${results.data.length} models`); * console.log('Total pages:', results.meta.pagination.total_pages); * * @example * // Advanced usage with pagination and sorting * const results = await client.models.list({ * page: { number: 2, size: 50 }, * sort: 'name', // Sort alphabetically * include: ['manufacturer', 'configurations'] // Include related data * }); * * // Access model information * results.data.forEach(model => { * console.log(`Model: ${model.attributes.name}`); * console.log(`Notes: ${model.attributes.notes || 'No notes'}`); * }); * * @example * // Filtering models by manufacturer * const dellModels = await client.models.list({ * filter: { * manufacturer_id: '456' * }, * sort: 'name', * include: ['manufacturer'] * }); * * console.log(`Found ${dellModels.data.length} Dell models`); * * @example * // Get all models for inventory management * const allModels = await client.models.list({}, true); // allPages = true * console.log(`Retrieved all ${allModels.data.length} models`); * * // Group by manufacturer for inventory reporting * const modelsByManufacturer = {}; * allModels.data.forEach(model => { * const manufacturerId = model.relationships?.manufacturer?.data?.id; * if (manufacturerId) { * if (!modelsByManufacturer[manufacturerId]) { * modelsByManufacturer[manufacturerId] = []; * } * modelsByManufacturer[manufacturerId].push({ * id: model.id, * name: model.attributes.name, * notes: model.attributes.notes * }); * } * }); * * @example * // Manual pagination for large model datasets * async function getAllModelsWithDetails() { * let page = 1; * let allModels = []; * let hasMore = true; * * while (hasMore) { * const response = await client.models.list({ * page: { number: page, size: 100 }, * sort: 'name', * include: ['manufacturer', 'configurations'] * }); * * allModels = [...allModels, ...response.data]; * hasMore = response.meta.pagination.total_pages > page; * page++; * } * * return allModels; * } * * @example * // Error handling for list operations * try { * const results = await client.models.list({ * filter: { invalid_field: 'value' } * }); * } catch (error) { * if (error.response?.status === 400) { * console.log('Invalid filter parameters:', error.response.data.errors); * } else if (error.response?.status === 401) { * console.log('Authentication failed - check your API key'); * } else if (error.response?.status === 403) { * console.log('Access denied - insufficient permissions to list models'); * } else { * console.log('Request failed:', error.message); * } * } */ list(options?: QueryUtilOptions, allPages?: boolean): Promise>; /** * Get a single model by ID * @param {string} id - Model ID * @param {QueryParams} [params] - Optional query parameters * @returns {Promise>} Model resource * @example * // Basic usage - get model by ID * const model = await client.models.get('123'); * console.log('Model name:', model.data.attributes.name); * console.log('Notes:', model.data.attributes.notes); * console.log('Created:', model.data.attributes.created_at); * * @example * // Get model with related manufacturer and configurations * const modelWithRelated = await client.models.get('123', { * include: ['manufacturer', 'configurations'] * }); * * // Access included data * const included = modelWithRelated.included || []; * const manufacturer = included.find(item => item.type === 'manufacturers'); * const configurations = included.filter(item => item.type === 'configurations'); * * console.log(`Model: ${modelWithRelated.data.attributes.name}`); * console.log(`Manufacturer: ${manufacturer?.attributes.name || 'Unknown'}`); * console.log(`Configurations: ${configurations.length} instances`); * * @example * // Error handling for get operations * try { * const model = await client.models.get('invalid-id'); * } catch (error) { * if (error.response?.status === 404) { * console.log('Model not found'); * } else if (error.response?.status === 403) { * console.log('Access denied - insufficient permissions'); * } else { * console.log('Error retrieving model:', error.message); * } * } * * @example * // Safe get with existence check * async function safeGetModel(id) { * try { * const model = await client.models.get(id); * return model.data; * } catch (error) { * if (error.response?.status === 404) { * return null; // Model doesn't exist * } * throw error; // Re-throw other errors * } * } * @see * {@link Manufacturers#get} - Get specific manufacturer details * {@link Manufacturers#list} - List manufacturers related to models */ get(id: string, params?: QueryParams): Promise>; /** * Create a new model * * Creates a new model entry in IT Glue. Models must be associated with a manufacturer * and should include detailed specifications and information about the product. * Ensure the model name is unique within the manufacturer's product line. * * @param {RequestBody} data - Model data (must be formatted according to JSON:API spec) * @returns {Promise>} Created model resource * @throws {Error} When validation fails (422) or unauthorized (401) * @example * // Basic hardware model creation * const newModel = await client.models.create({ * data: { * type: 'models', * attributes: { * name: 'PowerEdge R750', * notes: '2U rack server with dual Intel Xeon processors, up to 32 DIMM slots, and flexible storage options' * }, * relationships: { * manufacturer: { * data: { type: 'manufacturers', id: '456' } * } * } * } * }); * * console.log('Created model with ID:', newModel.data.id); * * @example * // Create software model with detailed specifications * const newModel = await client.models.create({ * data: { * type: 'models', * attributes: { * name: 'Windows Server 2022 Standard', * notes: 'Server operating system with Hyper-V virtualization, Active Directory, and enhanced security features. Supports up to 64 cores and 4TB RAM.' * }, * relationships: { * manufacturer: { * data: { type: 'manufacturers', id: '789' } * } * } * } * }); * * @example * // Bulk model creation with error handling * async function createMultipleModels(modelList) { * const results = []; * const errors = []; * * for (const modelData of modelList) { * try { * const created = await client.models.create({ * data: { * type: 'models', * attributes: { * name: modelData.name, * notes: modelData.notes * }, * relationships: { * manufacturer: { * data: { type: 'manufacturers', id: modelData.manufacturerId } * } * } * } * }); * results.push(created.data); * } catch (error) { * errors.push({ modelData, error: error.message }); * } * } * * return { results, errors }; * } * * // Usage * const modelsToCreate = [ * { name: 'iPhone 14 Pro', notes: 'Flagship smartphone with A16 Bionic chip', manufacturerId: '123' }, * { name: 'MacBook Pro 16"', notes: 'Professional laptop with M2 Pro/Max chip', manufacturerId: '123' }, * { name: 'Surface Pro 9', notes: 'Convertible tablet with Intel 12th gen processors', manufacturerId: '456' } * ]; * * @example * // Error handling for model creation * try { * const created = await client.models.create({ * data: { * type: 'models', * attributes: { * name: '' // Invalid empty name * } * } * }); * } catch (error) { * if (error.response?.status === 422) { * console.log('Validation errors:'); * error.response.data.errors.forEach(err => { * console.log(`- ${err.detail} (${err.source?.pointer})`); * }); * } else if (error.response?.status === 403) { * console.log('Permission denied - cannot create model'); * } else if (error.response?.status === 409) { * console.log('Conflict - model with this name may already exist for this manufacturer'); * } else { * console.log('Creation failed:', error.message); * } * } * @see * {@link Manufacturers#create} - Create new manufacturer * {@link Manufacturers#list} - List manufacturers related to models */ create(data: RequestBody): Promise>; /** * Update a model by ID * * Updates an existing model. Changes to model information will be reflected * in all associated configurations and assets that reference this model. * Use caution when updating model names as this may affect asset tracking * and inventory management. * * @param {string} id - Model ID * @param {RequestBody} data - Updated model data (must be formatted according to JSON:API spec) * @returns {Promise>} Updated model resource * @throws {Error} When model not found (404) or validation fails (422) * @example * // Basic update - modify model name and specifications * const updatedModel = await client.models.update('123', { * data: { * type: 'models', * attributes: { * name: 'PowerEdge R750xs', * notes: 'Updated model with enhanced storage capabilities and improved cooling system' * } * } * }); * * console.log('Model updated successfully'); * * @example * // Update model manufacturer relationship * const updatedModel = await client.models.update('123', { * data: { * type: 'models', * attributes: { * notes: 'Model transferred to new manufacturer after acquisition' * }, * relationships: { * manufacturer: { * data: { type: 'manufacturers', id: '999' } * } * } * } * }); * * @example * // Conditional update based on current state * async function conditionalUpdateModel(id, updates) { * try { * // First, get current state * const current = await client.models.get(id); * * // Check if update is needed * const needsUpdate = Object.keys(updates.attributes || {}).some( * key => current.data.attributes[key] !== updates.attributes[key] * ); * * if (!needsUpdate) { * console.log('Model is already up to date'); * return current; * } * * // Perform update * return await client.models.update(id, { * data: { * type: 'models', * ...updates * } * }); * } catch (error) { * console.error('Update failed:', error.message); * throw error; * } * } * * @example * // Error handling for model updates * try { * const updated = await client.models.update('invalid-id', { * data: { * type: 'models', * attributes: { * name: 'New Model Name' * } * } * }); * } catch (error) { * if (error.response?.status === 404) { * console.log('Model not found'); * } else if (error.response?.status === 422) { * console.log('Validation failed:', error.response.data.errors); * } else if (error.response?.status === 409) { * console.log('Conflict - model name may already be in use by this manufacturer'); * } else { * console.log('Update failed:', error.message); * } * } * @see * {@link Manufacturers#update} - Update manufacturer * {@link Manufacturers#get} - Get specific manufacturer details */ update(id: string, data: RequestBody): Promise>; /** * Delete a model by ID * * Permanently removes a model from IT Glue. This operation will fail if * the model is referenced by any configurations, assets, or other resources. * Consider updating or removing dependent resources before deleting the model. * * @param {string} id - Model ID * @returns {Promise} * @throws {Error} When model not found (404) or has dependent resources (409) * @example * // Basic deletion * await client.models.delete('123'); * console.log('Model deleted successfully'); * * @example * // Safe deletion with confirmation * async function safeDeleteModel(id) { * try { * // First verify the model exists * const model = await client.models.get(id); * console.log(`Deleting model: ${model.data.attributes.name}`); * * // Perform deletion * await client.models.delete(id); * console.log('Model deleted successfully'); * return true; * } catch (error) { * if (error.response?.status === 404) { * console.log('Model not found - may already be deleted'); * return false; * } * throw error; * } * } * * @example * // Bulk deletion with error handling * async function deleteMultipleModels(modelIds) { * const results = []; * * for (const id of modelIds) { * try { * await client.models.delete(id); * results.push({ id, status: 'deleted' }); * } catch (error) { * let errorType = 'unknown'; * if (error.response?.status === 404) errorType = 'not_found'; * else if (error.response?.status === 409) errorType = 'has_dependencies'; * * results.push({ * id, * status: 'error', * error: errorType, * message: error.message * }); * } * } * * return results; * } * * @example * // Error handling for model deletion * try { * await client.models.delete('123'); * } catch (error) { * if (error.response?.status === 404) { * console.log('Model not found - may already be deleted'); * } else if (error.response?.status === 403) { * console.log('Permission denied - cannot delete model'); * } else if (error.response?.status === 409) { * console.log('Cannot delete - model is referenced by configurations or assets'); * console.log('Remove dependent resources first, then retry deletion'); * } else { * console.log('Deletion failed:', error.message); * } * } * @see * {@link Manufacturers#list} - List manufacturers related to models * {@link Manufacturers#get} - Get specific manufacturer details */ delete(id: string): Promise; }