diff --git a/.env.example b/.env.example
index 9faf0fba420a7ae3aa5d184553b8442f77f82781..46f3dfcd89f8be34b9a66b545141ea3865a5db8e 100644
--- a/.env.example
+++ b/.env.example
@@ -19,3 +19,13 @@ AWS_ACCESS_KEY_ID=
 AWS_SECRET_ACCESS_KEY=
 AWS_REGION=default
 S3_BUCKET=mecredteste
+
+ELASTICSEARCH_USER=elastic
+ELASTICSEARCH_PASSWORD=123
+ELASTICSEARCH_HOST=localhost
+ELASTICSEARCH_PORT=9200
+ELASTICSEARCH_URL=http://${ELASTICSEARCH_USER}:${ELASTICSEARCH_PASSWORD}@${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}
+ELASTIC_INDEX_PREFIX=
+ELASTIC_INDEX_RESOURCES=${ELASTIC_INDEX_PREFIX}_resources
+ELASTIC_INDEX_COLLECTIONS=${ELASTIC_INDEX_PREFIX}_collections
+ELASTIC_INDEX_USERS=${ELASTIC_INDEX_PREFIX}_users
diff --git a/bun.lockb b/bun.lockb
index 21895ee2a75f1cca3c0d0a06287fadd4e7396b1e..07d65b227b112081b8a5c9b3bf38892687972d65 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000000000000000000000000000000000000..3544e82cac5eac0f8985ff33d220cbff88a6d222
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2250 @@
+{
+  "name": "hono-backend",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "hono-backend",
+      "dependencies": {
+        "@elastic/elasticsearch": "^8.17.0",
+        "@hono/zod-validator": "^0.2.2",
+        "dotenv": "^16.4.5",
+        "dotenv-expand": "^11.0.6",
+        "drizzle-orm": "^0.31.2",
+        "drizzle-zod": "^0.5.1",
+        "hono": "^4.4.8",
+        "postgres": "^3.4.4",
+        "reflect-metadata": "^0.2.2",
+        "typedi": "^0.10.0",
+        "zod": "^3.23.8"
+      },
+      "devDependencies": {
+        "@eslint/js": "^9.5.0",
+        "@types/bun": "latest",
+        "cross-env": "^7.0.3",
+        "drizzle-kit": "^0.22.7",
+        "eslint": "^8.56.0",
+        "eslint-config-prettier": "^9.1.0",
+        "globals": "^15.6.0",
+        "prettier": "^3.3.2",
+        "typescript-eslint": "^7.14.1"
+      }
+    },
+    "node_modules/@elastic/elasticsearch": {
+      "version": "8.17.0",
+      "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.17.0.tgz",
+      "integrity": "sha512-FZ+gQUrPsMpQ2RRIXwTmCoUeFCEausMhp4eQOyxT9j1cwGXHJrhelR6jffM1SC95kQUkB7+TcTq7oQ+bG2BQ9g==",
+      "dependencies": {
+        "@elastic/transport": "^8.9.1",
+        "apache-arrow": "^18.0.0",
+        "tslib": "^2.4.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@elastic/transport": {
+      "version": "8.9.4",
+      "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.9.4.tgz",
+      "integrity": "sha512-y6kjy5s0MQE3MQx9ItmvQ8th7GlGcZfzZ7ZDvI8bUhaKua2dJk01k9ia/bdJ4dnPpWpOyFTRgkgBZS31ZTLpcg==",
+      "dependencies": {
+        "@opentelemetry/api": "1.x",
+        "debug": "^4.3.7",
+        "hpagent": "^1.2.0",
+        "ms": "^2.1.3",
+        "secure-json-parse": "^3.0.1",
+        "tslib": "^2.8.1",
+        "undici": "^6.21.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild-kit/core-utils": {
+      "version": "3.3.2",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "esbuild": "~0.18.20",
+        "source-map-support": "^0.5.21"
+      }
+    },
+    "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": {
+      "version": "0.18.20",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.18.20",
+        "@esbuild/android-arm64": "0.18.20",
+        "@esbuild/android-x64": "0.18.20",
+        "@esbuild/darwin-arm64": "0.18.20",
+        "@esbuild/darwin-x64": "0.18.20",
+        "@esbuild/freebsd-arm64": "0.18.20",
+        "@esbuild/freebsd-x64": "0.18.20",
+        "@esbuild/linux-arm": "0.18.20",
+        "@esbuild/linux-arm64": "0.18.20",
+        "@esbuild/linux-ia32": "0.18.20",
+        "@esbuild/linux-loong64": "0.18.20",
+        "@esbuild/linux-mips64el": "0.18.20",
+        "@esbuild/linux-ppc64": "0.18.20",
+        "@esbuild/linux-riscv64": "0.18.20",
+        "@esbuild/linux-s390x": "0.18.20",
+        "@esbuild/linux-x64": "0.18.20",
+        "@esbuild/netbsd-x64": "0.18.20",
+        "@esbuild/openbsd-x64": "0.18.20",
+        "@esbuild/sunos-x64": "0.18.20",
+        "@esbuild/win32-arm64": "0.18.20",
+        "@esbuild/win32-ia32": "0.18.20",
+        "@esbuild/win32-x64": "0.18.20"
+      }
+    },
+    "node_modules/@esbuild-kit/core-utils/node_modules/esbuild/node_modules/@esbuild/linux-x64": {
+      "version": "0.18.20",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild-kit/esm-loader": {
+      "version": "2.6.5",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@esbuild-kit/core-utils": "^3.3.2",
+        "get-tsconfig": "^4.7.0"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.19.12",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+      }
+    },
+    "node_modules/@eslint-community/regexpp": {
+      "version": "4.10.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@eslint/eslintrc": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^6.12.4",
+        "debug": "^4.3.2",
+        "espree": "^9.6.0",
+        "globals": "^13.19.0",
+        "ignore": "^5.2.0",
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^4.1.0",
+        "minimatch": "^3.1.2",
+        "strip-json-comments": "^3.1.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/js": {
+      "version": "9.5.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      }
+    },
+    "node_modules/@hono/zod-validator": {
+      "version": "0.2.2",
+      "license": "MIT",
+      "peerDependencies": {
+        "hono": ">=3.9.0",
+        "zod": "^3.19.1"
+      }
+    },
+    "node_modules/@humanwhocodes/config-array": {
+      "version": "0.11.14",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+      "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+      "deprecated": "Use @eslint/config-array instead",
+      "dev": true,
+      "dependencies": {
+        "@humanwhocodes/object-schema": "^2.0.2",
+        "debug": "^4.3.1",
+        "minimatch": "^3.0.5"
+      },
+      "engines": {
+        "node": ">=10.10.0"
+      }
+    },
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=12.22"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
+    "node_modules/@humanwhocodes/object-schema": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+      "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+      "deprecated": "Use @eslint/object-schema instead",
+      "dev": true
+    },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.5",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.5",
+        "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.5",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.8",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "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==",
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@swc/helpers": {
+      "version": "0.5.15",
+      "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+      "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+      "dependencies": {
+        "tslib": "^2.8.0"
+      }
+    },
+    "node_modules/@types/bun": {
+      "version": "1.1.18",
+      "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.1.18.tgz",
+      "integrity": "sha512-gtw6cIv/8Q530D0BmoYnjEzR65SjVq2SaUE0NeU6tbm7QBMsTZ61/NBNERtK/FUJaoi7PiteUohK7JcrXBCkvw==",
+      "dev": true,
+      "dependencies": {
+        "bun-types": "1.1.44"
+      }
+    },
+    "node_modules/@types/command-line-args": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz",
+      "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw=="
+    },
+    "node_modules/@types/command-line-usage": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz",
+      "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg=="
+    },
+    "node_modules/@types/node": {
+      "version": "20.12.14",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "undici-types": "~5.26.4"
+      }
+    },
+    "node_modules/@types/ws": {
+      "version": "8.5.10",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@typescript-eslint/eslint-plugin": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.10.0",
+        "@typescript-eslint/scope-manager": "7.14.1",
+        "@typescript-eslint/type-utils": "7.14.1",
+        "@typescript-eslint/utils": "7.14.1",
+        "@typescript-eslint/visitor-keys": "7.14.1",
+        "graphemer": "^1.4.0",
+        "ignore": "^5.3.1",
+        "natural-compare": "^1.4.0",
+        "ts-api-utils": "^1.3.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/parser": "^7.0.0",
+        "eslint": "^8.56.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/parser": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "7.14.1",
+        "@typescript-eslint/types": "7.14.1",
+        "@typescript-eslint/typescript-estree": "7.14.1",
+        "@typescript-eslint/visitor-keys": "7.14.1",
+        "debug": "^4.3.4"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.56.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/scope-manager": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/types": "7.14.1",
+        "@typescript-eslint/visitor-keys": "7.14.1"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/type-utils": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/typescript-estree": "7.14.1",
+        "@typescript-eslint/utils": "7.14.1",
+        "debug": "^4.3.4",
+        "ts-api-utils": "^1.3.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.56.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/types": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "@typescript-eslint/types": "7.14.1",
+        "@typescript-eslint/visitor-keys": "7.14.1",
+        "debug": "^4.3.4",
+        "globby": "^11.1.0",
+        "is-glob": "^4.0.3",
+        "minimatch": "^9.0.4",
+        "semver": "^7.6.0",
+        "ts-api-utils": "^1.3.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+      "version": "9.0.4",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@typescript-eslint/utils": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.4.0",
+        "@typescript-eslint/scope-manager": "7.14.1",
+        "@typescript-eslint/types": "7.14.1",
+        "@typescript-eslint/typescript-estree": "7.14.1"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.56.0"
+      }
+    },
+    "node_modules/@typescript-eslint/visitor-keys": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/types": "7.14.1",
+        "eslint-visitor-keys": "^3.4.3"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@ungap/structured-clone": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz",
+      "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==",
+      "dev": true
+    },
+    "node_modules/acorn": {
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+      "dev": true,
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/acorn-jsx": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+      "dev": true,
+      "peerDependencies": {
+        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      }
+    },
+    "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,
+      "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/ansi-regex": {
+      "version": "5.0.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/apache-arrow": {
+      "version": "18.1.0",
+      "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-18.1.0.tgz",
+      "integrity": "sha512-v/ShMp57iBnBp4lDgV8Jx3d3Q5/Hac25FWmQ98eMahUiHPXcvwIMKJD0hBIgclm/FCG+LwPkAKtkRO1O/W0YGg==",
+      "dependencies": {
+        "@swc/helpers": "^0.5.11",
+        "@types/command-line-args": "^5.2.3",
+        "@types/command-line-usage": "^5.0.4",
+        "@types/node": "^20.13.0",
+        "command-line-args": "^5.2.1",
+        "command-line-usage": "^7.0.1",
+        "flatbuffers": "^24.3.25",
+        "json-bignum": "^0.0.3",
+        "tslib": "^2.6.2"
+      },
+      "bin": {
+        "arrow2csv": "bin/arrow2csv.js"
+      }
+    },
+    "node_modules/apache-arrow/node_modules/@types/node": {
+      "version": "20.17.14",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.14.tgz",
+      "integrity": "sha512-w6qdYetNL5KRBiSClK/KWai+2IMEJuAj+EujKCumalFOwXtvOXaEan9AuwcRID2IcOIAWSIfR495hBtgKlx2zg==",
+      "dependencies": {
+        "undici-types": "~6.19.2"
+      }
+    },
+    "node_modules/apache-arrow/node_modules/undici-types": {
+      "version": "6.19.8",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
+      "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
+    },
+    "node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true
+    },
+    "node_modules/array-back": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+      "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/array-union": {
+      "version": "2.1.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/buffer-from": {
+      "version": "1.1.2",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/bun-types": {
+      "version": "1.1.44",
+      "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.1.44.tgz",
+      "integrity": "sha512-jtcekoZeSINgEcHSISzhR13w/cyE+Fankw2Cpl4c0fN3lRmKVAX0i9ay4FyK4lOxUK1HG4HkuIlrPvXKz4Y7sw==",
+      "devOptional": true,
+      "dependencies": {
+        "@types/node": "~20.12.8",
+        "@types/ws": "~8.5.10"
+      }
+    },
+    "node_modules/callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/chalk": {
+      "version": "4.1.2",
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/chalk-template": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
+      "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
+      "dependencies": {
+        "chalk": "^4.1.2"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk-template?sponsor=1"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "license": "MIT"
+    },
+    "node_modules/command-line-args": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
+      "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==",
+      "dependencies": {
+        "array-back": "^3.1.0",
+        "find-replace": "^3.0.0",
+        "lodash.camelcase": "^4.3.0",
+        "typical": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/command-line-usage": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz",
+      "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==",
+      "dependencies": {
+        "array-back": "^6.2.2",
+        "chalk-template": "^0.4.0",
+        "table-layout": "^4.1.0",
+        "typical": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=12.20.0"
+      }
+    },
+    "node_modules/command-line-usage/node_modules/array-back": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
+      "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==",
+      "engines": {
+        "node": ">=12.17"
+      }
+    },
+    "node_modules/command-line-usage/node_modules/typical": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz",
+      "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==",
+      "engines": {
+        "node": ">=12.17"
+      }
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+      "dev": true
+    },
+    "node_modules/cross-env": {
+      "version": "7.0.3",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cross-spawn": "^7.0.1"
+      },
+      "bin": {
+        "cross-env": "src/bin/cross-env.js",
+        "cross-env-shell": "src/bin/cross-env-shell.js"
+      },
+      "engines": {
+        "node": ">=10.14",
+        "npm": ">=6",
+        "yarn": ">=1"
+      }
+    },
+    "node_modules/cross-spawn": {
+      "version": "7.0.3",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/debug": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/deep-is": {
+      "version": "0.1.4",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/dir-glob": {
+      "version": "3.0.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "dependencies": {
+        "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/dotenv": {
+      "version": "16.4.5",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://dotenvx.com"
+      }
+    },
+    "node_modules/dotenv-expand": {
+      "version": "11.0.6",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dotenv": "^16.4.4"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://dotenvx.com"
+      }
+    },
+    "node_modules/drizzle-kit": {
+      "version": "0.22.7",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@esbuild-kit/esm-loader": "^2.5.5",
+        "esbuild": "^0.19.7",
+        "esbuild-register": "^3.5.0"
+      },
+      "bin": {
+        "drizzle-kit": "bin.cjs"
+      }
+    },
+    "node_modules/drizzle-orm": {
+      "version": "0.31.2",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "@aws-sdk/client-rds-data": ">=3",
+        "@cloudflare/workers-types": ">=3",
+        "@electric-sql/pglite": ">=0.1.1",
+        "@libsql/client": "*",
+        "@neondatabase/serverless": ">=0.1",
+        "@op-engineering/op-sqlite": ">=2",
+        "@opentelemetry/api": "^1.4.1",
+        "@planetscale/database": ">=1",
+        "@tidbcloud/serverless": "*",
+        "@types/better-sqlite3": "*",
+        "@types/pg": "*",
+        "@types/react": ">=18",
+        "@types/sql.js": "*",
+        "@vercel/postgres": ">=0.8.0",
+        "@xata.io/client": "*",
+        "better-sqlite3": ">=7",
+        "bun-types": "*",
+        "expo-sqlite": ">=13.2.0",
+        "knex": "*",
+        "kysely": "*",
+        "mysql2": ">=2",
+        "pg": ">=8",
+        "postgres": ">=3",
+        "react": ">=18",
+        "sql.js": ">=1",
+        "sqlite3": ">=5"
+      },
+      "peerDependenciesMeta": {
+        "@aws-sdk/client-rds-data": {
+          "optional": true
+        },
+        "@cloudflare/workers-types": {
+          "optional": true
+        },
+        "@electric-sql/pglite": {
+          "optional": true
+        },
+        "@libsql/client": {
+          "optional": true
+        },
+        "@neondatabase/serverless": {
+          "optional": true
+        },
+        "@op-engineering/op-sqlite": {
+          "optional": true
+        },
+        "@opentelemetry/api": {
+          "optional": true
+        },
+        "@planetscale/database": {
+          "optional": true
+        },
+        "@tidbcloud/serverless": {
+          "optional": true
+        },
+        "@types/better-sqlite3": {
+          "optional": true
+        },
+        "@types/pg": {
+          "optional": true
+        },
+        "@types/react": {
+          "optional": true
+        },
+        "@types/sql.js": {
+          "optional": true
+        },
+        "@vercel/postgres": {
+          "optional": true
+        },
+        "@xata.io/client": {
+          "optional": true
+        },
+        "better-sqlite3": {
+          "optional": true
+        },
+        "bun-types": {
+          "optional": true
+        },
+        "expo-sqlite": {
+          "optional": true
+        },
+        "knex": {
+          "optional": true
+        },
+        "kysely": {
+          "optional": true
+        },
+        "mysql2": {
+          "optional": true
+        },
+        "pg": {
+          "optional": true
+        },
+        "postgres": {
+          "optional": true
+        },
+        "react": {
+          "optional": true
+        },
+        "sql.js": {
+          "optional": true
+        },
+        "sqlite3": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/drizzle-zod": {
+      "version": "0.5.1",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "drizzle-orm": ">=0.23.13",
+        "zod": "*"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.19.12",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.19.12",
+        "@esbuild/android-arm": "0.19.12",
+        "@esbuild/android-arm64": "0.19.12",
+        "@esbuild/android-x64": "0.19.12",
+        "@esbuild/darwin-arm64": "0.19.12",
+        "@esbuild/darwin-x64": "0.19.12",
+        "@esbuild/freebsd-arm64": "0.19.12",
+        "@esbuild/freebsd-x64": "0.19.12",
+        "@esbuild/linux-arm": "0.19.12",
+        "@esbuild/linux-arm64": "0.19.12",
+        "@esbuild/linux-ia32": "0.19.12",
+        "@esbuild/linux-loong64": "0.19.12",
+        "@esbuild/linux-mips64el": "0.19.12",
+        "@esbuild/linux-ppc64": "0.19.12",
+        "@esbuild/linux-riscv64": "0.19.12",
+        "@esbuild/linux-s390x": "0.19.12",
+        "@esbuild/linux-x64": "0.19.12",
+        "@esbuild/netbsd-x64": "0.19.12",
+        "@esbuild/openbsd-x64": "0.19.12",
+        "@esbuild/sunos-x64": "0.19.12",
+        "@esbuild/win32-arm64": "0.19.12",
+        "@esbuild/win32-ia32": "0.19.12",
+        "@esbuild/win32-x64": "0.19.12"
+      }
+    },
+    "node_modules/esbuild-register": {
+      "version": "3.5.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^4.3.4"
+      },
+      "peerDependencies": {
+        "esbuild": ">=0.12 <1"
+      }
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint": {
+      "version": "8.56.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
+      "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+      "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.4",
+        "@eslint/js": "8.56.0",
+        "@humanwhocodes/config-array": "^0.11.13",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
+        "@ungap/structured-clone": "^1.2.0",
+        "ajv": "^6.12.4",
+        "chalk": "^4.0.0",
+        "cross-spawn": "^7.0.2",
+        "debug": "^4.3.2",
+        "doctrine": "^3.0.0",
+        "escape-string-regexp": "^4.0.0",
+        "eslint-scope": "^7.2.2",
+        "eslint-visitor-keys": "^3.4.3",
+        "espree": "^9.6.1",
+        "esquery": "^1.4.2",
+        "esutils": "^2.0.2",
+        "fast-deep-equal": "^3.1.3",
+        "file-entry-cache": "^6.0.1",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "graphemer": "^1.4.0",
+        "ignore": "^5.2.0",
+        "imurmurhash": "^0.1.4",
+        "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
+        "js-yaml": "^4.1.0",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.4.1",
+        "lodash.merge": "^4.6.2",
+        "minimatch": "^3.1.2",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.9.3",
+        "strip-ansi": "^6.0.1",
+        "text-table": "^0.2.0"
+      },
+      "bin": {
+        "eslint": "bin/eslint.js"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint-config-prettier": {
+      "version": "9.1.0",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "eslint-config-prettier": "bin/cli.js"
+      },
+      "peerDependencies": {
+        "eslint": ">=7.0.0"
+      }
+    },
+    "node_modules/eslint-scope": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint-visitor-keys": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint/node_modules/@eslint/js": {
+      "version": "8.56.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
+      "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/eslint/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/espree": {
+      "version": "9.6.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^8.9.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/esquery": {
+      "version": "1.5.0",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "estraverse": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dev": true,
+      "dependencies": {
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "5.3.0",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "node_modules/fast-glob": {
+      "version": "3.3.2",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.2",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.4"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
+    "node_modules/fast-glob/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "node_modules/fast-levenshtein": {
+      "version": "2.0.6",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/fastq": {
+      "version": "1.17.1",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "node_modules/file-entry-cache": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+      "dev": true,
+      "dependencies": {
+        "flat-cache": "^3.0.4"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.0"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/find-replace": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
+      "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
+      "dependencies": {
+        "array-back": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "5.0.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/flat-cache": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+      "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+      "dev": true,
+      "dependencies": {
+        "flatted": "^3.2.9",
+        "keyv": "^4.5.3",
+        "rimraf": "^3.0.2"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.0"
+      }
+    },
+    "node_modules/flatbuffers": {
+      "version": "24.12.23",
+      "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.12.23.tgz",
+      "integrity": "sha512-dLVCAISd5mhls514keQzmEG6QHmUUsNuWsb4tFafIUwvvgDjXhtfAYSKOzt5SWOy+qByV5pbsDZ+Vb7HUOBEdA=="
+    },
+    "node_modules/flatted": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
+      "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
+      "dev": true
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+      "dev": true
+    },
+    "node_modules/get-tsconfig": {
+      "version": "4.7.5",
+      "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": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "deprecated": "Glob versions prior to v9 are no longer supported",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "6.0.2",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/globals": {
+      "version": "15.6.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/globby": {
+      "version": "11.1.0",
+      "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/graphemer": {
+      "version": "1.4.0",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/hono": {
+      "version": "4.4.8",
+      "license": "MIT",
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/hpagent": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz",
+      "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==",
+      "engines": {
+        "node": ">=14"
+      }
+    },
+    "node_modules/ignore": {
+      "version": "5.3.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/import-fresh": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+      "dev": true,
+      "dependencies": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/imurmurhash": {
+      "version": "0.1.4",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8.19"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-path-inside": {
+      "version": "3.0.3",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/json-bignum": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz",
+      "integrity": "sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/json-buffer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+      "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+      "dev": true
+    },
+    "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
+    },
+    "node_modules/json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/keyv": {
+      "version": "4.5.4",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+      "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+      "dev": true,
+      "dependencies": {
+        "json-buffer": "3.0.1"
+      }
+    },
+    "node_modules/levn": {
+      "version": "0.4.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "prelude-ls": "^1.2.1",
+        "type-check": "~0.4.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/locate-path": {
+      "version": "6.0.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-locate": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "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=="
+    },
+    "node_modules/lodash.merge": {
+      "version": "4.6.2",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.7",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "braces": "^3.0.3",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+    },
+    "node_modules/natural-compare": {
+      "version": "1.4.0",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/optionator": {
+      "version": "0.9.4",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "deep-is": "^0.1.3",
+        "fast-levenshtein": "^2.0.6",
+        "levn": "^0.4.1",
+        "prelude-ls": "^1.2.1",
+        "type-check": "^0.4.0",
+        "word-wrap": "^1.2.5"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/p-limit": {
+      "version": "3.1.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "5.0.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "dependencies": {
+        "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/path-exists": {
+      "version": "4.0.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-key": {
+      "version": "3.1.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-type": {
+      "version": "4.0.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/postgres": {
+      "version": "3.4.4",
+      "license": "Unlicense",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://github.com/sponsors/porsager"
+      }
+    },
+    "node_modules/prelude-ls": {
+      "version": "1.2.1",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/prettier": {
+      "version": "3.3.2",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "prettier": "bin/prettier.cjs"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/queue-microtask": {
+      "version": "1.2.3",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/reflect-metadata": {
+      "version": "0.2.2",
+      "license": "Apache-2.0"
+    },
+    "node_modules/resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/resolve-pkg-maps": {
+      "version": "1.0.0",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+      }
+    },
+    "node_modules/reusify": {
+      "version": "1.0.4",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "deprecated": "Rimraf versions prior to v4 are no longer supported",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/run-parallel": {
+      "version": "1.2.0",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "queue-microtask": "^1.2.2"
+      }
+    },
+    "node_modules/secure-json-parse": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-3.0.2.tgz",
+      "integrity": "sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fastify"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/fastify"
+        }
+      ]
+    },
+    "node_modules/semver": {
+      "version": "7.6.2",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/shebang-command": {
+      "version": "2.0.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/slash": {
+      "version": "3.0.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.21",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/strip-json-comments": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "7.2.0",
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/table-layout": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz",
+      "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==",
+      "dependencies": {
+        "array-back": "^6.2.2",
+        "wordwrapjs": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=12.17"
+      }
+    },
+    "node_modules/table-layout/node_modules/array-back": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
+      "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==",
+      "engines": {
+        "node": ">=12.17"
+      }
+    },
+    "node_modules/text-table": {
+      "version": "0.2.0",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/ts-api-utils": {
+      "version": "1.3.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=16"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.2.0"
+      }
+    },
+    "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=="
+    },
+    "node_modules/type-check": {
+      "version": "0.4.0",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "prelude-ls": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/typedi": {
+      "version": "0.10.0",
+      "license": "MIT"
+    },
+    "node_modules/typescript": {
+      "version": "5.5.2",
+      "dev": true,
+      "license": "Apache-2.0",
+      "peer": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/typescript-eslint": {
+      "version": "7.14.1",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/eslint-plugin": "7.14.1",
+        "@typescript-eslint/parser": "7.14.1",
+        "@typescript-eslint/utils": "7.14.1"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.56.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/typical": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
+      "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/undici": {
+      "version": "6.21.1",
+      "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
+      "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==",
+      "engines": {
+        "node": ">=18.17"
+      }
+    },
+    "node_modules/undici-types": {
+      "version": "5.26.5",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/which": {
+      "version": "2.0.2",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/word-wrap": {
+      "version": "1.2.5",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/wordwrapjs": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz",
+      "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==",
+      "engines": {
+        "node": ">=12.17"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "dev": true
+    },
+    "node_modules/yocto-queue": {
+      "version": "0.1.0",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/zod": {
+      "version": "3.23.8",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/colinhacks"
+      }
+    }
+  }
+}
diff --git a/package.json b/package.json
index ccb1549d89711056b5513a72a183914fc8fc835a..2cd1559215768cbf6c8d6f3664f09971050d9854 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
     "@aws-sdk/client-s3": "^3.750.0",
     "@hono/swagger-ui": "^0.5.0",
     "@hono/zod-openapi": "^0.18.3",
+    "@elastic/elasticsearch": "^8.17.0",
     "@hono/zod-validator": "^0.2.2",
     "@scalar/hono-api-reference": "^0.8.0",
     "archiver": "^7.0.1",
@@ -35,7 +36,7 @@
     "@types/bun": "latest",
     "cross-env": "^7.0.3",
     "drizzle-kit": "^0.22.7",
-    "eslint": "9.x",
+    "eslint": "^9.x",
     "eslint-config-prettier": "^9.1.0",
     "globals": "^15.6.0",
     "prettier": "^3.3.2",
diff --git a/src/db/repo/search.repo.ts b/src/db/repo/search.repo.ts
new file mode 100644
index 0000000000000000000000000000000000000000..210de3505446d2a9ff8e9e67ca51e9d4829e59e3
--- /dev/null
+++ b/src/db/repo/search.repo.ts
@@ -0,0 +1,157 @@
+import { Service } from "typedi";
+import db from "..";
+import { eq, sql } from "drizzle-orm";
+import { resourceIndexSchema, type ResourceIndex } from "../schema/search.schema";
+import { userIndexSchema, type UserIndex } from "../schema/search.schema";
+import { collectionIndexSchema, type CollectionIndex } from "../schema/search.schema";
+
+@Service()
+export class SearchRepo {
+  async findResourcesForIndexing(id: number): Promise<ResourceIndex[]> {
+    const query = db
+      .select({
+        id: sql`re.id`,
+        name: sql`re.name`,
+        author: sql`re.author`,
+        description: sql`re.description`,
+        link: sql`re.link`,
+        created_at: sql`re.published_at`, // "created" ao invés de "published" pra ficar consistente com users e collections 
+        educational_stages: sql`string_agg(distinct es.name, ',')`,
+        languages: sql`string_agg(distinct lg.name, ',')`,
+        subjects: sql`string_agg(distinct sj.name, ',')`,
+        license: sql`lc.name`,
+        object_type: sql`ot.name`,
+        state: sql`re.state`,
+        user: sql`us.name`,
+        views: sql`rest.views`,
+        downloads: sql`rest.downloads`,
+        likes: sql`rest.likes`,
+        shares: sql`rest.shares`,
+        score: sql`rest.score`,
+        comments: sql`rest.comments`,
+      })
+      .from(sql`resources re`)
+      .leftJoin(sql`resource_educational_stage res`, sql`res.resource_id = re.id`)
+      .leftJoin(sql`educational_stages es`, sql`res.educational_stage_id = es.id`)
+      .leftJoin(sql`resource_languages rel`, sql`rel.resource_id = re.id`)
+      .leftJoin(sql`languages lg`, sql`rel.language_id = lg.id`)
+      .leftJoin(sql`resource_subjects res`, sql`res.resource_id = re.id`)
+      .leftJoin(sql`subjects sj`, sql`res.subject_id = sj.id`)
+      .leftJoin(sql`licenses lc`, sql`re.license_id = lc.id`)
+      .leftJoin(sql`object_types ot`, sql`re.object_type_id = ot.id`)
+      .leftJoin(sql`users us`, sql`us.id = re.user_id`)
+      .leftJoin(sql`resource_stats rest`, sql`rest.id = re.resource_stats_id`)
+      .where(eq(sql`re.id`, id))
+      .groupBy(
+        sql`re.id`,
+        sql`re.name`,
+        sql`re.author`,
+        sql`re.description`,
+        sql`re.link`,
+        sql`re.published_at`,
+        sql`re.state`,
+        sql`re.views_count`,
+        sql`re.downloads_count`,
+        sql`re.likes_count`,
+        sql`re.shares_count`,
+        sql`ot.name`,
+        sql`lc.name`,
+        sql`us.name`,
+        sql`rest.views`,
+        sql`rest.downloads`,
+        sql`rest.likes`,
+        sql`rest.shares`,
+        sql`rest.score`,
+        sql`rest.comments`
+      );
+      
+      const results = await query.execute();
+
+    // Parse and validate each result using Zod schema
+    return results.map((result) => resourceIndexSchema.parse(result));
+  }
+
+  async findUsersForIndexing(id: number): Promise<UserIndex[]> {
+    const query = db
+      .select({
+          id: sql`users.id`,
+          name: sql`users.name`,
+          username: sql`users.username`,
+          description: sql`users.description`,
+          roles: sql`string_agg(distinct roles.name, ',')`,
+          institutions: sql`string_agg(distinct inst.name, ',')`,
+          created_at: sql`users.created_at`,
+          is_active: sql`users.is_active`,
+          score: sql`usst.score`,
+          likes_received: sql`usst.likes_received`,
+          followers: sql`usst.followers`,
+          approved_resources: sql`usst.approved_resources`,
+      })
+      .from(sql`users`)
+      .leftJoin(sql`user_roles ur`, sql`users.id = ur.user_id`)
+      .leftJoin(sql`roles`, sql`roles.id = ur.role_id`)
+      .leftJoin(sql`user_institutions ui`, sql`ui.user_id = users.id`)
+      .leftJoin(sql`institutions inst`, sql`inst.id = ui.institution_id`)
+      .leftJoin(sql`user_stats usst`, sql`usst.id = users.user_stats_id`)
+      .where(eq(sql`users.id`, id))
+      .groupBy(
+        sql`users.id`,
+        sql`users.name`,
+        sql`users.username`,
+        sql`users.description`,
+        sql`users.created_at`,
+        sql`users.is_active`,
+        sql`usst.score`,
+        sql`usst.likes_received`,
+        sql`usst.followers`,
+        sql`usst.approved_resources`
+      );
+
+      
+    const results = await query.execute();
+
+    // Parse and validate each result using Zod schema
+    return results.map((result) => userIndexSchema.parse(result));
+  }
+
+  // TODO fix the collections query
+  async findCollectionsForIndexing(id: number): Promise<CollectionIndex[]> {
+    const query = db
+      .select({
+        id: sql`col.id`,
+        name: sql`col.name`,
+        author: sql`users.name`,
+        description: sql`col.description`,
+        created_at: sql`col.created_at`,
+        score: sql`colst.score`,
+        views: sql`colst.views`,
+        downloads: sql`colst.downloads`,
+        likes: sql`colst.likes`,
+        shares: sql`colst.shares`,
+        follows: sql`colst.follows`,
+      })
+      .from(sql`collections col`)
+      .leftJoin(sql`users`, sql`users.id = col.user_id`)
+      .leftJoin(sql`collection_stats as colst`, sql`colst.id = col.id`)
+      .where(eq(sql`col.id`, id))
+      .groupBy(
+        sql`col.id`,
+        sql`col.name`,
+        sql`users.name`,
+        sql`col.description`,
+        sql`col.created_at`,
+        sql`colst.score`,
+        sql`colst.views`,
+        sql`colst.downloads`,
+        sql`colst.likes`,
+        sql`colst.shares`,
+        sql`colst.follows`,
+      );
+
+      const results = await query.execute();
+
+    // Parse and validate each result using Zod schema
+    return results.map((result) => collectionIndexSchema.parse(result));
+  }
+
+}
diff --git a/src/db/schema/resource-enum.schema.ts b/src/db/schema/resource-enum.schema.ts
index 78a1d61fc5896d20feab7bfac26a663e421ee68a..cb59688c272c6aa8f8fa05484a8a2ded490f62c7 100644
--- a/src/db/schema/resource-enum.schema.ts
+++ b/src/db/schema/resource-enum.schema.ts
@@ -6,7 +6,7 @@ import { z } from "zod";
 const resourceEnum = pgEnum('resource_state',
     ['draft', 'submitted', 'accepted', 'reported', 'deleted']
 )
-const resourceEnumSchema = z.enum(resourceEnum.enumValues)
+export const resourceEnumSchema = z.enum(resourceEnum.enumValues)
 
 export default resourceEnum
 export type ResourceEnum = z.infer<typeof resourceEnumSchema>
\ No newline at end of file
diff --git a/src/db/schema/search.schema.ts b/src/db/schema/search.schema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d385eeea9161c4aceab60d486b3fcb5346c7b915
--- /dev/null
+++ b/src/db/schema/search.schema.ts
@@ -0,0 +1,64 @@
+import { z } from "zod";
+import { resourceEnumSchema } from '../schema/resource-enum.schema'
+
+export const resourceIndexSchema = z.object({
+  id: z.number(),
+  name: z.string(), 
+  author: z.string().nullable(), 
+  description: z.string().nullable(), 
+  link: z.string().nullable(), 
+  created_at: z.string(),
+  educational_stages: z.string().nullable(), 
+  languages: z.string(), 
+  subjects: z.string().nullable(), 
+  license: z.string(),
+  object_type: z.string(),
+  state: resourceEnumSchema,
+  user: z.string(),
+  views: z.number(),
+  downloads: z.number(),
+  likes: z.number(),
+  shares: z.number(),
+  score: z.number(),
+  comments: z.number()
+});
+
+export const userIndexSchema = z.object({
+  id: z.number(),
+  name: z.string(),
+  username: z.string(),
+  description: z.string().nullable(), 
+  roles: z.string().nullable(),
+  institutions: z.string().nullable(),
+  created_at: z.string(),
+  is_active: z.boolean(),
+  score: z.number(),
+  likes_received: z.number(),
+  followers: z.number(),
+  approved_resources: z.number()
+});
+
+export const collectionIndexSchema = z.object({
+  id: z.number(),
+  name: z.string(), 
+  author: z.string().nullable(), 
+  description: z.string().nullable(), 
+  created_at: z.string(),
+  score: z.number(),
+  views: z.number(),
+  downloads: z.number(),
+  likes: z.number(),
+  shares: z.number(),
+  follows: z.number()
+});
+
+// export type LearningObjectIndex = z.infer<typeof learningObjectIndexSchema>;
+// export type UserIndex = z.infer<typeof userIndexSchema>;
+// export type CollectionIndex = z.infer<typeof collectionIndexSchema>;
+
+
+// export default { learningObjectIndexSchema, collectionIndexSchema, userIndexSchema };
+
+export type ResourceIndex = z.infer<typeof resourceIndexSchema>;
+export type UserIndex = z.infer<typeof userIndexSchema>;
+export type CollectionIndex = z.infer<typeof collectionIndexSchema>;
\ No newline at end of file
diff --git a/src/env.ts b/src/env.ts
index 4b3b2aa73f5337e7eb2f9563eb4d22259e78d19e..a8f1e670144fd6b95fd9bcab9c6fdf73691e856e 100644
--- a/src/env.ts
+++ b/src/env.ts
@@ -26,6 +26,16 @@ const EnvSchema = z.object({
   AWS_REGION: z.string(),
   S3_BUCKET: z.string(),
   URL: z.string(),
+
+  ELASTICSEARCH_USER: z.string(),
+  ELASTICSEARCH_PASSWORD: z.string(),
+  ELASTICSEARCH_HOST: z.string(),
+  ELASTICSEARCH_PORT: z.string(),
+  ELASTICSEARCH_URL: z.string(),
+  ELASTIC_INDEX_PREFIX: z.string(),
+  ELASTIC_INDEX_RESOURCES: z.string(),
+  ELASTIC_INDEX_COLLECTIONS: z.string(),
+  ELASTIC_INDEX_USERS: z.string(),
 })
 
 export type EnvSchema = z.infer<typeof EnvSchema>
diff --git a/src/index.ts b/src/index.ts
index 14b251f368bca425ac20dadf279f8d2e975d0a9e..6ec066b181764a21a0c153943efe18f3712bf147 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -46,6 +46,7 @@ import { publicUserCollectionsRoutes, userCollectionsRoute } from './routes/user
 import { publicS3, s3Routes } from './routes/s3.route'
 import { homologationRouter } from './routes/homologation.route'
 import { contactRoute } from './routes/contact.route'
+import { searchRouter } from './routes/search.route'
 
 
 
@@ -140,6 +141,7 @@ app
   .route('/userCollections', publicUserCollectionsRoutes)
   .route('/s3', publicS3)
   .route('/contact', contactRoute)
+  .route('/elastic', searchRouter)
 //rotas que precisam de token
 app
   .basePath('/api')
diff --git a/src/routes/auth.route.ts b/src/routes/auth.route.ts
index 11171e5ef93ce307e4fd75c2d7e5c51a489a09be..7a90b10077543860337198acbdb6d33728f8cbda 100644
--- a/src/routes/auth.route.ts
+++ b/src/routes/auth.route.ts
@@ -7,6 +7,7 @@ import { UserStatsService } from '@/services/user-stats.service'
 import { UserService } from '@/services/user.service'
 import { zValidator } from '@hono/zod-validator'
 import { Hono } from 'hono'
+import { SearchService } from "@/services/search.service";
 import Container from 'typedi'
 import jwt from 'jwt-simple';
 import {
@@ -21,6 +22,8 @@ import {
 const authService = Container.get(AuthService)
 const userService = Container.get(UserService)
 const userStatsService = Container.get(UserStatsService)
+// const passwordRecoveryService = Container.get(PasswordRecoveryService)
+const searchService = Container.get(SearchService);
 
 export const authRouter = new Hono().post(
   '/signin', signinRoute,
@@ -62,6 +65,8 @@ export const authRouter = new Hono().post(
 
       const user = userSchemas.userDtoSchema.parse(await userService.create(input));
 
+      await searchService.indexUser(user.id)
+
       await authService.sendConfirmationEmail(user.email, "Confirmação de email", user.name, user.email);
 
       return c.json({ user, userStats });
diff --git a/src/routes/collections.route.ts b/src/routes/collections.route.ts
index fcca066cbcb90c2e62b25913abf41f2c42c6635c..9de54735a1f5aa5d01db7e2c5a00b85b21d5c457 100644
--- a/src/routes/collections.route.ts
+++ b/src/routes/collections.route.ts
@@ -10,8 +10,8 @@ import { CollectionStatsService } from "@/services/collection-stats.service";
 import { getFile } from "@/services/s3.service";
 import archiver from "archiver"; // Biblioteca para criar ZIPs
 import { CollectionResourcesService } from "@/services/collection-resources.service";
-import { ResourceService } from "@/services/resource.service";
 import { addObjectTypeNameArray } from "./resource.route";
+import { SearchService } from "@/services/search.service";
 
 import {
   createCollectionRoute,
@@ -31,7 +31,7 @@ import {
 const service = Container.get(CollectionsService);
 const serviceStats = Container.get(CollectionStatsService);
 const serviceResourceCollection = Container.get(CollectionResourcesService) ;
-const resourceService = Container.get(ResourceService)
+const searchService = Container.get(SearchService);
 
 export const collectionsRouter = honoWithJwt()
   .post(
@@ -46,10 +46,13 @@ export const collectionsRouter = honoWithJwt()
         )
 
         input.collection_stats_id = collectionStats.id
+
         const collection = collectionSchemas.collectionDtoSchema.parse(
           await service.create(input)
         )
 
+        await searchService.indexCollection(collection.id)
+
         return c.json({ collection, collectionStats })
       } catch (e) {
         return c.json(
@@ -76,6 +79,8 @@ export const collectionsRouter = honoWithJwt()
           await service.update(input)
         )
 
+        await searchService.indexCollection(collection.id)
+
         return c.json({ collection })
       } catch (e) {
         console.log(e)
@@ -101,6 +106,8 @@ export const collectionsRouter = honoWithJwt()
         await service.delete(id)
       )
 
+      await searchService.deindexDocument(id, 'collections')
+
       return c.json({ collection })
     } catch (e) {
       return c.json(
@@ -123,6 +130,8 @@ export const collectionsRouter = honoWithJwt()
         await service.deletePermanently(id)
       )
 
+      await searchService.deindexDocument(id, 'collections')
+
       return c.json({ collection })
     } catch (e) {
       return c.json(
@@ -145,6 +154,8 @@ export const collectionsRouter = honoWithJwt()
         await service.restore(id)
       )
 
+      await searchService.indexCollection(id)
+
       return c.json({ collection })
     } catch (e) {
       return c.json(
diff --git a/src/routes/homologation.route.ts b/src/routes/homologation.route.ts
index d6f4b8fb9a6788baeab72747b33c8ea2630b6577..eb50889d94cf24ce92f581749677a46daffa3f59 100644
--- a/src/routes/homologation.route.ts
+++ b/src/routes/homologation.route.ts
@@ -7,6 +7,8 @@ import { z } from "zod";
 import { SubmissionService } from "@/services/submission.service";
 import { HomologationService } from "@/services/homologation.service";
 import { ResourceService } from "@/services/resource.service";
+import { SearchService } from "@/services/search.service";
+
 
 import {
     getAllHomologationRoute,
@@ -16,6 +18,7 @@ import {
 const serviceHomologation = Container.get(HomologationService)
 const service = Container.get(SubmissionService);
 const serviceResource = Container.get(ResourceService);
+const searchService = Container.get(SearchService);
 
 export const inputSchemaHomologation = z.object({
     resource_id: z.number(),
@@ -105,6 +108,7 @@ export const homologationRouter = honoWithJwt()
                 // Apenas altera o estado se houver pelo menos 3 submissões aceitas
                 if (acceptedSubmissionsCount >= 3) {
                     await serviceResource.setResourceState(validInput.resource_id);
+                    await searchService.indexResource(validInput.resource_id);
                 }
 
                 return c.json({ message: "Homologação feita com sucesso!", data: homologation })
diff --git a/src/routes/resource.route.ts b/src/routes/resource.route.ts
index 0da397c9e4615614470e8de6c04567025c397334..78b30b5be50be13581bb8a945850ec00b282905e 100644
--- a/src/routes/resource.route.ts
+++ b/src/routes/resource.route.ts
@@ -13,6 +13,7 @@ import { ObjectTypeService } from "@/services/object-type.service";
 import { ResourceEducationalStagesService } from "@/services/resource-educational-stages.service";
 import { ResourceSubjectsService } from "@/services/resource-subjects.service";
 import { UserService } from "@/services/user.service";
+import { SearchService } from "@/services/search.service";
 
 import {
     createResourceRoute,
@@ -35,6 +36,7 @@ const resourceLanguagesService = Container.get(resourceLanguagesRepo);
 const resourceEducationalStagesService = Container.get(ResourceEducationalStagesService);
 const resourceSubjectsService = Container.get(ResourceSubjectsService);
 const userService = Container.get(UserService);
+const searchService = Container.get(SearchService);
 
 //define um novo Model
 type ResourceWithObjectTypeName = ResourceModel & {
@@ -89,10 +91,13 @@ export const resourceRouter = honoWithJwt()
                 )
 
                 input.resource_stats_id = stats.id
+
                 const resource = resourceSchema.dto.parse(
                     await service.create(input)
                 )
 
+                await searchService.indexResource(resource.id)
+
                 return c.json({ resource, stats })
             } catch (e) {
                 return c.json(
@@ -118,6 +123,8 @@ export const resourceRouter = honoWithJwt()
                 const input = c.req.valid('json')
                 const resource = resourceSchema.dto.parse(await service.update(input))
 
+                await searchService.indexResource(resource.id)
+
                 return c.json({ resource })
             } catch (e) {
                 return c.json(
@@ -191,6 +198,8 @@ export const resourceRouter = honoWithJwt()
                 const id = +c.req.param('id')
                 const resource = resourceSchema.dto.parse(await service.delete(id))
 
+                await searchService.deindexDocument(resource.id, 'resources')
+
                 return c.json(resource)
             } catch (e) {
                 return c.json(
diff --git a/src/routes/search.route.ts b/src/routes/search.route.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a30fe330f02d96f45c945232fe5d32cb3d67fca0
--- /dev/null
+++ b/src/routes/search.route.ts
@@ -0,0 +1,111 @@
+import { SearchService } from "@/services/search.service";
+import Container from "typedi";
+// import { honoWithJwt } from "..";
+import { Hono } from "hono";
+import { z } from "zod";
+import { zValidator } from "@hono/zod-validator";
+import { createApexError, HttpStatus } from "@/services/error.service";
+
+const searchService = Container.get(SearchService);
+
+export const searchRouter = new Hono()
+  .get(
+    '/search',
+    zValidator(
+      'query',
+      z.object({
+        query: z.string().min(1, 'Query is required'),
+      })
+    ),
+    async (c) => {
+      try {
+        const { query } = c.req.valid('query');
+
+        const results = await searchService.searchIndex(query, {});
+
+        return c.json({ results });
+      } catch (e) {
+        console.log(e)
+        return c.json(
+          createApexError({
+            status: 'error',
+            message: 'Search failed',
+            code: HttpStatus.BAD_REQUEST,
+            path: c.req.routePath,
+            suggestion: 'Try a different query',
+          }),
+          HttpStatus.BAD_REQUEST
+        );
+      }
+    }
+  )
+
+  .post(
+    '/index/resource/:id', 
+    async (c) => {
+      try {
+        const id: number = +c.req.param('id')
+  
+        await searchService.indexResource(id);
+        return c.json({ message: `resource indexed successfully`});
+      } catch (e) {
+        return c.json(
+          createApexError({
+            status: 'error',
+            message: 'Failed to index resource',
+            code: HttpStatus.INTERNAL_SERVER_ERROR,
+            path: c.req.routePath,
+            suggestion: 'Check resource format and try again',
+          }),
+          HttpStatus.INTERNAL_SERVER_ERROR
+        );
+      }
+    }
+  )
+
+  .post(
+    '/index/collection/:id', 
+    async (c) => {
+      try {
+        const id: number = +c.req.param('id')
+  
+        await searchService.indexCollection(id);
+        return c.json({ message: `collection indexed successfully`});
+      } catch (e) {
+        return c.json(
+          createApexError({
+            status: 'error',
+            message: 'Failed to index collection',
+            code: HttpStatus.INTERNAL_SERVER_ERROR,
+            path: c.req.routePath,
+            suggestion: 'Check collection format and try again',
+          }),
+          HttpStatus.INTERNAL_SERVER_ERROR
+        );
+      }
+    }
+  )
+
+  .post(
+    '/index/user/:id', 
+    async (c) => {
+      try {
+        const id: number = +c.req.param('id')
+  
+        await searchService.indexUser(id);
+
+        return c.json({ message: `user indexed successfully`});
+      } catch (e) {
+        return c.json(
+          createApexError({
+            status: 'error',
+            message: 'Failed to index user',
+            code: HttpStatus.INTERNAL_SERVER_ERROR,
+            path: c.req.routePath,
+            suggestion: 'Check user format and try again',
+          }),
+          HttpStatus.INTERNAL_SERVER_ERROR
+        );
+      }
+    }
+  );
diff --git a/src/routes/user-institution.route.ts b/src/routes/user-institution.route.ts
index a053519ccda16b890faf0f9671d7aec52a47c6b3..097681ceca1dd8104f809eadad7447b9220610f0 100644
--- a/src/routes/user-institution.route.ts
+++ b/src/routes/user-institution.route.ts
@@ -33,7 +33,6 @@ export const userInstitutionRouter = honoWithJwt()
         if(user == null || institution == null || alreadyInstitution){
           throw new Error()
         }
-        console.log('oiiii')
 
         const user_institution = userInstitutionRelationSchemas.dto.parse(
           await service.create(input)
diff --git a/src/routes/user.route.ts b/src/routes/user.route.ts
index af4790d29824fa329970fac58e50f15eefed2a22..51bad6245337226ef9088727496ad6391245d10f 100644
--- a/src/routes/user.route.ts
+++ b/src/routes/user.route.ts
@@ -8,6 +8,7 @@ import { createApexError, HttpStatus } from '@/services/error.service'
 import { followRelationSchemas } from '@/db/relations/followers.relation'
 import { UserStatsService } from '@/services/user-stats.service'
 import { FollowRelationService } from '@/services/follow.relation.service'
+import { SearchService } from "@/services/search.service";
 
 import {
   followUserRoute,
@@ -27,6 +28,7 @@ import {
 const service = Container.get(UserService)
 const followService = Container.get(FollowRelationService)
 const userStatsService = Container.get(UserStatsService)
+const searchService = Container.get(SearchService);
 
 export const userRouter = honoWithJwt()
   .get('/me', meUserRoute,
@@ -289,6 +291,8 @@ export const userRouter = honoWithJwt()
         const deleted_user = userSchemas.userDtoSchema.parse(
           await service.update(user)
         )
+        
+        await searchService.deindexDocument(id, 'users')
 
         return c.json(deleted_user)
       } catch (e) {
@@ -312,6 +316,8 @@ export const userRouter = honoWithJwt()
           await service.systemDelete(id)
         )
 
+        await searchService.deindexDocument(id, 'users')
+
         return c.json(user)
       } catch (e) {
         return c.json(
diff --git a/src/search/index.ts b/src/search/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3269b06dd5f6f0d5be213f3c87eefc2eef590fb1
--- /dev/null
+++ b/src/search/index.ts
@@ -0,0 +1,29 @@
+import { Client, HttpConnection } from '@elastic/elasticsearch'
+import env from '@/env'
+import { Container } from 'typedi'
+
+// Initialize Elasticsearch client
+export const es = new Client({
+  node: env.ELASTICSEARCH_URL,
+  Connection: HttpConnection,
+})
+
+// Register the Elasticsearch client in the DI container
+console.log("Registering Elasticsearch client...");
+Container.set('ElasticSearchClient', es)
+
+export const checkElasticsearchConnection = async () => {
+  try {
+    const health = await es.cluster.health()
+    console.log(`Elasticsearch cluster status: ${health.status}`)
+  } catch (error) {
+    console.error('Error connecting to Elasticsearch:', error)
+    process.exit(1)
+  }
+}
+
+checkElasticsearchConnection()
+
+export type es = typeof es
+
+export default es
\ No newline at end of file
diff --git a/src/services/search.service.ts b/src/services/search.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5991e1fc8a32b8ff446097a45d78d7d95d2ea417
--- /dev/null
+++ b/src/services/search.service.ts
@@ -0,0 +1,237 @@
+import { Inject, Service } from "typedi"
+import es from '@/search'
+import env from '@/env'
+import  { SearchRepo } from "@/db/repo/search.repo";
+
+type ExactFilterFields = {
+  language?: string;
+  objectType?: string;
+  institution?: string;
+};
+
+@Service()
+export class SearchService {
+  @Inject('ElasticSearchClient')
+  private readonly esClient!: es
+
+  @Inject()
+  private readonly repo: SearchRepo
+
+    async indexResource(id: number): Promise<void> {
+      try {
+          const documents = await this.repo.findResourcesForIndexing(id);
+    
+          if (!documents.length) {
+            console.warn(`No document found for ID ${id}.`);
+            return;
+          }
+    
+          const document = documents[0];
+          await this.esClient.index({
+            index: env.ELASTIC_INDEX_RESOURCES,
+            id: document.id.toString(),
+            body: {
+              name: document.name,
+              author: document.author ?? "",
+              description: document.description ?? "",
+              link: document.link ?? "",
+              created_at: document.created_at,
+              educational_stages: document.educational_stages?.split(','), // Converte para array
+              languages: document.languages?.split(',') ?? [], // Converte para array
+              subjects: document.subjects?.split(',') ?? [], // Converte para array
+              license: document.license,
+              objectType: document.object_type,
+              state: document.state,
+              user: document.user,
+              views: document.views,
+              downloads: document.downloads,
+              likes: document.likes,
+              shares: document.shares,
+              score: document.score,
+              comments: document.comments
+            },
+          });
+    
+          console.log(`Document ${document.id} indexed successfully`);
+        } catch (error) {
+          console.error(`Error indexing document with ID ${id}:`, error);
+        }
+      }
+
+  async indexCollection(id: number): Promise<void> {
+    try {
+        const documents = await this.repo.findCollectionsForIndexing(id);
+    
+        if (!documents.length) {
+            console.warn(`No document found for ID ${id}.`);
+            return;
+        }
+    
+        const document = documents[0];
+        await this.esClient.index({
+            index: env.ELASTIC_INDEX_COLLECTIONS,
+            id: document.id.toString(),
+            body: {
+              name: document.name,
+              author: document.author ?? "",
+              description: document.description ?? "",
+              created_at: document.created_at,
+              score: document.score,
+              views: document.views,
+              downloads: document.downloads,
+              likes: document.likes,
+              shares: document.shares,
+              follows: document.follows
+            },
+        });
+    
+        console.log(`Document ${document.id} indexed successfully`);
+        } catch (error) {
+          console.error(`Error indexing document with ID ${id}:`, error);
+        }
+    }
+
+  async indexUser(id: number): Promise<void> {
+    try {
+        const documents = await this.repo.findUsersForIndexing(id);
+    
+        if (!documents.length) {
+            console.warn(`No document found for ID ${id}.`);
+            return;
+        }
+    
+        const document = documents[0];
+        await this.esClient.index({
+            index: env.ELASTIC_INDEX_USERS,
+            id: document.id.toString(),
+            body: {
+              name: document.name,
+              username: document.username,
+              description: document.description ?? "",
+              roles: document.roles?.split(',') ?? [],
+              institutions: document.institutions?.split(',') ?? [], // Converte para array
+              created_at: document.created_at,
+              is_active: document.is_active,
+              score: document.score,
+              likes_received: document.likes_received,
+              followers: document.followers,
+              approved_resources: document.approved_resources
+          },
+        });
+    
+        console.log(`Document ${document.id} indexed successfully`);
+        } catch (error) {
+        console.error(`Error indexing document with ID ${id}:`, error);
+        }
+    }
+
+  // filters: filtros para valores exatos (ex: language: "Português")
+  // sortBy: filtros para ordenação. No futuro: views, downloads...
+  // sortOrder: ordenação ascendente ou descendente
+  // index: lista de indexes
+  // offset: offset da paginação, número da página
+  // page_size: tamanho da página
+  async searchIndex(
+    query: string,
+    filters: Partial<ExactFilterFields>,
+    sortBy?: 'created_at',
+    sortOrder: 'asc' | 'desc' = 'desc',
+    index: string[] = [env.ELASTIC_INDEX_USERS, env.ELASTIC_INDEX_COLLECTIONS, env.ELASTIC_INDEX_RESOURCES],
+    offset: number = 0,
+    page_size: number = 1000
+  ) {
+
+    const filterClauses = Object.entries(filters)
+    .filter(([, value]) => value !== undefined)
+    .map(([key, value]) => ({
+      term: { [key]: value },
+    }));
+
+    let sort: Array<{ [key: string]: { order: 'asc' | 'desc' } }> = [];
+    if (sortBy) {
+      sort = [
+        {
+          [sortBy]: {
+            order: sortOrder,
+          },
+        },
+      ];
+    }
+
+    const result = await this.esClient.search({
+      index: index,
+      body: {
+        from: offset,
+        size: page_size,
+        query: {
+          bool: {
+            must: [
+              {
+                multi_match: {
+                  query,
+                  fuzziness: "AUTO",
+                  fields: ['name',
+                           'author',
+                           'description',
+                           'link',
+                           'fileFormats',
+                           'educational_stages',
+                           'languages',
+                           'subjects',
+                           'license',
+                           'object_type',
+                           'state',
+                           'user',
+                           'roles',
+                           'institution',
+                           'city',
+                           'views',
+                           'downloads',
+                           'likes',
+                           'shares',
+                           'score',
+                           'comments',
+                           'created_at'],
+                },
+              },
+            ],
+            filter: filterClauses,
+          },
+        },
+        sort: sort.length > 0 ? sort : undefined,
+      },
+    })
+
+    return result.hits.hits
+  }
+
+  async deindexDocument(id: number, index: string): Promise<void> {
+    try {
+      await this.esClient.delete({
+        index,
+        id: id.toString(),
+      });
+  
+      console.log(`Document ${id} deindexed successfully`);
+    } catch (error) {
+        console.error(`Error indexing document with ID ${id}:`, error);
+    }
+  }
+
+  async updateDocumentField(id: number, index: string, partialDoc: Record<string, unknown>): Promise<void> {
+    try {
+      await this.esClient.update({
+        index,
+        id: id.toString(),
+        body: {
+          doc: partialDoc,
+        },
+      });
+  
+      console.log(`Document ${id} updated successfully`);
+    } catch (error) {
+      console.error(`Error indexing document with ID ${id}:`, error);
+    }
+  }
+  
+}