mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-01-18 17:11:15 +08:00
bump tide version
This commit is contained in:
parent
a35eb16a2a
commit
0e12920910
764
Cargo.lock
generated
764
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -37,27 +37,14 @@ sysinfo = "0.9.5"
|
|||||||
ureq = { version = "0.11.2", features = ["tls"], default-features = false }
|
ureq = { version = "0.11.2", features = ["tls"], default-features = false }
|
||||||
walkdir = "2.2.9"
|
walkdir = "2.2.9"
|
||||||
whoami = "0.6"
|
whoami = "0.6"
|
||||||
|
tide = "0.5.1"
|
||||||
|
async-std = { version = "1.0.1", features = ["unstable", "attributes"] }
|
||||||
|
|
||||||
[dependencies.async-compression]
|
[dev-dependencies]
|
||||||
default-features = false
|
http-service-mock = "0.4.0"
|
||||||
features = ["stream", "gzip", "zlib", "brotli", "zstd"]
|
http-service = "0.4.0"
|
||||||
version = "=0.1.0-alpha.7"
|
|
||||||
|
|
||||||
[dependencies.tide]
|
tempdir = "0.3.7"
|
||||||
git = "https://github.com/rustasync/tide"
|
|
||||||
rev = "e77709370bb24cf776fe6da902467c35131535b1"
|
|
||||||
|
|
||||||
[dependencies.tide-log]
|
|
||||||
git = "https://github.com/rustasync/tide"
|
|
||||||
rev = "e77709370bb24cf776fe6da902467c35131535b1"
|
|
||||||
|
|
||||||
[dependencies.tide-slog]
|
|
||||||
git = "https://github.com/rustasync/tide"
|
|
||||||
rev = "e77709370bb24cf776fe6da902467c35131535b1"
|
|
||||||
|
|
||||||
[dependencies.tide-compression]
|
|
||||||
git = "https://github.com/rustasync/tide"
|
|
||||||
rev = "e77709370bb24cf776fe6da902467c35131535b1"
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
vergen = "3.0.4"
|
vergen = "3.0.4"
|
||||||
|
@ -3,7 +3,7 @@ use std::fmt::Display;
|
|||||||
use http::status::StatusCode;
|
use http::status::StatusCode;
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tide::response::IntoResponse;
|
use tide::IntoResponse;
|
||||||
use tide::Response;
|
use tide::Response;
|
||||||
|
|
||||||
pub type SResult<T> = Result<T, ResponseError>;
|
pub type SResult<T> = Result<T, ResponseError>;
|
||||||
@ -120,7 +120,5 @@ struct ErrorMessage {
|
|||||||
|
|
||||||
fn error(message: String, status: StatusCode) -> Response {
|
fn error(message: String, status: StatusCode) -> Response {
|
||||||
let message = ErrorMessage { message };
|
let message = ErrorMessage { message };
|
||||||
tide::response::json(message)
|
tide::Response::new(status.as_u16()).body_json(&message).unwrap()
|
||||||
.with_status(status)
|
|
||||||
.into_response()
|
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@ use crate::Data;
|
|||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use heed::types::{SerdeBincode, Str};
|
use heed::types::{SerdeBincode, Str};
|
||||||
use meilisearch_core::Index;
|
use meilisearch_core::Index;
|
||||||
use tide::Context;
|
use tide::Request;
|
||||||
|
|
||||||
pub trait ContextExt {
|
pub trait RequestExt {
|
||||||
fn is_allowed(&self, acl: ACL) -> SResult<()>;
|
fn is_allowed(&self, acl: ACL) -> SResult<()>;
|
||||||
fn header(&self, name: &str) -> Result<String, ResponseError>;
|
fn header(&self, name: &str) -> Result<String, ResponseError>;
|
||||||
fn url_param(&self, name: &str) -> Result<String, ResponseError>;
|
fn url_param(&self, name: &str) -> Result<String, ResponseError>;
|
||||||
@ -14,14 +14,16 @@ pub trait ContextExt {
|
|||||||
fn identifier(&self) -> Result<String, ResponseError>;
|
fn identifier(&self) -> Result<String, ResponseError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextExt for Context<Data> {
|
impl RequestExt for Request<Data> {
|
||||||
fn is_allowed(&self, acl: ACL) -> SResult<()> {
|
fn is_allowed(&self, acl: ACL) -> SResult<()> {
|
||||||
let api_key = match &self.state().api_key {
|
let api_key = match &self.state().api_key {
|
||||||
Some(api_key) => api_key,
|
Some(api_key) => api_key,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let user_api_key = self.header("X-Meili-API-Key")?;
|
let user_api_key = self.header("X-Meili-API-Key")
|
||||||
|
.ok_or(ResponseError::missing_header("X-Meili-API-Key"))?;
|
||||||
|
|
||||||
if user_api_key == *api_key {
|
if user_api_key == *api_key {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use std::env::VarError::NotPresent;
|
use std::env::VarError::NotPresent;
|
||||||
use std::{env, thread};
|
use std::{env, thread};
|
||||||
|
|
||||||
use http::header::HeaderValue;
|
use async_std::task;
|
||||||
use log::info;
|
use log::info;
|
||||||
use main_error::MainError;
|
use main_error::MainError;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use tide::middleware::{CorsMiddleware, CorsOrigin};
|
// use tide::middleware::{CorsMiddleware, CorsOrigin};
|
||||||
use tide_log::RequestLogger;
|
// use tide_log::RequestLogger;
|
||||||
|
|
||||||
use meilisearch_http::data::Data;
|
use meilisearch_http::data::Data;
|
||||||
use meilisearch_http::option::Opt;
|
use meilisearch_http::option::Opt;
|
||||||
@ -34,21 +34,23 @@ pub fn main() -> Result<(), MainError> {
|
|||||||
index_update_callback(name, &data_cloned, status);
|
index_update_callback(name, &data_cloned, status);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mut app = tide::App::with_state(data);
|
let mut app = tide::with_state(data);
|
||||||
|
|
||||||
app.middleware(
|
// app.middleware(
|
||||||
CorsMiddleware::new()
|
// CorsMiddleware::new()
|
||||||
.allow_origin(CorsOrigin::from("*"))
|
// .allow_origin(CorsOrigin::from("*"))
|
||||||
.allow_methods(HeaderValue::from_static("GET, POST, OPTIONS")),
|
// .allow_methods(HeaderValue::from_static("GET, POST, OPTIONS")),
|
||||||
);
|
// );
|
||||||
app.middleware(RequestLogger::new());
|
// app.middleware(RequestLogger::new());
|
||||||
app.middleware(tide_compression::Compression::new());
|
// app.middleware(tide_compression::Compression::new());
|
||||||
app.middleware(tide_compression::Decompression::new());
|
// app.middleware(tide_compression::Decompression::new());
|
||||||
|
|
||||||
routes::load_routes(&mut app);
|
routes::load_routes(&mut app);
|
||||||
|
|
||||||
info!("Server HTTP enabled");
|
info!("Server HTTP enabled");
|
||||||
app.run(opt.http_addr)?;
|
|
||||||
|
|
||||||
|
task::block_on(async {
|
||||||
|
app.listen(opt.http_addr).await.unwrap();
|
||||||
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
|
|
||||||
use std::collections::{BTreeSet, HashSet};
|
use std::collections::{BTreeSet, HashSet};
|
||||||
|
|
||||||
use http::StatusCode;
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tide::querystring::ContextExt as QSContextExt;
|
use tide::{Request, Response};
|
||||||
use tide::response::IntoResponse;
|
|
||||||
use tide::{Context, Response};
|
|
||||||
use meilisearch_core::settings::Settings;
|
use meilisearch_core::settings::Settings;
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
pub async fn get_document(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_document(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsRead)?;
|
ctx.is_allowed(DocumentsRead)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -35,7 +32,7 @@ pub async fn get_document(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
return Err(ResponseError::document_not_found(identifier));
|
return Err(ResponseError::document_not_found(identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Serialize)]
|
#[derive(Default, Serialize)]
|
||||||
@ -44,7 +41,7 @@ pub struct IndexUpdateResponse {
|
|||||||
pub update_id: u64,
|
pub update_id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_document(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn delete_document(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(DocumentsWrite)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -63,9 +60,7 @@ pub async fn delete_document(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
update_writer.commit().map_err(ResponseError::internal)?;
|
update_writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Deserialize)]
|
#[derive(Default, Deserialize)]
|
||||||
@ -76,11 +71,11 @@ struct BrowseQuery {
|
|||||||
attributes_to_retrieve: Option<String>,
|
attributes_to_retrieve: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_documents(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_all_documents(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsRead)?;
|
ctx.is_allowed(DocumentsRead)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let query: BrowseQuery = ctx.url_query().unwrap_or(BrowseQuery::default());
|
let query: BrowseQuery = ctx.query().unwrap_or(BrowseQuery::default());
|
||||||
|
|
||||||
let offset = query.offset.unwrap_or(0);
|
let offset = query.offset.unwrap_or(0);
|
||||||
let limit = query.limit.unwrap_or(20);
|
let limit = query.limit.unwrap_or(20);
|
||||||
@ -116,7 +111,7 @@ pub async fn get_all_documents(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tide::response::json(response_body))
|
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_identifier(document: &IndexMap<String, Value>) -> Option<String> {
|
fn find_identifier(document: &IndexMap<String, Value>) -> Option<String> {
|
||||||
@ -134,15 +129,14 @@ struct UpdateDocumentsQuery {
|
|||||||
identifier: Option<String>,
|
identifier: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_multiple_documents(mut ctx: Context<Data>, is_partial: bool) -> SResult<Response> {
|
async fn update_multiple_documents(mut ctx: Request<Data>, is_partial: bool) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(DocumentsWrite)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
let data: Vec<IndexMap<String, Value>> =
|
let data: Vec<IndexMap<String, Value>> =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
let query: UpdateDocumentsQuery = ctx
|
let query: UpdateDocumentsQuery = ctx.query().unwrap_or_default();
|
||||||
.url_query().unwrap_or_default();
|
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn().map_err(ResponseError::internal)?;
|
let reader = db.main_read_txn().map_err(ResponseError::internal)?;
|
||||||
@ -188,20 +182,18 @@ async fn update_multiple_documents(mut ctx: Context<Data>, is_partial: bool) ->
|
|||||||
update_writer.commit().map_err(ResponseError::internal)?;
|
update_writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_or_replace_multiple_documents(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn add_or_replace_multiple_documents(ctx: Request<Data>) -> SResult<Response> {
|
||||||
update_multiple_documents(ctx, false).await
|
update_multiple_documents(ctx, false).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_or_update_multiple_documents(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn add_or_update_multiple_documents(ctx: Request<Data>) -> SResult<Response> {
|
||||||
update_multiple_documents(ctx, true).await
|
update_multiple_documents(ctx, true).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_multiple_documents(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn delete_multiple_documents(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(DocumentsWrite)?;
|
||||||
|
|
||||||
let data: Vec<Value> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
let data: Vec<Value> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -226,12 +218,10 @@ pub async fn delete_multiple_documents(mut ctx: Context<Data>) -> SResult<Respon
|
|||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn clear_all_documents(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn clear_all_documents(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(DocumentsWrite)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -245,7 +235,5 @@ pub async fn clear_all_documents(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
use heed::types::{Str, Unit};
|
use heed::types::{Str, Unit};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tide::Context;
|
use tide::{Response, Request};
|
||||||
|
|
||||||
const UNHEALTHY_KEY: &str = "_is_unhealthy";
|
const UNHEALTHY_KEY: &str = "_is_unhealthy";
|
||||||
|
|
||||||
pub async fn get_health(ctx: Context<Data>) -> SResult<()> {
|
pub async fn get_health(ctx: Request<Data>) -> SResult<Response> {
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn().map_err(ResponseError::internal)?;
|
let reader = db.main_read_txn().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
@ -19,10 +19,10 @@ pub async fn get_health(ctx: Context<Data>) -> SResult<()> {
|
|||||||
return Err(ResponseError::Maintenance);
|
return Err(ResponseError::Maintenance);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(tide::Response::new(200))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_healthy(ctx: Context<Data>) -> SResult<()> {
|
pub async fn set_healthy(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
@ -38,10 +38,10 @@ pub async fn set_healthy(ctx: Context<Data>) -> SResult<()> {
|
|||||||
return Err(ResponseError::internal(e));
|
return Err(ResponseError::internal(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(tide::Response::new(200))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_unhealthy(ctx: Context<Data>) -> SResult<()> {
|
pub async fn set_unhealthy(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
@ -57,7 +57,7 @@ pub async fn set_unhealthy(ctx: Context<Data>) -> SResult<()> {
|
|||||||
return Err(ResponseError::internal(e));
|
return Err(ResponseError::internal(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(tide::Response::new(200))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone)]
|
||||||
@ -65,7 +65,7 @@ struct HealtBody {
|
|||||||
health: bool,
|
health: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn change_healthyness(mut ctx: Context<Data>) -> SResult<()> {
|
pub async fn change_healthyness(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
let body: HealtBody = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
let body: HealtBody = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
|
|
||||||
if body.health {
|
if body.health {
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use http::StatusCode;
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use meilisearch_core::ProcessedUpdateResult;
|
use meilisearch_core::ProcessedUpdateResult;
|
||||||
// use meilisearch_schema::Schema;
|
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use tide::response::IntoResponse;
|
use tide::{Request, Response};
|
||||||
use tide::{Context, Response};
|
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
@ -23,7 +20,7 @@ fn generate_uid() -> String {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_indexes(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn list_indexes(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(IndexesRead)?;
|
||||||
|
|
||||||
let indexes_uids = ctx.state().db.indexes_uids();
|
let indexes_uids = ctx.state().db.indexes_uids();
|
||||||
@ -69,7 +66,7 @@ pub async fn list_indexes(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tide::response::json(response_body))
|
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
@ -81,7 +78,7 @@ struct IndexResponse {
|
|||||||
updated_at: DateTime<Utc>,
|
updated_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_index(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_index(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(IndexesRead)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -113,7 +110,7 @@ pub async fn get_index(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
updated_at,
|
updated_at,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(response_body))
|
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@ -129,14 +126,11 @@ struct IndexCreateRequest {
|
|||||||
struct IndexCreateResponse {
|
struct IndexCreateResponse {
|
||||||
name: String,
|
name: String,
|
||||||
uid: String,
|
uid: String,
|
||||||
// schema: Option<SchemaBody>,
|
|
||||||
// #[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
// update_id: Option<u64>,
|
|
||||||
created_at: DateTime<Utc>,
|
created_at: DateTime<Utc>,
|
||||||
updated_at: DateTime<Utc>,
|
updated_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_index(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn create_index(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesWrite)?;
|
ctx.is_allowed(IndexesWrite)?;
|
||||||
|
|
||||||
let body = ctx
|
let body = ctx
|
||||||
@ -171,27 +165,17 @@ pub async fn create_index(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
// let schema: Option<Schema> = body.schema.clone().map(Into::into);
|
// let schema: Option<Schema> = body.schema.clone().map(Into::into);
|
||||||
// let mut response_update_id = None;
|
// let mut response_update_id = None;
|
||||||
// if let Some(schema) = schema {
|
// if let Some(schema) = schema {
|
||||||
// let update_id = created_index
|
|
||||||
// .schema_update(&mut update_writer, schema)
|
|
||||||
// .map_err(ResponseError::internal)?;
|
|
||||||
// response_update_id = Some(update_id)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
// update_writer.commit().map_err(ResponseError::internal)?;
|
|
||||||
|
|
||||||
let response_body = IndexCreateResponse {
|
let response_body = IndexCreateResponse {
|
||||||
name: body.name,
|
name: name,
|
||||||
uid,
|
uid,
|
||||||
// schema: body.schema,
|
|
||||||
// update_id: update_id,
|
|
||||||
created_at: Utc::now(),
|
created_at: Utc::now(),
|
||||||
updated_at: Utc::now(),
|
updated_at: Utc::now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(201).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::CREATED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@ -209,7 +193,7 @@ struct UpdateIndexResponse {
|
|||||||
updated_at: DateTime<Utc>,
|
updated_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_index(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn update_index(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesWrite)?;
|
ctx.is_allowed(IndexesWrite)?;
|
||||||
|
|
||||||
let body = ctx
|
let body = ctx
|
||||||
@ -254,12 +238,10 @@ pub async fn update_index(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
updated_at,
|
updated_at,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::OK)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_update_status(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_update_status(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(IndexesRead)?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
@ -275,41 +257,33 @@ pub async fn get_update_status(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
.map_err(ResponseError::internal)?;
|
.map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response = match status {
|
let response = match status {
|
||||||
Some(status) => tide::response::json(status)
|
Some(status) => tide::Response::new(200).body_json(&status).unwrap(),
|
||||||
.with_status(StatusCode::OK)
|
None => tide::Response::new(404).body_json(&json!({ "message": "unknown update id" })).unwrap(),
|
||||||
.into_response(),
|
|
||||||
None => tide::response::json(json!({ "message": "unknown update id" }))
|
|
||||||
.with_status(StatusCode::NOT_FOUND)
|
|
||||||
.into_response(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_updates_status(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_all_updates_status(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(IndexesRead)?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.update_read_txn().map_err(ResponseError::internal)?;
|
let reader = db.update_read_txn().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let all_status = index
|
let response = index
|
||||||
.all_updates_status(&reader)
|
.all_updates_status(&reader)
|
||||||
.map_err(ResponseError::internal)?;
|
.map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response = tide::response::json(all_status)
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
.with_status(StatusCode::OK)
|
|
||||||
.into_response();
|
|
||||||
|
|
||||||
Ok(response)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_index(ctx: Context<Data>) -> SResult<StatusCode> {
|
pub async fn delete_index(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesWrite)?;
|
ctx.is_allowed(IndexesWrite)?;
|
||||||
let _ = ctx.index()?;
|
let _ = ctx.index()?;
|
||||||
let index_uid = ctx.url_param("index")?;
|
let index_uid = ctx.url_param("index")?;
|
||||||
ctx.state().db.delete_index(&index_uid).map_err(ResponseError::internal)?;
|
ctx.state().db.delete_index(&index_uid).map_err(ResponseError::internal)?;
|
||||||
Ok(StatusCode::NO_CONTENT)
|
Ok(tide::Response::new(204))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpdateResult) {
|
pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpdateResult) {
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
use chrono::serde::ts_seconds;
|
use chrono::serde::ts_seconds;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use heed::types::{SerdeBincode, Str};
|
use heed::types::{SerdeBincode, Str};
|
||||||
use http::StatusCode;
|
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tide::response::IntoResponse;
|
use tide::{Request, Response};
|
||||||
use tide::{Context, Response};
|
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::models::token::*;
|
use crate::models::token::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
@ -22,7 +20,7 @@ fn generate_api_key() -> String {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn list(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
@ -41,10 +39,10 @@ pub async fn list(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
response.push(token);
|
response.push(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
let request_key = ctx.url_param("key")?;
|
let request_key = ctx.url_param("key")?;
|
||||||
|
|
||||||
@ -62,7 +60,7 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
token_key
|
token_key
|
||||||
)))?;
|
)))?;
|
||||||
|
|
||||||
Ok(tide::response::json(token_config))
|
Ok(tide::Response::new(200).body_json(&token_config).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@ -75,7 +73,7 @@ pub struct CreatedRequest {
|
|||||||
expires_at: DateTime<Utc>,
|
expires_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn create(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
|
|
||||||
let data: CreatedRequest = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
let data: CreatedRequest = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -103,9 +101,7 @@ pub async fn create(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
|
|
||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
Ok(tide::response::json(token_definition)
|
Ok(tide::Response::new(201).body_json(&token_definition).unwrap())
|
||||||
.with_status(StatusCode::CREATED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@ -118,7 +114,7 @@ pub struct UpdatedRequest {
|
|||||||
revoked: Option<bool>,
|
revoked: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
let request_key = ctx.url_param("key")?;
|
let request_key = ctx.url_param("key")?;
|
||||||
|
|
||||||
@ -168,12 +164,10 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
|
|
||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
Ok(tide::response::json(token_config)
|
Ok(tide::Response::new(200).body_json(&token_config).unwrap())
|
||||||
.with_status(StatusCode::OK)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(ctx: Context<Data>) -> SResult<StatusCode> {
|
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
let request_key = ctx.url_param("key")?;
|
let request_key = ctx.url_param("key")?;
|
||||||
|
|
||||||
@ -190,5 +184,5 @@ pub async fn delete(ctx: Context<Data>) -> SResult<StatusCode> {
|
|||||||
|
|
||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
Ok(StatusCode::NO_CONTENT)
|
Ok(tide::Response::new(204))
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
use tide::Response;
|
||||||
|
use tide::IntoResponse;
|
||||||
|
use std::future::Future;
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
|
|
||||||
pub mod document;
|
pub mod document;
|
||||||
@ -10,113 +13,108 @@ pub mod stats;
|
|||||||
pub mod stop_words;
|
pub mod stop_words;
|
||||||
pub mod synonym;
|
pub mod synonym;
|
||||||
|
|
||||||
pub fn load_routes(app: &mut tide::App<Data>) {
|
async fn into_response<T: IntoResponse, U: IntoResponse>(x: impl Future<Output = Result<T, U>>) -> Response {
|
||||||
|
match x.await {
|
||||||
|
Ok(resp) => resp.into_response(),
|
||||||
|
Err(resp) => resp.into_response(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_routes(app: &mut tide::Server<Data>) {
|
||||||
app.at("").nest(|router| {
|
app.at("").nest(|router| {
|
||||||
// expose the web interface static files
|
// expose the web interface static files
|
||||||
router.at("/").get(|_| async {
|
router.at("/").get(|_| async move {
|
||||||
let content = include_str!("../../public/interface.html").to_owned();
|
let response = include_str!("../../public/interface.html");
|
||||||
tide::http::Response::builder()
|
response
|
||||||
.header(tide::http::header::CONTENT_TYPE, "text/html; charset=utf-8")
|
|
||||||
.status(tide::http::StatusCode::OK)
|
|
||||||
.body(content).unwrap()
|
|
||||||
});
|
});
|
||||||
router.at("/bulma.min.css").get(|_| async {
|
router.at("/bulma.min.css").get(|_| async {
|
||||||
let content = include_str!("../../public/bulma.min.css");
|
let response = include_str!("../../public/bulma.min.css");
|
||||||
tide::http::Response::builder()
|
response
|
||||||
.header(tide::http::header::CONTENT_TYPE, "text/css; charset=utf-8")
|
|
||||||
.status(tide::http::StatusCode::OK)
|
|
||||||
.body(content).unwrap()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.at("/indexes").nest(|router| {
|
router.at("/indexes").nest(|router| {
|
||||||
router
|
router
|
||||||
.at("/")
|
.at("/")
|
||||||
.get(index::list_indexes)
|
.get(|ctx| into_response(index::list_indexes(ctx)))
|
||||||
.post(index::create_index);
|
.post(|ctx| into_response(index::create_index(ctx)));
|
||||||
|
|
||||||
router.at("/search").post(search::search_multi_index);
|
router.at("/search").post(|ctx| into_response(search::search_multi_index(ctx)));
|
||||||
|
|
||||||
router.at("/:index").nest(|router| {
|
router.at("/:index").nest(|router| {
|
||||||
router.at("/search").get(search::search_with_url_query);
|
router.at("/search").get(|ctx| into_response(search::search_with_url_query(ctx)));
|
||||||
|
|
||||||
router.at("/updates").nest(|router| {
|
router.at("/updates").nest(|router| {
|
||||||
router.at("/").get(index::get_all_updates_status);
|
router.at("/").get(|ctx| into_response(index::get_all_updates_status(ctx)));
|
||||||
|
|
||||||
router.at("/:update_id").get(index::get_update_status);
|
router.at("/:update_id").get(|ctx| into_response(index::get_update_status(ctx)));
|
||||||
});
|
});
|
||||||
|
|
||||||
router
|
router
|
||||||
.at("/")
|
.at("/")
|
||||||
.get(index::get_index)
|
.get(|ctx| into_response(index::get_index(ctx)))
|
||||||
.put(index::update_index)
|
.put(|ctx| into_response(index::update_index(ctx)))
|
||||||
.delete(index::delete_index);
|
.delete(|ctx| into_response(index::delete_index(ctx)));
|
||||||
|
|
||||||
// router
|
|
||||||
// .at("/schema")
|
|
||||||
// .get(index::get_index_schema)
|
|
||||||
// .put(index::update_schema);
|
|
||||||
|
|
||||||
router.at("/documents").nest(|router| {
|
router.at("/documents").nest(|router| {
|
||||||
router
|
router
|
||||||
.at("/")
|
.at("/")
|
||||||
.get(document::get_all_documents)
|
.get(|ctx| into_response(document::get_all_documents(ctx)))
|
||||||
.post(document::add_or_replace_multiple_documents)
|
.post(|ctx| into_response(document::add_or_replace_multiple_documents(ctx)))
|
||||||
.put(document::add_or_update_multiple_documents)
|
.put(|ctx| into_response(document::add_or_update_multiple_documents(ctx)))
|
||||||
.delete(document::clear_all_documents);
|
.delete(|ctx| into_response(document::clear_all_documents(ctx)));
|
||||||
|
|
||||||
router.at("/:identifier").nest(|router| {
|
router.at("/:identifier").nest(|router| {
|
||||||
router
|
router
|
||||||
.at("/")
|
.at("/")
|
||||||
.get(document::get_document)
|
.get(|ctx| into_response(document::get_document(ctx)))
|
||||||
.delete(document::delete_document);
|
.delete(|ctx| into_response(document::delete_document(ctx)));
|
||||||
});
|
});
|
||||||
|
|
||||||
router
|
router
|
||||||
.at("/delete-batch")
|
.at("/delete-batch")
|
||||||
.post(document::delete_multiple_documents);
|
.post(|ctx| into_response(document::delete_multiple_documents(ctx)));
|
||||||
});
|
});
|
||||||
|
|
||||||
router.at("/settings").nest(|router| {
|
router.at("/settings").nest(|router| {
|
||||||
router.at("/synonyms")
|
router.at("/synonyms")
|
||||||
.get(synonym::get)
|
.get(|ctx| into_response(synonym::get(ctx)))
|
||||||
.post(synonym::update)
|
.post(|ctx| into_response(synonym::update(ctx)))
|
||||||
.delete(synonym::delete);
|
.delete(|ctx| into_response(synonym::delete(ctx)));
|
||||||
|
|
||||||
router.at("/stop-words")
|
router.at("/stop-words")
|
||||||
.get(stop_words::get)
|
.get(|ctx| into_response(stop_words::get(ctx)))
|
||||||
.post(stop_words::update)
|
.post(|ctx| into_response(stop_words::update(ctx)))
|
||||||
.delete(stop_words::delete);
|
.delete(|ctx| into_response(stop_words::delete(ctx)));
|
||||||
})
|
})
|
||||||
.get(setting::get)
|
.get(|ctx| into_response(setting::get(ctx)))
|
||||||
.post(setting::update);
|
.post(|ctx| into_response(setting::update(ctx)));
|
||||||
|
|
||||||
|
router.at("/stats").get(|ctx| into_response(stats::index_stat(ctx)));
|
||||||
router.at("/stats").get(stats::index_stat);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.at("/keys").nest(|router| {
|
router.at("/keys").nest(|router| {
|
||||||
router.at("/").get(key::list).post(key::create);
|
router.at("/").get(|ctx| into_response(key::list(ctx))).post(|ctx| into_response(key::create(ctx)));
|
||||||
|
|
||||||
router
|
router
|
||||||
.at("/:key")
|
.at("/:key")
|
||||||
.get(key::get)
|
.get(|ctx| into_response(key::get(ctx)))
|
||||||
.put(key::update)
|
.put(|ctx| into_response(key::update(ctx)))
|
||||||
.delete(key::delete);
|
.delete(|ctx| into_response(key::delete(ctx)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.at("").nest(|router| {
|
app.at("").nest(|router| {
|
||||||
router
|
router
|
||||||
.at("/health")
|
.at("/health")
|
||||||
.get(health::get_health)
|
.get(|ctx| into_response(health::get_health(ctx)))
|
||||||
.put(health::change_healthyness);
|
.put(|ctx| into_response(health::change_healthyness(ctx)));
|
||||||
|
|
||||||
router.at("/stats").get(stats::get_stats);
|
router.at("/stats").get(|ctx| into_response(stats::get_stats(ctx)));
|
||||||
router.at("/version").get(stats::get_version);
|
router.at("/version").get(|ctx| into_response(stats::get_version(ctx)));
|
||||||
router.at("/sys-info").get(stats::get_sys_info);
|
router.at("/sys-info").get(|ctx| into_response(stats::get_sys_info(ctx)));
|
||||||
router
|
router
|
||||||
.at("/sys-info/pretty")
|
.at("/sys-info/pretty")
|
||||||
.get(stats::get_sys_info_pretty);
|
.get(|ctx| into_response(stats::get_sys_info_pretty(ctx)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,11 @@ use std::time::Duration;
|
|||||||
use meilisearch_core::Index;
|
use meilisearch_core::Index;
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tide::querystring::ContextExt as QSContextExt;
|
use tide::{Request, Response};
|
||||||
use tide::{Context, Response};
|
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchHit};
|
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchHit};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -28,7 +27,7 @@ struct SearchQuery {
|
|||||||
matches: Option<bool>,
|
matches: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search_with_url_query(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn search_with_url_query(ctx: Request<Data>) -> SResult<Response> {
|
||||||
// ctx.is_allowed(DocumentsRead)?;
|
// ctx.is_allowed(DocumentsRead)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -41,8 +40,7 @@ pub async fn search_with_url_query(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
.map_err(ResponseError::internal)?
|
.map_err(ResponseError::internal)?
|
||||||
.ok_or(ResponseError::open_index("No Schema found"))?;
|
.ok_or(ResponseError::open_index("No Schema found"))?;
|
||||||
|
|
||||||
let query: SearchQuery = ctx
|
let query: SearchQuery = ctx.query()
|
||||||
.url_query()
|
|
||||||
.map_err(|_| ResponseError::bad_request("invalid query parameter"))?;
|
.map_err(|_| ResponseError::bad_request("invalid query parameter"))?;
|
||||||
|
|
||||||
let mut search_builder = index.new_search(query.q.clone());
|
let mut search_builder = index.new_search(query.q.clone());
|
||||||
@ -111,7 +109,7 @@ pub async fn search_with_url_query(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
Err(others) => return Err(ResponseError::bad_request(others)),
|
Err(others) => return Err(ResponseError::bad_request(others)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
@ -140,7 +138,7 @@ struct SearchMultiBodyResponse {
|
|||||||
query: String,
|
query: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search_multi_index(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn search_multi_index(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
// ctx.is_allowed(DocumentsRead)?;
|
// ctx.is_allowed(DocumentsRead)?;
|
||||||
let body = ctx
|
let body = ctx
|
||||||
.body_json::<SearchMultiBody>()
|
.body_json::<SearchMultiBody>()
|
||||||
@ -232,5 +230,5 @@ pub async fn search_multi_index(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
query: body.query,
|
query: body.query,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use http::StatusCode;
|
|
||||||
use serde::{Deserialize, Serialize, Deserializer};
|
use serde::{Deserialize, Serialize, Deserializer};
|
||||||
use tide::response::IntoResponse;
|
use tide::{Request, Response};
|
||||||
use tide::{Context, Response};
|
|
||||||
// use indexmap::IndexMap;
|
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::routes::document::IndexUpdateResponse;
|
use crate::routes::document::IndexUpdateResponse;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
@ -13,7 +10,6 @@ use crate::Data;
|
|||||||
#[derive(Default, Serialize, Deserialize)]
|
#[derive(Default, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||||
pub struct Setting {
|
pub struct Setting {
|
||||||
// pub ranking_order: Option<RankingOrder>,
|
|
||||||
pub distinct_field: Option<DistinctField>,
|
pub distinct_field: Option<DistinctField>,
|
||||||
pub ranking_rules: Option<RankingRules>,
|
pub ranking_rules: Option<RankingRules>,
|
||||||
}
|
}
|
||||||
@ -25,11 +21,10 @@ pub enum RankingOrdering {
|
|||||||
Dsc,
|
Dsc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub type RankingOrder = Vec<String>;
|
|
||||||
pub type DistinctField = String;
|
pub type DistinctField = String;
|
||||||
pub type RankingRules = Vec<String>;
|
pub type RankingRules = Vec<String>;
|
||||||
|
|
||||||
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(SettingsRead)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -41,14 +36,12 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
None => Setting::default(),
|
None => Setting::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(settings))
|
Ok(tide::Response::new(200).body_json(&settings).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||||
pub struct SettingBody {
|
pub struct SettingBody {
|
||||||
// #[serde(default, deserialize_with = "deserialize_some")]
|
|
||||||
// pub ranking_order: Option<Option<RankingOrder>>,
|
|
||||||
#[serde(default, deserialize_with = "deserialize_some")]
|
#[serde(default, deserialize_with = "deserialize_some")]
|
||||||
pub distinct_field: Option<Option<DistinctField>>,
|
pub distinct_field: Option<Option<DistinctField>>,
|
||||||
#[serde(default, deserialize_with = "deserialize_some")]
|
#[serde(default, deserialize_with = "deserialize_some")]
|
||||||
@ -63,7 +56,7 @@ fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
|
|||||||
Deserialize::deserialize(deserializer).map(Some)
|
Deserialize::deserialize(deserializer).map(Some)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(SettingsWrite)?;
|
||||||
|
|
||||||
let settings: SettingBody = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
let settings: SettingBody = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -79,10 +72,6 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
None => Setting::default(),
|
None => Setting::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// if let Some(ranking_order) = settings.ranking_order {
|
|
||||||
// current_settings.ranking_order = ranking_order;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if let Some(distinct_field) = settings.distinct_field {
|
if let Some(distinct_field) = settings.distinct_field {
|
||||||
current_settings.distinct_field = distinct_field;
|
current_settings.distinct_field = distinct_field;
|
||||||
}
|
}
|
||||||
@ -100,7 +89,5 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,11 @@ use log::error;
|
|||||||
use pretty_bytes::converter::convert;
|
use pretty_bytes::converter::convert;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sysinfo::{NetworkExt, Pid, ProcessExt, ProcessorExt, System, SystemExt};
|
use sysinfo::{NetworkExt, Pid, ProcessExt, ProcessorExt, System, SystemExt};
|
||||||
use tide::{Context, Response};
|
use tide::{Request, Response};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ struct IndexStatsResponse {
|
|||||||
fields_frequency: HashMap<String, usize>,
|
fields_frequency: HashMap<String, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn index_stat(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn index_stat(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
let index_uid = ctx.url_param("index")?;
|
let index_uid = ctx.url_param("index")?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -52,7 +52,7 @@ pub async fn index_stat(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
is_indexing,
|
is_indexing,
|
||||||
fields_frequency,
|
fields_frequency,
|
||||||
};
|
};
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -63,7 +63,7 @@ struct StatsResult {
|
|||||||
indexes: HashMap<String, IndexStatsResponse>,
|
indexes: HashMap<String, IndexStatsResponse>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_stats(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_stats(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
|
|
||||||
let mut index_list = HashMap::new();
|
let mut index_list = HashMap::new();
|
||||||
@ -127,7 +127,7 @@ pub async fn get_stats(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
indexes: index_list,
|
indexes: index_list,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -138,7 +138,7 @@ struct VersionResponse {
|
|||||||
pkg_version: String,
|
pkg_version: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_version(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_version(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
let response = VersionResponse {
|
let response = VersionResponse {
|
||||||
commit_sha: env!("VERGEN_SHA").to_string(),
|
commit_sha: env!("VERGEN_SHA").to_string(),
|
||||||
@ -146,7 +146,7 @@ pub async fn get_version(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
pkg_version: env!("CARGO_PKG_VERSION").to_string(),
|
pkg_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -236,9 +236,10 @@ pub(crate) fn report(pid: Pid) -> SysInfo {
|
|||||||
info
|
info
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_sys_info(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_sys_info(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
Ok(tide::response::json(report(ctx.state().server_pid)))
|
let response = report(ctx.state().server_pid);
|
||||||
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -332,7 +333,8 @@ pub(crate) fn report_pretty(pid: Pid) -> SysInfoPretty {
|
|||||||
info
|
info
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_sys_info_pretty(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get_sys_info_pretty(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
Ok(tide::response::json(report_pretty(ctx.state().server_pid)))
|
let response = report_pretty(ctx.state().server_pid);
|
||||||
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use http::StatusCode;
|
use tide::{Request, Response};
|
||||||
use tide::response::IntoResponse;
|
|
||||||
use tide::{Context, Response};
|
|
||||||
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::routes::document::IndexUpdateResponse;
|
use crate::routes::document::IndexUpdateResponse;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(SettingsRead)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -29,10 +27,10 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
.into_strs()
|
.into_strs()
|
||||||
.map_err(ResponseError::internal)?;
|
.map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
Ok(tide::response::json(stop_words))
|
Ok(tide::Response::new(200).body_json(&stop_words).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(SettingsRead)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -52,12 +50,10 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(SettingsRead)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -75,7 +71,5 @@ pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use http::StatusCode;
|
use tide::{Request, Response};
|
||||||
use tide::response::IntoResponse;
|
|
||||||
use tide::{Context, Response};
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::ContextExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::models::token::ACL::*;
|
||||||
use crate::routes::document::IndexUpdateResponse;
|
use crate::routes::document::IndexUpdateResponse;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(SettingsRead)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -42,10 +40,10 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tide::response::json(response))
|
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(SettingsWrite)?;
|
||||||
|
|
||||||
let data: BTreeMap<String, Vec<String>> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
let data: BTreeMap<String, Vec<String>> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -66,13 +64,11 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
|||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
|
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(SettingsWrite)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -91,7 +87,5 @@ pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
|
|||||||
writer.commit().map_err(ResponseError::internal)?;
|
writer.commit().map_err(ResponseError::internal)?;
|
||||||
|
|
||||||
let response_body = IndexUpdateResponse { update_id };
|
let response_body = IndexUpdateResponse { update_id };
|
||||||
Ok(tide::response::json(response_body)
|
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
|
||||||
.with_status(StatusCode::ACCEPTED)
|
|
||||||
.into_response())
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user