inital commit
This commit is contained in:
commit
80e708d05a
|
@ -0,0 +1 @@
|
||||||
|
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
||||||
|
[package]
|
||||||
|
name = "starchart"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
axum = "0.6"
|
||||||
|
aide = { version = "0.11", features = [
|
||||||
|
"axum",
|
||||||
|
"axum-extra",
|
||||||
|
"redoc",
|
||||||
|
"macros",
|
||||||
|
"axum-ws",
|
||||||
|
"axum-multipart",
|
||||||
|
"axum-headers",
|
||||||
|
"axum-extra-cookie",
|
||||||
|
"axum-extra-cookie-private",
|
||||||
|
"axum-extra-form",
|
||||||
|
"axum-extra-query",
|
||||||
|
] }
|
||||||
|
rust-embed = { version = "8" }
|
||||||
|
confy = "0.5"
|
||||||
|
schemars = { version = "0.8", features = ["derive_json_schema", "uuid1"] }
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = [
|
||||||
|
"env-filter",
|
||||||
|
"fmt",
|
||||||
|
"ansi",
|
||||||
|
] }
|
||||||
|
once_cell = "1"
|
||||||
|
sqlx = { version = "0.7", features = ["runtime-tokio", "tls-rustls", "postgres", "macros"] }
|
||||||
|
serde = "1.0.186"
|
||||||
|
serde_derive = "1.0.186"
|
||||||
|
axum-jsonschema = { version = "0.6.0", features = ["aide"] }
|
||||||
|
axum-macros = "0.3.8"
|
||||||
|
tinyrand = "0.5.0"
|
||||||
|
tinyrand-std = "0.5.0"
|
||||||
|
mime_guess = "2.0.4"
|
||||||
|
hyper = "0.14.27"
|
|
@ -0,0 +1,5 @@
|
||||||
|
// generated by `sqlx migrate build-script`
|
||||||
|
fn main() {
|
||||||
|
// trigger recompilation when a new migration is added
|
||||||
|
println!("cargo:rerun-if-changed=migrations");
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
create table stars (
|
||||||
|
id Integer Primary Key Generated Always as Identity,
|
||||||
|
color varchar(7) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table stars
|
||||||
|
add constraint color_hex_constraint
|
||||||
|
check (color ~* '^#[a-f0-9]{2}[a-f0-9]{2}[a-f0-9]{2}$');
|
|
@ -0,0 +1,18 @@
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub db_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static CONFIG: Lazy<Config> =
|
||||||
|
Lazy::new(|| confy::load("starchart", Some("config")).expect("failed to load config"));
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
db_url: "postgres://starchart:hunter2@localhost/starchart".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
use sqlx::{postgres::PgPoolOptions, PgPool};
|
||||||
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
|
static DB_CONN: OnceCell<PgPool> = OnceCell::const_new();
|
||||||
|
|
||||||
|
pub async fn pool() -> &'static sqlx::postgres::PgPool {
|
||||||
|
DB_CONN
|
||||||
|
.get_or_init(|| async {
|
||||||
|
PgPoolOptions::new()
|
||||||
|
.min_connections(1)
|
||||||
|
.max_connections(5)
|
||||||
|
.connect(&crate::config::CONFIG.db_url)
|
||||||
|
.await
|
||||||
|
.expect("failed to connect to database")
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use aide::{
|
||||||
|
axum::{routing::get, ApiRouter, IntoApiResponse},
|
||||||
|
openapi::OpenApi,
|
||||||
|
redoc::Redoc,
|
||||||
|
};
|
||||||
|
use axum::{response::IntoResponse, Extension};
|
||||||
|
|
||||||
|
use crate::extractors::Json;
|
||||||
|
|
||||||
|
pub fn routes() -> ApiRouter {
|
||||||
|
ApiRouter::new()
|
||||||
|
.route("/openapi.json", get(openapi_json))
|
||||||
|
.route(
|
||||||
|
"/",
|
||||||
|
get(Redoc::new("/docs/openapi.json")
|
||||||
|
.with_title("starchart docs")
|
||||||
|
.axum_handler()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn openapi_json(Extension(api): Extension<Arc<OpenApi>>) -> impl IntoApiResponse {
|
||||||
|
Json(api).into_response()
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
use aide::operation::OperationIo;
|
||||||
|
use axum_macros::FromRequest;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(OperationIo, FromRequest)]
|
||||||
|
#[from_request(via(axum_jsonschema::Json))]
|
||||||
|
#[aide(
|
||||||
|
input_with = "axum_jsonschema::Json<T>",
|
||||||
|
output_with = "axum_jsonschema::Json<T>",
|
||||||
|
json_schema
|
||||||
|
)]
|
||||||
|
pub struct Json<T>(pub T);
|
||||||
|
|
||||||
|
impl<T> axum::response::IntoResponse for Json<T>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
axum::Json(self.0).into_response()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
use aide::axum::ApiRouter;
|
||||||
|
use axum::{
|
||||||
|
body::{boxed, Full},
|
||||||
|
response::{Html, IntoResponse, Response},
|
||||||
|
routing::get,
|
||||||
|
};
|
||||||
|
use hyper::{header, StatusCode, Uri};
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
|
|
||||||
|
pub fn routes() -> ApiRouter {
|
||||||
|
ApiRouter::new()
|
||||||
|
.route("/*file", get(static_handler))
|
||||||
|
.route("/", get(index))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index() -> Html<&'static str> {
|
||||||
|
Html(include_str!("../web/dist/index.html"))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn static_handler(uri: Uri) -> impl IntoResponse {
|
||||||
|
let path = uri.path().trim_start_matches('/');
|
||||||
|
|
||||||
|
if path.starts_with("/api/") {
|
||||||
|
return StatusCode::NOT_FOUND.into_response();
|
||||||
|
}
|
||||||
|
|
||||||
|
match Assets::get(path) {
|
||||||
|
Some(v) => {
|
||||||
|
tracing::debug!("found file: {}", path);
|
||||||
|
let body = boxed(Full::from(v.data));
|
||||||
|
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
||||||
|
|
||||||
|
Response::builder()
|
||||||
|
.header(header::CONTENT_TYPE, mime.as_ref())
|
||||||
|
.body(body)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
// return index.html, vue router will handle the rest
|
||||||
|
None => index().await.into_response(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RustEmbed)]
|
||||||
|
#[folder = "web/dist/"]
|
||||||
|
struct Assets;
|
|
@ -0,0 +1,56 @@
|
||||||
|
use aide::{axum::ApiRouter, openapi::OpenApi};
|
||||||
|
use axum::Extension;
|
||||||
|
use std::{
|
||||||
|
net::{Ipv4Addr, SocketAddr},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
use tracing::info;
|
||||||
|
use tracing_subscriber::fmt::SubscriberBuilder;
|
||||||
|
|
||||||
|
pub mod config;
|
||||||
|
pub mod db;
|
||||||
|
pub mod docs;
|
||||||
|
pub mod extractors;
|
||||||
|
mod frontend;
|
||||||
|
pub mod stars;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
SubscriberBuilder::default().pretty().init();
|
||||||
|
info!("running migrations! please wait...");
|
||||||
|
sqlx::migrate!("./migrations").run(db::pool().await).await?;
|
||||||
|
info!("migrations done! 😎");
|
||||||
|
start_server().await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn generate_server() -> Result<axum::Router, Box<dyn std::error::Error>> {
|
||||||
|
aide::gen::on_error(|error| panic!("{}", error));
|
||||||
|
aide::gen::extract_schemas(true);
|
||||||
|
let mut open_api = OpenApi::default();
|
||||||
|
aide::gen::on_error(|error| panic!("{}", error));
|
||||||
|
Ok(ApiRouter::new()
|
||||||
|
.nest_api_service("/api/v1/stars", stars::routes())
|
||||||
|
.nest_api_service("/docs", docs::routes())
|
||||||
|
.nest_api_service("/", frontend::routes())
|
||||||
|
.finish_api_with(&mut open_api, |docs| {
|
||||||
|
docs.title("starchart")
|
||||||
|
.summary("now you can discover a star!")
|
||||||
|
.contact(aide::openapi::Contact {
|
||||||
|
name: Some("zoe".into()),
|
||||||
|
url: Some("https://zoe.kittycat.homes".into()),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.version("0.1.0")
|
||||||
|
})
|
||||||
|
.layer(Extension(Arc::new(open_api))))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start_server() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let app = generate_server().await?;
|
||||||
|
let addr = SocketAddr::new(std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7056);
|
||||||
|
axum::Server::bind(&addr)
|
||||||
|
.serve(app.into_make_service())
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
use aide::axum::{
|
||||||
|
routing::{get_with, post_with},
|
||||||
|
ApiRouter,
|
||||||
|
};
|
||||||
|
use axum::{
|
||||||
|
extract::{Path, Query},
|
||||||
|
http::StatusCode,
|
||||||
|
Json,
|
||||||
|
};
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sqlx::FromRow;
|
||||||
|
|
||||||
|
mod size;
|
||||||
|
|
||||||
|
pub fn routes() -> ApiRouter {
|
||||||
|
ApiRouter::new()
|
||||||
|
.api_route(
|
||||||
|
"/discover",
|
||||||
|
post_with(discover, |docs| {
|
||||||
|
docs.response::<200, Json<Star>>()
|
||||||
|
.summary("add a new planet")
|
||||||
|
.id("discover")
|
||||||
|
.tag("stars")
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.api_route(
|
||||||
|
"/chart",
|
||||||
|
get_with(chart, |docs| {
|
||||||
|
docs.response::<200, Json<Vec<Protostar>>>()
|
||||||
|
.summary("the whole chart")
|
||||||
|
.id("chart")
|
||||||
|
.tag("stars")
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.api_route_with(
|
||||||
|
"/visit/",
|
||||||
|
get_with(visit, |docs| {
|
||||||
|
docs.response::<200, Json<Star>>()
|
||||||
|
.summary("visit a single planet")
|
||||||
|
.id("visit")
|
||||||
|
.tag("stars")
|
||||||
|
}),
|
||||||
|
|docs| docs,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// this gets stored in the db,
|
||||||
|
/// the other stuff is generated using
|
||||||
|
/// the id as a seed
|
||||||
|
#[derive(Serialize, FromRow, Clone, Deserialize, JsonSchema)]
|
||||||
|
pub struct Protostar {
|
||||||
|
pub id: i32,
|
||||||
|
/// hex code of the stars color
|
||||||
|
pub color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Protostar {
|
||||||
|
fn seed(&self) -> u64 {
|
||||||
|
self.id.abs() as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, JsonSchema)]
|
||||||
|
pub struct Star {
|
||||||
|
pub size: size::Size,
|
||||||
|
pub core: Protostar,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, JsonSchema)]
|
||||||
|
pub struct DiscoveryLog {
|
||||||
|
pub color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Star> for Protostar {
|
||||||
|
fn into(self) -> Star {
|
||||||
|
let seed = self.seed();
|
||||||
|
Star {
|
||||||
|
core: self,
|
||||||
|
size: size::Size::random(seed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// discover a new star in the solar system
|
||||||
|
async fn discover(Json(log): Json<DiscoveryLog>) -> Result<Json<Star>, StatusCode> {
|
||||||
|
let query = "INSERT INTO stars (color) VALUES ($1) RETURNING id, color";
|
||||||
|
|
||||||
|
let protostar: Protostar = sqlx::query_as(query)
|
||||||
|
.bind(log.color)
|
||||||
|
.fetch_one(crate::db::pool().await)
|
||||||
|
.await
|
||||||
|
.or(Err(StatusCode::INTERNAL_SERVER_ERROR))?;
|
||||||
|
let star: Star = protostar.into();
|
||||||
|
Ok(Json(star))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// show all stars
|
||||||
|
async fn chart() -> Json<Vec<Protostar>> {
|
||||||
|
let query = "SELECT * FROM stars ORDER BY id DESC";
|
||||||
|
let protostars: Vec<Protostar> = sqlx::query_as(query)
|
||||||
|
.fetch_all(crate::db::pool().await)
|
||||||
|
.await
|
||||||
|
.unwrap_or_default();
|
||||||
|
Json(protostars)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, JsonSchema)]
|
||||||
|
struct VisitorData {
|
||||||
|
/// the planet to visit
|
||||||
|
planet_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn visit(data: Query<VisitorData>) -> Result<Json<Star>, StatusCode> {
|
||||||
|
let query = "SELECT * FROM stars WHERE id = ($1)";
|
||||||
|
let star: Protostar = sqlx::query_as(query)
|
||||||
|
.bind(data.planet_id)
|
||||||
|
.fetch_one(crate::db::pool().await)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
//.or(Err(StatusCode::NOT_FOUND))?;
|
||||||
|
let star: Star = star.into();
|
||||||
|
Ok(Json(star))
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
use tinyrand::{RandRange, Seeded, StdRand};
|
||||||
|
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(JsonSchema, Serialize, Deserialize)]
|
||||||
|
pub struct Size {
|
||||||
|
pub small_item_multiplier: u8,
|
||||||
|
pub large_item_multiplier: u8,
|
||||||
|
pub small_item: String,
|
||||||
|
pub large_item: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Size {
|
||||||
|
pub fn random(seed: u64) -> Self {
|
||||||
|
let mut rand = StdRand::seed(seed);
|
||||||
|
|
||||||
|
// multipliers:
|
||||||
|
// this planet is as large as 10 x item
|
||||||
|
let small_item_multiplier: usize = rand.next_range(1..100);
|
||||||
|
let large_item_multiplier: usize = rand.next_range(1..100);
|
||||||
|
Self {
|
||||||
|
small_item_multiplier: small_item_multiplier as u8,
|
||||||
|
large_item_multiplier: large_item_multiplier as u8,
|
||||||
|
small_item: "rats".into(),
|
||||||
|
large_item: "ohios".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
> 1%
|
||||||
|
last 2 versions
|
||||||
|
not dead
|
||||||
|
not ie 11
|
|
@ -0,0 +1,19 @@
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
"plugin:vue/vue3-essential",
|
||||||
|
"eslint:recommended",
|
||||||
|
"@vue/typescript/recommended",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||||
|
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
|
@ -0,0 +1,24 @@
|
||||||
|
# starchart
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
npm run serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: ["@vue/cli-plugin-babel/preset"],
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "starchart",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint",
|
||||||
|
"swagger-gen": "rm -rf ./src/swagger && openapi-generator-cli generate -g typescript-fetch -i http://localhost:7056/docs/openapi.json -o src/swagger/"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"vue": "^3.2.13",
|
||||||
|
"vue-router": "^4.0.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-router": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-typescript": "~5.0.0",
|
||||||
|
"@vue/cli-service": "~5.0.0",
|
||||||
|
"@vue/eslint-config-typescript": "^9.1.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-config-prettier": "^8.3.0",
|
||||||
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"eslint-plugin-vue": "^8.0.3",
|
||||||
|
"pinia": "^2.1.6",
|
||||||
|
"prettier": "^2.4.1",
|
||||||
|
"sass": "^1.32.7",
|
||||||
|
"sass-loader": "^12.0.0",
|
||||||
|
"typescript": "~4.5.5",
|
||||||
|
"vue-router": "^4.2.4"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<nav>
|
||||||
|
<router-link to="/">Home</router-link> |
|
||||||
|
<router-link to="/about">About</router-link>
|
||||||
|
</nav>
|
||||||
|
<router-view />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
padding: 30px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c3e50;
|
||||||
|
|
||||||
|
&.router-link-exact-active {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { Configuration } from "@/swagger";
|
||||||
|
|
||||||
|
// is this production or dev?
|
||||||
|
function is_dev(): boolean {
|
||||||
|
return process.env.NODE_ENV === "development";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function conf(): Configuration {
|
||||||
|
return new Configuration({
|
||||||
|
// what url to send requests to
|
||||||
|
basePath: is_dev() ? "http://127.0.0.1:7056" : window.location.origin,
|
||||||
|
});
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
|
@ -0,0 +1,124 @@
|
||||||
|
<template>
|
||||||
|
<div class="hello">
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
<p>
|
||||||
|
For a guide and recipes on how to configure / customize this project,<br />
|
||||||
|
check out the
|
||||||
|
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>vue-cli documentation</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
<h3>Installed CLI Plugins</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>babel</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>typescript</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>eslint</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Essential Links</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>Forum</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>Community Chat</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
|
||||||
|
>Twitter</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Ecosystem</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://router.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>vue-router</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/vue-devtools#vue-devtools"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>vue-devtools</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>vue-loader</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/awesome-vue"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>awesome-vue</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "HelloWorld",
|
||||||
|
props: {
|
||||||
|
msg: String,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped lang="scss">
|
||||||
|
h3 {
|
||||||
|
margin: 40px 0 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { createApp } from "vue";
|
||||||
|
import { createPinia } from "pinia";
|
||||||
|
import "vue-router";
|
||||||
|
import App from "./App.vue";
|
||||||
|
import router from "./router";
|
||||||
|
|
||||||
|
const pinia = createPinia();
|
||||||
|
const app = createApp(App).use(router);
|
||||||
|
|
||||||
|
app.use(pinia);
|
||||||
|
app.mount("#app");
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
|
||||||
|
import HomeView from "../views/HomeView.vue";
|
||||||
|
|
||||||
|
const routes: Array<RouteRecordRaw> = [
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
name: "home",
|
||||||
|
component: HomeView,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/about",
|
||||||
|
name: "about",
|
||||||
|
// route level code-splitting
|
||||||
|
// this generates a separate chunk (about.[hash].js) for this route
|
||||||
|
// which is lazy-loaded when the route is visited.
|
||||||
|
component: () =>
|
||||||
|
import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(process.env.BASE_URL),
|
||||||
|
routes,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
|
@ -0,0 +1,6 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
declare module '*.vue' {
|
||||||
|
import type { DefineComponent } from 'vue'
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { conf } from "@/api";
|
||||||
|
import { Protostar, StarsApi } from "@/swagger";
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
type ChartInfoState = {
|
||||||
|
loading: boolean;
|
||||||
|
protostars: Protostar[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useChartStore = defineStore({
|
||||||
|
id: "chart",
|
||||||
|
state: () =>
|
||||||
|
({
|
||||||
|
loading: true,
|
||||||
|
protostars: [],
|
||||||
|
} as ChartInfoState),
|
||||||
|
actions: {
|
||||||
|
async fetchChart() {
|
||||||
|
this.loading = true;
|
||||||
|
this.protostars = await new StarsApi(conf())
|
||||||
|
.chart()
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
return this.protostars;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useVisitStore = defineStore({
|
||||||
|
id: "chart",
|
||||||
|
state: () =>
|
||||||
|
({
|
||||||
|
loading: true,
|
||||||
|
protostars: [],
|
||||||
|
} as ChartInfoState),
|
||||||
|
actions: {
|
||||||
|
async fetchChart() {
|
||||||
|
this.loading = true;
|
||||||
|
this.protostars = await new StarsApi(conf())
|
||||||
|
.chart()
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
return this.protostars;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,23 @@
|
||||||
|
# OpenAPI Generator Ignore
|
||||||
|
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||||
|
|
||||||
|
# Use this file to prevent files from being overwritten by the generator.
|
||||||
|
# The patterns follow closely to .gitignore or .dockerignore.
|
||||||
|
|
||||||
|
# As an example, the C# client generator defines ApiClient.cs.
|
||||||
|
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||||
|
#ApiClient.cs
|
||||||
|
|
||||||
|
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||||
|
#foo/*/qux
|
||||||
|
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||||
|
#foo/**/qux
|
||||||
|
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can also negate patterns with an exclamation (!).
|
||||||
|
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||||
|
#docs/*.md
|
||||||
|
# Then explicitly reverse the ignore rule for a single file:
|
||||||
|
#!docs/README.md
|
|
@ -0,0 +1,11 @@
|
||||||
|
.openapi-generator-ignore
|
||||||
|
apis/StarsApi.ts
|
||||||
|
apis/index.ts
|
||||||
|
index.ts
|
||||||
|
models/DiscoveryLog.ts
|
||||||
|
models/Protostar.ts
|
||||||
|
models/Size.ts
|
||||||
|
models/Star.ts
|
||||||
|
models/VisitorData.ts
|
||||||
|
models/index.ts
|
||||||
|
runtime.ts
|
|
@ -0,0 +1 @@
|
||||||
|
6.6.0
|
|
@ -0,0 +1,138 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* starchart
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 0.1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import * as runtime from '../runtime';
|
||||||
|
import type {
|
||||||
|
DiscoveryLog,
|
||||||
|
Star,
|
||||||
|
} from '../models';
|
||||||
|
import {
|
||||||
|
DiscoveryLogFromJSON,
|
||||||
|
DiscoveryLogToJSON,
|
||||||
|
StarFromJSON,
|
||||||
|
StarToJSON,
|
||||||
|
} from '../models';
|
||||||
|
|
||||||
|
export interface DiscoverRequest {
|
||||||
|
discoveryLog: DiscoveryLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VisitRequest {
|
||||||
|
planetId: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export class StarsApi extends runtime.BaseAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the whole chart
|
||||||
|
*/
|
||||||
|
async chartRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<any>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/api/v1/stars/chart`,
|
||||||
|
method: 'GET',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
if (this.isJsonMime(response.headers.get('content-type'))) {
|
||||||
|
return new runtime.JSONApiResponse<any>(response);
|
||||||
|
} else {
|
||||||
|
return new runtime.TextApiResponse(response) as any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the whole chart
|
||||||
|
*/
|
||||||
|
async chart(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<any> {
|
||||||
|
const response = await this.chartRaw(initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a new planet
|
||||||
|
*/
|
||||||
|
async discoverRaw(requestParameters: DiscoverRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Star>> {
|
||||||
|
if (requestParameters.discoveryLog === null || requestParameters.discoveryLog === undefined) {
|
||||||
|
throw new runtime.RequiredError('discoveryLog','Required parameter requestParameters.discoveryLog was null or undefined when calling discover.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
headerParameters['Content-Type'] = 'application/json';
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/api/v1/stars/discover`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
body: DiscoveryLogToJSON(requestParameters.discoveryLog),
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse(response, (jsonValue) => StarFromJSON(jsonValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a new planet
|
||||||
|
*/
|
||||||
|
async discover(requestParameters: DiscoverRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Star> {
|
||||||
|
const response = await this.discoverRaw(requestParameters, initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* visit a single planet
|
||||||
|
*/
|
||||||
|
async visitRaw(requestParameters: VisitRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Star>> {
|
||||||
|
if (requestParameters.planetId === null || requestParameters.planetId === undefined) {
|
||||||
|
throw new runtime.RequiredError('planetId','Required parameter requestParameters.planetId was null or undefined when calling visit.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
if (requestParameters.planetId !== undefined) {
|
||||||
|
queryParameters['planet_id'] = requestParameters.planetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/api/v1/stars/visit/`,
|
||||||
|
method: 'GET',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse(response, (jsonValue) => StarFromJSON(jsonValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* visit a single planet
|
||||||
|
*/
|
||||||
|
async visit(requestParameters: VisitRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Star> {
|
||||||
|
const response = await this.visitRaw(requestParameters, initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export * from './StarsApi';
|
|
@ -0,0 +1,5 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export * from './runtime';
|
||||||
|
export * from './apis';
|
||||||
|
export * from './models';
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* starchart
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 0.1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { exists, mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface DiscoveryLog
|
||||||
|
*/
|
||||||
|
export interface DiscoveryLog {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {any}
|
||||||
|
* @memberof DiscoveryLog
|
||||||
|
*/
|
||||||
|
color: any | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the DiscoveryLog interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfDiscoveryLog(value: object): boolean {
|
||||||
|
let isInstance = true;
|
||||||
|
isInstance = isInstance && "color" in value;
|
||||||
|
|
||||||
|
return isInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DiscoveryLogFromJSON(json: any): DiscoveryLog {
|
||||||
|
return DiscoveryLogFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DiscoveryLogFromJSONTyped(json: any, ignoreDiscriminator: boolean): DiscoveryLog {
|
||||||
|
if ((json === undefined) || (json === null)) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'color': json['color'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DiscoveryLogToJSON(value?: DiscoveryLog | null): any {
|
||||||
|
if (value === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'color': value.color,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* starchart
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 0.1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { exists, mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
* this gets stored in the db, the other stuff is generated using the id as a seed
|
||||||
|
* @export
|
||||||
|
* @interface Protostar
|
||||||
|
*/
|
||||||
|
export interface Protostar {
|
||||||
|
/**
|
||||||
|
* hex code of the stars color
|
||||||
|
* @type {any}
|
||||||
|
* @memberof Protostar
|
||||||
|
*/
|
||||||
|
color: any | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {any}
|
||||||
|
* @memberof Protostar
|
||||||
|
*/
|
||||||
|
id: any | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the Protostar interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfProtostar(value: object): boolean {
|
||||||
|
let isInstance = true;
|
||||||
|
isInstance = isInstance && "color" in value;
|
||||||
|
isInstance = isInstance && "id" in value;
|
||||||
|
|
||||||
|
return isInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProtostarFromJSON(json: any): Protostar {
|
||||||
|
return ProtostarFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProtostarFromJSONTyped(json: any, ignoreDiscriminator: boolean): Protostar {
|
||||||
|
if ((json === undefined) || (json === null)) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'color': json['color'],
|
||||||
|
'id': json['id'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProtostarToJSON(value?: Protostar | null): any {
|
||||||
|
if (value === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'color': value.color,
|
||||||
|
'id': value.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* starchart
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 0.1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { exists, mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface Size
|
||||||
|
*/
|
||||||
|
export interface Size {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {any}
|
||||||
|
* @memberof Size
|
||||||
|
*/
|
||||||
|
largeItem: any | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {any}
|
||||||
|
* @memberof Size
|
||||||
|
*/
|
||||||
|
largeItemMultiplier: any | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {any}
|
||||||
|
* @memberof Size
|
||||||
|
*/
|
||||||
|
smallItem: any | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {any}
|
||||||
|
* @memberof Size
|
||||||
|
*/
|
||||||
|
smallItemMultiplier: any | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the Size interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfSize(value: object): boolean {
|
||||||
|
let isInstance = true;
|
||||||
|
isInstance = isInstance && "largeItem" in value;
|
||||||
|
isInstance = isInstance && "largeItemMultiplier" in value;
|
||||||
|
isInstance = isInstance && "smallItem" in value;
|
||||||
|
isInstance = isInstance && "smallItemMultiplier" in value;
|
||||||
|
|
||||||
|
return isInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SizeFromJSON(json: any): Size {
|
||||||
|
return SizeFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SizeFromJSONTyped(json: any, ignoreDiscriminator: boolean): Size {
|
||||||
|
if ((json === undefined) || (json === null)) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'largeItem': json['large_item'],
|
||||||
|
'largeItemMultiplier': json['large_item_multiplier'],
|
||||||
|
'smallItem': json['small_item'],
|
||||||
|
'smallItemMultiplier': json['small_item_multiplier'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SizeToJSON(value?: Size | null): any {
|
||||||
|
if (value === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'large_item': value.largeItem,
|
||||||
|
'large_item_multiplier': value.largeItemMultiplier,
|
||||||
|
'small_item': value.smallItem,
|
||||||
|
'small_item_multiplier': value.smallItemMultiplier,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* starchart
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 0.1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { exists, mapValues } from '../runtime';
|
||||||
|
import type { Protostar } from './Protostar';
|
||||||
|
import {
|
||||||
|
ProtostarFromJSON,
|
||||||
|
ProtostarFromJSONTyped,
|
||||||
|
ProtostarToJSON,
|
||||||
|
} from './Protostar';
|
||||||
|
import type { Size } from './Size';
|
||||||
|
import {
|
||||||
|
SizeFromJSON,
|
||||||
|
SizeFromJSONTyped,
|
||||||
|
SizeToJSON,
|
||||||
|
} from './Size';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface Star
|
||||||
|
*/
|
||||||
|
export interface Star {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Protostar}
|
||||||
|
* @memberof Star
|
||||||
|
*/
|
||||||
|
core: Protostar;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Size}
|
||||||
|
* @memberof Star
|
||||||
|
*/
|
||||||
|
size: Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the Star interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfStar(value: object): boolean {
|
||||||
|
let isInstance = true;
|
||||||
|
isInstance = isInstance && "core" in value;
|
||||||
|
isInstance = isInstance && "size" in value;
|
||||||
|
|
||||||
|
return isInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StarFromJSON(json: any): Star {
|
||||||
|
return StarFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StarFromJSONTyped(json: any, ignoreDiscriminator: boolean): Star {
|
||||||
|
if ((json === undefined) || (json === null)) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'core': ProtostarFromJSON(json['core']),
|
||||||
|
'size': SizeFromJSON(json['size']),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StarToJSON(value?: Star | null): any {
|
||||||
|
if (value === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'core': ProtostarToJSON(value.core),
|
||||||
|
'size': SizeToJSON(value.size),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* starchart
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 0.1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { exists, mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface VisitorData
|
||||||
|
*/
|
||||||
|
export interface VisitorData {
|
||||||
|
/**
|
||||||
|
* the planet to visit
|
||||||
|
* @type {any}
|
||||||
|
* @memberof VisitorData
|
||||||
|
*/
|
||||||
|
planetId: any | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the VisitorData interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfVisitorData(value: object): boolean {
|
||||||
|
let isInstance = true;
|
||||||
|
isInstance = isInstance && "planetId" in value;
|
||||||
|
|
||||||
|
return isInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VisitorDataFromJSON(json: any): VisitorData {
|
||||||
|
return VisitorDataFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VisitorDataFromJSONTyped(json: any, ignoreDiscriminator: boolean): VisitorData {
|
||||||
|
if ((json === undefined) || (json === null)) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'planetId': json['planet_id'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VisitorDataToJSON(value?: VisitorData | null): any {
|
||||||
|
if (value === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'planet_id': value.planetId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export * from './DiscoveryLog';
|
||||||
|
export * from './Protostar';
|
||||||
|
export * from './Size';
|
||||||
|
export * from './Star';
|
||||||
|
export * from './VisitorData';
|
|
@ -0,0 +1,425 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* starchart
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 0.1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const BASE_PATH = "http://localhost".replace(/\/+$/, "");
|
||||||
|
|
||||||
|
export interface ConfigurationParameters {
|
||||||
|
basePath?: string; // override base path
|
||||||
|
fetchApi?: FetchAPI; // override for fetch implementation
|
||||||
|
middleware?: Middleware[]; // middleware to apply before/after fetch requests
|
||||||
|
queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings
|
||||||
|
username?: string; // parameter for basic security
|
||||||
|
password?: string; // parameter for basic security
|
||||||
|
apiKey?: string | ((name: string) => string); // parameter for apiKey security
|
||||||
|
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string | Promise<string>); // parameter for oauth2 security
|
||||||
|
headers?: HTTPHeaders; //header params we want to use on every request
|
||||||
|
credentials?: RequestCredentials; //value for the credentials param we want to use on each request
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Configuration {
|
||||||
|
constructor(private configuration: ConfigurationParameters = {}) {}
|
||||||
|
|
||||||
|
set config(configuration: Configuration) {
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
get basePath(): string {
|
||||||
|
return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fetchApi(): FetchAPI | undefined {
|
||||||
|
return this.configuration.fetchApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
get middleware(): Middleware[] {
|
||||||
|
return this.configuration.middleware || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get queryParamsStringify(): (params: HTTPQuery) => string {
|
||||||
|
return this.configuration.queryParamsStringify || querystring;
|
||||||
|
}
|
||||||
|
|
||||||
|
get username(): string | undefined {
|
||||||
|
return this.configuration.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
get password(): string | undefined {
|
||||||
|
return this.configuration.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
get apiKey(): ((name: string) => string) | undefined {
|
||||||
|
const apiKey = this.configuration.apiKey;
|
||||||
|
if (apiKey) {
|
||||||
|
return typeof apiKey === 'function' ? apiKey : () => apiKey;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
get accessToken(): ((name?: string, scopes?: string[]) => string | Promise<string>) | undefined {
|
||||||
|
const accessToken = this.configuration.accessToken;
|
||||||
|
if (accessToken) {
|
||||||
|
return typeof accessToken === 'function' ? accessToken : async () => accessToken;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
get headers(): HTTPHeaders | undefined {
|
||||||
|
return this.configuration.headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
get credentials(): RequestCredentials | undefined {
|
||||||
|
return this.configuration.credentials;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DefaultConfig = new Configuration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the base class for all generated API classes.
|
||||||
|
*/
|
||||||
|
export class BaseAPI {
|
||||||
|
|
||||||
|
private static readonly jsonRegex = new RegExp('^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$', 'i');
|
||||||
|
private middleware: Middleware[];
|
||||||
|
|
||||||
|
constructor(protected configuration = DefaultConfig) {
|
||||||
|
this.middleware = configuration.middleware;
|
||||||
|
}
|
||||||
|
|
||||||
|
withMiddleware<T extends BaseAPI>(this: T, ...middlewares: Middleware[]) {
|
||||||
|
const next = this.clone<T>();
|
||||||
|
next.middleware = next.middleware.concat(...middlewares);
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
withPreMiddleware<T extends BaseAPI>(this: T, ...preMiddlewares: Array<Middleware['pre']>) {
|
||||||
|
const middlewares = preMiddlewares.map((pre) => ({ pre }));
|
||||||
|
return this.withMiddleware<T>(...middlewares);
|
||||||
|
}
|
||||||
|
|
||||||
|
withPostMiddleware<T extends BaseAPI>(this: T, ...postMiddlewares: Array<Middleware['post']>) {
|
||||||
|
const middlewares = postMiddlewares.map((post) => ({ post }));
|
||||||
|
return this.withMiddleware<T>(...middlewares);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given MIME is a JSON MIME.
|
||||||
|
* JSON MIME examples:
|
||||||
|
* application/json
|
||||||
|
* application/json; charset=UTF8
|
||||||
|
* APPLICATION/JSON
|
||||||
|
* application/vnd.company+json
|
||||||
|
* @param mime - MIME (Multipurpose Internet Mail Extensions)
|
||||||
|
* @return True if the given MIME is JSON, false otherwise.
|
||||||
|
*/
|
||||||
|
protected isJsonMime(mime: string | null | undefined): boolean {
|
||||||
|
if (!mime) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return BaseAPI.jsonRegex.test(mime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise<Response> {
|
||||||
|
const { url, init } = await this.createFetchParams(context, initOverrides);
|
||||||
|
const response = await this.fetchApi(url, init);
|
||||||
|
if (response && (response.status >= 200 && response.status < 300)) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
throw new ResponseError(response, 'Response returned an error code');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) {
|
||||||
|
let url = this.configuration.basePath + context.path;
|
||||||
|
if (context.query !== undefined && Object.keys(context.query).length !== 0) {
|
||||||
|
// only add the querystring to the URL if there are query parameters.
|
||||||
|
// this is done to avoid urls ending with a "?" character which buggy webservers
|
||||||
|
// do not handle correctly sometimes.
|
||||||
|
url += '?' + this.configuration.queryParamsStringify(context.query);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = Object.assign({}, this.configuration.headers, context.headers);
|
||||||
|
Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {});
|
||||||
|
|
||||||
|
const initOverrideFn =
|
||||||
|
typeof initOverrides === "function"
|
||||||
|
? initOverrides
|
||||||
|
: async () => initOverrides;
|
||||||
|
|
||||||
|
const initParams = {
|
||||||
|
method: context.method,
|
||||||
|
headers,
|
||||||
|
body: context.body,
|
||||||
|
credentials: this.configuration.credentials,
|
||||||
|
};
|
||||||
|
|
||||||
|
const overriddenInit: RequestInit = {
|
||||||
|
...initParams,
|
||||||
|
...(await initOverrideFn({
|
||||||
|
init: initParams,
|
||||||
|
context,
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
|
||||||
|
const init: RequestInit = {
|
||||||
|
...overriddenInit,
|
||||||
|
body:
|
||||||
|
isFormData(overriddenInit.body) ||
|
||||||
|
overriddenInit.body instanceof URLSearchParams ||
|
||||||
|
isBlob(overriddenInit.body)
|
||||||
|
? overriddenInit.body
|
||||||
|
: JSON.stringify(overriddenInit.body),
|
||||||
|
};
|
||||||
|
|
||||||
|
return { url, init };
|
||||||
|
}
|
||||||
|
|
||||||
|
private fetchApi = async (url: string, init: RequestInit) => {
|
||||||
|
let fetchParams = { url, init };
|
||||||
|
for (const middleware of this.middleware) {
|
||||||
|
if (middleware.pre) {
|
||||||
|
fetchParams = await middleware.pre({
|
||||||
|
fetch: this.fetchApi,
|
||||||
|
...fetchParams,
|
||||||
|
}) || fetchParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let response: Response | undefined = undefined;
|
||||||
|
try {
|
||||||
|
response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init);
|
||||||
|
} catch (e) {
|
||||||
|
for (const middleware of this.middleware) {
|
||||||
|
if (middleware.onError) {
|
||||||
|
response = await middleware.onError({
|
||||||
|
fetch: this.fetchApi,
|
||||||
|
url: fetchParams.url,
|
||||||
|
init: fetchParams.init,
|
||||||
|
error: e,
|
||||||
|
response: response ? response.clone() : undefined,
|
||||||
|
}) || response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (response === undefined) {
|
||||||
|
if (e instanceof Error) {
|
||||||
|
throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response');
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const middleware of this.middleware) {
|
||||||
|
if (middleware.post) {
|
||||||
|
response = await middleware.post({
|
||||||
|
fetch: this.fetchApi,
|
||||||
|
url: fetchParams.url,
|
||||||
|
init: fetchParams.init,
|
||||||
|
response: response.clone(),
|
||||||
|
}) || response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a shallow clone of `this` by constructing a new instance
|
||||||
|
* and then shallow cloning data members.
|
||||||
|
*/
|
||||||
|
private clone<T extends BaseAPI>(this: T): T {
|
||||||
|
const constructor = this.constructor as any;
|
||||||
|
const next = new constructor(this.configuration);
|
||||||
|
next.middleware = this.middleware.slice();
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function isBlob(value: any): value is Blob {
|
||||||
|
return typeof Blob !== 'undefined' && value instanceof Blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFormData(value: any): value is FormData {
|
||||||
|
return typeof FormData !== "undefined" && value instanceof FormData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ResponseError extends Error {
|
||||||
|
override name: "ResponseError" = "ResponseError";
|
||||||
|
constructor(public response: Response, msg?: string) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FetchError extends Error {
|
||||||
|
override name: "FetchError" = "FetchError";
|
||||||
|
constructor(public cause: Error, msg?: string) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RequiredError extends Error {
|
||||||
|
override name: "RequiredError" = "RequiredError";
|
||||||
|
constructor(public field: string, msg?: string) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const COLLECTION_FORMATS = {
|
||||||
|
csv: ",",
|
||||||
|
ssv: " ",
|
||||||
|
tsv: "\t",
|
||||||
|
pipes: "|",
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FetchAPI = WindowOrWorkerGlobalScope['fetch'];
|
||||||
|
|
||||||
|
export type Json = any;
|
||||||
|
export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
|
||||||
|
export type HTTPHeaders = { [key: string]: string };
|
||||||
|
export type HTTPQuery = { [key: string]: string | number | null | boolean | Array<string | number | null | boolean> | Set<string | number | null | boolean> | HTTPQuery };
|
||||||
|
export type HTTPBody = Json | FormData | URLSearchParams;
|
||||||
|
export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody };
|
||||||
|
export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
|
||||||
|
|
||||||
|
export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise<RequestInit>
|
||||||
|
|
||||||
|
export interface FetchParams {
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RequestOpts {
|
||||||
|
path: string;
|
||||||
|
method: HTTPMethod;
|
||||||
|
headers: HTTPHeaders;
|
||||||
|
query?: HTTPQuery;
|
||||||
|
body?: HTTPBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function exists(json: any, key: string) {
|
||||||
|
const value = json[key];
|
||||||
|
return value !== null && value !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function querystring(params: HTTPQuery, prefix: string = ''): string {
|
||||||
|
return Object.keys(params)
|
||||||
|
.map(key => querystringSingleKey(key, params[key], prefix))
|
||||||
|
.filter(part => part.length > 0)
|
||||||
|
.join('&');
|
||||||
|
}
|
||||||
|
|
||||||
|
function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array<string | number | null | boolean> | Set<string | number | null | boolean> | HTTPQuery, keyPrefix: string = ''): string {
|
||||||
|
const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key);
|
||||||
|
if (value instanceof Array) {
|
||||||
|
const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue)))
|
||||||
|
.join(`&${encodeURIComponent(fullKey)}=`);
|
||||||
|
return `${encodeURIComponent(fullKey)}=${multiValue}`;
|
||||||
|
}
|
||||||
|
if (value instanceof Set) {
|
||||||
|
const valueAsArray = Array.from(value);
|
||||||
|
return querystringSingleKey(key, valueAsArray, keyPrefix);
|
||||||
|
}
|
||||||
|
if (value instanceof Date) {
|
||||||
|
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`;
|
||||||
|
}
|
||||||
|
if (value instanceof Object) {
|
||||||
|
return querystring(value as HTTPQuery, fullKey);
|
||||||
|
}
|
||||||
|
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapValues(data: any, fn: (item: any) => any) {
|
||||||
|
return Object.keys(data).reduce(
|
||||||
|
(acc, key) => ({ ...acc, [key]: fn(data[key]) }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function canConsumeForm(consumes: Consume[]): boolean {
|
||||||
|
for (const consume of consumes) {
|
||||||
|
if ('multipart/form-data' === consume.contentType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Consume {
|
||||||
|
contentType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RequestContext {
|
||||||
|
fetch: FetchAPI;
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResponseContext {
|
||||||
|
fetch: FetchAPI;
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
response: Response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ErrorContext {
|
||||||
|
fetch: FetchAPI;
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
error: unknown;
|
||||||
|
response?: Response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Middleware {
|
||||||
|
pre?(context: RequestContext): Promise<FetchParams | void>;
|
||||||
|
post?(context: ResponseContext): Promise<Response | void>;
|
||||||
|
onError?(context: ErrorContext): Promise<Response | void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiResponse<T> {
|
||||||
|
raw: Response;
|
||||||
|
value(): Promise<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResponseTransformer<T> {
|
||||||
|
(json: any): T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class JSONApiResponse<T> {
|
||||||
|
constructor(public raw: Response, private transformer: ResponseTransformer<T> = (jsonValue: any) => jsonValue) {}
|
||||||
|
|
||||||
|
async value(): Promise<T> {
|
||||||
|
return this.transformer(await this.raw.json());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class VoidApiResponse {
|
||||||
|
constructor(public raw: Response) {}
|
||||||
|
|
||||||
|
async value(): Promise<void> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BlobApiResponse {
|
||||||
|
constructor(public raw: Response) {}
|
||||||
|
|
||||||
|
async value(): Promise<Blob> {
|
||||||
|
return await this.raw.blob();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TextApiResponse {
|
||||||
|
constructor(public raw: Response) {}
|
||||||
|
|
||||||
|
async value(): Promise<string> {
|
||||||
|
return await this.raw.text();
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<div class="about">
|
||||||
|
<h1>This is an about page</h1>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<template>
|
||||||
|
<div class="home">
|
||||||
|
<img alt="Vue logo" src="../assets/logo.png" />
|
||||||
|
<HelloWorld msg="Welcome to Your Vue.js App" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// @ is an alias to /src
|
||||||
|
import HelloWorld from "@/components/HelloWorld.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "HomeView",
|
||||||
|
components: {
|
||||||
|
HelloWorld,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"types": [
|
||||||
|
"webpack-env"
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx",
|
||||||
|
"src/**/*.vue",
|
||||||
|
"tests/**/*.ts",
|
||||||
|
"tests/**/*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
const { defineConfig } = require("@vue/cli-service");
|
||||||
|
module.exports = defineConfig({
|
||||||
|
transpileDependencies: true,
|
||||||
|
});
|
Loading…
Reference in New Issue