diff --git a/.github/workflows/_node-ci.yml b/.github/workflows/_node-ci.yml new file mode 100644 index 0000000..ceda0d6 --- /dev/null +++ b/.github/workflows/_node-ci.yml @@ -0,0 +1,67 @@ +name: Common CI for Node.js projects + +on: + workflow_call: + inputs: + image_name: + description: The name of the image to build + required: true + type: string + + image_registry: + description: The registry to push the image to + required: true + type: string + + image_push: + description: Whether to push the image to the registry + required: true + type: boolean + + release_version: + description: Release version + default: dev + type: string + +jobs: + build-image: + name: Build Image + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: set up QEMU + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 + with: + platforms: linux/amd64,linux/arm64 + + - name: Login Container Registry + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Docker meta + id: meta + uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 + with: + images: ${{ inputs.image_registry }}/${{ inputs.image_name }} + tags: | + type=ref,event=pr + type=raw,value=${{ inputs.release_version }},enable=${{ inputs.image_push && inputs.release_version != 'dev' }} + + - name: Build and push + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ inputs.image_push }} + tags: ${{ steps.meta.outputs.tags }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 69b3976..891200d 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - main + - feat/ci-pr types: - opened - synchronize @@ -20,38 +21,10 @@ concurrency: jobs: # build: - build-image: - name: Build Image - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - name: set up QEMU - uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - with: - platforms: linux/amd64,linux/arm64 - - - name: Login Container Registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Build image - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: false - cache-from: type=gha - cache-to: type=gha,mode=max - build-args: | - VERSION=XXX - COMMIT_ID=${{ github.sha }} - secrets: | - NPM_TOKEN=${{ secrets.NPM_TOKEN }} + call-node-ci: + name: Call Node CI + uses: ./.github/workflows/_node-ci.yml + with: + image_name: ${{ github.repository }} + image_registry: ghcr.io + image_push: false diff --git a/Dockerfile b/Dockerfile index 83695cf..3e71459 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,11 +43,14 @@ WORKDIR /app # Copy only the production dependencies COPY --from=build /app/dist /app/dist -COPY --from=build /app/package.json /app/package.json -COPY --from=build /app/package-lock.json /app/package-lock.json +COPY --from=build /app/node_modules /app/node_modules # Set environment variables ENV NODE_ENV=production +# Set port +ARG PORT=4242 +ENV PORT=${PORT} + # Default command for production -CMD ["/nodejs/bin/node", "/app/dist/app.js"] +CMD ["dist/app.js"] diff --git a/package-lock.json b/package-lock.json index aa187d9..b13f006 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,27 +9,43 @@ "version": "0.0.8", "license": "ISC", "dependencies": { - "@modelcontextprotocol/sdk": "^1.11.0", - "ajv": "^8.17.1", + "@modelcontextprotocol/sdk": "^1.15.0", + "@opentelemetry/auto-instrumentations-node": "^0.62.1", + "@opentelemetry/exporter-trace-otlp-http": "^0.203.0", + "@opentelemetry/resources": "^2.0.1", + "@opentelemetry/sdk-node": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.36.0", + "@opentelemetry/winston-transport": "^0.14.1", "algoliasearch": "^5.23.4", - "commander": "^13.1.0", - "open": "^10.1.0", + "envalid": "^8.0.0", + "express": "^5.1.0", + "helmet": "^8.1.0", + "morgan": "^1.10.1", + "winston": "^3.17.0", "zod": "^3.24.4" }, "devDependencies": { "@eslint/js": "^9.24.0", - "@modelcontextprotocol/inspector": "^0.15.0", - "@types/node": "^22.14.0", + "@modelcontextprotocol/inspector": "^0.16.6", + "@types/cors": "^2.8.17", + "@types/express": "^5.0.0", + "@types/morgan": "^1.9.9", + "@types/node": "^22.10.2", + "@types/supertest": "^6.0.3", "@vitest/coverage-v8": "^3.1.1", - "bun": "^1.2.9", "eslint": "^9.24.0", "eslint-config-prettier": "^10.1.2", "globals": "^16.0.0", "msw": "^2.7.4", + "nodemon": "^3.1.10", "prettier": "^3.5.3", - "typescript": "^5.8.3", + "supertest": "^7.1.4", + "ts-node": "^10.9.2", + "tsc-alias": "^1.8.16", + "tsconfig-paths": "^4.2.0", + "typescript": "5.9.2", "typescript-eslint": "^8.30.1", - "vitest": "^3.1.1" + "vitest": "^3.0.5" }, "engines": { "node": ">=22.0.0" @@ -318,6 +334,15 @@ "tough-cookie": "^4.1.4" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -331,6 +356,17 @@ "node": ">=12" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "license": "MIT", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", @@ -757,9 +793,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.0.tgz", - "integrity": "sha512-WhCn7Z7TauhBtmzhvKpoQs0Wwb/kBcy4CwpuI0/eEIr2Lx2auxmulAzLr91wVZJaz47iUZdkXOK7WlAfxGKCnA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, "license": "MIT", "dependencies": { @@ -860,23 +896,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -890,13 +909,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, "node_modules/@eslint/js": { "version": "9.24.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", @@ -945,9 +957,9 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", - "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", "dev": true, "license": "MIT", "dependencies": { @@ -955,24 +967,24 @@ } }, "node_modules/@floating-ui/dom": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", - "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", "dev": true, "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.2", + "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", - "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", "dev": true, "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.2" + "@floating-ui/dom": "^1.7.4" }, "peerDependencies": { "react": ">=16.8.0", @@ -986,6 +998,37 @@ "dev": true, "license": "MIT" }, + "node_modules/@grpc/grpc-js": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz", + "integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1322,10 +1365,20 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/@modelcontextprotocol/inspector": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector/-/inspector-0.15.0.tgz", - "integrity": "sha512-PN1R7InR48Y6wU8s/vHWc0KOYAjlYQkgCpjUQsNFB078ebdv+empkMI6d1Gg+UIRx8mTrwtbBgv0A6ookGG+0w==", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector/-/inspector-0.16.6.tgz", + "integrity": "sha512-6x6dzTf8MV6z/XIdzr/4EMK4elMn1XUzTJHxczsBePLg1G5VNAM/4g5abNFIB9bzuxJ/1VH8016Vv6S7sj/24Q==", "dev": true, "license": "MIT", "workspaces": [ @@ -1334,29 +1387,32 @@ "cli" ], "dependencies": { - "@modelcontextprotocol/inspector-cli": "^0.15.0", - "@modelcontextprotocol/inspector-client": "^0.15.0", - "@modelcontextprotocol/inspector-server": "^0.15.0", - "@modelcontextprotocol/sdk": "^1.13.1", - "concurrently": "^9.0.1", - "open": "^10.1.0", - "shell-quote": "^1.8.2", + "@modelcontextprotocol/inspector-cli": "^0.16.6", + "@modelcontextprotocol/inspector-client": "^0.16.6", + "@modelcontextprotocol/inspector-server": "^0.16.6", + "@modelcontextprotocol/sdk": "^1.17.5", + "concurrently": "^9.2.0", + "open": "^10.2.0", + "shell-quote": "^1.8.3", "spawn-rx": "^5.1.2", "ts-node": "^10.9.2", - "zod": "^3.23.8" + "zod": "^3.25.76" }, "bin": { "mcp-inspector": "cli/build/cli.js" + }, + "engines": { + "node": ">=22.7.5" } }, "node_modules/@modelcontextprotocol/inspector-cli": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector-cli/-/inspector-cli-0.15.0.tgz", - "integrity": "sha512-mZxRqxYub6qFi3oypLI63yCm9TAxlTO8asE9FeAU4+HFlvKxQrujcfpckcWjqGKhZ0uVH1YUE+VwDx70nz+I5w==", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector-cli/-/inspector-cli-0.16.6.tgz", + "integrity": "sha512-28RAaGoN9XgKYvl8kOo9wTHBrLp5Th+biTt5mNGUzowMdcoG/FpI8mHROIhcgDyp+kj0SYR5fmwcb6GIxBnjUw==", "dev": true, "license": "MIT", "dependencies": { - "@modelcontextprotocol/sdk": "^1.13.1", + "@modelcontextprotocol/sdk": "^1.17.5", "commander": "^13.1.0", "spawn-rx": "^5.1.2" }, @@ -1365,13 +1421,13 @@ } }, "node_modules/@modelcontextprotocol/inspector-client": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector-client/-/inspector-client-0.15.0.tgz", - "integrity": "sha512-zIKxvp5HX1yE+kPOhI42/TVNuM9/RYEizdVmlpov7H38Mg9DeN9DptHYrsVLy8ZEJD1XFAu/eLl+ZtS3ceANNg==", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector-client/-/inspector-client-0.16.6.tgz", + "integrity": "sha512-2dwB0OXI02PTTsECCTIsB9DkERImIrsTAuZW6LlfUojtQMLI5NpuUID4Y4LaYPcdGnxkkkR1eddrPTsuzgabvg==", "dev": true, "license": "MIT", "dependencies": { - "@modelcontextprotocol/sdk": "^1.13.1", + "@modelcontextprotocol/sdk": "^1.17.5", "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-dialog": "^1.1.3", "@radix-ui/react-icons": "^1.3.0", @@ -1394,37 +1450,12 @@ "react-simple-code-editor": "^0.14.1", "serve-handler": "^6.1.6", "tailwind-merge": "^2.5.3", - "tailwindcss-animate": "^1.0.7", - "zod": "^3.23.8" + "zod": "^3.25.76" }, "bin": { "mcp-inspector-client": "bin/start.js" } }, - "node_modules/@modelcontextprotocol/inspector-client/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@modelcontextprotocol/inspector-client/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, "node_modules/@modelcontextprotocol/inspector-client/node_modules/pkce-challenge": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-4.1.0.tgz", @@ -1436,26 +1467,26 @@ } }, "node_modules/@modelcontextprotocol/inspector-server": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector-server/-/inspector-server-0.15.0.tgz", - "integrity": "sha512-x1qtDEUeSHURtBH1/WN30NX7O/Imb3u2IoY+T2YCf4mGiB24eo4hEudiZmnuKSDGwDs4BAj2keiFeL3/EwkH9w==", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/inspector-server/-/inspector-server-0.16.6.tgz", + "integrity": "sha512-BkE/4K2Y8ZcXK/cGBucG+rLTcTIUAaSyQabxqh0p+ErhkJDmepDvI+63OqQnauWUJydXPZYtBQyHppL4JN7RGw==", "dev": true, "license": "MIT", "dependencies": { - "@modelcontextprotocol/sdk": "^1.13.1", + "@modelcontextprotocol/sdk": "^1.17.5", "cors": "^2.8.5", "express": "^5.1.0", "ws": "^8.18.0", - "zod": "^3.23.8" + "zod": "^3.25.76" }, "bin": { "mcp-inspector-server": "build/index.js" } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.13.3.tgz", - "integrity": "sha512-bGwA78F/U5G2jrnsdRkPY3IwIwZeWUEfb5o764b79lb0rJmMT76TLwKhdNZOWakOQtedYefwIR4emisEMvInKA==", + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.17.5.tgz", + "integrity": "sha512-QakrKIGniGuRVfWBdMsDea/dx1PNE739QJ7gCM41s9q+qaCYTHCdsIBXQVVXry3mfWAiaM9kT22Hyz53Uw8mfg==", "license": "MIT", "dependencies": { "ajv": "^6.12.6", @@ -1475,28 +1506,6 @@ "node": ">=18" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, "node_modules/@mswjs/interceptors": { "version": "0.37.6", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.6.tgz", @@ -1515,6 +1524,19 @@ "node": ">=18" } }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1578,159 +1600,1908 @@ "dev": true, "license": "MIT" }, - "node_modules/@oven/bun-darwin-aarch64": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.2.9.tgz", - "integrity": "sha512-A190s6twmzNE6KGVoUxEDQaSebXUY0bTYXUwnAqTWpE/LxkkDZ7VLhDKxe0nqiDOWStSTTXpfZcFp5T2D6c8iQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/@oven/bun-darwin-x64": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.2.9.tgz", - "integrity": "sha512-s3unmXAPwhaZYpPWoiHb5X6Kxgl7sehf8AB+VQFr85WCaOZoqZhsFl4GzC9G06cdt8pBLxo6l5lI9bi4YmRFBw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/@oven/bun-darwin-x64-baseline": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.2.9.tgz", - "integrity": "sha512-iCqYZJ1lLlAirNoidH/nAx8Rg8WXoUs/8BjkMaCfjJG99YXSU00LH39MuxJQDRKlgKnd7IWQNJAluPuuB7j1Tw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@opentelemetry/auto-instrumentations-node": { + "version": "0.62.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/auto-instrumentations-node/-/auto-instrumentations-node-0.62.2.tgz", + "integrity": "sha512-Ipe6X7ddrCiRsuewyTU83IvKiSFT4piqmv9z8Ovg1E7v98pdTj1pUE6sDrHV50zl7/ypd+cONBgt+EYSZu4u9Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/instrumentation-amqplib": "^0.50.0", + "@opentelemetry/instrumentation-aws-lambda": "^0.54.1", + "@opentelemetry/instrumentation-aws-sdk": "^0.58.0", + "@opentelemetry/instrumentation-bunyan": "^0.49.0", + "@opentelemetry/instrumentation-cassandra-driver": "^0.49.0", + "@opentelemetry/instrumentation-connect": "^0.47.0", + "@opentelemetry/instrumentation-cucumber": "^0.19.0", + "@opentelemetry/instrumentation-dataloader": "^0.21.1", + "@opentelemetry/instrumentation-dns": "^0.47.0", + "@opentelemetry/instrumentation-express": "^0.52.0", + "@opentelemetry/instrumentation-fastify": "^0.48.0", + "@opentelemetry/instrumentation-fs": "^0.23.0", + "@opentelemetry/instrumentation-generic-pool": "^0.47.0", + "@opentelemetry/instrumentation-graphql": "^0.51.0", + "@opentelemetry/instrumentation-grpc": "^0.203.0", + "@opentelemetry/instrumentation-hapi": "^0.50.0", + "@opentelemetry/instrumentation-http": "^0.203.0", + "@opentelemetry/instrumentation-ioredis": "^0.51.0", + "@opentelemetry/instrumentation-kafkajs": "^0.13.0", + "@opentelemetry/instrumentation-knex": "^0.48.0", + "@opentelemetry/instrumentation-koa": "^0.51.0", + "@opentelemetry/instrumentation-lru-memoizer": "^0.48.0", + "@opentelemetry/instrumentation-memcached": "^0.47.0", + "@opentelemetry/instrumentation-mongodb": "^0.56.0", + "@opentelemetry/instrumentation-mongoose": "^0.50.0", + "@opentelemetry/instrumentation-mysql": "^0.49.0", + "@opentelemetry/instrumentation-mysql2": "^0.50.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.49.0", + "@opentelemetry/instrumentation-net": "^0.47.0", + "@opentelemetry/instrumentation-oracledb": "^0.29.0", + "@opentelemetry/instrumentation-pg": "^0.56.1", + "@opentelemetry/instrumentation-pino": "^0.50.1", + "@opentelemetry/instrumentation-redis": "^0.52.0", + "@opentelemetry/instrumentation-restify": "^0.49.0", + "@opentelemetry/instrumentation-router": "^0.48.0", + "@opentelemetry/instrumentation-runtime-node": "^0.17.1", + "@opentelemetry/instrumentation-socket.io": "^0.50.0", + "@opentelemetry/instrumentation-tedious": "^0.22.0", + "@opentelemetry/instrumentation-undici": "^0.14.0", + "@opentelemetry/instrumentation-winston": "^0.48.1", + "@opentelemetry/resource-detector-alibaba-cloud": "^0.31.3", + "@opentelemetry/resource-detector-aws": "^2.3.0", + "@opentelemetry/resource-detector-azure": "^0.10.0", + "@opentelemetry/resource-detector-container": "^0.7.3", + "@opentelemetry/resource-detector-gcp": "^0.37.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/sdk-node": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.4.1", + "@opentelemetry/core": "^2.0.0" + } }, - "node_modules/@oven/bun-linux-aarch64": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.2.9.tgz", - "integrity": "sha512-tyf8g3H+/CLyItST7/UKkLpRawViaBwroOAOVo0KB4fK+d8WZTDZdHJK9reifs7wwOWhgNrARakPV3d7Sj01HQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.0.1.tgz", + "integrity": "sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } }, - "node_modules/@oven/bun-linux-aarch64-musl": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.2.9.tgz", - "integrity": "sha512-IUA/5zR0FqWF6vwg7Ad9gFRbuu/uqGtoNyuq+mcfxZI1HhG0LKWVciuyXe0rpQ9Eno0YkEjcr2z271NTDyeNWg==", - "cpu": [ - "aarch64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "node_modules/@opentelemetry/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.1.0.tgz", + "integrity": "sha512-RMEtHsxJs/GiHHxYT58IY57UXAQTuUnZVco6ymDEqTNlJKTimM4qPUPVe8InNFyBjhHBEAx4k3Q8LtNayBsbUQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } }, - "node_modules/@oven/bun-linux-x64": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.2.9.tgz", - "integrity": "sha512-FoTJmItasGca/GDpwsBPTCbzxGngSgtbXxuV8JjQYDr4YeoRGt6Upc3FH7UV9uBBwxRRYb9sdvyqge1u+Pf/rQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "node_modules/@opentelemetry/exporter-logs-otlp-grpc": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.203.0.tgz", + "integrity": "sha512-g/2Y2noc/l96zmM+g0LdeuyYKINyBwN6FJySoU15LHPLcMN/1a0wNk2SegwKcxrRdE7Xsm7fkIR5n6XFe3QpPw==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/sdk-logs": "0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } }, - "node_modules/@oven/bun-linux-x64-baseline": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.2.9.tgz", - "integrity": "sha512-OSa6e8fCgNO8AtM6OL2Tgav+/DiJ5aRuzvAy4lLWQWkmGuzbCqLz/+nJqRrpfL6ALAFDg66ucx8GMa0w2bL4+g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "node_modules/@opentelemetry/exporter-logs-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } }, - "node_modules/@oven/bun-linux-x64-musl": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl/-/bun-linux-x64-musl-1.2.9.tgz", - "integrity": "sha512-xvoKSGzBCeTwNkLnkKlAv1xDw+HCACrUctMXx0eyWr0in/hcsG10QIfeCqec32xdunPLtOPSHv2H1CHO10LB0A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "node_modules/@opentelemetry/exporter-logs-otlp-http": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.203.0.tgz", + "integrity": "sha512-s0hys1ljqlMTbXx2XiplmMJg9wG570Z5lH7wMvrZX6lcODI56sG4HL03jklF63tBeyNwK2RV1/ntXGo3HgG4Qw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/sdk-logs": "0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } }, - "node_modules/@oven/bun-linux-x64-musl-baseline": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl-baseline/-/bun-linux-x64-musl-baseline-1.2.9.tgz", - "integrity": "sha512-/ZEVcz3RQIazmT9825t9+/rckUOz8vSosq4FylE4JCWmTJtQWnrbCYbC7VwdO8XLcf8iFuCM+o0pXkMKch/4iw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "node_modules/@opentelemetry/exporter-logs-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } }, - "node_modules/@oven/bun-windows-x64": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.2.9.tgz", - "integrity": "sha512-jAcIc+NBBzw0VQc+mx/Xwqiv3aubGiXMakYUcr40HpTiuokVn0Kl/U4SKt0IQ12l1wxBpfd6nIwKaXH6Yb3p8w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "node_modules/@opentelemetry/exporter-logs-otlp-proto": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.203.0.tgz", + "integrity": "sha512-nl/7S91MXn5R1aIzoWtMKGvqxgJgepB/sH9qW0rZvZtabnsjbf8OQ1uSx3yogtvLr0GzwD596nQKz2fV7q2RBw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-logs": "0.203.0", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-proto/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-proto/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.203.0.tgz", + "integrity": "sha512-FCCj9nVZpumPQSEI57jRAA89hQQgONuoC35Lt+rayWY/mzCAc6BQT7RFyFaZKJ2B7IQ8kYjOCPsF/HGFWjdQkQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/exporter-metrics-otlp-http": "0.203.0", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-metrics": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.203.0.tgz", + "integrity": "sha512-HFSW10y8lY6BTZecGNpV3GpoSy7eaO0Z6GATwZasnT4bEsILp8UJXNG5OmEsz4SdwCSYvyCbTJdNbZP3/8LGCQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-metrics": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.203.0.tgz", + "integrity": "sha512-OZnhyd9npU7QbyuHXFEPVm3LnjZYifuKpT3kTnF84mXeEQ84pJJZgyLBpU4FSkSwUkt/zbMyNAI7y5+jYTWGIg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/exporter-metrics-otlp-http": "0.203.0", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-metrics": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-prometheus": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.203.0.tgz", + "integrity": "sha512-2jLuNuw5m4sUj/SncDf/mFPabUxMZmmYetx5RKIMIQyPnl6G6ooFzfeE8aXNRf8YD1ZXNlCnRPcISxjveGJHNg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-metrics": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-prometheus/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-prometheus/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.203.0.tgz", + "integrity": "sha512-322coOTf81bm6cAA8+ML6A+m4r2xTCdmAZzGNTboPXRzhwPt4JEmovsFAs+grpdarObd68msOJ9FfH3jxM6wqA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.203.0.tgz", + "integrity": "sha512-ZDiaswNYo0yq/cy1bBLJFe691izEJ6IgNmkjm4C6kE9ub/OMQqDXORx2D2j8fzTBTxONyzusbaZlqtfmyqURPw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.203.0.tgz", + "integrity": "sha512-1xwNTJ86L0aJmWRwENCJlH4LULMG2sOXWIVw+Szta4fkqKVY50Eo4HoVKKq6U9QEytrWCr8+zjw0q/ZOeXpcAQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-2.0.1.tgz", + "integrity": "sha512-a9eeyHIipfdxzCfc2XPrE+/TI3wmrZUDFtG2RRXHSbZZULAny7SyybSvaDvS77a7iib5MPiAvluwVvbGTsHxsw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.50.0.tgz", + "integrity": "sha512-kwNs/itehHG/qaQBcVrLNcvXVPW0I4FCOVtw3LHMLdYIqD7GJ6Yv2nX+a4YHjzbzIeRYj8iyMp0Bl7tlkidq5w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-aws-lambda": { + "version": "0.54.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-lambda/-/instrumentation-aws-lambda-0.54.1.tgz", + "integrity": "sha512-qm8pGSAM1mXk7unbrGktWWGJc6IFI58ZsaHJ+i420Fp5VO3Vf7GglIgaXTS8CKBrVB4LHFj3NvzJg31PtsAQcA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/aws-lambda": "8.10.152" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-aws-sdk": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.58.0.tgz", + "integrity": "sha512-9vFH7gU686dsAeLMCkqUj9y0MQZ1xrTtStSpNV2UaGWtDnRjJrAdJLu9Y545oKEaDTeVaob4UflyZvvpZnw3Xw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-bunyan": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-bunyan/-/instrumentation-bunyan-0.49.0.tgz", + "integrity": "sha512-ky5Am1y6s3Ex/3RygHxB/ZXNG07zPfg9Z6Ora+vfeKcr/+I6CJbWXWhSBJor3gFgKN3RvC11UWVURnmDpBS6Pg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.203.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@types/bunyan": "1.8.11" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-cassandra-driver": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cassandra-driver/-/instrumentation-cassandra-driver-0.49.0.tgz", + "integrity": "sha512-BNIvqldmLkeikfI5w5Rlm9vG5NnQexfPoxOgEMzfDVOEF+vS6351I6DzWLLgWWR9CNF/jQJJi/lr6am2DLp0Rw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.47.0.tgz", + "integrity": "sha512-pjenvjR6+PMRb6/4X85L4OtkQCootgb/Jzh/l/Utu3SJHBid1F+gk9sTGU2FWuhhEfV6P7MZ7BmCdHXQjgJ42g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-cucumber": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cucumber/-/instrumentation-cucumber-0.19.0.tgz", + "integrity": "sha512-99ms8kQWRuPt5lkDqbJJzD+7Tq5TMUlBZki4SA2h6CgK4ncX+tyep9XFY1e+XTBLJIWmuFMGbWqBLJ4fSKIQNQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.21.1.tgz", + "integrity": "sha512-hNAm/bwGawLM8VDjKR0ZUDJ/D/qKR3s6lA5NV+btNaPVm2acqhPcT47l2uCVi+70lng2mywfQncor9v8/ykuyw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dns": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dns/-/instrumentation-dns-0.47.0.tgz", + "integrity": "sha512-775fOnewWkTF4iXMGKgwvOGqEmPrU1PZpXjjqvTrEErYBJe7Fz1WlEeUStHepyKOdld7Ghv7TOF/kE3QDctvrg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.52.0.tgz", + "integrity": "sha512-W7pizN0Wh1/cbNhhTf7C62NpyYw7VfCFTYg0DYieSTrtPBT1vmoSZei19wfKLnrMsz3sHayCg0HxCVL2c+cz5w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fastify": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.48.0.tgz", + "integrity": "sha512-3zQlE/DoVfVH6/ycuTv7vtR/xib6WOa0aLFfslYcvE62z0htRu/ot8PV/zmMZfnzpTQj8S/4ULv36R6UIbpJIg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.23.0.tgz", + "integrity": "sha512-Puan+QopWHA/KNYvDfOZN6M/JtF6buXEyD934vrb8WhsX1/FuM7OtoMlQyIqAadnE8FqqDL4KDPiEfCQH6pQcQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.47.0.tgz", + "integrity": "sha512-UfHqf3zYK+CwDwEtTjaD12uUqGGTswZ7ofLBEdQ4sEJp9GHSSJMQ2hT3pgBxyKADzUdoxQAv/7NqvL42ZI+Qbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.51.0.tgz", + "integrity": "sha512-LchkOu9X5DrXAnPI1+Z06h/EH/zC7D6sA86hhPrk3evLlsJTz0grPrkL/yUJM9Ty0CL/y2HSvmWQCjbJEz/ADg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-grpc": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.203.0.tgz", + "integrity": "sha512-Qmjx2iwccHYRLoE4RFS46CvQE9JG9Pfeae4EPaNZjvIuJxb/pZa2R9VWzRlTehqQWpAvto/dGhtkw8Tv+o0LTg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "0.203.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.50.0.tgz", + "integrity": "sha512-5xGusXOFQXKacrZmDbpHQzqYD1gIkrMWuwvlrEPkYOsjUqGUjl1HbxCsn5Y9bUXOCgP1Lj6A4PcKt1UiJ2MujA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.203.0.tgz", + "integrity": "sha512-y3uQAcCOAwnO6vEuNVocmpVzG3PER6/YZqbPbbffDdJ9te5NkHEkfSMNzlC3+v7KlE+WinPGc3N7MR30G1HY2g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/instrumentation": "0.203.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.51.0.tgz", + "integrity": "sha512-9IUws0XWCb80NovS+17eONXsw1ZJbHwYYMXiwsfR9TSurkLV5UNbRSKb9URHO+K+pIJILy9wCxvyiOneMr91Ig==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/redis-common": "^0.38.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.13.0.tgz", + "integrity": "sha512-FPQyJsREOaGH64hcxlzTsIEQC4DYANgTwHjiB7z9lldmvua1LRMVn3/FfBlzXoqF179B0VGYviz6rn75E9wsDw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.48.0.tgz", + "integrity": "sha512-V5wuaBPv/lwGxuHjC6Na2JFRjtPgstw19jTFl1B1b6zvaX8zVDYUDaR5hL7glnQtUSCMktPttQsgK4dhXpddcA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.51.0.tgz", + "integrity": "sha512-XNLWeMTMG1/EkQBbgPYzCeBD0cwOrfnn8ao4hWgLv0fNCFQu1kCsJYygz2cvKuCs340RlnG4i321hX7R8gj3Rg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.48.0.tgz", + "integrity": "sha512-KUW29wfMlTPX1wFz+NNrmE7IzN7NWZDrmFWHM/VJcmFEuQGnnBuTIdsP55CnBDxKgQ/qqYFp4udQFNtjeFosPw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-memcached": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-memcached/-/instrumentation-memcached-0.47.0.tgz", + "integrity": "sha512-vXDs/l4hlWy1IepPG1S6aYiIZn+tZDI24kAzwKKJmR2QEJRL84PojmALAEJGazIOLl/VdcCPZdMb0U2K0VzojA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/memcached": "^2.2.6" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.56.0.tgz", + "integrity": "sha512-YG5IXUUmxX3Md2buVMvxm9NWlKADrnavI36hbJsihqqvBGsWnIfguf0rUP5Srr0pfPqhQjUP+agLMsvu0GmUpA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.50.0.tgz", + "integrity": "sha512-Am8pk1Ct951r4qCiqkBcGmPIgGhoDiFcRtqPSLbJrUZqEPUsigjtMjoWDRLG1Ki1NHgOF7D0H7d+suWz1AAizw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.49.0.tgz", + "integrity": "sha512-QU9IUNqNsrlfE3dJkZnFHqLjlndiU39ll/YAAEvWE40sGOCi9AtOF6rmEGzJ1IswoZ3oyePV7q2MP8SrhJfVAA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/mysql": "2.15.27" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.50.0.tgz", + "integrity": "sha512-PoOMpmq73rOIE3nlTNLf3B1SyNYGsp7QXHYKmeTZZnJ2Ou7/fdURuOhWOI0e6QZ5gSem18IR1sJi6GOULBQJ9g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.41.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-nestjs-core": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.49.0.tgz", + "integrity": "sha512-1R/JFwdmZIk3T/cPOCkVvFQeKYzbbUvDxVH3ShXamUwBlGkdEu5QJitlRMyVNZaHkKZKWgYrBarGQsqcboYgaw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-net": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-net/-/instrumentation-net-0.47.0.tgz", + "integrity": "sha512-csoJ++Njpf7C09JH+0HNGenuNbDZBqO1rFhMRo6s0rAmJwNh9zY3M/urzptmKlqbKnf4eH0s+CKHy/+M8fbFsQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-oracledb": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-oracledb/-/instrumentation-oracledb-0.29.0.tgz", + "integrity": "sha512-2aHLiJdkyiUbooIUm7FaZf+O4jyqEl+RfFpgud1dxT87QeeYM216wi+xaMNzsb5yKtRBqbA3qeHBCyenYrOZwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/oracledb": "6.5.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.56.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.56.1.tgz", + "integrity": "sha512-0/PiHDPVaLdcXNw6Gqb3JBdMxComMEwh444X8glwiynJKJHRTR49+l2cqJfoOVzB8Sl1XRl3Yaqw6aDi3s8e9w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.0", + "@types/pg": "8.15.5", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pino": { + "version": "0.50.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pino/-/instrumentation-pino-0.50.1.tgz", + "integrity": "sha512-pBbvuWiHA9iAumAuQ0SKYOXK7NRlbnVTf/qBV0nMdRnxBPrc/GZTbh0f7Y59gZfYsbCLhXLL1oRTEnS+PwS3CA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.203.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.52.0.tgz", + "integrity": "sha512-R8Y7cCZlJ2Vl31S2i7bl5SqyC/aul54ski4wCFip/Tp9WGtLK1xVATi2rwy2wkc8ZCtjdEe9eEVR+QFG6gGZxg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/redis-common": "^0.38.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-restify": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-restify/-/instrumentation-restify-0.49.0.tgz", + "integrity": "sha512-tsGZZhS4mVZH7omYxw5jpsrD3LhWizqWc0PYtAnzpFUvL5ZINHE+cm57bssTQ2AK/GtZMxu9LktwCvIIf3dSmw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-router": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-router/-/instrumentation-router-0.48.0.tgz", + "integrity": "sha512-Wixrc8CchuJojXpaS/dCQjFOMc+3OEil1H21G+WLYQb8PcKt5kzW9zDBT19nyjjQOx/D/uHPfgbrT+Dc7cfJ9w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-runtime-node": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-runtime-node/-/instrumentation-runtime-node-0.17.1.tgz", + "integrity": "sha512-c1FlAk+bB2uF9a8YneGmNPTl7c/xVaan4mmWvbkWcOmH/ipKqR1LaKUlz/BMzLrJLjho1EJlG2NrS2w2Arg+nw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-socket.io": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.50.0.tgz", + "integrity": "sha512-6JN6lnKN9ZuZtZdMQIR+no1qHzQvXSZUsNe3sSWMgqmNRyEXuDUWBIyKKeG0oHRHtR4xE4QhJyD4D5kKRPWZFA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.22.0.tgz", + "integrity": "sha512-XrrNSUCyEjH1ax9t+Uo6lv0S2FCCykcF7hSxBMxKf7Xn0bPRxD3KyFUZy25aQXzbbbUHhtdxj3r2h88SfEM3aA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.14.0.tgz", + "integrity": "sha512-2HN+7ztxAReXuxzrtA3WboAKlfP5OsPA57KQn2AdYZbJ3zeRPcLXyW4uO/jpLE6PLm0QRtmeGCmfYpqRlwgSwg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/instrumentation-winston": { + "version": "0.48.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-winston/-/instrumentation-winston-0.48.1.tgz", + "integrity": "sha512-XyOuVwdziirHHYlsw+BWrvdI/ymjwnexupKA787zQQ+D5upaE/tseZxjfQa7+t4+FdVLxHICaMTmkSD4yZHpzQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.203.0", + "@opentelemetry/instrumentation": "^0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.203.0.tgz", + "integrity": "sha512-Wbxf7k+87KyvxFr5D7uOiSq/vHXWommvdnNE7vECO3tAhsA2GfOlpWINCMWUEPdHZ7tCXxw6Epp3vgx3jU7llQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-transformer": "0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.203.0.tgz", + "integrity": "sha512-te0Ze1ueJF+N/UOFl5jElJW4U0pZXQ8QklgSfJ2linHN0JJsuaHG8IabEUi2iqxY8ZBDlSiz1Trfv5JcjWWWwQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.203.0.tgz", + "integrity": "sha512-Y8I6GgoCna0qDQ2W6GCRtaF24SnvqvA8OfeTi7fqigD23u8Jpb4R5KFv/pRvrlGagcCLICMIyh9wiejp4TXu/A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-logs": "0.203.0", + "@opentelemetry/sdk-metrics": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1", + "protobufjs": "^7.3.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-2.0.1.tgz", + "integrity": "sha512-Hc09CaQ8Tf5AGLmf449H726uRoBNGPBL4bjr7AnnUpzWMvhdn61F78z9qb6IqB737TffBsokGAK1XykFEZ1igw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.0.1.tgz", + "integrity": "sha512-7PMdPBmGVH2eQNb/AtSJizQNgeNTfh6jQFqys6lfhd6P4r+m/nTh3gKPPpaCXVdRQ+z93vfKk+4UGty390283w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.0.tgz", + "integrity": "sha512-4Wc0AWURII2cfXVVoZ6vDqK+s5n4K5IssdrlVrvGsx6OEOKdghKtJZqXAHWFiZv4nTDLH2/2fldjIHY8clMOjQ==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, + "node_modules/@opentelemetry/resource-detector-alibaba-cloud": { + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-alibaba-cloud/-/resource-detector-alibaba-cloud-0.31.3.tgz", + "integrity": "sha512-I556LHcLVsBXEgnbPgQISP/JezDt5OfpgOaJNR1iVJl202r+K145OSSOxnH5YOc/KvrydBD0FOE03F7x0xnVTw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-aws": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-aws/-/resource-detector-aws-2.3.0.tgz", + "integrity": "sha512-PkD/lyXG3B3REq1Y6imBLckljkJYXavtqGYSryAeJYvGOf5Ds3doR+BCGjmKeF6ObAtI5MtpBeUStTDtGtBsWA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-azure": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-azure/-/resource-detector-azure-0.10.0.tgz", + "integrity": "sha512-5cNAiyPBg53Uxe/CW7hsCq8HiKNAUGH+gi65TtgpzSR9bhJG4AEbuZhbJDFwe97tn2ifAD1JTkbc/OFuaaFWbA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-container": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-container/-/resource-detector-container-0.7.3.tgz", + "integrity": "sha512-SK+xUFw6DKYbQniaGmIFsFxAZsr8RpRSRWxKi5/ZJAoqqPnjcyGI/SeUx8zzPk4XLO084zyM4pRHgir0hRTaSQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-gcp": { + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-gcp/-/resource-detector-gcp-0.37.0.tgz", + "integrity": "sha512-LGpJBECIMsVKhiulb4nxUw++m1oF4EiDDPmFGW2aqYaAF0oUvJNv8Z/55CAzcZ7SxvlTgUwzewXDBsuCup7iqw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "gcp-metadata": "^6.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.1.0.tgz", + "integrity": "sha512-1CJjf3LCvoefUOgegxi8h6r4B/wLSzInyhGP2UmIBYNlo4Qk5CZ73e1eEyWmfXvFtm1ybkmfb2DqWvspsYLrWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.1.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.203.0.tgz", + "integrity": "sha512-vM2+rPq0Vi3nYA5akQD2f3QwossDnTDLvKbea6u/A2NZ3XDkPxMfo/PNrDoXhDUD/0pPo2CdH5ce/thn9K0kLw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.0.1.tgz", + "integrity": "sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } }, - "node_modules/@oven/bun-windows-x64-baseline": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.2.9.tgz", - "integrity": "sha512-PhcIgGkcJwylH5MgRidgnMfIELT7a7ikOIbjFkkMTVetm3K1j4U1K2aH9paBrWVs6K57088E2CItCM0rvQd1QQ==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.203.0.tgz", + "integrity": "sha512-zRMvrZGhGVMvAbbjiNQW3eKzW/073dlrSiAKPVWmkoQzah9wfynpVPeL55f9fVIm0GaBxTLcPeukWGy0/Wj7KQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/exporter-logs-otlp-grpc": "0.203.0", + "@opentelemetry/exporter-logs-otlp-http": "0.203.0", + "@opentelemetry/exporter-logs-otlp-proto": "0.203.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.203.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.203.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.203.0", + "@opentelemetry/exporter-prometheus": "0.203.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.203.0", + "@opentelemetry/exporter-trace-otlp-http": "0.203.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.203.0", + "@opentelemetry/exporter-zipkin": "2.0.1", + "@opentelemetry/instrumentation": "0.203.0", + "@opentelemetry/propagator-b3": "2.0.1", + "@opentelemetry/propagator-jaeger": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-logs": "0.203.0", + "@opentelemetry/sdk-metrics": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1", + "@opentelemetry/sdk-trace-node": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.0.1.tgz", + "integrity": "sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.0.1.tgz", + "integrity": "sha512-UhdbPF19pMpBtCWYP5lHbTogLWx9N0EBxtdagvkn5YtsAnCBZzL7SjktG+ZmupRgifsHMjwUaCCaVmqGfSADmA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "2.0.1", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.37.0.tgz", + "integrity": "sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.0.tgz", + "integrity": "sha512-pmzXctVbEERbqSfiAgdes9Y63xjoOyXcD7B6IXBkVb+vbM7M9U98mn33nGXxPf4dfYR0M+vhcKRZmbSJ7HfqFA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@opentelemetry/winston-transport": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/winston-transport/-/winston-transport-0.14.1.tgz", + "integrity": "sha512-GQmZocc/orXmoLsDOyqKyaZrNQkp2U3748vFO+DfvgP0/438/0hD4b1o4keBVzrSPafbgtPPY7nCTuyZaFi5rA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.203.0", + "winston-transport": "4.*" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", + "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@noble/hashes": "^1.1.5" + } }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -1743,6 +3514,70 @@ "node": ">=14" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", @@ -1751,9 +3586,9 @@ "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", - "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", "dev": true, "license": "MIT" }, @@ -1782,16 +3617,16 @@ } }, "node_modules/@radix-ui/react-checkbox": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.2.tgz", - "integrity": "sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", @@ -1872,21 +3707,21 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", - "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -1925,13 +3760,13 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", - "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", @@ -1953,9 +3788,9 @@ } }, "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", - "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2048,22 +3883,22 @@ } }, "node_modules/@radix-ui/react-popover": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.14.tgz", - "integrity": "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -2086,9 +3921,9 @@ } }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", - "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", "dev": true, "license": "MIT", "dependencies": { @@ -2144,9 +3979,9 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", - "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2193,13 +4028,13 @@ } }, "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz", - "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", @@ -2225,23 +4060,23 @@ } }, "node_modules/@radix-ui/react-select": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.5.tgz", - "integrity": "sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", "dev": true, "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", @@ -2288,19 +4123,19 @@ } }, "node_modules/@radix-ui/react-tabs": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.12.tgz", - "integrity": "sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", + "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { @@ -2319,19 +4154,19 @@ } }, "node_modules/@radix-ui/react-toast": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.14.tgz", - "integrity": "sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz", + "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -2354,20 +4189,20 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz", - "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -2864,42 +4699,233 @@ "dev": true, "license": "MIT" }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/aws-lambda": { + "version": "8.10.152", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.152.tgz", + "integrity": "sha512-soT/c2gYBnT5ygwiHPmd9a1bftj462NWVk2tKCc1PYHSIacB2UwbTS2zYG4jzag1mRDuzg/OjtxQjQ2NKRB6Rw==", + "license": "MIT" + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bunyan": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.11.tgz", + "integrity": "sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", + "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz", + "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz", + "integrity": "sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/memcached": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/@types/memcached/-/memcached-2.2.10.tgz", + "integrity": "sha512-AM9smvZN55Gzs2wRrqeMHVP7KE8KWgCJO/XL5yCly2xF6EKa4YlbpK+cLSAH4NG/Ah64HrlegmGqW8kYws7Vxg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/methods": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", + "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/morgan": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz", + "integrity": "sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mysql": { + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", + "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/oracledb": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@types/oracledb/-/oracledb-6.5.2.tgz", + "integrity": "sha512-kK1eBS/Adeyis+3OlBDMeQQuasIDLUYXsi2T15ccNJ0iyUpQ4xDF7svFu3+bGVrI0CMBUclPciz+lsQR3JX3TQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/pg": { + "version": "8.15.5", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.5.tgz", + "integrity": "sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "dev": true, "license": "MIT" }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, "license": "MIT" }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } }, - "node_modules/@types/node": { - "version": "22.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", - "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==", + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" } }, "node_modules/@types/statuses": { @@ -2909,6 +4935,39 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/superagent": { + "version": "8.1.9", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", + "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookiejar": "^2.1.5", + "@types/methods": "^1.1.4", + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/supertest": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.3.tgz", + "integrity": "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/methods": "^1.1.4", + "@types/superagent": "^8.1.0" + } + }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -2916,22 +4975,28 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.30.1.tgz", - "integrity": "sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.42.0.tgz", + "integrity": "sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/type-utils": "8.30.1", - "@typescript-eslint/utils": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", + "@typescript-eslint/scope-manager": "8.42.0", + "@typescript-eslint/type-utils": "8.42.0", + "@typescript-eslint/utils": "8.42.0", + "@typescript-eslint/visitor-keys": "8.42.0", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2941,22 +5006,32 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "@typescript-eslint/parser": "^8.42.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz", - "integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.42.0.tgz", + "integrity": "sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", + "@typescript-eslint/scope-manager": "8.42.0", + "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/typescript-estree": "8.42.0", + "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4" }, "engines": { @@ -2968,38 +5043,78 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.42.0.tgz", + "integrity": "sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.42.0", + "@typescript-eslint/types": "^8.42.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz", - "integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.42.0.tgz", + "integrity": "sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1" + "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/visitor-keys": "8.42.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.42.0.tgz", + "integrity": "sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==", + "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.30.1.tgz", - "integrity": "sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.42.0.tgz", + "integrity": "sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/utils": "8.30.1", + "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/typescript-estree": "8.42.0", + "@typescript-eslint/utils": "8.42.0", "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3010,13 +5125,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz", - "integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.42.0.tgz", + "integrity": "sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==", "dev": true, "license": "MIT", "engines": { @@ -3028,20 +5143,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz", - "integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.42.0.tgz", + "integrity": "sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", + "@typescript-eslint/project-service": "8.42.0", + "@typescript-eslint/tsconfig-utils": "8.42.0", + "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3051,13 +5168,13 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3081,16 +5198,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.30.1.tgz", - "integrity": "sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.42.0.tgz", + "integrity": "sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.42.0", + "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/typescript-estree": "8.42.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3101,18 +5218,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz", - "integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.42.0.tgz", + "integrity": "sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.30.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.42.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3285,7 +5402,6 @@ "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -3294,6 +5410,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -3317,16 +5442,25 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "funding": { "type": "github", @@ -3389,7 +5523,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3399,7 +5532,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3411,6 +5543,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -3438,6 +5584,23 @@ "node": ">=10" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -3448,6 +5611,19 @@ "node": ">=12" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3455,6 +5631,46 @@ "dev": true, "license": "MIT" }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/body-parser": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", @@ -3499,45 +5715,11 @@ "node": ">=8" } }, - "node_modules/bun": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/bun/-/bun-1.2.9.tgz", - "integrity": "sha512-4l1MnbCk2aEDeyJPs8+St6XsVPwkQvq7XTHG501e7pdFOWvWCy9shfxsHtBwYzmT82gdvx9//AL4qStYfYMO4Q==", - "cpu": [ - "arm64", - "x64", - "aarch64" - ], - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "os": [ - "darwin", - "linux", - "win32" - ], - "bin": { - "bun": "bin/bun.exe", - "bunx": "bin/bun.exe" - }, - "optionalDependencies": { - "@oven/bun-darwin-aarch64": "1.2.9", - "@oven/bun-darwin-x64": "1.2.9", - "@oven/bun-darwin-x64-baseline": "1.2.9", - "@oven/bun-linux-aarch64": "1.2.9", - "@oven/bun-linux-aarch64-musl": "1.2.9", - "@oven/bun-linux-x64": "1.2.9", - "@oven/bun-linux-x64-baseline": "1.2.9", - "@oven/bun-linux-x64-musl": "1.2.9", - "@oven/bun-linux-x64-musl-baseline": "1.2.9", - "@oven/bun-windows-x64": "1.2.9", - "@oven/bun-windows-x64-baseline": "1.2.9" - } - }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, "license": "MIT", "dependencies": { "run-applescript": "^7.0.0" @@ -3651,6 +5833,50 @@ "node": ">= 16" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, "node_modules/class-variance-authority": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", @@ -3678,7 +5904,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -3706,45 +5931,112 @@ "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "^1.1.1", - "@radix-ui/react-dialog": "^1.1.6", - "@radix-ui/react-id": "^1.1.0", - "@radix-ui/react-primitive": "^2.0.2" - }, - "peerDependencies": { - "react": "^18 || ^19 || ^19.0.0-rc", - "react-dom": "^18 || ^19 || ^19.0.0-rc" + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "license": "MIT", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">= 0.8" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, "node_modules/commander": { "version": "13.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3753,19 +6045,18 @@ "license": "MIT" }, "node_modules/concurrently": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.2.tgz", - "integrity": "sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.1.2", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" }, "bin": { "conc": "dist/bin/concurrently.js", @@ -3833,6 +6124,13 @@ "node": ">=6.6.0" } }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true, + "license": "MIT" + }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -3905,6 +6203,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", @@ -3921,6 +6220,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -3933,6 +6233,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -3941,6 +6242,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3957,6 +6268,17 @@ "dev": true, "license": "MIT" }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3967,6 +6289,19 @@ "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3998,7 +6333,12 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, + "license": "MIT" + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", "license": "MIT" }, "node_modules/encodeurl": { @@ -4010,6 +6350,18 @@ "node": ">= 0.8" } }, + "node_modules/envalid": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/envalid/-/envalid-8.1.0.tgz", + "integrity": "sha512-OT6+qVhKVyCidaGoXflb2iK1tC8pd0OV2Q+v9n33wNhUJ+lus+rJobUj4vJaQBPxPZ0vYrPGuxdrenyCAIJcow==", + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -4047,6 +6399,22 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", @@ -4092,7 +6460,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4209,9 +6576,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4221,30 +6588,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", @@ -4416,6 +6759,12 @@ "express": "^4.11 || 5 || ^5.0.0-beta.1" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4465,21 +6814,12 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" }, "node_modules/fastq": { "version": "1.19.1", @@ -4491,6 +6831,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -4572,6 +6918,12 @@ "dev": true, "license": "ISC" }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -4589,6 +6941,64 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/formidable": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", + "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", + "dezalgo": "^1.0.4", + "once": "^1.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -4598,6 +7008,12 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -4631,11 +7047,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -4688,6 +7133,19 @@ "node": ">= 0.4" } }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -4761,6 +7219,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -4812,6 +7300,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -4831,6 +7335,15 @@ "dev": true, "license": "MIT" }, + "node_modules/helmet": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.1.0.tgz", + "integrity": "sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -4854,6 +7367,19 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -4876,6 +7402,13 @@ "node": ">= 4" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -4893,6 +7426,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-in-the-middle": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.14.2.tgz", + "integrity": "sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4909,19 +7454,54 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, "engines": { - "node": ">= 0.10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-docker": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, "license": "MIT", "bin": { "is-docker": "cli.js" @@ -4947,7 +7527,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4970,6 +7549,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, "license": "MIT", "dependencies": { "is-docker": "^3.0.0" @@ -5007,10 +7587,23 @@ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-wsl": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" @@ -5129,6 +7722,15 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -5137,9 +7739,9 @@ "license": "MIT" }, "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -5149,6 +7751,19 @@ "dev": true, "license": "MIT" }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5159,6 +7774,12 @@ "json-buffer": "3.0.1" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5189,11 +7810,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, "node_modules/lodash.merge": { @@ -5203,6 +7823,29 @@ "dev": true, "license": "MIT" }, + "node_modules/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "license": "MIT", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5325,6 +7968,16 @@ "node": ">= 8" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -5339,6 +7992,19 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", @@ -5373,6 +8039,16 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -5383,6 +8059,55 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, + "node_modules/morgan": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", + "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", + "license": "MIT", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.1.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5451,6 +8176,20 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -5486,6 +8225,88 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemon": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", + "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5519,6 +8340,15 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5528,16 +8358,26 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/open": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", - "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, "license": "MIT", "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", - "is-wsl": "^3.1.0" + "wsl-utils": "^0.1.0" }, "engines": { "node": ">=18" @@ -5658,6 +8498,12 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -5684,6 +8530,16 @@ "node": ">=16" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -5701,6 +8557,37 @@ "node": ">= 14.16" } }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5730,33 +8617,85 @@ "node": ">=16.20.0" } }, - "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/plimit-lit": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.6.1.tgz", + "integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "queue-lit": "^1.5.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "xtend": "^4.0.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=0.10.0" } }, "node_modules/prelude-ls": { @@ -5795,6 +8734,30 @@ "node": ">=6" } }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -5821,6 +8784,13 @@ "url": "https://github.com/sponsors/lupomontero" } }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5852,6 +8822,16 @@ "dev": true, "license": "MIT" }, + "node_modules/queue-lit": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz", + "integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -6007,23 +8987,54 @@ } } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8.6.0" } }, "node_modules/requires-port": { @@ -6033,6 +9044,26 @@ "dev": true, "license": "MIT" }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -6043,6 +9074,16 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -6114,6 +9155,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6176,6 +9218,15 @@ ], "license": "MIT" }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6346,9 +9397,9 @@ } }, "node_modules/shell-quote": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", - "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "dev": true, "license": "MIT", "engines": { @@ -6450,6 +9501,38 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -6471,6 +9554,15 @@ "rxjs": "^7.8.1" } }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -6501,11 +9593,19 @@ "dev": true, "license": "MIT" }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -6536,7 +9636,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -6559,6 +9658,16 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -6572,6 +9681,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/superagent": { + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.3.tgz", + "integrity": "sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.1", + "cookiejar": "^2.1.4", + "debug": "^4.3.7", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.4", + "formidable": "^3.5.4", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supertest": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.4.tgz", + "integrity": "sha512-tjLPs7dVyqgItVFirHYqe2T+MfWc2VOBQ8QFKKbWTA3PU7liZR8zoSpAi/C1k1ilm9RsXIKYf197oap9wXGVYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "methods": "^1.1.2", + "superagent": "^10.2.3" + }, + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6585,6 +9729,18 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tailwind-merge": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", @@ -6596,24 +9752,6 @@ "url": "https://github.com/sponsors/dcastil" } }, - "node_modules/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/tailwindcss-animate": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", - "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" - } - }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", @@ -6655,6 +9793,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -6766,6 +9910,16 @@ "node": ">=0.6" } }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -6782,6 +9936,12 @@ "node": ">=6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -6792,6 +9952,15 @@ "tree-kill": "cli.js" } }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -6849,11 +10018,57 @@ } } }, + "node_modules/tsc-alias": { + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.16.tgz", + "integrity": "sha512-QjCyu55NFyRSBAl6+MTFwplpFcnm2Pq01rR/uxfqJoLMm6X3O14KEGtaSDZpJYaE1bJBGDjD0eSuiIWPe2T58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "get-tsconfig": "^4.10.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + }, + "engines": { + "node": ">=16.20.2" + } + }, + "node_modules/tsc-alias/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, "node_modules/type-check": { @@ -6897,9 +10112,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6911,15 +10126,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.30.1.tgz", - "integrity": "sha512-D7lC0kcehVH7Mb26MRQi64LMyRJsj3dToJxM1+JVTl53DQSV5/7oUGWQLcKl1C1KnoVHxMMU2FNQMffr7F3Row==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.42.0.tgz", + "integrity": "sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.30.1", - "@typescript-eslint/parser": "8.30.1", - "@typescript-eslint/utils": "8.30.1" + "@typescript-eslint/eslint-plugin": "8.42.0", + "@typescript-eslint/parser": "8.42.0", + "@typescript-eslint/typescript-estree": "8.42.0", + "@typescript-eslint/utils": "8.42.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6930,14 +10146,20 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, "license": "MIT" }, "node_modules/universalify": { @@ -7024,6 +10246,25 @@ } } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -7236,6 +10477,22 @@ } } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7268,6 +10525,42 @@ "node": ">=8" } }, + "node_modules/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.7.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.9.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "license": "MIT", + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -7282,7 +10575,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -7343,11 +10635,35 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -7357,7 +10673,6 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -7376,7 +10691,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -7419,9 +10733,9 @@ } }, "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index 936e3af..c1718e0 100644 --- a/package.json +++ b/package.json @@ -1,42 +1,58 @@ { "name": "algolia-mcp", "version": "0.0.8", - "main": "index.js", + "main": "app.js", "scripts": { - "start": "node --experimental-strip-types --no-warnings=ExperimentalWarnings src/app.ts", + "dev": "NODE_ENV=development OTEL_SDK_DISABLED=true ts-node -T src/app.ts", + "start": "NODE_ENV=production node --enable-source-maps dist/app.js", "type-check": "tsc --noEmit", "lint": "eslint --ext .ts src", "test": "vitest", - "build": "bun build ./src/app.ts --compile", + "build": "rm -rf dist && tsc", "debug": "mcp-inspector npm start" }, - "type": "module", "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { - "@modelcontextprotocol/sdk": "^1.11.0", - "ajv": "^8.17.1", + "@modelcontextprotocol/sdk": "^1.15.0", + "@opentelemetry/auto-instrumentations-node": "^0.62.1", + "@opentelemetry/exporter-trace-otlp-http": "^0.203.0", + "@opentelemetry/resources": "^2.0.1", + "@opentelemetry/sdk-node": "^0.203.0", + "@opentelemetry/semantic-conventions": "^1.36.0", + "@opentelemetry/winston-transport": "^0.14.1", "algoliasearch": "^5.23.4", - "commander": "^13.1.0", - "open": "^10.1.0", + "envalid": "^8.0.0", + "express": "^5.1.0", + "helmet": "^8.1.0", + "morgan": "^1.10.1", + "winston": "^3.17.0", "zod": "^3.24.4" }, "devDependencies": { "@eslint/js": "^9.24.0", - "@modelcontextprotocol/inspector": "^0.15.0", - "@types/node": "^22.14.0", + "@modelcontextprotocol/inspector": "^0.16.6", + "@types/cors": "^2.8.17", + "@types/express": "^5.0.0", + "@types/morgan": "^1.9.9", + "@types/node": "^22.10.2", + "@types/supertest": "^6.0.3", "@vitest/coverage-v8": "^3.1.1", - "bun": "^1.2.9", "eslint": "^9.24.0", "eslint-config-prettier": "^10.1.2", "globals": "^16.0.0", "msw": "^2.7.4", + "nodemon": "^3.1.10", "prettier": "^3.5.3", - "typescript": "^5.8.3", + "supertest": "^7.1.4", + "ts-node": "^10.9.2", + "tsc-alias": "^1.8.16", + "tsconfig-paths": "^4.2.0", + "typescript": "5.9.2", "typescript-eslint": "^8.30.1", - "vitest": "^3.1.1" + "vitest": "^3.0.5" }, "engines": { "node": ">=22.0.0" diff --git a/src/CustomMcpServer.ts b/src/CustomMcpServer.ts deleted file mode 100644 index aeceed5..0000000 --- a/src/CustomMcpServer.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Server } from "@modelcontextprotocol/sdk/server/index.js"; -import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js"; -import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; -import type { - CallToolResult as BaseCallToolResult, - ServerNotification, - ServerRequest, - Tool, -} from "@modelcontextprotocol/sdk/types.js"; -import { - CallToolRequestSchema, - ErrorCode, - ListToolsRequestSchema, - McpError, - type ToolAnnotations, -} from "@modelcontextprotocol/sdk/types.js"; -import { Ajv2020 as Ajv } from "ajv/dist/2020.js"; -import type { SomeJSONSchema } from "ajv/dist/types/json-schema.js"; - -export type InputJsonSchema = Partial; - -type CallToolResult = string | BaseCallToolResult; -type ToolCallback = - Args extends InputJsonSchema - ? ( - args: object, - extra: RequestHandlerExtra, - ) => CallToolResult | Promise - : ( - extra: RequestHandlerExtra, - ) => CallToolResult | Promise; - -export type ToolDefinition = { - name: string; - inputSchema: T; - description?: string; - annotations?: ToolAnnotations; - cb: ToolCallback; -}; - -function formatToolError(error: unknown): BaseCallToolResult { - return { - content: [ - { - type: "text", - text: error instanceof Error ? error.message : String(error), - }, - ], - isError: true, - }; -} - -function formatToolResult(result: CallToolResult): BaseCallToolResult { - if (typeof result === "string") { - return { - content: [{ type: "text", text: result }], - }; - } - - return result; -} - -export class CustomMcpServer { - private readonly server: Server; - private ajv: Ajv; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private tools: Record> = {}; - - constructor(...args: ConstructorParameters) { - this.ajv = new Ajv({ removeAdditional: true, strict: false }); - this.server = new Server(...args); - - this.server.assertCanSetRequestHandler(ListToolsRequestSchema.shape.method.value); - this.server.assertCanSetRequestHandler(CallToolRequestSchema.shape.method.value); - this.server.registerCapabilities({ tools: { listChanged: true } }); - - this.server.setRequestHandler(ListToolsRequestSchema, () => { - return { - tools: Object.values(this.tools).map((tool) => { - return { - name: tool.name, - description: tool.description, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - inputSchema: (tool.inputSchema as any) ?? { type: "object" }, - annotations: tool.annotations, - }; - }), - }; - }); - - this.server.setRequestHandler( - CallToolRequestSchema, - async (request, extra): Promise => { - const tool = this.tools[request.params.name]; - if (!tool) { - throw new McpError(ErrorCode.InvalidParams, `Tool ${request.params.name} not found`); - } - - if (tool.inputSchema) { - const validate = this.ajv.compile(tool.inputSchema); - const callbackArguments: Record = - structuredClone(request.params.arguments) ?? {}; - - if ( - "requestBody" in callbackArguments && - typeof callbackArguments.requestBody === "string" - ) { - callbackArguments.requestBody = JSON.parse(callbackArguments.requestBody); - } - - const isValid = validate(callbackArguments); - if (!isValid) { - throw new McpError( - ErrorCode.InvalidParams, - `Invalid arguments for tool ${request.params.name}: ${this.ajv.errorsText(validate.errors)}`, - ); - } - - try { - const cb = tool.cb as unknown as ToolCallback; - return formatToolResult(await cb(callbackArguments, extra)); - } catch (error) { - return formatToolError(error); - } - } - - try { - const cb = tool.cb as unknown as ToolCallback; - return formatToolResult(await cb(extra)); - } catch (error) { - return formatToolError(error); - } - }, - ); - } - - async connect(transport: Transport): Promise { - return await this.server.connect(transport); - } - - async close(): Promise { - await this.server.close(); - } - - tool(options: ToolDefinition) { - if (this.tools[options.name]) { - throw new Error(`Tool with name ${options.name} already exists`); - } - - this.tools[options.name] = options; - this.sendToolListChanged(); - } - - private sendToolListChanged() { - if (this.server.transport) { - this.server.sendToolListChanged(); - } - } -} diff --git a/src/DashboardApi.ts b/src/DashboardApi.ts deleted file mode 100644 index 6f20245..0000000 --- a/src/DashboardApi.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { algoliasearch } from "algoliasearch"; -import z from "zod"; -import type { AppStateManager } from "./appState.ts"; -import { refreshToken } from "./authentication.ts"; -import { CONFIG } from "./config.ts"; - -import type { Acl } from "algoliasearch"; - -export type DashboardApiOptions = { - baseUrl: string; - appState: AppStateManager; -}; - -const User = z.object({ - data: z.object({ - id: z.string(), - type: z.string(), - attributes: z.object({ - full_name: z.string(), - email: z.string(), - avatar: z - .object({ - "64": z.string().url(), - }) - .partial(), - updated_at: z.string().datetime(), - }), - }), -}); -type User = z.infer; - -const Application = z.object({ - id: z.string(), - type: z.string(), - attributes: z.object({ - name: z.string().nullable(), - is_owner: z.boolean(), - permissions: z.array(z.string()), - log_region: z.string(), - }), -}); - -const ShowApplication = z.object({ - data: Application, -}); - -const ApplicationList = z.object({ - data: z.array(Application), - meta: z.object({ - total_count: z.number(), - per_page: z.number(), - current_page: z.number(), - total_pages: z.number(), - }), -}); -type ApplicationList = z.infer; - -const CreateApiKeyResponse = z.object({ - data: z.object({ - id: z.string(), - type: z.string(), - attributes: z.object({ - // application_id: z.string(), - value: z.string(), - // acl: z.array(z.string()), - // description: z.string(), - // indexes: z.array(z.string()), - // max_hits_per_query: z.number().nullable(), - // max_queries_per_ip_per_hour: z.number().nullable(), - // query_parameters: z.string().nullable(), - // referers: z.array(z.string()), - // validity: z.number().nullable(), - // owner: z.object({ - // id: z.string(), - // type: z.string(), - // name: z.string(), - // }), - // rotated_at: z.string().datetime().nullable(), - // created_at: z.string().datetime(), - // updated_at: z.string().datetime(), - }), - }), -}); -type CreateApiKeyResponse = z.infer; - -export const REQUIRED_ACLS = [ - "search", - "listIndexes", - "analytics", - "usage", - "settings", - "addObject", - "editSettings", - "deleteObject", - "deleteIndex", -] satisfies Acl[]; - -export class DashboardApi { - #options: DashboardApiOptions; - - constructor(options: DashboardApiOptions) { - this.#options = options; - } - - async getUser(): Promise { - const response = await this.#makeRequest(`${this.#options.baseUrl}/1/user`); - return User.parse(await response.json()); - } - - async getApplication(applicationId: string) { - const response = await this.#makeRequest( - `${this.#options.baseUrl}/1/application/${encodeURIComponent(applicationId)}`, - ); - return ShowApplication.parse(await response.json()); - } - - async getApplications(): Promise { - const response = await this.#makeRequest(`${this.#options.baseUrl}/1/applications`); - return ApplicationList.parse(await response.json()); - } - - async getApiKey(applicationId: string): Promise { - const apiKeys = this.#options.appState.get("apiKeys"); - let apiKey: string | undefined = apiKeys[applicationId]; - - const shouldCreateApiKey = - !apiKey || !(await this.#hasRightAcl(applicationId, apiKey, REQUIRED_ACLS)); - - if (shouldCreateApiKey) { - apiKey = await this.#createApiKey(applicationId); - this.#options.appState.update({ - apiKeys: { ...apiKeys, [applicationId]: apiKey }, - }); - } - - return apiKey; - } - - async #hasRightAcl(appId: string, key: string, acl: Acl[]) { - const client = algoliasearch(appId, key); - const apiKey = await client.getApiKey({ key }); - - return acl.every((permission) => apiKey.acl.includes(permission)); - } - - async #createApiKey(applicationId: string): Promise { - const response = await this.#makeRequest( - `${this.#options.baseUrl}/1/applications/${applicationId}/api-keys`, - { - method: "POST", - body: JSON.stringify({ - acl: REQUIRED_ACLS, - description: "API Key created by and for the Algolia MCP Server", - }), - }, - ); - - const key = CreateApiKeyResponse.parse(await response.json()).data.attributes.value; - - const client = algoliasearch(applicationId, key); - await client.waitForApiKey({ key, operation: "add" }); - - return key; - } - - async #makeRequest(url: string, requestInit: RequestInit = {}): Promise { - const response = await fetch(url, { - ...requestInit, - headers: { - ...this.#baseHeaders, - ...requestInit.headers, - }, - }); - - if (await this.#isTokenExpiredResponse(response)) { - const refreshResponse = await refreshToken(this.#options.appState.get("refreshToken")); - await this.#options.appState.update({ - accessToken: refreshResponse.access_token, - refreshToken: refreshResponse.refresh_token, - }); - - return this.#makeRequest(url, requestInit); - } - - if (!response.ok) { - const body = await response.text(); - - throw new Error(`Error ${response.status}: ${body}`); - } - - return response; - } - - async #isTokenExpiredResponse(response: Response): Promise { - if (response.status !== 401) return false; - const body = await response.clone().text(); - return body.includes("The access token expired"); - } - - get #baseHeaders() { - return { - Authorization: `Bearer ${this.#options.appState.get("accessToken")}`, - "Content-Type": "application/json", - Accept: "application/vnd.api+json", - "User-Agent": CONFIG.userAgent, - }; - } -} diff --git a/src/app.ts b/src/app.ts index 02394d4..f1cbebb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,131 +1,39 @@ -import { Command } from "commander"; -import { type ListToolsOptions } from "./commands/list-tools.ts"; -import { ZodError } from "zod"; - -const program = new Command("algolia-mcp"); - -const DEFAULT_ALLOW_TOOLS = [ - // Dashboard API Tools - "getUserInfo", - "getApplications", - // Search - "listIndices", - "getSettings", - "searchSingleIndex", - "searchRules", - "searchSynonyms", - "saveObject", - "batch", - "multipleBatch", - "partialUpdateObject", - "deleteByQuery", - // Analytics - "getTopSearches", - "getTopHits", - "getNoResultsRate", - // AB Testing - "listABTests", - // Monitoring - "getClustersStatus", - "getIncidents", - // Ingestion - "listTransformations", - "listTasks", - "listDestinations", - "listSources", - // Usage - "retrieveMetricsRegistry", - "retrieveMetricsDaily", - "retrieveApplicationMetricsHourly", - // Collections - "listCollections", - "getCollection", - // Query Suggestions - "listQuerySuggestionsConfigs", - "getQuerySuggestionsConfig", - "createQuerySuggestionsConfig", - "updateQuerySuggestionsConfig", - "getQuerySuggestionConfigStatus", - "getQuerySuggestionLogFile", - // Custom settings - "setAttributesForFaceting", - "setCustomRanking", -]; -const ALLOW_TOOLS_OPTIONS_TUPLE = [ - "-t, --allow-tools ", - "Comma separated list of tool ids (or all)", - (val: string) => { - if (val.trim().toLowerCase() === "all") { - return []; - } - return val.split(",").map((tool) => tool.trim()); - }, - DEFAULT_ALLOW_TOOLS, -] as const; - -function formatErrorForCli(error: unknown): string { - if (error instanceof ZodError) { - return [...error.errors.map((e) => `- ${e.path.join(".") || ""}: ${e.message}`)].join( - "\n", - ); - } - - if (error instanceof Error) { - return error.message; - } - - return "Unknown error"; -} - -program - .command("start-server", { isDefault: true }) - .description("Starts the Algolia MCP server") - .option(...ALLOW_TOOLS_OPTIONS_TUPLE) - .option( - "--credentials ", - "Application ID and associated API key to use. Optional: the MCP will authenticate you if unspecified, giving you access to all your applications.", - (val) => { - const [applicationId, apiKey] = val.split(":"); - if (!applicationId || !apiKey) { - throw new Error("Invalid credentials format. Use applicationId:apiKey"); - } - return { applicationId, apiKey }; - }, - ) - .action(async (opts) => { +import "./telemetry"; +import express from "express"; +import { config } from "./config"; +import { logger } from "./logging"; +import { errorHandler } from "./middleware/errorHandler"; +import { loggerMiddleware } from "./middleware/loggerMiddleware"; +import { mcpServerRouter } from "./routes/mcpServerRouter"; + +const app = express(); +app.use(express.json()); +app.use(loggerMiddleware); +app.use(errorHandler); + +app.use("/mcp", mcpServerRouter()); + +app.use((_, res) => { + res.status(404).json({ error: "Not Found" }); +}); + +const server = app.listen(config.PORT, () => { + logger.info(`Server is running on port ${config.PORT}`); +}); + +server.on("error", (err) => { + logger.error(`Server encountered an error: ${err.message}`, { error: err }); +}); + +["SIGTERM", "SIGINT"].forEach((signal) => { + process.on(signal, () => { try { - const { startServer } = await import("./commands/start-server.ts"); - await startServer(opts); - } catch (error) { - console.error(formatErrorForCli(error)); - process.exit(1); + server.close(); + server.closeAllConnections(); + } catch (err) { + logger.error("Error closing server connections:", err); } }); +}); -program - .command("authenticate") - .description("Authenticate with Algolia") - .action(async () => { - const { authenticate } = await import("./commands/authenticate.ts"); - await authenticate(); - }); - -program - .command("logout") - .description("Remove all stored credentials") - .action(async () => { - const { logout } = await import("./commands/logout.ts"); - await logout(); - }); - -program - .command("list-tools") - .description("List available tools") - .option(...ALLOW_TOOLS_OPTIONS_TUPLE) - .option("--all", "List all tools") - .action(async (opts: ListToolsOptions) => { - const { listTools } = await import("./commands/list-tools.ts"); - await listTools(opts); - }); - -program.parse(); +export default app; diff --git a/src/appState.ts b/src/appState.ts deleted file mode 100644 index a6e9512..0000000 --- a/src/appState.ts +++ /dev/null @@ -1,66 +0,0 @@ -import fs, { mkdir } from "node:fs/promises"; -import path from "node:path"; - -export type AppState = { - accessToken: string; - refreshToken: string; - apiKeys: Record; -}; - -const DEFAULT_APP_STATE: AppState = { - accessToken: "", - refreshToken: "", - apiKeys: {}, -}; - -const home = process.env.HOME || process.env.USERPROFILE; - -if (!home) { - throw new Error("Could not find home directory"); -} - -const STORAGE_PATH = path.join(home, ".algolia-mcp"); -const APP_STATE_PATH = path.join(STORAGE_PATH, "state.json"); - -let SINGLETON: AppStateManager | null = null; - -export class AppStateManager { - #appState: AppState; - - static async load() { - if (!SINGLETON) { - await mkdir(STORAGE_PATH, { recursive: true }); - - let content: Partial = {}; - - try { - content = JSON.parse(await fs.readFile(APP_STATE_PATH, "utf-8")) as Partial; - } catch { - console.error(`Could not read app state file at ${APP_STATE_PATH}. Using default state.`); - } - - SINGLETON = new AppStateManager({ ...DEFAULT_APP_STATE, ...content }); - } - - return SINGLETON; - } - - static async reset(): Promise { - SINGLETON = null; - - await fs.rmdir(STORAGE_PATH, { recursive: true }); - } - - constructor(initialState: AppState) { - this.#appState = initialState; - } - - get(key: K): AppState[K] { - return this.#appState[key]; - } - - async update(update: Partial) { - this.#appState = { ...this.#appState, ...update }; - await fs.writeFile(APP_STATE_PATH, JSON.stringify(this.#appState)); - } -} diff --git a/src/authentication.ts b/src/authentication.ts deleted file mode 100644 index 5ab0d43..0000000 --- a/src/authentication.ts +++ /dev/null @@ -1,127 +0,0 @@ -import http from "node:http"; -import crypto from "node:crypto"; -import open from "open"; -import { CONFIG } from "./config.ts"; - -export type TokenResponse = { - access_token: string; - refresh_token: string; - expires_in: number; - token_type: string; - scope: string; -}; - -function generateCodeVerifier() { - return crypto.randomBytes(32).toString("base64url"); -} -function generateCodeChallenge(verifier: string) { - return crypto.createHash("sha256").update(verifier).digest("base64url"); -} - -async function getAccessToken( - authorizationCode: string, - codeVerifier: string, -): Promise { - const body = new URLSearchParams({ - client_id: CONFIG.clientId, - redirect_uri: CONFIG.redirectUri, - code: authorizationCode, - grant_type: "authorization_code", - code_verifier: codeVerifier, - }); - - const response = await fetch(CONFIG.tokenUrl, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body, - }); - if (!response.ok) { - throw new Error(`Failed to get access token: ${response.statusText}`); - } - - const token = await response.json(); - return token as TokenResponse; -} - -export async function refreshToken(refreshToken: string): Promise { - const body = new URLSearchParams({ - client_id: CONFIG.clientId, - redirect_uri: CONFIG.redirectUri, - refresh_token: refreshToken, - grant_type: "refresh_token", - }); - - const response = await fetch(CONFIG.tokenUrl, { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - body, - }); - - if (!response.ok) { - throw new Error(`Failed to refresh token: ${response.statusText}`); - } - - const token = await response.json(); - return token as TokenResponse; -} - -export async function authenticate() { - const codeVerifier = generateCodeVerifier(); - const codeChallenge = generateCodeChallenge(codeVerifier); - - const authorizationUrl = new URL(CONFIG.authEndpoint); - authorizationUrl.searchParams.set("scope", `public keys:manage applications:manage`); - authorizationUrl.searchParams.set("response_type", "code"); - authorizationUrl.searchParams.set("client_id", CONFIG.clientId); - authorizationUrl.searchParams.set("redirect_uri", CONFIG.redirectUri); - authorizationUrl.searchParams.set("code_challenge", codeChallenge); - authorizationUrl.searchParams.set("code_challenge_method", "S256"); - - let server: http.Server | null = null; - - try { - const authCodeResolvers = Promise.withResolvers(); - server = http.createServer((req, res) => { - if (!req.url) { - res.writeHead(400, { "Content-Type": "text/plain" }); - res.end("Bad Request"); - return; - } - - const url = new URL(req.url, `http://localhost`); - - switch (url.pathname) { - case "/callback": { - // Handle the callback with the authorization code - const authorizationCode = url.searchParams.get("code"); - - res.writeHead(200, { "Content-Type": "text/html" }); - res.end(""); - - if (!authorizationCode) { - authCodeResolvers.reject(new Error("Authorization code not found")); - } else { - authCodeResolvers.resolve(authorizationCode); - } - break; - } - default: { - res.writeHead(404, { "Content-Type": "text/plain" }); - res.end("Not Found"); - } - } - }); - - server.listen(CONFIG.port); - - await open(authorizationUrl.toString()); - - const authorizationCode = await authCodeResolvers.promise; - - return await getAccessToken(authorizationCode, codeVerifier); - } finally { - server?.close(); - } -} diff --git a/src/commands/authenticate.ts b/src/commands/authenticate.ts deleted file mode 100644 index df14a49..0000000 --- a/src/commands/authenticate.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { AppStateManager } from "../appState.ts"; -import { authenticate as authenticateFn } from "../authentication.ts"; - -export async function authenticate(): Promise { - console.log("Starting authentication..."); - const appState = await AppStateManager.load(); - - const token = await authenticateFn(); - - await appState.update({ - accessToken: token.access_token, - refreshToken: token.refresh_token, - }); - console.log("Authentication successful!"); -} diff --git a/src/commands/list-tools.ts b/src/commands/list-tools.ts deleted file mode 100644 index 70d8d84..0000000 --- a/src/commands/list-tools.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { operationId as GetUserInfoOperationId } from "../tools/registerGetUserInfo.ts"; -import { operationId as GetApplicationsOperationId } from "../tools/registerGetApplications.ts"; -import { ALL_SPECS, type OpenApiSpec } from "../openApi.ts"; -import type { ToolFilter } from "../toolFilters.ts"; -import { type CliFilteringOptions, getToolFilter, isToolAllowed } from "../toolFilters.ts"; - -export function getToolIds(toolFilter?: ToolFilter): string[] { - const results = []; - for (const spec of ALL_SPECS) { - const toolIds = extractToolIds(spec).filter((id) => isToolAllowed(id, toolFilter)); - results.push(...toolIds); - } - return results; -} - -export type ListToolsOptions = CliFilteringOptions & { - all: boolean; -}; - -export async function listTools(opts: ListToolsOptions): Promise { - const toolFilter = opts.all ? undefined : getToolFilter(opts); - - const dashboardApiTools = [GetUserInfoOperationId, GetApplicationsOperationId].filter((id) => - isToolAllowed(id, toolFilter), - ); - if (dashboardApiTools.length > 0) { - displayGroup("Dashboard API", dashboardApiTools); - } - - for (const spec of ALL_SPECS) { - const toolIds = extractToolIds(spec).filter((id) => isToolAllowed(id, toolFilter)); - - if (toolIds.length > 0) { - displayGroup(spec.info.title, toolIds); - } - } -} - -function displayGroup(title: string, operationIds: string[]): void { - console.log(title); - console.log(`> ${operationIds.join(", ")}\n`); -} - -function extractToolIds(spec: OpenApiSpec): string[] { - return Object.values(spec.paths) - .flatMap((path) => Object.values(path)) - .filter((operation) => !operation["x-helper"]) - .map((operation) => operation.operationId); -} diff --git a/src/commands/logout.ts b/src/commands/logout.ts deleted file mode 100644 index dc8bb9d..0000000 --- a/src/commands/logout.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AppStateManager } from "../appState.ts"; - -export async function logout(): Promise { - console.log("Logging out..."); - await AppStateManager.reset(); - console.log("Logged out successfully!"); -} diff --git a/src/commands/start-server.test.ts b/src/commands/start-server.test.ts deleted file mode 100644 index 1d940d4..0000000 --- a/src/commands/start-server.test.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { Client } from "@modelcontextprotocol/sdk/client/index.js"; - -import { startServer } from "./start-server.ts"; -import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js"; -import { setupServer } from "msw/node"; -import { http } from "msw"; -import { ZodError } from "zod"; -import type { AppState } from "../appState.ts"; -import { AppStateManager } from "../appState.ts"; -import { REQUIRED_ACLS } from "../DashboardApi.ts"; - -const mswServer = setupServer(); - -beforeAll(() => mswServer.listen()); -afterEach(() => mswServer.resetHandlers()); -afterAll(() => mswServer.close()); - -describe("when specifying credentials flag", () => { - it("should throw if params are missing", async () => { - await expect( - startServer({ - // @ts-expect-error -- I'm testing missing params - credentials: { applicationId: "appId" }, - }), - ).rejects.toThrow(ZodError); - await expect( - startServer({ - // @ts-expect-error -- I'm testing missing params - credentials: { apiKey: "apiKey" }, - }), - ).rejects.toThrow(ZodError); - }); - - it("should not throw if both params are provided", async () => { - vi.spyOn(AppStateManager, "load").mockRejectedValue(new Error("Should not be called")); - const server = await startServer({ credentials: { applicationId: "appId", apiKey: "apiKey" } }); - - expect(AppStateManager.load).not.toHaveBeenCalled(); - - await server.close(); - }); - - it("should allow filtering tools", async () => { - mswServer.use( - http.put("https://appid.algolia.net/1/indexes/indexName/settings", () => - Response.json({ taskId: 123 }), - ), - ); - const client = new Client({ name: "test client", version: "1.0.0" }); - const server = await startServer({ - credentials: { - apiKey: "apiKey", - applicationId: "appId", - }, - allowTools: ["setSettings"], - }); - - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - - const { tools } = await client.listTools(); - - expect(tools).toHaveLength(1); - expect(tools[0].name).toBe("setSettings"); - - const result = await client.callTool({ - name: "setSettings", - arguments: { - indexName: "indexName", - requestBody: { - searchableAttributes: ["title"], - }, - }, - }); - - expect(result).toMatchInlineSnapshot(` - { - "content": [ - { - "text": "{"taskId":123}", - "type": "text", - }, - ], - } - `); - - await server.close(); - }); -}); - -describe("default behavior", () => { - beforeEach(() => { - const mockAppState: AppState = { - accessToken: "accessToken", - refreshToken: "refreshToken", - apiKeys: { - appId: "apiKey", - }, - }; - vi.spyOn(AppStateManager, "load").mockResolvedValue( - // @ts-expect-error -- It's just a partial mock - { - get: vi.fn((k: K) => mockAppState[k]), - update: vi.fn(), - }, - ); - }); - - it("should list dashboard tools", async () => { - const client = new Client({ name: "test client", version: "1.0.0" }); - const server = await startServer({}); - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - - expect(AppStateManager.load).toHaveBeenCalled(); - - const { tools } = await client.listTools(); - expect(tools).toHaveLength(176); - expect(tools.some((t) => t.name === "getUserInfo")).toBe(true); - }); - - it("should fetch the api key automatically", async () => { - mswServer.use( - http.get("https://appid-dsn.algolia.net/1/keys/apiKey", () => - Response.json({ acl: REQUIRED_ACLS }), - ), - http.get("https://appid.algolia.net/1/indexes/indexName/settings", () => Response.json({})), - ); - const client = new Client({ name: "test client", version: "1.0.0" }); - const server = await startServer({ allowTools: ["getSettings"] }); - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - - const result = await client.callTool({ - name: "getSettings", - arguments: { - applicationId: "appId", - indexName: "indexName", - }, - }); - - expect(result).toMatchInlineSnapshot(` - { - "content": [ - { - "text": "{}", - "type": "text", - }, - ], - } - `); - }); -}); diff --git a/src/commands/start-server.ts b/src/commands/start-server.ts deleted file mode 100644 index 5b9331d..0000000 --- a/src/commands/start-server.ts +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env -S node --experimental-strip-types - -import { authenticate } from "../authentication.ts"; -import { AppStateManager } from "../appState.ts"; -import { DashboardApi } from "../DashboardApi.ts"; -import { - operationId as GetUserInfoOperationId, - registerGetUserInfo, -} from "../tools/registerGetUserInfo.ts"; -import { - operationId as GetApplicationsOperationId, - registerGetApplications, -} from "../tools/registerGetApplications.ts"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import type { - ProcessCallbackArguments, - ProcessInputSchema, - RequestMiddleware, -} from "../tools/registerOpenApi.ts"; -import { registerOpenApiTools } from "../tools/registerOpenApi.ts"; -import { CONFIG } from "../config.ts"; -import { - ABTestingSpec, - AnalyticsSpec, - CollectionsSpec, - IngestionSpec, - MonitoringSpec, - QuerySuggestionsSpec, - RecommendSpec, - SearchSpec, - UsageSpec, -} from "../openApi.ts"; -import { CliFilteringOptionsSchema, getToolFilter, isToolAllowed } from "../toolFilters.ts"; -import { - operationId as SetAttributesForFacetingOperationId, - registerSetAttributesForFaceting, -} from "../tools/registerSetAttributesForFaceting.ts"; -import { - registerSetCustomRanking, - operationId as SetCustomRankingOperationId, -} from "../tools/registerSetCustomRanking.ts"; - -import { CustomMcpServer } from "../CustomMcpServer.ts"; -import { z } from "zod"; - -export const StartServerOptionsSchema = CliFilteringOptionsSchema.extend({ - credentials: z - .object({ - applicationId: z.string(), - apiKey: z.string(), - }) - .optional(), -}); - -type StartServerOptions = z.infer; - -function makeRegionRequestMiddleware(dashboardApi: DashboardApi): RequestMiddleware { - return async ({ request, params }) => { - const application = await dashboardApi.getApplication(params.applicationId); - const region = application.data.attributes.log_region === "de" ? "eu" : "us"; - - const url = new URL(request.url); - const regionFromUrl = url.hostname.match(/data\.(.+)\.algolia.com/)?.[0]; - - if (regionFromUrl !== region) { - console.error("Had to adjust region from", regionFromUrl, "to", region); - url.hostname = `data.${region}.algolia.com`; - return new Request(url, request.clone()); - } - - return request; - }; -} - -export async function startServer(options: StartServerOptions): Promise { - const { credentials, ...opts } = StartServerOptionsSchema.parse(options); - const toolFilter = getToolFilter(opts); - - const server = new CustomMcpServer({ - name: "algolia", - version: CONFIG.version, - capabilities: { - resources: {}, - tools: {}, - }, - }); - - const regionHotFixMiddlewares: RequestMiddleware[] = []; - let processCallbackArguments: ProcessCallbackArguments; - const processInputSchema: ProcessInputSchema = (inputSchema) => { - // If we got it from the options, we don't need it from the AI - if (credentials && inputSchema.properties?.applicationId) { - delete inputSchema.properties.applicationId; - - if (Array.isArray(inputSchema.required)) { - inputSchema.required = inputSchema.required.filter((item) => item !== "applicationId"); - } - } - - return inputSchema; - }; - - if (credentials) { - processCallbackArguments = async (params, securityKeys) => { - const result = { ...params }; - - if (securityKeys.has("applicationId")) { - result.applicationId = credentials.applicationId; - } - - if (securityKeys.has("apiKey")) { - result.apiKey = credentials.apiKey; - } - - return result; - }; - } else { - const appState = await AppStateManager.load(); - - if (!appState.get("accessToken")) { - const token = await authenticate(); - - await appState.update({ - accessToken: token.access_token, - refreshToken: token.refresh_token, - }); - } - - const dashboardApi = new DashboardApi({ baseUrl: CONFIG.dashboardApiBaseUrl, appState }); - - processCallbackArguments = async (params, securityKeys) => { - const result = { ...params }; - - if (securityKeys.has("apiKey")) { - result.apiKey = await dashboardApi.getApiKey(params.applicationId); - } - - return result; - }; - - regionHotFixMiddlewares.push(makeRegionRequestMiddleware(dashboardApi)); - - // Dashboard API Tools - if (isToolAllowed(GetUserInfoOperationId, toolFilter)) { - registerGetUserInfo(server, dashboardApi); - } - - if (isToolAllowed(GetApplicationsOperationId, toolFilter)) { - registerGetApplications(server, dashboardApi); - } - - // TODO: Make it available when with applicationId+apiKey mode too - if (isToolAllowed(SetAttributesForFacetingOperationId, toolFilter)) { - registerSetAttributesForFaceting(server, dashboardApi); - } - - if (isToolAllowed(SetCustomRankingOperationId, toolFilter)) { - registerSetCustomRanking(server, dashboardApi); - } - } - - for (const openApiSpec of [ - SearchSpec, - AnalyticsSpec, - RecommendSpec, - ABTestingSpec, - MonitoringSpec, - CollectionsSpec, - QuerySuggestionsSpec, - ]) { - registerOpenApiTools({ - server, - processInputSchema, - processCallbackArguments, - openApiSpec, - toolFilter, - }); - } - - // Usage - registerOpenApiTools({ - server, - processInputSchema, - processCallbackArguments, - openApiSpec: UsageSpec, - toolFilter, - requestMiddlewares: [ - // The Usage API expects `name` parameter as multiple values - // rather than comma-separated. - async ({ request }) => { - const url = new URL(request.url); - const nameParams = url.searchParams.get("name"); - - if (!nameParams) { - return new Request(url, request.clone()); - } - - const nameValues = nameParams.split(","); - - url.searchParams.delete("name"); - - nameValues.forEach((value) => { - url.searchParams.append("name", value); - }); - - return new Request(url, request.clone()); - }, - ], - }); - - // Ingestion API Tools - registerOpenApiTools({ - server, - processInputSchema, - processCallbackArguments, - openApiSpec: IngestionSpec, - toolFilter, - requestMiddlewares: [ - // Dirty fix for Claud hallucinating regions - ...regionHotFixMiddlewares, - ], - }); - - const transport = new StdioServerTransport(); - await server.connect(transport); - return server; -} diff --git a/src/config.ts b/src/config.ts index 25a91da..bd0edca 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,16 +1,7 @@ -import PackageJson from "../package.json" with { type: "json" }; +import { cleanEnv, port, str } from "envalid"; -const port = process.env.PORT ? parseInt(process.env.PORT) : 4242; - -export const CONFIG = { - // Authentication stuff - port, - clientId: "VERsdGeMujcaDaxphqeiRViwYvK2LtINlrD9EsZDWCs", - redirectUri: `http://localhost:${port}/callback`, - authEndpoint: "https://dashboard.algolia.com/oauth/authorize", - tokenUrl: `https://dashboard.algolia.com/oauth/token`, - // Dashboard API - dashboardApiBaseUrl: "https://api.dashboard.algolia.com", - userAgent: `algolia-mcp-node/${PackageJson.version}`, - version: PackageJson.version, -}; +export const config = cleanEnv(process.env, { + PORT: port({ devDefault: 8099 }), + LOG_LEVEL: str({ default: "debug" }), + VERSION: str({ default: "1.0.0" }), +}); diff --git a/src/data/abtesting.json b/src/data/abtesting.json deleted file mode 100644 index e93667c..0000000 --- a/src/data/abtesting.json +++ /dev/null @@ -1,1477 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "A/B Testing API", - "description": "The Algolia A/B Testing API lets you manage your Algolia A/B tests to optimize your search experience.\n\n## Base URLs\n\nThe base URLs for requests to the A/B testing API are:\n\n- `https://analytics.us.algolia.com`\n- `https://analytics.de.algolia.com`\n- `https://analytics.algolia.com` (routes requests to the closest of the above servers, based on your geographical location)\n\nUse the URL that matches your [analytics region](https://dashboard.algolia.com/account/infrastructure/analytics).\n\n**All requests must use HTTPS.**\n\n## Availability and authentication\n\nAccess to the A/B testing API is available as part of the [Premium or Elevate plans](https://www.algolia.com/pricing).\n\nTo authenticate your API requests, add these headers:\n\n- `x-algolia-application-id`. Your Algolia application ID.\n- `x-algolia-api-key`. An API key with the necessary permissions to make the request.\n The required access control list (ACL) to make a request is listed in each endpoint's reference.\n\nYou can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account).\n\n## Rate limits\n\nYou can make up to **100 requests per minute per app** to the A/B testing API.\nThe response includes headers with information about the limits.\n\n## Parameters\n\nQuery parameters must be [URL-encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding).\nNon-ASCII characters must be UTF-8 encoded.\nPlus characters (`+`) are interpreted as spaces.\n\n## Response status and errors\n\nThe A/B testing API returns JSON responses.\nSince JSON doesn't guarantee any specific ordering, don't rely on the order of attributes in the API response.\n\nSuccessful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status.\nError responses have a `message` property with more information.\n\n## Version\n\nThe current version of the A/B Testing API is version 2, as indicated by the `/2/` in each endpoint's URL.\n", - "version": "2.0.0" - }, - "servers": [ - { - "url": "https://analytics.{region}.algolia.com", - "variables": { - "region": { - "definition": "The log region is configured at the application level.", - "enum": ["us", "de"], - "default": "us" - } - } - }, - { - "url": "https://analytics.algolia.com" - } - ], - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ], - "tags": [ - { - "name": "abtest", - "x-displayName": "A/B testing", - "description": "Manage A/B tests.\n\nA/B tests are configurations one or more indices, usually your production index and an index with different settings that you want to test.\n" - } - ], - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/", - "description": "Related guide: A/B testing.\n" - }, - "paths": { - "/{path}": { - "get": { - "operationId": "customGet", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["abtesting"] - }, - "post": { - "operationId": "customPost", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["abtesting"] - }, - "put": { - "operationId": "customPut", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["abtesting"] - }, - "delete": { - "operationId": "customDelete", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["abtesting"] - } - }, - "/2/abtests": { - "post": { - "tags": ["abtesting"], - "operationId": "addABTests", - "x-acl": ["editSettings"], - "summary": "Create an A/B test", - "description": "Creates a new A/B test.", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "addABTestsRequest", - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "$ref": "#/components/schemas/name" - }, - "variants": { - "type": "array", - "description": "A/B test variants.", - "minItems": 2, - "maxItems": 2, - "items": { - "$ref": "#/components/schemas/AddABTestsVariant" - } - }, - "endAt": { - "$ref": "#/components/schemas/endAt" - } - }, - "required": ["name", "variants", "endAt"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ABTestResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "get": { - "tags": ["abtesting"], - "operationId": "listABTests", - "x-acl": ["analytics"], - "summary": "List all A/B tests", - "description": "Lists all A/B tests you configured for this application.", - "parameters": [ - { - "name": "offset", - "in": "query", - "description": "Position of the first item to return.", - "required": false, - "schema": { - "type": "integer", - "default": 0, - "minimum": 0 - } - }, - { - "name": "limit", - "in": "query", - "description": "Number of items to return.", - "required": false, - "schema": { - "type": "integer", - "default": 10 - } - }, - { - "name": "indexPrefix", - "in": "query", - "description": "Index name prefix. Only A/B tests for indices starting with this string are included in the response.", - "example": "dev_", - "schema": { - "type": "string" - } - }, - { - "name": "indexSuffix", - "in": "query", - "description": "Index name suffix. Only A/B tests for indices ending with this string are included in the response.", - "example": "_development", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "listABTestsResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "abtests": { - "$ref": "#/components/schemas/ABTests" - }, - "count": { - "type": "integer", - "description": "Number of A/B tests.", - "example": 10 - }, - "total": { - "type": "integer", - "description": "Number of retrievable A/B tests.", - "example": 12 - } - }, - "required": ["abtests", "count", "total"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/abtests/{id}": { - "get": { - "tags": ["abtesting"], - "operationId": "getABTest", - "x-acl": ["analytics"], - "summary": "Retrieve A/B test details", - "description": "Retrieves the details for an A/B test by its ID.", - "parameters": [ - { - "$ref": "#/components/parameters/ID" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ABTest" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["abtesting"], - "operationId": "deleteABTest", - "x-acl": ["editSettings"], - "summary": "Delete an A/B test", - "description": "Deletes an A/B test by its ID.", - "parameters": [ - { - "$ref": "#/components/parameters/ID" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ABTestResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/abtests/{id}/stop": { - "post": { - "tags": ["abtesting"], - "operationId": "stopABTest", - "x-acl": ["editSettings"], - "summary": "Stop an A/B test", - "description": "Stops an A/B test by its ID.\n\nYou can't restart stopped A/B tests.\n", - "parameters": [ - { - "$ref": "#/components/parameters/ID" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ABTestResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/abtests/schedule": { - "post": { - "tags": ["abtesting"], - "operationId": "scheduleABTest", - "x-acl": ["editSettings"], - "summary": "Schedule an A/B test", - "description": "Schedule an A/B test to be started at a later time.\n", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "scheduleABTestsRequest", - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "$ref": "#/components/schemas/name" - }, - "variants": { - "type": "array", - "description": "A/B test variants.", - "minItems": 2, - "maxItems": 2, - "items": { - "$ref": "#/components/schemas/AddABTestsVariant" - } - }, - "scheduledAt": { - "$ref": "#/components/schemas/scheduledAt" - }, - "endAt": { - "$ref": "#/components/schemas/endAt" - } - }, - "required": ["name", "variants", "scheduledAt", "endAt"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ScheduleABTestResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/abtests/estimate": { - "post": { - "tags": ["abtesting"], - "operationId": "estimateABTest", - "x-acl": ["analytics"], - "summary": "Estimate the sample size and duration of an A/B test", - "description": "Given the traffic percentage and the expected effect size, this endpoint estimates the sample size and duration of an A/B test based on historical traffic.", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "estimateABTestRequest", - "type": "object", - "additionalProperties": false, - "properties": { - "configuration": { - "title": "estimateConfiguration", - "type": "object", - "description": "A/B test configuration for estimating the sample size and duration using minimum detectable effect.", - "properties": { - "outliers": { - "$ref": "#/components/schemas/Outliers" - }, - "emptySearch": { - "$ref": "#/components/schemas/EmptySearch" - }, - "minimumDetectableEffect": { - "$ref": "#/components/schemas/MinimumDetectableEffect" - } - }, - "required": ["minimumDetectableEffect"] - }, - "variants": { - "type": "array", - "description": "A/B test variants.", - "minItems": 2, - "maxItems": 2, - "items": { - "$ref": "#/components/schemas/AddABTestsVariant" - } - } - }, - "required": ["configuration", "variants"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EstimateABTestResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/setClientApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["abtesting"], - "operationId": "setClientApiKey", - "summary": "Switch the API key used to authenticate requests", - "description": "Switch the API key used to authenticate requests.\n", - "parameters": [ - { - "in": "query", - "name": "apiKey", - "description": "API key to be used from now on.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No content." - } - } - } - } - }, - "components": { - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-application-id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-api-key", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - }, - "parameters": { - "PathInPath": { - "name": "path", - "in": "path", - "description": "Path of the endpoint, anything after \"/1\" must be specified.", - "required": true, - "schema": { - "type": "string", - "example": "/keys" - } - }, - "Parameters": { - "name": "parameters", - "in": "query", - "description": "Query parameters to apply to the current query.", - "schema": { - "type": "object", - "additionalProperties": true - } - }, - "ID": { - "in": "path", - "name": "id", - "description": "Unique A/B test identifier.", - "required": true, - "schema": { - "$ref": "#/components/schemas/abTestID" - } - } - }, - "schemas": { - "ErrorBase": { - "description": "Error.", - "type": "object", - "x-keep-model": true, - "additionalProperties": true, - "properties": { - "message": { - "type": "string", - "example": "Invalid Application-Id or API-Key" - } - } - }, - "abTestID": { - "type": "integer", - "description": "Unique A/B test identifier.", - "example": 224 - }, - "updatedAt": { - "type": "string", - "description": "Date and time when the A/B test was last updated, in RFC 3339 format.", - "example": "2023-06-15T15:06:44.400601Z" - }, - "createdAt": { - "type": "string", - "description": "Date and time when the A/B test was created, in RFC 3339 format.", - "example": "2023-06-15T15:06:04.249906Z" - }, - "endAt": { - "type": "string", - "description": "End date and time of the A/B test, in RFC 3339 format.", - "example": "2023-06-17T00:00:00Z" - }, - "name": { - "type": "string", - "description": "A/B test name.", - "example": "Custom ranking sales rank test" - }, - "Status": { - "type": "string", - "description": "A/B test status.\n\n- `active`. The A/B test is live and search traffic is split between the two variants.\n- `stopped`. You stopped the A/B test. The A/B test data is still available for analysis.\n- `expired`. The A/B test was automatically stopped after reaching its end date.\n- `failed`. Creating the A/B test failed.\n", - "example": "active", - "enum": ["active", "stopped", "expired", "failed"] - }, - "currency": { - "type": "object", - "properties": { - "currency": { - "type": "string", - "description": "Currency code.", - "example": "USD" - }, - "revenue": { - "type": "number", - "format": "double", - "description": "Revenue for this currency.", - "example": 120 - }, - "mean": { - "type": "number", - "format": "double", - "description": "Mean for this currency.", - "example": 53.7 - }, - "standardDeviation": { - "type": "number", - "format": "double", - "description": "Standard deviation for this currency.", - "example": 12.3 - } - } - }, - "currencies": { - "type": "object", - "description": "A/B test currencies.", - "example": { - "USD": { - "currency": "USD", - "revenue": 120, - "mean": 53.7, - "standardDeviation": 12.3 - }, - "EUR": { - "currency": "EUR", - "revenue": 100, - "mean": 43.7, - "standardDeviation": 10.3 - } - }, - "additionalProperties": { - "$ref": "#/components/schemas/currency", - "x-additionalPropertiesName": "currency code" - } - }, - "description": { - "type": "string", - "description": "Description for this variant.", - "example": "Current production index" - }, - "filterEffects": { - "type": "object", - "description": "A/B test filter effects resulting from configuration settings.", - "properties": { - "outliers": { - "title": "outliersFilter", - "type": "object", - "description": "Outliers removed from the A/B test as a result of configuration settings.", - "example": { - "usersCount": 1, - "trackedSearchesCount": 237 - }, - "properties": { - "usersCount": { - "type": "integer", - "description": "Number of users removed from the A/B test.", - "example": 1 - }, - "trackedSearchesCount": { - "type": "integer", - "description": "Number of tracked searches removed from the A/B test.", - "example": 237 - } - } - }, - "emptySearch": { - "title": "emptySearchFilter", - "type": "object", - "description": "Empty searches removed from the A/B test as a result of configuration settings.", - "example": { - "usersCount": 1, - "trackedSearchesCount": 237 - }, - "properties": { - "usersCount": { - "type": "integer", - "description": "Number of users removed from the A/B test.", - "example": 1 - }, - "trackedSearchesCount": { - "type": "integer", - "description": "Number of tracked searches removed from the A/B test.", - "example": 237 - } - } - } - } - }, - "index": { - "type": "string", - "description": "Index name of the A/B test variant (case-sensitive).", - "example": "delcourt_production" - }, - "trackedSearchCount": { - "type": "integer", - "example": 2, - "default": 0, - "description": "Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true." - }, - "trafficPercentage": { - "type": "integer", - "description": "Percentage of search requests each variant receives.", - "minimum": 0, - "maximum": 100, - "example": 60 - }, - "variant": { - "type": "object", - "additionalProperties": false, - "properties": { - "addToCartCount": { - "type": "integer", - "description": "Number of add-to-cart events for this variant.", - "example": 0 - }, - "addToCartRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "[Add-to-cart rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#add-to-cart-rate) for this variant.\n", - "example": 0 - }, - { - "type": "null" - } - ] - }, - "averageClickPosition": { - "oneOf": [ - { - "type": "integer", - "description": "[Average click position](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#click-position) for this variant.\n", - "example": 0 - }, - { - "type": "null" - } - ] - }, - "clickCount": { - "type": "integer", - "description": "Number of click events for this variant.", - "example": 65131 - }, - "clickThroughRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "[Click-through rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#click-through-rate) for this variant.\n", - "example": 0.22219857724813036 - }, - { - "type": "null" - } - ] - }, - "conversionCount": { - "type": "integer", - "description": "Number of click events for this variant.", - "example": 4785 - }, - "conversionRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "[Conversion rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#conversion-rate) for this variant.\n", - "example": 0.14546725846658964 - }, - { - "type": "null" - } - ] - }, - "currencies": { - "$ref": "#/components/schemas/currencies" - }, - "description": { - "$ref": "#/components/schemas/description" - }, - "estimatedSampleSize": { - "type": "integer", - "description": "Estimated number of searches required to achieve the desired statistical significance.\n\nThe A/B test configuration must include a `mininmumDetectableEffect` setting for this number to be included in the response.\n", - "example": 0 - }, - "filterEffects": { - "$ref": "#/components/schemas/filterEffects" - }, - "index": { - "$ref": "#/components/schemas/index" - }, - "noResultCount": { - "oneOf": [ - { - "type": "integer", - "description": "Number of [searches without results](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#searches-without-results) for this variant.", - "example": 0 - }, - { - "type": "null" - } - ] - }, - "purchaseCount": { - "type": "integer", - "description": "Number of purchase events for this variant.", - "example": 0 - }, - "purchaseRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "[Purchase rate](https://www.algolia.com/doc/guides/search-analytics/concepts/metrics/#purchase-rate) for this variant.\n", - "example": 0 - }, - { - "type": "null" - } - ] - }, - "searchCount": { - "oneOf": [ - { - "type": "integer", - "description": "Number of searches for this variant.", - "example": 86269 - }, - { - "type": "null" - } - ] - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "trafficPercentage": { - "$ref": "#/components/schemas/trafficPercentage" - }, - "userCount": { - "oneOf": [ - { - "type": "integer", - "description": "Number of users that made searches to this variant.", - "example": 55501 - }, - { - "type": "null" - } - ] - }, - "trackedUserCount": { - "oneOf": [ - { - "type": "integer", - "description": "Number of users that made tracked searches to this variant.", - "example": 55501 - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "userCount", - "trackedUserCount", - "trafficPercentage", - "searchCount", - "noResultCount", - "index", - "conversionCount", - "clickCount", - "addToCartCount", - "purchaseCount" - ] - }, - "variants": { - "type": "array", - "description": "A/B test variants.\n\nThe first variant is your _control_ index, typically your production index.\nThe second variant is an index with changed settings that you want to test against the control.\n", - "items": { - "$ref": "#/components/schemas/variant" - } - }, - "Outliers": { - "type": "object", - "description": "Configuration for handling outliers.", - "properties": { - "exclude": { - "type": "boolean", - "description": "Whether to exclude outliers when calculating A/B test results.", - "default": true - } - } - }, - "EmptySearch": { - "type": "object", - "description": "Configuration for handling empty searches.", - "properties": { - "exclude": { - "type": "boolean", - "description": "Whether to exclude empty searches when calculating A/B test results." - } - } - }, - "EffectMetric": { - "type": "string", - "description": "Metric for which you want to detect the smallest relative difference.", - "enum": ["addToCartRate", "clickThroughRate", "conversionRate", "purchaseRate"] - }, - "MinimumDetectableEffect": { - "type": "object", - "description": "Configuration for the smallest difference between test variants you want to detect.", - "properties": { - "size": { - "type": "number", - "format": "double", - "minimum": 0, - "maximum": 1, - "description": "Smallest difference in an observable metric between variants.\nFor example, to detect a 10% difference between variants, set this value to 0.1.\n" - }, - "metric": { - "$ref": "#/components/schemas/EffectMetric" - } - }, - "required": ["size", "metric"] - }, - "ABTestConfiguration": { - "title": "configuration", - "type": "object", - "description": "A/B test configuration.", - "properties": { - "outliers": { - "$ref": "#/components/schemas/Outliers" - }, - "emptySearch": { - "$ref": "#/components/schemas/EmptySearch" - }, - "minimumDetectableEffect": { - "$ref": "#/components/schemas/MinimumDetectableEffect" - } - } - }, - "ABTest": { - "type": "object", - "additionalProperties": false, - "properties": { - "abTestID": { - "$ref": "#/components/schemas/abTestID" - }, - "clickSignificance": { - "description": "A/B test significance calculated from click events.\n\nValues of 0.95 or higher can be considered significant,\nthat is, the difference between A and B variants is _not_ due to random variations.\nLower values have a.\n", - "oneOf": [ - { - "type": "number", - "format": "double", - "example": 1 - }, - { - "type": "null" - } - ] - }, - "conversionSignificance": { - "description": "A/B test significance calculated from conversion events.\n\nValues of 0.95 or higher can be considered significant,\nthat is, the difference between A and B variants is _not_ due to random variations.\n", - "oneOf": [ - { - "type": "number", - "format": "double", - "example": 1 - }, - { - "type": "null" - } - ] - }, - "addToCartSignificance": { - "description": "A/B test significance calculated from add-to-cart events.\n\nValues of 0.95 or higher can be considered significant,\nthat is, the difference between A and B variants is _not_ due to random variations.\n", - "oneOf": [ - { - "type": "number", - "format": "double", - "example": 1 - }, - { - "type": "null" - } - ] - }, - "purchaseSignificance": { - "description": "A/B test significance calculated from purchase events.\n\nValues of 0.95 or higher can be considered significant,\nthat is, the difference between A and B variants is _not_ due to random variations.\n", - "oneOf": [ - { - "type": "number", - "format": "double", - "example": 1 - }, - { - "type": "null" - } - ] - }, - "revenueSignificance": { - "description": "A/B test significance calculated from revenue data.\n\nValues of 0.95 or higher can be considered significant,\nthat is, the difference between A and B variants is _not_ due to random variations.\n", - "oneOf": [ - { - "type": "object", - "additionalProperties": { - "type": "number", - "format": "double", - "x-additionalPropertiesName": "currency code" - }, - "example": { - "USD": 1, - "EUR": 0.87 - } - }, - { - "type": "null" - } - ] - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "endAt": { - "$ref": "#/components/schemas/endAt" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "status": { - "$ref": "#/components/schemas/Status" - }, - "variants": { - "$ref": "#/components/schemas/variants" - }, - "configuration": { - "$ref": "#/components/schemas/ABTestConfiguration" - } - }, - "required": ["status", "name", "createdAt", "endAt", "updatedAt", "abTestID", "variants"] - }, - "ABTests": { - "oneOf": [ - { - "type": "array", - "description": "The list of A/B tests, null if no A/B tests are configured for this application.", - "items": { - "$ref": "#/components/schemas/ABTest" - } - }, - { - "type": "null" - } - ] - }, - "abTestsVariant": { - "type": "object", - "properties": { - "index": { - "$ref": "#/components/schemas/index" - }, - "trafficPercentage": { - "$ref": "#/components/schemas/trafficPercentage" - }, - "description": { - "$ref": "#/components/schemas/description" - } - }, - "required": ["index", "trafficPercentage"] - }, - "customSearchParams": { - "type": "object", - "description": "Search parameters to add to the test variant.\nOnly use this parameter if the two variants use the same index.\n", - "example": { - "typoTolerance": false, - "synonyms": false - }, - "properties": { - "customSearchParameters": { - "type": "object" - } - }, - "required": ["customSearchParameters"], - "x-discriminator-fields": ["customSearchParameters"] - }, - "abTestsVariantSearchParams": { - "allOf": [ - { - "$ref": "#/components/schemas/abTestsVariant" - }, - { - "$ref": "#/components/schemas/customSearchParams" - } - ], - "unevaluatedProperties": false - }, - "AddABTestsVariant": { - "oneOf": [ - { - "$ref": "#/components/schemas/abTestsVariant" - }, - { - "$ref": "#/components/schemas/abTestsVariantSearchParams" - } - ] - }, - "taskID": { - "type": "integer", - "format": "int64", - "example": 1514562690001, - "description": "Unique identifier of a task.\n\nA successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`.\n" - }, - "ABTestResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "index": { - "$ref": "#/components/schemas/index" - }, - "abTestID": { - "$ref": "#/components/schemas/abTestID" - }, - "taskID": { - "$ref": "#/components/schemas/taskID" - } - }, - "required": ["abTestID", "index", "taskID"] - }, - "scheduledAt": { - "type": "string", - "description": "Date and time when the A/B test is scheduled to start, in RFC 3339 format.", - "example": "2023-06-15T15:06:44.400601Z" - }, - "abTestScheduleID": { - "type": "integer", - "description": "Unique scheduled A/B test identifier.", - "example": 224 - }, - "ScheduleABTestResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "abTestScheduleID": { - "$ref": "#/components/schemas/abTestScheduleID" - } - }, - "required": ["abTestScheduleID"] - }, - "EstimateABTestResponse": { - "type": "object", - "properties": { - "durationDays": { - "type": "integer", - "format": "int64", - "description": "Estimated number of days needed to reach the sample sizes required for detecting the configured effect. This value is based on historical traffic.", - "example": 21 - }, - "sampleSizes": { - "type": "array", - "description": "Sample size estimates for each variant. The first element is the control variant.\nEach element is the estimated number of searches required to achieve the desired statistical significance.\n", - "items": { - "type": "integer", - "format": "int64", - "description": "Number of tracked searches needed to be able to detect the configured effect for the control variant.", - "example": 23415 - } - } - } - } - }, - "responses": { - "BadRequest": { - "description": "Bad request or request arguments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "FeatureNotEnabled": { - "description": "This feature is not enabled on your Algolia account.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "MethodNotAllowed": { - "description": "Method not allowed with this API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "IndexNotFound": { - "description": "Index not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - } - }, - "headers": { - "x-ratelimit-limit": { - "description": "Number of allowed requests per one minute.", - "example": 100, - "schema": { - "type": "integer" - } - }, - "x-ratelimit-remaining": { - "description": "Number of remaining requests in the current period.", - "example": 99, - "schema": { - "type": "integer" - } - }, - "x-ratelimit-reset": { - "description": "Timstamp when the rate limit will reset, measured in seconds since the Unix epoch.", - "example": 1710682486, - "schema": { - "type": "integer" - } - } - } - }, - "x-tagGroups": [ - { - "name": "General", - "tags": ["abtest"] - } - ] -} diff --git a/src/data/analytics.json b/src/data/analytics.json deleted file mode 100644 index 3dc6b4c..0000000 --- a/src/data/analytics.json +++ /dev/null @@ -1,2879 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "Analytics API", - "description": "The Analytics API gives you access to metrics related to your Algolia search experience.\n\n## Base URLs\n\nThe base URLs for requests to the Analytics API are:\n\n- `https://analytics.us.algolia.com`\n- `https://analytics.de.algolia.com`\n- `https://analytics.algolia.com` (routes requests to the closest of the above servers, based on your geographical location)\n\nUse the URL that matches your [analytics region](https://dashboard.algolia.com/account/infrastructure/analytics).\n\n**All requests must use HTTPS.**\n\n## Availability and authentication\n\nAccess to the Analytics API is available as part of the [Premium or Elevate plans](https://www.algolia.com/pricing).\n\nTo authenticate your API requests, add these headers:\n\n- `x-algolia-application-id`. Your Algolia application ID.\n- `x-algolia-api-key`. An API key with the necessary permissions to make the request.\n The required access control list (ACL) to make a request is listed in each endpoint's reference.\n\nYou can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account).\n\n## Rate limits\n\nYou can make up to **100 requests per minute per app** to the Analytics API.\nThe response includes headers with information about the limits.\n\n## Parameters\n\nQuery parameters must be [URL-encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding).\nNon-ASCII characters must be UTF-8 encoded.\nPlus characters (`+`) are interpreted as spaces.\n\n## Response status and errors\n\nThe Analytics API returns JSON responses.\nSince JSON doesn't guarantee any specific ordering, don't rely on the order of attributes in the API response.\n\n- Successful responses return a `2xx` status\n- Client errors return a `4xx` status\n- Server errors are indicated by a `5xx` status.\n\nError responses have a `message` property with more information.\n\n## Version\n\nThe current version of the Analytics API is version 2, as indicated by the `/2/` in each endpoint's URL.\n\n## Query aggregation\n\nAlgolia accepts queries on each keystroke.\nTo ensure you have relevant analytics data, however, the series of keystrokes is aggregated to keep only the latest (final) user query.\nThis is called \"prefix\" aggregation.\n\nFor more information, see [Query agggregation and processing](https://www.algolia.com/doc/guides/search-analytics/concepts/query-aggregation/).\n\nSee the analytics implementation overview for more information about query aggregation.\n", - "version": "2.0.0" - }, - "servers": [ - { - "url": "https://analytics.{region}.algolia.com", - "variables": { - "region": { - "enum": ["us", "de"], - "default": "us" - } - } - }, - { - "url": "https://analytics.algolia.com" - } - ], - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ], - "tags": [ - { - "name": "click", - "x-displayName": "Clicks", - "description": "Metrics related to click and conversion events,\nsuch as click and conversion rates for your search results.\n" - }, - { - "name": "filter", - "x-displayName": "Filters", - "description": "Metrics related to filters.\n" - }, - { - "name": "revenue", - "x-displayName": "Revenue", - "description": "Metrics related to revenue.\n" - }, - { - "name": "search", - "x-displayName": "Searches", - "description": "Metrics related to searches and search results,\nsuch as the no-results rate or the most frequent search queries.\n" - }, - { - "name": "status", - "x-displayName": "Status", - "description": "Check the status of the Analytics API." - }, - { - "name": "user", - "x-displayName": "Users", - "description": "Metrics related to the users of your search." - } - ], - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/search-analytics/overview/", - "description": "Related guide: Search analytics.\n" - }, - "paths": { - "/{path}": { - "get": { - "operationId": "customGet", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["analytics"] - }, - "post": { - "operationId": "customPost", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["analytics"] - }, - "put": { - "operationId": "customPut", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["analytics"] - }, - "delete": { - "operationId": "customDelete", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["analytics"] - } - }, - "/2/searches": { - "get": { - "tags": ["analytics"], - "operationId": "getTopSearches", - "x-acl": ["analytics"], - "summary": "Retrieve top searches", - "description": "Returns the most popular searches. For each search, it also includes the average number of hits.\n\nIf you set the `clickAnalytics` query parameter to `true`, the response also includes\n\n- Tracked searches count. Tracked searches are Search API requests with the `clickAnalytics` parameter set to `true`. This differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`.\n- Click count\n- Click-through rate (CTR)\n- Conversion count\n- Conversion rate (CR)\n- Average click position\n\nIf you set the `revenueAnalytics` query parameter to `true`, the response also includes:\n\n- Add-to-cart count\n- Add-to-cart rate (ATCR)\n- Purchase count\n- Purchase rate\n- Revenue details for each currency\n\n**There's a difference between 0% rates and null rates:**\n\n- **Null** means there were no queries: since Algolia didn't receive any events, the rates (CTR, CR, ATCR, purchase rate) are null.\n- **0% rates** mean there _were_ queries but no [click or conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/ClickAnalytics" - }, - { - "$ref": "#/components/parameters/RevenueAnalytics" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/OrderBy" - }, - { - "$ref": "#/components/parameters/Direction" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/getTopSearchesResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/searches/count": { - "get": { - "tags": ["analytics"], - "operationId": "getSearchesCount", - "x-acl": ["analytics"], - "summary": "Retrieve number of searches", - "description": "Retrieves the number of searches within a time range, including a daily breakdown.\n\nBy default, the analyzed period includes the last eight days including the current day.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getSearchesCountResponse", - "type": "object", - "additionalProperties": false, - "required": ["dates", "count"], - "properties": { - "count": { - "$ref": "#/components/schemas/parameters_count" - }, - "dates": { - "type": "array", - "description": "Daily number of searches.", - "items": { - "title": "dailySearches", - "type": "object", - "additionalProperties": false, - "required": ["date", "count"], - "properties": { - "date": { - "$ref": "#/components/schemas/date" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/searches/noResults": { - "get": { - "tags": ["analytics"], - "operationId": "getSearchesNoResults", - "x-acl": ["analytics"], - "summary": "Retrieve the most frequent searches without results", - "description": "Retrieves the 1,000 most frequent searches that produced zero results.", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getSearchesNoResultsResponse", - "type": "object", - "additionalProperties": false, - "required": ["searches"], - "properties": { - "searches": { - "type": "array", - "description": "Searches without results.", - "items": { - "title": "dailySearchesNoResults", - "type": "object", - "additionalProperties": false, - "required": ["search", "count", "withFilterCount"], - "properties": { - "search": { - "$ref": "#/components/schemas/search" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - }, - "withFilterCount": { - "$ref": "#/components/schemas/withFilterCount" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/searches/noClicks": { - "get": { - "tags": ["analytics"], - "operationId": "getSearchesNoClicks", - "x-acl": ["analytics"], - "summary": "Retrieve top searches without clicks", - "description": "Retrieves the most popular searches that didn't lead to any clicks, from the 1,000 most frequent searches.\n\nFor each search, it also returns the number of displayed search results that remained unclicked.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getSearchesNoClicksResponse", - "type": "object", - "additionalProperties": false, - "required": ["searches"], - "properties": { - "searches": { - "type": "array", - "description": "Searches without any clicks.", - "items": { - "title": "dailySearchesNoClicks", - "type": "object", - "additionalProperties": false, - "required": ["search", "count", "nbHits"], - "properties": { - "search": { - "$ref": "#/components/schemas/search" - }, - "count": { - "type": "integer", - "description": "Number of tracked searches.", - "minimum": 1, - "example": 7 - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/searches/noResultRate": { - "get": { - "tags": ["analytics"], - "operationId": "getNoResultsRate", - "x-acl": ["analytics"], - "summary": "Retrieve no results rate", - "description": "Retrieves the fraction of searches that didn't return any results within a time range, including a daily breakdown.\nIt also returns the count of searches and searches without results used to compute the rates.\n\nBy default, the analyzed period includes the last eight days including the current day.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getNoResultsRateResponse", - "type": "object", - "additionalProperties": false, - "required": ["rate", "count", "noResultCount", "dates"], - "properties": { - "rate": { - "$ref": "#/components/schemas/noResultsRate" - }, - "count": { - "$ref": "#/components/schemas/count" - }, - "noResultCount": { - "$ref": "#/components/schemas/noResultCount" - }, - "dates": { - "type": "array", - "description": "Daily no results rates.", - "items": { - "title": "dailyNoResultsRates", - "type": "object", - "additionalProperties": false, - "required": ["date", "noResultCount", "count", "rate"], - "properties": { - "date": { - "$ref": "#/components/schemas/date" - }, - "noResultCount": { - "$ref": "#/components/schemas/noResultCount" - }, - "count": { - "$ref": "#/components/schemas/count" - }, - "rate": { - "$ref": "#/components/schemas/noResultsRate" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/searches/noClickRate": { - "get": { - "tags": ["analytics"], - "operationId": "getNoClickRate", - "x-acl": ["analytics"], - "summary": "Retrieve no click rate", - "description": "Retrieves the fraction of searches that didn't lead to any click within a time range, including a daily breakdown.\nIt also returns the number of tracked searches and tracked searches without clicks.\n\nBy default, the analyzed period includes the last eight days including the current day.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getNoClickRateResponse", - "type": "object", - "additionalProperties": false, - "required": ["dates", "count", "noClickCount", "rate"], - "properties": { - "rate": { - "$ref": "#/components/schemas/noClickRate" - }, - "count": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "noClickCount": { - "$ref": "#/components/schemas/noClickCount" - }, - "dates": { - "type": "array", - "description": "Daily no click rates.", - "items": { - "title": "dailyNoClickRates", - "type": "object", - "additionalProperties": false, - "required": ["rate", "count", "noClickCount", "date"], - "properties": { - "rate": { - "$ref": "#/components/schemas/noClickRate" - }, - "count": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "noClickCount": { - "$ref": "#/components/schemas/noClickCount" - }, - "date": { - "$ref": "#/components/schemas/date" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/hits": { - "get": { - "tags": ["analytics"], - "operationId": "getTopHits", - "x-acl": ["analytics"], - "summary": "Retrieve top search results", - "description": "Retrieves the object IDs of the 1,000 most frequent search results.\n\nIf you set the `clickAnalytics` query parameter to true, the response also includes:\n\n- Tracked searches count. Tracked searches are Search API requests with the `clickAnalytics` parameter set to `true`. This differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`.\n- Click count\n- Click-through rate (CTR)\n- Conversion count\n- Conversion rate (CR)\n- Average click position\n\nIf you set the `revenueAnalytics` parameter to `true`, the response also includes:\n\n- Add-to-cart count\n- Add-to-cart rate (ATCR)\n- Purchase count\n- Purchase rate\n- Revenue details for each currency\n\n**There's a difference between 0% rates and null rates:**\n\n- **Null** means there were no queries: since Algolia didn't receive any events, the rates (CTR, CR, ATCR, purchase rate) are null.\n- **0% rates** mean there _were_ queries but no [click or conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/Search" - }, - { - "$ref": "#/components/parameters/ClickAnalytics" - }, - { - "$ref": "#/components/parameters/RevenueAnalytics" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/getTopHitsResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/users/count": { - "get": { - "tags": ["analytics"], - "operationId": "getUsersCount", - "x-acl": ["analytics"], - "summary": "Retrieve number of users", - "description": "Retrieves the number of unique users within a time range, including a daily breakdown.\n\nSince it returns the number of unique users, the sum of the daily values might be different from the total number.\n\nBy default:\n\n- Algolia distinguishes search users by their IP address, _unless_ you include a pseudonymous user identifier in your search requests with the `userToken` API parameter or `x-algolia-usertoken` request header.\n- The analyzed period includes the last eight days including the current day.\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/search-analytics/guides/usertoken/", - "description": "Related guide: Distinguish users for analytics.\n" - }, - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getUsersCountResponse", - "type": "object", - "additionalProperties": false, - "required": ["dates", "count"], - "properties": { - "count": { - "type": "integer", - "description": "Number of unique users." - }, - "dates": { - "type": "array", - "description": "Daily number of unique users.", - "items": { - "title": "dailyUsers", - "type": "object", - "additionalProperties": false, - "required": ["date", "count"], - "properties": { - "date": { - "$ref": "#/components/schemas/date" - }, - "count": { - "type": "integer", - "description": "Number of unique users." - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/filters": { - "get": { - "tags": ["analytics"], - "operationId": "getTopFilterAttributes", - "x-acl": ["analytics"], - "summary": "Retrieve top filters", - "description": "Retrieves the 1,000 most frequently used filter attributes.\n\nThese are attributes of your records that you included in the `attributesForFaceting` setting.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/Search" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/getTopFilterAttributesResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/filters/{attribute}": { - "get": { - "tags": ["analytics"], - "operationId": "getTopFilterForAttribute", - "x-acl": ["analytics"], - "summary": "Retrieve top filter values", - "description": "Retrieves the 1,000 most frequent filter (facet) values for a filter attribute.\n\nThese are attributes of your records that you included in the `attributesForFaceting` setting.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Attribute" - }, - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/Search" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/getTopFilterForAttributeResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/filters/noResults": { - "get": { - "tags": ["analytics"], - "operationId": "getTopFiltersNoResults", - "x-acl": ["analytics"], - "summary": "Retrieve top filters for a search without results", - "description": "Retrieves the 1,000 most frequently used filters for a search that didn't return any results.\n\nTo get the most frequent searches without results, use the [Retrieve searches without results](#tag/search/operation/getSearchesNoResults) operation.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/Search" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/getTopFiltersNoResultsResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/countries": { - "get": { - "tags": ["analytics"], - "operationId": "getTopCountries", - "x-acl": ["analytics"], - "summary": "Retrieve top countries", - "description": "Retrieves the countries with the most searches in your index.", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getTopCountriesResponse", - "type": "object", - "additionalProperties": false, - "required": ["countries"], - "properties": { - "countries": { - "type": "array", - "description": "Countries and number of searches.", - "items": { - "title": "topCountry", - "type": "object", - "additionalProperties": false, - "required": ["country", "count"], - "properties": { - "country": { - "description": "Country code.", - "type": "string", - "example": "UK" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/clicks/averageClickPosition": { - "get": { - "tags": ["analytics"], - "operationId": "getAverageClickPosition", - "x-acl": ["analytics"], - "summary": "Retrieve average click position", - "description": "Retrieves the average click position of your search results, including a daily breakdown.\n\nThe average click position is the average of all clicked search result positions.\nFor example, if users only ever click on the first result for any search, the average click position is 1.\nBy default, the analyzed period includes the last eight days including the current day.\n\nAn average of `null` when `clickAnalytics` is enabled means Algolia didn't receive any [click events](https://www.algolia.com/doc/guides/sending-events/getting-started/) for the queries.\nThe average is `null` until Algolia receives at least one click event.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getAverageClickPositionResponse", - "type": "object", - "additionalProperties": false, - "required": ["average", "clickCount", "dates"], - "properties": { - "average": { - "$ref": "#/components/schemas/averageClickPosition" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "dates": { - "type": "array", - "description": "Daily average click positions.", - "items": { - "title": "dailyAverageClicks", - "type": "object", - "additionalProperties": false, - "required": ["average", "clickCount", "date"], - "properties": { - "average": { - "$ref": "#/components/schemas/averageClickPosition" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "date": { - "$ref": "#/components/schemas/date" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/clicks/positions": { - "get": { - "tags": ["analytics"], - "operationId": "getClickPositions", - "x-acl": ["analytics"], - "summary": "Retrieve click positions", - "description": "Retrieves the positions in the search results and their associated number of clicks.\n\nThis lets you check how many clicks the first, second, or tenth search results receive.\n\nAn average of `0` when `clickAnalytics` is enabled means Algolia didn't receive any [click events](https://www.algolia.com/doc/guides/sending-events/getting-started/) for the queries.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getClickPositionsResponse", - "type": "object", - "additionalProperties": false, - "required": ["positions"], - "properties": { - "positions": { - "$ref": "#/components/schemas/clickPositions" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/clicks/clickThroughRate": { - "get": { - "tags": ["analytics"], - "operationId": "getClickThroughRate", - "x-acl": ["analytics"], - "summary": "Retrieve click-through rate", - "description": "Retrieves the click-through rate (CTR) for all your searches with at least one click event, including a daily breakdown.\n\nBy default, the analyzed period includes the last eight days including the current day.\n\n**There's a difference between a 0 and null CTR when `clickAnalytics` is enabled:**\n\n- **Null** means there were no queries: since Algolia didn't receive any events, CTR is null.\n- **0** mean there _were_ queries but no [click events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getClickThroughRateResponse", - "type": "object", - "additionalProperties": false, - "required": ["dates", "clickCount", "trackedSearchCount", "rate"], - "properties": { - "rate": { - "$ref": "#/components/schemas/clickThroughRate" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "dates": { - "type": "array", - "description": "Daily click-through rates.", - "items": { - "title": "dailyClickThroughRates", - "type": "object", - "additionalProperties": false, - "required": ["rate", "clickCount", "trackedSearchCount", "date"], - "properties": { - "rate": { - "$ref": "#/components/schemas/clickThroughRate" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "date": { - "$ref": "#/components/schemas/date" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/conversions/conversionRate": { - "get": { - "tags": ["analytics"], - "operationId": "getConversionRate", - "x-acl": ["analytics"], - "summary": "Retrieve conversion rate", - "description": "Retrieves the conversion rate (CR) for all your searches with at least one conversion event, including a daily breakdown.\n\nBy default, the analyzed period includes the last eight days including the current day.\n\n**There's a difference between a 0 and null CR when `clickAnalytics` is enabled:**\n\n- **Null** means there were no queries: since Algolia didn't receive any events, CR is null.\n- **0** mean there _were_ queries but no [conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getConversionRateResponse", - "type": "object", - "additionalProperties": false, - "required": ["dates", "trackedSearchCount", "conversionCount", "rate"], - "properties": { - "rate": { - "$ref": "#/components/schemas/conversionRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "conversionCount": { - "$ref": "#/components/schemas/conversionCount" - }, - "dates": { - "type": "array", - "description": "Daily conversion rates.", - "items": { - "title": "dailyConversionRates", - "type": "object", - "additionalProperties": false, - "required": ["rate", "trackedSearchCount", "conversionCount", "date"], - "properties": { - "rate": { - "$ref": "#/components/schemas/conversionRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "conversionCount": { - "$ref": "#/components/schemas/conversionCount" - }, - "date": { - "$ref": "#/components/schemas/date" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/conversions/addToCartRate": { - "get": { - "tags": ["analytics"], - "operationId": "getAddToCartRate", - "x-acl": ["analytics"], - "summary": "Retrieve add-to-cart rate", - "description": "Retrieves the add-to-cart rate for all your searches with at least one add-to-cart event, including a daily breakdown.\n\nBy default, the analyzed period includes the last eight days including the current day.\n\nThe rate is the number of add-to-cart conversion events divided by the number of tracked searches.\nA search is tracked if it returns a queryID (`clickAnalytics` is `true`).\nThis differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`.\n\n**There's a difference between a 0 and null add-to-cart rate when `clickAnalytics` is enabled:**\n\n- **Null** means there were no queries: since Algolia didn't receive any events, the add-to-cart rate is null.\n- **0** mean there _were_ queries but no [add-to-cart events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getAddToCartRateResponse", - "type": "object", - "additionalProperties": false, - "required": ["dates", "trackedSearchCount", "addToCartCount", "rate"], - "properties": { - "rate": { - "$ref": "#/components/schemas/addToCartRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "addToCartCount": { - "$ref": "#/components/schemas/addToCartCount" - }, - "dates": { - "type": "array", - "description": "Daily add-to-cart rates.", - "items": { - "title": "dailyAddToCartRates", - "type": "object", - "additionalProperties": false, - "required": ["rate", "trackedSearchCount", "addToCartCount", "date"], - "properties": { - "rate": { - "$ref": "#/components/schemas/addToCartRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "addToCartCount": { - "$ref": "#/components/schemas/addToCartCount" - }, - "date": { - "$ref": "#/components/schemas/date" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/conversions/purchaseRate": { - "get": { - "tags": ["analytics"], - "operationId": "getPurchaseRate", - "x-acl": ["analytics"], - "summary": "Retrieve purchase rate", - "description": "Retrieves the purchase rate for all your searches with at least one purchase event, including a daily breakdown.\n\nBy default, the analyzed period includes the last eight days including the current day.\n\nThe rate is the number of purchase conversion events divided by the number of tracked searches.\nA search is tracked if it returns a query ID (`clickAnalytics` is `true`).\nThis differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`.\n\n**There's a difference between a 0 and null purchase rate when `clickAnalytics` is enabled:**\n\n- **Null** means there were no queries: since Algolia didn't receive any events, the purchase rate is null.\n- **0** mean there _were_ queries but no [purchase conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "headers": { - "x-ratelimit-limit": { - "$ref": "#/components/headers/x-ratelimit-limit" - }, - "x-ratelimit-remaining": { - "$ref": "#/components/headers/x-ratelimit-remaining" - }, - "x-ratelimit-reset": { - "$ref": "#/components/headers/x-ratelimit-reset" - } - }, - "content": { - "application/json": { - "schema": { - "title": "getPurchaseRateResponse", - "type": "object", - "additionalProperties": false, - "required": ["dates", "trackedSearchCount", "purchaseCount", "rate"], - "properties": { - "rate": { - "$ref": "#/components/schemas/purchaseRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "purchaseCount": { - "$ref": "#/components/schemas/purchaseCount" - }, - "dates": { - "type": "array", - "description": "Daily purchase rates.", - "items": { - "title": "dailyPurchaseRates", - "type": "object", - "additionalProperties": false, - "required": ["rate", "trackedSearchCount", "purchaseCount", "date"], - "properties": { - "rate": { - "$ref": "#/components/schemas/purchaseRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "purchaseCount": { - "$ref": "#/components/schemas/purchaseCount" - }, - "date": { - "$ref": "#/components/schemas/date" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/conversions/revenue": { - "get": { - "tags": ["analytics"], - "operationId": "getRevenue", - "x-acl": ["analytics"], - "summary": "Retrieve revenue data", - "description": "Retrieves revenue-related metrics, such as the total revenue or the average order value.\n\nTo retrieve revenue-related metrics, send purchase events.\nBy default, the analyzed period includes the last eight days including the current day.\n\nRevenue is based on purchase conversion events (a conversion event with an `eventSubtype` attribute of `purchase`).\nThe revenue is the `price` attribute multiplied by the `quantity` attribute for each object in the event's `objectData` array.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - }, - { - "$ref": "#/components/parameters/StartDate" - }, - { - "$ref": "#/components/parameters/EndDate" - }, - { - "$ref": "#/components/parameters/Tags" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getRevenue", - "type": "object", - "additionalProperties": false, - "required": ["currencies", "dates"], - "properties": { - "currencies": { - "$ref": "#/components/schemas/currencies" - }, - "dates": { - "type": "array", - "description": "Daily revenue.", - "items": { - "title": "dailyRevenue", - "type": "object", - "additionalProperties": false, - "required": ["currencies", "date"], - "properties": { - "currencies": { - "$ref": "#/components/schemas/currencies" - }, - "date": { - "$ref": "#/components/schemas/date" - } - } - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/2/status": { - "get": { - "tags": ["analytics"], - "operationId": "getStatus", - "x-acl": ["analytics"], - "summary": "Retrieve update status", - "description": "Retrieves the time when the Analytics data for the specified index was last updated.\n\nIf the index has been recently created or no search has been performed yet the updated time is `null`.\n\nThe Analytics data is updated every 5 minutes.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Index" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getStatusResponse", - "type": "object", - "additionalProperties": false, - "required": ["updatedAt"], - "properties": { - "updatedAt": { - "$ref": "#/components/schemas/updatedAtNullable" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/setClientApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["analytics"], - "operationId": "setClientApiKey", - "summary": "Switch the API key used to authenticate requests", - "description": "Switch the API key used to authenticate requests.\n", - "parameters": [ - { - "in": "query", - "name": "apiKey", - "description": "API key to be used from now on.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No content." - } - } - } - } - }, - "components": { - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-application-id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-api-key", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - }, - "parameters": { - "PathInPath": { - "name": "path", - "in": "path", - "description": "Path of the endpoint, anything after \"/1\" must be specified.", - "required": true, - "schema": { - "type": "string", - "example": "/keys" - } - }, - "Parameters": { - "name": "parameters", - "in": "query", - "description": "Query parameters to apply to the current query.", - "schema": { - "type": "object", - "additionalProperties": true - } - }, - "Index": { - "in": "query", - "name": "index", - "description": "Index name.", - "required": true, - "schema": { - "type": "string", - "example": "ALGOLIA_INDEX_NAME" - } - }, - "ClickAnalytics": { - "in": "query", - "name": "clickAnalytics", - "description": "Whether to include metrics related to click and conversion events in the response.", - "schema": { - "type": "boolean", - "default": false - } - }, - "RevenueAnalytics": { - "in": "query", - "name": "revenueAnalytics", - "description": "Whether to include metrics related to revenue events in the response.", - "schema": { - "type": "boolean", - "default": false - } - }, - "StartDate": { - "in": "query", - "name": "startDate", - "description": "Start date of the period to analyze, in `YYYY-MM-DD` format.", - "schema": { - "type": "string", - "example": "2022-09-19" - } - }, - "EndDate": { - "in": "query", - "name": "endDate", - "description": "End date of the period to analyze, in `YYYY-MM-DD` format.", - "schema": { - "type": "string", - "example": "2023-01-21" - } - }, - "OrderBy": { - "in": "query", - "name": "orderBy", - "description": "Attribute by which to order the response items.\n\nIf the `clickAnalytics` parameter is false, only `searchCount` is available.\n", - "schema": { - "$ref": "#/components/schemas/orderBy" - } - }, - "Direction": { - "in": "query", - "name": "direction", - "description": "Sorting direction of the results: ascending or descending.\n", - "schema": { - "$ref": "#/components/schemas/direction" - } - }, - "Limit": { - "in": "query", - "name": "limit", - "description": "Number of items to return.\n", - "required": false, - "schema": { - "type": "integer", - "default": 10, - "maximum": 1000 - } - }, - "Offset": { - "in": "query", - "name": "offset", - "description": "Position of the first item to return.\n", - "required": false, - "schema": { - "type": "integer", - "default": 0, - "minimum": 0 - } - }, - "Tags": { - "name": "tags", - "in": "query", - "description": "Tags by which to segment the analytics.\n\nYou can combine multiple tags with `OR` and `AND`.\nTags must be URL-encoded.\nFor more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).\n", - "example": "device:mobile%20phone", - "schema": { - "type": "string" - } - }, - "Search": { - "in": "query", - "name": "search", - "description": "Search query.", - "example": "enable ab test", - "schema": { - "type": "string" - } - }, - "Attribute": { - "in": "path", - "name": "attribute", - "description": "Attribute name.", - "required": true, - "schema": { - "type": "string", - "example": "brand" - } - } - }, - "schemas": { - "ErrorBase": { - "description": "Error.", - "type": "object", - "x-keep-model": true, - "additionalProperties": true, - "properties": { - "message": { - "type": "string", - "example": "Invalid Application-Id or API-Key" - } - } - }, - "orderBy": { - "type": "string", - "description": "Attribute by which to order the response items.\n\nIf the `clickAnalytics` parameter is false, only `searchCount` is available.\n", - "enum": ["searchCount", "clickThroughRate", "conversionRate", "averageClickPosition"], - "default": "searchCount" - }, - "direction": { - "type": "string", - "enum": ["asc", "desc"], - "default": "asc" - }, - "search": { - "description": "Search query.", - "example": "separator", - "type": "string" - }, - "count": { - "description": "Number of searches.", - "type": "integer", - "example": 504 - }, - "nbHits": { - "type": "integer", - "description": "Number of results (hits).", - "example": 20 - }, - "topSearchesResponse": { - "type": "object", - "title": "Top searches", - "additionalProperties": false, - "required": ["searches"], - "properties": { - "searches": { - "type": "array", - "description": "Most popular searches and their number of search results (hits).", - "items": { - "title": "topSearch", - "type": "object", - "additionalProperties": false, - "required": ["search", "count", "nbHits"], - "properties": { - "search": { - "$ref": "#/components/schemas/search" - }, - "count": { - "$ref": "#/components/schemas/count" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - } - } - } - } - } - }, - "clickThroughRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "Click-through rate: calculated as the number of tracked searches with at least one click event divided by the number of tracked searches.\nIf null, Algolia didn't receive any search requests with `clickAnalytics` set to true.\n", - "minimum": 0, - "maximum": 1, - "default": null, - "example": 0.49 - }, - { - "type": "null" - } - ] - }, - "averageClickPosition": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "Average position of a clicked search result in the list of search results.\nIf null, Algolia didn't receive any search requests with `clickAnalytics` set to true.\n", - "minimum": 1, - "example": 2.035, - "default": null - }, - { - "type": "null" - } - ] - }, - "clickPositions": { - "type": "array", - "description": "List of positions in the search results and clicks associated with this search.", - "minItems": 12, - "maxItems": 12, - "items": { - "title": "clickPosition", - "type": "object", - "description": "Click position.", - "properties": { - "position": { - "type": "array", - "description": "Range of positions in the search results, using the pattern `[start,end]`.\n\nFor positions 11 and up, click events are summed over the specified range.\n`-1` indicates the end of the list of search results.\n", - "minItems": 2, - "maxItems": 2, - "example": [21, -1], - "items": { - "type": "integer" - } - }, - "clickCount": { - "type": "integer", - "description": "Number of times this search has been clicked at that position.", - "example": 24, - "minimum": 0, - "default": 0 - } - } - } - }, - "conversionRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "Conversion rate: calculated as the number of tracked searches with at least one conversion event divided by the number of tracked searches.\nIf null, Algolia didn't receive any search requests with `clickAnalytics` set to true.\n", - "minimum": 0, - "maximum": 1, - "default": null, - "example": 0.05 - }, - { - "type": "null" - } - ] - }, - "trackedSearchCount": { - "type": "integer", - "example": 2, - "default": 0, - "description": "Number of tracked searches. Tracked searches are search requests where the `clickAnalytics` parameter is true." - }, - "clickCount": { - "type": "integer", - "description": "Number of clicks associated with this search.", - "example": 162, - "minimum": 0, - "default": 0 - }, - "conversionCount": { - "type": "integer", - "description": "Number of conversions from this search.", - "example": 10, - "minimum": 0, - "default": 0 - }, - "topSearchesResponseWithAnalytics": { - "type": "object", - "title": "Top searches with click analytics", - "additionalProperties": false, - "required": ["searches"], - "properties": { - "searches": { - "type": "array", - "description": "Most popular searches and their associated click and conversion metrics.", - "items": { - "title": "topSearchWithAnalytics", - "type": "object", - "additionalProperties": false, - "required": [ - "search", - "count", - "nbHits", - "clickThroughRate", - "averageClickPosition", - "clickPositions", - "conversionRate", - "trackedSearchCount", - "clickCount", - "conversionCount" - ], - "properties": { - "search": { - "$ref": "#/components/schemas/search" - }, - "count": { - "$ref": "#/components/schemas/count" - }, - "clickThroughRate": { - "$ref": "#/components/schemas/clickThroughRate" - }, - "averageClickPosition": { - "$ref": "#/components/schemas/averageClickPosition" - }, - "clickPositions": { - "$ref": "#/components/schemas/clickPositions" - }, - "conversionRate": { - "$ref": "#/components/schemas/conversionRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "conversionCount": { - "$ref": "#/components/schemas/conversionCount" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - } - } - } - } - } - }, - "currencies": { - "type": "object", - "description": "Revenue associated with this search: broken down by currency.\n", - "default": {}, - "additionalProperties": { - "title": "currencyCode", - "x-additionalPropertiesName": "currency", - "type": "object", - "description": "Currency code.", - "properties": { - "currency": { - "type": "string", - "description": "Currency code.", - "example": "USD" - }, - "revenue": { - "type": "number", - "format": "float", - "description": "Revenue associated with this search in this currency.", - "example": 999.98 - } - } - } - }, - "addToCartRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "Add-to-cart rate: calculated as the number of tracked searches with at least one add-to-cart event divided by the number of tracked searches.\nIf null, Algolia didn't receive any search requests with `clickAnalytics` set to true.\n", - "minimum": 0, - "maximum": 1, - "default": null, - "example": 0.1 - }, - { - "type": "null" - } - ] - }, - "addToCartCount": { - "type": "integer", - "description": "Number of add-to-cart events from this search.", - "minimum": 0, - "default": 0, - "example": 10 - }, - "purchaseRate": { - "oneOf": [ - { - "type": "number", - "format": "double", - "description": "Purchase rate: calculated as the number of tracked searches with at least one purchase event divided by the number of tracked searches.\nIf null, Algolia didn't receive any search requests with `clickAnalytics` set to true.\n", - "minimum": 0, - "maximum": 1, - "default": null, - "example": 0.05 - }, - { - "type": "null" - } - ] - }, - "purchaseCount": { - "type": "integer", - "description": "Number of purchase events from this search.", - "default": 0, - "example": 10 - }, - "topSearchesResponseWithRevenueAnalytics": { - "type": "object", - "title": "Top searches with revenue analytics", - "additionalProperties": false, - "required": ["searches"], - "properties": { - "searches": { - "type": "array", - "description": "Most popular searches, including their click and revenue metrics.", - "items": { - "title": "topSearchWithRevenueAnalytics", - "type": "object", - "additionalProperties": false, - "required": [ - "search", - "count", - "nbHits", - "clickThroughRate", - "averageClickPosition", - "clickPositions", - "conversionRate", - "trackedSearchCount", - "clickCount", - "conversionCount", - "currencies", - "addToCartRate", - "addToCartCount", - "purchaseRate", - "purchaseCount" - ], - "properties": { - "search": { - "$ref": "#/components/schemas/search" - }, - "count": { - "$ref": "#/components/schemas/count" - }, - "clickThroughRate": { - "$ref": "#/components/schemas/clickThroughRate" - }, - "averageClickPosition": { - "$ref": "#/components/schemas/averageClickPosition" - }, - "clickPositions": { - "$ref": "#/components/schemas/clickPositions" - }, - "conversionRate": { - "$ref": "#/components/schemas/conversionRate" - }, - "trackedSearchCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "conversionCount": { - "$ref": "#/components/schemas/conversionCount" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - }, - "currencies": { - "$ref": "#/components/schemas/currencies" - }, - "addToCartRate": { - "$ref": "#/components/schemas/addToCartRate" - }, - "addToCartCount": { - "$ref": "#/components/schemas/addToCartCount" - }, - "purchaseRate": { - "$ref": "#/components/schemas/purchaseRate" - }, - "purchaseCount": { - "$ref": "#/components/schemas/purchaseCount" - } - } - } - } - } - }, - "getTopSearchesResponse": { - "oneOf": [ - { - "$ref": "#/components/schemas/topSearchesResponse" - }, - { - "$ref": "#/components/schemas/topSearchesResponseWithAnalytics" - }, - { - "$ref": "#/components/schemas/topSearchesResponseWithRevenueAnalytics" - } - ] - }, - "parameters_count": { - "description": "Number of occurrences.", - "example": 2, - "type": "integer" - }, - "date": { - "type": "string", - "description": "Date in the format YYYY-MM-DD.", - "example": "2023-06-14" - }, - "withFilterCount": { - "type": "integer", - "description": "Number of searches for this term with applied filters.", - "example": 5, - "minimum": 0, - "default": 0 - }, - "noResultsRate": { - "type": "number", - "format": "double", - "description": "No results rate: calculated as the number of searches with zero results divided by the total number of searches.\n", - "minimum": 0, - "maximum": 1, - "example": 0.49 - }, - "noResultCount": { - "description": "Number of searches without any results.", - "type": "integer", - "example": 54 - }, - "noClickRate": { - "type": "number", - "format": "double", - "description": "No click rate: calculated as the number of tracked searches without clicks divided by the number of tracked searches.\n", - "minimum": 0, - "maximum": 1, - "example": 0.15 - }, - "noClickCount": { - "type": "integer", - "description": "Number of times this search was returned as a result without any click.", - "example": 15, - "minimum": 1 - }, - "hit": { - "description": "Object ID of a record returned as a search result.", - "type": "string", - "example": "method-export-rules-php" - }, - "topHitsResponse": { - "type": "object", - "title": "Top search results", - "additionalProperties": false, - "required": ["hits"], - "properties": { - "hits": { - "type": "array", - "description": "Most frequent search results.", - "items": { - "title": "topHit", - "type": "object", - "additionalProperties": false, - "required": ["hit", "count"], - "properties": { - "hit": { - "$ref": "#/components/schemas/hit" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - } - } - } - } - } - }, - "topHitsResponseWithAnalytics": { - "type": "object", - "title": "Top search results with click analytics", - "additionalProperties": false, - "required": ["hits"], - "properties": { - "hits": { - "type": "array", - "description": "Most frequent search results with click and conversion metrics.", - "items": { - "title": "topHitWithAnalytics", - "type": "object", - "additionalProperties": false, - "required": [ - "hit", - "count", - "clickThroughRate", - "conversionRate", - "trackedHitCount", - "clickCount", - "conversionCount" - ], - "properties": { - "hit": { - "$ref": "#/components/schemas/hit" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - }, - "clickThroughRate": { - "$ref": "#/components/schemas/clickThroughRate" - }, - "conversionRate": { - "$ref": "#/components/schemas/conversionRate" - }, - "trackedHitCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "conversionCount": { - "$ref": "#/components/schemas/conversionCount" - } - } - } - } - } - }, - "topHitsResponseWithRevenueAnalytics": { - "type": "object", - "title": "Top search results with revenue analytics", - "additionalProperties": false, - "required": ["hits"], - "properties": { - "hits": { - "type": "array", - "description": "Most frequent search results with click, conversion, and revenue metrics.", - "items": { - "title": "topHitWithRevenueAnalytics", - "type": "object", - "additionalProperties": false, - "required": [ - "hit", - "count", - "clickThroughRate", - "conversionRate", - "trackedHitCount", - "clickCount", - "conversionCount", - "purchaseCount", - "addToCartCount", - "purchaseRate", - "addToCartRate", - "currencies" - ], - "properties": { - "hit": { - "$ref": "#/components/schemas/hit" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - }, - "clickThroughRate": { - "$ref": "#/components/schemas/clickThroughRate" - }, - "conversionRate": { - "$ref": "#/components/schemas/conversionRate" - }, - "trackedHitCount": { - "$ref": "#/components/schemas/trackedSearchCount" - }, - "clickCount": { - "$ref": "#/components/schemas/clickCount" - }, - "conversionCount": { - "$ref": "#/components/schemas/conversionCount" - }, - "addToCartRate": { - "$ref": "#/components/schemas/addToCartRate" - }, - "addToCartCount": { - "$ref": "#/components/schemas/addToCartCount" - }, - "purchaseRate": { - "$ref": "#/components/schemas/purchaseRate" - }, - "purchaseCount": { - "$ref": "#/components/schemas/purchaseCount" - }, - "currencies": { - "$ref": "#/components/schemas/currencies" - } - } - } - } - } - }, - "getTopHitsResponse": { - "oneOf": [ - { - "$ref": "#/components/schemas/topHitsResponse" - }, - { - "$ref": "#/components/schemas/topHitsResponseWithAnalytics" - }, - { - "$ref": "#/components/schemas/topHitsResponseWithRevenueAnalytics" - } - ] - }, - "attribute": { - "description": "Attribute name.", - "type": "string", - "example": "url" - }, - "getTopFilterAttribute": { - "type": "object", - "additionalProperties": false, - "required": ["attribute", "count"], - "properties": { - "attribute": { - "$ref": "#/components/schemas/attribute" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - } - } - }, - "getTopFilterAttributesResponse": { - "type": "object", - "additionalProperties": false, - "required": ["attributes"], - "properties": { - "attributes": { - "type": "array", - "description": "Most frequent filters.", - "items": { - "$ref": "#/components/schemas/getTopFilterAttribute" - } - } - } - }, - "operator": { - "description": "Character that characterizes how the filter is applied.\n\nFor example, for a facet filter `facet:value`, `:` is the operator.\nFor a numeric filter `count>50`, `>` is the operator.\n", - "type": "string", - "enum": [":", "<", "<=", "=", "!=", ">", ">="], - "example": ":" - }, - "value": { - "description": "Attribute value.", - "type": "string", - "example": "integration" - }, - "getTopFilterForAttribute": { - "type": "object", - "additionalProperties": false, - "required": ["operator", "attribute", "value", "count"], - "properties": { - "attribute": { - "$ref": "#/components/schemas/attribute" - }, - "operator": { - "$ref": "#/components/schemas/operator" - }, - "value": { - "$ref": "#/components/schemas/value" - }, - "count": { - "$ref": "#/components/schemas/parameters_count" - } - } - }, - "getTopFilterForAttributeResponse": { - "type": "object", - "additionalProperties": false, - "required": ["values"], - "properties": { - "values": { - "type": "array", - "description": "Filter values for an attribute.", - "items": { - "$ref": "#/components/schemas/getTopFilterForAttribute" - } - } - } - }, - "getTopFiltersNoResultsValue": { - "type": "object", - "additionalProperties": false, - "required": ["attribute", "operator", "value"], - "properties": { - "attribute": { - "$ref": "#/components/schemas/attribute" - }, - "operator": { - "$ref": "#/components/schemas/operator" - }, - "value": { - "$ref": "#/components/schemas/value" - } - } - }, - "getTopFiltersNoResultsValues": { - "type": "object", - "additionalProperties": false, - "required": ["values", "count"], - "properties": { - "count": { - "$ref": "#/components/schemas/parameters_count" - }, - "values": { - "type": "array", - "description": "Filters with no results.", - "items": { - "$ref": "#/components/schemas/getTopFiltersNoResultsValue" - } - } - } - }, - "getTopFiltersNoResultsResponse": { - "type": "object", - "additionalProperties": false, - "required": ["values"], - "properties": { - "values": { - "oneOf": [ - { - "type": "array", - "description": "Filters for searches without any results.\nIf null, the search term specified with the `search` parameter isn't a search without results,\nor the `search` parameter is absent from the request.\n", - "items": { - "$ref": "#/components/schemas/getTopFiltersNoResultsValues" - } - }, - { - "type": "null" - } - ] - } - } - }, - "updatedAtNullable": { - "oneOf": [ - { - "type": "string", - "default": null, - "description": "Date and time when the object was updated, in RFC 3339 format.", - "example": "2023-07-04T12:49:15Z" - }, - { - "type": "null" - } - ] - } - }, - "responses": { - "BadRequest": { - "description": "Bad request or request arguments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "FeatureNotEnabled": { - "description": "This feature is not enabled on your Algolia account.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "MethodNotAllowed": { - "description": "Method not allowed with this API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "IndexNotFound": { - "description": "Index not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - } - }, - "headers": { - "x-ratelimit-limit": { - "description": "Number of allowed requests per one minute.", - "example": 100, - "schema": { - "type": "integer" - } - }, - "x-ratelimit-remaining": { - "description": "Number of remaining requests in the current period.", - "example": 99, - "schema": { - "type": "integer" - } - }, - "x-ratelimit-reset": { - "description": "Timstamp when the rate limit will reset, measured in seconds since the Unix epoch.", - "example": 1710682486, - "schema": { - "type": "integer" - } - } - } - }, - "x-tagGroups": [ - { - "name": "Metrics", - "tags": ["search", "click", "revenue", "filter", "user"] - }, - { - "name": "Other", - "tags": ["status"] - } - ] -} diff --git a/src/data/collections.json b/src/data/collections.json deleted file mode 100644 index 36fff66..0000000 --- a/src/data/collections.json +++ /dev/null @@ -1,523 +0,0 @@ -{ - "openapi": "3.0.3", - "info": { - "title": "Collections API", - "description": "The Open API spec for Collections", - "version": "1.0.0", - "termsOfService": "https://www.algolia.com/policies/terms", - "license": { - "name": "unlicensed", - "url": "https://www.algolia.com" - } - }, - "servers": [ - { - "url": "https://experiences.algolia.com", - "description": "prod" - } - ], - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ], - "paths": { - "/1/collections": { - "get": { - "summary": "Get all collections", - "description": "Retrieve a list of all collections", - "operationId": "listCollections", - "tags": ["Collections"], - "parameters": [ - { - "name": "indexName", - "in": "query", - "required": true, - "schema": { - "type": "string" - }, - "description": "Name of the index" - }, - { - "name": "offset", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 0 - }, - "description": "Number of items to skip (default to 0)" - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 10 - }, - "description": "Number of items per fetch (defaults to 10)" - }, - { - "name": "query", - "in": "query", - "required": false, - "schema": { - "type": "string" - }, - "description": "Query to filter collections" - } - ], - "responses": { - "200": { - "description": "A list of collections", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Collection" - } - }, - "total": { - "type": "integer", - "description": "Total number of items" - }, - "offset": { - "type": "integer", - "description": "Offset used in this query" - }, - "limit": { - "type": "integer", - "description": "Limit used in this query" - } - } - } - } - } - }, - "404": { - "description": "Application or index not found" - } - } - }, - "post": { - "summary": "Upserts a collection", - "description": "Upserts a collection", - "operationId": "upsertCollection", - "tags": ["Collections"], - "parameters": [ - { - "name": "id", - "in": "body", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "indexName", - "in": "body", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "name", - "in": "body", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "description", - "in": "body", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "add", - "in": "body", - "required": false, - "schema": { - "type": "array", - "description": "a list of objectIDs", - "minItems": 0, - "items": { - "type": "string" - } - } - }, - { - "name": "remove", - "in": "body", - "required": false, - "schema": { - "type": "array", - "description": "a list of objectIDs", - "minItems": 0, - "items": { - "type": "string" - } - } - }, - { - "name": "conditions", - "in": "body", - "required": false, - "schema": { - "$ref": "#/components/schemas/Conditions" - } - } - ], - "responses": { - "200": { - "description": "Collection updated", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Collection" - } - } - } - }, - "201": { - "description": "Collection created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Collection" - } - } - } - } - } - } - }, - "/1/collections/{id}": { - "get": { - "summary": "Get collections by ID", - "description": "Retrieve a collection by ID", - "operationId": "getCollection", - "tags": ["Collections"], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "The requested collection", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Collection" - } - } - } - }, - "404": { - "description": "Collection not found" - } - } - }, - "delete": { - "summary": "Delete a collection by ID", - "description": "Soft deletes a collection by setting `deleted` to true.", - "operationId": "deleteCollection", - "tags": ["Collections"], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Collection deleted successfully" - }, - "404": { - "description": "Collection not found" - } - } - } - }, - "/1/collections/{id}/commit": { - "post": { - "summary": "Evaluates the changes on a collection and replicates them to the index", - "description": "Evaluates the changes on a collection and replicates them to the index", - "operationId": "commitCollection", - "tags": ["Collections"], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "Collection committing started", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "job_id": { - "type": "string" - } - } - } - } - } - }, - "404": { - "description": "Collection not found" - } - } - } - } - }, - "components": { - "schemas": { - "Experience": { - "type": "object", - "required": ["id", "name", "indexName", "createdAt", "updatedAt"], - "properties": { - "id": { - "type": "string", - "example": "5db3039e-04b5-4ed6-a00e-ba3304032c5a" - }, - "name": { - "type": "string", - "example": "Summer Deals" - }, - "indexName": { - "type": "string", - "example": "prod_products_EN" - }, - "createdAt": { - "type": "string", - "format": "date-time", - "example": "2024-10-07T00:00:00Z" - }, - "updatedAt": { - "type": "string", - "format": "date-time", - "example": "2024-10-07T00:00:00Z" - }, - "blocks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExperienceBlock" - } - } - } - }, - "ExperienceInput": { - "type": "object", - "required": [ - "id", - "name", - "applicationId", - "indexName", - "createdAt", - "updatedAt", - "commited", - "deleted" - ], - "properties": { - "id": { - "type": "string", - "example": "5db3039e-04b5-4ed6-a00e-ba3304032c5a" - }, - "name": { - "type": "string", - "example": "Summer Deals" - }, - "indexName": { - "type": "string", - "example": "prod_products_EN" - }, - "blocks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExperienceBlock" - } - } - } - }, - "ExperienceBlock": { - "type": "object", - "properties": { - "type": { - "type": "string", - "example": "ais.index" - }, - "parameters": { - "type": "object", - "example": { - "indexName": "prod_products_EN" - } - }, - "children": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ExperienceBlock" - }, - "example": [ - { - "type": "ais.configure", - "parameters": { - "hitsPerPage": 12 - } - }, - { - "type": "ais.hits" - } - ] - } - } - }, - "Collection": { - "type": "object", - "required": ["id", "name", "indexName", "createdAt", "updatedAt"], - "properties": { - "id": { - "type": "string", - "example": "5db3039e-04b5-4ed6-a00e-ba3304032c5a" - }, - "name": { - "type": "string", - "example": "Summer Deals" - }, - "indexName": { - "type": "string", - "example": "prod_products_EN" - }, - "createdAt": { - "type": "string", - "format": "date-time", - "example": "2024-10-07T00:00:00Z" - }, - "updatedAt": { - "type": "string", - "format": "date-time", - "example": "2024-10-07T00:00:00Z" - }, - "status": { - "type": "string", - "description": "Collection commit status.\nOnly returned if the request API key has write ACLs.\n", - "enum": ["COMMITTED", "COMMITTING", "TO_COMMIT"] - }, - "conditions": { - "type": "object", - "$ref": "#/components/schemas/Conditions" - }, - "records": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "Conditions": { - "type": "object", - "description": "conditions to filter records.", - "properties": { - "facetFilters": { - "type": "array", - "description": "one-level nested array. A nesting indicates OR, filters combined with AND top-level", - "items": { - "oneOf": [ - { - "type": "string", - "pattern": "/^[^:]+[^\\\\]*:.+$/", - "example": "brand:Apple", - "examples": { - "normal": { - "value": "brand:Apple", - "summary": "include Apple in the results" - }, - "negated": { - "value": "brand:-Apple", - "summary": "exclude Apple from the results" - }, - "escaped": { - "value": "discount:\\-50%", - "summary": "include \"-50%\" in the results" - } - } - }, - { - "type": "array", - "items": { - "type": "string", - "pattern": "/^[^:]+[^\\\\]*:.+$/", - "example": "brand:Samsung" - } - } - ] - } - }, - "numericFilters": { - "type": "array", - "description": "one-level nested array. A nesting indicates OR, filters combined with AND top-level", - "items": { - "oneOf": [ - { - "type": "string", - "pattern": "/(^[^:]+[^\\\\]*:\\d*\\.?\\d* TO \\d*\\.?\\d*$)|(^[^:]+[^\\\\]*(<|<=|=|>=|>)\\d*\\.?\\d*$)/", - "example": "price:5 TO 10" - }, - { - "type": "array", - "items": { - "type": "string", - "pattern": "/(^[^:]+[^\\\\]*:\\d*\\.?\\d* TO \\d*\\.?\\d*$)|(^[^:]+[^\\\\]*(<|<=|=|>=|>)\\d*\\.?\\d*$)/", - "example": "rating<=4.3" - } - } - ] - } - } - } - } - }, - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "name": "X-ALGOLIA-APPLICATION-ID", - "in": "header", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "name": "X-ALGOLIA-API-KEY", - "in": "header", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - } - } -} diff --git a/src/data/ingestion.json b/src/data/ingestion.json deleted file mode 100644 index 6dc8ce4..0000000 --- a/src/data/ingestion.json +++ /dev/null @@ -1,5277 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "Ingestion API", - "description": "The Ingestion API lets you connect third-party services and platforms with Algolia and schedule tasks to ingest your data.\nThe Ingestion API powers the no-code [data connectors](https://dashboard.algolia.com/connectors).\n\n## Base URLs\n\nThe base URLs for requests to the Ingestion API are:\n\n- `https://data.us.algolia.com`\n- `https://data.eu.algolia.com`\n\nUse the URL that matches your [analytics region](https://dashboard.algolia.com/account/infrastructure/analytics).\n\n**All requests must use HTTPS.**\n\n## Authentication\n\nTo authenticate your API requests, add these headers:\n\n- `x-algolia-application-id`. Your Algolia application ID.\n- `x-algolia-api-key`. An API key with the necessary permissions to make the request.\n The required access control list (ACL) to make a request is listed in each endpoint's reference.\n\nYou can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account).\n\n## Request format\n\nRequest bodies must be JSON objects.\n\n## Response status and errors\n\nResponse bodies are JSON objects.\n\nSuccessful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status.\nError responses have a `message` property with more information.\n\n## Version\n\nThe current version of the Ingestion API is version 1, as indicated by the `/1/` in each endpoint's URL.\n", - "version": "1.0.0" - }, - "servers": [ - { - "url": "https://data.{region}.algolia.com", - "variables": { - "region": { - "enum": ["eu", "us"], - "description": "The region where your Algolia application is hosted (either eu or us).", - "default": "us" - } - } - } - ], - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ], - "tags": [ - { - "name": "authentications", - "x-displayName": "Authentications", - "description": "Authentication resources describe how to connect to a source or destination." - }, - { - "name": "destinations", - "x-displayName": "Destinations", - "description": "Destinations are Algolia products or features where your data should be used, such as a search index or events.\nAlgolia destinations require authentication with the `algolia` type.\nYou can reference authentications by their ID when creating destinations.\n" - }, - { - "name": "observability", - "x-displayName": "Observability", - "description": "Check the status and details of your task runs. A run is one instance of a configured task." - }, - { - "name": "sources", - "x-displayName": "Sources", - "description": "Sources are third-party platforms or services from where you want to ingest your data.\nSources may require authentication. To interact with such sources, you can reference an authentication resource by its ID.\n" - }, - { - "name": "tasks", - "x-displayName": "Tasks", - "description": "Tasks contain information how your data should be read from a source and stored in a destination.\nTasks have _triggers_ which determine when the task should run.\n" - }, - { - "name": "transformations", - "x-displayName": "Transformations", - "description": "Transformations allows you to transform a record before it gets indexed in Algolia.\n" - } - ], - "paths": { - "/{path}": { - "get": { - "operationId": "customGet", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["ingestion"] - }, - "post": { - "operationId": "customPost", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["ingestion"] - }, - "put": { - "operationId": "customPut", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["ingestion"] - }, - "delete": { - "operationId": "customDelete", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["ingestion"] - } - }, - "/1/authentications": { - "get": { - "tags": ["ingestion"], - "summary": "List authentication resources", - "description": "Retrieves a list of all authentication resources.", - "operationId": "listAuthentications", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/type" - }, - { - "$ref": "#/components/parameters/platform" - }, - { - "$ref": "#/components/parameters/sort" - }, - { - "$ref": "#/components/parameters/order" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listAuthenticationsResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "authentications": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Authentication" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "required": ["authentications", "pagination"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "post": { - "tags": ["ingestion"], - "summary": "Create an authentication resource", - "description": "Creates a new authentication resource.", - "operationId": "createAuthentication", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AuthenticationCreate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AuthenticationCreateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/authentications/search": { - "post": { - "tags": ["ingestion"], - "summary": "Search for authentication resources", - "description": "Searches for authentication resources.", - "operationId": "searchAuthentications", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AuthenticationSearch" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchAuthenticationsResponse", - "type": "array", - "items": { - "$ref": "#/components/schemas/Authentication" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/authentications/{authenticationID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve an authentication resource", - "description": "Retrieves an authentication resource by its ID.", - "operationId": "getAuthentication", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathAuthenticationID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Authentication" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "patch": { - "tags": ["ingestion"], - "summary": "Update an authentication resource", - "description": "Updates an authentication resource.", - "operationId": "updateAuthentication", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathAuthenticationID" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AuthenticationUpdate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AuthenticationUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "delete": { - "tags": ["ingestion"], - "summary": "Delete an authentication resource", - "description": "Deletes an authentication resource. You can't delete authentication resources that are used by a source or a destination.", - "operationId": "deleteAuthentication", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathAuthenticationID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/destinations": { - "get": { - "tags": ["ingestion"], - "summary": "List destinations", - "description": "Retrieves a list of destinations.", - "operationId": "listDestinations", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/destinationParameters_type" - }, - { - "$ref": "#/components/parameters/authenticationID" - }, - { - "$ref": "#/components/parameters/transformationID" - }, - { - "$ref": "#/components/parameters/destinationParameters_sort" - }, - { - "$ref": "#/components/parameters/order" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listDestinationsResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "destinations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Destination" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "required": ["destinations", "pagination"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "post": { - "tags": ["ingestion"], - "summary": "Create a destination", - "description": "Creates a new destination.", - "operationId": "createDestination", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DestinationCreate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DestinationCreateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/destinations/search": { - "post": { - "tags": ["ingestion"], - "summary": "Search for destinations", - "description": "Searches for destinations.", - "operationId": "searchDestinations", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DestinationSearch" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchDestinationsResponse", - "type": "array", - "items": { - "$ref": "#/components/schemas/Destination" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/destinations/{destinationID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve a destination", - "description": "Retrieves a destination by its ID.", - "operationId": "getDestination", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathDestinationID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Destination" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "patch": { - "tags": ["ingestion"], - "summary": "Update a destination", - "description": "Updates the destination by its ID.", - "operationId": "updateDestination", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathDestinationID" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DestinationUpdate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DestinationUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "delete": { - "tags": ["ingestion"], - "summary": "Delete a destination", - "description": "Deletes a destination by its ID. You can't delete destinations that are referenced in tasks.", - "operationId": "deleteDestination", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathDestinationID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/sources": { - "get": { - "tags": ["ingestion"], - "summary": "List sources", - "description": "Retrieves a list of sources.", - "operationId": "listSources", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/sourceParameters_type" - }, - { - "$ref": "#/components/parameters/sourceParameters_authenticationID" - }, - { - "$ref": "#/components/parameters/sourceParameters_sort" - }, - { - "$ref": "#/components/parameters/order" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listSourcesResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "sources": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Source" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "required": ["sources", "pagination"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "post": { - "tags": ["ingestion"], - "summary": "Create a source", - "description": "Creates a new source.", - "operationId": "createSource", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SourceCreate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SourceCreateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/sources/validate": { - "post": { - "tags": ["ingestion"], - "summary": "Validates a source payload", - "description": "Validates a source payload to ensure it can be created and that the data source can be reached by Algolia.\n", - "operationId": "validateSource", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "x-timeouts": { - "connect": 180000, - "read": 180000, - "write": 180000 - }, - "requestBody": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SourceCreate" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WatchResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/sources/search": { - "post": { - "tags": ["ingestion"], - "summary": "Search for sources", - "description": "Searches for sources.", - "operationId": "searchSources", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SourceSearch" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchSourcesResponse", - "type": "array", - "items": { - "$ref": "#/components/schemas/Source" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/sources/{sourceID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve a source", - "description": "Retrieve a source by its ID.", - "operationId": "getSource", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathSourceID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Source" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "patch": { - "tags": ["ingestion"], - "summary": "Update a source", - "description": "Updates a source by its ID.", - "operationId": "updateSource", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathSourceID" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SourceUpdate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SourceUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "delete": { - "tags": ["ingestion"], - "summary": "Delete a source", - "description": "Deletes a source by its ID. You can't delete sources that are referenced in tasks.", - "operationId": "deleteSource", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathSourceID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/sources/{sourceID}/validate": { - "post": { - "tags": ["ingestion"], - "summary": "Validates an update of a source payload", - "description": "Validates an update of a source payload to ensure it can be created and that the data source can be reached by Algolia.\n", - "operationId": "validateSourceBeforeUpdate", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "x-timeouts": { - "connect": 180000, - "read": 180000, - "write": 180000 - }, - "parameters": [ - { - "$ref": "#/components/parameters/pathSourceID" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SourceUpdate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WatchResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/sources/{sourceID}/discover": { - "post": { - "tags": ["ingestion"], - "summary": "Trigger a stream-listing request", - "description": "Triggers a stream-listing request for a source.\nTriggering stream-listing requests only works with sources with `type: docker` and `imageType: airbyte`.\n", - "operationId": "triggerDockerSourceDiscover", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "x-timeouts": { - "connect": 180000, - "read": 180000, - "write": 180000 - }, - "parameters": [ - { - "$ref": "#/components/parameters/pathSourceID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WatchResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/sources/{sourceID}/run": { - "post": { - "tags": ["ingestion"], - "summary": "Run all tasks linked to a source", - "description": "Runs all tasks linked to a source, only available for Shopify sources. It will create 1 run per task.", - "operationId": "runSource", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathSourceID" - } - ], - "requestBody": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunSourcePayload" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "runSourceResponse", - "type": "object", - "properties": { - "taskWithRunID": { - "type": "object", - "description": "Map of taskID sent for reindex with the corresponding runID.", - "additionalProperties": { - "type": "string" - } - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["taskWithRunID", "createdAt"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/2/tasks": { - "get": { - "tags": ["ingestion"], - "summary": "List tasks", - "description": "Retrieves a list of tasks.", - "operationId": "listTasks", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/action" - }, - { - "$ref": "#/components/parameters/enabled" - }, - { - "$ref": "#/components/parameters/sourceID" - }, - { - "$ref": "#/components/parameters/sourceType" - }, - { - "$ref": "#/components/parameters/destinationID" - }, - { - "$ref": "#/components/parameters/triggerType" - }, - { - "$ref": "#/components/parameters/withEmailNotifications" - }, - { - "$ref": "#/components/parameters/taskParameters_sort" - }, - { - "$ref": "#/components/parameters/order" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listTasksResponse", - "type": "object", - "description": "Configured tasks and pagination information.", - "additionalProperties": false, - "properties": { - "tasks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Task" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "required": ["tasks", "pagination"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "post": { - "tags": ["ingestion"], - "summary": "Create a task", - "description": "Creates a new task.", - "operationId": "createTask", - "requestBody": { - "description": "Request body for creating a task.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskCreate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskCreateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/2/tasks/search": { - "post": { - "tags": ["ingestion"], - "summary": "Search for tasks", - "description": "Searches for tasks.", - "operationId": "searchTasks", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskSearch" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchTasksResponse", - "type": "array", - "items": { - "$ref": "#/components/schemas/Task" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/2/tasks/{taskID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve a task", - "description": "Retrieves a task by its ID.", - "operationId": "getIngestionTask", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Task" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "patch": { - "tags": ["ingestion"], - "summary": "Update a task", - "description": "Updates a task by its ID.", - "operationId": "updateTask", - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "delete": { - "tags": ["ingestion"], - "summary": "Delete a task", - "description": "Deletes a task by its ID.", - "operationId": "deleteTask", - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/2/tasks/{taskID}/run": { - "post": { - "tags": ["ingestion"], - "summary": "Run a task", - "description": "Runs a task. You can check the status of task runs with the observability endpoints.", - "operationId": "runTask", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/2/tasks/{taskID}/push": { - "post": { - "tags": ["ingestion"], - "summary": "Push a `batch` request payload through the Pipeline", - "description": "Push a `batch` request payload through the Pipeline. You can check the status of task pushes with the observability endpoints.", - "operationId": "pushTask", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "x-timeouts": { - "connect": 180000, - "read": 180000, - "write": 180000 - }, - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - }, - { - "name": "watch", - "in": "query", - "description": "When provided, the push operation will be synchronous and the API will wait for the ingestion to be finished before responding.", - "required": false, - "schema": { - "type": "boolean" - } - } - ], - "requestBody": { - "description": "Request body of a Search API `batch` request that will be pushed in the Connectors pipeline.", - "content": { - "application/json": { - "schema": { - "title": "pushTaskPayload", - "type": "object", - "properties": { - "action": { - "$ref": "#/components/schemas/action" - }, - "records": { - "type": "array", - "items": { - "title": "pushTaskRecords", - "type": "object", - "additionalProperties": true, - "required": ["objectID"], - "properties": { - "objectID": { - "$ref": "#/components/schemas/objectID" - } - } - } - } - }, - "required": ["action", "records"] - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WatchResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/2/tasks/{taskID}/enable": { - "put": { - "tags": ["ingestion"], - "summary": "Enable a task", - "description": "Enables a task.", - "operationId": "enableTask", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/2/tasks/{taskID}/disable": { - "put": { - "tags": ["ingestion"], - "summary": "Disable a task", - "description": "Disables a task.", - "operationId": "disableTask", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/tasks": { - "get": { - "tags": ["ingestion"], - "summary": "List tasks V1", - "description": "Retrieves a list of tasks using the v1 endpoint, please use `getTasks` instead.", - "operationId": "listTasksV1", - "deprecated": true, - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/action" - }, - { - "$ref": "#/components/parameters/enabled" - }, - { - "$ref": "#/components/parameters/sourceID" - }, - { - "$ref": "#/components/parameters/destinationID" - }, - { - "$ref": "#/components/parameters/triggerType" - }, - { - "$ref": "#/components/parameters/taskParameters_sort" - }, - { - "$ref": "#/components/parameters/order" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listTasksResponseV1", - "type": "object", - "description": "Configured tasks and pagination information.", - "additionalProperties": false, - "properties": { - "tasks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TaskV1" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "required": ["tasks", "pagination"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "post": { - "tags": ["ingestion"], - "summary": "Create a task V1", - "description": "Creates a new task using the v1 endpoint, please use `createTask` instead.", - "operationId": "createTaskV1", - "deprecated": true, - "x-codegen-request-body-name": "taskCreate", - "requestBody": { - "description": "Request body for creating a task.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskCreateV1" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskCreateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/tasks/search": { - "post": { - "tags": ["ingestion"], - "summary": "Search for tasks V1", - "description": "Searches for tasks using the v1 endpoint, please use `searchTasks` instead.", - "operationId": "searchTasksV1", - "deprecated": true, - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskSearch" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchTasksResponseV1", - "type": "array", - "items": { - "$ref": "#/components/schemas/TaskV1" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/tasks/{taskID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve a task V1", - "description": "Retrieves a task by its ID using the v1 endpoint, please use `getTask` instead.", - "operationId": "getTaskV1", - "deprecated": true, - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskV1" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "patch": { - "tags": ["ingestion"], - "summary": "Update a task V1", - "description": "Updates a task by its ID using the v1 endpoint, please use `updateTask` instead.", - "operationId": "updateTaskV1", - "deprecated": true, - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "x-codegen-request-body-name": "taskUpdate", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdateV1" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "delete": { - "tags": ["ingestion"], - "summary": "Delete a task", - "description": "Deletes a task by its ID using the v1 endpoint, please use `deleteTask` instead.", - "operationId": "deleteTaskV1", - "deprecated": true, - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/tasks/{taskID}/run": { - "post": { - "tags": ["ingestion"], - "summary": "Run a task V1", - "description": "Runs a task using the v1 endpoint, please use `runTask` instead. You can check the status of task runs with the observability endpoints.", - "operationId": "runTaskV1", - "deprecated": true, - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/tasks/{taskID}/enable": { - "put": { - "tags": ["ingestion"], - "summary": "Enable a task V1", - "description": "Enables a task using the v1 endpoint, please use `enableTask` instead.", - "operationId": "enableTaskV1", - "deprecated": true, - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/tasks/{taskID}/disable": { - "put": { - "tags": ["ingestion"], - "summary": "Disable a task V1", - "description": "Disables a task using the v1 endpoint, please use `disableTask` instead.", - "operationId": "disableTaskV1", - "deprecated": true, - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTaskID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/transformations": { - "get": { - "tags": ["ingestion"], - "summary": "List transformations", - "description": "Retrieves a list of transformations. If region is \"de\", use \"eu\" as the region.", - "operationId": "listTransformations", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/transformationParameters_sort" - }, - { - "$ref": "#/components/parameters/order" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listTransformationsResponse", - "type": "object", - "description": "Configured transformations and pagination information.", - "additionalProperties": false, - "properties": { - "transformations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Transformation" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "required": ["transformations", "pagination"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "post": { - "tags": ["ingestion"], - "summary": "Create a transformation", - "description": "Creates a new transformation.", - "operationId": "createTransformation", - "requestBody": { - "description": "Request body for creating a transformation.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationCreate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationCreateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/transformations/try": { - "post": { - "tags": ["ingestion"], - "summary": "Try a transformation before creating it", - "description": "Try a transformation before creating it.", - "operationId": "tryTransformation", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationTry" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationTryResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/transformations/search": { - "post": { - "tags": ["ingestion"], - "summary": "Search for transformations", - "description": "Searches for transformations.", - "operationId": "searchTransformations", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationSearch" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchTransformationsResponse", - "type": "array", - "items": { - "$ref": "#/components/schemas/Transformation" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/transformations/{transformationID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve a transformation", - "description": "Retrieves a transformation by its ID.", - "operationId": "getTransformation", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTransformationID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Transformation" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "put": { - "tags": ["ingestion"], - "summary": "Update a transformation", - "description": "Updates a transformation by its ID.", - "operationId": "updateTransformation", - "parameters": [ - { - "$ref": "#/components/parameters/pathTransformationID" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationCreate" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationUpdateResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - }, - "delete": { - "tags": ["ingestion"], - "summary": "Delete a transformation", - "description": "Deletes a transformation by its ID.", - "operationId": "deleteTransformation", - "parameters": [ - { - "$ref": "#/components/parameters/pathTransformationID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/transformations/{transformationID}/try": { - "post": { - "tags": ["ingestion"], - "summary": "Try a transformation before updating it", - "description": "Try a transformation before updating it.", - "operationId": "tryTransformationBeforeUpdate", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathTransformationID" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationTry" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransformationTryResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/runs": { - "get": { - "tags": ["ingestion"], - "summary": "List task runs", - "description": "Retrieve a list of task runs.", - "operationId": "listRuns", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/runStatus" - }, - { - "$ref": "#/components/parameters/runType" - }, - { - "$ref": "#/components/parameters/taskID" - }, - { - "$ref": "#/components/parameters/runSort" - }, - { - "$ref": "#/components/parameters/order" - }, - { - "name": "startDate", - "in": "query", - "description": "Date in RFC 3339 format for the earliest run to retrieve. By default, the current day minus seven days is used.", - "schema": { - "type": "string" - } - }, - { - "name": "endDate", - "in": "query", - "description": "Date in RFC 3339 format for the latest run to retrieve. By default, the current day is used.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunListResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/runs/{runID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve a task run", - "description": "Retrieve a single task run by its ID.", - "operationId": "getRun", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathRunID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Run" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/runs/{runID}/events": { - "get": { - "tags": ["ingestion"], - "summary": "List task run events", - "description": "Retrieves a list of events for a task run, identified by its ID.", - "operationId": "listEvents", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathRunID" - }, - { - "$ref": "#/components/parameters/itemsPerPage" - }, - { - "$ref": "#/components/parameters/page" - }, - { - "$ref": "#/components/parameters/eventStatus" - }, - { - "$ref": "#/components/parameters/eventType" - }, - { - "$ref": "#/components/parameters/eventSort" - }, - { - "$ref": "#/components/parameters/order" - }, - { - "name": "startDate", - "in": "query", - "description": "Date and time in RFC 3339 format for the earliest events to retrieve. By default, the current time minus three hours is used.", - "schema": { - "type": "string" - } - }, - { - "name": "endDate", - "in": "query", - "description": "Date and time in RFC 3339 format for the latest events to retrieve. By default, the current time is used.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listEventsResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "events": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Event" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - }, - "window": { - "$ref": "#/components/schemas/Window" - } - }, - "required": ["events", "pagination", "window"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/1/runs/{runID}/events/{eventID}": { - "get": { - "tags": ["ingestion"], - "summary": "Retrieve a task run event", - "description": "Retrieves a single task run event by its ID.", - "operationId": "getEvent", - "x-acl": ["addObject", "deleteIndex", "editSettings"], - "parameters": [ - { - "$ref": "#/components/parameters/pathRunID" - }, - { - "$ref": "#/components/parameters/pathEventID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Event" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/setClientApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["ingestion"], - "operationId": "setClientApiKey", - "summary": "Switch the API key used to authenticate requests", - "description": "Switch the API key used to authenticate requests.\n", - "parameters": [ - { - "in": "query", - "name": "apiKey", - "description": "API key to be used from now on.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No content." - } - } - } - } - }, - "components": { - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-application-id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-api-key", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - }, - "parameters": { - "PathInPath": { - "name": "path", - "in": "path", - "description": "Path of the endpoint, anything after \"/1\" must be specified.", - "required": true, - "schema": { - "type": "string", - "example": "/keys" - } - }, - "Parameters": { - "name": "parameters", - "in": "query", - "description": "Query parameters to apply to the current query.", - "schema": { - "type": "object", - "additionalProperties": true - } - }, - "itemsPerPage": { - "name": "itemsPerPage", - "in": "query", - "description": "Number of items per page.", - "required": false, - "schema": { - "$ref": "#/components/schemas/itemsPerPage" - } - }, - "page": { - "name": "page", - "in": "query", - "description": "Page number of the paginated API response.", - "required": false, - "schema": { - "$ref": "#/components/schemas/page" - } - }, - "type": { - "name": "type", - "in": "query", - "description": "Type of authentication resource to retrieve.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AuthenticationType" - }, - "example": "basic,oauth" - } - }, - "platform": { - "name": "platform", - "in": "query", - "description": "Ecommerce platform for which to retrieve authentications.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/platformWithNone" - }, - "example": "commercetools,none" - } - }, - "sort": { - "name": "sort", - "in": "query", - "description": "Property by which to sort the list of authentications.", - "required": false, - "schema": { - "$ref": "#/components/schemas/authenticationSortKeys" - } - }, - "order": { - "name": "order", - "in": "query", - "description": "Sort order of the response, ascending or descending.", - "required": false, - "schema": { - "$ref": "#/components/schemas/orderKeys" - } - }, - "pathAuthenticationID": { - "name": "authenticationID", - "in": "path", - "required": true, - "description": "Unique identifier of an authentication resource.", - "schema": { - "$ref": "#/components/schemas/authenticationID" - } - }, - "destinationParameters_type": { - "name": "type", - "in": "query", - "description": "Destination type.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DestinationType" - }, - "example": "search" - } - }, - "authenticationID": { - "name": "authenticationID", - "in": "query", - "description": "Authentication ID used by destinations.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/authenticationID" - } - } - }, - "transformationID": { - "name": "transformationID", - "in": "query", - "description": "Get the list of destinations used by a transformation.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "$ref": "#/components/schemas/transformationID" - } - }, - "destinationParameters_sort": { - "name": "sort", - "in": "query", - "description": "Property by which to sort the destinations.", - "required": false, - "example": "type", - "schema": { - "$ref": "#/components/schemas/destinationSortKeys" - } - }, - "pathDestinationID": { - "name": "destinationID", - "in": "path", - "required": true, - "description": "Unique identifier of a destination.", - "schema": { - "$ref": "#/components/schemas/destinationID" - } - }, - "sourceParameters_type": { - "name": "type", - "in": "query", - "description": "Source type. Some sources require authentication.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SourceType" - }, - "example": "commercetools,bigcommerce" - } - }, - "sourceParameters_authenticationID": { - "name": "authenticationID", - "in": "query", - "description": "Authentication IDs of the sources to retrieve.\n'none' returns sources that doesn't have an authentication.\n", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/authenticationID" - }, - "example": ["10000000-0a75-4000-a000-000000000001", "none"] - } - }, - "sourceParameters_sort": { - "name": "sort", - "in": "query", - "description": "Property by which to sort the list of sources.", - "required": false, - "schema": { - "$ref": "#/components/schemas/sourceSortKeys" - } - }, - "pathSourceID": { - "name": "sourceID", - "in": "path", - "required": true, - "description": "Unique identifier of a source.", - "schema": { - "$ref": "#/components/schemas/sourceID" - } - }, - "action": { - "name": "action", - "in": "query", - "required": false, - "description": "Actions for filtering the list of tasks.", - "style": "form", - "explode": false, - "schema": { - "type": "array", - "description": "Actions to perform on the Algolia index.", - "items": { - "$ref": "#/components/schemas/ActionType" - }, - "example": "save,replace,partial,append" - } - }, - "enabled": { - "name": "enabled", - "in": "query", - "description": "Whether to filter the list of tasks by the `enabled` status.", - "required": false, - "schema": { - "type": "boolean" - } - }, - "sourceID": { - "name": "sourceID", - "in": "query", - "description": "Source IDs for filtering the list of tasks.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/sourceID" - } - } - }, - "sourceType": { - "name": "sourceType", - "in": "query", - "description": "Filters the tasks with the specified source type.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SourceType" - }, - "example": "json,commercetools" - } - }, - "destinationID": { - "name": "destinationID", - "in": "query", - "description": "Destination IDs for filtering the list of tasks.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/destinationID" - } - } - }, - "triggerType": { - "name": "triggerType", - "in": "query", - "description": "Type of task trigger for filtering the list of tasks.", - "required": false, - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TriggerType" - }, - "example": "onDemand,schedule,subscription,streaming" - } - }, - "withEmailNotifications": { - "name": "withEmailNotifications", - "in": "query", - "description": "If specified, the response only includes tasks with notifications.email.enabled set to this value.", - "required": false, - "schema": { - "type": "boolean" - } - }, - "taskParameters_sort": { - "name": "sort", - "in": "query", - "description": "Property by which to sort the list of tasks.", - "required": false, - "schema": { - "$ref": "#/components/schemas/taskSortKeys" - } - }, - "pathTaskID": { - "name": "taskID", - "in": "path", - "required": true, - "description": "Unique identifier of a task.", - "schema": { - "$ref": "#/components/schemas/taskID" - } - }, - "transformationParameters_sort": { - "name": "sort", - "in": "query", - "description": "Property by which to sort the list of transformations.", - "required": false, - "schema": { - "$ref": "#/components/schemas/transformationSortKeys" - } - }, - "pathTransformationID": { - "name": "transformationID", - "in": "path", - "required": true, - "description": "Unique identifier of a transformation.", - "schema": { - "$ref": "#/components/schemas/transformationID" - } - }, - "runStatus": { - "name": "status", - "in": "query", - "description": "Run status for filtering the list of task runs.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RunStatus" - } - } - }, - "runType": { - "name": "type", - "in": "query", - "description": "Run type for filtering the list of task runs.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RunType" - } - } - }, - "taskID": { - "name": "taskID", - "in": "query", - "description": "Task ID for filtering the list of task runs.", - "schema": { - "$ref": "#/components/schemas/taskID" - } - }, - "runSort": { - "name": "sort", - "in": "query", - "description": "Property by which to sort the list of task runs.", - "required": false, - "schema": { - "$ref": "#/components/schemas/runSortKeys" - } - }, - "pathRunID": { - "name": "runID", - "in": "path", - "required": true, - "description": "Unique identifier of a task run.", - "schema": { - "$ref": "#/components/schemas/runID" - } - }, - "eventStatus": { - "name": "status", - "in": "query", - "description": "Event status for filtering the list of task runs.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EventStatus" - } - } - }, - "eventType": { - "name": "type", - "in": "query", - "description": "Event type for filtering the list of task runs.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EventType" - } - } - }, - "eventSort": { - "name": "sort", - "in": "query", - "description": "Property by which to sort the list of task run events.", - "required": false, - "schema": { - "$ref": "#/components/schemas/eventSortKeys" - } - }, - "pathEventID": { - "name": "eventID", - "in": "path", - "required": true, - "description": "Unique identifier of an event.", - "schema": { - "$ref": "#/components/schemas/eventID" - } - } - }, - "schemas": { - "ErrorBase": { - "description": "Error.", - "type": "object", - "x-keep-model": true, - "additionalProperties": true, - "properties": { - "message": { - "type": "string", - "example": "Invalid Application-Id or API-Key" - } - } - }, - "itemsPerPage": { - "type": "integer", - "description": "Number of items per page.", - "minimum": 1, - "maximum": 100, - "default": 10 - }, - "page": { - "type": "integer", - "minimum": 1, - "description": "Page of the API response to retrieve." - }, - "AuthenticationType": { - "type": "string", - "description": "Type of authentication. This determines the type of credentials required in the `input` object.", - "enum": [ - "googleServiceAccount", - "basic", - "apiKey", - "oauth", - "algolia", - "algoliaInsights", - "secrets" - ] - }, - "Platform": { - "default": null, - "oneOf": [ - { - "type": "string", - "description": "Name of an ecommerce platform with which to authenticate.\nThis determines which authentication type you can select.\n", - "enum": ["bigcommerce", "commercetools", "shopify"] - }, - { - "type": "null" - } - ] - }, - "platformNone": { - "type": "string", - "description": "Authentication resource not tied to any ecommerce platform, used for filtering.", - "enum": ["none"] - }, - "platformWithNone": { - "oneOf": [ - { - "$ref": "#/components/schemas/Platform" - }, - { - "$ref": "#/components/schemas/platformNone" - } - ] - }, - "authenticationSortKeys": { - "type": "string", - "description": "Property by which to sort the list of authentications.", - "default": "createdAt", - "enum": ["name", "type", "platform", "updatedAt", "createdAt"] - }, - "orderKeys": { - "type": "string", - "description": "Ascending or descending sort order.", - "default": "desc", - "enum": ["asc", "desc"] - }, - "authenticationID": { - "type": "string", - "description": "Universally unique identifier (UUID) of an authentication resource.", - "example": "6c02aeb1-775e-418e-870b-1faccd4b2c0f" - }, - "name": { - "type": "string", - "description": "Descriptive name for the resource." - }, - "owner": { - "oneOf": [ - { - "type": "string", - "description": "Owner of the resource." - }, - { - "type": "null" - } - ] - }, - "AuthGoogleServiceAccountPartial": { - "type": "object", - "description": "Credentials for authenticating with a Google service account, such as BigQuery.", - "additionalProperties": false, - "properties": { - "clientEmail": { - "type": "string", - "description": "Email address of the Google service account.", - "example": "service-account-name@project-id.iam.gserviceaccount.com" - }, - "privateKey": { - "type": "string", - "description": "Private key of the Google service account. This field is `null` in the API response." - } - }, - "x-discriminator-fields": ["clientEmail"] - }, - "AuthBasicPartial": { - "type": "object", - "description": "Credentials for authenticating with user name and password.", - "additionalProperties": false, - "properties": { - "username": { - "type": "string", - "description": "Username." - }, - "password": { - "type": "string", - "description": "Password. This field is `null` in the API response." - } - }, - "x-discriminator-fields": ["username"] - }, - "AuthAPIKeyPartial": { - "type": "object", - "description": "Credentials for authenticating with an API key.", - "additionalProperties": false, - "properties": { - "key": { - "type": "string", - "description": "API key. This field is `null` in the API response." - } - }, - "x-discriminator-fields": ["key"] - }, - "AuthOAuthPartial": { - "type": "object", - "description": "Credentials for authenticating with OAuth 2.0.", - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "description": "URL for the OAuth endpoint." - }, - "client_id": { - "type": "string", - "description": "Client ID." - }, - "client_secret": { - "type": "string", - "description": "Client secret. This field is `null` in the API response." - }, - "scope": { - "type": "string", - "default": "", - "description": "OAuth scope." - } - }, - "x-discriminator-fields": ["url"] - }, - "AuthAlgoliaPartial": { - "type": "object", - "description": "Credentials for authenticating with Algolia.", - "additionalProperties": false, - "properties": { - "applicationId": { - "type": "string", - "description": "Algolia application ID." - }, - "apiKey": { - "type": "string", - "description": "Algolia API key with the ACL: `addObject`, `deleteObject`, `settings`, `editSettings`, `listIndexes`, `deleteIndex`.\nThis field is `null` in the API response.\n" - } - } - }, - "AuthAlgoliaInsightsPartial": { - "type": "object", - "additionalProperties": false, - "description": "Credentials for authenticating with the Algolia Insights API.", - "properties": { - "applicationId": { - "type": "string", - "description": "Algolia application ID." - }, - "apiKey": { - "type": "string", - "description": "Algolia API key with the ACL: `search`.\nThis field is `null` in the API response.\n" - } - } - }, - "AuthSecrets": { - "type": "object", - "description": "A key:value authentication for your transformations.", - "additionalProperties": { - "type": "string" - } - }, - "AuthInputPartial": { - "oneOf": [ - { - "$ref": "#/components/schemas/AuthGoogleServiceAccountPartial" - }, - { - "$ref": "#/components/schemas/AuthBasicPartial" - }, - { - "$ref": "#/components/schemas/AuthAPIKeyPartial" - }, - { - "$ref": "#/components/schemas/AuthOAuthPartial" - }, - { - "$ref": "#/components/schemas/AuthAlgoliaPartial" - }, - { - "$ref": "#/components/schemas/AuthAlgoliaInsightsPartial" - }, - { - "$ref": "#/components/schemas/AuthSecrets" - } - ] - }, - "createdAt": { - "type": "string", - "description": "Date of creation in RFC 3339 format." - }, - "updatedAt": { - "type": "string", - "description": "Date of last update in RFC 3339 format." - }, - "Authentication": { - "type": "object", - "description": "Resource representing the information required to authenticate with a source or a destination.", - "additionalProperties": false, - "properties": { - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - }, - "type": { - "$ref": "#/components/schemas/AuthenticationType" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "platform": { - "$ref": "#/components/schemas/Platform" - }, - "owner": { - "$ref": "#/components/schemas/owner" - }, - "input": { - "$ref": "#/components/schemas/AuthInputPartial" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["authenticationID", "type", "name", "input", "createdAt", "updatedAt"] - }, - "Pagination": { - "type": "object", - "description": "Paginated API response.", - "additionalProperties": false, - "properties": { - "nbPages": { - "type": "integer", - "minimum": 1, - "description": "Number of pages in the API response." - }, - "page": { - "$ref": "#/components/schemas/page" - }, - "nbItems": { - "type": "integer", - "minimum": 0, - "description": "Number of items in the API response." - }, - "itemsPerPage": { - "$ref": "#/components/schemas/itemsPerPage" - } - }, - "required": ["nbPages", "page", "nbItems", "itemsPerPage"] - }, - "AuthGoogleServiceAccount": { - "type": "object", - "description": "Credentials for authenticating with a Google service account, such as BigQuery.", - "additionalProperties": false, - "properties": { - "clientEmail": { - "type": "string", - "description": "Email address of the Google service account.", - "example": "service-account-name@project-id.iam.gserviceaccount.com" - }, - "privateKey": { - "type": "string", - "description": "Private key of the Google service account. This field is `null` in the API response." - } - }, - "required": ["clientEmail", "privateKey"], - "x-discriminator-fields": ["clientEmail", "privateKey"] - }, - "AuthBasic": { - "type": "object", - "description": "Credentials for authenticating with user name and password.", - "additionalProperties": false, - "properties": { - "username": { - "type": "string", - "description": "Username." - }, - "password": { - "type": "string", - "description": "Password. This field is `null` in the API response." - } - }, - "required": ["username", "password"], - "x-discriminator-fields": ["username", "password"] - }, - "AuthAPIKey": { - "type": "object", - "description": "Credentials for authenticating with an API key.", - "additionalProperties": false, - "properties": { - "key": { - "type": "string", - "description": "API key. This field is `null` in the API response." - } - }, - "required": ["key"], - "x-discriminator-fields": ["key"] - }, - "AuthOAuth": { - "type": "object", - "description": "Credentials for authenticating with OAuth 2.0.", - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "description": "URL for the OAuth endpoint." - }, - "client_id": { - "type": "string", - "description": "Client ID." - }, - "client_secret": { - "type": "string", - "description": "Client secret. This field is `null` in the API response." - }, - "scope": { - "type": "string", - "default": "", - "description": "OAuth scope." - } - }, - "required": ["url", "client_id", "client_secret"], - "x-discriminator-fields": ["url", "client_id", "client_secret"] - }, - "AuthAlgolia": { - "type": "object", - "additionalProperties": false, - "description": "Credentials for authenticating with Algolia.", - "properties": { - "applicationId": { - "type": "string", - "description": "Algolia application ID." - }, - "apiKey": { - "type": "string", - "description": "Algolia API key with the ACL: `addObject`, `deleteObject`, `settings`, `editSettings`, `listIndexes`, `deleteIndex`.\nThis field is `null` in the API response.\n" - } - }, - "required": ["appID", "apiKey"] - }, - "AuthAlgoliaInsights": { - "type": "object", - "additionalProperties": false, - "description": "Credentials for authenticating with the Algolia Insights API.", - "properties": { - "applicationId": { - "type": "string", - "description": "Algolia application ID." - }, - "apiKey": { - "type": "string", - "description": "Algolia API key with the ACL: `search`.\nThis field is `null` in the API response.\n" - } - }, - "required": ["appID", "apiKey"] - }, - "AuthInput": { - "oneOf": [ - { - "$ref": "#/components/schemas/AuthGoogleServiceAccount" - }, - { - "$ref": "#/components/schemas/AuthBasic" - }, - { - "$ref": "#/components/schemas/AuthAPIKey" - }, - { - "$ref": "#/components/schemas/AuthOAuth" - }, - { - "$ref": "#/components/schemas/AuthAlgolia" - }, - { - "$ref": "#/components/schemas/AuthAlgoliaInsights" - }, - { - "$ref": "#/components/schemas/AuthSecrets" - } - ] - }, - "AuthenticationCreate": { - "type": "object", - "description": "Request body for creating a new authentication resource.", - "additionalProperties": false, - "properties": { - "type": { - "$ref": "#/components/schemas/AuthenticationType" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "platform": { - "$ref": "#/components/schemas/Platform" - }, - "input": { - "$ref": "#/components/schemas/AuthInput" - } - }, - "required": ["type", "name", "input"] - }, - "AuthenticationCreateResponse": { - "type": "object", - "description": "API response for the successful creation of an authentication resource.", - "additionalProperties": false, - "properties": { - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["authenticationID", "name", "createdAt"] - }, - "AuthenticationSearch": { - "type": "object", - "additionalProperties": false, - "description": "Request body for searching for authentication resources.", - "properties": { - "authenticationIDs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/authenticationID" - } - } - }, - "required": ["authenticationIDs"] - }, - "DeleteResponse": { - "type": "object", - "properties": { - "deletedAt": { - "type": "string", - "description": "Date of deletion in RFC 3339 format." - } - }, - "required": ["deletedAt"] - }, - "AuthenticationUpdate": { - "type": "object", - "description": "Request body for updating an authentication resource.", - "additionalProperties": false, - "properties": { - "type": { - "$ref": "#/components/schemas/AuthenticationType" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "platform": { - "$ref": "#/components/schemas/Platform" - }, - "input": { - "$ref": "#/components/schemas/AuthInputPartial" - } - } - }, - "AuthenticationUpdateResponse": { - "type": "object", - "additionalProperties": false, - "description": "API response for a successful update of an authentication resource.", - "properties": { - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["authenticationID", "name", "updatedAt"] - }, - "DestinationType": { - "type": "string", - "description": "Destination type.\n\n- `search`.\n Data is stored in an Algolia index.\n\n- `insights`.\n Data is recorded as user events in the Insights API.\n", - "enum": ["search", "insights"] - }, - "transformationID": { - "type": "string", - "description": "Universally unique identifier (UUID) of a transformation.", - "example": "6c02aeb1-775e-418e-870b-1faccd4b2c0f" - }, - "destinationSortKeys": { - "type": "string", - "description": "Property by which to sort the destinations.", - "default": "createdAt", - "enum": ["name", "type", "updatedAt", "createdAt"] - }, - "destinationID": { - "type": "string", - "description": "Universally unique identifier (UUID) of a destination resource.", - "example": "6c02aeb1-775e-418e-870b-1faccd4b2c0f" - }, - "RecordType": { - "type": "string", - "description": "Record type for ecommerce sources.", - "enum": ["product", "variant", "collection"] - }, - "AttributesToExclude": { - "type": "array", - "description": "Attributes from your source to exclude from Algolia records.\n\nNot all your data attributes will be useful for searching.\nKeeping your Algolia records small increases indexing and search performance.\n\n- Exclude nested attributes with `.` notation. For example, `foo.bar` indexes the `foo` attribute and all its children **except** the `bar` attribute.\n- Exclude attributes from arrays with `[i]`, where `i` is the index of the array element.\n For example, `foo.[0].bar` only excludes the `bar` attribute from the first element of the `foo` array, but indexes the complete `foo` attribute for all other elements.\n Use `*` as wildcard: `foo.[*].bar` excludes `bar` from all elements of the `foo` array.\n", - "items": { - "type": "string" - } - }, - "DestinationIndexName": { - "type": "object", - "additionalProperties": false, - "properties": { - "indexName": { - "type": "string", - "description": "Algolia index name (case-sensitive)." - }, - "recordType": { - "$ref": "#/components/schemas/RecordType" - }, - "attributesToExclude": { - "$ref": "#/components/schemas/AttributesToExclude" - } - }, - "required": ["indexName"] - }, - "DestinationInput": { - "oneOf": [ - { - "$ref": "#/components/schemas/DestinationIndexName" - } - ] - }, - "transformationIDs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/transformationID" - } - }, - "Destination": { - "type": "object", - "description": "Destinations are Algolia resources like indices or event streams.", - "additionalProperties": false, - "properties": { - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "type": { - "$ref": "#/components/schemas/DestinationType" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "owner": { - "$ref": "#/components/schemas/owner" - }, - "input": { - "$ref": "#/components/schemas/DestinationInput" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - }, - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - }, - "transformationIDs": { - "$ref": "#/components/schemas/transformationIDs" - } - }, - "required": ["destinationID", "type", "name", "input", "createdAt", "updatedAt"] - }, - "DestinationCreate": { - "type": "object", - "additionalProperties": false, - "description": "API request body for creating a new destination.", - "properties": { - "type": { - "$ref": "#/components/schemas/DestinationType" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "input": { - "$ref": "#/components/schemas/DestinationInput" - }, - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - }, - "transformationIDs": { - "$ref": "#/components/schemas/transformationIDs" - } - }, - "required": ["type", "name", "input"] - }, - "DestinationCreateResponse": { - "type": "object", - "additionalProperties": false, - "description": "API response for creating a new destination.", - "properties": { - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["destinationID", "name", "createdAt"] - }, - "DestinationSearch": { - "type": "object", - "additionalProperties": false, - "description": "API request body for searching destinations.", - "properties": { - "destinationIDs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/destinationID" - } - } - }, - "required": ["destinationIDs"] - }, - "DestinationUpdate": { - "type": "object", - "additionalProperties": false, - "description": "API request body for updating a destination.", - "properties": { - "type": { - "$ref": "#/components/schemas/DestinationType" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "input": { - "$ref": "#/components/schemas/DestinationInput" - }, - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - }, - "transformationIDs": { - "$ref": "#/components/schemas/transformationIDs" - } - } - }, - "DestinationUpdateResponse": { - "type": "object", - "additionalProperties": false, - "description": "API response for updating a destination.", - "properties": { - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "name": { - "$ref": "#/components/schemas/name" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["destinationID", "name", "updatedAt"] - }, - "SourceType": { - "type": "string", - "enum": [ - "bigcommerce", - "bigquery", - "commercetools", - "csv", - "docker", - "ga4BigqueryExport", - "json", - "shopify", - "push" - ] - }, - "sourceSortKeys": { - "type": "string", - "description": "Property by which to sort the list of sources.", - "default": "createdAt", - "enum": ["name", "type", "updatedAt", "createdAt"] - }, - "sourceID": { - "type": "string", - "description": "Universally uniqud identifier (UUID) of a source.", - "example": "6c02aeb1-775e-418e-870b-1faccd4b2c0f" - }, - "CommercetoolsCustomFields": { - "type": "object", - "additionalProperties": false, - "description": "Custom fields from commercetools to add to the records.\n\nFor more information, see [Using Custom Types and Custom Fields](https://docs.commercetools.com/tutorials/custom-types).\n", - "properties": { - "inventory": { - "oneOf": [ - { - "type": "array", - "description": "Inventory custom fields.", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "price": { - "oneOf": [ - { - "type": "array", - "description": "Price custom fields.", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "category": { - "oneOf": [ - { - "type": "array", - "description": "Category custom fields.", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] - } - } - }, - "SourceCommercetools": { - "type": "object", - "additionalProperties": false, - "properties": { - "storeKeys": { - "type": "array", - "items": { - "description": "Unique and immutable key of the referenced store.", - "type": "string" - } - }, - "locales": { - "type": "array", - "description": "Locales for your commercetools stores.", - "items": { - "type": "string", - "pattern": "^[a-z]{2}(-[A-Z]{2})?$", - "description": "Locale specfied as combination of a two-letter language code and an optional two-letter country code.", - "example": "fr-FR" - } - }, - "url": { - "type": "string" - }, - "projectKey": { - "type": "string" - }, - "fallbackIsInStockValue": { - "type": "boolean", - "default": true, - "description": "Whether a fallback value is stored in the Algolia record if there's no inventory information about the product.\n" - }, - "productQueryPredicate": { - "type": "string", - "description": "Predicate to filter out specific products when indexing. For more information, see [Query Predicate](https://docs.commercetools.com/api/predicates/query).\n" - }, - "customFields": { - "$ref": "#/components/schemas/CommercetoolsCustomFields" - } - }, - "required": ["url", "projectKey"], - "x-discriminator-fields": ["projectKey"] - }, - "BigCommerceChannel": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "description": "ID of the BigCommerce channel." - }, - "currencies": { - "type": "array", - "description": "Currencies for the given channel.", - "example": ["usd", "eur"], - "items": { - "type": "string", - "description": "Three-letter code for the currency.", - "example": "usd" - } - } - }, - "required": ["id"] - }, - "BigCommerceMetafield": { - "type": "object", - "additionalProperties": false, - "properties": { - "namespace": { - "type": "string", - "description": "Namespace of the metafield." - }, - "key": { - "type": "string", - "description": "Key identifier of the metafield." - } - }, - "required": ["namespace", "key"] - }, - "SourceBigCommerce": { - "type": "object", - "additionalProperties": false, - "properties": { - "storeHash": { - "type": "string", - "description": "Store hash identifying your BigCommerce store." - }, - "channel": { - "$ref": "#/components/schemas/BigCommerceChannel" - }, - "customFields": { - "type": "array", - "items": { - "type": "string" - } - }, - "productMetafields": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BigCommerceMetafield" - } - }, - "variantMetafields": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BigCommerceMetafield" - } - } - }, - "required": ["storeHash"], - "x-discriminator-fields": ["storeHash"] - }, - "UniqueIDColumn": { - "type": "string", - "description": "Name of a column that contains a unique ID which will be used as `objectID` in Algolia." - }, - "MethodType": { - "type": "string", - "description": "HTTP method to be used for retrieving your data.", - "enum": ["GET", "POST"] - }, - "SourceJSON": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "description": "URL of the file." - }, - "uniqueIDColumn": { - "$ref": "#/components/schemas/UniqueIDColumn" - }, - "method": { - "$ref": "#/components/schemas/MethodType" - } - }, - "required": ["url"] - }, - "MappingTypeCSV": { - "type": "string", - "enum": ["string", "integer", "float", "boolean", "json"] - }, - "SourceCSV": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "description": "URL of the file." - }, - "uniqueIDColumn": { - "$ref": "#/components/schemas/UniqueIDColumn" - }, - "mapping": { - "type": "object", - "description": "Key-value pairs of column names and their expected types.\n", - "x-additionalPropertyName": "column name", - "additionalProperties": { - "$ref": "#/components/schemas/MappingTypeCSV" - } - }, - "method": { - "$ref": "#/components/schemas/MethodType" - }, - "delimiter": { - "type": "string", - "minLength": 1, - "maxLength": 1, - "default": ",", - "description": "The character used to split the value on each line, default to a comma (\\r, \\n, 0xFFFD, and space are forbidden)." - } - }, - "required": ["url"] - }, - "BigQueryDataType": { - "type": "string", - "enum": ["ga4", "ga360"] - }, - "SourceBigQuery": { - "type": "object", - "additionalProperties": false, - "properties": { - "projectID": { - "type": "string", - "description": "Project ID of the BigQuery source." - }, - "datasetID": { - "type": "string", - "description": "Dataset ID of the BigQuery source." - }, - "dataType": { - "$ref": "#/components/schemas/BigQueryDataType" - }, - "table": { - "type": "string", - "description": "Table name for the BigQuery export." - }, - "tablePrefix": { - "type": "string", - "description": "Table prefix for a Google Analytics 4 data export to BigQuery." - }, - "customSQLRequest": { - "type": "string", - "description": "Custom SQL request to extract data from the BigQuery table." - }, - "uniqueIDColumn": { - "$ref": "#/components/schemas/UniqueIDColumn" - } - }, - "required": ["projectID", "datasetID"], - "x-discriminator-fields": ["projectID"] - }, - "SourceGA4BigQueryExport": { - "type": "object", - "additionalProperties": false, - "properties": { - "projectID": { - "type": "string", - "description": "GCP project ID that the BigQuery export writes to." - }, - "datasetID": { - "type": "string", - "description": "BigQuery dataset ID that the BigQuery export writes to." - }, - "tablePrefix": { - "type": "string", - "description": "Prefix of the tables that the BigQuery Export writes to.", - "example": "events_intraday_" - } - }, - "required": ["projectID", "datasetID", "tablePrefix"], - "x-discriminator-fields": ["projectID", "datasetID", "tablePrefix"] - }, - "SourceDocker": { - "type": "object", - "additionalProperties": false, - "properties": { - "image": { - "type": "string", - "description": "Name of the connector.", - "example": "zendesk" - }, - "configuration": { - "type": "object", - "description": "Configuration of the spec." - } - }, - "required": ["image", "configuration"], - "x-discriminator-fields": ["image", "configuration"] - }, - "SourceUpdateShopify": { - "type": "object", - "properties": { - "featureFlags": { - "type": "object", - "description": "Feature flags for the Shopify source.", - "additionalProperties": true - } - } - }, - "sourceShopifyBase": { - "type": "object", - "properties": { - "shopURL": { - "type": "string", - "description": "URL of the Shopify store." - } - }, - "required": ["shopURL"], - "x-discriminator-fields": ["shopURL"] - }, - "SourceShopify": { - "allOf": [ - { - "$ref": "#/components/schemas/SourceUpdateShopify" - }, - { - "$ref": "#/components/schemas/sourceShopifyBase" - } - ], - "unevaluatedProperties": false - }, - "SourceInput": { - "oneOf": [ - { - "$ref": "#/components/schemas/SourceCommercetools" - }, - { - "$ref": "#/components/schemas/SourceBigCommerce" - }, - { - "$ref": "#/components/schemas/SourceJSON" - }, - { - "$ref": "#/components/schemas/SourceCSV" - }, - { - "$ref": "#/components/schemas/SourceBigQuery" - }, - { - "$ref": "#/components/schemas/SourceGA4BigQueryExport" - }, - { - "$ref": "#/components/schemas/SourceDocker" - }, - { - "$ref": "#/components/schemas/SourceShopify" - } - ] - }, - "Source": { - "type": "object", - "additionalProperties": false, - "properties": { - "sourceID": { - "$ref": "#/components/schemas/sourceID" - }, - "type": { - "$ref": "#/components/schemas/SourceType" - }, - "name": { - "type": "string" - }, - "owner": { - "$ref": "#/components/schemas/owner" - }, - "input": { - "$ref": "#/components/schemas/SourceInput" - }, - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["sourceID", "type", "name", "createdAt", "updatedAt"] - }, - "SourceCreate": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "$ref": "#/components/schemas/SourceType" - }, - "name": { - "type": "string", - "description": "Descriptive name of the source." - }, - "input": { - "$ref": "#/components/schemas/SourceInput" - }, - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - } - }, - "required": ["type", "name"] - }, - "SourceCreateResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "sourceID": { - "$ref": "#/components/schemas/sourceID" - }, - "name": { - "type": "string", - "description": "Descriptive name of the source." - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["sourceID", "name", "createdAt"] - }, - "runID": { - "type": "string", - "description": "Universally unique identifier (UUID) of a task run.", - "example": "6c02aeb1-775e-418e-870b-1faccd4b2c0f" - }, - "eventID": { - "type": "string", - "description": "Universally unique identifier (UUID) of an event.", - "example": "6c02aeb1-775e-418e-870b-1faccd4b2c0f" - }, - "EventStatus": { - "oneOf": [ - { - "type": "string", - "enum": ["created", "started", "retried", "failed", "succeeded", "critical"] - }, - { - "type": "null" - } - ] - }, - "EventType": { - "type": "string", - "enum": ["fetch", "record", "log", "transform"] - }, - "publishedAt": { - "type": "string", - "description": "Date of publish RFC 3339 format." - }, - "Event": { - "type": "object", - "description": "An event describe a step of the task execution flow..", - "additionalProperties": false, - "properties": { - "eventID": { - "$ref": "#/components/schemas/eventID" - }, - "runID": { - "$ref": "#/components/schemas/runID" - }, - "status": { - "$ref": "#/components/schemas/EventStatus" - }, - "type": { - "$ref": "#/components/schemas/EventType" - }, - "batchSize": { - "type": "integer", - "description": "The extracted record batch size.", - "example": 10, - "minimum": 0, - "multipleOf": 1 - }, - "data": { - "oneOf": [ - { - "type": "object", - "additionalProperties": true - }, - { - "type": "null" - } - ] - }, - "publishedAt": { - "$ref": "#/components/schemas/publishedAt" - } - }, - "required": ["eventID", "runID", "status", "type", "batchSize", "publishedAt"] - }, - "WatchResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "runID": { - "$ref": "#/components/schemas/runID" - }, - "data": { - "type": "array", - "description": "when used with discovering or validating sources, the sampled data of your source is returned.", - "items": { - "type": "object" - } - }, - "events": { - "description": "in case of error, observability events will be added to the response, if any.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Event" - } - }, - "message": { - "description": "a message describing the outcome of a validate run.", - "type": "string" - } - }, - "required": ["runID"] - }, - "SourceSearch": { - "type": "object", - "additionalProperties": false, - "properties": { - "sourceIDs": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["sourceIDs"] - }, - "SourceUpdateCommercetools": { - "type": "object", - "additionalProperties": false, - "properties": { - "storeKeys": { - "type": "array", - "items": { - "description": "Unique and immutable key of the referenced store.", - "type": "string" - } - }, - "locales": { - "type": "array", - "description": "Locales for your commercetools stores.", - "items": { - "type": "string", - "pattern": "^[a-z]{2}(-[A-Z]{2})?$", - "description": "Locale specfied as combination of a two-letter language code and an optional two-letter country code.", - "example": "fr-FR" - } - }, - "url": { - "type": "string" - }, - "fallbackIsInStockValue": { - "type": "boolean", - "description": "Whether a fallback value is stored in the Algolia record if there's no inventory information about the product.\n" - }, - "productQueryPredicate": { - "type": "string", - "description": "Predicate to filter out specific products when indexing. For more information, see [Query Predicate](https://docs.commercetools.com/api/predicates/query).\n" - }, - "customFields": { - "$ref": "#/components/schemas/CommercetoolsCustomFields" - } - } - }, - "SourceUpdateDocker": { - "type": "object", - "additionalProperties": false, - "properties": { - "configuration": { - "type": "object", - "description": "Configuration of the spec." - } - }, - "required": ["configuration"], - "x-discriminator-fields": ["configuration"] - }, - "SourceUpdateInput": { - "oneOf": [ - { - "$ref": "#/components/schemas/SourceUpdateCommercetools" - }, - { - "$ref": "#/components/schemas/SourceJSON" - }, - { - "$ref": "#/components/schemas/SourceCSV" - }, - { - "$ref": "#/components/schemas/SourceBigQuery" - }, - { - "$ref": "#/components/schemas/SourceGA4BigQueryExport" - }, - { - "$ref": "#/components/schemas/SourceUpdateDocker" - }, - { - "$ref": "#/components/schemas/SourceUpdateShopify" - } - ] - }, - "SourceUpdate": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "Descriptive name of the source." - }, - "input": { - "$ref": "#/components/schemas/SourceUpdateInput" - }, - "authenticationID": { - "$ref": "#/components/schemas/authenticationID" - } - } - }, - "SourceUpdateResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "sourceID": { - "$ref": "#/components/schemas/sourceID" - }, - "name": { - "type": "string", - "description": "Descriptive name of the source." - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["sourceID", "name", "updatedAt"] - }, - "EntityType": { - "type": "string", - "description": "Type of entity to update.", - "enum": ["product", "collection"] - }, - "RunSourcePayload": { - "type": "object", - "additionalProperties": false, - "properties": { - "indexToInclude": { - "type": "array", - "description": "List of index names to include in reidexing/update.", - "items": { - "type": "string" - } - }, - "indexToExclude": { - "type": "array", - "description": "List of index names to exclude in reidexing/update.", - "items": { - "type": "string" - } - }, - "entityIDs": { - "type": "array", - "items": { - "type": "string" - }, - "description": "List of entityID to update." - }, - "entityType": { - "$ref": "#/components/schemas/EntityType" - } - } - }, - "ActionType": { - "type": "string", - "description": "Action to perform on the Algolia index.", - "enum": ["replace", "save", "partial", "append"] - }, - "TriggerType": { - "type": "string", - "description": "Task trigger, describing when a task should run.\n\n- `onDemand`.\n Manually trigger the task with the `/run` endpoint.\n\n- `schedule`.\n Regularly trigger the task on a `cron` schedule.\n\n- `subscription`.\n Trigger the task after an event is received, such as, a webhook.\n\n- `streaming`.\n Run the task continuously.\n", - "enum": ["onDemand", "schedule", "subscription", "streaming"] - }, - "taskSortKeys": { - "type": "string", - "description": "Property by which to sort the list of tasks.", - "default": "createdAt", - "enum": ["enabled", "triggerType", "action", "updatedAt", "createdAt"] - }, - "taskID": { - "type": "string", - "description": "Universally unique identifier (UUID) of a task.", - "example": "6c02aeb1-775e-418e-870b-1faccd4b2c0f" - }, - "Cron": { - "type": "string", - "description": "Cron expression for the task's schedule.", - "example": "* * 1 * *" - }, - "LastRun": { - "description": "The last time the scheduled task ran in RFC 3339 format.", - "type": "string" - }, - "NextRun": { - "description": "The next scheduled run of the task in RFC 3339 format.", - "type": "string" - }, - "MappingFormatSchema": { - "type": "string", - "description": "Mapping format schema.", - "enum": ["mappingkit/v1"] - }, - "MappingFieldDirective": { - "type": "object", - "additionalProperties": false, - "description": "Describes how a field should be resolved by applying a set of directives.", - "properties": { - "fieldKey": { - "description": "Destination field key.", - "type": "string" - }, - "value": { - "type": "object", - "additionalProperties": true, - "description": "How the destination field should be resolved from the source." - } - }, - "required": ["fieldKey", "value"] - }, - "MappingKitAction": { - "type": "object", - "additionalProperties": false, - "description": "Describes how a destination object should be resolved by means of applying a set of directives.", - "properties": { - "id": { - "description": "ID to uniquely identify this action.", - "type": "string" - }, - "enabled": { - "description": "Whether this action has any effect.", - "type": "boolean" - }, - "trigger": { - "description": "Condition which must be satisfied to apply the action. If this evaluates to false, the action is not applied, and the process attempts to apply the next action, if any.", - "type": "string" - }, - "fieldDirectives": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MappingFieldDirective" - } - } - }, - "required": ["enabled", "trigger", "fieldDirectives"] - }, - "MappingInput": { - "type": "object", - "additionalProperties": false, - "description": "Transformations to apply to the source, serialized as a JSON string.", - "properties": { - "format": { - "$ref": "#/components/schemas/MappingFormatSchema" - }, - "actions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MappingKitAction" - } - } - }, - "required": ["format", "actions"], - "x-discriminator-fields": ["format", "actions"] - }, - "StreamingInput": { - "type": "object", - "additionalProperties": false, - "description": "Input for a `streaming` task whose source is of type `ga4BigqueryExport` and for which extracted data is continuously streamed.", - "properties": { - "mapping": { - "$ref": "#/components/schemas/MappingInput" - } - }, - "required": ["mapping"], - "x-discriminator-fields": ["mapping"] - }, - "DockerStreamsSyncMode": { - "type": "string", - "description": "The strategy to use to fetch the data.", - "enum": ["incremental", "fullTable"] - }, - "DockerStreams": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the stream to fetch the data from (e.g. table name)." - }, - "properties": { - "type": "array", - "description": "The properties of the stream to select (e.g. column).", - "items": { - "type": "string" - } - }, - "syncMode": { - "$ref": "#/components/schemas/DockerStreamsSyncMode" - } - }, - "required": ["name", "syncMode"] - }, - "DockerStreamsInput": { - "description": "The selected streams of an airbyte connector.", - "type": "object", - "properties": { - "streams": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DockerStreams" - } - } - }, - "required": ["streams"], - "x-discriminator-fields": ["streams"] - }, - "ShopifyMetafield": { - "type": "object", - "additionalProperties": false, - "description": "Represents a metafield in Shopify.", - "properties": { - "namespace": { - "type": "string" - }, - "key": { - "type": "string" - }, - "value": { - "type": "string" - } - }, - "required": ["namespace", "key", "value"] - }, - "ShopifyMarket": { - "type": "object", - "additionalProperties": false, - "description": "Represents a market in Shopify.", - "properties": { - "countries": { - "type": "array", - "items": { - "type": "string" - } - }, - "currencies": { - "type": "array", - "items": { - "type": "string" - } - }, - "locales": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["countries", "currencies", "locales"] - }, - "ShopifyInput": { - "type": "object", - "additionalProperties": false, - "description": "Represents the required elements of the task input when using a `shopify` source.", - "properties": { - "metafields": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ShopifyMetafield" - } - }, - "market": { - "$ref": "#/components/schemas/ShopifyMarket" - } - }, - "required": ["metafields", "market"] - }, - "TaskInput": { - "description": "Configuration of the task, depending on its type.", - "oneOf": [ - { - "$ref": "#/components/schemas/StreamingInput" - }, - { - "$ref": "#/components/schemas/DockerStreamsInput" - }, - { - "$ref": "#/components/schemas/ShopifyInput" - } - ] - }, - "failureThreshold": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "description": "Maximum accepted percentage of failures for a task run to finish successfully." - }, - "cursor": { - "type": "string", - "description": "Date of the last cursor in RFC 3339 format." - }, - "Notifications": { - "type": "object", - "additionalProperties": false, - "description": "Notifications settings for a task.", - "properties": { - "email": { - "title": "emailNotifications", - "type": "object", - "additionalProperties": false, - "properties": { - "enabled": { - "description": "Whether to send email notifications, note that this doesn't prevent the task from being blocked.", - "type": "boolean" - } - } - } - }, - "required": ["email"] - }, - "Policies": { - "type": "object", - "additionalProperties": false, - "description": "Set of rules for a task.", - "properties": { - "criticalThreshold": { - "description": "The number of critical failures in a row before blocking the task and sending a notification.", - "type": "integer", - "minimum": 1, - "maximum": 10 - } - } - }, - "Task": { - "type": "object", - "additionalProperties": false, - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "sourceID": { - "$ref": "#/components/schemas/sourceID" - }, - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "cron": { - "$ref": "#/components/schemas/Cron" - }, - "lastRun": { - "$ref": "#/components/schemas/LastRun" - }, - "nextRun": { - "$ref": "#/components/schemas/NextRun" - }, - "owner": { - "$ref": "#/components/schemas/owner" - }, - "input": { - "$ref": "#/components/schemas/TaskInput" - }, - "enabled": { - "type": "boolean", - "default": true, - "description": "Whether the task is enabled." - }, - "failureThreshold": { - "$ref": "#/components/schemas/failureThreshold" - }, - "action": { - "$ref": "#/components/schemas/ActionType" - }, - "subscriptionAction": { - "$ref": "#/components/schemas/ActionType" - }, - "cursor": { - "$ref": "#/components/schemas/cursor" - }, - "notifications": { - "$ref": "#/components/schemas/Notifications" - }, - "policies": { - "$ref": "#/components/schemas/Policies" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["taskID", "sourceID", "destinationID", "enabled", "createdAt", "updatedAt"] - }, - "TaskCreate": { - "type": "object", - "additionalProperties": false, - "description": "API request body for creating a task.", - "properties": { - "sourceID": { - "$ref": "#/components/schemas/sourceID" - }, - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "action": { - "$ref": "#/components/schemas/ActionType" - }, - "subscriptionAction": { - "$ref": "#/components/schemas/ActionType" - }, - "cron": { - "$ref": "#/components/schemas/Cron" - }, - "enabled": { - "type": "boolean", - "description": "Whether the task is enabled." - }, - "failureThreshold": { - "$ref": "#/components/schemas/failureThreshold" - }, - "input": { - "$ref": "#/components/schemas/TaskInput" - }, - "cursor": { - "$ref": "#/components/schemas/cursor" - }, - "notifications": { - "$ref": "#/components/schemas/Notifications" - }, - "policies": { - "$ref": "#/components/schemas/Policies" - } - }, - "required": ["sourceID", "destinationID", "action"] - }, - "TaskCreateResponse": { - "type": "object", - "additionalProperties": false, - "description": "API response for creating a task.", - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["taskID", "createdAt"] - }, - "TaskSearch": { - "type": "object", - "additionalProperties": false, - "properties": { - "taskIDs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/taskID" - } - } - }, - "required": ["taskIDs"] - }, - "TaskUpdate": { - "type": "object", - "additionalProperties": false, - "description": "API request body for updating a task.", - "properties": { - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "cron": { - "$ref": "#/components/schemas/Cron" - }, - "input": { - "$ref": "#/components/schemas/TaskInput" - }, - "enabled": { - "type": "boolean", - "description": "Whether the task is enabled." - }, - "subscriptionAction": { - "$ref": "#/components/schemas/ActionType" - }, - "failureThreshold": { - "$ref": "#/components/schemas/failureThreshold" - }, - "notifications": { - "$ref": "#/components/schemas/Notifications" - }, - "policies": { - "$ref": "#/components/schemas/Policies" - } - } - }, - "TaskUpdateResponse": { - "type": "object", - "description": "API response for updating a task.", - "additionalProperties": false, - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["taskID", "updatedAt"] - }, - "RunResponse": { - "type": "object", - "additionalProperties": false, - "description": "API response for running a task.", - "properties": { - "runID": { - "$ref": "#/components/schemas/runID" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["runID", "createdAt"] - }, - "action": { - "type": "string", - "enum": [ - "addObject", - "updateObject", - "partialUpdateObject", - "partialUpdateObjectNoCreate", - "deleteObject", - "delete", - "clear" - ], - "description": "Type of indexing operation." - }, - "objectID": { - "type": "string", - "description": "Unique record identifier.", - "example": "test-record-123" - }, - "OnDemandTriggerType": { - "type": "string", - "description": "Task is run manually, with the `/run` endpoint.", - "enum": ["onDemand"] - }, - "OnDemandTrigger": { - "type": "object", - "additionalProperties": false, - "description": "Trigger information for manually-triggered tasks.", - "properties": { - "type": { - "$ref": "#/components/schemas/OnDemandTriggerType" - }, - "lastRun": { - "$ref": "#/components/schemas/LastRun" - } - }, - "required": ["type"] - }, - "ScheduleTriggerType": { - "type": "string", - "description": "Task runs on a schedule.", - "enum": ["schedule"] - }, - "ScheduleTrigger": { - "type": "object", - "additionalProperties": false, - "description": "Trigger information for scheduled tasks.", - "properties": { - "type": { - "$ref": "#/components/schemas/ScheduleTriggerType" - }, - "cron": { - "$ref": "#/components/schemas/Cron" - }, - "lastRun": { - "$ref": "#/components/schemas/LastRun" - }, - "nextRun": { - "$ref": "#/components/schemas/NextRun" - } - }, - "required": ["type", "cron", "nextRun"] - }, - "SubscriptionTriggerType": { - "type": "string", - "description": "Task runs after receiving subscribed event.", - "enum": ["subscription"] - }, - "SubscriptionTrigger": { - "type": "object", - "additionalProperties": false, - "description": "Trigger input for subscription tasks.", - "properties": { - "type": { - "$ref": "#/components/schemas/SubscriptionTriggerType" - } - }, - "required": ["type"] - }, - "StreamingTriggerType": { - "type": "string", - "description": "Task runs continuously.", - "enum": ["streaming"] - }, - "StreamingTrigger": { - "type": "object", - "additionalProperties": false, - "description": "Trigger input for continuously running tasks.", - "properties": { - "type": { - "$ref": "#/components/schemas/StreamingTriggerType" - } - }, - "required": ["type"] - }, - "Trigger": { - "description": "Trigger that runs the task.", - "oneOf": [ - { - "$ref": "#/components/schemas/OnDemandTrigger" - }, - { - "$ref": "#/components/schemas/ScheduleTrigger" - }, - { - "$ref": "#/components/schemas/SubscriptionTrigger" - }, - { - "$ref": "#/components/schemas/StreamingTrigger" - } - ] - }, - "TaskV1": { - "type": "object", - "additionalProperties": false, - "deprecated": true, - "description": "The V1 task object, please use methods and types that don't contain the V1 suffix.", - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "sourceID": { - "$ref": "#/components/schemas/sourceID" - }, - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "trigger": { - "$ref": "#/components/schemas/Trigger" - }, - "input": { - "$ref": "#/components/schemas/TaskInput" - }, - "enabled": { - "type": "boolean", - "default": true, - "description": "Whether the task is enabled." - }, - "failureThreshold": { - "$ref": "#/components/schemas/failureThreshold" - }, - "action": { - "$ref": "#/components/schemas/ActionType" - }, - "cursor": { - "$ref": "#/components/schemas/cursor" - }, - "notifications": { - "$ref": "#/components/schemas/Notifications" - }, - "policies": { - "$ref": "#/components/schemas/Policies" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": [ - "taskID", - "sourceID", - "destinationID", - "trigger", - "enabled", - "createdAt", - "updatedAt" - ] - }, - "OnDemandTriggerInput": { - "type": "object", - "additionalProperties": false, - "description": "Trigger information for manually-triggered tasks.", - "properties": { - "type": { - "$ref": "#/components/schemas/OnDemandTriggerType" - } - }, - "required": ["type"] - }, - "ScheduleTriggerInput": { - "type": "object", - "additionalProperties": false, - "description": "Trigger input for scheduled tasks.", - "properties": { - "type": { - "$ref": "#/components/schemas/ScheduleTriggerType" - }, - "cron": { - "$ref": "#/components/schemas/Cron" - } - }, - "required": ["type", "cron"], - "x-discriminator-fields": ["cron"] - }, - "TaskCreateTrigger": { - "oneOf": [ - { - "$ref": "#/components/schemas/OnDemandTriggerInput" - }, - { - "$ref": "#/components/schemas/ScheduleTriggerInput" - }, - { - "$ref": "#/components/schemas/SubscriptionTrigger" - }, - { - "$ref": "#/components/schemas/StreamingTrigger" - } - ] - }, - "TaskCreateV1": { - "type": "object", - "additionalProperties": false, - "deprecated": true, - "description": "API request body for creating a task using the V1 shape, please use methods and types that don't contain the V1 suffix.", - "properties": { - "sourceID": { - "$ref": "#/components/schemas/sourceID" - }, - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "trigger": { - "$ref": "#/components/schemas/TaskCreateTrigger" - }, - "action": { - "$ref": "#/components/schemas/ActionType" - }, - "enabled": { - "type": "boolean", - "description": "Whether the task is enabled." - }, - "failureThreshold": { - "$ref": "#/components/schemas/failureThreshold" - }, - "input": { - "$ref": "#/components/schemas/TaskInput" - }, - "cursor": { - "$ref": "#/components/schemas/cursor" - } - }, - "required": ["sourceID", "destinationID", "trigger", "action"] - }, - "TriggerUpdateInput": { - "type": "object", - "additionalProperties": false, - "description": "Trigger for a task update.", - "properties": { - "cron": { - "$ref": "#/components/schemas/Cron" - } - }, - "required": ["cron"] - }, - "TaskUpdateV1": { - "type": "object", - "additionalProperties": false, - "deprecated": true, - "description": "API request body for updating a task using the V1 shape, please use methods and types that don't contain the V1 suffix.", - "properties": { - "destinationID": { - "$ref": "#/components/schemas/destinationID" - }, - "trigger": { - "$ref": "#/components/schemas/TriggerUpdateInput" - }, - "input": { - "$ref": "#/components/schemas/TaskInput" - }, - "enabled": { - "type": "boolean", - "description": "Whether the task is enabled." - }, - "failureThreshold": { - "$ref": "#/components/schemas/failureThreshold" - } - } - }, - "transformationSortKeys": { - "type": "string", - "description": "Property by which to sort the list of transformations.", - "default": "createdAt", - "enum": ["name", "updatedAt", "createdAt"] - }, - "AuthenticationIDs": { - "description": "The authentications associated with the current transformation.", - "type": "array", - "items": { - "$ref": "#/components/schemas/authenticationID" - } - }, - "Code": { - "type": "string", - "description": "The source code of the transformation." - }, - "Name": { - "type": "string", - "description": "The uniquely identified name of your transformation." - }, - "Description": { - "type": "string", - "description": "A descriptive name for your transformation of what it does." - }, - "Transformation": { - "type": "object", - "additionalProperties": false, - "properties": { - "transformationID": { - "$ref": "#/components/schemas/transformationID" - }, - "authenticationIDs": { - "$ref": "#/components/schemas/AuthenticationIDs" - }, - "code": { - "$ref": "#/components/schemas/Code" - }, - "name": { - "$ref": "#/components/schemas/Name" - }, - "description": { - "$ref": "#/components/schemas/Description" - }, - "owner": { - "$ref": "#/components/schemas/owner" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["transformationID", "code", "name", "createdAt", "updatedAt"] - }, - "TransformationCreate": { - "type": "object", - "additionalProperties": false, - "description": "API request body for creating a transformation.", - "properties": { - "code": { - "$ref": "#/components/schemas/Code" - }, - "name": { - "$ref": "#/components/schemas/Name" - }, - "description": { - "$ref": "#/components/schemas/Description" - }, - "authenticationIDs": { - "$ref": "#/components/schemas/AuthenticationIDs" - } - }, - "required": ["code", "name"] - }, - "TransformationCreateResponse": { - "type": "object", - "additionalProperties": false, - "description": "API response for creating a transformation.", - "properties": { - "transformationID": { - "$ref": "#/components/schemas/transformationID" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["transformationID", "createdAt"] - }, - "TransformationTry": { - "type": "object", - "additionalProperties": false, - "properties": { - "code": { - "$ref": "#/components/schemas/Code" - }, - "sampleRecord": { - "description": "The record to apply the given code to.", - "type": "object" - }, - "authentications": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AuthenticationCreate" - } - } - }, - "required": ["code", "sampleRecord"] - }, - "TransformationTryResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "payloads": { - "type": "array", - "description": "The array of stringified records returned by the transformation service.", - "items": { - "type": "string" - } - }, - "error": { - "title": "transformationError", - "type": "object", - "description": "The error if the transformation failed.", - "properties": { - "code": { - "description": "The error status code.", - "type": "integer" - }, - "message": { - "description": "A descriptive message explaining the failure.", - "type": "string" - } - } - } - }, - "required": ["payloads"] - }, - "TransformationSearch": { - "type": "object", - "additionalProperties": false, - "properties": { - "transformationIDs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/transformationID" - } - } - }, - "required": ["transformationIDs"] - }, - "TransformationUpdateResponse": { - "type": "object", - "description": "API response for updating a transformation.", - "additionalProperties": false, - "properties": { - "transformationID": { - "$ref": "#/components/schemas/transformationID" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["transformationID", "updatedAt"] - }, - "RunStatus": { - "type": "string", - "description": "Task run status.", - "enum": ["created", "started", "idled", "finished", "skipped"] - }, - "RunType": { - "type": "string", - "description": "Task run type.", - "enum": ["reindex", "update", "discover", "validate", "push"] - }, - "runSortKeys": { - "type": "string", - "description": "Property by which to sort the list of task runs.", - "default": "createdAt", - "enum": ["status", "updatedAt", "createdAt"] - }, - "RunOutcome": { - "type": "string", - "description": "Task run outcome.", - "enum": ["success", "failure"] - }, - "RunReasonCode": { - "type": "string", - "description": "A code for the task run's outcome. A readable description of the code is included in the `reason` response property.", - "enum": [ - "internal", - "critical", - "no_events", - "too_many_errors", - "ok", - "discarded", - "blocking" - ] - }, - "startedAt": { - "type": "string", - "description": "Date of start in RFC 3339 format." - }, - "finishedAt": { - "type": "string", - "description": "Date of finish in RFC 3339 format." - }, - "Run": { - "type": "object", - "additionalProperties": false, - "properties": { - "runID": { - "$ref": "#/components/schemas/runID" - }, - "applicationId": { - "type": "string" - }, - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "status": { - "$ref": "#/components/schemas/RunStatus" - }, - "progress": { - "title": "runProgress", - "type": "object", - "additionalProperties": false, - "properties": { - "expectedNbOfEvents": { - "type": "integer" - }, - "receivedNbOfEvents": { - "type": "integer" - } - }, - "required": ["expectedNbOfEvents", "receivedNbOfEvents"] - }, - "outcome": { - "$ref": "#/components/schemas/RunOutcome" - }, - "failureThreshold": { - "$ref": "#/components/schemas/failureThreshold" - }, - "reason": { - "type": "string", - "description": "More information about the task run's outcome." - }, - "reasonCode": { - "$ref": "#/components/schemas/RunReasonCode" - }, - "type": { - "$ref": "#/components/schemas/RunType" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "startedAt": { - "$ref": "#/components/schemas/startedAt" - }, - "finishedAt": { - "$ref": "#/components/schemas/finishedAt" - } - }, - "required": ["runID", "appID", "taskID", "status", "type", "createdAt"] - }, - "Window": { - "type": "object", - "additionalProperties": false, - "description": "Time window by which to filter the observability data.", - "properties": { - "startDate": { - "type": "string", - "description": "Date in RFC 3339 format representing the oldest data in the time window." - }, - "endDate": { - "type": "string", - "description": "Date in RFC 3339 format representing the newest data in the time window." - } - }, - "required": ["startDate", "endDate"] - }, - "RunListResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "runs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Run" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - }, - "window": { - "$ref": "#/components/schemas/Window" - } - }, - "required": ["runs", "pagination", "window"] - }, - "eventSortKeys": { - "type": "string", - "description": "Property by which to sort the list of task run events.", - "enum": ["status", "type", "publishedAt"] - } - }, - "responses": { - "BadRequest": { - "description": "Bad request or request arguments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "FeatureNotEnabled": { - "description": "This feature is not enabled on your Algolia account.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "MethodNotAllowed": { - "description": "Method not allowed with this API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "IndexNotFound": { - "description": "Index not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - } - } - }, - "x-tagGroups": [ - { - "name": "Resources", - "tags": [ - "authentications", - "destinations", - "observability", - "sources", - "tasks", - "transformations" - ] - } - ], - "x-timeouts": { - "browser": { - "connect": 25000, - "read": 25000, - "write": 25000 - }, - "server": { - "connect": 25000, - "read": 25000, - "write": 25000 - } - } -} diff --git a/src/data/monitoring.json b/src/data/monitoring.json deleted file mode 100644 index e019c6c..0000000 --- a/src/data/monitoring.json +++ /dev/null @@ -1,1225 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "Algolia Monitoring API", - "description": "The Monitoring API lets you check the status of your Algolia infrastructure.\n\n## Base URLs\n\nThe base URL for requests to the Monitoring API is:\n\n- `https://status.algolia.com`\n\n**All requests must use HTTPS.**\n\n## Availability and authentication\n\nAccess to the [Infrastructure](#tag/infrastructure) endpoints\nis available as part of the [Premium or Elevate plans](https://www.algolia.com/pricing).\n\nTo authenticate requests to the Infrastructure endpoints, add these headers:\n\n- `x-algolia-application-id`. Your Algolia application ID.\n- `x-algolia-api-key`. Your Monitoring API key.\n\nYou can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account).\n\nOther endpoints don't require authentication.\n\n## Response status and errors\n\nThe Monitoring API returns JSON responses.\nSince JSON doesn't guarantee any specific ordering, don't rely on the order of attributes in the API response.\n\nSuccessful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status.\nError responses have a `message` property with more information.\n\n## Version\n\nThe current version of the Monitoring API is version 1, as indicated by the `/1/` in each endpoint's URL.\n", - "version": "1.0.0" - }, - "servers": [ - { - "url": "https://status.algolia.com" - } - ], - "tags": [ - { - "name": "incidents", - "description": "List the known incidents.", - "x-displayName": "Incidents" - }, - { - "name": "infrastructure", - "description": "Return information about the Algolia infrastructure used by your application.", - "x-displayName": "Infrastructure" - }, - { - "name": "monitoring-tag", - "description": "Report search and indexing times for your clusters, and get a list of servers.", - "x-displayName": "Monitoring" - }, - { - "name": "status", - "description": "Report the status of Algolia clusters.", - "x-displayName": "Status" - } - ], - "paths": { - "/{path}": { - "get": { - "operationId": "customGet", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["monitoring"] - }, - "post": { - "operationId": "customPost", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["monitoring"] - }, - "put": { - "operationId": "customPut", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["monitoring"] - }, - "delete": { - "operationId": "customDelete", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["monitoring"] - } - }, - "/1/status": { - "get": { - "operationId": "getClustersStatus", - "summary": "Retrieve status of all clusters", - "security": [], - "tags": ["monitoring"], - "description": "Retrieves the status of all Algolia clusters and instances.", - "responses": { - "200": { - "$ref": "#/components/responses/StatusResponse" - }, - "401": { - "$ref": "#/components/responses/UnauthorizedResponse" - } - } - } - }, - "/1/status/{clusters}": { - "get": { - "summary": "Retrieve cluster status", - "description": "Retrieves the status of selected clusters.", - "operationId": "getClusterStatus", - "tags": ["monitoring"], - "security": [], - "parameters": [ - { - "$ref": "#/components/parameters/Clusters" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/StatusResponse" - }, - "401": { - "$ref": "#/components/responses/UnauthorizedResponse" - }, - "404": { - "$ref": "#/components/responses/NotFoundResponse" - } - } - } - }, - "/1/incidents": { - "get": { - "summary": "Retrieve all incidents", - "description": "Retrieves known incidents for all clusters.", - "operationId": "getIncidents", - "security": [], - "tags": ["monitoring"], - "responses": { - "200": { - "$ref": "#/components/responses/IncidentsResponse" - }, - "401": { - "$ref": "#/components/responses/UnauthorizedResponse" - } - } - } - }, - "/1/incidents/{clusters}": { - "get": { - "summary": "Retrieve cluster incidents", - "description": "Retrieves known incidents for the selected clusters.", - "operationId": "getClusterIncidents", - "tags": ["monitoring"], - "security": [], - "parameters": [ - { - "$ref": "#/components/parameters/Clusters" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/IncidentsResponse" - }, - "401": { - "$ref": "#/components/responses/UnauthorizedResponse" - }, - "404": { - "$ref": "#/components/responses/NotFoundResponse" - } - } - } - }, - "/1/inventory/servers": { - "get": { - "summary": "Retrieve servers", - "operationId": "getServers", - "security": [ - { - "applicationId": [] - }, - { - "apiKey": [] - } - ], - "description": "Retrieves the servers that belong to clusters.\n\nThe response depends on whether you authenticate your API request:\n\n- With authentication, the response lists the servers assigned to your\nAlgolia application's cluster.\n\n- Without authentication, the response lists the servers for all Algolia\nclusters.\n", - "tags": ["monitoring"], - "responses": { - "200": { - "$ref": "#/components/responses/InventoryResponse" - }, - "403": { - "$ref": "#/components/responses/ForbiddenResponse" - } - } - } - }, - "/1/latency/{clusters}": { - "get": { - "summary": "Retrieve search latency times", - "description": "Retrieves the average latency for search requests for selected clusters.", - "operationId": "getLatency", - "security": [], - "tags": ["monitoring"], - "parameters": [ - { - "$ref": "#/components/parameters/Clusters" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/LatencyResponse" - }, - "400": { - "$ref": "#/components/responses/BadRequestResponse" - } - } - } - }, - "/1/indexing/{clusters}": { - "get": { - "summary": "Retrieve indexing times", - "description": "Retrieves average times for indexing operations for selected clusters.", - "operationId": "getIndexingTime", - "security": [], - "tags": ["monitoring"], - "parameters": [ - { - "$ref": "#/components/parameters/Clusters" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/IndexingResponse" - }, - "400": { - "$ref": "#/components/responses/BadRequestResponse" - } - } - } - }, - "/1/reachability/{clusters}/probes": { - "get": { - "summary": "Test the reachability of clusters", - "description": "Test whether clusters are reachable or not.", - "operationId": "getReachability", - "security": [], - "tags": ["monitoring"], - "parameters": [ - { - "$ref": "#/components/parameters/Clusters" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/ReachabilityResponse" - }, - "400": { - "$ref": "#/components/responses/BadRequestResponse" - } - } - } - }, - "/1/infrastructure/{metric}/period/{period}": { - "get": { - "summary": "Retrieve metrics", - "description": "Retrieves metrics related to your Algolia infrastructure, aggregated over a selected time window.\n\nAccess to this API is available as part of the [Premium or Elevate plans](https://www.algolia.com/pricing).\nYou must authenticate requests with the `x-algolia-application-id` and `x-algolia-api-key` headers (using the Monitoring API key).\n", - "operationId": "getMetrics", - "tags": ["monitoring"], - "parameters": [ - { - "$ref": "#/components/parameters/MetricInPath" - }, - { - "$ref": "#/components/parameters/PeriodInPath" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/InfrastructureResponse" - }, - "401": { - "$ref": "#/components/responses/InfrastructureAPIUnauthorized" - } - } - } - }, - "/setClientApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["monitoring"], - "operationId": "setClientApiKey", - "summary": "Switch the API key used to authenticate requests", - "description": "Switch the API key used to authenticate requests.\n", - "parameters": [ - { - "in": "query", - "name": "apiKey", - "description": "API key to be used from now on.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No content." - } - } - } - } - }, - "components": { - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "X-Algolia-Application-Id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "X-Algolia-API-Key", - "description": "Your Algolia Monitoring API key." - } - }, - "parameters": { - "PathInPath": { - "name": "path", - "in": "path", - "description": "Path of the endpoint, anything after \"/1\" must be specified.", - "required": true, - "schema": { - "type": "string", - "example": "/keys" - } - }, - "Parameters": { - "name": "parameters", - "in": "query", - "description": "Query parameters to apply to the current query.", - "schema": { - "type": "object", - "additionalProperties": true - } - }, - "Clusters": { - "name": "clusters", - "in": "path", - "required": true, - "description": "Subset of clusters, separated by commas.", - "schema": { - "type": "string", - "example": "c1-de,c2-de,c3-de" - } - }, - "MetricInPath": { - "name": "metric", - "in": "path", - "required": true, - "description": "Metric to report.\n\nFor more information about the individual metrics, see the description of the API response.\nTo include all metrics, use `*`.\n", - "schema": { - "$ref": "#/components/schemas/Metric" - } - }, - "PeriodInPath": { - "name": "period", - "in": "path", - "required": true, - "description": "Period over which to aggregate the metrics:\n\n- `minute`. Aggregate the last minute. 1 data point per 10 seconds.\n- `hour`. Aggregate the last hour. 1 data point per minute.\n- `day`. Aggregate the last day. 1 data point per 10 minutes.\n- `week`. Aggregate the last week. 1 data point per hour.\n- `month`. Aggregate the last month. 1 data point per day.\n", - "schema": { - "$ref": "#/components/schemas/Period" - } - } - }, - "schemas": { - "ErrorBase": { - "description": "Error.", - "type": "object", - "x-keep-model": true, - "additionalProperties": true, - "properties": { - "message": { - "type": "string", - "example": "Invalid Application-Id or API-Key" - } - } - }, - "Status": { - "title": "status", - "type": "string", - "description": "Status of the cluster.", - "enum": ["operational", "degraded_performance", "partial_outage", "major_outage"] - }, - "Timestamp": { - "type": "integer", - "format": "int64", - "description": "Timestamp, measured in milliseconds since the Unix epoch." - }, - "Incident": { - "title": "incident", - "description": "Incident details.", - "type": "object", - "properties": { - "title": { - "type": "string", - "description": "Description of the incident." - }, - "status": { - "$ref": "#/components/schemas/Status" - } - } - }, - "Incidents": { - "title": "incidents", - "description": "Key-value pairs with the cluster names as keys and the list of incidents reported for this cluster as values.", - "type": "array", - "items": { - "title": "incidentEntry", - "type": "object", - "properties": { - "t": { - "$ref": "#/components/schemas/Timestamp" - }, - "v": { - "$ref": "#/components/schemas/Incident" - } - } - } - }, - "Region": { - "title": "region", - "type": "string", - "description": "Region where the cluster is located.", - "enum": [ - "au", - "br", - "ca", - "de", - "eu", - "hk", - "in", - "jp", - "sg", - "uae", - "uk", - "usc", - "use", - "usw", - "za" - ], - "example": "de" - }, - "ServerStatus": { - "title": "status", - "type": "string", - "enum": ["PRODUCTION"] - }, - "Type": { - "title": "type", - "type": "string", - "enum": ["cluster"] - }, - "Server": { - "title": "server", - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "Server name.", - "example": "c16-de-1" - }, - "region": { - "$ref": "#/components/schemas/Region" - }, - "is_slave": { - "type": "boolean", - "default": false, - "deprecated": true, - "description": "Included to support legacy applications.\nUse `is_replica` instead.\n", - "example": false - }, - "is_replica": { - "type": "boolean", - "default": false, - "description": "Whether this server is a replica of another server.", - "example": false - }, - "cluster": { - "type": "string", - "description": "Name of the cluster to which this server belongs.", - "example": "c16-de" - }, - "status": { - "$ref": "#/components/schemas/ServerStatus" - }, - "type": { - "$ref": "#/components/schemas/Type" - } - } - }, - "Time": { - "title": "times", - "description": "Time measured by a probe.", - "type": "array", - "items": { - "title": "timeEntry", - "type": "object", - "additionalProperties": false, - "properties": { - "t": { - "$ref": "#/components/schemas/Timestamp" - }, - "v": { - "type": "integer", - "description": "Time in ms." - } - } - } - }, - "Probes": { - "title": "probes", - "description": "Probes and their response.", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "probe", - "type": "boolean", - "description": "Key-value pair with the probe name as the key and the reachability status as the value." - } - }, - "Metric": { - "type": "string", - "enum": [ - "avg_build_time", - "ssd_usage", - "ram_search_usage", - "ram_indexing_usage", - "cpu_usage", - "*" - ], - "example": "*" - }, - "Period": { - "type": "string", - "enum": ["minute", "hour", "day", "week", "month"], - "example": "week" - }, - "ProbesMetric": { - "title": "metric", - "type": "object", - "additionalProperties": false, - "properties": { - "t": { - "$ref": "#/components/schemas/Timestamp" - }, - "v": { - "type": "integer", - "description": "Value of the metric." - } - } - }, - "InfraProbes": { - "title": "probes", - "type": "array", - "items": { - "$ref": "#/components/schemas/ProbesMetric" - } - } - }, - "responses": { - "BadRequest": { - "description": "Bad request or request arguments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "FeatureNotEnabled": { - "description": "This feature is not enabled on your Algolia account.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "MethodNotAllowed": { - "description": "Method not allowed with this API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "IndexNotFound": { - "description": "Index not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "StatusResponse": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "statusResponse", - "type": "object", - "properties": { - "status": { - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "cluster", - "$ref": "#/components/schemas/Status" - } - } - } - }, - "examples": { - "Success": { - "value": { - "status": { - "c16-de": "operational" - } - } - } - } - } - } - }, - "UnauthorizedResponse": { - "description": "Unauthorized", - "content": { - "text/plain": { - "schema": { - "type": "string" - }, - "examples": { - "Unauthorized": { - "summary": "Invalid credentials", - "description": "Use the Monitoring API key.", - "value": "Invalid credentials" - } - } - } - } - }, - "NotFoundResponse": { - "description": "Not Found.", - "content": { - "text/plain": { - "schema": { - "type": "string" - }, - "examples": { - "NotFound": { - "value": "Unknown cluster \"test\"" - } - } - } - } - }, - "IncidentsResponse": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "incidentsResponse", - "type": "object", - "properties": { - "incidents": { - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "cluster", - "$ref": "#/components/schemas/Incidents" - } - } - } - }, - "examples": { - "success": { - "value": { - "incidents": { - "m134-de": [ - { - "t": 1687441685000, - "v": { - "title": "Incident on cluster m134-de: Everything operating normally.\n", - "status": "operational" - } - }, - { - "t": 1687441579000, - "v": { - "title": "Incident on cluster m134-de: We are encountering a major\nissue that impact all API calls.\n", - "status": "major_outage" - } - } - ] - } - } - } - } - } - } - }, - "InventoryResponse": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "inventoryResponse", - "type": "object", - "properties": { - "inventory": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Server" - } - } - } - }, - "examples": { - "Success": { - "value": { - "inventory": [ - { - "name": "c16-de-3", - "region": "de", - "is_slave": false, - "is_replica": false, - "cluster": "c16-de", - "status": "PRODUCTION", - "type": "cluster" - }, - { - "name": "c16-de-2", - "region": "de", - "is_slave": false, - "is_replica": false, - "cluster": "c16-de", - "status": "PRODUCTION", - "type": "cluster" - }, - { - "name": "c16-de-1", - "region": "de", - "is_slave": false, - "is_replica": false, - "cluster": "c16-de", - "status": "PRODUCTION", - "type": "cluster" - } - ] - } - } - } - } - } - }, - "ForbiddenResponse": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "title": "forbidden", - "type": "object", - "additionalProperties": false, - "properties": { - "reason": { - "type": "string" - } - } - }, - "examples": { - "Forbidden": { - "value": { - "reason": "invalid credentials" - } - } - } - } - } - }, - "LatencyResponse": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "latencyResponse", - "type": "object", - "properties": { - "metrics": { - "title": "latencyMetric", - "type": "object", - "additionalProperties": false, - "properties": { - "latency": { - "additionalProperties": { - "x-additionalPropertiesName": "latencies", - "$ref": "#/components/schemas/Time" - } - } - } - } - } - }, - "examples": { - "Success": { - "value": { - "metrics": { - "latency": { - "c16-de": [ - { - "t": 1688056200000, - "v": 64 - }, - { - "t": 1688056800000, - "v": 59 - }, - { - "t": 1688057400000, - "v": 55 - } - ] - } - } - } - } - } - } - } - }, - "BadRequestResponse": { - "description": "Bad Request.", - "content": { - "application/json": { - "schema": { - "title": "badRequest", - "type": "object", - "additionalProperties": false, - "properties": { - "reason": { - "type": "string" - } - } - }, - "examples": { - "BadRequest": { - "value": { - "reason": "Unknown servers" - } - } - } - } - } - }, - "IndexingResponse": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "indexingTimeResponse", - "type": "object", - "properties": { - "metrics": { - "title": "indexingMetric", - "type": "object", - "additionalProperties": false, - "properties": { - "indexing": { - "additionalProperties": { - "x-additionalPropertiesName": "cluster", - "$ref": "#/components/schemas/Time" - } - } - } - } - } - }, - "examples": { - "Success": { - "value": { - "metrics": { - "indexing": { - "c16-de": [ - { - "t": 1688056200000, - "v": 1562 - }, - { - "t": 1688056800000, - "v": 1637 - }, - { - "t": 1688057400000, - "v": 1754 - } - ] - } - } - } - } - } - } - } - }, - "ReachabilityResponse": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "reachabilityResponse", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "cluster", - "$ref": "#/components/schemas/Probes" - } - }, - "examples": { - "Success": { - "value": { - "c16-de": { - "sdn-probe-frankfurt": false, - "monitoring-2": false, - "sdn-probe-awswest1": false - } - } - } - } - } - } - }, - "InfrastructureResponse": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "infrastructureResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "metrics": { - "title": "metrics", - "type": "object", - "additionalProperties": false, - "properties": { - "cpu_usage": { - "type": "object", - "description": "CPU idleness in %.", - "additionalProperties": { - "x-additionalPropertiesName": "probes", - "$ref": "#/components/schemas/InfraProbes" - } - }, - "ram_indexing_usage": { - "type": "object", - "description": "RAM used for indexing in MB.", - "additionalProperties": { - "x-additionalPropertiesName": "probes", - "$ref": "#/components/schemas/InfraProbes" - } - }, - "ram_search_usage": { - "type": "object", - "description": "RAM used for search in MB.", - "additionalProperties": { - "x-additionalPropertiesName": "probes", - "$ref": "#/components/schemas/InfraProbes" - } - }, - "ssd_usage": { - "type": "object", - "description": "Solid-state disk (SSD) usage expressed as % of RAM.\n0% means no SSD usage. A value of 50% indicates 32 GB SSD usage for a machine with 64 RAM.\n", - "additionalProperties": { - "x-additionalPropertiesName": "probes", - "$ref": "#/components/schemas/InfraProbes" - } - }, - "avg_build_time": { - "type": "object", - "description": "Average build time of the indices in seconds.", - "additionalProperties": { - "x-additionalPropertiesName": "probes", - "$ref": "#/components/schemas/InfraProbes" - } - } - } - } - } - }, - "examples": { - "success": { - "value": { - "metrics": { - "cpu_usage": { - "s4-fr": [ - { - "t": 1455101280, - "v": 46 - }, - { - "t": 1455101290, - "v": 46 - }, - { - "t": 1455101300, - "v": 46 - } - ], - "c3-use-1": [ - { - "t": 1455101280, - "v": 42 - }, - { - "t": 1455101290, - "v": 42 - }, - { - "t": 1455101300, - "v": 42 - }, - { - "t": 1455101310, - "v": 37 - } - ], - "c3-use-2": [ - { - "t": 1455101280, - "v": 56 - }, - { - "t": 1455101290, - "v": 56 - }, - { - "t": 1455101300, - "v": 56 - }, - { - "t": 1455101310, - "v": 56 - }, - { - "t": 1455101320, - "v": 51 - } - ] - } - } - } - } - } - } - } - }, - "InfrastructureAPIUnauthorized": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "title": "unauthorized", - "type": "object", - "additionalProperties": false, - "properties": { - "reason": { - "type": "string" - } - } - }, - "examples": { - "Unauthorized": { - "value": { - "reason": "The infrastructure usage API is only available on Enterprise plans. Please contact enterprise@algolia.com for more detail." - } - } - } - } - } - } - } - }, - "x-tagGroups": [ - { - "name": "General", - "tags": ["status", "incidents", "infrastructure", "monitoring-tag"] - } - ] -} diff --git a/src/data/query-suggestions.json b/src/data/query-suggestions.json deleted file mode 100644 index 0d35c4e..0000000 --- a/src/data/query-suggestions.json +++ /dev/null @@ -1,1088 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "Query Suggestions API", - "description": "The Query Suggestions API lets you manage your Query Suggestions configurations.\nQuery Suggestions add new indices to your Algolia application with popular search queries, external suggestions, or facet values.\nIn your user interface, you can query the Query Suggestions indices like regular indices and add [suggested searches](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js/) to guide users and speed up their search.\n\n## Base URLs\n\nThe base URLs for requests to the Query Suggestions API are:\n\n- `https://query-suggestions.us.algolia.com`\n- `https://query-suggestions.eu.algolia.com`\n\nUse the URL that matches your [analytics region](https://dashboard.algolia.com/account/infrastructure/analytics).\n\n**All requests must use HTTPS.**\n\n## Authentication\n\nTo authenticate your API requests, add these headers:\n\n- `x-algolia-application-id`. Your Algolia application ID.\n- `x-algolia-api-key`. An API key with the necessary permissions to make the request.\n The required access control list (ACL) to make a request is listed in each endpoint's reference.\n\nYou can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account).\n\n## Request format\n\nRequest bodies must be JSON objects.\n\n## Response status and errors\n\nResponse bodies are JSON objects.\nDeleting a user token returns an empty response body with rate-limiting information as headers.\n\nSuccessful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status.\nError responses have a `message` property with more information.\n\n## Version\n\nThe current version of the Query Suggestions API is version 1, as indicated by the `/1/` in each endpoint's URL.\n", - "version": "1.0.0" - }, - "servers": [ - { - "url": "https://query-suggestions.{region}.algolia.com", - "description": "You can check the region for your application in the [Algolia dashboard](https://dashboard.algolia.com/account/infrastructure/analytics).\nIf you connect to the wrong region, the API returns an error with the status `401` and the message: \"The log processing region does not match\".\n", - "variables": { - "region": { - "enum": ["us", "eu"], - "default": "us" - } - } - } - ], - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ], - "tags": [ - { - "name": "configurations", - "x-displayName": "Configurations", - "description": "Manage Query Suggestions configurations." - }, - { - "name": "logs", - "x-displayName": "Logs", - "description": "Get logs for a Query Suggestions index." - } - ], - "paths": { - "/{path}": { - "get": { - "operationId": "customQuerySuggestionGet", - "summary": "Send requests to the Algolia Query Suggestions REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["query-suggestions"] - }, - "post": { - "operationId": "customQuerySuggestionPost", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia Query Suggestions REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["query-suggestions"] - }, - "put": { - "operationId": "customQuerySuggestionPut", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia Query Suggestions REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["query-suggestions"] - }, - "delete": { - "operationId": "customQuerySuggestionDelete", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia Query Suggestions REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["query-suggestions"] - } - }, - "/1/configs": { - "get": { - "tags": ["query-suggestions"], - "operationId": "listQuerySuggestionsConfigs", - "x-acl": ["settings"], - "summary": "List Query Suggestions configurations", - "description": "Retrieves all Query Suggestions configurations of your Algolia application.", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ConfigurationResponse" - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - } - } - }, - "post": { - "tags": ["query-suggestions"], - "operationId": "createQuerySuggestionsConfig", - "x-acl": ["editSettings"], - "summary": "Create a Query Suggestions configuration", - "description": "Creates a new Query Suggestions configuration.\n\nYou can have up to 100 configurations per Algolia application.\n", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ConfigurationWithIndex" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "Created": { - "summary": "Configuration created", - "value": { - "status": 200, - "message": "Configuration was created, and a new indexing job has been scheduled." - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest-2" - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "422": { - "$ref": "#/components/responses/UnprocessableEntity" - }, - "500": { - "$ref": "#/components/responses/InternalError" - } - } - } - }, - "/1/configs/{indexName}": { - "get": { - "tags": ["query-suggestions"], - "operationId": "getQuerySuggestionsConfig", - "x-acl": ["settings"], - "summary": "Retrieve a Query Suggestions configuration", - "description": "Retrieves a single Query Suggestions configuration by its index name.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ConfigurationResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest-2" - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - }, - "put": { - "tags": ["query-suggestions"], - "operationId": "updateQuerySuggestionConfig", - "x-acl": ["editSettings"], - "summary": "Update a Query Suggestions configuration", - "description": "Updates a QuerySuggestions configuration.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Configuration" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "Created": { - "summary": "Configuration created", - "value": { - "status": 200, - "message": "Configuration was updated, and a new indexing job has been scheduled." - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "500": { - "$ref": "#/components/responses/InternalError-2" - } - } - }, - "delete": { - "tags": ["query-suggestions"], - "operationId": "deleteQuerySuggestionConfig", - "x-acl": ["editSettings"], - "summary": "Delete a Query Suggestions configuration", - "description": "Deletes a Query Suggestions configuration.\n\nDeleting only removes the configuration and stops updates to the Query Suggestions index.\nTo delete the Query Suggestions index itself, use the Search API and the `Delete an index` operation.\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "Created": { - "summary": "Configuration created", - "value": { - "status": 200, - "message": "Configuration was deleted with success." - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "500": { - "$ref": "#/components/responses/InternalError-2" - } - } - } - }, - "/1/configs/{indexName}/status": { - "get": { - "tags": ["query-suggestions"], - "operationId": "getQuerySuggestionConfigStatus", - "x-acl": ["settings"], - "summary": "Retrieve a Query Suggestions configuration status", - "description": "Reports the status of a Query Suggestions index.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "configStatus", - "type": "object", - "additionalProperties": false, - "properties": { - "indexName": { - "$ref": "#/components/schemas/IndexName" - }, - "isRunning": { - "type": "boolean", - "description": "Whether the creation or update of the Query Suggestions index is in progress.", - "example": false - }, - "lastBuiltAt": { - "type": "string", - "description": "Date and time when the Query Suggestions index was last built, in RFC 3339 format.", - "example": "2023-07-05T08:03:53Z" - }, - "lastSuccessfulBuiltAt": { - "type": "string", - "description": "Date and time when the Query Suggestions index was last updated successfully.", - "example": "2023-07-05T08:03:53Z" - }, - "lastSuccessfulBuildDuration": { - "type": "string", - "description": "Duration of the last successful build in seconds.", - "example": 28 - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - } - }, - "/1/logs/{indexName}": { - "get": { - "tags": ["query-suggestions"], - "operationId": "getQuerySuggestionLogFile", - "x-acl": ["settings"], - "summary": "Retrieve a Query Suggestions index logs", - "description": "Retrieves the logs for a single Query Suggestions index.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "logFile", - "type": "object", - "additionalProperties": false, - "properties": { - "timestamp": { - "type": "string", - "description": "Date and time of the log entry, in RFC 3339 format.", - "example": "2023-07-05T08:03:33.898076171Z" - }, - "level": { - "$ref": "#/components/schemas/LogLevel" - }, - "message": { - "type": "string", - "description": "Details about this log entry.", - "example": "skipping query \"Brooke Adams\": not enough search results, got 1, expected 5" - }, - "contextLevel": { - "type": "integer", - "description": "Level indicating the position of a suggestion in a hierarchy of records.\n\nFor example, a `contextLevel` of 1 indicates that this suggestion belongs to a previous suggestion with `contextLevel` 0.\n", - "example": 1 - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - } - }, - "/setClientApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["query-suggestions"], - "operationId": "setClientApiKey", - "summary": "Switch the API key used to authenticate requests", - "description": "Switch the API key used to authenticate requests.\n", - "parameters": [ - { - "in": "query", - "name": "apiKey", - "description": "API key to be used from now on.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No content." - } - } - } - } - }, - "components": { - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-application-id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-api-key", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - }, - "parameters": { - "PathInPath": { - "name": "path", - "in": "path", - "description": "Path of the endpoint, anything after \"/1\" must be specified.", - "required": true, - "schema": { - "type": "string", - "example": "/keys" - } - }, - "Parameters": { - "name": "parameters", - "in": "query", - "description": "Query parameters to apply to the current query.", - "schema": { - "type": "object", - "additionalProperties": true - } - }, - "IndexName": { - "name": "indexName", - "in": "path", - "required": true, - "description": "Query Suggestions index name.", - "schema": { - "$ref": "#/components/schemas/IndexName" - } - } - }, - "schemas": { - "ErrorBase": { - "description": "Error.", - "type": "object", - "x-keep-model": true, - "additionalProperties": true, - "properties": { - "message": { - "type": "string", - "example": "Invalid Application-Id or API-Key" - } - } - }, - "AppID": { - "type": "object", - "properties": { - "appID": { - "type": "string", - "description": "Algolia application ID to which this Query Suggestions configuration belongs." - } - } - }, - "IndexName": { - "title": "indexName", - "type": "string", - "description": "Name of the Query Suggestions index (case-sensitive).", - "example": "ALGOLIA_INDEX_NAME" - }, - "AnalyticsTags": { - "title": "analyticsTags", - "description": "Analytics tags for filtering the popular searches.\nFor more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).\n", - "default": null, - "oneOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "Facet": { - "type": "object", - "description": "Facet to use as category.", - "properties": { - "attribute": { - "type": "string", - "description": "Facet name." - }, - "amount": { - "type": "integer", - "description": "Number of suggestions." - } - } - }, - "Facets": { - "title": "facets", - "description": "Facets to use as top categories with your suggestions.\n\nIf provided, Query Suggestions adds the top facet values to each suggestion.\n", - "default": null, - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/Facet" - } - }, - { - "type": "null" - } - ], - "example": [ - { - "attribute": "category", - "amount": 3 - }, - { - "attribute": "brand", - "amount": 2 - } - ] - }, - "Generate": { - "title": "generate", - "description": "Facets used for generating query suggestions from facet values.\n\nFor example, if you set `generate: [\"color\", \"brand\"]`, combinations from the facet values are added as query suggestions,\nsuch as \"blue adidas\", \"red adidas\", \"blue nike\", \"red nike\", etc.\n\nYou can include nested lists.\n", - "default": null, - "oneOf": [ - { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "string" - } - } - }, - { - "type": "null" - } - ], - "example": [["color", "brand"]] - }, - "External": { - "description": "Algolia indices with popular searches to use as query suggestions.\n\nRecords of these indices must have these attributes:\n\n- `query`: search query which will be added as a suggestion\n- `count`: measure of popularity of that search query\n\nFor example, you can export popular searches from an external analytics provider, such as Google Analytics or Adobe Analytics,\nand feed this data into an Algolia index.\nYou can use this index to generate query suggestions until your Algolia Analytics has collected enough data.\n", - "default": null, - "oneOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "SourceIndex": { - "type": "object", - "description": "Configuration of an Algolia index for Query Suggestions.", - "required": ["indexName"], - "properties": { - "indexName": { - "type": "string", - "description": "Name of the Algolia index (case-sensitive) to use as source for query suggestions.", - "example": "products" - }, - "replicas": { - "type": "boolean", - "default": false, - "description": "If true, Query Suggestions uses all replica indices to find popular searches.\nIf false, only the primary index is used.\n", - "example": false - }, - "analyticsTags": { - "$ref": "#/components/schemas/AnalyticsTags" - }, - "facets": { - "$ref": "#/components/schemas/Facets" - }, - "minHits": { - "type": "integer", - "minimum": 0, - "default": 5, - "description": "Minimum number of hits required to be included as a suggestion.\n\nA search query must at least generate `minHits` search results to be included in the Query Suggestions index.\n" - }, - "minLetters": { - "type": "integer", - "minimum": 0, - "default": 4, - "description": "Minimum letters required to be included as a suggestion.\n\nA search query must be at least `minLetters` long to be included in the Query Suggestions index.\n" - }, - "generate": { - "$ref": "#/components/schemas/Generate" - }, - "external": { - "$ref": "#/components/schemas/External" - } - } - }, - "Languages": { - "title": "languages", - "description": "Languages for deduplicating singular and plural suggestions.\nIf specified, only the more popular form is included.\n", - "default": false, - "oneOf": [ - { - "type": "array", - "description": "Languages for which to deduplicate singular and plural forms.", - "items": { - "type": "string", - "description": "Two-letter country code." - } - }, - { - "type": "boolean", - "description": "If true, deduplication is enabled for all languages." - } - ] - }, - "Exclude": { - "title": "exclude", - "description": "Words or regular expressions to exclude from the suggestions.", - "default": null, - "oneOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] - }, - "Configuration": { - "type": "object", - "description": "Query Suggestions configuration.", - "required": ["sourceIndices"], - "properties": { - "sourceIndices": { - "type": "array", - "description": "Algolia indices from which to get the popular searches for query suggestions.", - "minItems": 1, - "items": { - "$ref": "#/components/schemas/SourceIndex" - } - }, - "languages": { - "$ref": "#/components/schemas/Languages" - }, - "exclude": { - "$ref": "#/components/schemas/Exclude" - }, - "enablePersonalization": { - "type": "boolean", - "default": false, - "description": "Whether to turn on personalized query suggestions." - }, - "allowSpecialCharacters": { - "type": "boolean", - "default": false, - "description": "Whether to include suggestions with special characters." - } - } - }, - "ConfigurationWithIndex": { - "type": "object", - "description": "Query Suggestions configuration.", - "required": ["indexName", "sourceIndices"], - "allOf": [ - { - "type": "object", - "properties": { - "indexName": { - "$ref": "#/components/schemas/IndexName" - } - } - }, - { - "$ref": "#/components/schemas/Configuration" - } - ], - "unevaluatedProperties": false - }, - "ConfigurationResponse": { - "type": "object", - "description": "API response for retrieving Query Suggestions configurations.", - "allOf": [ - { - "$ref": "#/components/schemas/AppID" - }, - { - "$ref": "#/components/schemas/ConfigurationWithIndex" - } - ], - "required": [ - "appID", - "allowSpecialCharacters", - "enablePersonalization", - "exclude", - "languages", - "sourceIndices" - ], - "unevaluatedProperties": false - }, - "BaseResponse": { - "type": "object", - "properties": { - "status": { - "type": "integer", - "description": "HTTP status code." - }, - "message": { - "type": "string", - "description": "Details about the response, such as error messages." - } - } - }, - "LogLevel": { - "title": "level", - "type": "string", - "description": "Type of log entry.\n\n- `SKIP`. A query is skipped because it doesn't match the conditions for successful inclusion. For example, when a query doesn't generate enough search results.\n- `INFO`. An informative log entry.\n- `ERROR`. The Query Suggestions process encountered an error.\n", - "enum": ["SKIP", "INFO", "ERROR"] - } - }, - "responses": { - "BadRequest": { - "description": "Bad request or request arguments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "FeatureNotEnabled": { - "description": "This feature is not enabled on your Algolia account.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "MethodNotAllowed": { - "description": "Method not allowed with this API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "IndexNotFound": { - "description": "Index not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "Unauthorized": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "Unauthorized": { - "summary": "Wrong region", - "description": "Make sure to make your request to the server corresponding to your region.\n\nYou can check the region for your application in the [Algolia dashboard](https://dashboard.algolia.com/account/infrastructure/analytics).\n", - "value": { - "status": 401, - "message": "The log processing region does not match." - } - }, - "InvalidCredentials": { - "summary": "Invalid credentials", - "description": "Your application ID or API key is wrong.", - "value": { - "status": 401, - "message": "Invalid credentials" - } - }, - "MissingACL": { - "summary": "Key is missing ACL", - "description": "Your API key is missing the required ACL for this operation.", - "value": { - "status": 401, - "message": "The provided API key is missing the \\\"editSettings\\\" ACL." - } - } - } - } - } - }, - "BadRequest-2": { - "description": "Bad Request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "IndexNameRequired": { - "summary": "Index name required", - "value": { - "status": 400, - "message": "IndexName cannot be empty." - } - }, - "SourceIndicesRequired": { - "summary": "Source indices required", - "value": { - "status": 400, - "message": "Invalid body \"sourceIndices needs to contain at least one index\"." - } - }, - "SourceIndexNameRequired": { - "summary": "Source index name required", - "value": { - "status": 400, - "message": "Invalid body \"every source index must have an `indexName`\"." - } - }, - "MinHitsPositive": { - "summary": "MinHits must be positive", - "value": { - "status": 400, - "message": "Invalid body \"every source index `minHits` must be positive\"." - } - }, - "MinLettersPositive": { - "summary": "MinLetters must be positive", - "value": { - "status": 400, - "message": "Invalid body \"every source index `minLetters` must be positive\"." - } - } - } - } - } - }, - "UnprocessableEntity": { - "description": "Unprocessable Entity.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "UnprocessableEntity": { - "summary": "Configuration already exists", - "value": { - "status": 422, - "message": "Configuration already exists for index: test-qs" - } - } - } - } - } - }, - "InternalError": { - "description": "Internal error.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "NotFound": { - "description": "Not Found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "NotFound": { - "summary": "Index not found", - "value": { - "status": 404, - "message": "Not Found" - } - } - } - } - } - }, - "InternalError-2": { - "description": "Internal Server Error.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BaseResponse" - }, - "examples": { - "Error": { - "description": "This error can happen if you use a non-existing `indexName` as a path parameter when trying to update or delete a Query Suggestions configuration.", - "value": { - "status": 500, - "message": "Internal Server Error" - } - } - } - } - } - } - } - }, - "x-tagGroups": [ - { - "name": "Configurations", - "tags": ["configurations"] - }, - { - "name": "Logs", - "tags": ["logs"] - } - ] -} diff --git a/src/data/recommend.json b/src/data/recommend.json deleted file mode 100644 index 231eed3..0000000 --- a/src/data/recommend.json +++ /dev/null @@ -1,3212 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "Recommend API", - "description": "The Recommend API lets you retrieve recommendations from one of Algolia's AI recommendation models that you previously trained on your data.\n\n## Client libraries\n\nUse Algolia's API clients and libraries to reliably integrate Algolia's APIs with your apps.\nThe official API clients are covered by Algolia's [Service Level Agreement](https://www.algolia.com/policies/sla/).\n\nSee: [Algolia's ecosystem](https://www.algolia.com/doc/guides/getting-started/how-algolia-works/in-depth/ecosystem/)\n\n## Base URLs\n\nThe base URLs for requests to the Recommend API are:\n\n- `https://{APPLICATION_ID}.algolia.net`\n- `https://{APPLICATION_ID}-dsn.algolia.net`.\n If your subscription includes a [Distributed Search Network](https://dashboard.algolia.com/infra),\n this ensures that requests are sent to servers closest to users.\n\nBoth URLs provide high availability by distributing requests with load balancing.\n\n**All requests must use HTTPS.**\n\n## Retry strategy\n\nTo guarantee a high availability, implement a retry strategy for all API requests using the URLs of your servers as fallbacks:\n\n- `https://{APPLICATION_ID}-1.algolianet.com`\n- `https://{APPLICATION_ID}-2.algolianet.com`\n- `https://{APPLICATION_ID}-3.algolianet.com`\n\nThese URLs use a different DNS provider than the primary URLs.\nYou should randomize this list to ensure an even load across the three servers.\n\nAll Algolia API clients implement this retry strategy.\n\n## Authentication\n\nTo authenticate your API requests, add these headers:\n\n- `x-algolia-application-id`. Your Algolia application ID.\n- `x-algolia-api-key`. An API key with the necessary permissions to make the request.\n The required access control list (ACL) to make a request is listed in each endpoint's reference.\n\nYou can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account).\n\n## Request format\n\nRequest bodies must be JSON objects.\n\n## Response status and errors\n\nThe Recommend API returns JSON responses.\nSince JSON doesn't guarantee any specific ordering, don't rely on the order of attributes in the API response.\n\nSuccessful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status.\nError responses have a `message` property with more information.\n\n## Version\n\nThe current version of the Recommend API is version 1, as indicated by the `/1/` in each endpoint's URL.\n", - "version": "1.0.0" - }, - "servers": [ - { - "url": "https://{applicationId}.algolia.net", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-1.algolianet.com", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-2.algolianet.com", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-3.algolianet.com", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-dsn.algolia.net", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - } - ], - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ], - "tags": [ - { - "name": "recommendations", - "x-displayName": "Recommendations", - "description": "Retrieve recommendations from a pre-trained AI model. You can train models in the [Algolia dashboard](https://dashboard.algolia.com/recommend/).", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/algolia-recommend/overview/", - "description": "Related guide: Algolia Recommend.\n" - } - }, - { - "name": "rules", - "x-displayName": "Rules", - "description": "Curate your recommendations with rules, which are _if_-_then_ statements.", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/algolia-recommend/how-to/rules/", - "description": "Related guide: Recommend Rules.\n" - } - } - ], - "paths": { - "/{path}": { - "get": { - "operationId": "customGet", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["recommend"] - }, - "post": { - "operationId": "customPost", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["recommend"] - }, - "put": { - "operationId": "customPut", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["recommend"] - }, - "delete": { - "operationId": "customDelete", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["recommend"] - } - }, - "/1/indexes/*/recommendations": { - "post": { - "tags": ["recommend"], - "operationId": "getRecommendations", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["search"], - "x-legacy-signature-recommend": true, - "summary": "Retrieve recommendations", - "description": "Retrieves recommendations from selected AI models.\n", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "getRecommendationsParams", - "description": "Recommend request body.", - "type": "object", - "additionalProperties": false, - "properties": { - "requests": { - "type": "array", - "description": "Recommendation request with parameters depending on the requested model.", - "items": { - "$ref": "#/components/schemas/recommendationsRequest" - } - } - }, - "required": ["requests"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getRecommendationsResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/recommendationsResults" - } - } - }, - "required": ["results"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/{model}/recommend/rules/{objectID}": { - "get": { - "tags": ["recommend"], - "operationId": "getRecommendRule", - "x-acl": ["settings"], - "summary": "Retrieve a rule", - "description": "Retrieves a Recommend rule that you previously created in the Algolia dashboard.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/Models" - }, - { - "$ref": "#/components/parameters/ObjectID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RecommendRule" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["recommend"], - "operationId": "deleteRecommendRule", - "x-acl": ["editSettings"], - "summary": "Delete a rule", - "description": "Deletes a Recommend rule from a recommendation scenario.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/Models" - }, - { - "$ref": "#/components/parameters/ObjectID" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/DeletedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/{model}/task/{taskID}": { - "get": { - "tags": ["recommend"], - "operationId": "getRecommendStatus", - "x-acl": ["editSettings"], - "summary": "Check task status", - "description": "Checks the status of a given task.\n\nDeleting a Recommend rule is asynchronous.\nWhen you delete a rule, a task is created on a queue and completed depending on the load on the server.\nThe API response includes a task ID that you can use to check the status.\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/Models" - }, - { - "name": "taskID", - "in": "path", - "description": "Unique task identifier.", - "required": true, - "schema": { - "$ref": "#/components/schemas/taskID" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getRecommendTaskResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "status": { - "$ref": "#/components/schemas/taskStatus" - } - }, - "required": ["status"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/{model}/recommend/rules/search": { - "post": { - "tags": ["recommend"], - "operationId": "searchRecommendRules", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["settings"], - "summary": "Search for rules", - "description": "Searches for Recommend rules.\n\nUse an empty query to list all rules for this recommendation scenario.\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/Models" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "title": "searchRecommendRulesParams", - "type": "object", - "description": "Recommend rules parameters.", - "additionalProperties": false, - "properties": { - "query": { - "$ref": "#/components/schemas/parameters_query" - }, - "context": { - "type": "string", - "description": "Only search for rules with matching context.", - "example": "mobile" - }, - "page": { - "$ref": "#/components/schemas/parameters_page" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/parameters_hitsPerPage" - }, - "enabled": { - "type": "boolean", - "description": "Whether to only show rules where the value of their `enabled` property matches this parameter.\nIf absent, show all rules, regardless of their `enabled` property.\n" - }, - "filters": { - "type": "string", - "description": "Filter expression. This only searches for rules matching the filter expression.", - "example": "objectID:rr-123456" - }, - "facets": { - "type": "array", - "description": "Include facets and facet values in the response. Use `['*']` to include all facets.", - "example": ["*"], - "items": { - "type": "string", - "description": "Facet name for rule objects or `*` as wildcard character.", - "example": "condition.context" - } - }, - "maxValuesPerFacet": { - "type": "integer", - "description": "Maximum number of values to return for each facet.", - "minimum": 1, - "maximum": 1000 - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchRecommendRulesResponse", - "type": "object", - "additionalProperties": false, - "required": ["hits", "nbHits", "page", "nbPages"], - "properties": { - "hits": { - "type": "array", - "description": "Recommend rules that match the search criteria.", - "items": { - "$ref": "#/components/schemas/RecommendRule" - } - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - }, - "page": { - "$ref": "#/components/schemas/page" - }, - "nbPages": { - "$ref": "#/components/schemas/nbPages" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/{model}/recommend/rules/batch": { - "post": { - "tags": ["recommend"], - "operationId": "batchRecommendRules", - "x-acl": ["editSettings"], - "summary": "Create or update a batch of Recommend Rules", - "description": "Create or update a batch of Recommend Rules\n\nEach Recommend Rule is created or updated, depending on whether a Recommend Rule with the same `objectID` already exists.\nYou may also specify `true` for `clearExistingRules`, in which case the batch will atomically replace all the existing Recommend Rules.\n\nRecommend Rules are similar to Search Rules, except that the conditions and consequences apply to a [source item](/doc/guides/algolia-recommend/overview/#recommend-models) instead of a query. The main differences are the following:\n- Conditions `pattern` and `anchoring` are unavailable.\n- Condition `filters` triggers if the source item matches the specified filters.\n- Condition `filters` accepts numeric filters.\n- Consequence `params` only covers filtering parameters.\n- Consequence `automaticFacetFilters` doesn't require a facet value placeholder (it tries to match the data source item's attributes instead).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/Models" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "title": "rules", - "type": "array", - "description": "Recommend rules.", - "items": { - "$ref": "#/components/schemas/RecommendRule" - } - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/RecommendUpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/setClientApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["recommend"], - "operationId": "setClientApiKey", - "summary": "Switch the API key used to authenticate requests", - "description": "Switch the API key used to authenticate requests.\n", - "parameters": [ - { - "in": "query", - "name": "apiKey", - "description": "API key to be used from now on.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No content." - } - } - } - } - }, - "components": { - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-application-id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-api-key", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - }, - "parameters": { - "PathInPath": { - "name": "path", - "in": "path", - "description": "Path of the endpoint, anything after \"/1\" must be specified.", - "required": true, - "schema": { - "type": "string", - "example": "/keys" - } - }, - "Parameters": { - "name": "parameters", - "in": "query", - "description": "Query parameters to apply to the current query.", - "schema": { - "type": "object", - "additionalProperties": true - } - }, - "IndexName": { - "name": "indexName", - "in": "path", - "description": "Name of the index on which to perform the operation.", - "required": true, - "schema": { - "type": "string", - "example": "ALGOLIA_INDEX_NAME" - } - }, - "Models": { - "in": "path", - "name": "model", - "required": true, - "description": "[Recommend model](https://www.algolia.com/doc/guides/algolia-recommend/overview/#recommend-models).\n", - "schema": { - "$ref": "#/components/schemas/recommendModels" - } - }, - "ObjectID": { - "name": "objectID", - "in": "path", - "description": "Unique record identifier.", - "required": true, - "schema": { - "$ref": "#/components/schemas/objectID" - } - } - }, - "schemas": { - "ErrorBase": { - "description": "Error.", - "type": "object", - "x-keep-model": true, - "additionalProperties": true, - "properties": { - "message": { - "type": "string", - "example": "Invalid Application-Id or API-Key" - } - } - }, - "indexName": { - "type": "string", - "example": "products", - "description": "Index name (case-sensitive)." - }, - "similarQuery": { - "type": "string", - "description": "Keywords to be used instead of the search query to conduct a more broader search.\n\nUsing the `similarQuery` parameter changes other settings:\n\n- `queryType` is set to `prefixNone`.\n- `removeStopWords` is set to true.\n- `words` is set as the first ranking criterion.\n- All remaining words are treated as `optionalWords`.\n\nSince the `similarQuery` is supposed to do a broad search, they usually return many results.\nCombine it with `filters` to narrow down the list of results.\n", - "default": "", - "example": "comedy drama crime Macy Buscemi", - "x-categories": ["Search"] - }, - "filters": { - "type": "string", - "description": "Filter expression to only include items that match the filter criteria in the response.\n\nYou can use these filter expressions:\n\n- **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`.\n- **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive).\n- **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value.\n- **Tag filters.** `_tags:` or just `` (case-sensitive).\n- **Boolean filters.** `: true | false`.\n\nYou can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions:\n\n- You can only combine filters of the same type with `OR`.\n **Not supported:** `facet:value OR num > 3`.\n- You can't use `NOT` with combinations of filters.\n **Not supported:** `NOT(facet:value OR facet:value)`\n- You can't combine conjunctions (`AND`) with `OR`.\n **Not supported:** `facet:value OR (facet:value AND facet:value)`\n\nUse quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes.\nIf a facet attribute is an array, the filter matches if it matches at least one element of the array.\n\nFor more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/).\n", - "example": "(category:Book OR category:Ebook) AND _tags:published", - "x-categories": ["Filtering"] - }, - "facetFilters": { - "description": "Filter the search by facet values, so that only records with the same facet values are retrieved.\n\n**Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.**\n\n- `[filter1, filter2]` is interpreted as `filter1 AND filter2`.\n- `[[filter1, filter2], filter3]` is interpreted as `filter1 OR filter2 AND filter3`.\n- `facet:-value` is interpreted as `NOT facet:value`.\n\nWhile it's best to avoid attributes that start with a `-`, you can still filter them by escaping with a backslash:\n`facet:\\-value`.\n", - "example": [["category:Book", "category:-Movie"], "author:John Doe"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/facetFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "optionalFilters": { - "description": "Filters to promote or demote records in the search results.\n\nOptional filters work like facet filters, but they don't exclude records from the search results.\nRecords that match the optional filter rank before records that don't match.\nIf you're using a negative filter `facet:-value`, matching records rank after records that don't match.\n\n- Optional filters don't work on virtual replicas.\n- Optional filters are applied _after_ sort-by attributes.\n- Optional filters are applied _before_ custom ranking attributes (in the default [ranking](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/)).\n- Optional filters don't work with numeric attributes.\n", - "example": ["category:Book", "author:John Doe"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/optionalFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "numericFilters": { - "description": "Filter by numeric facets.\n\n**Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.**\n\nYou can use numeric comparison operators: `<`, `<=`, `=`, `!=`, `>`, `>=`.\nComparisons are precise up to 3 decimals.\nYou can also provide ranges: `facet: TO `. The range includes the lower and upper boundaries.\nThe same combination rules apply as for `facetFilters`.\n", - "example": [["inStock = 1", "deliveryDate < 1441755506"], "price < 1000"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/numericFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "tagFilters": { - "description": "Filter the search by values of the special `_tags` attribute.\n\n**Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.**\n\nDifferent from regular facets, `_tags` can only be used for filtering (including or excluding records).\nYou won't get a facet count.\nThe same combination and escaping rules apply as for `facetFilters`.\n", - "example": [["Book", "Movie"], "SciFi"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/tagFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "sumOrFiltersScores": { - "type": "boolean", - "description": "Whether to sum all filter scores.\n\nIf true, all filter scores are summed.\nOtherwise, the maximum filter score is kept.\nFor more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores).\n", - "default": false, - "x-categories": ["Filtering"] - }, - "restrictSearchableAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["title", "author"], - "description": "Restricts a search to a subset of your searchable attributes.\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Filtering"] - }, - "facets": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Facets for which to retrieve facet values that match the search criteria and the number of matching facet values.\n\nTo retrieve all facets, use the wildcard character `*`.\nFor more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts).\n", - "default": [], - "example": ["*"], - "x-categories": ["Faceting"] - }, - "facetingAfterDistinct": { - "type": "boolean", - "description": "Whether faceting should be applied after deduplication with `distinct`.\n\nThis leads to accurate facet counts when using faceting in combination with `distinct`.\nIt's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting,\nas `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`.\n", - "default": false, - "x-categories": ["Faceting"] - }, - "aroundLatLng": { - "type": "string", - "description": "Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude.\n\nOnly records included within a circle around this central location are included in the results.\nThe radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings.\nThis parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`.\n", - "example": "40.71,-74.01", - "default": "", - "x-categories": ["Geo-Search"] - }, - "aroundLatLngViaIP": { - "type": "boolean", - "description": "Whether to obtain the coordinates from the request's IP address.", - "default": false, - "x-categories": ["Geo-Search"] - }, - "aroundRadiusAll": { - "title": "all", - "type": "string", - "description": "Return all records with a valid `_geoloc` attribute. Don't filter by distance.", - "enum": ["all"] - }, - "aroundRadius": { - "description": "Maximum radius for a search around a central location.\n\nThis parameter works in combination with the `aroundLatLng` and `aroundLatLngViaIP` parameters.\nBy default, the search radius is determined automatically from the density of hits around the central location.\nThe search radius is small if there are many hits close to the central coordinates.\n", - "oneOf": [ - { - "type": "integer", - "minimum": 1, - "description": "Maximum search radius around a central location in meters." - }, - { - "$ref": "#/components/schemas/aroundRadiusAll" - } - ], - "x-categories": ["Geo-Search"] - }, - "aroundPrecisionFromValue": { - "title": "range objects", - "type": "array", - "items": { - "title": "range", - "type": "object", - "description": "Range object with lower and upper values in meters to define custom ranges.", - "properties": { - "from": { - "type": "integer", - "description": "Lower boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal.", - "example": 20 - }, - "value": { - "type": "integer", - "description": "Upper boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal." - } - } - } - }, - "aroundPrecision": { - "description": "Precision of a coordinate-based search in meters to group results with similar distances.\n\nThe Geo ranking criterion considers all matches within the same range of distances to be equal.\n", - "oneOf": [ - { - "type": "integer", - "default": 10, - "description": "Distance in meters to group results by similar distances.\n\nFor example, if you set `aroundPrecision` to 100, records wihin 100 meters to the central coordinate are considered to have the same distance,\nas are records between 100 and 199 meters.\n" - }, - { - "$ref": "#/components/schemas/aroundPrecisionFromValue" - } - ], - "x-categories": ["Geo-Search"] - }, - "minimumAroundRadius": { - "type": "integer", - "description": "Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - "minimum": 1, - "x-categories": ["Geo-Search"] - }, - "insideBoundingBoxArray": { - "type": "array", - "items": { - "type": "array", - "minItems": 4, - "maxItems": 4, - "items": { - "type": "number", - "format": "double" - } - }, - "description": "Coordinates for a rectangular area in which to search.\n\nEach bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair:\n`[p1 lat, p1 long, p2 lat, p2 long]`.\nProvide multiple bounding boxes as nested arrays.\nFor more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas).\n", - "example": [ - [47.3165, 4.9665, 47.3424, 5.0201], - [40.9234, 2.1185, 38.643, 1.9916] - ], - "x-categories": ["Geo-Search"] - }, - "insideBoundingBox": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "null" - }, - { - "$ref": "#/components/schemas/insideBoundingBoxArray" - } - ] - }, - "insidePolygon": { - "type": "array", - "items": { - "type": "array", - "minItems": 6, - "maxItems": 20000, - "items": { - "type": "number", - "format": "double" - } - }, - "description": "Coordinates of a polygon in which to search.\n\nPolygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude.\nProvide multiple polygons as nested arrays.\nFor more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas).\nThis parameter is ignored if you also specify `insideBoundingBox`.\n", - "example": [ - [47.3165, 4.9665, 47.3424, 5.0201, 47.32, 4.9], - [40.9234, 2.1185, 38.643, 1.9916, 39.2587, 2.0104] - ], - "x-categories": ["Geo-Search"] - }, - "supportedLanguage": { - "type": "string", - "description": "ISO code for a supported language.", - "enum": [ - "af", - "ar", - "az", - "bg", - "bn", - "ca", - "cs", - "cy", - "da", - "de", - "el", - "en", - "eo", - "es", - "et", - "eu", - "fa", - "fi", - "fo", - "fr", - "ga", - "gl", - "he", - "hi", - "hu", - "hy", - "id", - "is", - "it", - "ja", - "ka", - "kk", - "ko", - "ku", - "ky", - "lt", - "lv", - "mi", - "mn", - "mr", - "ms", - "mt", - "nb", - "nl", - "no", - "ns", - "pl", - "ps", - "pt", - "pt-br", - "qu", - "ro", - "ru", - "sk", - "sq", - "sv", - "sw", - "ta", - "te", - "th", - "tl", - "tn", - "tr", - "tt", - "uk", - "ur", - "uz", - "zh" - ] - }, - "naturalLanguages": { - "type": "array", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - }, - "description": "ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches):\n\n- Sets `removeStopWords` and `ignorePlurals` to the list of provided languages.\n- Sets `removeWordsIfNoResults` to `allOptional`.\n- Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`.\n", - "default": [], - "x-categories": ["Languages"] - }, - "ruleContexts": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Assigns a rule context to the search query.\n\n[Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules.\n", - "default": [], - "example": ["mobile"], - "x-categories": ["Rules"] - }, - "personalizationImpact": { - "type": "integer", - "description": "Impact that Personalization should have on this search.\n\nThe higher this value is, the more Personalization determines the ranking compared to other factors.\nFor more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact).\n", - "default": 100, - "minimum": 0, - "maximum": 100, - "x-categories": ["Personalization"] - }, - "userToken": { - "type": "string", - "description": "Unique pseudonymous or anonymous user identifier.\n\nThis helps with analytics and click and conversion events.\nFor more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/).\n", - "example": "test-user-123", - "x-categories": ["Personalization"] - }, - "getRankingInfo": { - "type": "boolean", - "description": "Whether the search response should include detailed ranking information.", - "default": false, - "x-categories": ["Advanced"] - }, - "synonyms": { - "type": "boolean", - "description": "Whether to take into account an index's synonyms for this search.", - "default": true, - "x-categories": ["Advanced"] - }, - "clickAnalytics": { - "type": "boolean", - "description": "Whether to include a `queryID` attribute in the response.\n\nThe query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/).\n", - "default": false, - "x-categories": ["Analytics"] - }, - "analytics": { - "type": "boolean", - "description": "Whether this search will be included in Analytics.", - "default": true, - "x-categories": ["Analytics"] - }, - "analyticsTags": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - "default": [], - "x-categories": ["Analytics"] - }, - "percentileComputation": { - "type": "boolean", - "description": "Whether to include this search when calculating processing-time percentiles.", - "default": true, - "x-categories": ["Advanced"] - }, - "enableABTest": { - "type": "boolean", - "description": "Whether to enable A/B testing for this search.", - "default": true, - "x-categories": ["Advanced"] - }, - "baseRecommendSearchParams": { - "type": "object", - "properties": { - "similarQuery": { - "$ref": "#/components/schemas/similarQuery" - }, - "filters": { - "$ref": "#/components/schemas/filters" - }, - "facetFilters": { - "$ref": "#/components/schemas/facetFilters" - }, - "optionalFilters": { - "$ref": "#/components/schemas/optionalFilters" - }, - "numericFilters": { - "$ref": "#/components/schemas/numericFilters" - }, - "tagFilters": { - "$ref": "#/components/schemas/tagFilters" - }, - "sumOrFiltersScores": { - "$ref": "#/components/schemas/sumOrFiltersScores" - }, - "restrictSearchableAttributes": { - "$ref": "#/components/schemas/restrictSearchableAttributes" - }, - "facets": { - "$ref": "#/components/schemas/facets" - }, - "facetingAfterDistinct": { - "$ref": "#/components/schemas/facetingAfterDistinct" - }, - "aroundLatLng": { - "$ref": "#/components/schemas/aroundLatLng" - }, - "aroundLatLngViaIP": { - "$ref": "#/components/schemas/aroundLatLngViaIP" - }, - "aroundRadius": { - "$ref": "#/components/schemas/aroundRadius" - }, - "aroundPrecision": { - "$ref": "#/components/schemas/aroundPrecision" - }, - "minimumAroundRadius": { - "$ref": "#/components/schemas/minimumAroundRadius" - }, - "insideBoundingBox": { - "$ref": "#/components/schemas/insideBoundingBox" - }, - "insidePolygon": { - "$ref": "#/components/schemas/insidePolygon" - }, - "naturalLanguages": { - "$ref": "#/components/schemas/naturalLanguages" - }, - "ruleContexts": { - "$ref": "#/components/schemas/ruleContexts" - }, - "personalizationImpact": { - "$ref": "#/components/schemas/personalizationImpact" - }, - "userToken": { - "$ref": "#/components/schemas/userToken" - }, - "getRankingInfo": { - "$ref": "#/components/schemas/getRankingInfo" - }, - "synonyms": { - "$ref": "#/components/schemas/synonyms" - }, - "clickAnalytics": { - "$ref": "#/components/schemas/clickAnalytics" - }, - "analytics": { - "$ref": "#/components/schemas/analytics" - }, - "analyticsTags": { - "$ref": "#/components/schemas/analyticsTags" - }, - "percentileComputation": { - "$ref": "#/components/schemas/percentileComputation" - }, - "enableABTest": { - "$ref": "#/components/schemas/enableABTest" - } - } - }, - "query": { - "type": "string", - "description": "Search query.", - "default": "", - "x-categories": ["Search"] - }, - "searchParamsQuery": { - "type": "object", - "properties": { - "query": { - "$ref": "#/components/schemas/query" - } - } - }, - "userData": { - "example": { - "settingID": "f2a7b51e3503acc6a39b3784ffb84300", - "pluginVersion": "1.6.0" - }, - "description": "An object with custom data.\n\nYou can store up to 32kB as custom data.\n", - "default": {}, - "x-categories": ["Advanced"] - }, - "maxFacetHits": { - "type": "integer", - "description": "Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - "maximum": 100, - "default": 10, - "x-categories": ["Advanced"] - }, - "baseIndexSettings": { - "type": "object", - "properties": { - "attributesForFaceting": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "author", - "filterOnly(isbn)", - "searchable(edition)", - "afterDistinct(category)", - "afterDistinct(searchable(publisher))" - ], - "description": "Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/).\n\nFacets are attributes that let you categorize search results.\nThey can be used for filtering search results.\nBy default, no attribute is used for faceting.\nAttribute names are case-sensitive.\n\n**Modifiers**\n\n- `filterOnly(\"ATTRIBUTE\")`.\n Allows the attribute to be used as a filter but doesn't evaluate the facet values.\n\n- `searchable(\"ATTRIBUTE\")`.\n Allows searching for facet values.\n\n- `afterDistinct(\"ATTRIBUTE\")`.\n Evaluates the facet count _after_ deduplication with `distinct`.\n This ensures accurate facet counts.\n You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`.\n", - "default": [], - "x-categories": ["Faceting"] - }, - "replicas": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["virtual(prod_products_price_asc)", "dev_products_replica"], - "description": "Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/).\n\nReplicas are copies of a primary index with the same records but different settings, synonyms, or rules.\nIf you want to offer a different ranking or sorting of your search results, you'll use replica indices.\nAll index operations on a primary index are automatically forwarded to its replicas.\nTo add a replica index, you must provide the complete set of replicas to this parameter.\nIf you omit a replica from this list, the replica turns into a regular, standalone index that will no longer be synced with the primary index.\n\n**Modifier**\n\n- `virtual(\"REPLICA\")`.\n Create a virtual replica,\n Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/).\n", - "default": [], - "x-categories": ["Ranking"] - }, - "paginationLimitedTo": { - "type": "integer", - "example": 100, - "description": "Maximum number of search results that can be obtained through pagination.\n\nHigher pagination limits might slow down your search.\nFor pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed.\n", - "default": 1000, - "maximum": 20000 - }, - "unretrievableAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["total_sales"], - "description": "Attributes that can't be retrieved at query time.\n\nThis can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/),\nbut don't want to include it in the search results.\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Attributes"] - }, - "disableTypoToleranceOnWords": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["wheel", "1X2BCD"], - "description": "Creates a list of [words which require exact matches](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#turn-off-typo-tolerance-for-certain-words).\nThis also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words.\n", - "default": [], - "x-categories": ["Typos"] - }, - "attributesToTransliterate": { - "description": "Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead).\n\nTransliteration supports searching in any of the Japanese writing systems.\nTo support transliteration, you must set the indexing language to Japanese.\nAttribute names are case-sensitive.\n", - "type": "array", - "items": { - "type": "string" - }, - "example": ["name", "description"], - "x-categories": ["Languages"] - }, - "camelCaseAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["description"], - "description": "Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words.\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Languages"] - }, - "decompoundedAttributes": { - "type": "object", - "example": { - "de": ["name"] - }, - "description": "Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding).\nAttribute names are case-sensitive.\n\nCompound words are formed by combining two or more individual words,\nand are particularly prevalent in Germanic languages—for example, \"firefighter\".\nWith decompounding, the individual components are indexed separately.\n\nYou can specify different lists for different languages.\nDecompounding is supported for these languages:\nDutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`).\nDecompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark).\nFor example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308).\n", - "default": {}, - "x-categories": ["Languages"] - }, - "indexLanguages": { - "type": "array", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - }, - "example": ["ja"], - "description": "Languages for language-specific processing steps, such as word detection and dictionary settings.\n\n**You should always specify an indexing language.**\nIf you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/),\nor the languages you specified with the `ignorePlurals` or `removeStopWords` parameters.\nThis can lead to unexpected search results.\nFor more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/).\n", - "default": [], - "x-categories": ["Languages"] - }, - "disablePrefixOnAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["sku"], - "description": "Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search).\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Query strategy"] - }, - "allowCompressionOfIntegerArray": { - "type": "boolean", - "description": "Whether arrays with exclusively non-negative integers should be compressed for better performance.\nIf true, the compressed arrays may be reordered.\n", - "default": false, - "x-categories": ["Performance"] - }, - "numericAttributesForFiltering": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters).\nAttribute names are case-sensitive.\n\nBy default, all numeric attributes are available as numerical filters.\nFor faster indexing, reduce the number of numeric attributes.\n\nTo turn off filtering for all numeric attributes, specify an attribute that doesn't exist in your index, such as `NO_NUMERIC_FILTERING`.\n\n**Modifier**\n\n- `equalOnly(\"ATTRIBUTE\")`.\n Support only filtering based on equality comparisons `=` and `!=`.\n", - "example": ["equalOnly(quantity)", "popularity"], - "default": [], - "x-categories": ["Performance"] - }, - "separatorsToIndex": { - "type": "string", - "example": "+#", - "description": "Control which non-alphanumeric characters are indexed.\n\nBy default, Algolia ignores [non-alphanumeric characters](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/#handling-non-alphanumeric-characters) like hyphen (`-`), plus (`+`), and parentheses (`(`,`)`).\nTo include such characters, define them with `separatorsToIndex`.\n\nSeparators are all non-letter characters except spaces and currency characters, such as $€£¥.\n\nWith `separatorsToIndex`, Algolia treats separator characters as separate words.\nFor example, in a search for \"Disney+\", Algolia considers \"Disney\" and \"+\" as two separate words.\n", - "default": "", - "x-categories": ["Typos"] - }, - "searchableAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["title,alternative_title", "author", "unordered(text)", "emails.personal"], - "description": "Attributes used for searching. Attribute names are case-sensitive.\n\nBy default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off.\nWith a non-empty list, Algolia only returns results with matches in the selected attributes.\nIn addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first.\nTo make matches in two attributes rank equally, include them in a comma-separated string, such as `\"title,alternate_title\"`.\nAttributes with the same priority are always unordered.\n\nFor more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/).\n\n**Modifier**\n\n- `unordered(\"ATTRIBUTE\")`.\n Ignore the position of a match within the attribute.\n\nWithout a modifier, matches at the beginning of an attribute rank higher than matches at the end.\n", - "default": [], - "x-categories": ["Attributes"] - }, - "userData": { - "$ref": "#/components/schemas/userData" - }, - "customNormalization": { - "description": "Characters and their normalized replacements.\nThis overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/).\n", - "type": "object", - "example": { - "default": { - "ä": "ae", - "ü": "ue" - } - }, - "additionalProperties": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "x-categories": ["Languages"] - }, - "attributeForDistinct": { - "description": "Attribute that should be used to establish groups of results.\nAttribute names are case-sensitive.\n\nAll records with the same value for this attribute are considered a group.\nYou can combine `attributeForDistinct` with the `distinct` search parameter to control\nhow many items per group are included in the search results.\n\nIf you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting.\nThis applies faceting _after_ deduplication, which will result in accurate facet counts.\n", - "example": "url", - "type": "string" - }, - "maxFacetHits": { - "$ref": "#/components/schemas/maxFacetHits" - }, - "keepDiacriticsOnCharacters": { - "type": "string", - "example": "øé", - "description": "Characters for which diacritics should be preserved.\n\nBy default, Algolia removes diacritics from letters.\nFor example, `é` becomes `e`. If this causes issues in your search,\nyou can specify characters that should keep their diacritics.\n", - "default": "", - "x-categories": ["Languages"] - }, - "customRanking": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["desc(popularity)", "asc(price)"], - "description": "Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/).\nAttribute names are case-sensitive.\n\nThe custom ranking attributes decide which items are shown first if the other ranking criteria are equal.\n\nRecords with missing values for your selected custom ranking attributes are always sorted last.\nBoolean attributes are sorted based on their alphabetical order.\n\n**Modifiers**\n\n- `asc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in ascending order.\n\n- `desc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in descending order.\n\nIf you use two or more custom ranking attributes,\n[reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes,\nor the other attributes will never be applied.\n", - "default": [], - "x-categories": ["Ranking"] - } - } - }, - "attributesToRetrieve": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["author", "title", "content"], - "description": "Attributes to include in the API response.\n\nTo reduce the size of your response, you can retrieve only some of the attributes.\nAttribute names are case-sensitive.\n\n- `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings.\n- To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`.\n- The `objectID` attribute is always included.\n", - "default": ["*"], - "x-categories": ["Attributes"] - }, - "ranking": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Determines the order in which Algolia returns your results.\n\nBy default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/).\nThe tie-breaking algorithm sequentially applies each criterion in the order they're specified.\nIf you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/),\nyou put the sorting attribute at the top of the list.\n\n**Modifiers**\n\n- `asc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in ascending order.\n- `desc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in descending order.\n\nBefore you modify the default setting,\nyou should test your changes in the dashboard,\nand by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/).\n", - "default": ["typo", "geo", "words", "filters", "proximity", "attribute", "exact", "custom"], - "x-categories": ["Ranking"] - }, - "relevancyStrictness": { - "type": "integer", - "example": 90, - "description": "Relevancy threshold below which less relevant results aren't included in the results.\n\nYou can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas).\nUse this setting to strike a balance between the relevance and number of returned results.\n", - "default": 100, - "x-categories": ["Ranking"] - }, - "attributesToHighlight": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["author", "title", "conten", "content"], - "description": "Attributes to highlight.\n\nBy default, all searchable attributes are highlighted.\nUse `*` to highlight all attributes or use an empty array `[]` to turn off highlighting.\nAttribute names are case-sensitive.\n\nWith highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`.\nYou can use this to visually highlight matching parts of a search query in your UI.\n\nFor more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/).\n", - "x-categories": ["Highlighting and Snippeting"] - }, - "attributesToSnippet": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["content:80", "description"], - "description": "Attributes for which to enable snippets.\nAttribute names are case-sensitive.\n\nSnippets provide additional context to matched words.\nIf you enable snippets, they include 10 words, including the matched word.\nThe matched word will also be wrapped by HTML tags for highlighting.\nYou can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`,\nwhere `NUMBER` is the number of words to be extracted.\n", - "default": [], - "x-categories": ["Highlighting and Snippeting"] - }, - "highlightPreTag": { - "type": "string", - "description": "HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - "default": "", - "x-categories": ["Highlighting and Snippeting"] - }, - "highlightPostTag": { - "type": "string", - "description": "HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - "default": "", - "x-categories": ["Highlighting and Snippeting"] - }, - "snippetEllipsisText": { - "type": "string", - "description": "String used as an ellipsis indicator when a snippet is truncated.", - "default": "…", - "x-categories": ["Highlighting and Snippeting"] - }, - "restrictHighlightAndSnippetArrays": { - "type": "boolean", - "description": "Whether to restrict highlighting and snippeting to items that at least partially matched the search query.\nBy default, all items are highlighted and snippeted.\n", - "default": false, - "x-categories": ["Highlighting and Snippeting"] - }, - "minWordSizefor1Typo": { - "type": "integer", - "description": "Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - "default": 4, - "x-categories": ["Typos"] - }, - "minWordSizefor2Typos": { - "type": "integer", - "description": "Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - "default": 8, - "x-categories": ["Typos"] - }, - "typoToleranceEnum": { - "type": "string", - "title": "typo tolerance", - "description": "- `min`. Return matches with the lowest number of typos.\n For example, if you have matches without typos, only include those.\n But if there are no matches without typos (with 1 typo), include matches with 1 typo (2 typos).\n- `strict`. Return matches with the two lowest numbers of typos.\n With `strict`, the Typo ranking criterion is applied first in the `ranking` setting.\n", - "enum": ["min", "strict"] - }, - "typoTolerance": { - "description": "Whether [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/) is enabled and how it is applied.\n\nIf typo tolerance is true, `min`, or `strict`, [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) are also active.\n", - "oneOf": [ - { - "type": "boolean", - "default": true, - "description": "Whether typo tolerance is active. If true, matches with typos are included in the search results and rank after exact matches." - }, - { - "$ref": "#/components/schemas/typoToleranceEnum" - } - ], - "x-categories": ["Typos"] - }, - "allowTyposOnNumericTokens": { - "type": "boolean", - "description": "Whether to allow typos on numbers in the search query.\n\nTurn off this setting to reduce the number of irrelevant matches\nwhen searching in large sets of similar numbers.\n", - "default": true, - "x-categories": ["Typos"] - }, - "disableTypoToleranceOnAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["sku"], - "description": "Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/).\nAttribute names are case-sensitive.\n\nReturning only exact matches can help when:\n\n- [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/).\n- Reducing the number of matches when you have too many.\n This can happen with attributes that are long blocks of text, such as product descriptions.\n\nConsider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos.\n", - "default": [], - "x-categories": ["Typos"] - }, - "booleanString": { - "type": "string", - "enum": ["true", "false"] - }, - "ignorePlurals": { - "description": "Treat singular, plurals, and other forms of declensions as equivalent.\nYou should only use this feature for the languages used in your index.\n", - "example": ["ca", "es"], - "oneOf": [ - { - "type": "array", - "description": "ISO code for languages for which this feature should be active.\nThis overrides languages you set with `queryLanguages`.\n", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - } - }, - { - "$ref": "#/components/schemas/booleanString" - }, - { - "type": "boolean", - "description": "If true, `ignorePlurals` is active for all languages included in `queryLanguages`, or for all supported languages, if `queryLanguges` is empty.\nIf false, singulars, plurals, and other declensions won't be considered equivalent.\n", - "default": false - } - ], - "x-categories": ["Languages"] - }, - "removeStopWords": { - "description": "Removes stop words from the search query.\n\nStop words are common words like articles, conjunctions, prepositions, or pronouns that have little or no meaning on their own.\nIn English, \"the\", \"a\", or \"and\" are stop words.\n\nYou should only use this feature for the languages used in your index.\n", - "example": ["ca", "es"], - "oneOf": [ - { - "type": "array", - "description": "ISO code for languages for which stop words should be removed. This overrides languages you set in `queryLanguges`.", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - } - }, - { - "type": "boolean", - "default": false, - "description": "If true, stop words are removed for all languages you included in `queryLanguages`, or for all supported languages, if `queryLanguages` is empty.\nIf false, stop words are not removed.\n" - } - ], - "x-categories": ["Languages"] - }, - "queryLanguages": { - "type": "array", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - }, - "example": ["es"], - "description": "Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries.\n\nThis setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings.\nThis setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages.\nTo support this, you must place the CJK language **first**.\n\n**You should always specify a query language.**\nIf you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/),\nor the languages you specified with the `ignorePlurals` or `removeStopWords` parameters.\nThis can lead to unexpected search results.\nFor more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/).\n", - "default": [], - "x-categories": ["Languages"] - }, - "decompoundQuery": { - "type": "boolean", - "description": "Whether to split compound words in the query into their building blocks.\n\nFor more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words).\nWord segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian.\nDecompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark).\nFor example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308).\n", - "default": true, - "x-categories": ["Languages"] - }, - "enableRules": { - "type": "boolean", - "description": "Whether to enable rules.", - "default": true, - "x-categories": ["Rules"] - }, - "enablePersonalization": { - "type": "boolean", - "description": "Whether to enable Personalization.", - "default": false, - "x-categories": ["Personalization"] - }, - "queryType": { - "type": "string", - "enum": ["prefixLast", "prefixAll", "prefixNone"], - "description": "Determines if and how query words are interpreted as prefixes.\n\nBy default, only the last query word is treated as a prefix (`prefixLast`).\nTo turn off prefix search, use `prefixNone`.\nAvoid `prefixAll`, which treats all query words as prefixes.\nThis might lead to counterintuitive results and makes your search slower.\n\nFor more information, see [Prefix searching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/prefix-searching/).\n", - "default": "prefixLast", - "x-categories": ["Query strategy"] - }, - "removeWordsIfNoResults": { - "type": "string", - "enum": ["none", "lastWords", "firstWords", "allOptional"], - "example": "firstWords", - "description": "Strategy for removing words from the query when it doesn't return any results.\nThis helps to avoid returning empty search results.\n\n- `none`.\n No words are removed when a query doesn't return results.\n\n- `lastWords`.\n Treat the last (then second to last, then third to last) word as optional,\n until there are results or at most 5 words have been removed.\n\n- `firstWords`.\n Treat the first (then second, then third) word as optional,\n until there are results or at most 5 words have been removed.\n\n- `allOptional`.\n Treat all words as optional.\n\nFor more information, see [Remove words to improve results](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/in-depth/why-use-remove-words-if-no-results/).\n", - "default": "none", - "x-categories": ["Query strategy"] - }, - "advancedSyntax": { - "type": "boolean", - "description": "Whether to support phrase matching and excluding words from search queries.\n\nUse the `advancedSyntaxFeatures` parameter to control which feature is supported.\n", - "default": false, - "x-categories": ["Query strategy"] - }, - "optionalWordsArray": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["blue", "iphone case"], - "description": "List of [optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words).", - "default": [], - "x-categories": ["Query strategy"] - }, - "optionalWords": { - "description": "Words that should be considered optional when found in the query.\n\nBy default, records must match all words in the search query to be included in the search results.\nAdding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words.\nFor example, if the search query is \"action video\" and \"video\" is an optional word,\nthe search engine runs two queries. One for \"action video\" and one for \"action\".\nRecords that match all words are ranked higher.\n\nFor a search query with 4 or more words **and** all its words are optional,\nthe number of matched words required for a record to be included in the search results increases for every 1,000 records:\n\n- If `optionalWords` has less than 10 words, the required number of matched words increases by 1:\n results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words.\n- If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words divided by 5 (rounded down).\n For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words.\n\nFor more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words).\n", - "oneOf": [ - { - "type": "string" - }, - { - "type": "null" - }, - { - "$ref": "#/components/schemas/optionalWordsArray" - } - ] - }, - "disableExactOnAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["description"], - "description": "Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes).\nAttribute names are case-sensitive.\n\nThis can be useful for attributes with long values, where the likelihood of an exact match is high,\nsuch as product descriptions.\nTurning off the Exact ranking criterion for these attributes favors exact matching on other attributes.\nThis reduces the impact of individual attributes with a lot of content on ranking.\n", - "default": [], - "x-categories": ["Query strategy"] - }, - "exactOnSingleWordQuery": { - "type": "string", - "enum": ["attribute", "none", "word"], - "description": "Determines how the [Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes) is computed when the search query has only one word.\n\n- `attribute`.\n The Exact ranking criterion is 1 if the query word and attribute value are the same.\n For example, a search for \"road\" will match the value \"road\", but not \"road trip\".\n\n- `none`.\n The Exact ranking criterion is ignored on single-word searches.\n\n- `word`.\n The Exact ranking criterion is 1 if the query word is found in the attribute value.\n The query word must have at least 3 characters and must not be a stop word.\n Only exact matches will be highlighted,\n partial and prefix matches won't.\n", - "default": "attribute", - "x-categories": ["Query strategy"] - }, - "alternativesAsExact": { - "type": "string", - "enum": ["ignorePlurals", "singleWordSynonym", "multiWordsSynonym", "ignoreConjugations"], - "x-categories": ["Query strategy"] - }, - "properties-alternativesAsExact": { - "type": "array", - "items": { - "$ref": "#/components/schemas/alternativesAsExact" - }, - "description": "Determine which plurals and synonyms should be considered an exact matches.\n\nBy default, Algolia treats singular and plural forms of a word, and single-word synonyms, as [exact](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#exact) matches when searching.\nFor example:\n\n- \"swimsuit\" and \"swimsuits\" are treated the same\n- \"swimsuit\" and \"swimwear\" are treated the same (if they are [synonyms](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#regular-synonyms)).\n\n- `ignorePlurals`.\n Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches.\n\n- `singleWordSynonym`.\n Single-word synonyms, such as \"NY\" = \"NYC\", are considered exact matches.\n\n- `multiWordsSynonym`.\n Multi-word synonyms, such as \"NY\" = \"New York\", are considered exact matches.\n", - "default": ["ignorePlurals", "singleWordSynonym"], - "x-categories": ["Query strategy"] - }, - "advancedSyntaxFeatures": { - "type": "string", - "enum": ["exactPhrase", "excludeWords"], - "x-categories": ["Query strategy"] - }, - "properties-advancedSyntaxFeatures": { - "type": "array", - "items": { - "$ref": "#/components/schemas/advancedSyntaxFeatures" - }, - "description": "Advanced search syntax features you want to support.\n\n- `exactPhrase`.\n Phrases in quotes must match exactly.\n For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\".\n\n- `excludeWords`.\n Query words prefixed with a `-` must not occur in a record.\n For example, `search -engine` matches records that contain \"search\" but not \"engine\".\n\nThis setting only has an effect if `advancedSyntax` is true.\n", - "default": ["exactPhrase", "excludeWords"], - "x-categories": ["Query strategy"] - }, - "distinct": { - "description": "Determines how many records of a group are included in the search results.\n\nRecords with the same value for the `attributeForDistinct` attribute are considered a group.\nThe `distinct` setting controls how many members of the group are returned.\nThis is useful for [deduplication and grouping](https://www.algolia.com/doc/guides/managing-results/refine-results/grouping/#introducing-algolias-distinct-feature).\n\nThe `distinct` setting is ignored if `attributeForDistinct` is not set.\n", - "example": 1, - "oneOf": [ - { - "type": "boolean", - "description": "Whether deduplication is turned on. If true, only one member of a group is shown in the search results." - }, - { - "type": "integer", - "description": "Number of members of a group of records to include in the search results.\n\n- Don't use `distinct > 1` for records that might be [promoted by rules](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/promote-hits/).\n The number of hits won't be correct and faceting won't work as expected.\n- With `distinct > 1`, the `hitsPerPage` parameter controls the number of returned groups.\n For example, with `hitsPerPage: 10` and `distinct: 2`, up to 20 records are returned.\n Likewise, the `nbHits` response attribute contains the number of returned groups.\n", - "minimum": 0, - "maximum": 4, - "default": 0 - } - ], - "x-categories": ["Advanced"] - }, - "replaceSynonymsInHighlight": { - "type": "boolean", - "description": "Whether to replace a highlighted word with the matched synonym.\n\nBy default, the original words are highlighted even if a synonym matches.\nFor example, with `home` as a synonym for `house` and a search for `home`,\nrecords matching either \"home\" or \"house\" are included in the search results,\nand either \"home\" or \"house\" are highlighted.\n\nWith `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records,\nbut all occurrences of \"house\" are replaced by \"home\" in the highlighted response.\n", - "default": false, - "x-categories": ["Highlighting and Snippeting"] - }, - "minProximity": { - "type": "integer", - "minimum": 1, - "maximum": 7, - "description": "Minimum proximity score for two matching words.\n\nThis adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity)\nby equally scoring matches that are farther apart.\n\nFor example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score.\n", - "default": 1, - "x-categories": ["Advanced"] - }, - "responseFields": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Properties to include in the API response of search and browse requests.\n\nBy default, all response properties are included.\nTo reduce the response size, you can select which properties should be included.\n\nAn empty list may lead to an empty API response (except properties you can't exclude).\n\nYou can't exclude these properties:\n`message`, `warning`, `cursor`, `abTestVariantID`,\nor any property added by setting `getRankingInfo` to true.\n\nYour search depends on the `hits` field. If you omit this field, searches won't return any results.\nYour UI might also depend on other properties, for example, for pagination.\nBefore restricting the response size, check the impact on your search experience.\n", - "default": ["*"], - "x-categories": ["Advanced"] - }, - "maxValuesPerFacet": { - "type": "integer", - "description": "Maximum number of facet values to return for each facet.", - "default": 100, - "maximum": 1000, - "x-categories": ["Faceting"] - }, - "sortFacetValuesBy": { - "type": "string", - "description": "Order in which to retrieve facet values.\n\n- `count`.\n Facet values are retrieved by decreasing count.\n The count is the number of matching records containing this facet value.\n\n- `alpha`.\n Retrieve facet values alphabetically.\n\nThis setting doesn't influence how facet values are displayed in your UI (see `renderingContent`).\nFor more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/).\n", - "default": "count", - "x-categories": ["Faceting"] - }, - "attributeCriteriaComputedByMinProximity": { - "type": "boolean", - "description": "Whether the best matching attribute should be determined by minimum proximity.\n\nThis setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting.\nIf true, the best matching attribute is selected based on the minimum proximity of multiple matches.\nOtherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting.\n", - "default": false, - "x-categories": ["Advanced"] - }, - "order": { - "description": "Explicit order of facets or facet values.\n\nThis setting lets you always show specific facets or facet values at the top of the list.\n", - "type": "array", - "items": { - "type": "string" - } - }, - "IndexSettings_facets": { - "description": "Order of facet names.", - "type": "object", - "additionalProperties": false, - "properties": { - "order": { - "$ref": "#/components/schemas/order" - } - } - }, - "sortRemainingBy": { - "description": "Order of facet values that aren't explicitly positioned with the `order` setting.\n\n- `count`.\n Order remaining facet values by decreasing count.\n The count is the number of matching records containing this facet value.\n\n- `alpha`.\n Sort facet values alphabetically.\n\n- `hidden`.\n Don't show facet values that aren't explicitly positioned.\n", - "type": "string", - "enum": ["count", "alpha", "hidden"] - }, - "hide": { - "description": "Hide facet values.", - "type": "array", - "items": { - "type": "string" - } - }, - "value": { - "type": "object", - "additionalProperties": false, - "properties": { - "order": { - "$ref": "#/components/schemas/order" - }, - "sortRemainingBy": { - "$ref": "#/components/schemas/sortRemainingBy" - }, - "hide": { - "$ref": "#/components/schemas/hide" - } - } - }, - "values": { - "description": "Order of facet values. One object for each facet.", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "facet", - "$ref": "#/components/schemas/value" - } - }, - "facetOrdering": { - "description": "Order of facet names and facet values in your UI.", - "type": "object", - "additionalProperties": false, - "properties": { - "facets": { - "$ref": "#/components/schemas/IndexSettings_facets" - }, - "values": { - "$ref": "#/components/schemas/values" - } - } - }, - "redirectURL": { - "description": "The redirect rule container.", - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string" - } - } - }, - "bannerImageUrl": { - "description": "URL for an image to show inside a banner.", - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string" - } - } - }, - "bannerImage": { - "description": "Image to show inside a banner.", - "type": "object", - "additionalProperties": false, - "properties": { - "urls": { - "type": "array", - "items": { - "$ref": "#/components/schemas/bannerImageUrl" - } - }, - "title": { - "type": "string" - } - } - }, - "bannerLink": { - "description": "Link for a banner defined in the Merchandising Studio.", - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string" - } - } - }, - "banner": { - "description": "Banner with image and link to redirect users.", - "type": "object", - "additionalProperties": false, - "properties": { - "image": { - "$ref": "#/components/schemas/bannerImage" - }, - "link": { - "$ref": "#/components/schemas/bannerLink" - } - } - }, - "banners": { - "description": "Banners defined in the Merchandising Studio for a given search.", - "type": "array", - "items": { - "$ref": "#/components/schemas/banner" - } - }, - "widgets": { - "description": "Widgets returned from any rules that are applied to the current search.", - "type": "object", - "additionalProperties": false, - "properties": { - "banners": { - "$ref": "#/components/schemas/banners" - } - } - }, - "renderingContent": { - "description": "Extra data that can be used in the search UI.\n\nYou can use this to control aspects of your search UI, such as the order of facet names and values\nwithout changing your frontend code.\n", - "type": "object", - "additionalProperties": false, - "properties": { - "facetOrdering": { - "$ref": "#/components/schemas/facetOrdering" - }, - "redirect": { - "$ref": "#/components/schemas/redirectURL" - }, - "widgets": { - "$ref": "#/components/schemas/widgets" - } - }, - "x-categories": ["Advanced"] - }, - "enableReRanking": { - "type": "boolean", - "description": "Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/).\n\nThis setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard.\n", - "default": true, - "x-categories": ["Filtering"] - }, - "reRankingApplyFilter": { - "description": "Restrict [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/) to records that match these filters.\n", - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/reRankingApplyFilter" - } - }, - { - "type": "string", - "x-categories": ["Filtering"] - } - ] - }, - "properties-reRankingApplyFilter": { - "oneOf": [ - { - "$ref": "#/components/schemas/reRankingApplyFilter" - }, - { - "type": "null" - } - ] - }, - "baseRecommendIndexSettings": { - "type": "object", - "properties": { - "attributesToRetrieve": { - "$ref": "#/components/schemas/attributesToRetrieve" - }, - "ranking": { - "$ref": "#/components/schemas/ranking" - }, - "relevancyStrictness": { - "$ref": "#/components/schemas/relevancyStrictness" - }, - "attributesToHighlight": { - "$ref": "#/components/schemas/attributesToHighlight" - }, - "attributesToSnippet": { - "$ref": "#/components/schemas/attributesToSnippet" - }, - "highlightPreTag": { - "$ref": "#/components/schemas/highlightPreTag" - }, - "highlightPostTag": { - "$ref": "#/components/schemas/highlightPostTag" - }, - "snippetEllipsisText": { - "$ref": "#/components/schemas/snippetEllipsisText" - }, - "restrictHighlightAndSnippetArrays": { - "$ref": "#/components/schemas/restrictHighlightAndSnippetArrays" - }, - "minWordSizefor1Typo": { - "$ref": "#/components/schemas/minWordSizefor1Typo" - }, - "minWordSizefor2Typos": { - "$ref": "#/components/schemas/minWordSizefor2Typos" - }, - "typoTolerance": { - "$ref": "#/components/schemas/typoTolerance" - }, - "allowTyposOnNumericTokens": { - "$ref": "#/components/schemas/allowTyposOnNumericTokens" - }, - "disableTypoToleranceOnAttributes": { - "$ref": "#/components/schemas/disableTypoToleranceOnAttributes" - }, - "ignorePlurals": { - "$ref": "#/components/schemas/ignorePlurals" - }, - "removeStopWords": { - "$ref": "#/components/schemas/removeStopWords" - }, - "queryLanguages": { - "$ref": "#/components/schemas/queryLanguages" - }, - "decompoundQuery": { - "$ref": "#/components/schemas/decompoundQuery" - }, - "enableRules": { - "$ref": "#/components/schemas/enableRules" - }, - "enablePersonalization": { - "$ref": "#/components/schemas/enablePersonalization" - }, - "queryType": { - "$ref": "#/components/schemas/queryType" - }, - "removeWordsIfNoResults": { - "$ref": "#/components/schemas/removeWordsIfNoResults" - }, - "advancedSyntax": { - "$ref": "#/components/schemas/advancedSyntax" - }, - "optionalWords": { - "$ref": "#/components/schemas/optionalWords" - }, - "disableExactOnAttributes": { - "$ref": "#/components/schemas/disableExactOnAttributes" - }, - "exactOnSingleWordQuery": { - "$ref": "#/components/schemas/exactOnSingleWordQuery" - }, - "alternativesAsExact": { - "$ref": "#/components/schemas/properties-alternativesAsExact" - }, - "advancedSyntaxFeatures": { - "$ref": "#/components/schemas/properties-advancedSyntaxFeatures" - }, - "distinct": { - "$ref": "#/components/schemas/distinct" - }, - "replaceSynonymsInHighlight": { - "$ref": "#/components/schemas/replaceSynonymsInHighlight" - }, - "minProximity": { - "$ref": "#/components/schemas/minProximity" - }, - "responseFields": { - "$ref": "#/components/schemas/responseFields" - }, - "maxValuesPerFacet": { - "$ref": "#/components/schemas/maxValuesPerFacet" - }, - "sortFacetValuesBy": { - "$ref": "#/components/schemas/sortFacetValuesBy" - }, - "attributeCriteriaComputedByMinProximity": { - "$ref": "#/components/schemas/attributeCriteriaComputedByMinProximity" - }, - "renderingContent": { - "$ref": "#/components/schemas/renderingContent" - }, - "enableReRanking": { - "$ref": "#/components/schemas/enableReRanking" - }, - "reRankingApplyFilter": { - "$ref": "#/components/schemas/properties-reRankingApplyFilter" - } - } - }, - "recommendIndexSettings": { - "description": "Index settings.", - "allOf": [ - { - "$ref": "#/components/schemas/baseIndexSettings" - }, - { - "$ref": "#/components/schemas/baseRecommendIndexSettings" - } - ] - }, - "recommendSearchParams": { - "title": "Search parameters as object", - "description": "Search parameters for filtering the recommendations.", - "allOf": [ - { - "$ref": "#/components/schemas/baseRecommendSearchParams" - }, - { - "$ref": "#/components/schemas/searchParamsQuery" - }, - { - "$ref": "#/components/schemas/recommendIndexSettings" - } - ] - }, - "baseRecommendRequest": { - "type": "object", - "properties": { - "indexName": { - "$ref": "#/components/schemas/indexName" - }, - "threshold": { - "type": "number", - "format": "double", - "minimum": 0, - "maximum": 100, - "description": "Minimum score a recommendation must have to be included in the response." - }, - "maxRecommendations": { - "type": "integer", - "minimum": 1, - "maximum": 30, - "default": 30, - "description": "Maximum number of recommendations to retrieve.\nBy default, all recommendations are returned and no fallback request is made.\nDepending on the available recommendations and the other request parameters,\nthe actual number of recommendations may be lower than this value.\n" - }, - "queryParameters": { - "$ref": "#/components/schemas/recommendSearchParams" - } - }, - "required": ["indexName", "threshold"] - }, - "fbtModel": { - "type": "string", - "description": "Frequently bought together model.\n\nThis model recommends items that have been purchased within 1 day with the item with the ID `objectID`.\n", - "enum": ["bought-together"] - }, - "objectID": { - "type": "string", - "description": "Unique record identifier.", - "example": "test-record-123" - }, - "frequentlyBoughtTogether": { - "type": "object", - "properties": { - "model": { - "$ref": "#/components/schemas/fbtModel" - }, - "objectID": { - "$ref": "#/components/schemas/objectID" - } - }, - "required": ["model", "objectID"] - }, - "boughtTogetherQuery": { - "title": "Frequently bought together", - "allOf": [ - { - "$ref": "#/components/schemas/baseRecommendRequest" - }, - { - "$ref": "#/components/schemas/frequentlyBoughtTogether" - } - ], - "unevaluatedProperties": false - }, - "relatedModel": { - "type": "string", - "description": "Related products or similar content model.\n\nThis model recommends items that are similar to the item with the ID `objectID`.\nSimilarity is determined from the user interactions and attributes.\n", - "enum": ["related-products"] - }, - "fallbackParams": { - "title": "fallbackParameters", - "allOf": [ - { - "$ref": "#/components/schemas/recommendSearchParams" - }, - { - "type": "object", - "description": "Search parameters to use for a fallback request if there aren't enough recommendations." - } - ], - "unevaluatedProperties": false - }, - "relatedProducts": { - "type": "object", - "properties": { - "model": { - "$ref": "#/components/schemas/relatedModel" - }, - "objectID": { - "$ref": "#/components/schemas/objectID" - }, - "fallbackParameters": { - "$ref": "#/components/schemas/fallbackParams" - } - }, - "required": ["model", "objectID"] - }, - "relatedQuery": { - "title": "Related products", - "allOf": [ - { - "$ref": "#/components/schemas/baseRecommendRequest" - }, - { - "$ref": "#/components/schemas/relatedProducts" - } - ], - "unevaluatedProperties": false - }, - "facetName": { - "type": "string", - "description": "Facet attribute. To be used in combination with `facetValue`.\nIf specified, only recommendations matching the facet filter will be returned.\n" - }, - "facetValue": { - "type": "string", - "description": "Facet value. To be used in combination with `facetName`.\nIf specified, only recommendations matching the facet filter will be returned.\n" - }, - "trendingItemsModel": { - "description": "Trending items model.\n\nTrending items are determined from the number of conversion events collected on them.\n", - "type": "string", - "enum": ["trending-items"] - }, - "trendingItems": { - "type": "object", - "properties": { - "facetName": { - "$ref": "#/components/schemas/facetName" - }, - "facetValue": { - "$ref": "#/components/schemas/facetValue" - }, - "model": { - "$ref": "#/components/schemas/trendingItemsModel" - }, - "fallbackParameters": { - "$ref": "#/components/schemas/fallbackParams" - } - }, - "required": ["model"] - }, - "trendingItemsQuery": { - "title": "Trending items", - "allOf": [ - { - "$ref": "#/components/schemas/baseRecommendRequest" - }, - { - "$ref": "#/components/schemas/trendingItems" - } - ], - "unevaluatedProperties": false - }, - "trendingFacetsModel": { - "type": "string", - "description": "Trending facet values model.\n\nThis model recommends trending facet values for the specified facet attribute.\n", - "enum": ["trending-facets"] - }, - "trendingFacets": { - "type": "object", - "properties": { - "facetName": { - "type": "string", - "description": "Facet attribute for which to retrieve trending facet values." - }, - "model": { - "$ref": "#/components/schemas/trendingFacetsModel" - }, - "fallbackParameters": { - "$ref": "#/components/schemas/fallbackParams" - } - }, - "required": ["facetName", "model"] - }, - "trendingFacetsQuery": { - "title": "Trending facet values", - "allOf": [ - { - "$ref": "#/components/schemas/baseRecommendRequest" - }, - { - "$ref": "#/components/schemas/trendingFacets" - } - ], - "unevaluatedProperties": false - }, - "lookingSimilarModel": { - "type": "string", - "description": "Looking similar model.\n\nThis model recommends items that look similar to the item with the ID `objectID` based on image attributes in your index.\n", - "enum": ["looking-similar"] - }, - "lookingSimilar": { - "type": "object", - "properties": { - "model": { - "$ref": "#/components/schemas/lookingSimilarModel" - }, - "objectID": { - "$ref": "#/components/schemas/objectID" - }, - "fallbackParameters": { - "$ref": "#/components/schemas/fallbackParams" - } - }, - "required": ["model", "objectID"] - }, - "lookingSimilarQuery": { - "title": "Looking similar", - "allOf": [ - { - "$ref": "#/components/schemas/baseRecommendRequest" - }, - { - "$ref": "#/components/schemas/lookingSimilar" - } - ], - "unevaluatedProperties": false - }, - "recommendationsRequest": { - "oneOf": [ - { - "$ref": "#/components/schemas/boughtTogetherQuery" - }, - { - "$ref": "#/components/schemas/relatedQuery" - }, - { - "$ref": "#/components/schemas/trendingItemsQuery" - }, - { - "$ref": "#/components/schemas/trendingFacetsQuery" - }, - { - "$ref": "#/components/schemas/lookingSimilarQuery" - } - ] - }, - "processingTimeMS": { - "type": "integer", - "description": "Time the server took to process the request, in milliseconds.", - "example": 20 - }, - "RedirectRuleIndexMetadata": { - "type": "object", - "properties": { - "source": { - "type": "string", - "description": "Source index for the redirect rule." - }, - "dest": { - "type": "string", - "description": "Destination index for the redirect rule." - }, - "reason": { - "type": "string", - "description": "Reason for the redirect rule." - }, - "succeed": { - "type": "boolean", - "description": "Redirect rule status." - }, - "data": { - "title": "redirectRuleIndexData", - "type": "object", - "description": "Redirect rule data.", - "required": ["ruleObjectID"], - "properties": { - "ruleObjectID": { - "type": "string" - } - } - } - }, - "required": ["data", "succeed", "reason", "dest", "source"] - }, - "baseSearchResponse": { - "type": "object", - "required": ["processingTimeMS"], - "properties": { - "abTestID": { - "type": "integer", - "description": "A/B test ID. This is only included in the response for indices that are part of an A/B test." - }, - "abTestVariantID": { - "type": "integer", - "minimum": 1, - "description": "Variant ID. This is only included in the response for indices that are part of an A/B test." - }, - "aroundLatLng": { - "type": "string", - "description": "Computed geographical location.", - "example": "40.71,-74.01", - "pattern": "^(-?\\d+(\\.\\d+)?),\\s*(-?\\d+(\\.\\d+)?)$" - }, - "automaticRadius": { - "type": "string", - "description": "Distance from a central coordinate provided by `aroundLatLng`." - }, - "exhaustive": { - "title": "exhaustive", - "type": "object", - "description": "Whether certain properties of the search response are calculated exhaustive (exact) or approximated.", - "properties": { - "facetsCount": { - "type": "boolean", - "title": "facetsCount", - "description": "Whether the facet count is exhaustive (`true`) or approximate (`false`). See the [related discussion](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-)." - }, - "facetValues": { - "type": "boolean", - "title": "facetValues", - "description": "The value is `false` if not all facet values are retrieved." - }, - "nbHits": { - "type": "boolean", - "title": "nbHits", - "description": "Whether the `nbHits` is exhaustive (`true`) or approximate (`false`). When the query takes more than 50ms to be processed, the engine makes an approximation. This can happen when using complex filters on millions of records, when typo-tolerance was not exhaustive, or when enough hits have been retrieved (for example, after the engine finds 10,000 exact matches). `nbHits` is reported as non-exhaustive whenever an approximation is made, even if the approximation didn’t, in the end, impact the exhaustivity of the query." - }, - "rulesMatch": { - "type": "boolean", - "title": "rulesMatch", - "description": "Rules matching exhaustivity. The value is `false` if rules were enable for this query, and could not be fully processed due a timeout. This is generally caused by the number of alternatives (such as typos) which is too large." - }, - "typo": { - "type": "boolean", - "title": "typo", - "description": "Whether the typo search was exhaustive (`true`) or approximate (`false`). An approximation is done when the typo search query part takes more than 10% of the query budget (ie. 5ms by default) to be processed (this can happen when a lot of typo alternatives exist for the query). This field will not be included when typo-tolerance is entirely disabled." - } - } - }, - "appliedRules": { - "description": "Rules applied to the query.", - "title": "appliedRules", - "type": "array", - "items": { - "type": "object" - } - }, - "exhaustiveFacetsCount": { - "type": "boolean", - "description": "See the `facetsCount` field of the `exhaustive` object in the response.", - "deprecated": true - }, - "exhaustiveNbHits": { - "type": "boolean", - "description": "See the `nbHits` field of the `exhaustive` object in the response.", - "deprecated": true - }, - "exhaustiveTypo": { - "type": "boolean", - "description": "See the `typo` field of the `exhaustive` object in the response.", - "deprecated": true - }, - "facets": { - "title": "facets", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "facet", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "facet count", - "type": "integer" - } - }, - "description": "Facet counts.", - "example": { - "category": { - "food": 1, - "tech": 42 - } - } - }, - "facets_stats": { - "type": "object", - "description": "Statistics for numerical facets.", - "additionalProperties": { - "title": "facetStats", - "type": "object", - "properties": { - "min": { - "type": "number", - "format": "double", - "description": "Minimum value in the results." - }, - "max": { - "type": "number", - "format": "double", - "description": "Maximum value in the results." - }, - "avg": { - "type": "number", - "format": "double", - "description": "Average facet value in the results." - }, - "sum": { - "type": "number", - "format": "double", - "description": "Sum of all values in the results." - } - } - } - }, - "index": { - "type": "string", - "example": "indexName", - "description": "Index name used for the query." - }, - "indexUsed": { - "type": "string", - "description": "Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query.", - "example": "indexNameAlt" - }, - "message": { - "type": "string", - "description": "Warnings about the query." - }, - "nbSortedHits": { - "type": "integer", - "description": "Number of hits selected and sorted by the relevant sort algorithm.", - "example": 20 - }, - "parsedQuery": { - "type": "string", - "description": "Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched.", - "example": "george clo" - }, - "processingTimeMS": { - "$ref": "#/components/schemas/processingTimeMS" - }, - "processingTimingsMS": { - "type": "object", - "description": "Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues." - }, - "queryAfterRemoval": { - "type": "string", - "description": "Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set." - }, - "redirect": { - "title": "redirect", - "type": "object", - "description": "[Redirect results to a URL](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/redirects/), this this parameter is for internal use only.\n", - "properties": { - "index": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RedirectRuleIndexMetadata" - } - } - } - }, - "renderingContent": { - "$ref": "#/components/schemas/renderingContent" - }, - "serverTimeMS": { - "type": "integer", - "description": "Time the server took to process the request, in milliseconds.", - "example": 20 - }, - "serverUsed": { - "type": "string", - "description": "Host name of the server that processed the request.", - "example": "c2-uk-3.algolia.net" - }, - "userData": { - "$ref": "#/components/schemas/userData" - }, - "queryID": { - "type": "string", - "description": "Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/).", - "example": "a00dbc80a8d13c4565a442e7e2dca80a" - }, - "_automaticInsights": { - "type": "boolean", - "description": "Whether automatic events collection is enabled for the application." - } - } - }, - "page": { - "type": "integer", - "description": "Page of search results to retrieve.", - "default": 0, - "minimum": 0, - "x-categories": ["Pagination"] - }, - "nbHits": { - "type": "integer", - "description": "Number of results (hits).", - "example": 20 - }, - "nbPages": { - "type": "integer", - "description": "Number of pages of results.", - "example": 1 - }, - "hitsPerPage": { - "type": "integer", - "description": "Number of hits per page.", - "default": 20, - "minimum": 1, - "maximum": 1000, - "x-categories": ["Pagination"] - }, - "SearchPagination": { - "type": "object", - "properties": { - "page": { - "$ref": "#/components/schemas/page" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - }, - "nbPages": { - "$ref": "#/components/schemas/nbPages" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/hitsPerPage" - } - } - }, - "highlightedValue": { - "type": "string", - "description": "Highlighted attribute value, including HTML tags.", - "example": "George Clooney" - }, - "matchLevel": { - "type": "string", - "description": "Whether the whole query string matches or only a part.", - "enum": ["none", "partial", "full"] - }, - "highlightResultOption": { - "type": "object", - "description": "Surround words that match the query with HTML tags for highlighting.", - "additionalProperties": false, - "properties": { - "value": { - "$ref": "#/components/schemas/highlightedValue" - }, - "matchLevel": { - "$ref": "#/components/schemas/matchLevel" - }, - "matchedWords": { - "type": "array", - "description": "List of matched words from the search query.", - "example": ["action"], - "items": { - "type": "string" - } - }, - "fullyHighlighted": { - "type": "boolean", - "description": "Whether the entire attribute value is highlighted." - } - }, - "required": ["value", "matchLevel", "matchedWords"], - "x-discriminator-fields": ["matchLevel", "matchedWords"] - }, - "highlightResultMap": { - "type": "object", - "description": "Surround words that match the query with HTML tags for highlighting.", - "x-is-free-form": false, - "additionalProperties": { - "x-additionalPropertiesName": "attribute", - "$ref": "#/components/schemas/highlightResult" - } - }, - "highlightResult": { - "oneOf": [ - { - "$ref": "#/components/schemas/highlightResultOption" - }, - { - "$ref": "#/components/schemas/highlightResultMap" - }, - { - "$ref": "#/components/schemas/highlightResultArray" - } - ] - }, - "highlightResultArray": { - "type": "array", - "description": "Surround words that match the query with HTML tags for highlighting.", - "items": { - "$ref": "#/components/schemas/highlightResult" - } - }, - "snippetResultOption": { - "type": "object", - "description": "Snippets that show the context around a matching search query.", - "additionalProperties": false, - "properties": { - "value": { - "$ref": "#/components/schemas/highlightedValue" - }, - "matchLevel": { - "$ref": "#/components/schemas/matchLevel" - } - }, - "required": ["value", "matchLevel"], - "x-discriminator-fields": ["matchLevel"] - }, - "snippetResultMap": { - "type": "object", - "description": "Snippets that show the context around a matching search query.", - "x-is-free-form": false, - "additionalProperties": { - "x-additionalPropertiesName": "attribute", - "$ref": "#/components/schemas/snippetResult" - } - }, - "snippetResult": { - "oneOf": [ - { - "$ref": "#/components/schemas/snippetResultOption" - }, - { - "$ref": "#/components/schemas/snippetResultMap" - }, - { - "$ref": "#/components/schemas/snippetResultArray" - } - ] - }, - "snippetResultArray": { - "type": "array", - "description": "Snippets that show the context around a matching search query.", - "items": { - "$ref": "#/components/schemas/snippetResult" - } - }, - "matchedGeoLocation": { - "type": "object", - "properties": { - "lat": { - "type": "number", - "format": "double", - "description": "Latitude of the matched location." - }, - "lng": { - "type": "number", - "format": "double", - "description": "Longitude of the matched location." - }, - "distance": { - "type": "integer", - "description": "Distance between the matched location and the search location (in meters)." - } - } - }, - "personalization": { - "type": "object", - "properties": { - "filtersScore": { - "type": "integer", - "description": "The score of the filters." - }, - "rankingScore": { - "type": "integer", - "description": "The score of the ranking." - }, - "score": { - "type": "integer", - "description": "The score of the event." - } - } - }, - "rankingInfo": { - "type": "object", - "description": "Object with detailed information about the record's ranking.", - "additionalProperties": false, - "properties": { - "filters": { - "type": "integer", - "minimum": 0, - "description": "Whether a filter matched the query." - }, - "firstMatchedWord": { - "type": "integer", - "minimum": 0, - "description": "Position of the first matched word in the best matching attribute of the record." - }, - "geoDistance": { - "type": "integer", - "minimum": 0, - "description": "Distance between the geo location in the search query and the best matching geo location in the record, divided by the geo precision (in meters)." - }, - "geoPrecision": { - "type": "integer", - "minimum": 1, - "description": "Precision used when computing the geo distance, in meters." - }, - "matchedGeoLocation": { - "$ref": "#/components/schemas/matchedGeoLocation" - }, - "personalization": { - "$ref": "#/components/schemas/personalization" - }, - "nbExactWords": { - "type": "integer", - "minimum": 0, - "description": "Number of exactly matched words." - }, - "nbTypos": { - "type": "integer", - "minimum": 0, - "description": "Number of typos encountered when matching the record." - }, - "promoted": { - "type": "boolean", - "description": "Whether the record was promoted by a rule." - }, - "proximityDistance": { - "type": "integer", - "minimum": 0, - "description": "Number of words between multiple matches in the query plus 1. For single word queries, `proximityDistance` is 0." - }, - "userScore": { - "type": "integer", - "description": "Overall ranking of the record, expressed as a single integer. This attribute is internal." - }, - "words": { - "type": "integer", - "minimum": 1, - "description": "Number of matched words." - }, - "promotedByReRanking": { - "type": "boolean", - "description": "Whether the record is re-ranked." - } - }, - "required": ["nbTypos", "firstMatchedWord", "geoDistance", "nbExactWords", "userScore"] - }, - "distinctSeqID": { - "type": "integer" - }, - "recommendScore": { - "type": "number", - "format": "double", - "minimum": 0, - "maximum": 100, - "description": "Recommendation score." - }, - "recommendHit": { - "type": "object", - "description": "Recommend hit.", - "additionalProperties": true, - "required": ["objectID"], - "properties": { - "objectID": { - "$ref": "#/components/schemas/objectID" - }, - "_highlightResult": { - "$ref": "#/components/schemas/highlightResultMap" - }, - "_snippetResult": { - "$ref": "#/components/schemas/snippetResultMap" - }, - "_rankingInfo": { - "$ref": "#/components/schemas/rankingInfo" - }, - "_distinctSeqID": { - "$ref": "#/components/schemas/distinctSeqID" - }, - "_score": { - "$ref": "#/components/schemas/recommendScore" - } - }, - "x-discriminator-fields": ["objectID"] - }, - "trendingFacetHit": { - "type": "object", - "description": "Trending facet hit.", - "required": ["facetName", "facetValue"], - "properties": { - "_score": { - "$ref": "#/components/schemas/recommendScore" - }, - "facetName": { - "$ref": "#/components/schemas/facetName" - }, - "facetValue": { - "$ref": "#/components/schemas/facetValue" - } - }, - "x-discriminator-fields": ["facetName", "facetValue"] - }, - "recommendationsHit": { - "oneOf": [ - { - "$ref": "#/components/schemas/recommendHit" - }, - { - "$ref": "#/components/schemas/trendingFacetHit" - } - ] - }, - "recommendationsHits": { - "type": "object", - "properties": { - "hits": { - "type": "array", - "items": { - "$ref": "#/components/schemas/recommendationsHit" - } - } - }, - "required": ["hits"] - }, - "recommendationsResults": { - "allOf": [ - { - "$ref": "#/components/schemas/baseSearchResponse" - }, - { - "$ref": "#/components/schemas/SearchPagination" - }, - { - "$ref": "#/components/schemas/recommendationsHits" - } - ], - "unevaluatedProperties": false - }, - "recommendModels": { - "type": "string", - "enum": ["related-products", "bought-together", "trending-facets", "trending-items"] - }, - "updatedAt": { - "type": "string", - "example": "2023-07-04T12:49:15Z", - "description": "Date and time when the object was updated, in RFC 3339 format." - }, - "ruleID": { - "title": "objectID", - "type": "string", - "description": "Unique identifier of a rule object." - }, - "context": { - "type": "string", - "pattern": "[A-Za-z0-9_-]+", - "description": "An additional restriction that only triggers the rule, when the search has the same value as `ruleContexts` parameter.\nFor example, if `context: mobile`, the rule is only triggered when the search request has a matching `ruleContexts: mobile`.\nA rule context must only contain alphanumeric characters.\n", - "example": "mobile" - }, - "Condition": { - "type": "object", - "description": "Condition that triggers the rule.\nIf not specified, the rule is triggered for all recommendations.\n", - "properties": { - "filters": { - "$ref": "#/components/schemas/filters" - }, - "context": { - "$ref": "#/components/schemas/context" - } - } - }, - "HideConsequenceObject": { - "type": "object", - "description": "Object ID of the recommendation you want to exclude.", - "properties": { - "objectID": { - "$ref": "#/components/schemas/objectID" - } - } - }, - "HideConsequence": { - "type": "array", - "description": "Exclude items from recommendations.", - "minItems": 1, - "items": { - "$ref": "#/components/schemas/HideConsequenceObject" - } - }, - "PromoteConsequenceObject": { - "type": "object", - "description": "Object ID and position of the recommendation you want to pin.", - "properties": { - "objectID": { - "$ref": "#/components/schemas/objectID" - }, - "position": { - "type": "integer", - "description": "Index in the list of recommendations where to place this item.", - "minimum": 0 - } - } - }, - "PromoteConsequence": { - "type": "array", - "description": "Place items at specific positions in the list of recommendations.", - "minItems": 1, - "items": { - "$ref": "#/components/schemas/PromoteConsequenceObject" - } - }, - "AutoFacetFilter": { - "type": "object", - "description": "Facet attribute. Only recommendations with the same value (or only recommendations with a different value) as the original viewed item are included.", - "properties": { - "facet": { - "type": "string", - "description": "Facet attribute." - }, - "negative": { - "type": "boolean", - "description": "Whether the filter is negative.\nIf true, recommendations must not have the same value for the `facet` attribute.\nIf false, recommendations must have the same value for the `facet` attribute.\n" - } - } - }, - "ParamsConsequence": { - "type": "object", - "description": "Filter or boost recommendations matching a facet filter.", - "properties": { - "automaticFacetFilters": { - "type": "array", - "description": "Filter recommendations that match or don't match the same `facet:facet_value` combination as the viewed item.", - "items": { - "$ref": "#/components/schemas/AutoFacetFilter" - } - }, - "filters": { - "$ref": "#/components/schemas/filters" - }, - "optionalFilters": { - "type": "array", - "description": "Filters to promote or demote records in the search results.\n\nOptional filters work like facet filters, but they don't exclude records from the search results.\nRecords that match the optional filter rank before records that don't match.\nMatches with higher weights (``) rank before matches with lower weights.\nIf you're using a negative filter `facet:-value`, matching records rank after records that don't match.\n", - "items": { - "type": "string" - }, - "example": ["category:books", "category:-movies"] - } - } - }, - "Consequence": { - "type": "object", - "description": "Effect of the rule.", - "properties": { - "hide": { - "$ref": "#/components/schemas/HideConsequence" - }, - "promote": { - "$ref": "#/components/schemas/PromoteConsequence" - }, - "params": { - "$ref": "#/components/schemas/ParamsConsequence" - } - } - }, - "timeRange": { - "type": "object", - "additionalProperties": false, - "properties": { - "from": { - "type": "integer", - "format": "int64", - "description": "When the rule should start to be active, in Unix epoch time." - }, - "until": { - "type": "integer", - "format": "int64", - "description": "When the rule should stop to be active, in Unix epoch time." - } - }, - "required": ["from", "until"] - }, - "RecommendRule": { - "type": "object", - "description": "Recommend rule.", - "additionalProperties": false, - "properties": { - "_metadata": { - "title": "ruleMetadata", - "type": "object", - "description": "Rule metadata.", - "properties": { - "lastUpdate": { - "$ref": "#/components/schemas/updatedAt" - } - } - }, - "objectID": { - "$ref": "#/components/schemas/ruleID" - }, - "condition": { - "$ref": "#/components/schemas/Condition" - }, - "consequence": { - "$ref": "#/components/schemas/Consequence" - }, - "description": { - "type": "string", - "description": "Description of the rule's purpose. This can be helpful for display in the Algolia dashboard.", - "example": "Boost on-sale items" - }, - "enabled": { - "type": "boolean", - "default": true, - "description": "Indicates whether to enable the rule. If it isn't enabled, it isn't applied at query time." - }, - "validity": { - "type": "array", - "description": "Time periods when the rule is active.", - "items": { - "$ref": "#/components/schemas/timeRange" - } - } - } - }, - "taskID": { - "type": "integer", - "format": "int64", - "example": 1514562690001, - "description": "Unique identifier of a task.\n\nA successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`.\n" - }, - "deletedAt": { - "type": "string", - "example": "2023-06-27T14:42:38.831Z", - "description": "Date and time when the object was deleted, in RFC 3339 format." - }, - "taskStatus": { - "type": "string", - "enum": ["published", "notPublished"], - "description": "Task status, `published` if the task is completed, `notPublished` otherwise." - }, - "parameters_query": { - "type": "string", - "description": "Search query.", - "default": "" - }, - "parameters_page": { - "type": "integer", - "minimum": 0, - "description": "Requested page of the API response.\n\nAlgolia uses `page` and `hitsPerPage` to control how search results are displayed ([paginated](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/pagination/js/)).\n\n- `hitsPerPage`: sets the number of search results (_hits_) displayed per page.\n- `page`: specifies the page number of the search results you want to retrieve. Page numbering starts at 0, so the first page is `page=0`, the second is `page=1`, and so on.\n\nFor example, to display 10 results per page starting from the third page, set `hitsPerPage` to 10 and `page` to 2.\n" - }, - "parameters_hitsPerPage": { - "type": "integer", - "default": 20, - "minimum": 1, - "maximum": 1000, - "description": "Maximum number of hits per page.\n\nAlgolia uses `page` and `hitsPerPage` to control how search results are displayed ([paginated](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/pagination/js/)).\n\n- `hitsPerPage`: sets the number of search results (_hits_) displayed per page.\n- `page`: specifies the page number of the search results you want to retrieve. Page numbering starts at 0, so the first page is `page=0`, the second is `page=1`, and so on.\n\nFor example, to display 10 results per page starting from the third page, set `hitsPerPage` to 10 and `page` to 2.\n" - }, - "recommendUpdatedAtResponse": { - "type": "object", - "description": "Response, taskID, and update timestamp.", - "additionalProperties": false, - "required": ["taskID", "updatedAt"], - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - } - } - }, - "responses": { - "BadRequest": { - "description": "Bad request or request arguments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "FeatureNotEnabled": { - "description": "This feature is not enabled on your Algolia account.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "MethodNotAllowed": { - "description": "Method not allowed with this API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "IndexNotFound": { - "description": "Index not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "DeletedAt": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "deletedAtResponse", - "description": "Response, taskID, and deletion timestamp.", - "additionalProperties": false, - "type": "object", - "required": ["taskID", "deletedAt"], - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "deletedAt": { - "$ref": "#/components/schemas/deletedAt" - } - } - } - } - } - }, - "RecommendUpdatedAt": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/recommendUpdatedAtResponse" - } - } - } - } - } - }, - "x-tagGroups": [ - { - "name": "Recommend", - "tags": ["recommendations", "rules"] - } - ] -} diff --git a/src/data/search.json b/src/data/search.json deleted file mode 100644 index bd24c94..0000000 --- a/src/data/search.json +++ /dev/null @@ -1,7747 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "Search API", - "description": "The Algolia Search API lets you search, configure, and manage your indices and records.\n\n## Client libraries\n\nUse Algolia's API clients and libraries to reliably integrate Algolia's APIs with your apps.\nThe official API clients are covered by Algolia's [Service Level Agreement](https://www.algolia.com/policies/sla/).\n\nSee: [Algolia's ecosystem](https://www.algolia.com/doc/guides/getting-started/how-algolia-works/in-depth/ecosystem/)\n\n## Base URLs\n\nThe base URLs for requests to the Search API are:\n\n- `https://{APPLICATION_ID}.algolia.net`\n- `https://{APPLICATION_ID}-dsn.algolia.net`.\n If your subscription includes a [Distributed Search Network](https://dashboard.algolia.com/infra),\n this ensures that requests are sent to servers closest to users.\n\nBoth URLs provide high availability by distributing requests with load balancing.\n\n**All requests must use HTTPS.**\n\n## Retry strategy\n\nTo guarantee high availability, implement a retry strategy for all API requests using the URLs of your servers as fallbacks:\n\n- `https://{APPLICATION_ID}-1.algolianet.com`\n- `https://{APPLICATION_ID}-2.algolianet.com`\n- `https://{APPLICATION_ID}-3.algolianet.com`\n\nThese URLs use a different DNS provider than the primary URLs.\nYou should randomize this list to ensure an even load across the three servers.\n\nAll Algolia API clients implement this retry strategy.\n\n## Authentication\n\nTo authenticate your API requests, add these headers:\n\n- `x-algolia-application-id`. Your Algolia application ID.\n- `x-algolia-api-key`. An API key with the necessary permissions to make the request.\n The required access control list (ACL) to make a request is listed in each endpoint's reference.\n\nYou can find your application ID and API key in the [Algolia dashboard](https://dashboard.algolia.com/account).\n\n## Request format\n\nDepending on the endpoint, request bodies are either JSON objects or arrays of JSON objects,\n\n## Parameters\n\nParameters are passed as query parameters for GET and DELETE requests,\nand in the request body for POST and PUT requests.\n\nQuery parameters must be [URL-encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding).\nNon-ASCII characters must be UTF-8 encoded.\nPlus characters (`+`) are interpreted as spaces.\nArrays as query parameters must be one of:\n\n- A comma-separated string: `attributesToRetrieve=title,description`\n- A URL-encoded JSON array: `attributesToRetrieve=%5B%22title%22,%22description%22%D`\n\n## Response status and errors\n\nThe Search API returns JSON responses.\nSince JSON doesn't guarantee any specific ordering, don't rely on the order of attributes in the API response.\n\nSuccessful responses return a `2xx` status. Client errors return a `4xx` status. Server errors are indicated by a `5xx` status.\nError responses have a `message` property with more information.\n\n## Version\n\nThe current version of the Search API is version 1, as indicated by the `/1/` in each endpoint's URL.\n", - "version": "1.0.0" - }, - "servers": [ - { - "url": "https://{applicationId}.algolia.net", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-1.algolianet.com", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-2.algolianet.com", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-3.algolianet.com", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - }, - { - "url": "https://{applicationId}-dsn.algolia.net", - "variables": { - "applicationId": { - "default": "ALGOLIA_APPLICATION_ID" - } - } - } - ], - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ], - "tags": [ - { - "name": "Advanced", - "description": "Query your logs." - }, - { - "name": "Api Keys", - "x-displayName": "API keys", - "description": "Manage your API keys.\n\nAPI requests must be authenticated with an API key.\nAPI keys can have permissions (access control lists, ACL) and restrictions.\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/security/api-keys/", - "description": "Related guide: API keys.\n" - } - }, - { - "name": "Clusters", - "description": "Multi-cluster operations.\n\nMulti-cluster operations are **deprecated**.\nIf you have issues with your Algolia infrastructure\ndue to large volumes of data, contact the Algolia support team.\n" - }, - { - "name": "Dictionaries", - "description": "Manage your dictionaries.\n\nCustomize language-specific settings, such as stop words, plurals, or word segmentation.\n\nDictionaries are application-wide.\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/", - "description": "Related guide: Natural languages.\n" - } - }, - { - "name": "Indices", - "description": "Manage your indices and index settings.\n\nIndices are copies of your data that are stored on Algolia's servers.\nThey're optimal data structures for fast search and are made up of records and settings.\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/sending-and-managing-data/manage-indices-and-apps/manage-indices/", - "description": "Related guide: Manage your indices.\n" - } - }, - { - "name": "Records", - "description": "Add, update, and delete records from your indices.\n\nRecords are individual items in your index.\nWhen they match a search query, they're returned as search results, in the order determined by your ranking.\nRecords are schemaless JSON objects.\nWhen adding or updating many records, check the [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/", - "description": "Related guide: Prepare your records.\n" - } - }, - { - "name": "Rules", - "description": "Create, update, delete, and search for rules.\n\nRules are _if-then_ statements that you can use to curate search results.\nRules have _conditions_ that can trigger _consequences_.\nConsequences are changes to the search results, such as changing the order of search results or boosting a facet.\nThis can be useful for tuning specific queries or for merchandising.\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/", - "description": "Related guide: Rules.\n" - } - }, - { - "name": "Search", - "description": "Search one or more indices for matching records or facet values." - }, - { - "name": "Synonyms", - "description": "Create, update, delete, and search for synonyms.\n\nSynonyms are terms that the search engine should consider equal.\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/", - "description": "Related guide: Synonyms.\n" - } - }, - { - "name": "Vaults", - "description": "Algolia Vault lets you restrict access to your clusters to specific IP addresses and provides disk-level encryption at rest.", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/security/algolia-vault/", - "description": "Related guide: Algolia Vault.\n" - } - }, - { - "name": "_model_index_settings", - "x-displayName": "Index settings", - "description": ".\n" - } - ], - "paths": { - "/{path}": { - "get": { - "operationId": "customGet", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["search"] - }, - "post": { - "operationId": "customPost", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["search"] - }, - "put": { - "operationId": "customPut", - "requestBody": { - "description": "Parameters to send with the custom request.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["search"] - }, - "delete": { - "operationId": "customDelete", - "summary": "Send requests to the Algolia REST API", - "description": "This method lets you send requests to the Algolia REST API.", - "parameters": [ - { - "$ref": "#/components/parameters/PathInPath" - }, - { - "$ref": "#/components/parameters/Parameters" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["search"] - } - }, - "/1/indexes/{indexName}/query": { - "post": { - "tags": ["search"], - "operationId": "searchSingleIndex", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["search"], - "summary": "Search an index", - "description": "Searches a single index and returns matching search results (_hits_).\n\nThis method lets you retrieve up to 1,000 hits.\nIf you need more, use the [`browse` operation](#tag/Search/operation/browse) or increase the `paginatedLimitedTo` index setting.\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/searchParams" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/searchResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/*/queries": { - "post": { - "tags": ["search"], - "operationId": "search", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-legacy-signature": true, - "x-acl": ["search"], - "summary": "Search multiple indices", - "description": "Sends multiple search requests to one or more indices.\n\nThis can be useful in these cases:\n\n- Different indices for different purposes, such as, one index for products, another one for marketing content.\n- Multiple searches to the same index—for example, with different filters.\n", - "requestBody": { - "required": true, - "description": "Muli-search request body. Results are returned in the same order as the requests.", - "content": { - "application/json": { - "schema": { - "title": "searchMethodParams", - "type": "object", - "additionalProperties": false, - "properties": { - "requests": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SearchQuery" - } - }, - "strategy": { - "$ref": "#/components/schemas/searchStrategy" - } - }, - "required": ["requests"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchResponses", - "type": "object", - "additionalProperties": false, - "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/searchResult" - } - } - }, - "required": ["results"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/facets/{facetName}/query": { - "post": { - "tags": ["search"], - "operationId": "searchForFacetValues", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["search"], - "summary": "Search for facet values", - "description": "Searches for values of a specified facet attribute.\n\n- By default, facet values are sorted by decreasing count.\n You can adjust this with the `sortFacetValueBy` parameter.\n- Searching for facet values doesn't work if you have **more than 65 searchable facets and searchable attributes combined**.\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "name": "facetName", - "description": "Facet attribute in which to search for values.\n\nThis attribute must be included in the `attributesForFaceting` index setting with the `searchable()` modifier.\n", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "title": "searchForFacetValuesRequest", - "type": "object", - "additionalProperties": false, - "properties": { - "params": { - "$ref": "#/components/schemas/paramsAsString" - }, - "facetQuery": { - "$ref": "#/components/schemas/facetQuery" - }, - "maxFacetHits": { - "$ref": "#/components/schemas/maxFacetHits" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/searchForFacetValuesResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/browse": { - "post": { - "tags": ["search"], - "operationId": "browse", - "x-use-read-transporter": true, - "x-acl": ["browse"], - "summary": "Browse for records", - "description": "Retrieves records from an index, up to 1,000 per request.\n\nWhile searching retrieves _hits_ (records augmented with attributes for highlighting and ranking details),\nbrowsing _just_ returns matching records.\nThis can be useful if you want to export your indices.\n\n- The Analytics API doesn't collect data when using `browse`.\n- Records are ranked by attributes and custom ranking.\n- There's no ranking for: typo-tolerance, number of matched words, proximity, geo distance.\n\nBrowse requests automatically apply these settings:\n\n- `advancedSyntax`: `false`\n- `attributesToHighlight`: `[]`\n- `attributesToSnippet`: `[]`\n- `distinct`: `false`\n- `enablePersonalization`: `false`\n- `enableRules`: `false`\n- `facets`: `[]`\n- `getRankingInfo`: `false`\n- `ignorePlurals`: `false`\n- `optionalFilters`: `[]`\n- `typoTolerance`: `true` or `false` (`min` and `strict` evaluate to `true`)\n\nIf you send these parameters with your browse requests, they'll be ignored.\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/browseParams" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/browseResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}": { - "post": { - "tags": ["search"], - "operationId": "saveObject", - "x-acl": ["addObject"], - "description": "Adds a record to an index or replaces it.\n\n- If the record doesn't have an object ID, a new record with an auto-generated object ID is added to your index.\n- If a record with the specified object ID exists, the existing record is replaced.\n- If a record with the specified object ID doesn't exist, a new record is added to your index.\n- If you add a record to an index that doesn't exist yet, a new index is created.\n\nTo update _some_ attributes of a record, use the [`partial` operation](#tag/Records/operation/partialUpdateObject).\nTo add, update, or replace multiple records, use the [`batch` operation](#tag/Records/operation/batch).\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "summary": "Add a new record (with auto-generated object ID)", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "required": true, - "description": "The record. A schemaless object with attributes that are useful in the context of search and discovery.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "title": "saveObjectResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "createdAt": { - "$ref": "#/components/schemas/createdAt" - }, - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "objectID": { - "$ref": "#/components/schemas/objectID" - } - }, - "required": ["taskID", "createdAt"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["search"], - "operationId": "deleteIndex", - "x-acl": ["deleteIndex"], - "summary": "Delete an index", - "description": "Deletes an index and all its settings.\n\n- Deleting an index doesn't delete its analytics data.\n- If you try to delete a non-existing index, the operation is ignored without warning.\n- If the index you want to delete has replica indices, the replicas become independent indices.\n- If the index you want to delete is a replica index, you must first unlink it from its primary index before you can delete it.\n For more information, see [Delete replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/deleting-replicas/).\n", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/sending-and-managing-data/manage-indices-and-apps/manage-indices/how-to/delete-indices/", - "description": "Related guide: Delete indices.\n" - }, - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/DeletedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/{objectID}": { - "get": { - "tags": ["search"], - "operationId": "getObject", - "x-acl": ["search"], - "summary": "Retrieve a record", - "description": "Retrieves one record by its object ID.\n\nTo retrieve more than one record, use the [`objects` operation](#tag/Records/operation/getObjects).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ObjectID" - }, - { - "name": "attributesToRetrieve", - "in": "query", - "description": "Attributes to include with the records in the response.\nThis is useful to reduce the size of the API response.\nBy default, all retrievable attributes are returned.\n\n`objectID` is always retrieved.\n\nAttributes included in `unretrievableAttributes`\nwon't be retrieved unless the request is authenticated with the admin API key.\n", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "description": "The requested record." - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "put": { - "tags": ["search"], - "operationId": "addOrUpdateObject", - "x-acl": ["addObject"], - "summary": "Add or replace a record", - "description": "If a record with the specified object ID exists, the existing record is replaced.\nOtherwise, a new record is added to the index.\n\nIf you want to use auto-generated object IDs, use the [`saveObject` operation](#tag/Records/operation/saveObject).\nTo update _some_ attributes of an existing record, use the [`partial` operation](#tag/Records/operation/partialUpdateObject) instead.\nTo add, update, or replace multiple records, use the [`batch` operation](#tag/Records/operation/batch).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ObjectID" - } - ], - "requestBody": { - "required": true, - "description": "The record. A schemaless object with attributes that are useful in the context of search and discovery.", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAtWithObjectId" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["search"], - "operationId": "deleteObject", - "x-acl": ["deleteObject"], - "summary": "Delete a record", - "description": "Deletes a record by its object ID.\n\nTo delete more than one record, use the [`batch` operation](#tag/Records/operation/batch).\nTo delete records matching a query, use the [`deleteByQuery` operation](#tag/Records/operation/deleteBy).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ObjectID" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/DeletedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/deleteByQuery": { - "post": { - "tags": ["search"], - "operationId": "deleteBy", - "x-acl": ["deleteIndex"], - "summary": "Delete records matching a filter", - "description": "This operation doesn't accept empty filters.\n\nThis operation is resource-intensive.\nYou should only use it if you can't get the object IDs of the records you want to delete.\nIt's more efficient to get a list of object IDs with the [`browse` operation](#tag/Search/operation/browse),\nand then delete the records using the [`batch` operation](#tag/Records/operation/batch).\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "externalDocs": { - "url": "https://support.algolia.com/hc/en-us/articles/16385098766353-Should-I-use-the-deleteby-method-for-deleting-records-matching-a-query-", - "description": "Should I use the deleteBy method for deleting records." - }, - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/deleteByParams" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/clear": { - "post": { - "tags": ["search"], - "operationId": "clearObjects", - "x-acl": ["deleteIndex"], - "summary": "Delete all records from an index", - "description": "Deletes only the records from an index while keeping settings, synonyms, and rules.\nThis operation is resource-intensive and subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/{objectID}/partial": { - "post": { - "tags": ["search"], - "operationId": "partialUpdateObject", - "x-acl": ["addObject"], - "summary": "Add or update attributes", - "x-codegen-request-body-name": "attributesToUpdate", - "description": "Adds new attributes to a record, or updates existing ones.\n\n- If a record with the specified object ID doesn't exist,\n a new record is added to the index **if** `createIfNotExists` is true.\n- If the index doesn't exist yet, this method creates a new index.\n- You can use any first-level attribute but not nested attributes.\n If you specify a nested attribute, this operation replaces its first-level ancestor.\n\nTo update an attribute without pushing the entire record, you can use these built-in operations.\nThese operations can be helpful if you don't have access to your initial data.\n\n- Increment: increment a numeric attribute\n- Decrement: decrement a numeric attribute\n- Add: append a number or string element to an array attribute\n- Remove: remove all matching number or string elements from an array attribute made of numbers or strings\n- AddUnique: add a number or string element to an array attribute made of numbers or strings only if it's not already present\n- IncrementFrom: increment a numeric integer attribute only if the provided value matches the current value, and otherwise ignore the whole object update. For example, if you pass an IncrementFrom value of 2 for the version attribute, but the current value of the attribute is 1, the engine ignores the update. If the object doesn't exist, the engine only creates it if you pass an IncrementFrom value of 0.\n- IncrementSet: increment a numeric integer attribute only if the provided value is greater than the current value, and otherwise ignore the whole object update. For example, if you pass an IncrementSet value of 2 for the version attribute, and the current value of the attribute is 1, the engine updates the object. If the object doesn't exist yet, the engine only creates it if you pass an IncrementSet value greater than 0.\n\nYou can specify an operation by providing an object with the attribute to update as the key and its value being an object with the following properties:\n\n- _operation: the operation to apply on the attribute\n- value: the right-hand side argument to the operation, for example, increment or decrement step, value to add or remove.\n\nWhen updating multiple attributes or using multiple operations targeting the same record, you should use a single partial update for faster processing.\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ObjectID" - }, - { - "name": "createIfNotExists", - "description": "Whether to create a new record if it doesn't exist.", - "in": "query", - "schema": { - "type": "boolean", - "default": true - } - } - ], - "requestBody": { - "required": true, - "description": "Attributes with their values.", - "content": { - "application/json": { - "schema": { - "description": "Attributes to update.", - "type": "object" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAtWithObjectId" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/batch": { - "post": { - "tags": ["search"], - "operationId": "batch", - "summary": "Batch indexing operations on one index", - "description": "Adds, updates, or deletes records in one index with a single API request.\n\nBatching index updates reduces latency and increases data integrity.\n\n- Actions are applied in the order they're specified.\n- Actions are equivalent to the individual API requests of the same name.\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "x-codegen-request-body-name": "batchWriteParams", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/batchWriteParams" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/batchResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/*/batch": { - "post": { - "tags": ["search"], - "operationId": "multipleBatch", - "description": "Adds, updates, or deletes records in multiple indices with a single API request.\n\n- Actions are applied in the order they are specified.\n- Actions are equivalent to the individual API requests of the same name.\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "summary": "Batch indexing operations on multiple indices", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "batchParams", - "description": "Batch parameters.", - "type": "object", - "additionalProperties": false, - "properties": { - "requests": { - "type": "array", - "items": { - "title": "multipleBatchRequest", - "type": "object", - "additionalProperties": false, - "properties": { - "action": { - "$ref": "#/components/schemas/action" - }, - "body": { - "type": "object", - "description": "Operation arguments (varies with specified `action`)." - }, - "indexName": { - "$ref": "#/components/schemas/indexName" - } - }, - "required": ["action", "indexName"] - } - } - }, - "required": ["requests"] - }, - "examples": { - "batch": { - "summary": "Batch indexing request to two indices", - "value": { - "requests": [ - { - "action": "addObject", - "indexName": "contacts", - "body": { - "name": "Betty Jane McCamey", - "company": "Vita Foods Inc.", - "email": "betty@mccamey.com" - } - }, - { - "action": "addObject", - "indexName": "public_contacts", - "body": { - "name": "Gayla Geimer", - "company": "Ortman McCain Co.", - "email": "gayla@geimer.com" - } - } - ] - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "multipleBatchResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "taskID": { - "type": "object", - "description": "Task IDs. One for each index.", - "additionalProperties": { - "$ref": "#/components/schemas/taskID" - } - }, - "objectIDs": { - "$ref": "#/components/schemas/objectIDs" - } - }, - "required": ["taskID", "objectIDs"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/*/objects": { - "post": { - "tags": ["search"], - "operationId": "getObjects", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["search"], - "summary": "Retrieve records", - "description": "Retrieves one or more records, potentially from different indices.\n\nRecords are returned in the same order as the requests.\n", - "requestBody": { - "required": true, - "description": "Request object.", - "content": { - "application/json": { - "schema": { - "title": "getObjectsParams", - "description": "Request parameters.", - "type": "object", - "additionalProperties": false, - "properties": { - "requests": { - "type": "array", - "items": { - "title": "getObjectsRequest", - "description": "Request body for retrieving records.", - "type": "object", - "additionalProperties": false, - "required": ["objectID", "indexName"], - "properties": { - "attributesToRetrieve": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Attributes to retrieve.\nIf not specified, all retrievable attributes are returned.\n", - "example": ["author", "title", "content"] - }, - "objectID": { - "type": "string", - "description": "Object ID for the record to retrieve.", - "example": "product-1" - }, - "indexName": { - "type": "string", - "description": "Index from which to retrieve the records.", - "example": "books" - } - } - } - } - }, - "required": ["requests"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getObjectsResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "message": { - "type": "string", - "description": "An optional status message.", - "example": "Index INDEX_NAME does not exist." - }, - "results": { - "type": "array", - "description": "Retrieved records.", - "items": { - "type": "object", - "description": "Retrieved record.", - "x-is-generic": true - } - } - }, - "required": ["results"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/settings": { - "get": { - "tags": ["search"], - "operationId": "getSettings", - "x-acl": ["search"], - "description": "Retrieves an object with non-null index settings.", - "summary": "Retrieve index settings", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/settingsResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "put": { - "tags": ["search"], - "operationId": "setSettings", - "x-acl": ["editSettings"], - "description": "Update the specified index settings.\n\nIndex settings that you don't specify are left unchanged.\nSpecify `null` to reset a setting to its default value.\n\nFor best performance, update the index settings before you add new records to your index.\n", - "summary": "Update index settings", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/indexSettings" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/synonyms/{objectID}": { - "get": { - "tags": ["search"], - "operationId": "getSynonym", - "x-acl": ["settings"], - "summary": "Retrieve a synonym", - "description": "Retrieves a synonym by its ID.\nTo find the object IDs for your synonyms,\nuse the [`search` operation](#tag/Synonyms/operation/searchSynonyms).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/parameters_ObjectID" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/synonymHit" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "put": { - "tags": ["search"], - "operationId": "saveSynonym", - "x-acl": ["editSettings"], - "summary": "Create or replace a synonym", - "description": "If a synonym with the specified object ID doesn't exist, Algolia adds a new one.\nOtherwise, the existing synonym is replaced.\nTo add multiple synonyms in a single API request, use the [`batch` operation](#tag/Synonyms/operation/saveSynonyms).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/parameters_ObjectID" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/synonymHit" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "saveSynonymResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - }, - "id": { - "$ref": "#/components/schemas/id" - } - }, - "required": ["taskID", "updatedAt", "id"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["search"], - "operationId": "deleteSynonym", - "x-acl": ["editSettings"], - "summary": "Delete a synonym", - "description": "Deletes a synonym by its ID.\nTo find the object IDs of your synonyms, use the [`search` operation](#tag/Synonyms/operation/searchSynonyms).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/parameters_ObjectID" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/DeletedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/synonyms/batch": { - "post": { - "tags": ["search"], - "operationId": "saveSynonyms", - "x-acl": ["editSettings"], - "summary": "Create or replace synonyms", - "description": "If a synonym with the `objectID` doesn't exist, Algolia adds a new one.\nOtherwise, existing synonyms are replaced.\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - }, - { - "$ref": "#/components/parameters/ReplaceExistingSynonyms" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/synonymHits" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/synonyms/clear": { - "post": { - "tags": ["search"], - "operationId": "clearSynonyms", - "x-acl": ["editSettings"], - "summary": "Delete all synonyms", - "description": "Deletes all synonyms from the index.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/synonyms/search": { - "post": { - "tags": ["search"], - "operationId": "searchSynonyms", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["settings"], - "summary": "Search for synonyms", - "description": "Searches for synonyms in your index.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "description": "Body of the `searchSynonyms` operation.", - "content": { - "application/json": { - "schema": { - "title": "searchSynonymsParams", - "type": "object", - "unevaluatedProperties": false, - "properties": { - "query": { - "$ref": "#/components/schemas/query" - }, - "type": { - "$ref": "#/components/schemas/SynonymType" - }, - "page": { - "$ref": "#/components/schemas/page" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/hitsPerPage" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/searchSynonymsResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/keys": { - "get": { - "tags": ["search"], - "operationId": "listApiKeys", - "x-acl": ["admin"], - "summary": "List API keys", - "description": "Lists all API keys associated with your Algolia application, including their permissions and restrictions.", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listApiKeysResponse", - "type": "object", - "additionalProperties": false, - "required": ["keys"], - "properties": { - "keys": { - "type": "array", - "description": "API keys.", - "items": { - "$ref": "#/components/schemas/getApiKeyResponse" - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "post": { - "tags": ["search"], - "operationId": "addApiKey", - "x-acl": ["admin"], - "summary": "Create an API key", - "description": "Creates a new API key with specific permissions and restrictions.", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/apiKey" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/addApiKeyResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/keys/{key}": { - "get": { - "tags": ["search"], - "operationId": "getApiKey", - "summary": "Retrieve API key permissions", - "description": "Gets the permissions and restrictions of an API key.\n\nWhen authenticating with the admin API key, you can request information for any of your application's keys.\nWhen authenticating with other API keys, you can only retrieve information for that key,\nwith the description replaced by ``.\n", - "parameters": [ - { - "$ref": "#/components/parameters/KeyString" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/getApiKeyResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "put": { - "tags": ["search"], - "operationId": "updateApiKey", - "x-acl": ["admin"], - "summary": "Update an API key", - "description": "Replaces the permissions of an existing API key.\n\nAny unspecified attribute resets that attribute to its default value.\n", - "parameters": [ - { - "$ref": "#/components/parameters/KeyString" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/apiKey", - "unevaluatedProperties": false - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "updateApiKeyResponse", - "type": "object", - "additionalProperties": false, - "required": ["key", "updatedAt"], - "properties": { - "key": { - "$ref": "#/components/schemas/keyString" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["search"], - "operationId": "deleteApiKey", - "x-acl": ["admin"], - "summary": "Delete an API key", - "description": "Deletes the API key.", - "parameters": [ - { - "$ref": "#/components/parameters/KeyString" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "deleteApiKeyResponse", - "type": "object", - "additionalProperties": false, - "required": ["deletedAt"], - "properties": { - "deletedAt": { - "$ref": "#/components/schemas/deletedAt" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/keys/{key}/restore": { - "post": { - "tags": ["search"], - "operationId": "restoreApiKey", - "x-acl": ["admin"], - "summary": "Restore an API key", - "description": "Restores a deleted API key.\n\nRestoring resets the `validity` attribute to `0`.\n\nAlgolia stores up to 1,000 API keys per application.\nIf you create more, the oldest API keys are deleted and can't be restored.\n", - "parameters": [ - { - "$ref": "#/components/parameters/KeyString" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/addApiKeyResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/rules/{objectID}": { - "get": { - "tags": ["search"], - "operationId": "getRule", - "x-acl": ["settings"], - "summary": "Retrieve a rule", - "description": "Retrieves a rule by its ID.\nTo find the object ID of rules, use the [`search` operation](#tag/Rules/operation/searchRules).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ObjectIDRule" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/rule" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "put": { - "tags": ["search"], - "operationId": "saveRule", - "x-acl": ["editSettings"], - "summary": "Create or replace a rule", - "description": "If a rule with the specified object ID doesn't exist, it's created.\nOtherwise, the existing rule is replaced.\n\nTo create or update more than one rule, use the [`batch` operation](#tag/Rules/operation/saveRules).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ObjectIDRule" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/rule" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["search"], - "operationId": "deleteRule", - "x-acl": ["editSettings"], - "summary": "Delete a rule", - "description": "Deletes a rule by its ID.\nTo find the object ID for rules,\nuse the [`search` operation](#tag/Rules/operation/searchRules).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ObjectIDRule" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/rules/batch": { - "post": { - "tags": ["search"], - "operationId": "saveRules", - "x-acl": ["editSettings"], - "summary": "Create or update rules", - "description": "Create or update multiple rules.\n\nIf a rule with the specified object ID doesn't exist, Algolia creates a new one.\nOtherwise, existing rules are replaced.\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "x-codegen-request-body-name": "rules", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - }, - { - "$ref": "#/components/parameters/ClearExistingRules" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "array", - "description": "Rules to add or replace.", - "items": { - "$ref": "#/components/schemas/rule" - } - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/rules/clear": { - "post": { - "tags": ["search"], - "operationId": "clearRules", - "x-acl": ["editSettings"], - "summary": "Delete all rules", - "description": "Deletes all rules from the index.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "$ref": "#/components/parameters/ForwardToReplicas" - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/rules/search": { - "post": { - "tags": ["search"], - "operationId": "searchRules", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["settings"], - "summary": "Search for rules", - "description": "Searches for rules in your index.", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "title": "searchRulesParams", - "type": "object", - "description": "Rules search parameters.", - "additionalProperties": false, - "properties": { - "query": { - "$ref": "#/components/schemas/parameters_query" - }, - "anchoring": { - "$ref": "#/components/schemas/anchoring" - }, - "context": { - "type": "string", - "description": "Only return rules that match the context (exact match).", - "example": "mobile" - }, - "page": { - "$ref": "#/components/schemas/parameters_page" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/parameters_hitsPerPage" - }, - "enabled": { - "oneOf": [ - { - "type": "boolean", - "description": "If `true`, return only enabled rules.\nIf `false`, return only inactive rules.\nBy default, _all_ rules are returned.\n" - }, - { - "type": "null" - } - ], - "default": null - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchRulesResponse", - "type": "object", - "additionalProperties": false, - "required": ["hits", "nbHits", "page", "nbPages"], - "properties": { - "hits": { - "type": "array", - "description": "Rules that matched the search criteria.", - "items": { - "$ref": "#/components/schemas/rule" - } - }, - "nbHits": { - "type": "integer", - "description": "Number of rules that matched the search criteria." - }, - "page": { - "type": "integer", - "description": "Current page." - }, - "nbPages": { - "type": "integer", - "description": "Number of pages." - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/dictionaries/{dictionaryName}/batch": { - "post": { - "tags": ["search"], - "operationId": "batchDictionaryEntries", - "x-acl": ["editSettings"], - "description": "Adds or deletes multiple entries from your plurals, segmentation, or stop word dictionaries.", - "summary": "Add or delete dictionary entries", - "parameters": [ - { - "$ref": "#/components/parameters/DictionaryName" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "batchDictionaryEntriesParams", - "description": "Request body for updating dictionary entries.", - "type": "object", - "required": ["requests"], - "additionalProperties": false, - "properties": { - "clearExistingDictionaryEntries": { - "type": "boolean", - "default": false, - "description": "Whether to replace all custom entries in the dictionary with the ones sent with this request." - }, - "requests": { - "type": "array", - "description": "List of additions and deletions to your dictionaries.", - "items": { - "title": "batchDictionaryEntriesRequest", - "type": "object", - "additionalProperties": false, - "required": ["action", "body"], - "properties": { - "action": { - "$ref": "#/components/schemas/dictionaryAction" - }, - "body": { - "$ref": "#/components/schemas/dictionaryEntry" - } - } - } - } - } - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/dictionaries/{dictionaryName}/search": { - "post": { - "tags": ["search"], - "operationId": "searchDictionaryEntries", - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["settings"], - "description": "Searches for standard and custom dictionary entries.", - "summary": "Search dictionary entries", - "parameters": [ - { - "$ref": "#/components/parameters/DictionaryName" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "searchDictionaryEntriesParams", - "description": "Search parameter.", - "type": "object", - "required": ["query"], - "additionalProperties": false, - "properties": { - "query": { - "$ref": "#/components/schemas/query" - }, - "page": { - "$ref": "#/components/schemas/page" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/hitsPerPage" - }, - "language": { - "$ref": "#/components/schemas/supportedLanguage" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/searchDictionaryEntriesResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/dictionaries/*/settings": { - "get": { - "tags": ["search"], - "operationId": "getDictionarySettings", - "x-acl": ["settings"], - "summary": "Retrieve dictionary settings", - "description": "Retrieves the languages for which standard dictionary entries are turned off.", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getDictionarySettingsResponse", - "additionalProperties": false, - "type": "object", - "required": ["disableStandardEntries"], - "properties": { - "disableStandardEntries": { - "$ref": "#/components/schemas/standardEntries" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "put": { - "tags": ["search"], - "operationId": "setDictionarySettings", - "x-acl": ["editSettings"], - "description": "Turns standard stop word dictionary entries on or off for a given language.", - "summary": "Update dictionary settings", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "dictionarySettingsParams", - "type": "object", - "additionalProperties": false, - "description": "Turn on or off the built-in Algolia stop words for a specific language.\n", - "required": ["disableStandardEntries"], - "properties": { - "disableStandardEntries": { - "$ref": "#/components/schemas/standardEntries" - } - } - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/dictionaries/*/languages": { - "get": { - "tags": ["search"], - "operationId": "getDictionaryLanguages", - "x-acl": ["settings"], - "description": "Lists supported languages with their supported dictionary types and number of custom entries.\n", - "summary": "List available languages", - "externalDocs": { - "url": "https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/", - "description": "Supported languages." - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getDictionaryLanguagesResponse", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "language", - "$ref": "#/components/schemas/languages" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/clusters/mapping": { - "post": { - "tags": ["search"], - "operationId": "assignUserId", - "deprecated": true, - "x-acl": ["admin"], - "summary": "Assign or move a user ID", - "description": "Assigns or moves a user ID to a cluster.\n\nThe time it takes to move a user is proportional to the amount of data linked to the user ID.\n", - "parameters": [ - { - "$ref": "#/components/parameters/UserIDInHeader" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "assignUserIdParams", - "type": "object", - "description": "Assign userID parameters.", - "additionalProperties": false, - "properties": { - "cluster": { - "$ref": "#/components/schemas/clusterName" - } - }, - "required": ["cluster"] - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/CreatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "get": { - "tags": ["search"], - "operationId": "listUserIds", - "deprecated": true, - "x-acl": ["admin"], - "summary": "List user IDs", - "description": "Lists the userIDs assigned to a multi-cluster application.\n\nSince it can take a few seconds to get the data from the different clusters,\nthe response isn't real-time.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Page" - }, - { - "$ref": "#/components/parameters/HitsPerPage" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listUserIdsResponse", - "type": "object", - "description": "User ID data.", - "properties": { - "userIDs": { - "type": "array", - "description": "User IDs.", - "items": { - "$ref": "#/components/schemas/userId" - } - } - }, - "required": ["userIDs"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/clusters/mapping/batch": { - "post": { - "tags": ["search"], - "operationId": "batchAssignUserIds", - "deprecated": true, - "x-acl": ["admin"], - "summary": "Assign multiple userIDs", - "description": "Assigns multiple user IDs to a cluster.\n\n**You can't move users with this operation**.\n", - "parameters": [ - { - "$ref": "#/components/parameters/UserIDInHeader" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "batchAssignUserIdsParams", - "type": "object", - "description": "Assign userID parameters.", - "additionalProperties": false, - "properties": { - "cluster": { - "$ref": "#/components/schemas/clusterName" - }, - "users": { - "type": "array", - "description": "User IDs to assign.", - "example": ["einstein", "bohr", "feynman"], - "items": { - "type": "string" - } - } - }, - "required": ["cluster", "users"] - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/CreatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/clusters/mapping/top": { - "get": { - "tags": ["search"], - "operationId": "getTopUserIds", - "deprecated": true, - "x-acl": ["admin"], - "summary": "Get top user IDs", - "description": "Get the IDs of the 10 users with the highest number of records per cluster.\n\nSince it can take a few seconds to get the data from the different clusters,\nthe response isn't real-time.\n", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getTopUserIdsResponse", - "type": "object", - "description": "User IDs and clusters.", - "properties": { - "topUsers": { - "type": "array", - "description": "Key-value pairs with cluster names as keys and lists of users with the highest number of records per cluster as values.", - "items": { - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "cluster", - "type": "array", - "items": { - "$ref": "#/components/schemas/userId" - } - } - } - } - }, - "required": ["topUsers"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/clusters/mapping/{userID}": { - "get": { - "tags": ["search"], - "operationId": "getUserId", - "deprecated": true, - "x-acl": ["admin"], - "summary": "Retrieve user ID", - "description": "Returns the user ID data stored in the mapping.\n\nSince it can take a few seconds to get the data from the different clusters,\nthe response isn't real-time.\n", - "parameters": [ - { - "$ref": "#/components/parameters/UserIDInPath" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/userId" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "delete": { - "tags": ["search"], - "operationId": "removeUserId", - "deprecated": true, - "x-acl": ["admin"], - "summary": "Delete user ID", - "description": "Deletes a user ID and its associated data from the clusters.", - "parameters": [ - { - "$ref": "#/components/parameters/UserIDInPath" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "removeUserIdResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "deletedAt": { - "$ref": "#/components/schemas/deletedAt" - } - }, - "required": ["deletedAt"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/clusters": { - "get": { - "tags": ["search"], - "operationId": "listClusters", - "deprecated": true, - "x-acl": ["admin"], - "summary": "List clusters", - "description": "Lists the available clusters in a multi-cluster setup.", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "listClustersResponse", - "type": "object", - "description": "Clusters.", - "properties": { - "topUsers": { - "type": "array", - "description": "Key-value pairs with cluster names as keys and lists of users with the highest number of records per cluster as values.", - "items": { - "$ref": "#/components/schemas/clusterName" - } - } - }, - "required": ["topUsers"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/clusters/mapping/search": { - "post": { - "tags": ["search"], - "operationId": "searchUserIds", - "deprecated": true, - "x-use-read-transporter": true, - "x-cacheable": true, - "x-acl": ["admin"], - "summary": "Search for user IDs", - "description": "Since it can take a few seconds to get the data from the different clusters,\nthe response isn't real-time.\n\nTo ensure rapid updates, the user IDs index isn't built at the same time as the mapping. Instead, it's built every 12 hours, at the same time as the update of user ID usage. For example, if you add or move a user ID, the search will show an old value until the next time the mapping is rebuilt (every 12 hours).\n", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "searchUserIdsParams", - "type": "object", - "description": "OK", - "additionalProperties": false, - "properties": { - "query": { - "type": "string", - "description": "Query to search. The search is a prefix search with [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/) enabled. An empty query will retrieve all users." - }, - "clusterName": { - "$ref": "#/components/schemas/clusterName" - }, - "page": { - "$ref": "#/components/schemas/page" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/hitsPerPage" - } - }, - "required": ["query"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "searchUserIdsResponse", - "type": "object", - "description": "userIDs data.", - "properties": { - "hits": { - "type": "array", - "description": "User objects that match the query.", - "items": { - "title": "userHit", - "type": "object", - "properties": { - "userID": { - "$ref": "#/components/schemas/userID" - }, - "clusterName": { - "$ref": "#/components/schemas/clusterName" - }, - "nbRecords": { - "$ref": "#/components/schemas/nbRecords" - }, - "dataSize": { - "$ref": "#/components/schemas/dataSize" - }, - "objectID": { - "type": "string", - "description": "userID of the requested user. Same as userID." - }, - "_highlightResult": { - "title": "userHighlightResult", - "type": "object", - "properties": { - "userID": { - "$ref": "#/components/schemas/highlightResult" - }, - "clusterName": { - "$ref": "#/components/schemas/highlightResult" - } - }, - "required": ["userID", "clusterName"] - } - }, - "required": [ - "userID", - "clusterName", - "nbRecords", - "dataSize", - "objectID", - "_highlightResult" - ] - } - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - }, - "page": { - "$ref": "#/components/schemas/page" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/parameters_hitsPerPage" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - }, - "required": ["hits", "nbHits", "page", "hitsPerPage", "updatedAt"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/clusters/mapping/pending": { - "get": { - "tags": ["search"], - "operationId": "hasPendingMappings", - "deprecated": true, - "x-acl": ["admin"], - "summary": "Get migration and user mapping status", - "description": "To determine when the time-consuming process of creating a large batch of users or migrating users from one cluster to another is complete, this operation retrieves the status of the process.\n", - "parameters": [ - { - "in": "query", - "name": "getClusters", - "description": "Whether to include the cluster's pending mapping state in the response.", - "schema": { - "type": "boolean" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "hasPendingMappingsResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "pending": { - "description": "Whether there are clusters undergoing migration, creation, or deletion.", - "type": "boolean" - }, - "clusters": { - "description": "Cluster pending mapping state: migrating, creating, deleting.\n", - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "required": ["pending"] - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/security/sources": { - "get": { - "tags": ["search"], - "operationId": "getSources", - "x-acl": ["admin"], - "summary": "List allowed sources", - "description": "Retrieves all allowed IP addresses with access to your application.", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/sources" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - }, - "put": { - "tags": ["search"], - "operationId": "replaceSources", - "x-acl": ["admin"], - "summary": "Replace allowed sources", - "description": "Replaces the list of allowed sources.", - "requestBody": { - "required": true, - "description": "Allowed sources.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/sources" - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "replaceSourceResponse", - "type": "object", - "additionalProperties": false, - "required": ["updatedAt"], - "properties": { - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/security/sources/append": { - "post": { - "tags": ["search"], - "operationId": "appendSource", - "x-acl": ["admin"], - "description": "Adds a source to the list of allowed sources.", - "summary": "Add a source", - "requestBody": { - "required": true, - "description": "Source to add.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/source" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/CreatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/security/sources/{source}": { - "delete": { - "tags": ["search"], - "operationId": "deleteSecuritySource", - "x-acl": ["admin"], - "description": "Deletes a source from the list of allowed sources.", - "summary": "Delete a source", - "parameters": [ - { - "name": "source", - "in": "path", - "required": true, - "description": "IP address range of the source.", - "schema": { - "type": "string", - "example": "10.0.0.1/32" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "deleteSourceResponse", - "type": "object", - "additionalProperties": false, - "required": ["deletedAt"], - "properties": { - "deletedAt": { - "$ref": "#/components/schemas/deletedAt" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/logs": { - "get": { - "tags": ["search"], - "operationId": "getLogs", - "x-acl": ["logs"], - "description": "The request must be authenticated by an API key with the [`logs` ACL](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl).\n\n- Logs are held for the last seven days.\n- Up to 1,000 API requests per server are logged.\n- This request counts towards your [operations quota](https://support.algolia.com/hc/en-us/articles/4406981829777-How-does-Algolia-count-records-and-operations-) but doesn't appear in the logs itself.\n", - "summary": "Retrieve log entries", - "parameters": [ - { - "name": "offset", - "in": "query", - "description": "First log entry to retrieve. The most recent entries are listed first.", - "schema": { - "type": "integer", - "default": 0 - } - }, - { - "name": "length", - "in": "query", - "description": "Maximum number of entries to retrieve.", - "schema": { - "type": "integer", - "default": 10, - "maximum": 1000 - } - }, - { - "name": "indexName", - "in": "query", - "description": "Index for which to retrieve log entries.\nBy default, log entries are retrieved for all indices.\n", - "example": "products", - "schema": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - { - "name": "type", - "in": "query", - "description": "Type of log entries to retrieve.\nBy default, all log entries are retrieved.\n", - "schema": { - "$ref": "#/components/schemas/logType" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "getLogsResponse", - "type": "object", - "additionalProperties": false, - "required": ["logs"], - "properties": { - "logs": { - "type": "array", - "items": { - "title": "log", - "type": "object", - "properties": { - "timestamp": { - "type": "string", - "description": "Date and time of the API request, in RFC 3339 format.", - "example": "2023-03-08T12:34:56Z" - }, - "method": { - "type": "string", - "description": "HTTP method of the request.", - "example": "GET" - }, - "answer_code": { - "type": "string", - "description": "HTTP status code of the response.", - "example": "200" - }, - "query_body": { - "type": "string", - "maxLength": 1000, - "description": "Request body.", - "example": "{\\n \\\"requests\\\": [\\n {\\n \\\"indexName\\\": \\\"best_buy\\\",\\n \\\"params\\\": \\\"query=&hitsPerPage=10&page=0&attributesToRetrieve=*&highlightPreTag=%3Cais-highlight-0000000000%3E&highlightPostTag=%3C%2Fais-highlight-0000000000%3E&getRankingInfo=1&facets=%5B%22brand%22%2C%22categories%22%2C%22free_shipping%22%2C%22type%22%5D&tagFilters=\\\"\\n }\\n ]\\n}\\n" - }, - "answer": { - "type": "string", - "maxLength": 1000, - "description": "Response body.", - "example": "'n{\\n \"results\": [\\n {\\n \"hits\": [\\n {\\n \"name\": \"Amazon - Fire TV Stick\",\\n \"description\": \"Amazon Fire TV Stick connects to your TV's HDMI port. Just grab and go to enjoy Netflix, Prime Instant Video, Hulu Plus, YouTube.com, music, and much more.\",\\n \"brand\": \"Amazon\",\\n \"categories\": [\\n \"TV & Home Theater\",\\n \"Streaming Media Players\"\\n ],\\n \"hierarchicalCategories\": {\\n \"lvl0\": \"TV & Home Theater\",\\n \"lvl1\": \"TV & Home Theater > Streaming Media Players\"\\n },\\n \"type\": \"Streaming media player\",\\n \"price\": 39.99,\\n \"price_range\": \"1 }\\n ]\\n }\\n ]\\n}'\n" - }, - "url": { - "type": "string", - "format": "uri-reference", - "description": "URL of the API endpoint.", - "example": "/1/indexes" - }, - "ip": { - "type": "string", - "format": "ipv4", - "description": "IP address of the client that performed the request.", - "example": "93.184.216.34" - }, - "query_headers": { - "type": "string", - "description": "Request headers (API keys are obfuscated).", - "example": "User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5\\nHost: example.com\\nAccept: */*\\nContent-Type: application/json; charset=utf-8\\nX-Algolia-API-Key: 20f***************************\\nX-Algolia-Application-Id: MyApplicationID\\n" - }, - "sha1": { - "type": "string", - "description": "SHA1 signature of the log entry.", - "example": "26c53bd7e38ca71f4741b71994cd94a600b7ac68" - }, - "nb_api_calls": { - "type": "string", - "description": "Number of API requests.", - "example": "1" - }, - "processing_time_ms": { - "type": "string", - "description": "Processing time for the query in milliseconds.\nThis doesn't include latency due to the network.\n", - "example": "2" - }, - "index": { - "type": "string", - "description": "Index targeted by the query.", - "example": "products" - }, - "query_params": { - "type": "string", - "description": "Query parameters sent with the request.", - "example": "query=georgia&attributesToRetrieve=name,city,country" - }, - "query_nb_hits": { - "type": "string", - "description": "Number of search results (hits) returned for the query.", - "example": "1" - }, - "inner_queries": { - "type": "array", - "description": "Queries performed for the given request.", - "items": { - "title": "logQuery", - "type": "object", - "properties": { - "index_name": { - "type": "string", - "description": "Index targeted by the query.", - "example": "products" - }, - "user_token": { - "type": "string", - "description": "A user identifier.", - "example": "93.189.166.128" - }, - "query_id": { - "type": "string", - "description": "Unique query identifier.", - "example": "96f59a3145dd9bd8963dc223950507c8" - } - } - } - } - }, - "required": [ - "timestamp", - "method", - "answer_code", - "query_body", - "answer", - "url", - "ip", - "query_headers", - "sha1", - "processing_time_ms" - ] - } - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/task/{taskID}": { - "get": { - "tags": ["search"], - "operationId": "getAppTask", - "x-acl": ["editSettings"], - "description": "Checks the status of a given application task.\n", - "summary": "Check application task status", - "parameters": [ - { - "name": "taskID", - "in": "path", - "description": "Unique task identifier.", - "required": true, - "schema": { - "type": "integer", - "format": "int64", - "example": 1506303845001 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetTaskResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - } - } - } - }, - "/1/indexes/{indexName}/task/{taskID}": { - "get": { - "tags": ["search"], - "operationId": "getTask", - "x-acl": ["addObject"], - "description": "Checks the status of a given task.\n\nIndexing tasks are asynchronous.\nWhen you add, update, or delete records or indices,\na task is created on a queue and completed depending on the load on the server.\n\nThe indexing tasks' responses include a task ID that you can use to check the status.\n", - "summary": "Check task status", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - }, - { - "name": "taskID", - "in": "path", - "description": "Unique task identifier.", - "required": true, - "schema": { - "type": "integer", - "format": "int64", - "example": 1506303845001 - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetTaskResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes/{indexName}/operation": { - "post": { - "tags": ["search"], - "operationId": "operationIndex", - "x-acl": ["addObject"], - "summary": "Copy or move an index", - "description": "Copies or moves (renames) an index within the same Algolia application.\n\n- Existing destination indices are overwritten, except for their analytics data.\n- If the destination index doesn't exist yet, it'll be created.\n- This operation is resource-intensive.\n\n**Copy**\n\n- Copying a source index that doesn't exist creates a new index with 0 records and default settings.\n- The API keys of the source index are merged with the existing keys in the destination index.\n- You can't copy the `enableReRanking`, `mode`, and `replicas` settings.\n- You can't copy to a destination index that already has replicas.\n- Be aware of the [size limits](https://www.algolia.com/doc/guides/scaling/algolia-service-limits/#application-record-and-index-limits).\n- Related guide: [Copy indices](https://www.algolia.com/doc/guides/sending-and-managing-data/manage-indices-and-apps/manage-indices/how-to/copy-indices/)\n\n**Move**\n\n- Moving a source index that doesn't exist is ignored without returning an error.\n- When moving an index, the analytics data keeps its original name, and a new set of analytics data is started for the new name.\n To access the original analytics in the dashboard, create an index with the original name.\n- If the destination index has replicas, moving will overwrite the existing index and copy the data to the replica indices.\n- Related guide: [Move indices](https://www.algolia.com/doc/guides/sending-and-managing-data/manage-indices-and-apps/manage-indices/how-to/move-indices/).\n\nThis operation is subject to [indexing rate limits](https://support.algolia.com/hc/en-us/articles/4406975251089-Is-there-a-rate-limit-for-indexing-on-Algolia).\n", - "parameters": [ - { - "$ref": "#/components/parameters/IndexName" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "title": "operationIndexParams", - "type": "object", - "additionalProperties": false, - "properties": { - "operation": { - "$ref": "#/components/schemas/operationType" - }, - "destination": { - "$ref": "#/components/schemas/indexName" - }, - "scope": { - "type": "array", - "items": { - "$ref": "#/components/schemas/scopeType" - }, - "description": "**Only for copying.**\n\nIf you specify a scope, only the selected scopes are copied. Records and the other scopes are left unchanged.\nIf you omit the `scope` parameter, everything is copied: records, settings, synonyms, and rules.\n" - } - }, - "required": ["operation", "destination"] - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/UpdatedAt" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/1/indexes": { - "get": { - "tags": ["search"], - "operationId": "listIndices", - "x-acl": ["listIndexes"], - "summary": "List indices", - "description": "Lists all indices in the current Algolia application.\n\nThe request follows any index restrictions of the API key you use to make the request.\n", - "parameters": [ - { - "$ref": "#/components/parameters/Page" - }, - { - "$ref": "#/components/parameters/HitsPerPage" - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/listIndicesResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "402": { - "$ref": "#/components/responses/FeatureNotEnabled" - }, - "403": { - "$ref": "#/components/responses/MethodNotAllowed" - }, - "404": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/waitForApiKey": { - "get": { - "x-helper": true, - "tags": ["search"], - "operationId": "waitForApiKey", - "summary": "Wait for an API key operation", - "description": "Waits for an API key to be added, updated, or deleted.", - "parameters": [ - { - "in": "query", - "name": "key", - "description": "API key to wait for.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "operation", - "description": "Whether the API key was created, updated, or deleted.", - "required": true, - "schema": { - "$ref": "#/components/schemas/apiKeyOperation" - } - }, - { - "in": "query", - "name": "apiKey", - "description": "Used to compare fields of the `getApiKey` response on an `update` operation, to check if the `key` has been updated.", - "required": false, - "schema": { - "$ref": "#/components/schemas/apiKey" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/getApiKeyResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/waitForTask": { - "get": { - "x-helper": true, - "tags": ["search"], - "operationId": "waitForTask", - "summary": "Wait for operation to complete", - "description": "Wait for a task to complete to ensure synchronized index updates.\n\nAll Algolia write operations are asynchronous. When you make a request for a write operation, for example, to add or update records in your index, Algolia creates a task on a queue and returns a taskID. The task itself runs separately, depending on the server load.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The name of the index on which the operation was performed.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "taskID", - "description": "The taskID returned by the operation.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetTaskResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/waitForAppTask": { - "get": { - "x-helper": true, - "operationId": "waitForAppTask", - "summary": "Wait for application-level operation to complete", - "description": "Wait for a application-level task to complete.", - "parameters": [ - { - "in": "query", - "name": "taskID", - "description": "The taskID returned by the operation.", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetTaskResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - }, - "tags": ["search"] - } - }, - "/browseObjects": { - "get": { - "x-helper": true, - "tags": ["search"], - "operationId": "browseObjects", - "summary": "Get all records from an index", - "description": "You can use the browse method to get records from an index—for example, to export your index as a backup. To export all records, use an empty query.\n\nUse browse instead of search when exporting records from your index, when ranking, or analytics, isn't important. The Analytics API doesn't collect data when using browse.\n\nDon't use this method for building a search UI. Use search instead.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The name of the index on which the operation was performed.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "browseParams", - "description": "Browse parameters.", - "required": true, - "schema": { - "$ref": "#/components/schemas/browseParamsObject" - } - } - ], - "responses": { - "204": { - "description": "No content." - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/generateSecuredApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["search"], - "operationId": "generateSecuredApiKey", - "summary": "Create secured API keys", - "description": "Generates a secured API key without any requests to Algolia's servers.\n\nSecured API keys are API keys that you generate on your server without any API request to Algolia.\nSecured API keys help in environments where you can't easily update the client-side code, such as mobile apps,\nor when you need to restrict access to a part of your index for every user.\n\nWhen your users start searching, instead of using the Search API key, they request a short-lived secured API key from your server.\nOn your server, you use this method to create a secured API key, with any restrictions you'd like, such as filters, index access restrictions,\nor expiration times. The API key gets longer the more restrictions you add.\nYour users then use the secured API key to search with Algolia.\n\nYou can't create secured API keys from other secured API keys or from your Admin API key.\nThe generated API key can have the same restrictions as the parent API key, or be more restrictive.\n", - "parameters": [ - { - "in": "query", - "name": "parentApiKey", - "description": "API key from which the secured API key will inherit its restrictions.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "restrictions", - "description": "Restrictions to add to the API key.", - "required": true, - "schema": { - "$ref": "#/components/schemas/securedApiKeyRestrictions" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/replaceAllObjects": { - "get": { - "x-helper": true, - "tags": ["search"], - "operationId": "replaceAllObjects", - "summary": "Replace all records in an index", - "description": "Replace all records from your index with a new set of records.\n\nThis method lets you replace all records in your index without downtime. It performs these operations:\n 1. Copy settings, synonyms, and rules from your original index to a temporary index.\n 2. Add your new records to the temporary index.\n 3. Replace your original index with the temporary index.\n\nUse the safe parameter to ensure that these (asynchronous) operations are performed in sequence.\nIf there's an error duing one of these steps, the temporary index won't be deleted.\nThis operation is rate-limited.\nThis method creates a temporary index: your record count is temporarily doubled. Algolia doesn't count the three days with the highest number of records towards your monthly usage.\nIf you're on a legacy plan (before July 2020), this method counts two operations towards your usage (in addition to the number of records): copySettings and moveIndex.\nThe API key you use for this operation must have access to the index YourIndex and the temporary index YourIndex_tmp.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The `indexName` to replace `objects` in.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "objects", - "description": "List of objects to replace the current objects with.", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "object" - } - } - }, - { - "in": "query", - "name": "batchSize", - "description": "The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.", - "required": false, - "schema": { - "type": "integer", - "default": 1000 - } - }, - { - "in": "query", - "name": "scopes", - "description": "List of scopes to kepp in the index. Defaults to `settings`, `synonyms`, and `rules`.", - "required": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/scopeType" - } - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/replaceAllObjectsResponse" - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/chunkedBatch": { - "get": { - "x-helper": true, - "tags": ["search"], - "operationId": "chunkedBatch", - "summary": "Replace all records in an index", - "description": "Helper: Chunks the given `objects` list in subset of 1000 elements max in order to make it fit in `batch` requests.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The `indexName` to replace `objects` in.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "objects", - "description": "List of objects to replace the current objects with.", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "object" - } - } - }, - { - "in": "query", - "name": "action", - "description": "The `batch` `action` to perform on the given array of `objects`, defaults to `addObject`.", - "required": false, - "schema": { - "$ref": "#/components/schemas/action" - } - }, - { - "in": "query", - "name": "waitForTasks", - "description": "Whether or not we should wait until every `batch` tasks has been processed, this operation may slow the total execution time of this method but is more reliable.", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "in": "query", - "name": "batchSize", - "description": "The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.", - "required": false, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/batchResponse" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/saveObjects": { - "get": { - "x-helper": true, - "tags": ["search"], - "operationId": "saveObjects", - "summary": "Saves the given array of objects in the given index", - "description": "Helper: Saves the given array of objects in the given index. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objects in it.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The `indexName` to save `objects` into.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "objects", - "description": "The objects to save in the index.", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "object" - } - } - }, - { - "in": "query", - "name": "waitForTasks", - "description": "Whether or not we should wait until every `batch` tasks has been processed, this operation may slow the total execution time of this method but is more reliable.", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - }, - { - "in": "query", - "name": "batchSize", - "description": "The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.", - "required": false, - "schema": { - "type": "integer", - "default": 1000 - } - }, - { - "in": "query", - "name": "requestOptions", - "description": "The request options to pass to the `batch` method.", - "required": false, - "schema": { - "type": "object" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/batchResponse" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/deleteObjects": { - "post": { - "x-helper": true, - "tags": ["search"], - "operationId": "deleteObjects", - "summary": "Deletes every records for the given objectIDs", - "description": "Helper: Deletes every records for the given objectIDs. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objectIDs in it.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The `indexName` to delete `objectIDs` from.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "objectIDs", - "description": "The objectIDs to delete.", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - { - "in": "query", - "name": "waitForTasks", - "description": "Whether or not we should wait until every `batch` tasks has been processed, this operation may slow the total execution time of this method but is more reliable.", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "in": "query", - "name": "batchSize", - "description": "The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.", - "required": false, - "schema": { - "type": "integer" - } - }, - { - "in": "query", - "name": "requestOptions", - "description": "The request options to pass to the `batch` method.", - "required": false, - "schema": { - "type": "object" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/batchResponse" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/partialUpdateObjects": { - "post": { - "x-helper": true, - "tags": ["search"], - "operationId": "partialUpdateObjects", - "summary": "Replaces object content of all the given objects according to their respective `objectID` field", - "description": "Helper: Replaces object content of all the given objects according to their respective `objectID` field. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objects in it.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The `indexName` where to update `objects`.", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "query", - "name": "objects", - "description": "The objects to update.", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "object" - } - } - }, - { - "in": "query", - "name": "createIfNotExists", - "description": "To be provided if non-existing objects are passed, otherwise, the call will fail.", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - }, - { - "in": "query", - "name": "waitForTasks", - "description": "Whether or not we should wait until every `batch` tasks has been processed, this operation may slow the total execution time of this method but is more reliable.", - "required": false, - "schema": { - "type": "boolean", - "default": false - } - }, - { - "in": "query", - "name": "batchSize", - "description": "The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000.", - "required": false, - "schema": { - "type": "integer", - "default": 1000 - } - }, - { - "in": "query", - "name": "requestOptions", - "description": "The request options to pass to the `batch` method.", - "required": false, - "schema": { - "type": "object" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/batchResponse" - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/IndexNotFound" - } - } - } - }, - "/indexExists": { - "get": { - "x-helper": true, - "tags": ["search"], - "operationId": "indexExists", - "summary": "Check if an index exists or not", - "description": "You can initialize an index with any name. The index is created on Algolia's servers when you add objects or set settings. To prevent accidentally creating new indices, or changing existing indices, you can use the exists method. The exists method returns a boolean that indicates whether an initialized index has been created.\n", - "parameters": [ - { - "in": "query", - "name": "indexName", - "description": "The name of the index to check.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Index exists.", - "content": { - "application/json": { - "schema": { - "type": "boolean" - } - } - } - } - } - } - }, - "/setClientApiKey": { - "get": { - "x-helper": true, - "x-asynchronous-helper": false, - "tags": ["search"], - "operationId": "setClientApiKey", - "summary": "Switch the API key used to authenticate requests", - "description": "Switch the API key used to authenticate requests.\n", - "parameters": [ - { - "in": "query", - "name": "apiKey", - "description": "API key to be used from now on.", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No content." - } - } - } - } - }, - "components": { - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-application-id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-api-key", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - }, - "schemas": { - "attributeToUpdate": { - "x-keep-model": true, - "deprecated": true, - "oneOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/builtInOperation" - } - ] - }, - "ErrorBase": { - "description": "Error.", - "type": "object", - "x-keep-model": true, - "additionalProperties": true, - "properties": { - "message": { - "type": "string", - "example": "Invalid Application-Id or API-Key" - } - } - }, - "paramsAsString": { - "description": "Search parameters as a URL-encoded query string.", - "example": "hitsPerPage=2&getRankingInfo=1", - "type": "string", - "default": "" - }, - "searchParamsString": { - "type": "object", - "title": "Search parameters as query string.", - "description": "Search parameters as query string.", - "additionalProperties": false, - "x-discriminator-fields": ["params"], - "properties": { - "params": { - "$ref": "#/components/schemas/paramsAsString" - } - }, - "required": ["params"] - }, - "query": { - "type": "string", - "description": "Search query.", - "default": "", - "x-categories": ["Search"] - }, - "searchParamsQuery": { - "type": "object", - "properties": { - "query": { - "$ref": "#/components/schemas/query" - } - } - }, - "filters": { - "type": "string", - "description": "Filter expression to only include items that match the filter criteria in the response.\n\nYou can use these filter expressions:\n\n- **Numeric filters.** ` `, where `` is one of `<`, `<=`, `=`, `!=`, `>`, `>=`.\n- **Ranges.** `: TO ` where `` and `` are the lower and upper limits of the range (inclusive).\n- **Facet filters.** `:` where `` is a facet attribute (case-sensitive) and `` a facet value.\n- **Tag filters.** `_tags:` or just `` (case-sensitive).\n- **Boolean filters.** `: true | false`.\n\nYou can combine filters with `AND`, `OR`, and `NOT` operators with the following restrictions:\n\n- You can only combine filters of the same type with `OR`.\n **Not supported:** `facet:value OR num > 3`.\n- You can't use `NOT` with combinations of filters.\n **Not supported:** `NOT(facet:value OR facet:value)`\n- You can't combine conjunctions (`AND`) with `OR`.\n **Not supported:** `facet:value OR (facet:value AND facet:value)`\n\nUse quotes around your filters, if the facet attribute name or facet value has spaces, keywords (`OR`, `AND`, `NOT`), or quotes.\nIf a facet attribute is an array, the filter matches if it matches at least one element of the array.\n\nFor more information, see [Filters](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/).\n", - "example": "(category:Book OR category:Ebook) AND _tags:published", - "x-categories": ["Filtering"] - }, - "facetFilters": { - "description": "Filter the search by facet values, so that only records with the same facet values are retrieved.\n\n**Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.**\n\n- `[filter1, filter2]` is interpreted as `filter1 AND filter2`.\n- `[[filter1, filter2], filter3]` is interpreted as `filter1 OR filter2 AND filter3`.\n- `facet:-value` is interpreted as `NOT facet:value`.\n\nWhile it's best to avoid attributes that start with a `-`, you can still filter them by escaping with a backslash:\n`facet:\\-value`.\n", - "example": [["category:Book", "category:-Movie"], "author:John Doe"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/facetFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "optionalFilters": { - "description": "Filters to promote or demote records in the search results.\n\nOptional filters work like facet filters, but they don't exclude records from the search results.\nRecords that match the optional filter rank before records that don't match.\nIf you're using a negative filter `facet:-value`, matching records rank after records that don't match.\n\n- Optional filters don't work on virtual replicas.\n- Optional filters are applied _after_ sort-by attributes.\n- Optional filters are applied _before_ custom ranking attributes (in the default [ranking](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/)).\n- Optional filters don't work with numeric attributes.\n", - "example": ["category:Book", "author:John Doe"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/optionalFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "numericFilters": { - "description": "Filter by numeric facets.\n\n**Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.**\n\nYou can use numeric comparison operators: `<`, `<=`, `=`, `!=`, `>`, `>=`.\nComparisons are precise up to 3 decimals.\nYou can also provide ranges: `facet: TO `. The range includes the lower and upper boundaries.\nThe same combination rules apply as for `facetFilters`.\n", - "example": [["inStock = 1", "deliveryDate < 1441755506"], "price < 1000"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/numericFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "tagFilters": { - "description": "Filter the search by values of the special `_tags` attribute.\n\n**Prefer using the `filters` parameter, which supports all filter types and combinations with boolean operators.**\n\nDifferent from regular facets, `_tags` can only be used for filtering (including or excluding records).\nYou won't get a facet count.\nThe same combination and escaping rules apply as for `facetFilters`.\n", - "example": [["Book", "Movie"], "SciFi"], - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/tagFilters" - } - }, - { - "type": "string" - } - ], - "x-categories": ["Filtering"] - }, - "page": { - "type": "integer", - "description": "Page of search results to retrieve.", - "default": 0, - "minimum": 0, - "x-categories": ["Pagination"] - }, - "aroundLatLng": { - "type": "string", - "description": "Coordinates for the center of a circle, expressed as a comma-separated string of latitude and longitude.\n\nOnly records included within a circle around this central location are included in the results.\nThe radius of the circle is determined by the `aroundRadius` and `minimumAroundRadius` settings.\nThis parameter is ignored if you also specify `insidePolygon` or `insideBoundingBox`.\n", - "example": "40.71,-74.01", - "default": "", - "x-categories": ["Geo-Search"] - }, - "aroundLatLngViaIP": { - "type": "boolean", - "description": "Whether to obtain the coordinates from the request's IP address.", - "default": false, - "x-categories": ["Geo-Search"] - }, - "aroundRadiusAll": { - "title": "all", - "type": "string", - "description": "Return all records with a valid `_geoloc` attribute. Don't filter by distance.", - "enum": ["all"] - }, - "aroundRadius": { - "description": "Maximum radius for a search around a central location.\n\nThis parameter works in combination with the `aroundLatLng` and `aroundLatLngViaIP` parameters.\nBy default, the search radius is determined automatically from the density of hits around the central location.\nThe search radius is small if there are many hits close to the central coordinates.\n", - "oneOf": [ - { - "type": "integer", - "minimum": 1, - "description": "Maximum search radius around a central location in meters." - }, - { - "$ref": "#/components/schemas/aroundRadiusAll" - } - ], - "x-categories": ["Geo-Search"] - }, - "aroundPrecisionFromValue": { - "title": "range objects", - "type": "array", - "items": { - "title": "range", - "type": "object", - "description": "Range object with lower and upper values in meters to define custom ranges.", - "properties": { - "from": { - "type": "integer", - "description": "Lower boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal.", - "example": 20 - }, - "value": { - "type": "integer", - "description": "Upper boundary of a range in meters. The Geo ranking criterion considers all records within the range to be equal." - } - } - } - }, - "aroundPrecision": { - "description": "Precision of a coordinate-based search in meters to group results with similar distances.\n\nThe Geo ranking criterion considers all matches within the same range of distances to be equal.\n", - "oneOf": [ - { - "type": "integer", - "default": 10, - "description": "Distance in meters to group results by similar distances.\n\nFor example, if you set `aroundPrecision` to 100, records wihin 100 meters to the central coordinate are considered to have the same distance,\nas are records between 100 and 199 meters.\n" - }, - { - "$ref": "#/components/schemas/aroundPrecisionFromValue" - } - ], - "x-categories": ["Geo-Search"] - }, - "insideBoundingBoxArray": { - "type": "array", - "items": { - "type": "array", - "minItems": 4, - "maxItems": 4, - "items": { - "type": "number", - "format": "double" - } - }, - "description": "Coordinates for a rectangular area in which to search.\n\nEach bounding box is defined by the two opposite points of its diagonal, and expressed as latitude and longitude pair:\n`[p1 lat, p1 long, p2 lat, p2 long]`.\nProvide multiple bounding boxes as nested arrays.\nFor more information, see [rectangular area](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas).\n", - "example": [ - [47.3165, 4.9665, 47.3424, 5.0201], - [40.9234, 2.1185, 38.643, 1.9916] - ], - "x-categories": ["Geo-Search"] - }, - "insideBoundingBox": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "null" - }, - { - "$ref": "#/components/schemas/insideBoundingBoxArray" - } - ] - }, - "insidePolygon": { - "type": "array", - "items": { - "type": "array", - "minItems": 6, - "maxItems": 20000, - "items": { - "type": "number", - "format": "double" - } - }, - "description": "Coordinates of a polygon in which to search.\n\nPolygons are defined by 3 to 10,000 points. Each point is represented by its latitude and longitude.\nProvide multiple polygons as nested arrays.\nFor more information, see [filtering inside polygons](https://www.algolia.com/doc/guides/managing-results/refine-results/geolocation/#filtering-inside-rectangular-or-polygonal-areas).\nThis parameter is ignored if you also specify `insideBoundingBox`.\n", - "example": [ - [47.3165, 4.9665, 47.3424, 5.0201, 47.32, 4.9], - [40.9234, 2.1185, 38.643, 1.9916, 39.2587, 2.0104] - ], - "x-categories": ["Geo-Search"] - }, - "supportedLanguage": { - "type": "string", - "description": "ISO code for a supported language.", - "enum": [ - "af", - "ar", - "az", - "bg", - "bn", - "ca", - "cs", - "cy", - "da", - "de", - "el", - "en", - "eo", - "es", - "et", - "eu", - "fa", - "fi", - "fo", - "fr", - "ga", - "gl", - "he", - "hi", - "hu", - "hy", - "id", - "is", - "it", - "ja", - "ka", - "kk", - "ko", - "ku", - "ky", - "lt", - "lv", - "mi", - "mn", - "mr", - "ms", - "mt", - "nb", - "nl", - "no", - "ns", - "pl", - "ps", - "pt", - "pt-br", - "qu", - "ro", - "ru", - "sk", - "sq", - "sv", - "sw", - "ta", - "te", - "th", - "tl", - "tn", - "tr", - "tt", - "uk", - "ur", - "uz", - "zh" - ] - }, - "userToken": { - "type": "string", - "description": "Unique pseudonymous or anonymous user identifier.\n\nThis helps with analytics and click and conversion events.\nFor more information, see [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/).\n", - "example": "test-user-123", - "x-categories": ["Personalization"] - }, - "baseSearchParamsWithoutQuery": { - "type": "object", - "properties": { - "similarQuery": { - "type": "string", - "description": "Keywords to be used instead of the search query to conduct a more broader search.\n\nUsing the `similarQuery` parameter changes other settings:\n\n- `queryType` is set to `prefixNone`.\n- `removeStopWords` is set to true.\n- `words` is set as the first ranking criterion.\n- All remaining words are treated as `optionalWords`.\n\nSince the `similarQuery` is supposed to do a broad search, they usually return many results.\nCombine it with `filters` to narrow down the list of results.\n", - "default": "", - "example": "comedy drama crime Macy Buscemi", - "x-categories": ["Search"] - }, - "filters": { - "$ref": "#/components/schemas/filters" - }, - "facetFilters": { - "$ref": "#/components/schemas/facetFilters" - }, - "optionalFilters": { - "$ref": "#/components/schemas/optionalFilters" - }, - "numericFilters": { - "$ref": "#/components/schemas/numericFilters" - }, - "tagFilters": { - "$ref": "#/components/schemas/tagFilters" - }, - "sumOrFiltersScores": { - "type": "boolean", - "description": "Whether to sum all filter scores.\n\nIf true, all filter scores are summed.\nOtherwise, the maximum filter score is kept.\nFor more information, see [filter scores](https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/#accumulating-scores-with-sumorfiltersscores).\n", - "default": false, - "x-categories": ["Filtering"] - }, - "restrictSearchableAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["title", "author"], - "description": "Restricts a search to a subset of your searchable attributes.\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Filtering"] - }, - "facets": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Facets for which to retrieve facet values that match the search criteria and the number of matching facet values.\n\nTo retrieve all facets, use the wildcard character `*`.\nFor more information, see [facets](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#contextual-facet-values-and-counts).\n", - "default": [], - "example": ["*"], - "x-categories": ["Faceting"] - }, - "facetingAfterDistinct": { - "type": "boolean", - "description": "Whether faceting should be applied after deduplication with `distinct`.\n\nThis leads to accurate facet counts when using faceting in combination with `distinct`.\nIt's usually better to use `afterDistinct` modifiers in the `attributesForFaceting` setting,\nas `facetingAfterDistinct` only computes correct facet counts if all records have the same facet values for the `attributeForDistinct`.\n", - "default": false, - "x-categories": ["Faceting"] - }, - "page": { - "$ref": "#/components/schemas/page" - }, - "offset": { - "type": "integer", - "description": "Position of the first hit to retrieve.", - "x-categories": ["Pagination"] - }, - "length": { - "type": "integer", - "description": "Number of hits to retrieve (used in combination with `offset`).", - "minimum": 0, - "maximum": 1000, - "x-categories": ["Pagination"] - }, - "aroundLatLng": { - "$ref": "#/components/schemas/aroundLatLng" - }, - "aroundLatLngViaIP": { - "$ref": "#/components/schemas/aroundLatLngViaIP" - }, - "aroundRadius": { - "$ref": "#/components/schemas/aroundRadius" - }, - "aroundPrecision": { - "$ref": "#/components/schemas/aroundPrecision" - }, - "minimumAroundRadius": { - "type": "integer", - "description": "Minimum radius (in meters) for a search around a location when `aroundRadius` isn't set.", - "minimum": 1, - "x-categories": ["Geo-Search"] - }, - "insideBoundingBox": { - "$ref": "#/components/schemas/insideBoundingBox" - }, - "insidePolygon": { - "$ref": "#/components/schemas/insidePolygon" - }, - "naturalLanguages": { - "type": "array", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - }, - "description": "ISO language codes that adjust settings that are useful for processing natural language queries (as opposed to keyword searches):\n\n- Sets `removeStopWords` and `ignorePlurals` to the list of provided languages.\n- Sets `removeWordsIfNoResults` to `allOptional`.\n- Adds a `natural_language` attribute to `ruleContexts` and `analyticsTags`.\n", - "default": [], - "x-categories": ["Languages"] - }, - "ruleContexts": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Assigns a rule context to the search query.\n\n[Rule contexts](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/how-to/customize-search-results-by-platform/#whats-a-context) are strings that you can use to trigger matching rules.\n", - "default": [], - "example": ["mobile"], - "x-categories": ["Rules"] - }, - "personalizationImpact": { - "type": "integer", - "description": "Impact that Personalization should have on this search.\n\nThe higher this value is, the more Personalization determines the ranking compared to other factors.\nFor more information, see [Understanding Personalization impact](https://www.algolia.com/doc/guides/personalization/personalizing-results/in-depth/configuring-personalization/#understanding-personalization-impact).\n", - "default": 100, - "minimum": 0, - "maximum": 100, - "x-categories": ["Personalization"] - }, - "userToken": { - "$ref": "#/components/schemas/userToken" - }, - "getRankingInfo": { - "type": "boolean", - "description": "Whether the search response should include detailed ranking information.", - "default": false, - "x-categories": ["Advanced"] - }, - "synonyms": { - "type": "boolean", - "description": "Whether to take into account an index's synonyms for this search.", - "default": true, - "x-categories": ["Advanced"] - }, - "clickAnalytics": { - "type": "boolean", - "description": "Whether to include a `queryID` attribute in the response.\n\nThe query ID is a unique identifier for a search query and is required for tracking [click and conversion events](https://www.algolia.com/guides/sending-events/getting-started/).\n", - "default": false, - "x-categories": ["Analytics"] - }, - "analytics": { - "type": "boolean", - "description": "Whether this search will be included in Analytics.", - "default": true, - "x-categories": ["Analytics"] - }, - "analyticsTags": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Tags to apply to the query for [segmenting analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/).", - "default": [], - "x-categories": ["Analytics"] - }, - "percentileComputation": { - "type": "boolean", - "description": "Whether to include this search when calculating processing-time percentiles.", - "default": true, - "x-categories": ["Advanced"] - }, - "enableABTest": { - "type": "boolean", - "description": "Whether to enable A/B testing for this search.", - "default": true, - "x-categories": ["Advanced"] - } - } - }, - "baseSearchParams": { - "allOf": [ - { - "$ref": "#/components/schemas/searchParamsQuery" - }, - { - "$ref": "#/components/schemas/baseSearchParamsWithoutQuery" - } - ] - }, - "hitsPerPage": { - "type": "integer", - "description": "Number of hits per page.", - "default": 20, - "minimum": 1, - "maximum": 1000, - "x-categories": ["Pagination"] - }, - "typoToleranceEnum": { - "type": "string", - "title": "typo tolerance", - "description": "- `min`. Return matches with the lowest number of typos.\n For example, if you have matches without typos, only include those.\n But if there are no matches without typos (with 1 typo), include matches with 1 typo (2 typos).\n- `strict`. Return matches with the two lowest numbers of typos.\n With `strict`, the Typo ranking criterion is applied first in the `ranking` setting.\n", - "enum": ["min", "strict"] - }, - "typoTolerance": { - "description": "Whether [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/) is enabled and how it is applied.\n\nIf typo tolerance is true, `min`, or `strict`, [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) are also active.\n", - "oneOf": [ - { - "type": "boolean", - "default": true, - "description": "Whether typo tolerance is active. If true, matches with typos are included in the search results and rank after exact matches." - }, - { - "$ref": "#/components/schemas/typoToleranceEnum" - } - ], - "x-categories": ["Typos"] - }, - "booleanString": { - "type": "string", - "enum": ["true", "false"] - }, - "ignorePlurals": { - "description": "Treat singular, plurals, and other forms of declensions as equivalent.\nYou should only use this feature for the languages used in your index.\n", - "example": ["ca", "es"], - "oneOf": [ - { - "type": "array", - "description": "ISO code for languages for which this feature should be active.\nThis overrides languages you set with `queryLanguages`.\n", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - } - }, - { - "$ref": "#/components/schemas/booleanString" - }, - { - "type": "boolean", - "description": "If true, `ignorePlurals` is active for all languages included in `queryLanguages`, or for all supported languages, if `queryLanguges` is empty.\nIf false, singulars, plurals, and other declensions won't be considered equivalent.\n", - "default": false - } - ], - "x-categories": ["Languages"] - }, - "removeStopWords": { - "description": "Removes stop words from the search query.\n\nStop words are common words like articles, conjunctions, prepositions, or pronouns that have little or no meaning on their own.\nIn English, \"the\", \"a\", or \"and\" are stop words.\n\nYou should only use this feature for the languages used in your index.\n", - "example": ["ca", "es"], - "oneOf": [ - { - "type": "array", - "description": "ISO code for languages for which stop words should be removed. This overrides languages you set in `queryLanguges`.", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - } - }, - { - "type": "boolean", - "default": false, - "description": "If true, stop words are removed for all languages you included in `queryLanguages`, or for all supported languages, if `queryLanguages` is empty.\nIf false, stop words are not removed.\n" - } - ], - "x-categories": ["Languages"] - }, - "queryType": { - "type": "string", - "enum": ["prefixLast", "prefixAll", "prefixNone"], - "description": "Determines if and how query words are interpreted as prefixes.\n\nBy default, only the last query word is treated as a prefix (`prefixLast`).\nTo turn off prefix search, use `prefixNone`.\nAvoid `prefixAll`, which treats all query words as prefixes.\nThis might lead to counterintuitive results and makes your search slower.\n\nFor more information, see [Prefix searching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/prefix-searching/).\n", - "default": "prefixLast", - "x-categories": ["Query strategy"] - }, - "removeWordsIfNoResults": { - "type": "string", - "enum": ["none", "lastWords", "firstWords", "allOptional"], - "example": "firstWords", - "description": "Strategy for removing words from the query when it doesn't return any results.\nThis helps to avoid returning empty search results.\n\n- `none`.\n No words are removed when a query doesn't return results.\n\n- `lastWords`.\n Treat the last (then second to last, then third to last) word as optional,\n until there are results or at most 5 words have been removed.\n\n- `firstWords`.\n Treat the first (then second, then third) word as optional,\n until there are results or at most 5 words have been removed.\n\n- `allOptional`.\n Treat all words as optional.\n\nFor more information, see [Remove words to improve results](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/in-depth/why-use-remove-words-if-no-results/).\n", - "default": "none", - "x-categories": ["Query strategy"] - }, - "mode": { - "type": "string", - "enum": ["neuralSearch", "keywordSearch"], - "description": "Search mode the index will use to query for results.\n\nThis setting only applies to indices, for which Algolia enabled NeuralSearch for you.\n", - "default": "keywordSearch", - "x-categories": ["Query strategy"] - }, - "semanticSearch": { - "type": "object", - "description": "Settings for the semantic search part of NeuralSearch.\nOnly used when `mode` is `neuralSearch`.\n", - "properties": { - "eventSources": { - "oneOf": [ - { - "type": "array", - "description": "Indices from which to collect click and conversion events.\n\nIf null, the current index and all its replicas are used.\n", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ] - } - } - }, - "optionalWordsArray": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["blue", "iphone case"], - "description": "List of [optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words).", - "default": [], - "x-categories": ["Query strategy"] - }, - "optionalWords": { - "description": "Words that should be considered optional when found in the query.\n\nBy default, records must match all words in the search query to be included in the search results.\nAdding optional words can help to increase the number of search results by running an additional search query that doesn't include the optional words.\nFor example, if the search query is \"action video\" and \"video\" is an optional word,\nthe search engine runs two queries. One for \"action video\" and one for \"action\".\nRecords that match all words are ranked higher.\n\nFor a search query with 4 or more words **and** all its words are optional,\nthe number of matched words required for a record to be included in the search results increases for every 1,000 records:\n\n- If `optionalWords` has less than 10 words, the required number of matched words increases by 1:\n results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 2 matched words.\n- If `optionalWords` has 10 or more words, the number of required matched words increases by the number of optional words divided by 5 (rounded down).\n For example, with 18 optional words: results 1 to 1,000 require 1 matched word, results 1,001 to 2000 need 4 matched words.\n\nFor more information, see [Optional words](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/empty-or-insufficient-results/#creating-a-list-of-optional-words).\n", - "oneOf": [ - { - "type": "string" - }, - { - "type": "null" - }, - { - "$ref": "#/components/schemas/optionalWordsArray" - } - ] - }, - "exactOnSingleWordQuery": { - "type": "string", - "enum": ["attribute", "none", "word"], - "description": "Determines how the [Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes) is computed when the search query has only one word.\n\n- `attribute`.\n The Exact ranking criterion is 1 if the query word and attribute value are the same.\n For example, a search for \"road\" will match the value \"road\", but not \"road trip\".\n\n- `none`.\n The Exact ranking criterion is ignored on single-word searches.\n\n- `word`.\n The Exact ranking criterion is 1 if the query word is found in the attribute value.\n The query word must have at least 3 characters and must not be a stop word.\n Only exact matches will be highlighted,\n partial and prefix matches won't.\n", - "default": "attribute", - "x-categories": ["Query strategy"] - }, - "alternativesAsExact": { - "type": "string", - "enum": ["ignorePlurals", "singleWordSynonym", "multiWordsSynonym", "ignoreConjugations"], - "x-categories": ["Query strategy"] - }, - "advancedSyntaxFeatures": { - "type": "string", - "enum": ["exactPhrase", "excludeWords"], - "x-categories": ["Query strategy"] - }, - "distinct": { - "description": "Determines how many records of a group are included in the search results.\n\nRecords with the same value for the `attributeForDistinct` attribute are considered a group.\nThe `distinct` setting controls how many members of the group are returned.\nThis is useful for [deduplication and grouping](https://www.algolia.com/doc/guides/managing-results/refine-results/grouping/#introducing-algolias-distinct-feature).\n\nThe `distinct` setting is ignored if `attributeForDistinct` is not set.\n", - "example": 1, - "oneOf": [ - { - "type": "boolean", - "description": "Whether deduplication is turned on. If true, only one member of a group is shown in the search results." - }, - { - "type": "integer", - "description": "Number of members of a group of records to include in the search results.\n\n- Don't use `distinct > 1` for records that might be [promoted by rules](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/promote-hits/).\n The number of hits won't be correct and faceting won't work as expected.\n- With `distinct > 1`, the `hitsPerPage` parameter controls the number of returned groups.\n For example, with `hitsPerPage: 10` and `distinct: 2`, up to 20 records are returned.\n Likewise, the `nbHits` response attribute contains the number of returned groups.\n", - "minimum": 0, - "maximum": 4, - "default": 0 - } - ], - "x-categories": ["Advanced"] - }, - "order": { - "description": "Explicit order of facets or facet values.\n\nThis setting lets you always show specific facets or facet values at the top of the list.\n", - "type": "array", - "items": { - "type": "string" - } - }, - "facets": { - "description": "Order of facet names.", - "type": "object", - "additionalProperties": false, - "properties": { - "order": { - "$ref": "#/components/schemas/order" - } - } - }, - "sortRemainingBy": { - "description": "Order of facet values that aren't explicitly positioned with the `order` setting.\n\n- `count`.\n Order remaining facet values by decreasing count.\n The count is the number of matching records containing this facet value.\n\n- `alpha`.\n Sort facet values alphabetically.\n\n- `hidden`.\n Don't show facet values that aren't explicitly positioned.\n", - "type": "string", - "enum": ["count", "alpha", "hidden"] - }, - "hide": { - "description": "Hide facet values.", - "type": "array", - "items": { - "type": "string" - } - }, - "value": { - "type": "object", - "additionalProperties": false, - "properties": { - "order": { - "$ref": "#/components/schemas/order" - }, - "sortRemainingBy": { - "$ref": "#/components/schemas/sortRemainingBy" - }, - "hide": { - "$ref": "#/components/schemas/hide" - } - } - }, - "values": { - "description": "Order of facet values. One object for each facet.", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "facet", - "$ref": "#/components/schemas/value" - } - }, - "facetOrdering": { - "description": "Order of facet names and facet values in your UI.", - "type": "object", - "additionalProperties": false, - "properties": { - "facets": { - "$ref": "#/components/schemas/facets" - }, - "values": { - "$ref": "#/components/schemas/values" - } - } - }, - "redirectURL": { - "description": "The redirect rule container.", - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string" - } - } - }, - "bannerImageUrl": { - "description": "URL for an image to show inside a banner.", - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string" - } - } - }, - "bannerImage": { - "description": "Image to show inside a banner.", - "type": "object", - "additionalProperties": false, - "properties": { - "urls": { - "type": "array", - "items": { - "$ref": "#/components/schemas/bannerImageUrl" - } - }, - "title": { - "type": "string" - } - } - }, - "bannerLink": { - "description": "Link for a banner defined in the Merchandising Studio.", - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string" - } - } - }, - "banner": { - "description": "Banner with image and link to redirect users.", - "type": "object", - "additionalProperties": false, - "properties": { - "image": { - "$ref": "#/components/schemas/bannerImage" - }, - "link": { - "$ref": "#/components/schemas/bannerLink" - } - } - }, - "banners": { - "description": "Banners defined in the Merchandising Studio for a given search.", - "type": "array", - "items": { - "$ref": "#/components/schemas/banner" - } - }, - "widgets": { - "description": "Widgets returned from any rules that are applied to the current search.", - "type": "object", - "additionalProperties": false, - "properties": { - "banners": { - "$ref": "#/components/schemas/banners" - } - } - }, - "renderingContent": { - "description": "Extra data that can be used in the search UI.\n\nYou can use this to control aspects of your search UI, such as the order of facet names and values\nwithout changing your frontend code.\n", - "type": "object", - "additionalProperties": false, - "properties": { - "facetOrdering": { - "$ref": "#/components/schemas/facetOrdering" - }, - "redirect": { - "$ref": "#/components/schemas/redirectURL" - }, - "widgets": { - "$ref": "#/components/schemas/widgets" - } - }, - "x-categories": ["Advanced"] - }, - "reRankingApplyFilter": { - "description": "Restrict [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/) to records that match these filters.\n", - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/reRankingApplyFilter" - } - }, - { - "type": "string", - "x-categories": ["Filtering"] - } - ] - }, - "indexSettingsAsSearchParams": { - "type": "object", - "properties": { - "attributesToRetrieve": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["author", "title", "content"], - "description": "Attributes to include in the API response.\n\nTo reduce the size of your response, you can retrieve only some of the attributes.\nAttribute names are case-sensitive.\n\n- `*` retrieves all attributes, except attributes included in the `customRanking` and `unretrievableAttributes` settings.\n- To retrieve all attributes except a specific one, prefix the attribute with a dash and combine it with the `*`: `[\"*\", \"-ATTRIBUTE\"]`.\n- The `objectID` attribute is always included.\n", - "default": ["*"], - "x-categories": ["Attributes"] - }, - "ranking": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Determines the order in which Algolia returns your results.\n\nBy default, each entry corresponds to a [ranking criteria](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/).\nThe tie-breaking algorithm sequentially applies each criterion in the order they're specified.\nIf you configure a replica index for [sorting by an attribute](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/),\nyou put the sorting attribute at the top of the list.\n\n**Modifiers**\n\n- `asc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in ascending order.\n- `desc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in descending order.\n\nBefore you modify the default setting,\nyou should test your changes in the dashboard,\nand by [A/B testing](https://www.algolia.com/doc/guides/ab-testing/what-is-ab-testing/).\n", - "default": [ - "typo", - "geo", - "words", - "filters", - "proximity", - "attribute", - "exact", - "custom" - ], - "x-categories": ["Ranking"] - }, - "relevancyStrictness": { - "type": "integer", - "example": 90, - "description": "Relevancy threshold below which less relevant results aren't included in the results.\n\nYou can only set `relevancyStrictness` on [virtual replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/#what-are-virtual-replicas).\nUse this setting to strike a balance between the relevance and number of returned results.\n", - "default": 100, - "x-categories": ["Ranking"] - }, - "attributesToHighlight": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["author", "title", "conten", "content"], - "description": "Attributes to highlight.\n\nBy default, all searchable attributes are highlighted.\nUse `*` to highlight all attributes or use an empty array `[]` to turn off highlighting.\nAttribute names are case-sensitive.\n\nWith highlighting, strings that match the search query are surrounded by HTML tags defined by `highlightPreTag` and `highlightPostTag`.\nYou can use this to visually highlight matching parts of a search query in your UI.\n\nFor more information, see [Highlighting and snippeting](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/highlighting-snippeting/js/).\n", - "x-categories": ["Highlighting and Snippeting"] - }, - "attributesToSnippet": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["content:80", "description"], - "description": "Attributes for which to enable snippets.\nAttribute names are case-sensitive.\n\nSnippets provide additional context to matched words.\nIf you enable snippets, they include 10 words, including the matched word.\nThe matched word will also be wrapped by HTML tags for highlighting.\nYou can adjust the number of words with the following notation: `ATTRIBUTE:NUMBER`,\nwhere `NUMBER` is the number of words to be extracted.\n", - "default": [], - "x-categories": ["Highlighting and Snippeting"] - }, - "highlightPreTag": { - "type": "string", - "description": "HTML tag to insert before the highlighted parts in all highlighted results and snippets.", - "default": "", - "x-categories": ["Highlighting and Snippeting"] - }, - "highlightPostTag": { - "type": "string", - "description": "HTML tag to insert after the highlighted parts in all highlighted results and snippets.", - "default": "", - "x-categories": ["Highlighting and Snippeting"] - }, - "snippetEllipsisText": { - "type": "string", - "description": "String used as an ellipsis indicator when a snippet is truncated.", - "default": "…", - "x-categories": ["Highlighting and Snippeting"] - }, - "restrictHighlightAndSnippetArrays": { - "type": "boolean", - "description": "Whether to restrict highlighting and snippeting to items that at least partially matched the search query.\nBy default, all items are highlighted and snippeted.\n", - "default": false, - "x-categories": ["Highlighting and Snippeting"] - }, - "hitsPerPage": { - "$ref": "#/components/schemas/hitsPerPage" - }, - "minWordSizefor1Typo": { - "type": "integer", - "description": "Minimum number of characters a word in the search query must contain to accept matches with [one typo](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - "default": 4, - "x-categories": ["Typos"] - }, - "minWordSizefor2Typos": { - "type": "integer", - "description": "Minimum number of characters a word in the search query must contain to accept matches with [two typos](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#configuring-word-length-for-typos).", - "default": 8, - "x-categories": ["Typos"] - }, - "typoTolerance": { - "$ref": "#/components/schemas/typoTolerance" - }, - "allowTyposOnNumericTokens": { - "type": "boolean", - "description": "Whether to allow typos on numbers in the search query.\n\nTurn off this setting to reduce the number of irrelevant matches\nwhen searching in large sets of similar numbers.\n", - "default": true, - "x-categories": ["Typos"] - }, - "disableTypoToleranceOnAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["sku"], - "description": "Attributes for which you want to turn off [typo tolerance](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/).\nAttribute names are case-sensitive.\n\nReturning only exact matches can help when:\n\n- [Searching in hyphenated attributes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/).\n- Reducing the number of matches when you have too many.\n This can happen with attributes that are long blocks of text, such as product descriptions.\n\nConsider alternatives such as `disableTypoToleranceOnWords` or adding synonyms if your attributes have intentional unusual spellings that might look like typos.\n", - "default": [], - "x-categories": ["Typos"] - }, - "ignorePlurals": { - "$ref": "#/components/schemas/ignorePlurals" - }, - "removeStopWords": { - "$ref": "#/components/schemas/removeStopWords" - }, - "queryLanguages": { - "type": "array", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - }, - "example": ["es"], - "description": "Languages for language-specific query processing steps such as plurals, stop-word removal, and word-detection dictionaries.\n\nThis setting sets a default list of languages used by the `removeStopWords` and `ignorePlurals` settings.\nThis setting also sets a dictionary for word detection in the logogram-based [CJK](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/#normalization-for-logogram-based-languages-cjk) languages.\nTo support this, you must place the CJK language **first**.\n\n**You should always specify a query language.**\nIf you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/),\nor the languages you specified with the `ignorePlurals` or `removeStopWords` parameters.\nThis can lead to unexpected search results.\nFor more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/).\n", - "default": [], - "x-categories": ["Languages"] - }, - "decompoundQuery": { - "type": "boolean", - "description": "Whether to split compound words in the query into their building blocks.\n\nFor more information, see [Word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#splitting-compound-words).\nWord segmentation is supported for these languages: German, Dutch, Finnish, Swedish, and Norwegian.\nDecompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark).\nFor example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308).\n", - "default": true, - "x-categories": ["Languages"] - }, - "enableRules": { - "type": "boolean", - "description": "Whether to enable rules.", - "default": true, - "x-categories": ["Rules"] - }, - "enablePersonalization": { - "type": "boolean", - "description": "Whether to enable Personalization.", - "default": false, - "x-categories": ["Personalization"] - }, - "queryType": { - "$ref": "#/components/schemas/queryType" - }, - "removeWordsIfNoResults": { - "$ref": "#/components/schemas/removeWordsIfNoResults" - }, - "mode": { - "$ref": "#/components/schemas/mode" - }, - "semanticSearch": { - "$ref": "#/components/schemas/semanticSearch" - }, - "advancedSyntax": { - "type": "boolean", - "description": "Whether to support phrase matching and excluding words from search queries.\n\nUse the `advancedSyntaxFeatures` parameter to control which feature is supported.\n", - "default": false, - "x-categories": ["Query strategy"] - }, - "optionalWords": { - "$ref": "#/components/schemas/optionalWords" - }, - "disableExactOnAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["description"], - "description": "Searchable attributes for which you want to [turn off the Exact ranking criterion](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/in-depth/adjust-exact-settings/#turn-off-exact-for-some-attributes).\nAttribute names are case-sensitive.\n\nThis can be useful for attributes with long values, where the likelihood of an exact match is high,\nsuch as product descriptions.\nTurning off the Exact ranking criterion for these attributes favors exact matching on other attributes.\nThis reduces the impact of individual attributes with a lot of content on ranking.\n", - "default": [], - "x-categories": ["Query strategy"] - }, - "exactOnSingleWordQuery": { - "$ref": "#/components/schemas/exactOnSingleWordQuery" - }, - "alternativesAsExact": { - "type": "array", - "items": { - "$ref": "#/components/schemas/alternativesAsExact" - }, - "description": "Determine which plurals and synonyms should be considered an exact matches.\n\nBy default, Algolia treats singular and plural forms of a word, and single-word synonyms, as [exact](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#exact) matches when searching.\nFor example:\n\n- \"swimsuit\" and \"swimsuits\" are treated the same\n- \"swimsuit\" and \"swimwear\" are treated the same (if they are [synonyms](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/#regular-synonyms)).\n\n- `ignorePlurals`.\n Plurals and similar declensions added by the `ignorePlurals` setting are considered exact matches.\n\n- `singleWordSynonym`.\n Single-word synonyms, such as \"NY\" = \"NYC\", are considered exact matches.\n\n- `multiWordsSynonym`.\n Multi-word synonyms, such as \"NY\" = \"New York\", are considered exact matches.\n", - "default": ["ignorePlurals", "singleWordSynonym"], - "x-categories": ["Query strategy"] - }, - "advancedSyntaxFeatures": { - "type": "array", - "items": { - "$ref": "#/components/schemas/advancedSyntaxFeatures" - }, - "description": "Advanced search syntax features you want to support.\n\n- `exactPhrase`.\n Phrases in quotes must match exactly.\n For example, `sparkly blue \"iPhone case\"` only returns records with the exact string \"iPhone case\".\n\n- `excludeWords`.\n Query words prefixed with a `-` must not occur in a record.\n For example, `search -engine` matches records that contain \"search\" but not \"engine\".\n\nThis setting only has an effect if `advancedSyntax` is true.\n", - "default": ["exactPhrase", "excludeWords"], - "x-categories": ["Query strategy"] - }, - "distinct": { - "$ref": "#/components/schemas/distinct" - }, - "replaceSynonymsInHighlight": { - "type": "boolean", - "description": "Whether to replace a highlighted word with the matched synonym.\n\nBy default, the original words are highlighted even if a synonym matches.\nFor example, with `home` as a synonym for `house` and a search for `home`,\nrecords matching either \"home\" or \"house\" are included in the search results,\nand either \"home\" or \"house\" are highlighted.\n\nWith `replaceSynonymsInHighlight` set to `true`, a search for `home` still matches the same records,\nbut all occurrences of \"house\" are replaced by \"home\" in the highlighted response.\n", - "default": false, - "x-categories": ["Highlighting and Snippeting"] - }, - "minProximity": { - "type": "integer", - "minimum": 1, - "maximum": 7, - "description": "Minimum proximity score for two matching words.\n\nThis adjusts the [Proximity ranking criterion](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#proximity)\nby equally scoring matches that are farther apart.\n\nFor example, if `minProximity` is 2, neighboring matches and matches with one word between them would have the same score.\n", - "default": 1, - "x-categories": ["Advanced"] - }, - "responseFields": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Properties to include in the API response of search and browse requests.\n\nBy default, all response properties are included.\nTo reduce the response size, you can select which properties should be included.\n\nAn empty list may lead to an empty API response (except properties you can't exclude).\n\nYou can't exclude these properties:\n`message`, `warning`, `cursor`, `abTestVariantID`,\nor any property added by setting `getRankingInfo` to true.\n\nYour search depends on the `hits` field. If you omit this field, searches won't return any results.\nYour UI might also depend on other properties, for example, for pagination.\nBefore restricting the response size, check the impact on your search experience.\n", - "default": ["*"], - "x-categories": ["Advanced"] - }, - "maxValuesPerFacet": { - "type": "integer", - "description": "Maximum number of facet values to return for each facet.", - "default": 100, - "maximum": 1000, - "x-categories": ["Faceting"] - }, - "sortFacetValuesBy": { - "type": "string", - "description": "Order in which to retrieve facet values.\n\n- `count`.\n Facet values are retrieved by decreasing count.\n The count is the number of matching records containing this facet value.\n\n- `alpha`.\n Retrieve facet values alphabetically.\n\nThis setting doesn't influence how facet values are displayed in your UI (see `renderingContent`).\nFor more information, see [facet value display](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/js/).\n", - "default": "count", - "x-categories": ["Faceting"] - }, - "attributeCriteriaComputedByMinProximity": { - "type": "boolean", - "description": "Whether the best matching attribute should be determined by minimum proximity.\n\nThis setting only affects ranking if the Attribute ranking criterion comes before Proximity in the `ranking` setting.\nIf true, the best matching attribute is selected based on the minimum proximity of multiple matches.\nOtherwise, the best matching attribute is determined by the order in the `searchableAttributes` setting.\n", - "default": false, - "x-categories": ["Advanced"] - }, - "renderingContent": { - "$ref": "#/components/schemas/renderingContent" - }, - "enableReRanking": { - "type": "boolean", - "description": "Whether this search will use [Dynamic Re-Ranking](https://www.algolia.com/doc/guides/algolia-ai/re-ranking/).\n\nThis setting only has an effect if you activated Dynamic Re-Ranking for this index in the Algolia dashboard.\n", - "default": true, - "x-categories": ["Filtering"] - }, - "reRankingApplyFilter": { - "oneOf": [ - { - "$ref": "#/components/schemas/reRankingApplyFilter" - }, - { - "type": "null" - } - ] - } - } - }, - "searchParamsObject": { - "title": "Search parameters as object", - "description": "Each parameter value, including the `query` must not be larger than 512 bytes.", - "allOf": [ - { - "$ref": "#/components/schemas/baseSearchParams" - }, - { - "$ref": "#/components/schemas/indexSettingsAsSearchParams" - } - ], - "unevaluatedProperties": false - }, - "searchParams": { - "oneOf": [ - { - "$ref": "#/components/schemas/searchParamsString" - }, - { - "$ref": "#/components/schemas/searchParamsObject" - } - ] - }, - "processingTimeMS": { - "type": "integer", - "description": "Time the server took to process the request, in milliseconds.", - "example": 20 - }, - "RedirectRuleIndexMetadata": { - "type": "object", - "properties": { - "source": { - "type": "string", - "description": "Source index for the redirect rule." - }, - "dest": { - "type": "string", - "description": "Destination index for the redirect rule." - }, - "reason": { - "type": "string", - "description": "Reason for the redirect rule." - }, - "succeed": { - "type": "boolean", - "description": "Redirect rule status." - }, - "data": { - "title": "redirectRuleIndexData", - "type": "object", - "description": "Redirect rule data.", - "required": ["ruleObjectID"], - "properties": { - "ruleObjectID": { - "type": "string" - } - } - } - }, - "required": ["data", "succeed", "reason", "dest", "source"] - }, - "userData": { - "example": { - "settingID": "f2a7b51e3503acc6a39b3784ffb84300", - "pluginVersion": "1.6.0" - }, - "description": "An object with custom data.\n\nYou can store up to 32kB as custom data.\n", - "default": {}, - "x-categories": ["Advanced"] - }, - "baseSearchResponse": { - "type": "object", - "required": ["processingTimeMS"], - "properties": { - "abTestID": { - "type": "integer", - "description": "A/B test ID. This is only included in the response for indices that are part of an A/B test." - }, - "abTestVariantID": { - "type": "integer", - "minimum": 1, - "description": "Variant ID. This is only included in the response for indices that are part of an A/B test." - }, - "aroundLatLng": { - "type": "string", - "description": "Computed geographical location.", - "example": "40.71,-74.01", - "pattern": "^(-?\\d+(\\.\\d+)?),\\s*(-?\\d+(\\.\\d+)?)$" - }, - "automaticRadius": { - "type": "string", - "description": "Distance from a central coordinate provided by `aroundLatLng`." - }, - "exhaustive": { - "title": "exhaustive", - "type": "object", - "description": "Whether certain properties of the search response are calculated exhaustive (exact) or approximated.", - "properties": { - "facetsCount": { - "type": "boolean", - "title": "facetsCount", - "description": "Whether the facet count is exhaustive (`true`) or approximate (`false`). See the [related discussion](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-)." - }, - "facetValues": { - "type": "boolean", - "title": "facetValues", - "description": "The value is `false` if not all facet values are retrieved." - }, - "nbHits": { - "type": "boolean", - "title": "nbHits", - "description": "Whether the `nbHits` is exhaustive (`true`) or approximate (`false`). When the query takes more than 50ms to be processed, the engine makes an approximation. This can happen when using complex filters on millions of records, when typo-tolerance was not exhaustive, or when enough hits have been retrieved (for example, after the engine finds 10,000 exact matches). `nbHits` is reported as non-exhaustive whenever an approximation is made, even if the approximation didn’t, in the end, impact the exhaustivity of the query." - }, - "rulesMatch": { - "type": "boolean", - "title": "rulesMatch", - "description": "Rules matching exhaustivity. The value is `false` if rules were enable for this query, and could not be fully processed due a timeout. This is generally caused by the number of alternatives (such as typos) which is too large." - }, - "typo": { - "type": "boolean", - "title": "typo", - "description": "Whether the typo search was exhaustive (`true`) or approximate (`false`). An approximation is done when the typo search query part takes more than 10% of the query budget (ie. 5ms by default) to be processed (this can happen when a lot of typo alternatives exist for the query). This field will not be included when typo-tolerance is entirely disabled." - } - } - }, - "appliedRules": { - "description": "Rules applied to the query.", - "title": "appliedRules", - "type": "array", - "items": { - "type": "object" - } - }, - "exhaustiveFacetsCount": { - "type": "boolean", - "description": "See the `facetsCount` field of the `exhaustive` object in the response.", - "deprecated": true - }, - "exhaustiveNbHits": { - "type": "boolean", - "description": "See the `nbHits` field of the `exhaustive` object in the response.", - "deprecated": true - }, - "exhaustiveTypo": { - "type": "boolean", - "description": "See the `typo` field of the `exhaustive` object in the response.", - "deprecated": true - }, - "facets": { - "title": "facets", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "facet", - "type": "object", - "additionalProperties": { - "x-additionalPropertiesName": "facet count", - "type": "integer" - } - }, - "description": "Facet counts.", - "example": { - "category": { - "food": 1, - "tech": 42 - } - } - }, - "facets_stats": { - "type": "object", - "description": "Statistics for numerical facets.", - "additionalProperties": { - "title": "facetStats", - "type": "object", - "properties": { - "min": { - "type": "number", - "format": "double", - "description": "Minimum value in the results." - }, - "max": { - "type": "number", - "format": "double", - "description": "Maximum value in the results." - }, - "avg": { - "type": "number", - "format": "double", - "description": "Average facet value in the results." - }, - "sum": { - "type": "number", - "format": "double", - "description": "Sum of all values in the results." - } - } - } - }, - "index": { - "type": "string", - "example": "indexName", - "description": "Index name used for the query." - }, - "indexUsed": { - "type": "string", - "description": "Index name used for the query. During A/B testing, the targeted index isn't always the index used by the query.", - "example": "indexNameAlt" - }, - "message": { - "type": "string", - "description": "Warnings about the query." - }, - "nbSortedHits": { - "type": "integer", - "description": "Number of hits selected and sorted by the relevant sort algorithm.", - "example": 20 - }, - "parsedQuery": { - "type": "string", - "description": "Post-[normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/#what-does-normalization-mean) query string that will be searched.", - "example": "george clo" - }, - "processingTimeMS": { - "$ref": "#/components/schemas/processingTimeMS" - }, - "processingTimingsMS": { - "type": "object", - "description": "Experimental. List of processing steps and their times, in milliseconds. You can use this list to investigate performance issues." - }, - "queryAfterRemoval": { - "type": "string", - "description": "Markup text indicating which parts of the original query have been removed to retrieve a non-empty result set." - }, - "redirect": { - "title": "redirect", - "type": "object", - "description": "[Redirect results to a URL](https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/redirects/), this this parameter is for internal use only.\n", - "properties": { - "index": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RedirectRuleIndexMetadata" - } - } - } - }, - "renderingContent": { - "$ref": "#/components/schemas/renderingContent" - }, - "serverTimeMS": { - "type": "integer", - "description": "Time the server took to process the request, in milliseconds.", - "example": 20 - }, - "serverUsed": { - "type": "string", - "description": "Host name of the server that processed the request.", - "example": "c2-uk-3.algolia.net" - }, - "userData": { - "$ref": "#/components/schemas/userData" - }, - "queryID": { - "type": "string", - "description": "Unique identifier for the query. This is used for [click analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/).", - "example": "a00dbc80a8d13c4565a442e7e2dca80a" - }, - "_automaticInsights": { - "type": "boolean", - "description": "Whether automatic events collection is enabled for the application." - } - } - }, - "nbHits": { - "type": "integer", - "description": "Number of results (hits).", - "example": 20 - }, - "nbPages": { - "type": "integer", - "description": "Number of pages of results.", - "example": 1 - }, - "SearchPagination": { - "type": "object", - "properties": { - "page": { - "$ref": "#/components/schemas/page" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - }, - "nbPages": { - "$ref": "#/components/schemas/nbPages" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/hitsPerPage" - } - } - }, - "objectID": { - "type": "string", - "description": "Unique record identifier.", - "example": "test-record-123" - }, - "highlightedValue": { - "type": "string", - "description": "Highlighted attribute value, including HTML tags.", - "example": "George Clooney" - }, - "matchLevel": { - "type": "string", - "description": "Whether the whole query string matches or only a part.", - "enum": ["none", "partial", "full"] - }, - "highlightResultOption": { - "type": "object", - "description": "Surround words that match the query with HTML tags for highlighting.", - "additionalProperties": false, - "properties": { - "value": { - "$ref": "#/components/schemas/highlightedValue" - }, - "matchLevel": { - "$ref": "#/components/schemas/matchLevel" - }, - "matchedWords": { - "type": "array", - "description": "List of matched words from the search query.", - "example": ["action"], - "items": { - "type": "string" - } - }, - "fullyHighlighted": { - "type": "boolean", - "description": "Whether the entire attribute value is highlighted." - } - }, - "required": ["value", "matchLevel", "matchedWords"], - "x-discriminator-fields": ["matchLevel", "matchedWords"] - }, - "highlightResultMap": { - "type": "object", - "description": "Surround words that match the query with HTML tags for highlighting.", - "x-is-free-form": false, - "additionalProperties": { - "x-additionalPropertiesName": "attribute", - "$ref": "#/components/schemas/highlightResult" - } - }, - "highlightResult": { - "oneOf": [ - { - "$ref": "#/components/schemas/highlightResultOption" - }, - { - "$ref": "#/components/schemas/highlightResultMap" - }, - { - "$ref": "#/components/schemas/highlightResultArray" - } - ] - }, - "highlightResultArray": { - "type": "array", - "description": "Surround words that match the query with HTML tags for highlighting.", - "items": { - "$ref": "#/components/schemas/highlightResult" - } - }, - "snippetResultOption": { - "type": "object", - "description": "Snippets that show the context around a matching search query.", - "additionalProperties": false, - "properties": { - "value": { - "$ref": "#/components/schemas/highlightedValue" - }, - "matchLevel": { - "$ref": "#/components/schemas/matchLevel" - } - }, - "required": ["value", "matchLevel"], - "x-discriminator-fields": ["matchLevel"] - }, - "snippetResultMap": { - "type": "object", - "description": "Snippets that show the context around a matching search query.", - "x-is-free-form": false, - "additionalProperties": { - "x-additionalPropertiesName": "attribute", - "$ref": "#/components/schemas/snippetResult" - } - }, - "snippetResult": { - "oneOf": [ - { - "$ref": "#/components/schemas/snippetResultOption" - }, - { - "$ref": "#/components/schemas/snippetResultMap" - }, - { - "$ref": "#/components/schemas/snippetResultArray" - } - ] - }, - "snippetResultArray": { - "type": "array", - "description": "Snippets that show the context around a matching search query.", - "items": { - "$ref": "#/components/schemas/snippetResult" - } - }, - "matchedGeoLocation": { - "type": "object", - "properties": { - "lat": { - "type": "number", - "format": "double", - "description": "Latitude of the matched location." - }, - "lng": { - "type": "number", - "format": "double", - "description": "Longitude of the matched location." - }, - "distance": { - "type": "integer", - "description": "Distance between the matched location and the search location (in meters)." - } - } - }, - "personalization": { - "type": "object", - "properties": { - "filtersScore": { - "type": "integer", - "description": "The score of the filters." - }, - "rankingScore": { - "type": "integer", - "description": "The score of the ranking." - }, - "score": { - "type": "integer", - "description": "The score of the event." - } - } - }, - "rankingInfo": { - "type": "object", - "description": "Object with detailed information about the record's ranking.", - "additionalProperties": false, - "properties": { - "filters": { - "type": "integer", - "minimum": 0, - "description": "Whether a filter matched the query." - }, - "firstMatchedWord": { - "type": "integer", - "minimum": 0, - "description": "Position of the first matched word in the best matching attribute of the record." - }, - "geoDistance": { - "type": "integer", - "minimum": 0, - "description": "Distance between the geo location in the search query and the best matching geo location in the record, divided by the geo precision (in meters)." - }, - "geoPrecision": { - "type": "integer", - "minimum": 1, - "description": "Precision used when computing the geo distance, in meters." - }, - "matchedGeoLocation": { - "$ref": "#/components/schemas/matchedGeoLocation" - }, - "personalization": { - "$ref": "#/components/schemas/personalization" - }, - "nbExactWords": { - "type": "integer", - "minimum": 0, - "description": "Number of exactly matched words." - }, - "nbTypos": { - "type": "integer", - "minimum": 0, - "description": "Number of typos encountered when matching the record." - }, - "promoted": { - "type": "boolean", - "description": "Whether the record was promoted by a rule." - }, - "proximityDistance": { - "type": "integer", - "minimum": 0, - "description": "Number of words between multiple matches in the query plus 1. For single word queries, `proximityDistance` is 0." - }, - "userScore": { - "type": "integer", - "description": "Overall ranking of the record, expressed as a single integer. This attribute is internal." - }, - "words": { - "type": "integer", - "minimum": 1, - "description": "Number of matched words." - }, - "promotedByReRanking": { - "type": "boolean", - "description": "Whether the record is re-ranked." - } - }, - "required": ["nbTypos", "firstMatchedWord", "geoDistance", "nbExactWords", "userScore"] - }, - "distinctSeqID": { - "type": "integer" - }, - "hit": { - "type": "object", - "description": "Search result.\n\nA hit is a record from your index, augmented with special attributes for highlighting, snippeting, and ranking.\n", - "x-is-generic": true, - "additionalProperties": true, - "required": ["objectID"], - "properties": { - "objectID": { - "$ref": "#/components/schemas/objectID" - }, - "_highlightResult": { - "$ref": "#/components/schemas/highlightResultMap" - }, - "_snippetResult": { - "$ref": "#/components/schemas/snippetResultMap" - }, - "_rankingInfo": { - "$ref": "#/components/schemas/rankingInfo" - }, - "_distinctSeqID": { - "$ref": "#/components/schemas/distinctSeqID" - } - } - }, - "searchHits": { - "type": "object", - "properties": { - "hits": { - "type": "array", - "description": "Search results (hits).\n\nHits are records from your index that match the search criteria, augmented with additional attributes, such as, for highlighting.\n", - "items": { - "$ref": "#/components/schemas/hit" - } - }, - "query": { - "$ref": "#/components/schemas/query" - }, - "params": { - "type": "string", - "description": "URL-encoded string of all search parameters.", - "example": "query=a&hitsPerPage=20" - } - }, - "required": ["hits", "query", "params"] - }, - "searchResponse": { - "additionalProperties": true, - "allOf": [ - { - "$ref": "#/components/schemas/baseSearchResponse" - }, - { - "$ref": "#/components/schemas/SearchPagination" - }, - { - "$ref": "#/components/schemas/searchHits" - } - ], - "unevaluatedProperties": false - }, - "indexName": { - "type": "string", - "example": "products", - "description": "Index name (case-sensitive)." - }, - "searchTypeDefault": { - "type": "string", - "enum": ["default"], - "default": "default", - "description": "- `default`: perform a search query\n- `facet` [searches for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).\n" - }, - "searchForHitsOptions": { - "x-is-SearchForHitsOptions": true, - "type": "object", - "properties": { - "indexName": { - "$ref": "#/components/schemas/indexName" - }, - "type": { - "$ref": "#/components/schemas/searchTypeDefault" - } - }, - "required": ["indexName"] - }, - "SearchForHits": { - "allOf": [ - { - "$ref": "#/components/schemas/searchParams" - }, - { - "$ref": "#/components/schemas/searchForHitsOptions" - } - ], - "unevaluatedProperties": false - }, - "facetQuery": { - "type": "string", - "description": "Text to search inside the facet's values.", - "example": "george", - "default": "" - }, - "maxFacetHits": { - "type": "integer", - "description": "Maximum number of facet values to return when [searching for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).", - "maximum": 100, - "default": 10, - "x-categories": ["Advanced"] - }, - "searchTypeFacet": { - "type": "string", - "enum": ["facet"], - "default": "facet", - "description": "- `default`: perform a search query\n- `facet` [searches for facet values](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/#search-for-facet-values).\n" - }, - "searchForFacetsOptions": { - "type": "object", - "properties": { - "facet": { - "type": "string", - "description": "Facet name." - }, - "indexName": { - "$ref": "#/components/schemas/indexName" - }, - "facetQuery": { - "$ref": "#/components/schemas/facetQuery" - }, - "maxFacetHits": { - "$ref": "#/components/schemas/maxFacetHits" - }, - "type": { - "$ref": "#/components/schemas/searchTypeFacet" - } - }, - "required": ["indexName", "type", "facet"] - }, - "SearchForFacets": { - "allOf": [ - { - "$ref": "#/components/schemas/searchParams" - }, - { - "$ref": "#/components/schemas/searchForFacetsOptions" - } - ], - "x-discriminator-fields": ["facet", "type"], - "unevaluatedProperties": false - }, - "SearchQuery": { - "oneOf": [ - { - "$ref": "#/components/schemas/SearchForHits" - }, - { - "$ref": "#/components/schemas/SearchForFacets" - } - ] - }, - "searchStrategy": { - "type": "string", - "enum": ["none", "stopIfEnoughMatches"], - "description": "Strategy for multiple search queries:\n\n- `none`. Run all queries.\n- `stopIfEnoughMatches`. Run the queries one by one, stopping as soon as a query matches at least the `hitsPerPage` number of results.\n" - }, - "searchForFacetValuesResponse": { - "type": "object", - "additionalProperties": false, - "required": ["facetHits", "exhaustiveFacetsCount"], - "x-discriminator-fields": ["facetHits"], - "properties": { - "facetHits": { - "type": "array", - "description": "Matching facet values.", - "items": { - "title": "facetHits", - "type": "object", - "additionalProperties": false, - "required": ["value", "highlighted", "count"], - "properties": { - "value": { - "description": "Facet value.", - "example": "Mobile phone", - "type": "string" - }, - "highlighted": { - "$ref": "#/components/schemas/highlightedValue" - }, - "count": { - "description": "Number of records with this facet value. [The count may be approximated](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-).", - "type": "integer" - } - } - } - }, - "exhaustiveFacetsCount": { - "type": "boolean", - "description": "Whether the facet count is exhaustive (true) or approximate (false).\nFor more information, see [Why are my facet and hit counts not accurate](https://support.algolia.com/hc/en-us/articles/4406975248145-Why-are-my-facet-and-hit-counts-not-accurate-).\n" - }, - "processingTimeMS": { - "$ref": "#/components/schemas/processingTimeMS" - } - } - }, - "searchResult": { - "oneOf": [ - { - "$ref": "#/components/schemas/searchResponse" - }, - { - "$ref": "#/components/schemas/searchForFacetValuesResponse" - } - ] - }, - "cursor": { - "type": "object", - "properties": { - "cursor": { - "type": "string", - "description": "Cursor to get the next page of the response.\n\nThe parameter must match the value returned in the response of a previous request.\nThe last page of the response does not return a `cursor` attribute.\n", - "example": "jMDY3M2MwM2QwMWUxMmQwYWI0ZTN" - } - } - }, - "browseParamsObject": { - "allOf": [ - { - "$ref": "#/components/schemas/searchParamsObject" - }, - { - "$ref": "#/components/schemas/cursor" - } - ], - "unevaluatedProperties": false - }, - "browseParams": { - "oneOf": [ - { - "$ref": "#/components/schemas/searchParamsString" - }, - { - "$ref": "#/components/schemas/browseParamsObject" - } - ] - }, - "BrowsePagination": { - "type": "object", - "properties": { - "page": { - "$ref": "#/components/schemas/page" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - }, - "nbPages": { - "$ref": "#/components/schemas/nbPages" - }, - "hitsPerPage": { - "$ref": "#/components/schemas/hitsPerPage" - } - } - }, - "browseResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/baseSearchResponse" - }, - { - "$ref": "#/components/schemas/BrowsePagination" - }, - { - "$ref": "#/components/schemas/searchHits" - }, - { - "$ref": "#/components/schemas/cursor" - } - ], - "unevaluatedProperties": false - }, - "createdAt": { - "type": "string", - "example": "2023-07-04T12:49:15Z", - "description": "Date and time when the object was created, in RFC 3339 format." - }, - "taskID": { - "type": "integer", - "format": "int64", - "example": 1514562690001, - "description": "Unique identifier of a task.\n\nA successful API response means that a task was added to a queue. It might not run immediately. You can check the task's progress with the [`task` operation](#tag/Indices/operation/getTask) and this `taskID`.\n" - }, - "deletedAt": { - "type": "string", - "example": "2023-06-27T14:42:38.831Z", - "description": "Date and time when the object was deleted, in RFC 3339 format." - }, - "updatedAt": { - "type": "string", - "example": "2023-07-04T12:49:15Z", - "description": "Date and time when the object was updated, in RFC 3339 format." - }, - "deleteByParams": { - "type": "object", - "additionalProperties": false, - "properties": { - "facetFilters": { - "$ref": "#/components/schemas/facetFilters" - }, - "filters": { - "$ref": "#/components/schemas/filters" - }, - "numericFilters": { - "$ref": "#/components/schemas/numericFilters" - }, - "tagFilters": { - "$ref": "#/components/schemas/tagFilters" - }, - "aroundLatLng": { - "$ref": "#/components/schemas/aroundLatLng" - }, - "aroundRadius": { - "$ref": "#/components/schemas/aroundRadius" - }, - "insideBoundingBox": { - "$ref": "#/components/schemas/insideBoundingBox" - }, - "insidePolygon": { - "$ref": "#/components/schemas/insidePolygon" - } - } - }, - "updatedAtResponse": { - "type": "object", - "description": "Response, taskID, and update timestamp.", - "additionalProperties": false, - "required": ["taskID", "updatedAt"], - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - } - } - }, - "action": { - "type": "string", - "enum": [ - "addObject", - "updateObject", - "partialUpdateObject", - "partialUpdateObjectNoCreate", - "deleteObject", - "delete", - "clear" - ], - "description": "Type of indexing operation." - }, - "batchWriteParams": { - "title": "batchWriteParams", - "description": "Batch parameters.", - "type": "object", - "additionalProperties": false, - "properties": { - "requests": { - "type": "array", - "items": { - "title": "batchRequest", - "type": "object", - "additionalProperties": false, - "properties": { - "action": { - "$ref": "#/components/schemas/action" - }, - "body": { - "type": "object", - "description": "Operation arguments (varies with specified `action`).", - "example": { - "name": "Betty Jane McCamey", - "company": "Vita Foods Inc.", - "email": "betty@mccamey.com" - } - } - }, - "required": ["action", "body"] - } - } - }, - "required": ["requests"], - "example": { - "requests": [ - { - "action": "addObject", - "body": { - "name": "Betty Jane McCamey", - "company": "Vita Foods Inc.", - "email": "betty@mccamey.com" - } - }, - { - "action": "addObject", - "body": { - "name": "Gayla geimer", - "company": "Ortman McCain Co.", - "email": "gayla@geimer.com" - } - } - ] - } - }, - "objectIDs": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["record-1", "record-2"], - "description": "Unique record identifiers." - }, - "batchResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "objectIDs": { - "$ref": "#/components/schemas/objectIDs" - } - }, - "required": ["taskID", "objectIDs"] - }, - "baseIndexSettings": { - "type": "object", - "properties": { - "attributesForFaceting": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "author", - "filterOnly(isbn)", - "searchable(edition)", - "afterDistinct(category)", - "afterDistinct(searchable(publisher))" - ], - "description": "Attributes used for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/).\n\nFacets are attributes that let you categorize search results.\nThey can be used for filtering search results.\nBy default, no attribute is used for faceting.\nAttribute names are case-sensitive.\n\n**Modifiers**\n\n- `filterOnly(\"ATTRIBUTE\")`.\n Allows the attribute to be used as a filter but doesn't evaluate the facet values.\n\n- `searchable(\"ATTRIBUTE\")`.\n Allows searching for facet values.\n\n- `afterDistinct(\"ATTRIBUTE\")`.\n Evaluates the facet count _after_ deduplication with `distinct`.\n This ensures accurate facet counts.\n You can apply this modifier to searchable facets: `afterDistinct(searchable(ATTRIBUTE))`.\n", - "default": [], - "x-categories": ["Faceting"] - }, - "replicas": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["virtual(prod_products_price_asc)", "dev_products_replica"], - "description": "Creates [replica indices](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/replicas/).\n\nReplicas are copies of a primary index with the same records but different settings, synonyms, or rules.\nIf you want to offer a different ranking or sorting of your search results, you'll use replica indices.\nAll index operations on a primary index are automatically forwarded to its replicas.\nTo add a replica index, you must provide the complete set of replicas to this parameter.\nIf you omit a replica from this list, the replica turns into a regular, standalone index that will no longer be synced with the primary index.\n\n**Modifier**\n\n- `virtual(\"REPLICA\")`.\n Create a virtual replica,\n Virtual replicas don't increase the number of records and are optimized for [Relevant sorting](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/in-depth/relevant-sort/).\n", - "default": [], - "x-categories": ["Ranking"] - }, - "paginationLimitedTo": { - "type": "integer", - "example": 100, - "description": "Maximum number of search results that can be obtained through pagination.\n\nHigher pagination limits might slow down your search.\nFor pagination limits above 1,000, the sorting of results beyond the 1,000th hit can't be guaranteed.\n", - "default": 1000, - "maximum": 20000 - }, - "unretrievableAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["total_sales"], - "description": "Attributes that can't be retrieved at query time.\n\nThis can be useful if you want to use an attribute for ranking or to [restrict access](https://www.algolia.com/doc/guides/security/api-keys/how-to/user-restricted-access-to-data/),\nbut don't want to include it in the search results.\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Attributes"] - }, - "disableTypoToleranceOnWords": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["wheel", "1X2BCD"], - "description": "Creates a list of [words which require exact matches](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/in-depth/configuring-typo-tolerance/#turn-off-typo-tolerance-for-certain-words).\nThis also turns off [word splitting and concatenation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/splitting-and-concatenation/) for the specified words.\n", - "default": [], - "x-categories": ["Typos"] - }, - "attributesToTransliterate": { - "description": "Attributes, for which you want to support [Japanese transliteration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/#japanese-transliteration-and-type-ahead).\n\nTransliteration supports searching in any of the Japanese writing systems.\nTo support transliteration, you must set the indexing language to Japanese.\nAttribute names are case-sensitive.\n", - "type": "array", - "items": { - "type": "string" - }, - "example": ["name", "description"], - "x-categories": ["Languages"] - }, - "camelCaseAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["description"], - "description": "Attributes for which to split [camel case](https://wikipedia.org/wiki/Camel_case) words.\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Languages"] - }, - "decompoundedAttributes": { - "type": "object", - "example": { - "de": ["name"] - }, - "description": "Searchable attributes to which Algolia should apply [word segmentation](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/how-to/customize-segmentation/) (decompounding).\nAttribute names are case-sensitive.\n\nCompound words are formed by combining two or more individual words,\nand are particularly prevalent in Germanic languages—for example, \"firefighter\".\nWith decompounding, the individual components are indexed separately.\n\nYou can specify different lists for different languages.\nDecompounding is supported for these languages:\nDutch (`nl`), German (`de`), Finnish (`fi`), Danish (`da`), Swedish (`sv`), and Norwegian (`no`).\nDecompounding doesn't work for words with [non-spacing mark Unicode characters](https://www.charactercodes.net/category/non-spacing_mark).\nFor example, `Gartenstühle` won't be decompounded if the `ü` consists of `u` (U+0075) and `◌̈` (U+0308).\n", - "default": {}, - "x-categories": ["Languages"] - }, - "indexLanguages": { - "type": "array", - "items": { - "$ref": "#/components/schemas/supportedLanguage" - }, - "example": ["ja"], - "description": "Languages for language-specific processing steps, such as word detection and dictionary settings.\n\n**You should always specify an indexing language.**\nIf you don't specify an indexing language, the search engine uses all [supported languages](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/),\nor the languages you specified with the `ignorePlurals` or `removeStopWords` parameters.\nThis can lead to unexpected search results.\nFor more information, see [Language-specific configuration](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/language-specific-configurations/).\n", - "default": [], - "x-categories": ["Languages"] - }, - "disablePrefixOnAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["sku"], - "description": "Searchable attributes for which you want to turn off [prefix matching](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/override-search-engine-defaults/#adjusting-prefix-search).\nAttribute names are case-sensitive.\n", - "default": [], - "x-categories": ["Query strategy"] - }, - "allowCompressionOfIntegerArray": { - "type": "boolean", - "description": "Whether arrays with exclusively non-negative integers should be compressed for better performance.\nIf true, the compressed arrays may be reordered.\n", - "default": false, - "x-categories": ["Performance"] - }, - "numericAttributesForFiltering": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Numeric attributes that can be used as [numerical filters](https://www.algolia.com/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query/#numerical-filters).\nAttribute names are case-sensitive.\n\nBy default, all numeric attributes are available as numerical filters.\nFor faster indexing, reduce the number of numeric attributes.\n\nTo turn off filtering for all numeric attributes, specify an attribute that doesn't exist in your index, such as `NO_NUMERIC_FILTERING`.\n\n**Modifier**\n\n- `equalOnly(\"ATTRIBUTE\")`.\n Support only filtering based on equality comparisons `=` and `!=`.\n", - "example": ["equalOnly(quantity)", "popularity"], - "default": [], - "x-categories": ["Performance"] - }, - "separatorsToIndex": { - "type": "string", - "example": "+#", - "description": "Control which non-alphanumeric characters are indexed.\n\nBy default, Algolia ignores [non-alphanumeric characters](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/typo-tolerance/how-to/how-to-search-in-hyphenated-attributes/#handling-non-alphanumeric-characters) like hyphen (`-`), plus (`+`), and parentheses (`(`,`)`).\nTo include such characters, define them with `separatorsToIndex`.\n\nSeparators are all non-letter characters except spaces and currency characters, such as $€£¥.\n\nWith `separatorsToIndex`, Algolia treats separator characters as separate words.\nFor example, in a search for \"Disney+\", Algolia considers \"Disney\" and \"+\" as two separate words.\n", - "default": "", - "x-categories": ["Typos"] - }, - "searchableAttributes": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["title,alternative_title", "author", "unordered(text)", "emails.personal"], - "description": "Attributes used for searching. Attribute names are case-sensitive.\n\nBy default, all attributes are searchable and the [Attribute](https://www.algolia.com/doc/guides/managing-results/relevance-overview/in-depth/ranking-criteria/#attribute) ranking criterion is turned off.\nWith a non-empty list, Algolia only returns results with matches in the selected attributes.\nIn addition, the Attribute ranking criterion is turned on: matches in attributes that are higher in the list of `searchableAttributes` rank first.\nTo make matches in two attributes rank equally, include them in a comma-separated string, such as `\"title,alternate_title\"`.\nAttributes with the same priority are always unordered.\n\nFor more information, see [Searchable attributes](https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/setting-searchable-attributes/).\n\n**Modifier**\n\n- `unordered(\"ATTRIBUTE\")`.\n Ignore the position of a match within the attribute.\n\nWithout a modifier, matches at the beginning of an attribute rank higher than matches at the end.\n", - "default": [], - "x-categories": ["Attributes"] - }, - "userData": { - "$ref": "#/components/schemas/userData" - }, - "customNormalization": { - "description": "Characters and their normalized replacements.\nThis overrides Algolia's default [normalization](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/normalization/).\n", - "type": "object", - "example": { - "default": { - "ä": "ae", - "ü": "ue" - } - }, - "additionalProperties": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "x-categories": ["Languages"] - }, - "attributeForDistinct": { - "description": "Attribute that should be used to establish groups of results.\nAttribute names are case-sensitive.\n\nAll records with the same value for this attribute are considered a group.\nYou can combine `attributeForDistinct` with the `distinct` search parameter to control\nhow many items per group are included in the search results.\n\nIf you want to use the same attribute also for faceting, use the `afterDistinct` modifier of the `attributesForFaceting` setting.\nThis applies faceting _after_ deduplication, which will result in accurate facet counts.\n", - "example": "url", - "type": "string" - }, - "maxFacetHits": { - "$ref": "#/components/schemas/maxFacetHits" - }, - "keepDiacriticsOnCharacters": { - "type": "string", - "example": "øé", - "description": "Characters for which diacritics should be preserved.\n\nBy default, Algolia removes diacritics from letters.\nFor example, `é` becomes `e`. If this causes issues in your search,\nyou can specify characters that should keep their diacritics.\n", - "default": "", - "x-categories": ["Languages"] - }, - "customRanking": { - "type": "array", - "items": { - "type": "string" - }, - "example": ["desc(popularity)", "asc(price)"], - "description": "Attributes to use as [custom ranking](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/).\nAttribute names are case-sensitive.\n\nThe custom ranking attributes decide which items are shown first if the other ranking criteria are equal.\n\nRecords with missing values for your selected custom ranking attributes are always sorted last.\nBoolean attributes are sorted based on their alphabetical order.\n\n**Modifiers**\n\n- `asc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in ascending order.\n\n- `desc(\"ATTRIBUTE\")`.\n Sort the index by the values of an attribute, in descending order.\n\nIf you use two or more custom ranking attributes,\n[reduce the precision](https://www.algolia.com/doc/guides/managing-results/must-do/custom-ranking/how-to/controlling-custom-ranking-metrics-precision/) of your first attributes,\nor the other attributes will never be applied.\n", - "default": [], - "x-categories": ["Ranking"] - } - } - }, - "indexSettings": { - "description": "Index settings.", - "allOf": [ - { - "$ref": "#/components/schemas/baseIndexSettings" - }, - { - "$ref": "#/components/schemas/indexSettingsAsSearchParams" - } - ], - "unevaluatedProperties": false - }, - "WithPrimary": { - "type": "object", - "properties": { - "primary": { - "type": "string", - "description": "Replica indices only: the name of the primary index for this replica.\n" - } - } - }, - "settingsResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/indexSettings" - }, - { - "$ref": "#/components/schemas/WithPrimary" - } - ], - "unevaluatedProperties": false - }, - "SynonymType": { - "type": "string", - "description": "Synonym type.", - "example": "onewaysynonym", - "enum": [ - "synonym", - "onewaysynonym", - "altcorrection1", - "altcorrection2", - "placeholder", - "oneWaySynonym", - "altCorrection1", - "altCorrection2" - ] - }, - "synonymHit": { - "type": "object", - "description": "Synonym object.", - "additionalProperties": false, - "properties": { - "objectID": { - "type": "string", - "description": "Unique identifier of a synonym object.", - "example": "synonymID" - }, - "type": { - "$ref": "#/components/schemas/SynonymType" - }, - "synonyms": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Words or phrases considered equivalent.", - "example": ["vehicle", "auto"] - }, - "input": { - "type": "string", - "description": "Word or phrase to appear in query strings (for [`onewaysynonym`s](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/one-way-synonyms/)).", - "example": "car" - }, - "word": { - "type": "string", - "description": "Word or phrase to appear in query strings (for [`altcorrection1` and `altcorrection2`](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-alternative-corrections/)).", - "example": "car" - }, - "corrections": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Words to be matched in records.", - "example": ["vehicle", "auto"] - }, - "placeholder": { - "type": "string", - "description": "[Placeholder token](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-placeholders/) to be put inside records.\n", - "example": "" - }, - "replacements": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Query words that will match the [placeholder token](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/adding-synonyms/in-depth/synonyms-placeholders/).", - "example": ["street", "st"] - } - }, - "required": ["objectID", "type"] - }, - "id": { - "type": "string", - "example": "12", - "description": "Unique identifier of a synonym object." - }, - "synonymHits": { - "type": "array", - "description": "Matching synonyms.", - "items": { - "$ref": "#/components/schemas/synonymHit" - } - }, - "searchSynonymsResponse": { - "type": "object", - "additionalProperties": true, - "properties": { - "hits": { - "$ref": "#/components/schemas/synonymHits" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - } - }, - "required": ["hits", "nbHits"] - }, - "keyString": { - "type": "string", - "description": "API key.", - "example": "13ad45b4d0a2f6ea65ecbddf6aa260f2" - }, - "createdAtTimestamp": { - "type": "integer", - "format": "int64", - "example": 1656345570000, - "description": "Timestamp when the object was created, in milliseconds since the Unix epoch." - }, - "baseGetApiKeyResponse": { - "type": "object", - "properties": { - "value": { - "$ref": "#/components/schemas/keyString" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAtTimestamp" - } - }, - "required": ["value", "createdAt"] - }, - "acl": { - "description": "Access control list permissions.", - "type": "string", - "enum": [ - "addObject", - "analytics", - "browse", - "deleteObject", - "deleteIndex", - "editSettings", - "inference", - "listIndexes", - "logs", - "personalization", - "recommendation", - "search", - "seeUnretrievableAttributes", - "settings", - "usage" - ] - }, - "apiKey": { - "type": "object", - "description": "API key object.", - "properties": { - "acl": { - "type": "array", - "description": "Permissions that determine the type of API requests this key can make.\nThe required ACL is listed in each endpoint's reference.\nFor more information, see [access control list](https://www.algolia.com/doc/guides/security/api-keys/#access-control-list-acl).\n", - "example": ["search", "addObject"], - "default": [], - "items": { - "$ref": "#/components/schemas/acl" - } - }, - "description": { - "type": "string", - "description": "Description of an API key to help you identify this API key.", - "example": "Used for indexing by the CLI", - "default": "" - }, - "indexes": { - "type": "array", - "description": "Index names or patterns that this API key can access.\nBy default, an API key can access all indices in the same application.\n\nYou can use leading and trailing wildcard characters (`*`):\n\n- `dev_*` matches all indices starting with \"dev_\".\n- `*_dev` matches all indices ending with \"_dev\".\n- `*_products_*` matches all indices containing \"_products_\".\n", - "example": ["dev_*", "prod_en_products"], - "default": [], - "items": { - "type": "string" - } - }, - "maxHitsPerQuery": { - "type": "integer", - "description": "Maximum number of results this API key can retrieve in one query.\nBy default, there's no limit.\n", - "default": 0 - }, - "maxQueriesPerIPPerHour": { - "type": "integer", - "description": "Maximum number of API requests allowed per IP address or [user token](https://www.algolia.com/doc/guides/sending-events/concepts/usertoken/) per hour.\n\nIf this limit is reached, the API returns an error with status code `429`.\nBy default, there's no limit.\n", - "default": 0 - }, - "queryParameters": { - "type": "string", - "description": "Query parameters to add when making API requests with this API key.\n\nTo restrict this API key to specific IP addresses, add the `restrictSources` parameter.\nYou can only add a single source, but you can provide a range of IP addresses.\n\nCreating an API key fails if the request is made from an IP address outside the restricted range.\n", - "example": "typoTolerance=strict&restrictSources=192.168.1.0/24", - "default": "" - }, - "referers": { - "type": "array", - "description": "Allowed HTTP referrers for this API key.\n\nBy default, all referrers are allowed.\nYou can use leading and trailing wildcard characters (`*`):\n\n- `https://algolia.com/*` allows all referrers starting with \"https://algolia.com/\"\n- `*.algolia.com` allows all referrers ending with \".algolia.com\"\n- `*algolia.com*` allows all referrers in the domain \"algolia.com\".\n\nLike all HTTP headers, referrers can be spoofed. Don't rely on them to secure your data.\nFor more information, see [HTTP referrer restrictions](https://www.algolia.com/doc/guides/security/security-best-practices/#http-referrers-restrictions).\n", - "example": ["*algolia.com*"], - "default": [], - "items": { - "type": "string" - } - }, - "validity": { - "type": "integer", - "description": "Duration (in seconds) after which the API key expires.\nBy default, API keys don't expire.\n", - "example": 86400, - "default": 0 - } - }, - "required": ["acl"] - }, - "getApiKeyResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/baseGetApiKeyResponse" - }, - { - "$ref": "#/components/schemas/apiKey" - } - ], - "unevaluatedProperties": false - }, - "addApiKeyResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "key": { - "$ref": "#/components/schemas/keyString" - }, - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - }, - "required": ["key", "createdAt"] - }, - "ruleID": { - "title": "objectID", - "type": "string", - "description": "Unique identifier of a rule object." - }, - "anchoring": { - "type": "string", - "description": "Which part of the search query the pattern should match:\n\n- `startsWith`. The pattern must match the beginning of the query.\n- `endsWith`. The pattern must match the end of the query.\n- `is`. The pattern must match the query exactly.\n- `contains`. The pattern must match anywhere in the query.\n\nEmpty queries are only allowed as patterns with `anchoring: is`.\n", - "enum": ["is", "startsWith", "endsWith", "contains"] - }, - "context": { - "type": "string", - "pattern": "[A-Za-z0-9_-]+", - "description": "An additional restriction that only triggers the rule, when the search has the same value as `ruleContexts` parameter.\nFor example, if `context: mobile`, the rule is only triggered when the search request has a matching `ruleContexts: mobile`.\nA rule context must only contain alphanumeric characters.\n", - "example": "mobile" - }, - "condition": { - "type": "object", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string", - "description": "Query pattern that triggers the rule.\n\nYou can use either a literal string, or a special pattern `{facet:ATTRIBUTE}`, where `ATTRIBUTE` is a facet name.\nThe rule is triggered if the query matches the literal string or a value of the specified facet.\nFor example, with `pattern: {facet:genre}`, the rule is triggered when users search for a genre, such as \"comedy\".\n", - "example": "{facet:genre}" - }, - "anchoring": { - "$ref": "#/components/schemas/anchoring" - }, - "alternatives": { - "type": "boolean", - "description": "Whether the pattern should match plurals, synonyms, and typos.", - "default": false - }, - "context": { - "$ref": "#/components/schemas/context" - }, - "filters": { - "type": "string", - "description": "Filters that trigger the rule.\n\nYou can add filters using the syntax `facet:value` so that the rule is triggered, when the specific filter is selected.\nYou can use `filters` on its own or combine it with the `pattern` parameter.\nYou can't combine multiple filters with `OR` and you can't use numeric filters.\n", - "example": "genre:comedy" - } - } - }, - "editType": { - "description": "Type of edit.", - "type": "string", - "enum": ["remove", "replace"] - }, - "edit": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "$ref": "#/components/schemas/editType" - }, - "delete": { - "description": "Text or patterns to remove from the query string.", - "type": "string" - }, - "insert": { - "description": "Text to be added in place of the deleted text inside the query string.", - "type": "string" - } - } - }, - "consequenceQueryObject": { - "type": "object", - "additionalProperties": false, - "properties": { - "remove": { - "description": "Words to remove from the search query.", - "type": "array", - "items": { - "type": "string" - } - }, - "edits": { - "description": "Changes to make to the search query.", - "type": "array", - "items": { - "$ref": "#/components/schemas/edit" - } - } - } - }, - "consequenceQuery": { - "description": "Replace or edit the search query.\n\nIf `consequenceQuery` is a string, the entire search query is replaced with that string.\nIf `consequenceQuery` is an object, it describes incremental edits made to the query.\n", - "oneOf": [ - { - "$ref": "#/components/schemas/consequenceQueryObject" - }, - { - "type": "string" - } - ] - }, - "automaticFacetFilter": { - "type": "object", - "description": "Filter or optional filter to be applied to the search.", - "additionalProperties": false, - "properties": { - "facet": { - "type": "string", - "description": "Facet name to be applied as filter.\nThe name must match placeholders in the `pattern` parameter.\nFor example, with `pattern: {facet:genre}`, `automaticFacetFilters` must be `genre`.\n" - }, - "score": { - "type": "integer", - "default": 1, - "description": "Filter scores to give different weights to individual filters." - }, - "disjunctive": { - "type": "boolean", - "default": false, - "description": "Whether the filter is disjunctive or conjunctive.\n\nIf true the filter has multiple matches, multiple occurences are combined with the logical `OR` operation.\nIf false, multiple occurences are combined with the logical `AND` operation.\n" - } - }, - "required": ["facet"] - }, - "automaticFacetFilters": { - "description": "Filter to be applied to the search.\n\nYou can use this to respond to search queries that match a facet value.\nFor example, if users search for \"comedy\", which matches a facet value of the \"genre\" facet,\nyou can filter the results to show the top-ranked comedy movies.\n", - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/components/schemas/automaticFacetFilter" - } - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "params": { - "type": "object", - "description": "Parameters to apply to this search.\n\nYou can use all search parameters, plus special `automaticFacetFilters`, `automaticOptionalFacetFilters`, and `query`.\n", - "properties": { - "query": { - "$ref": "#/components/schemas/consequenceQuery" - }, - "automaticFacetFilters": { - "$ref": "#/components/schemas/automaticFacetFilters" - }, - "automaticOptionalFacetFilters": { - "$ref": "#/components/schemas/automaticFacetFilters" - }, - "renderingContent": { - "$ref": "#/components/schemas/renderingContent" - } - } - }, - "consequenceParams": { - "allOf": [ - { - "$ref": "#/components/schemas/baseSearchParamsWithoutQuery" - }, - { - "$ref": "#/components/schemas/indexSettingsAsSearchParams" - }, - { - "$ref": "#/components/schemas/params" - } - ], - "unevaluatedProperties": false - }, - "promotePosition": { - "type": "integer", - "description": "Position in the search results where you want to show the promoted records.", - "example": 0 - }, - "promoteObjectIDs": { - "title": "objectIDs", - "description": "Records to promote.", - "type": "object", - "additionalProperties": false, - "properties": { - "objectIDs": { - "type": "array", - "maxItems": 100, - "description": "Object IDs of the records you want to promote.\n\nThe records are placed as a group at the `position`.\nFor example, if you want to promote four records to position `0`,\nthey will be the first four search results.\n", - "items": { - "$ref": "#/components/schemas/objectID" - } - }, - "position": { - "$ref": "#/components/schemas/promotePosition" - } - }, - "required": ["position", "objectIDs"], - "x-discriminator-fields": ["objectIDs"] - }, - "promoteObjectID": { - "title": "objectID", - "description": "Record to promote.", - "type": "object", - "additionalProperties": false, - "properties": { - "objectID": { - "$ref": "#/components/schemas/objectID" - }, - "position": { - "$ref": "#/components/schemas/promotePosition" - } - }, - "required": ["position", "objectID"], - "x-discriminator-fields": ["objectID"] - }, - "promote": { - "oneOf": [ - { - "$ref": "#/components/schemas/promoteObjectIDs" - }, - { - "$ref": "#/components/schemas/promoteObjectID" - } - ] - }, - "consequence": { - "type": "object", - "description": "Effect of the rule.\n\nFor more information, see [Consequences](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/#consequences).\n", - "additionalProperties": false, - "properties": { - "params": { - "$ref": "#/components/schemas/consequenceParams" - }, - "promote": { - "type": "array", - "maxItems": 300, - "description": "Records you want to pin to a specific position in the search results.\n\nYou can promote up to 300 records, either individually, or as groups of up to 100 records each.\n", - "items": { - "$ref": "#/components/schemas/promote" - } - }, - "filterPromotes": { - "type": "boolean", - "default": false, - "description": "Whether promoted records must match an active filter for the consequence to be applied.\n\nThis ensures that user actions (filtering the search) are given a higher precendence.\nFor example, if you promote a record with the `color: red` attribute, and the user filters the search for `color: blue`,\nthe \"red\" record won't be shown.\n" - }, - "hide": { - "type": "array", - "maxItems": 50, - "description": "Records you want to hide from the search results.", - "items": { - "title": "consequenceHide", - "type": "object", - "description": "Object ID of the record to hide.", - "additionalProperties": false, - "properties": { - "objectID": { - "$ref": "#/components/schemas/objectID" - } - }, - "required": ["objectID"] - } - }, - "userData": { - "type": "object", - "description": "A JSON object with custom data that will be appended to the `userData` array in the response.\nThis object isn't interpreted by the API and is limited to 1 kB of minified JSON.\n", - "example": { - "settingID": "f2a7b51e3503acc6a39b3784ffb84300", - "pluginVersion": "1.6.0" - } - } - } - }, - "timeRange": { - "type": "object", - "additionalProperties": false, - "properties": { - "from": { - "type": "integer", - "format": "int64", - "description": "When the rule should start to be active, in Unix epoch time." - }, - "until": { - "type": "integer", - "format": "int64", - "description": "When the rule should stop to be active, in Unix epoch time." - } - }, - "required": ["from", "until"] - }, - "rule": { - "type": "object", - "description": "Rule object.", - "additionalProperties": false, - "properties": { - "objectID": { - "$ref": "#/components/schemas/ruleID" - }, - "conditions": { - "type": "array", - "minItems": 0, - "maxItems": 25, - "description": "Conditions that trigger a rule.\n\nSome consequences require specific conditions or don't require any condition.\nFor more information, see [Conditions](https://www.algolia.com/doc/guides/managing-results/rules/rules-overview/#conditions).\n", - "items": { - "$ref": "#/components/schemas/condition" - } - }, - "consequence": { - "$ref": "#/components/schemas/consequence" - }, - "description": { - "type": "string", - "description": "Description of the rule's purpose to help you distinguish between different rules.", - "example": "Display a promotional banner" - }, - "enabled": { - "type": "boolean", - "default": true, - "description": "Whether the rule is active." - }, - "validity": { - "type": "array", - "description": "Time periods when the rule is active.", - "items": { - "$ref": "#/components/schemas/timeRange" - } - } - }, - "required": ["objectID", "consequence"] - }, - "parameters_query": { - "type": "string", - "description": "Search query for rules.", - "default": "" - }, - "parameters_page": { - "type": "integer", - "minimum": 0, - "description": "Requested page of the API response.\n\nAlgolia uses `page` and `hitsPerPage` to control how search results are displayed ([paginated](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/pagination/js/)).\n\n- `hitsPerPage`: sets the number of search results (_hits_) displayed per page.\n- `page`: specifies the page number of the search results you want to retrieve. Page numbering starts at 0, so the first page is `page=0`, the second is `page=1`, and so on.\n\nFor example, to display 10 results per page starting from the third page, set `hitsPerPage` to 10 and `page` to 2.\n" - }, - "parameters_hitsPerPage": { - "type": "integer", - "default": 20, - "minimum": 1, - "maximum": 1000, - "description": "Maximum number of hits per page.\n\nAlgolia uses `page` and `hitsPerPage` to control how search results are displayed ([paginated](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/pagination/js/)).\n\n- `hitsPerPage`: sets the number of search results (_hits_) displayed per page.\n- `page`: specifies the page number of the search results you want to retrieve. Page numbering starts at 0, so the first page is `page=0`, the second is `page=1`, and so on.\n\nFor example, to display 10 results per page starting from the third page, set `hitsPerPage` to 10 and `page` to 2.\n" - }, - "dictionaryType": { - "type": "string", - "enum": ["plurals", "stopwords", "compounds"] - }, - "dictionaryAction": { - "type": "string", - "enum": ["addEntry", "deleteEntry"], - "description": "Actions to perform." - }, - "dictionaryEntryState": { - "type": "string", - "enum": ["enabled", "disabled"], - "default": "enabled", - "description": "Whether a dictionary entry is active." - }, - "dictionaryEntryType": { - "type": "string", - "enum": ["custom", "standard"], - "description": "Whether a dictionary entry is provided by Algolia (standard), or has been added by you (custom)." - }, - "dictionaryEntry": { - "type": "object", - "description": "Dictionary entry.", - "additionalProperties": true, - "required": ["objectID"], - "properties": { - "objectID": { - "type": "string", - "description": "Unique identifier for the dictionary entry.", - "example": "828afd405e1f4fe950b6b98c2c43c032" - }, - "language": { - "$ref": "#/components/schemas/supportedLanguage" - }, - "word": { - "type": "string", - "description": "Matching dictionary word for `stopwords` and `compounds` dictionaries.", - "example": "the" - }, - "words": { - "type": "array", - "description": "Matching words in the `plurals` dictionary including declensions.", - "example": ["cheval", "cheveaux"], - "items": { - "type": "string" - } - }, - "decomposition": { - "type": "array", - "description": "Invividual components of a compound word in the `compounds` dictionary.", - "example": ["kopf", "schmerz", "tablette"], - "items": { - "type": "string" - } - }, - "state": { - "$ref": "#/components/schemas/dictionaryEntryState" - }, - "type": { - "$ref": "#/components/schemas/dictionaryEntryType" - } - } - }, - "searchDictionaryEntriesResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "hits": { - "type": "array", - "description": "Dictionary entries matching the search criteria.", - "items": { - "$ref": "#/components/schemas/dictionaryEntry" - } - }, - "page": { - "$ref": "#/components/schemas/parameters_page" - }, - "nbHits": { - "$ref": "#/components/schemas/nbHits" - }, - "nbPages": { - "$ref": "#/components/schemas/nbPages" - } - }, - "required": ["hits", "page", "nbHits", "nbPages"] - }, - "standardEntry": { - "oneOf": [ - { - "type": "object", - "description": "Key-value pair of a language ISO code and a boolean value.", - "example": { - "fr": false - }, - "additionalProperties": { - "x-additionalPropertiesName": "language", - "type": "boolean" - } - }, - { - "type": "null" - } - ] - }, - "standardEntries": { - "type": "object", - "description": "Key-value pairs of [supported language ISO codes](https://www.algolia.com/doc/guides/managing-results/optimize-search-results/handling-natural-languages-nlp/in-depth/supported-languages/) and boolean values.\n", - "additionalProperties": false, - "properties": { - "plurals": { - "$ref": "#/components/schemas/standardEntry" - }, - "stopwords": { - "$ref": "#/components/schemas/standardEntry" - }, - "compounds": { - "$ref": "#/components/schemas/standardEntry" - } - } - }, - "dictionaryLanguage": { - "oneOf": [ - { - "type": "object", - "additionalProperties": false, - "description": "Dictionary type. If `null`, this dictionary type isn't supported for the language.", - "properties": { - "nbCustomEntries": { - "description": "Number of custom dictionary entries.", - "type": "integer" - } - } - }, - { - "type": "null" - } - ] - }, - "languages": { - "type": "object", - "description": "Dictionary language.", - "additionalProperties": false, - "required": ["plurals", "stopwords", "compounds"], - "properties": { - "plurals": { - "$ref": "#/components/schemas/dictionaryLanguage" - }, - "stopwords": { - "$ref": "#/components/schemas/dictionaryLanguage" - }, - "compounds": { - "$ref": "#/components/schemas/dictionaryLanguage" - } - } - }, - "userID": { - "type": "string", - "pattern": "^[a-zA-Z0-9 \\-*.]+$", - "description": "Unique identifier of the user who makes the search request.", - "example": "user1" - }, - "userId": { - "title": "userID", - "type": "object", - "description": "Unique user ID.", - "properties": { - "userID": { - "$ref": "#/components/schemas/userID" - }, - "clusterName": { - "type": "string", - "description": "Cluster to which the user is assigned.", - "example": "c1-test" - }, - "nbRecords": { - "type": "integer", - "description": "Number of records belonging to the user.", - "example": 42 - }, - "dataSize": { - "type": "integer", - "description": "Data size used by the user.", - "example": 0 - } - }, - "required": ["userID", "clusterName", "nbRecords", "dataSize"] - }, - "clusterName": { - "type": "string", - "description": "Cluster name.", - "example": "c11-test" - }, - "nbRecords": { - "type": "integer", - "description": "Number of records in the cluster.", - "example": 3 - }, - "dataSize": { - "type": "integer", - "description": "Data size taken by all the users assigned to the cluster.", - "example": 481 - }, - "source": { - "type": "object", - "description": "Source.", - "required": ["source"], - "properties": { - "source": { - "description": "IP address range of the source.", - "type": "string", - "example": "10.0.0.1/32" - }, - "description": { - "description": "Source description.", - "type": "string", - "example": "Server subnet" - } - } - }, - "sources": { - "description": "Sources.", - "type": "array", - "items": { - "$ref": "#/components/schemas/source" - } - }, - "logType": { - "type": "string", - "enum": ["all", "query", "build", "error"], - "default": "all" - }, - "taskStatus": { - "type": "string", - "enum": ["published", "notPublished"], - "description": "Task status, `published` if the task is completed, `notPublished` otherwise." - }, - "GetTaskResponse": { - "title": "getTaskResponse", - "type": "object", - "additionalProperties": false, - "properties": { - "status": { - "$ref": "#/components/schemas/taskStatus" - } - }, - "required": ["status"] - }, - "operationType": { - "type": "string", - "enum": ["move", "copy"], - "example": "copy", - "description": "Operation to perform on the index." - }, - "scopeType": { - "type": "string", - "enum": ["settings", "synonyms", "rules"] - }, - "fetchedIndex": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "Index name.", - "example": "movies" - }, - "createdAt": { - "type": "string", - "description": "Index creation date. An empty string means that the index has no records.", - "example": "2022-09-19T16:36:44.471Z" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - }, - "entries": { - "type": "integer", - "description": "Number of records contained in the index.", - "example": 100 - }, - "dataSize": { - "type": "integer", - "description": "Number of bytes of the index in minified format.", - "example": 48450 - }, - "fileSize": { - "type": "integer", - "description": "Number of bytes of the index binary file.", - "example": 112927 - }, - "lastBuildTimeS": { - "type": "integer", - "description": "Last build time.", - "example": 3 - }, - "numberOfPendingTasks": { - "type": "integer", - "default": 0, - "description": "Number of pending indexing operations. This value is deprecated and should not be used." - }, - "pendingTask": { - "type": "boolean", - "default": false, - "description": "A boolean which says whether the index has pending tasks. This value is deprecated and should not be used." - }, - "primary": { - "type": "string", - "description": "Only present if the index is a replica. Contains the name of the related primary index.", - "example": "T02" - }, - "replicas": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Only present if the index is a primary index with replicas. Contains the names of all linked replicas.", - "example": ["T02_push", "T2replica"] - }, - "virtual": { - "type": "boolean", - "description": "Only present if the index is a [virtual replica](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-an-index-alphabetically/#virtual-replicas).", - "x-categories": ["Ranking"] - } - }, - "required": [ - "name", - "createdAt", - "updatedAt", - "entries", - "dataSize", - "fileSize", - "lastBuildTimeS", - "pendingTask", - "numberOfPendingTasks" - ] - }, - "listIndicesResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "items": { - "type": "array", - "description": "All indices in your Algolia application.", - "items": { - "$ref": "#/components/schemas/fetchedIndex" - } - }, - "nbPages": { - "type": "integer", - "description": "Number of pages.", - "example": 100 - } - }, - "required": ["items"] - }, - "apiKeyOperation": { - "type": "string", - "enum": ["add", "delete", "update"] - }, - "securedApiKeyRestrictions": { - "type": "object", - "additionalProperties": false, - "properties": { - "searchParams": { - "$ref": "#/components/schemas/searchParamsObject" - }, - "filters": { - "type": "string", - "description": "Filters that apply to every search made with the secured API key.\nExtra filters added at search time will be combined with `AND`.\nFor example, if you set `group:admin` as fixed filter on your generated API key,\nand add `groups:visitors` to the search query, the complete set of filters will be `group:admin AND groups:visitors`.\n" - }, - "validUntil": { - "type": "integer", - "format": "int64", - "description": "Timestamp when the secured API key expires, measured in seconds since the Unix epoch." - }, - "restrictIndices": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Index names or patterns that this API key can access.\nBy default, an API key can access all indices in the same application.\n\nYou can use leading and trailing wildcard characters (`*`):\n\n- `dev_*` matches all indices starting with \"dev_\".\n- `*_dev` matches all indices ending with \"_dev\".\n- `*_products_*` matches all indices containing \"_products_\".\n" - }, - "restrictSources": { - "type": "string", - "description": "IP network that are allowed to use this key.\n\nYou can only add a single source, but you can provide a range of IP addresses.\nUse this to protect against API key leaking and reuse.\n", - "example": "192.168.1.0/24" - }, - "userToken": { - "type": "string", - "description": "Pseudonymous user identifier to restrict usage of this API key to specific users.\n\nBy default, rate limits are set based on IP addresses. This can be an issue if many users search from the same IP address.\nTo avoid this, add a user token to each generated API key.\n" - } - } - }, - "replaceAllObjectsResponse": { - "type": "object", - "additionalProperties": false, - "properties": { - "copyOperationResponse": { - "description": "The response of the `operationIndex` request for the `copy` operation.", - "$ref": "#/components/schemas/updatedAtResponse" - }, - "batchResponses": { - "type": "array", - "description": "The response of the `batch` request(s).", - "items": { - "$ref": "#/components/schemas/batchResponse" - } - }, - "moveOperationResponse": { - "description": "The response of the `operationIndex` request for the `move` operation.", - "$ref": "#/components/schemas/updatedAtResponse" - } - }, - "required": ["copyOperationResponse", "batchResponses", "moveOperationResponse"] - }, - "builtInOperationType": { - "type": "string", - "enum": [ - "Increment", - "Decrement", - "Add", - "Remove", - "AddUnique", - "IncrementFrom", - "IncrementSet" - ], - "description": "How to change the attribute." - }, - "builtInOperationValue": { - "oneOf": [ - { - "type": "string", - "description": "A string to append or remove for the `Add`, `Remove`, and `AddUnique` operations." - }, - { - "type": "integer", - "description": "A number to add, remove, or append, depending on the operation." - } - ] - }, - "builtInOperation": { - "type": "object", - "description": "Update to perform on the attribute.", - "additionalProperties": false, - "properties": { - "_operation": { - "$ref": "#/components/schemas/builtInOperationType" - }, - "value": { - "$ref": "#/components/schemas/builtInOperationValue" - } - }, - "required": ["_operation", "value"] - } - }, - "parameters": { - "PathInPath": { - "name": "path", - "in": "path", - "description": "Path of the endpoint, anything after \"/1\" must be specified.", - "required": true, - "schema": { - "type": "string", - "example": "/keys" - } - }, - "Parameters": { - "name": "parameters", - "in": "query", - "description": "Query parameters to apply to the current query.", - "schema": { - "type": "object", - "additionalProperties": true - } - }, - "IndexName": { - "name": "indexName", - "in": "path", - "description": "Name of the index on which to perform the operation.", - "required": true, - "schema": { - "type": "string", - "example": "ALGOLIA_INDEX_NAME" - } - }, - "ObjectID": { - "name": "objectID", - "in": "path", - "description": "Unique record identifier.", - "required": true, - "schema": { - "$ref": "#/components/schemas/objectID" - } - }, - "ForwardToReplicas": { - "in": "query", - "name": "forwardToReplicas", - "required": false, - "description": "Whether changes are applied to replica indices.", - "schema": { - "type": "boolean" - } - }, - "parameters_ObjectID": { - "name": "objectID", - "in": "path", - "description": "Unique identifier of a synonym object.", - "required": true, - "schema": { - "type": "string", - "example": "synonymID" - } - }, - "ReplaceExistingSynonyms": { - "in": "query", - "name": "replaceExistingSynonyms", - "schema": { - "type": "boolean" - }, - "description": "Whether to replace all synonyms in the index with the ones sent with this request." - }, - "KeyString": { - "in": "path", - "name": "key", - "required": true, - "schema": { - "type": "string", - "example": "ALGOLIA_API_KEY" - }, - "description": "API key." - }, - "ObjectIDRule": { - "in": "path", - "name": "objectID", - "description": "Unique identifier of a rule object.", - "required": true, - "schema": { - "$ref": "#/components/schemas/ruleID" - } - }, - "ClearExistingRules": { - "in": "query", - "name": "clearExistingRules", - "required": false, - "schema": { - "type": "boolean" - }, - "description": "Whether existing rules should be deleted before adding this batch." - }, - "DictionaryName": { - "in": "path", - "name": "dictionaryName", - "description": "Dictionary type in which to search.", - "required": true, - "schema": { - "$ref": "#/components/schemas/dictionaryType" - } - }, - "Page": { - "in": "query", - "name": "page", - "description": "Requested page of the API response.\nIf `null`, the API response is not paginated.\n", - "required": false, - "schema": { - "type": "integer" - } - }, - "HitsPerPage": { - "in": "query", - "name": "hitsPerPage", - "description": "Number of hits per page.", - "required": false, - "schema": { - "type": "integer", - "default": 100 - } - }, - "UserIDInHeader": { - "name": "X-Algolia-User-ID", - "description": "Unique identifier of the user who makes the search request.", - "in": "header", - "required": true, - "schema": { - "$ref": "#/components/schemas/userID" - } - }, - "UserIDInPath": { - "name": "userID", - "description": "Unique identifier of the user who makes the search request.", - "in": "path", - "required": true, - "schema": { - "$ref": "#/components/schemas/userID" - } - } - }, - "responses": { - "BadRequest": { - "description": "Bad request or request arguments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "FeatureNotEnabled": { - "description": "This feature is not enabled on your Algolia account.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "MethodNotAllowed": { - "description": "Method not allowed with this API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "IndexNotFound": { - "description": "Index not found.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorBase" - } - } - } - }, - "DeletedAt": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "deletedAtResponse", - "description": "Response, taskID, and deletion timestamp.", - "additionalProperties": false, - "type": "object", - "required": ["taskID", "deletedAt"], - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "deletedAt": { - "$ref": "#/components/schemas/deletedAt" - } - } - } - } - } - }, - "UpdatedAtWithObjectId": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "updatedAtWithObjectIdResponse", - "description": "Response, taskID, unique object identifier, and an update timestamp.", - "additionalProperties": false, - "type": "object", - "properties": { - "taskID": { - "$ref": "#/components/schemas/taskID" - }, - "updatedAt": { - "$ref": "#/components/schemas/updatedAt" - }, - "objectID": { - "$ref": "#/components/schemas/objectID" - } - } - } - } - } - }, - "UpdatedAt": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/updatedAtResponse" - } - } - } - }, - "CreatedAt": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "title": "createdAtResponse", - "description": "Response and creation timestamp.", - "additionalProperties": false, - "type": "object", - "required": ["createdAt"], - "properties": { - "createdAt": { - "$ref": "#/components/schemas/createdAt" - } - } - } - } - } - } - } - }, - "x-tagGroups": [ - { - "name": "Search and indexing", - "tags": ["Indices", "Records", "Search"] - }, - { - "name": "Relevance", - "tags": ["Rules", "Synonyms", "Dictionaries"] - }, - { - "name": "Others", - "tags": ["Api Keys", "Clusters", "Vaults", "Advanced"] - }, - { - "name": "Models", - "tags": ["_model_index_settings"] - } - ] -} diff --git a/src/data/usage-api-v2.json b/src/data/usage-api-v2.json deleted file mode 100644 index 7b0203f..0000000 --- a/src/data/usage-api-v2.json +++ /dev/null @@ -1,361 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "title": "Usage API", - "version": "2.0.0", - "description": "API that returns Algolia usage metrics" - }, - "servers": [ - { - "url": "https://usage.algolia.com", - "description": "Production server" - } - ], - "paths": { - "/2/metrics/registry": { - "get": { - "summary": "Returns the list of available metrics", - "operationId": "retrieveMetricsRegistry", - "parameters": [ - { - "$ref": "#/components/parameters/ApplicationsID" - } - ], - "responses": { - "200": { - "description": "List of available metrics returned successfully", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MetricsRegistryResponse" - } - } - } - }, - "401": { - "$ref": "#/components/responses/UnauthorizedResponse" - } - } - } - }, - "/2/metrics/daily": { - "get": { - "summary": "Returns a list of billing metrics per day for the specified applications", - "operationId": "retrieveMetricsDaily", - "parameters": [ - { - "$ref": "#/components/parameters/ApplicationsID" - }, - { - "name": "startDate", - "in": "query", - "required": true, - "schema": { - "type": "string", - "format": "date" - }, - "description": "The start date of the period for which the metrics should be returned. The start date should be anterior to current date." - }, - { - "name": "endDate", - "in": "query", - "schema": { - "type": "string", - "format": "date" - }, - "description": "The end date (included) of the period for which the metrics should be returned. The end date should be posterior to start date and not in the future.\nIf unset, the current date will be used." - }, - { - "$ref": "#/components/parameters/MetricNames" - } - ], - "responses": { - "200": { - "description": "List of usage metrics returned successfully", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DailyMetricsResponse" - } - } - } - }, - "422": { - "description": "Invalid request", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "string", - "example": "request validation: application is required" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/UnauthorizedResponse" - } - } - } - }, - "/2/metrics/hourly": { - "get": { - "summary": "Returns a list of billing metrics per hour for the specified application", - "operationId": "retrieveApplicationMetricsHourly", - "parameters": [ - { - "$ref": "#/components/parameters/ApplicationID" - }, - { - "$ref": "#/components/parameters/MetricNames" - }, - { - "name": "startTime", - "in": "query", - "required": true, - "schema": { - "type": "string", - "format": "date-time" - }, - "description": "The start time of the period for which the metrics should be returned. The start time should be anterior to current time." - }, - { - "name": "endTime", - "in": "query", - "schema": { - "type": "string", - "format": "date-time" - }, - "description": "The end time (included) of the period for which the metrics should be returned. The end time should be posterior to start time and not in the future.\nIf unset, the current date will be used." - } - ], - "responses": { - "200": { - "description": "List of usage metrics returned successfully", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HourlyApplicationMetricsResponse" - } - } - } - }, - "422": { - "description": "Invalid request", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "string", - "example": "request validation: application is required" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/UnauthorizedResponse" - } - } - } - } - }, - "components": { - "parameters": { - "ApplicationsID": { - "name": "application", - "in": "query", - "description": "List of Algolia Application IDs", - "required": true, - "schema": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[_a-zA-Z0-9]{1,30}$", - "minLength": 1, - "maxLength": 30 - } - } - }, - "ApplicationID": { - "name": "application", - "in": "path", - "description": "Algolia Application ID", - "required": true, - "schema": { - "type": "string", - "pattern": "^[_a-zA-Z0-9]{1,30}$", - "minLength": 1, - "maxLength": 30 - } - }, - "MetricNames": { - "name": "name", - "in": "query", - "required": true, - "description": "Any metric name. Available metrics are listed in endpoint /2/metrics/registry", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "responses": { - "UnauthorizedResponse": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { - "type": "integer", - "example": 401 - }, - "message": { - "type": "string", - "example": "Invalid credential" - } - } - } - } - } - } - }, - "schemas": { - "DailyMetricsResponse": { - "type": "object", - "properties": { - "applications": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/DailyEntries" - } - } - } - }, - "DailyEntries": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DailyEntry" - } - }, - "DailyEntry": { - "type": "object", - "required": ["date", "values"], - "properties": { - "date": { - "type": "string", - "format": "date", - "description": "The date for the given metric values" - }, - "values": { - "$ref": "#/components/schemas/MetricsValues" - } - } - }, - "MetricsValues": { - "type": "object", - "additionalProperties": { - "type": "integer", - "format": "int64" - }, - "description": "Map of metrics values where key is metric name and value is metric value for a given period (day or hour).", - "example": { - "metric1": 12345, - "metric2": 98765 - } - }, - "HourlyApplicationMetricsResponse": { - "type": "object", - "properties": { - "metrics": { - "$ref": "#/components/schemas/HourlyEntries" - } - } - }, - "HourlyEntries": { - "type": "array", - "items": { - "$ref": "#/components/schemas/HourlyEntry" - } - }, - "HourlyEntry": { - "type": "object", - "required": ["date", "values"], - "properties": { - "time": { - "type": "string", - "format": "date-time", - "description": "The time for the given metric values" - }, - "values": { - "$ref": "#/components/schemas/MetricsValues" - } - } - }, - "MetricsRegistryResponse": { - "type": "object", - "properties": { - "metrics": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MetricDefinition" - } - } - } - }, - "MetricDefinition": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the metric (unique)" - }, - "label": { - "type": "string", - "description": "The label of the metric" - }, - "description": { - "type": "string", - "description": "The description of the metric" - } - }, - "example": { - "name": "queries_operations", - "label": "Query operations", - "description": "Number of single [queries](https://www.algolia.com/doc/rest-api/search/#search-index-post)" - } - } - }, - "securitySchemes": { - "applicationId": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-application-id", - "description": "Your Algolia application ID." - }, - "apiKey": { - "type": "apiKey", - "in": "header", - "name": "x-algolia-api-key", - "description": "Your Algolia API key with the necessary permissions to make the request.\nPermissions are controlled through access control lists (ACL) and access restrictions.\nThe required ACL to make a request is listed in each endpoint's reference.\n" - } - } - }, - "security": [ - { - "applicationId": [], - "apiKey": [] - } - ] -} diff --git a/src/logging.ts b/src/logging.ts new file mode 100644 index 0000000..fd20399 --- /dev/null +++ b/src/logging.ts @@ -0,0 +1,10 @@ +import { OpenTelemetryTransportV3 } from "@opentelemetry/winston-transport"; +import { createLogger, format, transports } from "winston"; + +import { config } from "./config"; + +export const logger = createLogger({ + level: config.isDevelopment ? config.LOG_LEVEL : "info", + format: format.combine(format.timestamp(), format.json()), + transports: [new transports.Console(), new OpenTelemetryTransportV3()], +}); diff --git a/src/mcpServer.ts b/src/mcpServer.ts new file mode 100644 index 0000000..c10de3d --- /dev/null +++ b/src/mcpServer.ts @@ -0,0 +1,27 @@ +import { config } from "./config"; +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { algoliasearch } from "algoliasearch"; + +import { registerGetAlgoliaSearchSingleIndexTool } from "./tools/search/getAlgoliaSearchSingleIndexTool"; +import { registerGetAlgoliaTopSearchesTool } from "./tools/analytics/getAlgoliaTopSearchesTool"; +import type { Region } from "./tools/toolConfig"; + +/** + * Creates a Model Context Protocol (MCP) server + */ +export function createAlgoliaMcpServer(appId: string, apiKey: string, region: Region): McpServer { + const mcpServer = new McpServer({ + name: "algolia-mcp", + version: config.VERSION, + }); + + const algoliaApi = algoliasearch(appId, apiKey); + algoliaApi.addAlgoliaAgent("algolia-mcp-server", config.VERSION); + + const toolConfig = { mcpServer, algoliaApi, region }; + + registerGetAlgoliaSearchSingleIndexTool(toolConfig); + registerGetAlgoliaTopSearchesTool(toolConfig); + + return mcpServer; +} diff --git a/src/middleware/errorHandler.ts b/src/middleware/errorHandler.ts new file mode 100644 index 0000000..d8b50be --- /dev/null +++ b/src/middleware/errorHandler.ts @@ -0,0 +1,23 @@ +import type { NextFunction, Request, Response } from "express"; +import { ZodError } from "zod"; + +import { logger } from "../logging"; + +export const errorHandler = ( + err: Error, + _req: Request, + res: Response, + _next: NextFunction, +): void => { + logger.error(err.stack); + + if (err instanceof ZodError) { + res.status(422).json({ errors: err.errors }); + return; + } + + res.status(500).json({ + status: "error", + message: "Internal server error", + }); +}; diff --git a/src/middleware/loggerMiddleware.ts b/src/middleware/loggerMiddleware.ts new file mode 100644 index 0000000..442cec7 --- /dev/null +++ b/src/middleware/loggerMiddleware.ts @@ -0,0 +1,24 @@ +import morgan from "morgan"; + +import { logger } from "../logging"; + +export const loggerMiddleware = morgan( + function (tokens, req, res) { + return JSON.stringify({ + label: "api", + method: tokens.method(req, res), + url: tokens.url(req, res), + status: tokens.status(req, res) ?? Number.parseFloat(tokens.status(req, res)!), + content_length: tokens.res(req, res, "content-length"), + response_time: + tokens["response-time"](req, res) ?? Number.parseFloat(tokens["response-time"](req, res)!), + }); + }, + { + stream: { + write: (message) => { + logger.http("incoming-request", JSON.parse(message)); + }, + }, + }, +); diff --git a/src/openApi.ts b/src/openApi.ts deleted file mode 100644 index a5dbdcf..0000000 --- a/src/openApi.ts +++ /dev/null @@ -1,104 +0,0 @@ -import SearchSpecJson from "./data/search.json" with { type: "json" }; -import AnalyticsSpecJson from "./data/analytics.json" with { type: "json" }; -import RecommendSpecJson from "./data/recommend.json" with { type: "json" }; -import ABTestingSpecJson from "./data/abtesting.json" with { type: "json" }; -import MonitoringSpecJson from "./data/monitoring.json" with { type: "json" }; -import IngestionSpecJson from "./data/ingestion.json" with { type: "json" }; -import UsageSpecJson from "./data/usage-api-v2.json" with { type: "json" }; -import CollectionsSpecJson from "./data/collections.json" with { type: "json" }; -import QuerySuggestionsSpecJson from "./data/query-suggestions.json" with { type: "json" }; -import type { SomeJSONSchema } from "ajv/dist/types/json-schema.js"; - -// import { type JsonSchema } from "./helpers.ts"; - -export type Methods = "get" | "post" | "put" | "delete"; - -export type Operation = { - "x-helper"?: boolean; - "x-use-read-transporter"?: boolean; - operationId: string; - summary?: string; - description?: string; - parameters?: Array; - requestBody?: RequestBody; - security?: Array; -}; - -type Ref = { - $ref: string; -}; - -type Path = Record; - -export type Parameter = { - in: "query" | "path"; - name: string; - description?: string; - required?: boolean; - schema: SomeJSONSchema; -}; - -type RequestBody = { - required?: boolean; - description?: string; - content: Record; -}; - -type RequestBodyContent = { - schema: SomeJSONSchema; -}; - -export type SecurityItem = Record>; - -export type SecurityScheme = { - type: string; - in: "header" | "query"; - name: string; - description?: string; - required?: boolean; -}; - -type UrlVariable = { - default?: string; - description?: string; -}; - -export type OpenApiSpec = { - info: { - title: string; - description: string; - }; - paths: Record; - servers: Array<{ - url: string; - variables?: Record; - }>; - security?: Array; - components?: { - schemas?: Record; - parameters?: Record; - securitySchemes?: Record; - }; -}; - -export const SearchSpec = SearchSpecJson as unknown as OpenApiSpec; -export const AnalyticsSpec = AnalyticsSpecJson as unknown as OpenApiSpec; -export const RecommendSpec = RecommendSpecJson as unknown as OpenApiSpec; -export const ABTestingSpec = ABTestingSpecJson as unknown as OpenApiSpec; -export const MonitoringSpec = MonitoringSpecJson as unknown as OpenApiSpec; -export const IngestionSpec = IngestionSpecJson as unknown as OpenApiSpec; -export const UsageSpec = UsageSpecJson as unknown as OpenApiSpec; -export const CollectionsSpec = CollectionsSpecJson as unknown as OpenApiSpec; -export const QuerySuggestionsSpec = QuerySuggestionsSpecJson as unknown as OpenApiSpec; - -export const ALL_SPECS = [ - SearchSpec, - AnalyticsSpec, - RecommendSpec, - ABTestingSpec, - MonitoringSpec, - IngestionSpec, - UsageSpec, - CollectionsSpec, - QuerySuggestionsSpec, -]; diff --git a/src/routes/__tests__/mcpServerRouter.test.ts b/src/routes/__tests__/mcpServerRouter.test.ts new file mode 100644 index 0000000..da2cccb --- /dev/null +++ b/src/routes/__tests__/mcpServerRouter.test.ts @@ -0,0 +1,73 @@ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import * as StreamableHttpMock from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import type { JSONRPCError } from "@modelcontextprotocol/sdk/types.js"; +import { ErrorCode } from "@modelcontextprotocol/sdk/types.js"; +import type { Response } from "express"; +import express from "express"; +import request from "supertest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { createAlgoliaMcpServer } from "../../mcpServer"; +import { mcpServerRouter } from "../mcpServerRouter"; + +vi.mock("@modelcontextprotocol/sdk/server/streamableHttp.js", () => { + const mockHandleRequest = vi.fn(); + const MockTransport = vi.fn().mockImplementation(() => ({ handleRequest: mockHandleRequest })); + return { + StreamableHTTPServerTransport: MockTransport, + mockHandleRequest, + MockTransport, + }; +}); +const { mockHandleRequest, MockTransport } = StreamableHttpMock as unknown as { + mockHandleRequest: ReturnType; + MockTransport: ReturnType; +}; + +vi.mock("../../mcpServer", () => ({ + createAlgoliaMcpServer: vi.fn(), +})); + +const mockConnect = vi.fn(); +const mockMcpServer: McpServer = { connect: mockConnect } as unknown as McpServer; + +const app = express(); +app.use(express.json()); +app.use("/", mcpServerRouter()); + +describe("mcpServerRouter", () => { + beforeEach(() => { + mockConnect.mockReset(); + mockHandleRequest.mockReset(); + MockTransport.mockClear(); + + mockConnect.mockResolvedValue(undefined); + mockHandleRequest.mockImplementation((_req, res: Response) => { + res.status(200).end(); + }); + + (createAlgoliaMcpServer as unknown as ReturnType).mockReturnValue(mockMcpServer); + }); + + it("returns 400 if app ID & api key are missing", async () => { + const res = await request(app).post("/").send({}); + expect(res.status).toBe(400); + const body = res.body as JSONRPCError; + expect(body.error.code).toBe(ErrorCode.InvalidRequest); + }); + + it("returns 405 for non-POST methods", async () => { + const res = await request(app).get("/"); + expect(res.status).toBe(405); + expect(res.text).toContain("Method not allowed"); + }); + + it("calls createAlgoliaMcpServer, mcpServer.connect and transport.handleRequest on valid POST", async () => { + const res = await request(app).post("/").set("authorization", "Bearer appId:apiKey"); + + expect(createAlgoliaMcpServer).toHaveBeenCalledWith("appId", "apiKey", "us"); + expect(mockConnect).toHaveBeenCalled(); + expect(mockHandleRequest).toHaveBeenCalled(); + expect(res.status).not.toBe(400); + }); +}); diff --git a/src/routes/mcpServerRouter.ts b/src/routes/mcpServerRouter.ts new file mode 100644 index 0000000..64c4120 --- /dev/null +++ b/src/routes/mcpServerRouter.ts @@ -0,0 +1,70 @@ +import { Router } from "express"; +import { ErrorCode } from "@modelcontextprotocol/sdk/types.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import { createAlgoliaMcpServer } from "../mcpServer"; +import type { Region } from "../tools/toolConfig"; + +/** + * Extracts appId and apiKey from the Authorization header. + * Expected format: "Bearer :" + */ +function parseBearerAuth(header?: string): { appId?: string; apiKey?: string } { + const bearerPrefix = "Bearer "; + if (!header?.startsWith(bearerPrefix)) return {}; + const token = header.replace(bearerPrefix, "").trim(); + const [appId, apiKey] = token.split(":"); + return appId && apiKey ? { appId, apiKey } : {}; +} + +/** + * Parses and validates the "region" query parameter. + * Returns a value of type Region, defaults to "us". + */ +function parseRegion(regionParam: unknown): Region { + if (regionParam === "us" || regionParam === "de") { + return regionParam; + } + return "us"; +} + +/** + * Router for handling MCP server requests. + */ +export function mcpServerRouter(): Router { + const router = Router(); + + /** Main entry – RPC stream */ + router.post("/", async (req, res) => { + const { appId, apiKey } = parseBearerAuth(req.headers["authorization"] as string); + + if (!appId || !apiKey) { + res.status(400).json({ + jsonrpc: "2.0", + error: { + code: ErrorCode.InvalidRequest, + message: "Missing or invalid app id or api key header", + }, + id: null, + }); + return; + } + + const region = parseRegion(req.query.region); + + const mcpServer = createAlgoliaMcpServer(appId, apiKey, region); + const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined }); + await mcpServer.connect(transport); + await transport.handleRequest(req, res, req.body); + }); + + /** 405 for everything else */ + router.all("/", (_req, res) => { + res.status(405).json({ + jsonrpc: "2.0", + error: { code: ErrorCode.ConnectionClosed, message: "Method not allowed." }, + id: null, + }); + }); + + return router; +} diff --git a/src/telemetry.ts b/src/telemetry.ts new file mode 100644 index 0000000..c1725a3 --- /dev/null +++ b/src/telemetry.ts @@ -0,0 +1,11 @@ +import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api"; +import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node"; +import { NodeSDK } from "@opentelemetry/sdk-node"; + +diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR); + +const sdk = new NodeSDK({ + instrumentations: [getNodeAutoInstrumentations()], +}); + +sdk.start(); diff --git a/src/toolFilters.test.ts b/src/toolFilters.test.ts deleted file mode 100644 index 6744d59..0000000 --- a/src/toolFilters.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { describe, expect, it, test } from "vitest"; -import type { ToolFilter } from "./toolFilters.ts"; -import { getToolFilter, isToolAllowed } from "./toolFilters.ts"; - -test("getToolFilter", () => { - expect(getToolFilter({})).toEqual({ - allowedTools: undefined, - deniedTools: undefined, - }); - - expect(getToolFilter({ allowTools: ["foo"] })).toEqual({ - allowedTools: new Set(["foo"]), - deniedTools: undefined, - }); - expect(getToolFilter({ denyTools: ["foo"] })).toEqual({ - allowedTools: undefined, - deniedTools: new Set(["foo"]), - }); -}); - -describe("isToolAllowed", () => { - it("should allow all tools by default", () => { - expect(isToolAllowed("foo")).toBe(true); - }); - - it("should allow denying tools", () => { - const filter: ToolFilter = { - deniedTools: new Set(["jafar"]), - }; - expect(isToolAllowed("jafar", filter)).toBe(false); - expect(isToolAllowed("iago", filter)).toBe(true); - }); - - it("should allow tools", () => { - const filter: ToolFilter = { - allowedTools: new Set(["muphasa"]), - }; - expect(isToolAllowed("muphasa", filter)).toBe(true); - expect(isToolAllowed("scar", filter)).toBe(false); - }); - - it("should deny custom methods by default", () => { - expect(isToolAllowed("customGet")).toBe(false); - expect(isToolAllowed("customPost")).toBe(false); - expect( - isToolAllowed("customPut", { - // Even if allowed explicitely - allowedTools: new Set(["customPut"]), - }), - ).toBe(false); - }); -}); diff --git a/src/toolFilters.ts b/src/toolFilters.ts deleted file mode 100644 index 131e7c5..0000000 --- a/src/toolFilters.ts +++ /dev/null @@ -1,37 +0,0 @@ -import z from "zod"; - -export const CliFilteringOptionsSchema = z.object({ - allowTools: z.array(z.string()).optional(), - denyTools: z.array(z.string()).optional(), -}); -export type CliFilteringOptions = z.infer; - -export type ToolFilter = { - allowedTools?: Set; - deniedTools?: Set; -}; - -const INTERNAL_DENIED_TOOLS = new Set(["customGet", "customPost", "customPut", "customDelete"]); - -export const getToolFilter = (opts: CliFilteringOptions): ToolFilter => { - return { - allowedTools: opts.allowTools?.length ? new Set(opts.allowTools) : undefined, - deniedTools: opts.denyTools?.length ? new Set(opts.denyTools) : undefined, - }; -}; - -export function isToolAllowed(toolId: string, filter: ToolFilter = {}): boolean { - if (INTERNAL_DENIED_TOOLS.has(toolId)) { - return false; - } - - if (filter.deniedTools?.has(toolId)) { - return false; - } - - if (!filter.allowedTools) { - return true; - } - - return filter.allowedTools.has(toolId); -} diff --git a/src/tools/analytics/getAlgoliaTopSearchesTool.ts b/src/tools/analytics/getAlgoliaTopSearchesTool.ts new file mode 100644 index 0000000..13c5e6f --- /dev/null +++ b/src/tools/analytics/getAlgoliaTopSearchesTool.ts @@ -0,0 +1,77 @@ +import { z } from "zod"; + +import { runTextToolCall } from "../runToolCall"; + +import type { ToolRegisterConfig } from "../toolConfig"; + +/** + * Registers a tool to execute a search on a single Algolia index. + */ +export function registerGetAlgoliaTopSearchesTool(config: ToolRegisterConfig) { + const { mcpServer, algoliaApi, region } = config; + const analyticsClient = algoliaApi.initAnalytics({ region }); + + mcpServer.registerTool( + "algolia-analytics-topSearches", + { + title: "Algolia Top Searches for an Index", + description: + "Returns the most popular searches. For each search, it also includes the average number of hits.", + inputSchema: { + index: z.string().describe("Index name to make search"), + clickAnalytics: z + .boolean() + .optional() + .default(false) + .describe( + "Whether to include metrics related to click and conversion events in the response.", + ), + direction: z + .enum(["asc", "desc"]) + .optional() + .default("asc") + .describe("Sorting direction of the results: ascending (asc) or descending (desc)."), + startDate: z + .string() + .optional() + .describe("Start date of the period to analyze, in YYYY-MM-DD format."), + endDate: z + .string() + .optional() + .describe("End date of the period to analyze, in YYYY-MM-DD format."), + limit: z + .number() + .optional() + .default(10) + .describe("Number of items to return (maximum: 1000, default: 10)"), + offset: z.number().optional().default(0).describe("Position of the first item to return."), + orderBy: z + .enum(["searchCount", "averageClickPosition", "clickThroughRate", "conversionRate"]) + .optional() + .default("searchCount") + .describe( + "Attribute by which to order the response items. If the clickAnalytics parameter is false, only searchCount is available.", + ), + revenueAnalytics: z + .boolean() + .optional() + .default(false) + .describe("Whether to include metrics related to revenue events in the response."), + tags: z + .string() + .optional() + .describe( + "Tags by which to segment the analytics. You can combine multiple tags with OR and AND. Tags must be URL-encoded. Example: tags=device:mobile%20phone", + ), + }, + }, + async ({ index, ...optionalParams }) => { + return runTextToolCall(() => + analyticsClient.getTopSearches({ + index, + ...optionalParams, + }), + ); + }, + ); +} diff --git a/src/tools/registerGetApplications.ts b/src/tools/registerGetApplications.ts deleted file mode 100644 index ce9f399..0000000 --- a/src/tools/registerGetApplications.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { type DashboardApi } from "../DashboardApi.ts"; -import type { CustomMcpServer } from "../CustomMcpServer.ts"; - -export const operationId = "getApplications"; -export const description = "Gets a paginated list of Algolia applications for the current user"; - -export function registerGetApplications(server: CustomMcpServer, dashboardApi: DashboardApi) { - server.tool({ - name: operationId, - description, - annotations: { readOnlyHint: true }, - inputSchema: undefined, - cb: async () => { - const applications = await dashboardApi.getApplications(); - return JSON.stringify(applications); - }, - }); -} diff --git a/src/tools/registerGetUserInfo.ts b/src/tools/registerGetUserInfo.ts deleted file mode 100644 index c54e4cf..0000000 --- a/src/tools/registerGetUserInfo.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { CustomMcpServer } from "../CustomMcpServer.ts"; -import { type DashboardApi } from "../DashboardApi.ts"; - -export const operationId = "getUserInfo"; -export const description = "Get information about the user in the Algolia system"; - -export function registerGetUserInfo(server: CustomMcpServer, dashboardApi: DashboardApi) { - server.tool({ - name: operationId, - description, - annotations: { readOnlyHint: true }, - inputSchema: undefined, - cb: async () => { - const user = await dashboardApi.getUser(); - - return JSON.stringify(user); - }, - }); -} diff --git a/src/tools/registerOpenApi.test.ts b/src/tools/registerOpenApi.test.ts deleted file mode 100644 index 5f2b866..0000000 --- a/src/tools/registerOpenApi.test.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest"; -import { http, HttpResponse } from "msw"; -import type { ToolFilter } from "../toolFilters.ts"; -import { ALL_SPECS, SearchSpec } from "../openApi.ts"; -import type { ProcessCallbackArguments } from "./registerOpenApi.ts"; -import { registerOpenApiTools } from "./registerOpenApi.ts"; -import { setupServer } from "msw/node"; -import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js"; -import { Client } from "@modelcontextprotocol/sdk/client/index.js"; -import { - CallToolResultSchema, - ErrorCode, - ListToolsResultSchema, -} from "@modelcontextprotocol/sdk/types.js"; -import type { InputJsonSchema, ToolDefinition } from "../CustomMcpServer.ts"; -import { CustomMcpServer } from "../CustomMcpServer.ts"; - -const mswServer = setupServer(); - -beforeAll(() => mswServer.listen()); -afterEach(() => mswServer.resetHandlers()); -afterAll(() => mswServer.close()); - -const processCallbackArguments: ProcessCallbackArguments = async (params, securityKeys) => { - const result = { ...params }; - - if (securityKeys.has("applicationId")) { - result.applicationId = "simba"; - } - - if (securityKeys.has("apiKey")) { - result.apiKey = "dummy_api_key"; - } - - return result; -}; - -describe("registerOpenApiTools", () => { - it("should generate a working getSettings tool", async () => { - mswServer.use( - http.get("https://simba.algolia.net/1/indexes/indexName/settings", () => - HttpResponse.json({ searchableAttributes: ["title"] }), - ), - ); - - const server = new CustomMcpServer({ name: "algolia", version: "1.0.0" }); - const client = new Client({ name: "test client", version: "1.0.0" }); - - registerOpenApiTools({ - server, - processCallbackArguments, - openApiSpec: SearchSpec, - }); - - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - - await expect( - client.request( - { - method: "tools/call", - params: { - name: "getSettings", - arguments: { - applicationId: "SIMBA", - indexName: "indexName", - }, - }, - }, - CallToolResultSchema, - ), - ).resolves.toMatchInlineSnapshot(` - { - "content": [ - { - "text": "{"searchableAttributes":["title"]}", - "type": "text", - }, - ], - } - `); - }); - - it("should work with jsonl responses", async () => { - const toolFilter: ToolFilter = { - allowedTools: new Set(["getSettings"]), - }; - - const serverMock = { tool: vi.fn() }; - - registerOpenApiTools({ - server: serverMock, - processCallbackArguments, - openApiSpec: SearchSpec, - toolFilter, - }); - - const { cb: toolCallback } = serverMock.tool.mock - .calls[0][0] as unknown as ToolDefinition; - - const jsonlResponse = `{ "searchableAttributes": ["title"] } -{ "searchableAttributes": ["genre"] }`; - mswServer.use( - http.get("https://simba.algolia.net/1/indexes/indexName/settings", () => - HttpResponse.text(jsonlResponse), - ), - ); - const result = await toolCallback( - { - applicationId: "appId", - indexName: "indexName", - }, - // @ts-expect-error - not mocking the extra parameter - {}, - ); - - expect(result).toEqual({ - content: [ - { - text: jsonlResponse, - type: "text", - }, - ], - }); - }); - - it("should generate annotations hints", async () => { - const server = new CustomMcpServer({ name: "algolia", version: "1.0.0" }); - const client = new Client({ name: "test client", version: "1.0.0" }); - - registerOpenApiTools({ - server, - processCallbackArguments, - openApiSpec: SearchSpec, - toolFilter: { - allowedTools: new Set(["getSettings", "setSettings", "browse"]), - }, - }); - - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - - const listResult = await client.request({ method: "tools/list" }, ListToolsResultSchema); - - expect(listResult.tools).toHaveLength(3); - - const [browseTool, getSettingsTool, setSettingsTool] = listResult.tools; - - // Browse tool uses the http post method, but has the x-use-read-transporter set to true - expect(browseTool.name).toBe("browse"); - expect(browseTool.annotations).toEqual({ destructiveHint: false, readOnlyHint: true }); - - // get settings uses the http get method - expect(getSettingsTool.name).toBe("getSettings"); - expect(getSettingsTool.annotations).toEqual({ destructiveHint: false, readOnlyHint: true }); - - // set settings uses the http post method - expect(setSettingsTool.name).toBe("setSettings"); - expect(setSettingsTool.annotations).toEqual({ destructiveHint: true, readOnlyHint: false }); - }); - - it("should not crash when registering ALL tools", async () => { - const server = new CustomMcpServer({ name: "algolia", version: "1.0.0" }); - const client = new Client({ name: "test client", version: "1.0.0" }); - - for (const openApiSpec of ALL_SPECS) { - registerOpenApiTools({ - server, - processCallbackArguments, - openApiSpec, - }); - } - - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - - const { tools } = await client.listTools(); - expect(tools).toHaveLength(172); - }); - - it("should allow filtering tools", async () => { - const server = new CustomMcpServer({ name: "algolia", version: "1.0.0" }); - const client = new Client({ name: "test client", version: "1.0.0" }); - - registerOpenApiTools({ - server, - processCallbackArguments, - openApiSpec: SearchSpec, - toolFilter: { - allowedTools: new Set(["getSettings"]), - }, - }); - - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - - const { tools } = await client.listTools(); - expect(tools).toHaveLength(1); - expect(tools[0].name).toBe("getSettings"); - }); - - describe("tool arguments validation", () => { - let client: Client; - - beforeAll(async () => { - const server = new CustomMcpServer({ name: "algolia", version: "1.0.0" }); - client = new Client({ name: "test client", version: "1.0.0" }); - - registerOpenApiTools({ - server, - processCallbackArguments, - openApiSpec: SearchSpec, - }); - - const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); - await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]); - }); - - it.each<[operationId: string, description: string, params: object, valid: boolean]>([ - // Valid params - [ - "searchSingleIndex", - "query object", - { - applicationId: "1234", - indexName: "indexName", - requestBody: { query: "hello world" }, - }, - true, - ], - [ - "searchSingleIndex", - "query url", - { - applicationId: "1234", - indexName: "indexName", - requestBody: { params: "query=hello%20world" }, - }, - true, - ], - [ - "searchSingleIndex", - "complex params", - { - applicationId: "1234", - indexName: "indexName", - requestBody: { query: "hello world", attributesToRetrieve: [] }, - }, - true, - ], - [ - "searchSingleIndex", - "facetFilters", - { - applicationId: "1234", - indexName: "indexName", - requestBody: { - query: "hello world", - facetFilters: [ - ["attribute1:value", "attribute2:value"], - "attribute3:value", - ["attribute4:value", "attribute5:value"], - ], - }, - }, - true, - ], - [ - "saveRules", - "simple rule", - { - applicationId: "1234", - indexName: "indexName", - requestBody: [ - { - objectID: "1234", - condition: { - pattern: "hello world", - anchor: "end", - context: "query", - }, - consequence: { - promote: [{ objectID: "objectId1", position: 1 }], - }, - }, - ], - }, - true, - ], - - // Invalid params - [ - "searchSingleIndex", - "Invalid application id", - { - applicationId: 1234, - indexName: "indexName", - requestBody: { query: "hello world" }, - }, - false, - ], - [ - "searchSingleIndex", - "Missing index name", - { - applicationId: "1234", - requestBody: { query: "hello world" }, - }, - false, - ], - [ - "searchSingleIndex", - "Invalid query parameter", - { - applicationId: "1234", - indexName: "indexName", - requestBody: { query: false }, - }, - false, - ], - [ - "searchSingleIndex", - "Extra properties", - { - applicationId: "1234", - indexName: "indexName", - requestBody: { iDontExist: true }, - }, - false, - ], - [ - "searchSingleIndex", - "invalid facetFilters", - { - applicationId: "1234", - indexName: "indexName", - requestBody: { - query: "hello world", - facetFilters: [["attribute1:value", 2], "attribute3:value"], - }, - }, - false, - ], - [ - "saveRules", - "Invalid rule", - { - applicationId: "1234", - indexName: "indexName", - requestBody: [ - { - objectID: "1234", - condition: { - context: "query", - }, - consequence: { - promote: [{ objectID: "objectId1", position: false }], - }, - }, - ], - }, - false, - ], - ])( - "should validate parameters correctly ($0 - $1)", - async (operationId, _desc, params, valid) => { - mswServer.use(http.all(/.+/, () => Response.json({}))); - - const error = await client - .request( - { - method: "tools/call", - params: { - name: operationId, - arguments: params, - }, - }, - CallToolResultSchema, - ) - .then( - () => undefined, - (err) => err, - ); - const expectedErrorCode = valid ? undefined : ErrorCode.InvalidParams; - - expect(error?.code).toBe(expectedErrorCode); - }, - ); - }); -}); diff --git a/src/tools/registerOpenApi.ts b/src/tools/registerOpenApi.ts deleted file mode 100644 index e6e5170..0000000 --- a/src/tools/registerOpenApi.ts +++ /dev/null @@ -1,320 +0,0 @@ -import { isToolAllowed, type ToolFilter } from "../toolFilters.ts"; -import type { Methods, OpenApiSpec, Operation, Parameter, SecurityScheme } from "../openApi.ts"; -import { CONFIG } from "../config.ts"; -import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; -import type { CustomMcpServer, InputJsonSchema } from "../CustomMcpServer.ts"; -import type { SomeJSONSchema } from "ajv/dist/types/json-schema.js"; - -export type RequestMiddleware = (opts: { - request: Request; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - params: Record; -}) => Promise; - -export type ProcessInputSchema = (inputSchema: InputJsonSchema) => InputJsonSchema; -export type ProcessCallbackArguments = ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - params: Record, - securityKeys: Set, -) => Promise; - -type OpenApiToolsOptions = { - server: Pick; - openApiSpec: OpenApiSpec; - toolFilter?: ToolFilter; - requestMiddlewares?: Array; - processInputSchema?: ProcessInputSchema; - processCallbackArguments?: ProcessCallbackArguments; -}; - -export async function registerOpenApiTools({ - server, - openApiSpec, - toolFilter, - requestMiddlewares, - processCallbackArguments, - processInputSchema, -}: OpenApiToolsOptions) { - for (const [path, methods] of Object.entries(openApiSpec.paths)) { - for (const [method, operation] of Object.entries(methods)) { - if (!isToolAllowed(operation.operationId, toolFilter)) continue; - if (operation["x-helper"]) continue; - - const securityKeys = new Set( - [...(openApiSpec.security ?? []), ...(operation.security ?? [])].flatMap((item) => - Object.keys(item), - ), - ); - const securitySchemes = openApiSpec.components?.securitySchemes ?? {}; - - const toolCallback = buildToolCallback({ - path, - openApiSpec, - method: method as Methods, - operation, - processCallbackArguments, - requestMiddlewares, - securityKeys, - }); - - const isReadOnly = Boolean(method === "get" || operation["x-use-read-transporter"]); - const inputSchema: InputJsonSchema = { - type: "object", - properties: {}, - required: [], - $defs: {}, - }; - - addSecurityParametersToInputSchema(inputSchema, securityKeys, securitySchemes); - addUrlParametersToInputSchema(inputSchema, openApiSpec.servers); - addParametersToInputSchema(inputSchema, operation, openApiSpec); - - addDefinitionsToInputSchema(inputSchema, openApiSpec); - inputSchema.required = [...new Set(inputSchema.required)]; - processInputSchema?.(inputSchema); - - server.tool({ - name: operation.operationId, - description: operation.summary || operation.description || "", - annotations: { destructiveHint: !isReadOnly, readOnlyHint: isReadOnly }, - inputSchema, - cb: toolCallback, - }); - } - } -} - -type ToolCallbackBuildOptions = { - path: string; - openApiSpec: OpenApiSpec; - method: Methods; - operation: Operation; - securityKeys: Set; - processCallbackArguments?: ProcessCallbackArguments; - requestMiddlewares?: Array; -}; - -function buildToolCallback({ - path, - openApiSpec, - method, - operation, - requestMiddlewares, - securityKeys, - processCallbackArguments, -}: ToolCallbackBuildOptions) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return async (params: Record): Promise => { - // eslint-disable-next-line no-param-reassign - params = processCallbackArguments - ? await processCallbackArguments(params, securityKeys) - : params; - - const { requestBody } = params; - - if (method === "get" && requestBody) { - throw new Error("requestBody is not supported for GET requests"); - } - - const serverBaseUrl = openApiSpec.servers[0].url; - const preparedUrl = serverBaseUrl.replace(/{([^}]+)}/g, (_, key) => params[key]); - const url = new URL(preparedUrl); - url.pathname = path.replace(/{([^}]+)}/g, (_, key) => params[key]); - - if (operation.parameters) { - for (const parameter of operation.parameters) { - const resolvedParameter = - "$ref" in parameter ? resolveRef(openApiSpec, parameter.$ref) : parameter; - if (resolvedParameter.in !== "query") continue; - // TODO: throw error if param is required and not in callbackParams - if (!(resolvedParameter.name in params)) continue; - url.searchParams.set(resolvedParameter.name, params[resolvedParameter.name]); - } - } - - const body = requestBody - ? // Claude likes to send me JSON already serialized as a string... - isJsonString(requestBody) - ? requestBody - : JSON.stringify(requestBody) - : undefined; - - let request = new Request(url.toString(), { method, body }); - - if (securityKeys.size) { - const securitySchemes = openApiSpec.components?.securitySchemes ?? {}; - for (const key of securityKeys) { - const securityScheme = securitySchemes[key]; - - if (!securityScheme) { - throw new Error(`Security scheme ${key} not found`); - } else if (securityScheme.type !== "apiKey") { - throw new Error(`Unsupported security scheme type: ${securityScheme.type}`); - } - - const value: string = params[key]; - - if (!value) { - throw new Error(`Missing security parameter: ${key}`); - } - - switch (securityScheme.in) { - case "header": - request.headers.set(securityScheme.name, value); - break; - case "query": - url.searchParams.set(securityScheme.name, value); - break; - default: - throw new Error(`Unsupported security scheme in: ${securityScheme.in}`); - } - } - } - - request.headers.append("User-Agent", CONFIG.userAgent); - - if (requestMiddlewares?.length) { - for (const middleware of requestMiddlewares) { - request = await middleware({ request, params }); - } - } - - const response = await fetch(request); - const text = await response.text(); - - return { - content: [{ type: "text", text }], - }; - }; -} - -function isJsonString(json: unknown): json is string { - if (typeof json !== "string") return false; - - try { - JSON.parse(json); - return true; - } catch { - // It wasn't valid JSON - } - - return false; -} - -function addUrlParametersToInputSchema( - inputSchema: InputJsonSchema, - servers: OpenApiSpec["servers"], -) { - const vars = servers[0].variables || {}; - - for (const [name, urlVariable] of Object.entries(vars)) { - inputSchema.properties[name] = { - type: "string", - description: urlVariable.description, - }; - inputSchema.required.push(name); - } -} - -function addSecurityParametersToInputSchema( - inputSchema: InputJsonSchema, - securityKeys: Set, - securitySchemes: Record, -) { - for (const key of securityKeys) { - // Special case for API key which we don't want the AI to fill in (it will be added internally) - if (key === "apiKey") continue; - if (!securitySchemes[key]) continue; - - inputSchema.properties[key] = { - type: "string", - description: securitySchemes[key].description, - }; - inputSchema.required.push(key); - } -} - -function addParametersToInputSchema( - inputSchema: InputJsonSchema, - operation: Operation, - spec: OpenApiSpec, -) { - const requestBody = operation.requestBody?.content["application/json"]; - if (requestBody) { - const bodySchema = structuredClone( - typeof requestBody.schema.$ref === "string" - ? resolveRef(spec, requestBody.schema.$ref) - : requestBody.schema, - ); - - inputSchema.properties["requestBody"] = { - description: operation.requestBody?.description, - ...bodySchema, - }; - inputSchema.required.push("requestBody"); - } - - if (operation.parameters) { - for (const parameter of operation.parameters) { - const resolvedParameter = - "$ref" in parameter ? resolveRef(spec, parameter.$ref) : parameter; - - inputSchema.properties[resolvedParameter.name] = structuredClone(resolvedParameter.schema); - if (resolvedParameter.required) { - inputSchema.required.push(resolvedParameter.name); - } - } - } -} - -function addDefinitionsToInputSchema(inputSchema: InputJsonSchema, spec: OpenApiSpec) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const definitions: Record = {}; - - function collectDefinitions(obj: unknown) { - if (obj === null || typeof obj !== "object") return; - - if (Array.isArray(obj)) { - for (const item of obj) { - collectDefinitions(item); - } - } - - if ("$ref" in obj && typeof obj.$ref === "string" && !obj.$ref.startsWith("#/$defs")) { - const definition = resolveRef(spec, obj.$ref); - const definitionName = obj.$ref.split("/").at(-1)!; - obj.$ref = `#/$defs/${definitionName}`; - - if (definitionName in definitions) { - return; - } - - const clonedDefinition = structuredClone(definition); - definitions[definitionName] = clonedDefinition; - collectDefinitions(clonedDefinition); - return; - } - - for (const value of Object.values(obj)) { - collectDefinitions(value); - } - } - - collectDefinitions(inputSchema); - inputSchema.$defs = definitions; -} - -function resolveRef( - spec: OpenApiSpec, - ref: string, -): Value { - const parts = ref.split("/").slice(1); - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let current: any = spec; - for (const part of parts) { - current = current[part]; - } - - return current; -} diff --git a/src/tools/registerSetAttributesForFaceting.ts b/src/tools/registerSetAttributesForFaceting.ts deleted file mode 100644 index 29f7e1b..0000000 --- a/src/tools/registerSetAttributesForFaceting.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { algoliasearch } from "algoliasearch"; -import type { DashboardApi } from "../DashboardApi.ts"; -import type { CustomMcpServer } from "../CustomMcpServer.ts"; - -export const operationId = "setAttributesForFaceting"; -export const description = - "lets you create categories based on specific attributes so users can filter search results by those categories. For example, if you have an index of books, you could categorize them by author and genre. This allows users to filter search results by their favorite author or discover new genres. To enable this categorization, declare your attributes as `attributesForFaceting`"; - -export function registerSetAttributesForFaceting( - server: CustomMcpServer, - dashboardApi: DashboardApi, -) { - server.tool({ - name: operationId, - description, - inputSchema: { - type: "object", - properties: { - applicationId: { - type: "string", - description: "The application ID that owns the index to manipulate", - }, - indexName: { - type: "string", - description: "The index name on which you want to set the attributes for faceting", - }, - attributesForFaceting: { - type: "array", - description: - "The list of attributes on which you want to be able to apply category filters", - items: { type: "string" }, - }, - strategy: { - type: "string", - description: - "If `append`, the attributes will be added to the existing ones (default strategy to avoid overwriting). If `replace`, the existing attributes will be replaced.", - enum: ["append", "replace"], - default: "append", - }, - }, - required: ["applicationId", "indexName", "attributesForFaceting"], - }, - annotations: { destructiveHint: true }, - cb: async (args) => { - const { - applicationId, - indexName, - attributesForFaceting, - strategy = "append", - } = args as { - applicationId: string; - indexName: string; - attributesForFaceting: string[]; - strategy?: "append" | "replace"; - }; - const apiKey = await dashboardApi.getApiKey(applicationId); - const client = algoliasearch(applicationId, apiKey); - - let newAttributes: string[] = []; - if (strategy === "append") { - const currentSettings = await client.getSettings({ indexName }); - - newAttributes = currentSettings.attributesForFaceting || []; - } - - newAttributes = [...newAttributes, ...attributesForFaceting]; - - const task = await client.setSettings({ - indexName, - indexSettings: { - attributesForFaceting: newAttributes, - }, - }); - - return `The task to set the attributes for faceting has been created. You can check the status of the task using the \`waitForTask\` method over the task ID '${task.taskID}' and on the index '${indexName}'`; - }, - }); -} diff --git a/src/tools/registerSetCustomRanking.ts b/src/tools/registerSetCustomRanking.ts deleted file mode 100644 index bb26b3a..0000000 --- a/src/tools/registerSetCustomRanking.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { algoliasearch } from "algoliasearch"; -import type { DashboardApi } from "../DashboardApi.ts"; -import type { CustomMcpServer } from "../CustomMcpServer.ts"; - -export const operationId = "setCustomRanking"; -export const description = - "Set the custom ranking for an Algolia index. This allows you to define how the results are sorted based on the attributes you specify. You can use this to prioritize certain attributes over others when displaying search results."; - -export function registerSetCustomRanking(server: CustomMcpServer, dashboardApi: DashboardApi) { - server.tool({ - name: operationId, - description, - annotations: { destructiveHint: true }, - inputSchema: { - type: "object", - properties: { - applicationId: { - type: "string", - description: "The application ID that owns the index to manipulate", - }, - indexName: { - type: "string", - description: "The index name on which you want to set the attributes for faceting", - }, - customRanking: { - type: "array", - items: { - type: "object", - properties: { - attribute: { - type: "string", - description: "The attribute name", - }, - direction: { - type: "string", - enum: ["asc", "desc"], - default: "desc", - description: "The direction of the ranking (can be either 'asc' or 'desc')", - }, - }, - required: ["attribute"], - }, - description: "The attributes you want to use for custom ranking", - }, - strategy: { - type: "string", - enum: ["append", "replace"], - default: "append", - description: - "If `append`, the attributes will be added to the existing ones (default strategy to avoid overwriting). If `replace`, the existing attributes will be replaced.", - }, - }, - required: ["applicationId", "indexName", "customRanking"], - }, - cb: async (args) => { - const { - applicationId, - indexName, - customRanking, - strategy = "append", - } = args as { - applicationId: string; - indexName: string; - customRanking: { attribute: string; direction?: "asc" | "desc" }[]; - strategy?: "append" | "replace"; - }; - const apiKey = await dashboardApi.getApiKey(applicationId); - const client = algoliasearch(applicationId, apiKey); - - let newCustomRanking: string[] = []; - - if (strategy === "append") { - const currentSettings = await client.getSettings({ - indexName, - }); - - newCustomRanking = currentSettings.customRanking || []; - } - - newCustomRanking = [ - ...newCustomRanking, - ...customRanking.map(({ attribute, direction }) => `${direction}(${attribute})`), - ]; - - const task = await client.setSettings({ - indexName, - indexSettings: { - customRanking: newCustomRanking, - }, - }); - - return { - content: [ - { - type: "text", - text: `The task to set the custom ranking has been created. You can check the status of the task using the \`waitForTask\` method over the task ID '${task.taskID}' and on the index '${indexName}'`, - }, - ], - }; - }, - }); -} diff --git a/src/tools/runToolCall.ts b/src/tools/runToolCall.ts new file mode 100644 index 0000000..7efae6f --- /dev/null +++ b/src/tools/runToolCall.ts @@ -0,0 +1,30 @@ +/** + * Executes a call and returns a standardized `ToolTextResponse`. + */ +export async function runTextToolCall(call: () => Promise): Promise { + try { + const response = await call(); + const data = JSON.stringify(response); + return serializeTextResponse(data); + } catch (err) { + return serializeTextError(err as Error); + } +} + +type ToolTextResponse = { + content: Array<{ type: "text"; text: string }>; + isError?: boolean; +}; + +function serializeTextResponse(data: string): ToolTextResponse { + return { + content: [{ type: "text", text: data }], + }; +} + +function serializeTextError(error: Error): ToolTextResponse { + return { + content: [{ type: "text", text: `Error: ${error.message}` }], + isError: true, + }; +} diff --git a/src/tools/search/getAlgoliaSearchSingleIndexTool.ts b/src/tools/search/getAlgoliaSearchSingleIndexTool.ts new file mode 100644 index 0000000..ae203ca --- /dev/null +++ b/src/tools/search/getAlgoliaSearchSingleIndexTool.ts @@ -0,0 +1,97 @@ +import { z } from "zod"; +import { runTextToolCall } from "../runToolCall"; + +import type { ToolRegisterConfig } from "../toolConfig"; + +/** + * Registers a tool to execute a search on a single Algolia index. + */ +export function registerGetAlgoliaSearchSingleIndexTool(config: ToolRegisterConfig) { + const { mcpServer, algoliaApi } = config; + mcpServer.registerTool( + "algolia-search-searchSingleIndex", + { + title: "Algolia Search Single Index", + description: + "Searches a single index and returns matching search results (hits). Display the Algolia results exactly as returned. Do not filter, reorder, or summarize the hits. This method lets you retrieve up to 1,000 hits. If you need more increase the paginatedLimitedTo query parameter setting.", + inputSchema: { + indexName: z.string().describe("Index name to make search"), + query: z + .string() + .describe( + "Search query to execute. Always include all the results returned, don't filter them out, nor reorder them.", + ), + attributesToRetrieve: z + .array(z.string()) + .optional() + .default(["*"]) + .describe( + "List of attributes to retrieve. If not specified, all attributes are returned. If user specifies something to return, leverage this setting to ensure minimal payload.", + ), + restrictSearchableAttributes: z + .array(z.string()) + .optional() + .default([]) + .describe( + "List of attributes to restrict the search to. If user specifies something to restrict search on, leverage this setting to ensure better relevancy.", + ), + ruleContexts: z + .array(z.string()) + .optional() + .default([]) + .describe( + "List of custom tags to pass with a search query in Algolia to control which Rules should apply in that specific context. When this parameter is set, don't check results relevancy and display them in the same order as the hits array.", + ), + page: z + .number() + .optional() + .default(0) + .describe( + "Specify the page to retrieve. Algolia uses the page and hitsPerPage parameters to control how search results are displayed (minimum: 0, default: 0)", + ), + hitsPerPage: z + .number() + .optional() + .default(5) + .describe("Number of hits per page. (minimum: 1, maximum: 1000, default: 5)"), + filters: z.string().optional().default("").describe(` + Filter to apply to the search query. Filter the query with numeric, facet, or tag filters. + Algolia supports the following operators, which must be in capital letters: + - OR: must match any of the combined conditions + - AND: must match all the combined conditions + - NOT: negates a filter + + Use parentheses ( and ) to combine several OR conditions. These rules apply: + - Don’t group ANDs within ORs. For example, A OR (B AND C) OR (D AND E) isn’t supported. + - Don’t use parentheses with top-level AND combinations. For example, (A AND (B OR C)) isn’t supported. (But A AND (B OR C) is supported) + - Don’t use parentheses to negate a group of expressions. For example, NOT (filter1 OR filter2) isn’t supported. + + The following examples are valid combinations of filter expressions: + - A AND (B OR C) + - (A OR B) AND C + - A AND (B OR C) AND (D OR E) + - A AND B AND (C OR D) AND (E OR F) + - (A OR B) AND (C OR D) AND E + + Filter combinations can be created using SQL-style boolean logic, including AND, OR, and parentheses for grouping. + `), + }, + }, + async ({ indexName, query, ...optionalParams }) => { + return runTextToolCall(() => + algoliaApi.search({ + requests: [ + { + indexName, + query, + ...optionalParams, + // Default values for not exposed parameters: + attributesToHighlight: [], + responseFields: ["hits", "nbHits", "page", "nbPages", "hitsPerPage", "facets"], + }, + ], + }), + ); + }, + ); +} diff --git a/src/tools/toolConfig.ts b/src/tools/toolConfig.ts new file mode 100644 index 0000000..74f7ebb --- /dev/null +++ b/src/tools/toolConfig.ts @@ -0,0 +1,13 @@ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import type { Algoliasearch } from "algoliasearch"; + +export type Region = "us" | "de"; + +/** + * Configuration to register tools with the Model Context Protocol (MCP) server. + */ +export interface ToolRegisterConfig { + mcpServer: McpServer; + algoliaApi: Algoliasearch; + region?: Region; +} diff --git a/tsconfig.json b/tsconfig.json index 5be2b52..1005229 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,16 @@ { "compilerOptions": { - "lib": ["es2023", "ES2024.Promise"], - "module": "nodenext", + "module": "NodeNext", "target": "es2022", - + "outDir": "./dist", "strict": true, "esModuleInterop": true, "skipLibCheck": true, - "moduleResolution": "node16", - "allowImportingTsExtensions": true, - "noEmit": true, + "moduleResolution": "NodeNext", "verbatimModuleSyntax": false, "noUnusedLocals": true, "resolveJsonModule": true - } + }, + "include": ["src/**/*"], + "exclude": ["src/**/*.test.ts", "node_modules"] } diff --git a/vite.config.mts b/vite.config.mts new file mode 100644 index 0000000..2c53493 --- /dev/null +++ b/vite.config.mts @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["src/**/*.test.ts"], + environment: "node", + globals: true, + }, +});