UNPKG

@pinecone-database/pinecone

Version:

This is the official Node.js SDK for [Pinecone](https://www.pinecone.io), written in TypeScript.

180 lines • 8.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.waitUntilIndexIsReady = exports.createIndex = void 0; const db_control_1 = require("../pinecone-generated-ts-fetch/db_control"); const utils_1 = require("../utils"); const types_1 = require("./types"); const errors_1 = require("../errors"); const validateObjectProperties_1 = require("../utils/validateObjectProperties"); const CreateIndexOptionsProperties = [ 'spec', 'name', 'dimension', 'metric', 'deletionProtection', 'waitUntilReady', 'suppressConflicts', 'tags', 'vectorType', ]; const CreateIndexSpecProperties = ['serverless', 'pod']; const CreateIndexServerlessSpecProperties = [ 'cloud', 'region', ]; const CreateIndexPodSpecProperties = [ 'environment', 'replicas', 'shards', 'podType', 'pods', 'metadataConfig', 'sourceCollection', ]; const createIndex = (api) => { return async (options) => { if (!options) { throw new errors_1.PineconeArgumentError('You must pass an object with required properties (`name`, `dimension`, `spec`) to create an index.'); } // If metric is not specified for a sparse index, default to dotproduct if (options.vectorType && options.vectorType.toLowerCase() === 'sparse') { if (!options.metric) { options.metric = db_control_1.IndexModelMetricEnum.Dotproduct; } } else { // If metric is not specified for a dense index, default to cosine if (!options.metric) { options.metric = db_control_1.IndexModelMetricEnum.Cosine; } } validateCreateIndexRequest(options); try { const createResponse = await api.createIndex({ createIndexRequest: options, }); if (options.waitUntilReady) { return await (0, exports.waitUntilIndexIsReady)(api, options.name); } return createResponse; } catch (e) { if (!(options.suppressConflicts && e instanceof Error && e.name === 'PineconeConflictError')) { throw e; } } }; }; exports.createIndex = createIndex; const waitUntilIndexIsReady = async (api, indexName, seconds = 0) => { try { const indexDescription = await api.describeIndex({ indexName }); if (!indexDescription.status?.ready) { await new Promise((r) => setTimeout(r, 1000)); return await (0, exports.waitUntilIndexIsReady)(api, indexName, seconds + 1); } else { (0, utils_1.debugLog)(`Index ${indexName} is ready after ${seconds}`); return indexDescription; } } catch (e) { const err = await (0, errors_1.handleApiError)(e, async (_, rawMessageText) => `Error creating index ${indexName}: ${rawMessageText}`); throw err; } }; exports.waitUntilIndexIsReady = waitUntilIndexIsReady; const validateCreateIndexRequest = (options) => { // validate options properties if (options) { (0, validateObjectProperties_1.ValidateObjectProperties)(options, CreateIndexOptionsProperties); } if (!options.name) { throw new errors_1.PineconeArgumentError('You must pass a non-empty string for `name` in order to create an index.'); } if (options.dimension && options.dimension <= 0) { throw new errors_1.PineconeArgumentError('You must pass a positive integer for `dimension` in order to create an index.'); } // validate options.spec properties if (!options.spec) { throw new errors_1.PineconeArgumentError('You must pass a `pods` or `serverless` `spec` object in order to create an index.'); } if (options.spec) { (0, validateObjectProperties_1.ValidateObjectProperties)(options.spec, CreateIndexSpecProperties); } // validate options.metric if (options.metric && !Object.values(db_control_1.IndexModelMetricEnum).includes(options.metric)) { { throw new errors_1.PineconeArgumentError(`Invalid metric value: ${options.metric}. Valid values are: 'cosine', 'euclidean', or 'dotproduct.'`); } } // validate options.spec.serverless properties if serverless spec is passed if (options.spec.serverless) { (0, validateObjectProperties_1.ValidateObjectProperties)(options.spec.serverless, CreateIndexServerlessSpecProperties); // extract and default vectorType to 'dense' if not specified const vectorType = options.vectorType ? options.vectorType.toLowerCase() : 'dense'; if (vectorType !== 'dense' && vectorType !== 'sparse') { throw new errors_1.PineconeArgumentError('Invalid `vectorType` value. Valid values are `dense` or `sparse`.'); } // sparse indexes must have a metric of 'dotproduct' and no dimension if (vectorType == 'sparse') { if (options.dimension && options.dimension > 0) { throw new errors_1.PineconeArgumentError('Sparse indexes cannot have a `dimension`.'); } if (options.metric && options.metric !== 'dotproduct') { throw new errors_1.PineconeArgumentError('Sparse indexes must have a `metric` of `dotproduct`.'); } } else if (vectorType == 'dense') { // dense indexes must have a dimension if (!options.dimension || options.dimension <= 0) { throw new errors_1.PineconeArgumentError('You must pass a positive `dimension` when creating a dense index.'); } } // validate serverless cloud & region if (!options.spec.serverless.cloud) { throw new errors_1.PineconeArgumentError('You must pass a `cloud` for the serverless `spec` object in order to create an index.'); } if (options.spec.serverless.cloud && !Object.values(db_control_1.ServerlessSpecCloudEnum).includes(options.spec.serverless.cloud)) { throw new errors_1.PineconeArgumentError(`Invalid cloud value: ${options.spec.serverless.cloud}. Valid values are: ${Object.values(db_control_1.ServerlessSpecCloudEnum).join(', ')}.`); } if (!options.spec.serverless.region) { throw new errors_1.PineconeArgumentError('You must pass a `region` for the serverless `spec` object in order to create an index.'); } } else if (options.spec.pod) { // validate options.spec.pod properties if pod spec is passed (0, validateObjectProperties_1.ValidateObjectProperties)(options.spec.pod, CreateIndexPodSpecProperties); if (!options.spec.pod.environment) { throw new errors_1.PineconeArgumentError('You must pass an `environment` for the pod `spec` object in order to create an index.'); } // pod indexes must have a dimension if (!options.dimension || options.dimension <= 0) { throw new errors_1.PineconeArgumentError('You must pass a positive `dimension` when creating a dense index.'); } // pod indexes must be dense const vectorType = 'dense'; if (options.vectorType && options.vectorType.toLowerCase() !== vectorType) { throw new errors_1.PineconeArgumentError('Pod indexes must have a `vectorType` of `dense`.'); } if (!options.spec.pod.podType) { throw new errors_1.PineconeArgumentError('You must pass a `podType` for the pod `spec` object in order to create an index.'); } if (options.spec.pod.replicas && options.spec.pod.replicas <= 0) { throw new errors_1.PineconeArgumentError('You must pass a positive integer for `replicas` in order to create an index.'); } if (options.spec.pod.pods && options.spec.pod.pods <= 0) { throw new errors_1.PineconeArgumentError('You must pass a positive integer for `pods` in order to create an index.'); } if (!types_1.ValidPodTypes.includes(options.spec.pod.podType)) { throw new errors_1.PineconeArgumentError(`Invalid pod type: ${options.spec.pod.podType}. Valid values are: ${types_1.ValidPodTypes.join(', ')}.`); } } }; //# sourceMappingURL=createIndex.js.map