{"version":3,"sources":["../../../src/vectorsearch/vector_search/query_public_endpoint.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n  FindNeighborsResponse,\n  INumericRestriction,\n  IRestriction,\n} from './types';\n\ninterface QueryPublicEndpointParams {\n  featureVector: number[];\n  neighborCount: number;\n  accessToken: string;\n  projectId: string;\n  location: string;\n  indexEndpointId: string;\n  publicDomainName: string;\n  projectNumber: string;\n  deployedIndexId: string;\n  restricts?: IRestriction[];\n  numericRestricts?: INumericRestriction[];\n}\n/**\n * Queries a public index endpoint to find neighbors for a given feature vector.\n *\n * This function sends a request to a specified public endpoint to find neighbors\n * for a given feature vector using the provided parameters.\n *\n * @param {QueryPublicEndpointParams} params - The parameters required to query the public endpoint.\n * @param {number[]} params.featureVector - The feature vector for which to find neighbors.\n * @param {number} params.neighborCount - The number of neighbors to retrieve.\n * @param {string} params.accessToken - The access token for authorization.\n * @param {string} params.projectId - The ID of the Google Cloud project.\n * @param {string} params.location - The location of the index endpoint.\n * @param {string} params.indexEndpointId - The ID of the index endpoint.\n * @param {string} params.publicDomainName - The domain name of the public endpoint.\n * @param {string} params.projectNumber - The project number.\n * @param {string} params.deployedIndexId - The ID of the deployed index.\n * @returns {Promise<FindNeighborsResponse>} - The response from the public endpoint.\n */\nexport async function queryPublicEndpoint(\n  params: QueryPublicEndpointParams\n): Promise<FindNeighborsResponse> {\n  const {\n    featureVector,\n    neighborCount,\n    accessToken,\n    indexEndpointId,\n    publicDomainName,\n    projectNumber,\n    deployedIndexId,\n    location,\n    restricts,\n    numericRestricts,\n  } = params;\n  const url = new URL(\n    `https://${publicDomainName}/v1/projects/${projectNumber}/locations/${location}/indexEndpoints/${indexEndpointId}:findNeighbors`\n  );\n\n  const requestBody = {\n    deployed_index_id: deployedIndexId,\n    queries: [\n      {\n        datapoint: {\n          datapoint_id: '0',\n          feature_vector: featureVector,\n          restricts:\n            restricts?.map((r) => ({\n              namespace: r.namespace,\n              allow_list: r.allowList,\n              deny_list: r.denyList,\n            })) || [],\n          numeric_restricts:\n            numericRestricts?.map((nr) => {\n              const newNR: Record<string, unknown> = {\n                namespace: nr.namespace,\n              };\n              // Exactly one of these should be set in a valid request.\n              // If there are more or less, vector search will complain\n              // and we can just pass the error on, rather than randomly\n              // selecting exactly one of them here (as that would be difficult\n              // to debug for the user)\n              if (nr.valueInt !== undefined) {\n                newNR.value_int = nr.valueInt;\n              }\n              if (nr.valueFloat !== undefined) {\n                newNR.value_float = nr.valueFloat;\n              }\n              if (nr.valueDouble !== undefined) {\n                newNR.value_double = nr.valueDouble;\n              }\n              newNR.op = nr.op;\n              return newNR;\n            }) || [],\n        },\n        neighbor_count: neighborCount,\n      },\n    ],\n  };\n\n  const response = await fetch(url, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      Authorization: `Bearer ${accessToken}`,\n    },\n    body: JSON.stringify(requestBody),\n  });\n\n  if (!response.ok) {\n    const errMsg = (await response.json()).error?.message || '';\n    throw new Error(`Error querying index: ${response.statusText}. ${errMsg}`);\n  }\n  return (await response.json()) as FindNeighborsResponse;\n}\n"],"mappings":"AAqDA,eAAsB,oBACpB,QACgC;AAChC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,MAAM,IAAI;AAAA,IACd,WAAW,gBAAgB,gBAAgB,aAAa,cAAc,QAAQ,mBAAmB,eAAe;AAAA,EAClH;AAEA,QAAM,cAAc;AAAA,IAClB,mBAAmB;AAAA,IACnB,SAAS;AAAA,MACP;AAAA,QACE,WAAW;AAAA,UACT,cAAc;AAAA,UACd,gBAAgB;AAAA,UAChB,WACE,WAAW,IAAI,CAAC,OAAO;AAAA,YACrB,WAAW,EAAE;AAAA,YACb,YAAY,EAAE;AAAA,YACd,WAAW,EAAE;AAAA,UACf,EAAE,KAAK,CAAC;AAAA,UACV,mBACE,kBAAkB,IAAI,CAAC,OAAO;AAC5B,kBAAM,QAAiC;AAAA,cACrC,WAAW,GAAG;AAAA,YAChB;AAMA,gBAAI,GAAG,aAAa,QAAW;AAC7B,oBAAM,YAAY,GAAG;AAAA,YACvB;AACA,gBAAI,GAAG,eAAe,QAAW;AAC/B,oBAAM,cAAc,GAAG;AAAA,YACzB;AACA,gBAAI,GAAG,gBAAgB,QAAW;AAChC,oBAAM,eAAe,GAAG;AAAA,YAC1B;AACA,kBAAM,KAAK,GAAG;AACd,mBAAO;AAAA,UACT,CAAC,KAAK,CAAC;AAAA,QACX;AAAA,QACA,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,WAAW;AAAA,IACtC;AAAA,IACA,MAAM,KAAK,UAAU,WAAW;AAAA,EAClC,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,UAAU,MAAM,SAAS,KAAK,GAAG,OAAO,WAAW;AACzD,UAAM,IAAI,MAAM,yBAAyB,SAAS,UAAU,KAAK,MAAM,EAAE;AAAA,EAC3E;AACA,SAAQ,MAAM,SAAS,KAAK;AAC9B;","names":[]}