diff --git a/Cargo.lock b/Cargo.lock index 2bbdb3b2538..a7eb0e6f01f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1963,9 +1963,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -2675,6 +2675,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "normpath" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2771,6 +2780,17 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "opener" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" +dependencies = [ + "bstr 1.5.0", + "normpath", + "winapi", +] + [[package]] name = "openssl" version = "0.10.55" @@ -5597,6 +5617,7 @@ dependencies = [ "distance", "flate2", "hex", + "hyper", "indexmap", "indicatif", "is-terminal", @@ -5604,6 +5625,7 @@ dependencies = [ "log", "object 0.30.4", "once_cell", + "opener", "pathdiff", "predicates 3.0.3", "pretty_assertions", diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index 6d405d2c5d6..75dec5c74b0 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -28,21 +28,41 @@ required-features = ["headless"] [dependencies] # Repo-local dependencies. wasmer = { version = "=4.0.0", path = "../api", default-features = false } -wasmer-compiler = { version = "=4.0.0", path = "../compiler", features = ["compiler"], optional = true } +wasmer-compiler = { version = "=4.0.0", path = "../compiler", features = [ + "compiler", +], optional = true } wasmer-compiler-cranelift = { version = "=4.0.0", path = "../compiler-cranelift", optional = true } wasmer-compiler-singlepass = { version = "=4.0.0", path = "../compiler-singlepass", optional = true } wasmer-compiler-llvm = { version = "=4.0.0", path = "../compiler-llvm", optional = true } wasmer-emscripten = { version = "=4.0.0", path = "../emscripten" } wasmer-vm = { version = "=4.0.0", path = "../vm", optional = true } -wasmer-wasix = { version = "0.9.0", path = "../wasix", features = ["logging", "webc_runner", "webc_runner_rt_wcgi", "webc_runner_rt_wasi", "webc_runner_rt_emscripten", "host-fs"] } -wasmer-wasix-experimental-io-devices = { version = "0.9.0", path = "../wasi-experimental-io-devices", optional = true, features = ["link_external_libs"] } +wasmer-wasix = { version = "0.9.0", path = "../wasix", features = [ + "logging", + "webc_runner", + "webc_runner_rt_wcgi", + "webc_runner_rt_wasi", + "webc_runner_rt_emscripten", + "host-fs", +] } +wasmer-wasix-experimental-io-devices = { version = "0.9.0", path = "../wasi-experimental-io-devices", optional = true, features = [ + "link_external_libs", +] } wasmer-wast = { version = "=4.0.0", path = "../../tests/lib/wast", optional = true } -wasmer-cache = { version = "=4.0.0", path = "../cache", features = ["blake3-pure"] } -wasmer-types = { version = "=4.0.0", path = "../types", features = ["enable-serde"] } -wasmer-registry = { version = "5.2.0", path = "../registry", features = ["build-package", "clap"] } +wasmer-cache = { version = "=4.0.0", path = "../cache", features = [ + "blake3-pure", +] } +wasmer-types = { version = "=4.0.0", path = "../types", features = [ + "enable-serde", +] } +wasmer-registry = { version = "5.2.0", path = "../registry", features = [ + "build-package", + "clap", +] } wasmer-object = { version = "=4.0.0", path = "../object", optional = true } -virtual-fs = { version = "0.6.0", path = "../virtual-fs", default-features = false, features = ["host-fs"] } -virtual-net = { version = "0.3.0", path = "../virtual-net" } +virtual-fs = { version = "0.6.0", path = "../virtual-fs", default-features = false, features = [ + "host-fs", +] } +virtual-net = { version = "0.3.0", path = "../virtual-net" } # Wasmer-owned dependencies. webc = { workspace = true } @@ -90,11 +110,13 @@ sha2 = "0.10.6" object = "0.30.0" wasm-coredump-builder = { version = "0.1.11", optional = true } tracing = { version = "0.1" } -tracing-subscriber = { version = "0.3", features = [ "env-filter", "fmt" ] } +tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] } async-trait = "0.1.68" tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] } once_cell = "1.17.1" indicatif = "0.17.5" +opener = "0.6.1" +hyper = { version = "0.14.27", features = ["server"] } # NOTE: Must use different features for clap because the "color" feature does not # work on wasi due to the anstream dependency not compiling. @@ -109,16 +131,27 @@ clap = { version = "4.2.7", default-features = false, features = [ "suggestions", "derive", "env", -]} +] } [target.'cfg(not(target_arch = "riscv64"))'.dependencies] -reqwest = { version = "^0.11", default-features = false, features = ["rustls-tls", "json", "multipart"] } +reqwest = { version = "^0.11", default-features = false, features = [ + "rustls-tls", + "json", + "multipart", +] } [target.'cfg(target_arch = "riscv64")'.dependencies] -reqwest = { version = "^0.11", default-features = false, features = ["native-tls", "json", "multipart"] } +reqwest = { version = "^0.11", default-features = false, features = [ + "native-tls", + "json", + "multipart", +] } [build-dependencies] -chrono = { version = "^0.4", default-features = false, features = ["std", "clock"] } +chrono = { version = "^0.4", default-features = false, features = [ + "std", + "clock", +] } [target.'cfg(target_os = "linux")'.dependencies] unix_mode = "0.1.3" @@ -126,7 +159,14 @@ unix_mode = "0.1.3" [features] # Don't add the compiler features in default, please add them on the Makefile # since we might want to autoconfigure them depending on the availability on the host. -default = ["sys", "wat", "wast", "compiler", "wasmer-artifact-create", "static-artifact-create"] +default = [ + "sys", + "wat", + "wast", + "compiler", + "wasmer-artifact-create", + "static-artifact-create", +] backend = [] coredump = ["wasm-coredump-builder"] sys = ["compiler", "wasmer-vm"] @@ -134,21 +174,56 @@ jsc = ["backend", "wasmer/jsc", "wasmer/std"] wast = ["wasmer-wast"] host-net = ["virtual-net/host-net"] wat = ["wasmer/wat"] -compiler = ["backend", "wasmer/compiler", "wasmer-compiler/translator", "wasmer-compiler/compiler"] -wasmer-artifact-create = ["compiler", "wasmer/wasmer-artifact-load", "wasmer/wasmer-artifact-create", "wasmer-compiler/wasmer-artifact-load", "wasmer-compiler/wasmer-artifact-create", "wasmer-object"] -static-artifact-create = ["compiler", "wasmer/static-artifact-load", "wasmer/static-artifact-create", "wasmer-compiler/static-artifact-load", "wasmer-compiler/static-artifact-create", "wasmer-object"] -wasmer-artifact-load = ["compiler", "wasmer/wasmer-artifact-load", "wasmer-compiler/wasmer-artifact-load"] -static-artifact-load = ["compiler", "wasmer/static-artifact-load", "wasmer-compiler/static-artifact-load"] +compiler = [ + "backend", + "wasmer/compiler", + "wasmer-compiler/translator", + "wasmer-compiler/compiler", +] +wasmer-artifact-create = [ + "compiler", + "wasmer/wasmer-artifact-load", + "wasmer/wasmer-artifact-create", + "wasmer-compiler/wasmer-artifact-load", + "wasmer-compiler/wasmer-artifact-create", + "wasmer-object", +] +static-artifact-create = [ + "compiler", + "wasmer/static-artifact-load", + "wasmer/static-artifact-create", + "wasmer-compiler/static-artifact-load", + "wasmer-compiler/static-artifact-create", + "wasmer-object", +] +wasmer-artifact-load = [ + "compiler", + "wasmer/wasmer-artifact-load", + "wasmer-compiler/wasmer-artifact-load", +] +static-artifact-load = [ + "compiler", + "wasmer/static-artifact-load", + "wasmer-compiler/static-artifact-load", +] experimental-io-devices = ["wasmer-wasix-experimental-io-devices"] singlepass = ["wasmer-compiler-singlepass", "compiler"] cranelift = ["wasmer-compiler-cranelift", "compiler"] llvm = ["wasmer-compiler-llvm", "compiler"] -disable-all-logging = ["wasmer-wasix/disable-all-logging", "log/release_max_level_off"] +disable-all-logging = [ + "wasmer-wasix/disable-all-logging", + "log/release_max_level_off", +] headless = [] headless-minimal = ["headless", "disable-all-logging"] # Optional -enable-serde = ["wasmer/enable-serde", "wasmer-vm/enable-serde", "wasmer-compiler/enable-serde", "wasmer-wasix/enable-serde"] +enable-serde = [ + "wasmer/enable-serde", + "wasmer-vm/enable-serde", + "wasmer-compiler/enable-serde", + "wasmer-wasix/enable-serde", +] [dev-dependencies] assert_cmd = "2.0.11" diff --git a/lib/cli/src/commands/login.rs b/lib/cli/src/commands/login.rs index fa7158a358a..27258c0ea77 100644 --- a/lib/cli/src/commands/login.rs +++ b/lib/cli/src/commands/login.rs @@ -1,14 +1,99 @@ -use std::path::PathBuf; +use std::{net::TcpListener, path::PathBuf, str::FromStr, time::Duration}; + +use anyhow::Ok; use clap::Parser; #[cfg(not(test))] -use dialoguer::Input; +use dialoguer::{console::style, Input}; +use reqwest::Method; + +use serde::Deserialize; +use wasmer_registry::{ + types::NewNonceOutput, + wasmer_env::{Registry, WasmerEnv, WASMER_DIR}, + RegistryClient, +}; + +use hyper::{ + service::{make_service_fn, service_fn}, + Body, Request, Response, Server, StatusCode, +}; + +const WASMER_CLI: &str = "wasmer-cli"; + +/// Payload from the frontend after the user has authenticated. +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum TokenStatus { + /// Signifying that the token is cancelled + Cancelled, + /// Signifying that the token is authorized + Authorized, +} + +/// Payload from the frontend after the user has authenticated. +/// +/// This has the token that we need to set in the WASMER_TOML file. +#[derive(Clone, Debug, Deserialize)] +pub struct ValidatedNonceOutput { + /// Token Received from the frontend + pub token: Option, + /// Status of the token , whether it is authorized or cancelled + pub status: TokenStatus, +} + +/// Enum for the boolean like prompt options +#[derive(Debug, Clone, PartialEq)] +pub enum BoolPromptOptions { + /// Signifying a yes/true - using `y/Y` + Yes, + /// Signifying a No/false - using `n/N` + No, +} + +impl FromStr for BoolPromptOptions { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s { + "y" | "Y" => Ok(BoolPromptOptions::Yes), + "n" | "N" => Ok(BoolPromptOptions::No), + _ => Err(anyhow::anyhow!("Invalid option")), + } + } +} + +impl ToString for BoolPromptOptions { + fn to_string(&self) -> String { + match self { + BoolPromptOptions::Yes => "y".to_string(), + BoolPromptOptions::No => "n".to_string(), + } + } +} + +type Token = String; + +#[derive(Debug, Clone)] +enum AuthorizationState { + TokenSuccess(Token), + Cancelled, + TimedOut, + UnknownMethod, +} -use wasmer_registry::wasmer_env::{Registry, WasmerEnv, WASMER_DIR}; +#[derive(Clone)] +struct AppContext { + server_shutdown_tx: tokio::sync::mpsc::Sender, + token_tx: tokio::sync::mpsc::Sender, +} -/// Subcommand for listing packages +/// Subcommand for log in a user into Wasmer (using a browser or provided a token) #[derive(Debug, Clone, Parser)] pub struct Login { + /// Variable to login without opening a browser + #[clap(long, name = "no-browser", default_value = "false")] + pub no_browser: bool, // Note: This is essentially a copy of WasmerEnv except the token is // accepted as a main argument instead of via --token. /// Set Wasmer's home directory @@ -27,9 +112,9 @@ pub struct Login { } impl Login { - fn get_token_or_ask_user(&self, env: &WasmerEnv) -> Result { + fn get_token_or_ask_user(&self, env: &WasmerEnv) -> Result { if let Some(token) = &self.token { - return Ok(token.clone()); + return Ok(AuthorizationState::TokenSuccess(token.clone())); } let registry_host = env.registry_endpoint()?; @@ -41,6 +126,7 @@ impl Login { format!("Invalid registry for login {}: {e}", registry_host), ) })?; + let login_prompt = match ( registry_tld.domain.as_deref(), registry_tld.suffix.as_deref(), @@ -52,15 +138,77 @@ impl Login { }; #[cfg(test)] { - Ok(login_prompt) + Ok(AuthorizationState::TokenSuccess(login_prompt)) } #[cfg(not(test))] { let token = Input::new().with_prompt(&login_prompt).interact_text()?; - Ok(token) + Ok(AuthorizationState::TokenSuccess(token)) } } + async fn get_token_from_browser( + &self, + env: &WasmerEnv, + ) -> Result { + let registry = env.registry_endpoint()?; + + let client = RegistryClient::new(registry.clone(), None, None); + + let (listener, server_url) = Self::setup_listener().await?; + + let (server_shutdown_tx, mut server_shutdown_rx) = tokio::sync::mpsc::channel::(1); + let (token_tx, mut token_rx) = tokio::sync::mpsc::channel::(1); + + // Create a new AppContext + let app_context = AppContext { + server_shutdown_tx, + token_tx, + }; + + let NewNonceOutput { auth_url } = + wasmer_registry::api::create_nonce(&client, WASMER_CLI.to_string(), server_url).await?; + + // if failed to open the browser, then don't error out just print the auth_url with a message + println!("Opening auth link in your default browser: {}", &auth_url); + opener::open_browser(&auth_url).unwrap_or_else(|_| { + println!( + "⚠️ Failed to open the browser.\n + Please open the url: {}", + &auth_url + ); + }); + + // Create a new server + let make_svc = make_service_fn(move |_| { + let context = app_context.clone(); + + // Create a `Service` for responding to the request. + let service = service_fn(move |req| service_router(context.clone(), req)); + + // Return the service to hyper. + async move { Ok(service) } + }); + + print!("Waiting for session... "); + + // start the server + Server::from_tcp(listener)? + .serve(make_svc) + .with_graceful_shutdown(async { + server_shutdown_rx.recv().await; + }) + .await?; + + // receive the token from the server + let token = token_rx + .recv() + .await + .ok_or_else(|| anyhow::anyhow!("❌ Failed to receive token from localhost"))?; + + Ok(token) + } + fn wasmer_env(&self) -> WasmerEnv { WasmerEnv::new( self.wasmer_dir.clone(), @@ -70,23 +218,212 @@ impl Login { ) } + async fn setup_listener() -> Result<(TcpListener, String), anyhow::Error> { + let listener = TcpListener::bind("127.0.0.1:0")?; + let addr = listener.local_addr()?; + let port = addr.port(); + + let server_url = format!("http://localhost:{}", port); + + Ok((listener, server_url)) + } + /// execute [List] - pub fn execute(&self) -> Result<(), anyhow::Error> { + #[tokio::main] + pub async fn execute(&self) -> Result<(), anyhow::Error> { let env = self.wasmer_env(); - let token = self.get_token_or_ask_user(&env)?; - let registry = env.registry_endpoint()?; - match wasmer_registry::login::login_and_save_token(env.dir(), registry.as_str(), &token)? { - Some(s) => println!("Login for Wasmer user {:?} saved", s), - None => println!( - "Error: no user found on registry {:?} with token {:?}. Token saved regardless.", - registry, token - ), - } + + let auth_state = match self.token.clone() { + Some(token) => Ok(AuthorizationState::TokenSuccess(token)), + None => { + let person_wants_to_login = + match wasmer_registry::whoami(env.dir(), Some(registry.as_str()), None) { + std::result::Result::Ok((registry, user)) => { + println!( + "You are already logged in as {:?} on registry {:?}", + user, registry + ); + + #[cfg(not(test))] + { + let login_again = Input::new() + .with_prompt(format!( + "{} {} - [y/{}]", + style("?").yellow().bold(), + style("Do you want to login with another user?") + .bright() + .bold(), + style("N").green().bold() + )) + .show_default(false) + .default(BoolPromptOptions::No) + .interact_text()?; + + login_again == BoolPromptOptions::Yes + } + #[cfg(test)] + { + false + } + } + _ => true, + }; + + if !person_wants_to_login { + Ok(AuthorizationState::Cancelled) + } else if self.no_browser { + self.get_token_or_ask_user(&env) + } else { + // switch between two methods of getting the token. + // start two async processes, 10 minute timeout and get token from browser. Whichever finishes first, use that. + let timeout_future = tokio::time::sleep(Duration::from_secs(60 * 10)); + tokio::select! { + _ = timeout_future => { + Ok(AuthorizationState::TimedOut) + }, + token = self.get_token_from_browser(&env) => { + token + } + } + } + } + }?; + + match auth_state { + AuthorizationState::TokenSuccess(token) => { + match wasmer_registry::login::login_and_save_token( + env.dir(), + registry.as_str(), + &token, + )? { + Some(s) => { + print!("Done!"); + println!("\n✅ Login for Wasmer user {:?} saved", s) + } + None => print!( + "Warning: no user found on {:?} with the provided token.\nToken saved regardless.", + registry.domain().unwrap_or("registry.wasmer.io") + ), + }; + } + AuthorizationState::TimedOut => { + print!("Timed out (10 mins exceeded)"); + } + AuthorizationState::Cancelled => { + println!("Cancelled by the user"); + } + AuthorizationState::UnknownMethod => { + println!("Error: unknown method\n"); + } + }; Ok(()) } } +async fn preflight(req: Request) -> Result, anyhow::Error> { + let _whole_body = hyper::body::aggregate(req).await?; + let response = Response::builder() + .status(StatusCode::OK) + .header("Access-Control-Allow-Origin", "*") // FIXME: this is not secure, Don't allow all origins. @syrusakbary + .header("Access-Control-Allow-Headers", "Content-Type") + .header("Access-Control-Allow-Methods", "POST, OPTIONS") + .body(Body::default())?; + Ok(response) +} + +async fn handle_post_save_token( + context: AppContext, + req: Request, +) -> Result, anyhow::Error> { + let AppContext { + server_shutdown_tx, + token_tx, + } = context; + let (.., body) = req.into_parts(); + let body = hyper::body::to_bytes(body).await?; + + let ValidatedNonceOutput { + token, + status: token_status, + } = serde_json::from_slice::(&body)?; + + // send the AuthorizationState based on token_status to the main thread and get the response message + let (response_message, parse_failure) = match token_status { + TokenStatus::Cancelled => { + token_tx + .send(AuthorizationState::Cancelled) + .await + .expect("Failed to send token"); + + ("Token Cancelled by the user", false) + } + TokenStatus::Authorized => { + if let Some(token) = token { + token_tx + .send(AuthorizationState::TokenSuccess(token.clone())) + .await + .expect("Failed to send token"); + ("Token Authorized", false) + } else { + ("Token not found", true) + } + } + }; + + server_shutdown_tx + .send(true) + .await + .expect("Failed to send shutdown signal"); + + let status = if parse_failure { + StatusCode::BAD_REQUEST + } else { + StatusCode::OK + }; + + Ok(Response::builder() + .status(status) + .header("Access-Control-Allow-Origin", "*") // FIXME: this is not secure, Don't allow all origins. @syrusakbary + .header("Access-Control-Allow-Headers", "Content-Type") + .header("Access-Control-Allow-Methods", "POST, OPTIONS") + .body(Body::from(response_message))?) +} + +async fn handle_unknown_method(context: AppContext) -> Result, anyhow::Error> { + let AppContext { + server_shutdown_tx, + token_tx, + } = context; + + token_tx + .send(AuthorizationState::UnknownMethod) + .await + .expect("Failed to send token"); + + server_shutdown_tx + .send(true) + .await + .expect("Failed to send shutdown signal"); + + Ok(Response::builder() + .status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::from("Method not allowed"))?) +} + +/// Handle the preflight headers first - OPTIONS request +/// Then proceed to handle the actual request - POST request +async fn service_router( + context: AppContext, + req: Request, +) -> Result, anyhow::Error> { + match *req.method() { + Method::OPTIONS => preflight(req).await, + Method::POST => handle_post_save_token(context, req).await, + _ => handle_unknown_method(context).await, + } +} + #[cfg(test)] mod tests { use clap::CommandFactory; @@ -98,6 +435,7 @@ mod tests { fn interactive_login() { let temp = TempDir::new().unwrap(); let login = Login { + no_browser: true, registry: Some("wasmer.wtf".into()), wasmer_dir: temp.path().to_path_buf(), token: None, @@ -106,17 +444,26 @@ mod tests { let env = login.wasmer_env(); let token = login.get_token_or_ask_user(&env).unwrap(); - - assert_eq!( - token, - "Please paste the login token from https://wasmer.wtf/settings/access-tokens" - ); + match token { + AuthorizationState::TokenSuccess(token) => { + assert_eq!( + token, + "Please paste the login token from https://wasmer.wtf/settings/access-tokens" + ); + } + AuthorizationState::Cancelled + | AuthorizationState::TimedOut + | AuthorizationState::UnknownMethod => { + panic!("Should not reach here") + } + } } #[test] fn login_with_token() { let temp = TempDir::new().unwrap(); let login = Login { + no_browser: true, registry: Some("wasmer.wtf".into()), wasmer_dir: temp.path().to_path_buf(), token: Some("abc".to_string()), @@ -126,7 +473,16 @@ mod tests { let token = login.get_token_or_ask_user(&env).unwrap(); - assert_eq!(token, "abc"); + match token { + AuthorizationState::TokenSuccess(token) => { + assert_eq!(token, "abc"); + } + AuthorizationState::Cancelled + | AuthorizationState::TimedOut + | AuthorizationState::UnknownMethod => { + panic!("Should not reach here") + } + } } #[test] diff --git a/lib/registry/graphql/mutations/new_nonce.graphql b/lib/registry/graphql/mutations/new_nonce.graphql new file mode 100644 index 00000000000..b5a6b1827e8 --- /dev/null +++ b/lib/registry/graphql/mutations/new_nonce.graphql @@ -0,0 +1,7 @@ +mutation NewNonce($name: String!, $callbackUrl: String!) { + newNonce(input: { name: $name, callbackUrl: $callbackUrl }) { + nonce { + authUrl + } + } +} diff --git a/lib/registry/graphql/schema.graphql b/lib/registry/graphql/schema.graphql index 0c8392d4ccf..aa506f7de9e 100644 --- a/lib/registry/graphql/schema.graphql +++ b/lib/registry/graphql/schema.graphql @@ -1,59 +1,139 @@ -""" -Exposes a URL that specifies the behaviour of this scalar. -""" -directive @specifiedBy( +interface Node { """ - The URL that specifies the behaviour of this scalar. + The ID of the object """ - url: String! -) on SCALAR - -input AcceptNamespaceCollaboratorInviteInput { - inviteId: ID! - clientMutationId: String -} - -type AcceptNamespaceCollaboratorInvitePayload { - namespaceCollaboratorInvite: NamespaceCollaboratorInvite! - clientMutationId: String -} - -input AcceptPackageCollaboratorInviteInput { - inviteId: ID! - clientMutationId: String + id: ID! } -type AcceptPackageCollaboratorInvitePayload { - packageCollaboratorInvite: PackageCollaboratorInvite! - clientMutationId: String +type PublicKey implements Node { + """ + The ID of the object + """ + id: ID! + owner: User! + keyId: String! + key: String! + revokedAt: DateTime + uploadedAt: DateTime! + verifyingSignature: Signature + revoked: Boolean! } -input AcceptPackageTransferRequestInput { - packageTransferRequestId: ID! - clientMutationId: String -} +type User implements Node & PackageOwner & Owner { + firstName: String! + lastName: String! + email: String! + dateJoined: DateTime! -type AcceptPackageTransferRequestPayload { - package: Package! - packageTransferRequest: PackageTransferRequest! - clientMutationId: String -} + """ + Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only. + """ + username: String! + isEmailValidated: Boolean! + bio: String + location: String + websiteUrl: String -type ActivityEvent implements Node { """ The ID of the object """ id: ID! - body: ActivityEventBody! - actorIcon: String! - createdAt: DateTime! + globalName: String! + avatar(size: Int = 80): String! + isViewer: Boolean! + hasUsablePassword: Boolean + fullName: String! + githubUrl: String + twitterUrl: String + publicActivity( + before: String + after: String + first: Int + last: Int + ): ActivityEventConnection! + billing: Billing + waitlist(name: String!): WaitlistMember + namespaces( + role: GrapheneRole + before: String + after: String + first: Int + last: Int + ): NamespaceConnection! + packages( + collaborating: Boolean = false + before: String + after: String + first: Int + last: Int + ): PackageConnection! + apps( + collaborating: Boolean = false + sortBy: DeployAppsSortBy + offset: Int + before: String + after: String + first: Int + last: Int + ): DeployAppConnection! + usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]! + isStaff: Boolean + packageVersions( + before: String + after: String + first: Int + last: Int + ): PackageVersionConnection! + packageTransfersIncoming( + before: String + after: String + first: Int + last: Int + ): PackageTransferRequestConnection! + packageInvitesIncoming( + before: String + after: String + first: Int + last: Int + ): PackageCollaboratorInviteConnection! + namespaceInvitesIncoming( + before: String + after: String + first: Int + last: Int + ): NamespaceCollaboratorInviteConnection! + apiTokens( + before: String + after: String + first: Int + last: Int + ): APITokenConnection! + notifications( + before: String + after: String + first: Int + last: Int + ): UserNotificationConnection! } -type ActivityEventBody { - text: String! - ranges: [NodeBodyRange!]! +""" +Setup for backwards compatibility with existing frontends. +""" +interface PackageOwner { + globalName: String! +} + +interface Owner { + globalName: String! } +""" +The `DateTime` scalar type represents a DateTime +value as specified by +[iso8601](https://en.wikipedia.org/wiki/ISO_8601). +""" +scalar DateTime + type ActivityEventConnection { """ Pagination data for this connection. @@ -67,59 +147,38 @@ type ActivityEventConnection { } """ -A Relay edge containing a `ActivityEvent` and its cursor. +The Relay compliant `PageInfo` type, containing data necessary to paginate this connection. """ -type ActivityEventEdge { +type PageInfo { """ - The item at the end of the edge + When paginating forwards, are there more items? """ - node: ActivityEvent + hasNextPage: Boolean! """ - A cursor for use in pagination + When paginating backwards, are there more items? """ - cursor: String! -} - -type AggregateMetrics { - cpuTime: String! - memoryUsage: String! - memoryTime: String! - ingress: String! - egress: String! - mountedVolumes: String! - monthlyCost: String! -} - -type APIToken { - id: ID! - user: User! - identifier: String - createdAt: DateTime! - revokedAt: DateTime - lastUsedAt: DateTime -} + hasPreviousPage: Boolean! -type APITokenConnection { """ - Pagination data for this connection. + When paginating backwards, the cursor to continue. """ - pageInfo: PageInfo! + startCursor: String """ - Contains the nodes in this connection. + When paginating forwards, the cursor to continue. """ - edges: [APITokenEdge]! + endCursor: String } """ -A Relay edge containing a `APIToken` and its cursor. +A Relay edge containing a `ActivityEvent` and its cursor. """ -type APITokenEdge { +type ActivityEventEdge { """ The item at the end of the edge """ - node: APIToken + node: ActivityEvent """ A cursor for use in pagination @@ -127,34 +186,52 @@ type APITokenEdge { cursor: String! } -type AppConnection { +type ActivityEvent implements Node { """ - Pagination data for this connection. + The ID of the object """ - pageInfo: PageInfo! + id: ID! + body: ActivityEventBody! + actorIcon: String! + createdAt: DateTime! +} - """ - Contains the nodes in this connection. - """ - edges: [AppEdge]! +type ActivityEventBody { + text: String! + ranges: [NodeBodyRange!]! } -""" -A Relay edge containing a `App` and its cursor. -""" -type AppEdge { +type NodeBodyRange { + entity: Node! + offset: Int! + length: Int! +} + +type WaitlistMember implements Node { + waitlist: Waitlist! + joinedAt: DateTime! + approvedAt: DateTime + """ - The item at the end of the edge + The ID of the object """ - node: DeployApp + id: ID! + member: Owner! + approved: Boolean! +} + +type Waitlist implements Node { + name: String! + createdAt: DateTime! + updatedAt: DateTime! """ - A cursor for use in pagination + The ID of the object """ - cursor: String! + id: ID! } -type AppVersionConnection { +type NamespaceConnection { """ Pagination data for this connection. """ @@ -163,17 +240,17 @@ type AppVersionConnection { """ Contains the nodes in this connection. """ - edges: [AppVersionEdge]! + edges: [NamespaceEdge]! } """ -A Relay edge containing a `AppVersion` and its cursor. +A Relay edge containing a `Namespace` and its cursor. """ -type AppVersionEdge { +type NamespaceEdge { """ The item at the end of the edge """ - node: DeployAppVersion + node: Namespace """ A cursor for use in pagination @@ -181,48 +258,82 @@ type AppVersionEdge { cursor: String! } -input ArchivePackageInput { - packageId: ID! - clientMutationId: String -} - -type ArchivePackagePayload { - package: Package! - clientMutationId: String -} - -""" -The `BigInt` scalar type represents non-fractional whole numeric values. -`BigInt` is not constrained to 32-bit like the `Int` type and thus is a less -compatible type. -""" -scalar BigInt - -type BindingsGenerator implements Node { +type Namespace implements Node & PackageOwner & Owner { """ The ID of the object """ id: ID! - packageVersion: PackageVersion! - active: Boolean! - commandName: String! - registryJavascriptlanguagebindings( + name: String! + displayName: String + description: String! + avatar: String! + avatarUpdatedAt: DateTime + createdAt: DateTime! + updatedAt: DateTime! + maintainerInvites( offset: Int before: String after: String first: Int last: Int - ): PackageVersionNPMBindingConnection! - registryPythonlanguagebindings( + ): NamespaceCollaboratorInviteConnection! + userSet( offset: Int before: String after: String first: Int last: Int - ): PackageVersionPythonBindingConnection! + ): UserConnection! + globalName: String! + packages( + before: String + after: String + first: Int + last: Int + ): PackageConnection! + apps( + sortBy: DeployAppsSortBy + offset: Int + before: String + after: String + first: Int + last: Int + ): DeployAppConnection! + packageVersions( + before: String + after: String + first: Int + last: Int + ): PackageVersionConnection! + collaborators( + before: String + after: String + first: Int + last: Int + ): NamespaceCollaboratorConnection! + publicActivity( + before: String + after: String + first: Int + last: Int + ): ActivityEventConnection! + pendingInvites( + before: String + after: String + first: Int + last: Int + ): NamespaceCollaboratorInviteConnection! + viewerHasRole(role: GrapheneRole!): Boolean! + packageTransfersIncoming( + before: String + after: String + first: Int + last: Int + ): PackageTransferRequestConnection! + usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]! } -type BindingsGeneratorConnection { +type NamespaceCollaboratorInviteConnection { """ Pagination data for this connection. """ @@ -231,17 +342,17 @@ type BindingsGeneratorConnection { """ Contains the nodes in this connection. """ - edges: [BindingsGeneratorEdge]! + edges: [NamespaceCollaboratorInviteEdge]! } """ -A Relay edge containing a `BindingsGenerator` and its cursor. +A Relay edge containing a `NamespaceCollaboratorInvite` and its cursor. """ -type BindingsGeneratorEdge { +type NamespaceCollaboratorInviteEdge { """ The item at the end of the edge """ - node: BindingsGenerator + node: NamespaceCollaboratorInvite """ A cursor for use in pagination @@ -249,89 +360,72 @@ type BindingsGeneratorEdge { cursor: String! } -input ChangePackageVersionArchivedStatusInput { - packageVersionId: ID! - isArchived: Boolean - clientMutationId: String -} - -type ChangePackageVersionArchivedStatusPayload { - packageVersion: PackageVersion! - clientMutationId: String -} - -input ChangeUserEmailInput { - newEmail: String! - clientMutationId: String -} - -type ChangeUserEmailPayload { - user: User! - clientMutationId: String -} - -input ChangeUserPasswordInput { +type NamespaceCollaboratorInvite implements Node { """ - The token associated to change the password. If not existing it will use the request user by default + The ID of the object """ - token: String - oldPassword: String - password: String! - clientMutationId: String + id: ID! + requestedBy: User! + user: User + inviteEmail: String + namespace: Namespace! + role: RegistryNamespaceMaintainerInviteRoleChoices! + accepted: NamespaceCollaborator + approvedBy: User + declinedBy: User + createdAt: DateTime! + expiresAt: DateTime! + closedAt: DateTime } -type ChangeUserPasswordPayload { - token: String - clientMutationId: String -} +enum RegistryNamespaceMaintainerInviteRoleChoices { + """ + Admin + """ + ADMIN -input ChangeUserUsernameInput { """ - The new user username + Editor """ - username: String! - clientMutationId: String -} + EDITOR -type ChangeUserUsernamePayload { - user: User - token: String - clientMutationId: String + """ + Viewer + """ + VIEWER } -input CheckUserExistsInput { +type NamespaceCollaborator implements Node { """ - The user + The ID of the object """ - user: String! - clientMutationId: String + id: ID! + user: User! + role: RegistryNamespaceMaintainerRoleChoices! + namespace: Namespace! + createdAt: DateTime! + updatedAt: DateTime! + invite: NamespaceCollaboratorInvite } -type CheckUserExistsPayload { - exists: Boolean! +enum RegistryNamespaceMaintainerRoleChoices { + """ + Admin + """ + ADMIN """ - The user is only returned if the user input was the username + Editor """ - user: User - clientMutationId: String -} + EDITOR -type Collection { - slug: String! - displayName: String! - description: String! - createdAt: DateTime! - banner: String! - packages( - before: String - after: String - first: Int - last: Int - ): PackageConnection! + """ + Viewer + """ + VIEWER } -type CollectionConnection { +type UserConnection { """ Pagination data for this connection. """ @@ -340,17 +434,22 @@ type CollectionConnection { """ Contains the nodes in this connection. """ - edges: [CollectionEdge]! + edges: [UserEdge]! + + """ + Total number of items in the connection. + """ + totalCount: Int } """ -A Relay edge containing a `Collection` and its cursor. +A Relay edge containing a `User` and its cursor. """ -type CollectionEdge { +type UserEdge { """ The item at the end of the edge """ - node: Collection + node: User """ A cursor for use in pagination @@ -358,211 +457,576 @@ type CollectionEdge { cursor: String! } -type Command { - command: String! - packageVersion: PackageVersion! - module: PackageVersionModule! -} - -input CreateNamespaceInput { - name: String! - - """ - The namespace display name - """ - displayName: String - +type PackageConnection { """ - The namespace description + Pagination data for this connection. """ - description: String + pageInfo: PageInfo! """ - The namespace avatar + Contains the nodes in this connection. """ - avatar: String - clientMutationId: String -} - -type CreateNamespacePayload { - namespace: Namespace! - user: User! - clientMutationId: String + edges: [PackageEdge]! } """ -The `DateTime` scalar type represents a DateTime -value as specified by -[iso8601](https://en.wikipedia.org/wiki/ISO_8601). +A Relay edge containing a `Package` and its cursor. """ -scalar DateTime - -input DeleteNamespaceInput { - namespaceId: ID! - clientMutationId: String -} +type PackageEdge { + """ + The item at the end of the edge + """ + node: Package -type DeleteNamespacePayload { - success: Boolean! - clientMutationId: String + """ + A cursor for use in pagination + """ + cursor: String! } -type DeployApp implements Node & Owner { +type Package implements Likeable & Node & PackageOwner { """ The ID of the object """ id: ID! name: String! - createdBy: User! + namespace: String + private: Boolean! createdAt: DateTime! - activeVersion: DeployAppVersion! - globalName: String! - url: String! - description: String - owner: Owner! - versions( - before: String + updatedAt: DateTime! + maintainers: [User]! @deprecated(reason: "Please use collaborators instead") + curated: Boolean! + ownerObjectId: Int! + lastVersion: PackageVersion + + """ + The app icon. It should be formatted in the same way as Apple icons + """ + icon: String! + totalDownloads: Int! + iconUpdatedAt: DateTime + watchersCount: Int! + versions: [PackageVersion]! + collectionSet: [Collection!]! + likersCount: Int! + viewerHasLiked: Boolean! + globalName: String! + alias: String + displayName: String! + + """ + The name of the package without the owner + """ + packageName: String! + + """ + The app icon. It should be formatted in the same way as Apple icons + """ + appIcon: String! @deprecated(reason: "Please use icon instead") + + """ + The total number of downloads of the package + """ + downloadsCount: Int + + """ + The public keys for all the published versions + """ + publicKeys: [PublicKey!]! + collaborators( + before: String + after: String + first: Int + last: Int + ): PackageCollaboratorConnection! + pendingInvites( + before: String + after: String + first: Int + last: Int + ): PackageCollaboratorInviteConnection! + viewerHasRole(role: GrapheneRole!): Boolean! + owner: PackageOwner! + isTransferring: Boolean! + activeTransferRequest: PackageTransferRequest + isArchived: Boolean! + viewerIsWatching: Boolean! +} + +interface Likeable { + id: ID! + likersCount: Int! + viewerHasLiked: Boolean! +} + +type PackageVersion implements Node { + """ + The ID of the object + """ + id: ID! + package: Package! + version: String! + description: String! + manifest: String! + license: String + licenseFile: String + readme: String + witMd: String + repository: String + homepage: String + createdAt: DateTime! + updatedAt: DateTime! + staticObjectsCompiled: Boolean! + nativeExecutablesCompiled: Boolean! + publishedBy: User! + signature: Signature + isArchived: Boolean! + file: String! + + """ + """ + fileSize: BigInt! + piritaFile: String + + """ + """ + piritaFileSize: BigInt! + piritaManifest: JSONString + piritaVolumes: JSONString + totalDownloads: Int! + pirita256hash: String + @deprecated(reason: "Please use distribution.piritaSha256Hash instead.") + bindingsState: RegistryPackageVersionBindingsStateChoices! + nativeExecutablesState: RegistryPackageVersionNativeExecutablesStateChoices! + lastversionPackage( + offset: Int + before: String + after: String + first: Int + last: Int + ): PackageConnection! + commands: [Command!]! + nativeexecutableSet( + offset: Int + before: String + after: String + first: Int + last: Int + ): NativeExecutableConnection! + bindingsgeneratorSet( + offset: Int + before: String + after: String + first: Int + last: Int + ): BindingsGeneratorConnection! + javascriptlanguagebindingSet( + offset: Int + before: String + after: String + first: Int + last: Int + ): PackageVersionNPMBindingConnection! + pythonlanguagebindingSet( + offset: Int + before: String + after: String + first: Int + last: Int + ): PackageVersionPythonBindingConnection! + distribution: PackageDistribution! + filesystem: [PackageVersionFilesystem]! + isLastVersion: Boolean! + witFile: String + isSigned: Boolean! + moduleInterfaces: [InterfaceVersion!]! + modules: [PackageVersionModule!]! + getPiritaContents( + volume: String! = "atom" + root: String! = "" + ): [PiritaFilesystemItem!]! + nativeExecutables( + triple: String + wasmerCompilerVersion: String + ): [NativeExecutable] + bindings: [PackageVersionLanguageBinding]! + npmBindings: PackageVersionNPMBinding + pythonBindings: PackageVersionPythonBinding + hasBindings: Boolean! + hasCommands: Boolean! +} + +""" +The `BigInt` scalar type represents non-fractional whole numeric values. +`BigInt` is not constrained to 32-bit like the `Int` type and thus is a less +compatible type. +""" +scalar BigInt + +""" +Allows use of a JSON String for input / output from the GraphQL schema. + +Use of this type is *not recommended* as you lose the benefits of having a defined, static +schema (one of the key benefits of GraphQL). +""" +scalar JSONString + +enum RegistryPackageVersionBindingsStateChoices { + """ + Bindings are not detected + """ + NOT_PRESENT + + """ + Bindings are being built + """ + GENERATING + + """ + Bindings generation has failed + """ + ERROR + + """ + Bindings are built and present + """ + GENERATED_AND_PRESENT +} + +enum RegistryPackageVersionNativeExecutablesStateChoices { + """ + Native Executables are not detected + """ + NOT_PRESENT + + """ + Native Executables are being built + """ + GENERATING + + """ + Native Executables generation has failed + """ + ERROR + + """ + Native Executables are built and present + """ + GENERATED_AND_PRESENT +} + +type Command { + command: String! + packageVersion: PackageVersion! + module: PackageVersionModule! +} + +type PackageVersionModule { + name: String! + source: String! + abi: String + publicUrl: String! +} + +type NativeExecutableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + + """ + Contains the nodes in this connection. + """ + edges: [NativeExecutableEdge]! + + """ + Total number of items in the connection. + """ + totalCount: Int +} + +""" +A Relay edge containing a `NativeExecutable` and its cursor. +""" +type NativeExecutableEdge { + """ + The item at the end of the edge + """ + node: NativeExecutable + + """ + A cursor for use in pagination + """ + cursor: String! +} + +type NativeExecutable implements Node { + """ + The ID of the object + """ + id: ID! + module: String! @deprecated(reason: "Use filename instead") + filename: String! + targetTriple: String! + downloadUrl: String! +} + +type BindingsGeneratorConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + + """ + Contains the nodes in this connection. + """ + edges: [BindingsGeneratorEdge]! + + """ + Total number of items in the connection. + """ + totalCount: Int +} + +""" +A Relay edge containing a `BindingsGenerator` and its cursor. +""" +type BindingsGeneratorEdge { + """ + The item at the end of the edge + """ + node: BindingsGenerator + + """ + A cursor for use in pagination + """ + cursor: String! +} + +type BindingsGenerator implements Node { + """ + The ID of the object + """ + id: ID! + packageVersion: PackageVersion! + active: Boolean! + commandName: String! + registryJavascriptlanguagebindings( + offset: Int + before: String after: String first: Int last: Int - ): AppVersionConnection! - aggregateMetrics: AggregateMetrics! + ): PackageVersionNPMBindingConnection! + registryPythonlanguagebindings( + offset: Int + before: String + after: String + first: Int + last: Int + ): PackageVersionPythonBindingConnection! } -type DeployAppVersion implements Node { +type PackageVersionNPMBindingConnection { """ - The ID of the object + Pagination data for this connection. """ - id: ID! - app: DeployApp - configWebc: String - signature: String - description: String - publishedBy: User! - createdAt: DateTime! - webcUrl: String! - config: String! - url: String! - version: String! - manifest: String! + pageInfo: PageInfo! + + """ + Contains the nodes in this connection. + """ + edges: [PackageVersionNPMBindingEdge]! + + """ + Total number of items in the connection. + """ + totalCount: Int } -type DeployConfigInfo implements Node { +""" +A Relay edge containing a `PackageVersionNPMBinding` and its cursor. +""" +type PackageVersionNPMBindingEdge { """ - The ID of the object + The item at the end of the edge """ - id: ID! - name: String! - createdBy: User! - createdAt: DateTime! - updatedAt: DateTime! - versions: [DeployConfigVersion] - publishedBy: User - namespace: String! + node: PackageVersionNPMBinding + + """ + A cursor for use in pagination + """ + cursor: String! } -type DeployConfigVersion implements Node { +type PackageVersionNPMBinding implements PackageVersionLanguageBinding & Node { """ The ID of the object """ id: ID! - configWebc: String - signature: String - description: String + language: ProgrammingLanguage! + + """ + The URL of the generated artifacts on Wasmer CDN. + """ + url: String! + + """ + When the binding was generated + """ createdAt: DateTime! - versionNumber: BigInt! - fileOffset: Int - fileSize: Int - updatedAt: DateTime! - webcUrl: String! - config: String! - info: DeployConfigInfo -} -type ErrorType { - field: String! - messages: [String!]! -} + """ + Package version used to generate this binding + """ + generator: BindingsGenerator! + name: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) + kind: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) -input GenerateAPITokenInput { - identifier: String - clientMutationId: String + """ + Name of package source + """ + packageName: String! + module: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) + npmDefaultInstallPackageName(url: String): String! + @deprecated(reason: "Please use packageName instead") } -type GenerateAPITokenPayload { - token: APIToken - tokenRaw: String - user: User - clientMutationId: String -} +interface PackageVersionLanguageBinding { + id: ID! + language: ProgrammingLanguage! -input GenerateBindingsForAllPackagesInput { - bindingsGeneratorId: ID - bindingsGeneratorCommand: String - clientMutationId: String -} + """ + The URL of the generated artifacts on Wasmer CDN. + """ + url: String! -type GenerateBindingsForAllPackagesPayload { - message: String! - clientMutationId: String + """ + When the binding was generated + """ + createdAt: DateTime! + + """ + Package version used to generate this binding + """ + generator: BindingsGenerator! + name: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) + kind: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) + + """ + Name of package source + """ + packageName: String! + module: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) } -input GenerateDeployTokenInput { - deployConfigVersionId: String! - clientMutationId: String +enum ProgrammingLanguage { + PYTHON + JAVASCRIPT } -type GenerateDeployTokenPayload { - token: String! - deployConfigVersion: DeployConfigVersion! - clientMutationId: String +type PackageVersionPythonBindingConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + + """ + Contains the nodes in this connection. + """ + edges: [PackageVersionPythonBindingEdge]! + + """ + Total number of items in the connection. + """ + totalCount: Int } """ -The `GenericScalar` scalar type represents a generic -GraphQL scalar value that could be: -String, Boolean, Int, Float, List or Object. +A Relay edge containing a `PackageVersionPythonBinding` and its cursor. """ -scalar GenericScalar +type PackageVersionPythonBindingEdge { + """ + The item at the end of the edge + """ + node: PackageVersionPythonBinding -type GetPasswordResetToken { - valid: Boolean! - user: User + """ + A cursor for use in pagination + """ + cursor: String! } -union GlobalObject = User | Namespace +type PackageVersionPythonBinding implements PackageVersionLanguageBinding & Node { + """ + The ID of the object + """ + id: ID! + language: ProgrammingLanguage! -enum GrapheneRole { - ADMIN - EDITOR - VIEWER -} + """ + The URL of the generated artifacts on Wasmer CDN. + """ + url: String! -input InputSignature { - publicKeyKeyId: String! - data: String! -} + """ + When the binding was generated + """ + createdAt: DateTime! -type Interface implements Node { """ - The ID of the object + Package version used to generate this binding """ - id: ID! + generator: BindingsGenerator! name: String! - displayName: String! - description: String! - homepage: String - icon: String - createdAt: DateTime! - updatedAt: DateTime! - versions( - offset: Int - before: String - after: String - first: Int - last: Int - ): InterfaceVersionConnection! - lastVersion: InterfaceVersion + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) + kind: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) + + """ + Name of package source + """ + packageName: String! + module: String! + @deprecated( + reason: "Do not use this field, since bindings for all modules are generated at once now." + ) + pythonDefaultInstallPackageName(url: String): String! +} + +type PackageDistribution { + downloadUrl: String! + size: Int! + piritaDownloadUrl: String + piritaSize: Int! + piritaSha256Hash: String +} + +type PackageVersionFilesystem { + wasm: String! + host: String! } type InterfaceVersion implements Node { @@ -585,266 +1049,29 @@ type InterfaceVersion implements Node { ): PackageVersionConnection! } -type InterfaceVersionConnection { - """ - Pagination data for this connection. - """ - pageInfo: PageInfo! - - """ - Contains the nodes in this connection. - """ - edges: [InterfaceVersionEdge]! -} - -""" -A Relay edge containing a `InterfaceVersion` and its cursor. -""" -type InterfaceVersionEdge { - """ - The item at the end of the edge - """ - node: InterfaceVersion - - """ - A cursor for use in pagination - """ - cursor: String! -} - -input InviteNamespaceCollaboratorInput { - namespaceId: ID! - role: GrapheneRole! - username: String - email: String - clientMutationId: String -} - -type InviteNamespaceCollaboratorPayload { - invite: NamespaceCollaboratorInvite! - namespace: Namespace! - clientMutationId: String -} - -input InvitePackageCollaboratorInput { - packageName: String! - role: GrapheneRole! - username: String - email: String - clientMutationId: String -} - -type InvitePackageCollaboratorPayload { - invite: PackageCollaboratorInvite! - package: Package! - clientMutationId: String -} - -""" -Allows use of a JSON String for input / output from the GraphQL schema. - -Use of this type is *not recommended* as you lose the benefits of having a defined, static -schema (one of the key benefits of GraphQL). -""" -scalar JSONString - -interface Likeable { - id: ID! - likersCount: Int! - viewerHasLiked: Boolean! -} - -input LikePackageInput { - packageId: ID! - clientMutationId: String -} - -type LikePackagePayload { - package: Package! - clientMutationId: String -} - -type Mutation { - publishDeployConfig( - input: PublishDeployConfigInput! - ): PublishDeployConfigPayload - @deprecated(reason: "Please use publishDeployApp instead.") - publishDeployApp(input: PublishDeployAppInput!): PublishDeployAppPayload - tokenAuth(input: ObtainJSONWebTokenInput!): ObtainJSONWebTokenPayload - generateDeployToken( - input: GenerateDeployTokenInput! - ): GenerateDeployTokenPayload - verifyAccessToken(token: String): Verify - refreshAccessToken(refreshToken: String): Refresh - revokeAccessToken(refreshToken: String): Revoke - registerUser(input: RegisterUserInput!): RegisterUserPayload - socialAuth(input: SocialAuthJWTInput!): SocialAuthJWTPayload - validateUserEmail(input: ValidateUserEmailInput!): ValidateUserEmailPayload - requestPasswordReset( - input: RequestPasswordResetInput! - ): RequestPasswordResetPayload - requestValidationEmail( - input: RequestValidationEmailInput! - ): RequestValidationEmailPayload - changeUserPassword(input: ChangeUserPasswordInput!): ChangeUserPasswordPayload - changeUserUsername(input: ChangeUserUsernameInput!): ChangeUserUsernamePayload - changeUserEmail(input: ChangeUserEmailInput!): ChangeUserEmailPayload - updateUserInfo(input: UpdateUserInfoInput!): UpdateUserInfoPayload - validateUserPassword( - input: ValidateUserPasswordInput! - ): ValidateUserPasswordPayload - generateApiToken(input: GenerateAPITokenInput!): GenerateAPITokenPayload - revokeApiToken(input: RevokeAPITokenInput!): RevokeAPITokenPayload - checkUserExists(input: CheckUserExistsInput!): CheckUserExistsPayload - readNotification(input: ReadNotificationInput!): ReadNotificationPayload - seePendingNotifications( - input: SeePendingNotificationsInput! - ): SeePendingNotificationsPayload - publishPublicKey(input: PublishPublicKeyInput!): PublishPublicKeyPayload - publishPackage(input: PublishPackageInput!): PublishPackagePayload - updatePackage(input: UpdatePackageInput!): UpdatePackagePayload - likePackage(input: LikePackageInput!): LikePackagePayload - unlikePackage(input: UnlikePackageInput!): UnlikePackagePayload - watchPackage(input: WatchPackageInput!): WatchPackagePayload - unwatchPackage(input: UnwatchPackageInput!): UnwatchPackagePayload - archivePackage(input: ArchivePackageInput!): ArchivePackagePayload - changePackageVersionArchivedStatus( - input: ChangePackageVersionArchivedStatusInput! - ): ChangePackageVersionArchivedStatusPayload - createNamespace(input: CreateNamespaceInput!): CreateNamespacePayload - updateNamespace(input: UpdateNamespaceInput!): UpdateNamespacePayload - deleteNamespace(input: DeleteNamespaceInput!): DeleteNamespacePayload - inviteNamespaceCollaborator( - input: InviteNamespaceCollaboratorInput! - ): InviteNamespaceCollaboratorPayload - acceptNamespaceCollaboratorInvite( - input: AcceptNamespaceCollaboratorInviteInput! - ): AcceptNamespaceCollaboratorInvitePayload - removeNamespaceCollaboratorInvite( - input: RemoveNamespaceCollaboratorInviteInput! - ): RemoveNamespaceCollaboratorInvitePayload - removeNamespaceCollaborator( - input: RemoveNamespaceCollaboratorInput! - ): RemoveNamespaceCollaboratorPayload - updateNamespaceCollaboratorRole( - input: UpdateNamespaceCollaboratorRoleInput! - ): UpdateNamespaceCollaboratorRolePayload - updateNamespaceCollaboratorInviteRole( - input: UpdateNamespaceCollaboratorInviteRoleInput! - ): UpdateNamespaceCollaboratorInviteRolePayload - invitePackageCollaborator( - input: InvitePackageCollaboratorInput! - ): InvitePackageCollaboratorPayload - acceptPackageCollaboratorInvite( - input: AcceptPackageCollaboratorInviteInput! - ): AcceptPackageCollaboratorInvitePayload - removePackageCollaboratorInvite( - input: RemovePackageCollaboratorInviteInput! - ): RemovePackageCollaboratorInvitePayload - updatePackageCollaboratorRole( - input: UpdatePackageCollaboratorRoleInput! - ): UpdatePackageCollaboratorRolePayload - updatePackageCollaboratorInviteRole( - input: UpdatePackageCollaboratorInviteRoleInput! - ): UpdatePackageCollaboratorInviteRolePayload - removePackageCollaborator( - input: RemovePackageCollaboratorInput! - ): RemovePackageCollaboratorPayload - requestPackageTransfer( - input: RequestPackageTransferInput! - ): RequestPackageTransferPayload - acceptPackageTransferRequest( - input: AcceptPackageTransferRequestInput! - ): AcceptPackageTransferRequestPayload - removePackageTransferRequest( - input: RemovePackageTransferRequestInput! - ): RemovePackageTransferRequestPayload - generateBindingsForAllPackages( - input: GenerateBindingsForAllPackagesInput! - ): GenerateBindingsForAllPackagesPayload -} - -type Namespace implements Node & PackageOwner & Owner { +type Interface implements Node { """ The ID of the object """ id: ID! name: String! - displayName: String + displayName: String! description: String! - avatar: String! - avatarUpdatedAt: DateTime + homepage: String + icon: String createdAt: DateTime! updatedAt: DateTime! - maintainerInvites( - offset: Int - before: String - after: String - first: Int - last: Int - ): NamespaceCollaboratorInviteConnection! - userSet( + versions( offset: Int before: String after: String first: Int last: Int - ): UserConnection! - globalName: String! - packages( - before: String - after: String - first: Int - last: Int - ): PackageConnection! - apps(before: String, after: String, first: Int, last: Int): AppConnection! - packageVersions( - before: String - after: String - first: Int - last: Int - ): PackageVersionConnection! - collaborators( - before: String - after: String - first: Int - last: Int - ): NamespaceCollaboratorConnection! - publicActivity( - before: String - after: String - first: Int - last: Int - ): ActivityEventConnection! - pendingInvites( - before: String - after: String - first: Int - last: Int - ): NamespaceCollaboratorInviteConnection! - viewerHasRole(role: GrapheneRole!): Boolean! - packageTransfersIncoming( - before: String - after: String - first: Int - last: Int - ): PackageTransferRequestConnection! -} - -type NamespaceCollaborator implements Node { - """ - The ID of the object - """ - id: ID! - user: User! - role: RegistryNamespaceMaintainerRoleChoices! - namespace: Namespace! - createdAt: DateTime! - updatedAt: DateTime! - invite: NamespaceCollaboratorInvite + ): InterfaceVersionConnection! + lastVersion: InterfaceVersion } -type NamespaceCollaboratorConnection { +type InterfaceVersionConnection { """ Pagination data for this connection. """ @@ -853,17 +1080,22 @@ type NamespaceCollaboratorConnection { """ Contains the nodes in this connection. """ - edges: [NamespaceCollaboratorEdge]! + edges: [InterfaceVersionEdge]! + + """ + Total number of items in the connection. + """ + totalCount: Int } """ -A Relay edge containing a `NamespaceCollaborator` and its cursor. +A Relay edge containing a `InterfaceVersion` and its cursor. """ -type NamespaceCollaboratorEdge { +type InterfaceVersionEdge { """ The item at the end of the edge """ - node: NamespaceCollaborator + node: InterfaceVersion """ A cursor for use in pagination @@ -871,25 +1103,7 @@ type NamespaceCollaboratorEdge { cursor: String! } -type NamespaceCollaboratorInvite implements Node { - """ - The ID of the object - """ - id: ID! - requestedBy: User! - user: User - inviteEmail: String - namespace: Namespace! - role: RegistryNamespaceMaintainerInviteRoleChoices! - accepted: NamespaceCollaborator - approvedBy: User - declinedBy: User - createdAt: DateTime! - expiresAt: DateTime! - closedAt: DateTime -} - -type NamespaceCollaboratorInviteConnection { +type PackageVersionConnection { """ Pagination data for this connection. """ @@ -898,17 +1112,17 @@ type NamespaceCollaboratorInviteConnection { """ Contains the nodes in this connection. """ - edges: [NamespaceCollaboratorInviteEdge]! + edges: [PackageVersionEdge]! } """ -A Relay edge containing a `NamespaceCollaboratorInvite` and its cursor. +A Relay edge containing a `PackageVersion` and its cursor. """ -type NamespaceCollaboratorInviteEdge { +type PackageVersionEdge { """ The item at the end of the edge """ - node: NamespaceCollaboratorInvite + node: PackageVersion """ A cursor for use in pagination @@ -916,7 +1130,38 @@ type NamespaceCollaboratorInviteEdge { cursor: String! } -type NamespaceConnection { +union PiritaFilesystemItem = PiritaFilesystemFile | PiritaFilesystemDir + +type PiritaFilesystemFile { + name(display: PiritaFilesystemNameDisplay): String! + size: Int! + offset: Int! +} + +enum PiritaFilesystemNameDisplay { + RELATIVE + ABSOLUTE +} + +type PiritaFilesystemDir { + name(display: PiritaFilesystemNameDisplay): String! +} + +type Collection { + slug: String! + displayName: String! + description: String! + createdAt: DateTime! + banner: String! + packages( + before: String + after: String + first: Int + last: Int + ): PackageConnection! +} + +type PackageCollaboratorConnection { """ Pagination data for this connection. """ @@ -925,17 +1170,17 @@ type NamespaceConnection { """ Contains the nodes in this connection. """ - edges: [NamespaceEdge]! + edges: [PackageCollaboratorEdge]! } """ -A Relay edge containing a `Namespace` and its cursor. +A Relay edge containing a `PackageCollaborator` and its cursor. """ -type NamespaceEdge { +type PackageCollaboratorEdge { """ The item at the end of the edge """ - node: Namespace + node: PackageCollaborator """ A cursor for use in pagination @@ -943,18 +1188,72 @@ type NamespaceEdge { cursor: String! } -type NativeExecutable implements Node { +type PackageCollaborator implements Node { """ The ID of the object """ id: ID! - module: String! @deprecated(reason: "Use filename instead") - filename: String! - targetTriple: String! - downloadUrl: String! + user: User! + role: RegistryPackageMaintainerRoleChoices! + package: Package! + createdAt: DateTime! + updatedAt: DateTime! + invite: PackageCollaboratorInvite } -type NativeExecutableConnection { +enum RegistryPackageMaintainerRoleChoices { + """ + Admin + """ + ADMIN + + """ + Editor + """ + EDITOR + + """ + Viewer + """ + VIEWER +} + +type PackageCollaboratorInvite implements Node { + """ + The ID of the object + """ + id: ID! + requestedBy: User! + user: User + inviteEmail: String + package: Package! + role: RegistryPackageMaintainerInviteRoleChoices! + accepted: PackageCollaborator + approvedBy: User + declinedBy: User + createdAt: DateTime! + expiresAt: DateTime! + closedAt: DateTime +} + +enum RegistryPackageMaintainerInviteRoleChoices { + """ + Admin + """ + ADMIN + + """ + Editor + """ + EDITOR + + """ + Viewer + """ + VIEWER +} + +type PackageCollaboratorInviteConnection { """ Pagination data for this connection. """ @@ -963,17 +1262,17 @@ type NativeExecutableConnection { """ Contains the nodes in this connection. """ - edges: [NativeExecutableEdge]! + edges: [PackageCollaboratorInviteEdge]! } """ -A Relay edge containing a `NativeExecutable` and its cursor. +A Relay edge containing a `PackageCollaboratorInvite` and its cursor. """ -type NativeExecutableEdge { +type PackageCollaboratorInviteEdge { """ The item at the end of the edge """ - node: NativeExecutable + node: PackageCollaboratorInvite """ A cursor for use in pagination @@ -981,121 +1280,142 @@ type NativeExecutableEdge { cursor: String! } -interface Node { +enum GrapheneRole { + ADMIN + EDITOR + VIEWER +} + +type PackageTransferRequest implements Node { """ The ID of the object """ id: ID! + requestedBy: User! + previousOwnerObjectId: Int! + newOwnerObjectId: Int! + package: Package! + approvedBy: User + declinedBy: User + createdAt: DateTime! + expiresAt: DateTime! + closedAt: DateTime + previousOwner: PackageOwner! + newOwner: PackageOwner! } -type NodeBodyRange { - entity: Node! - offset: Int! - length: Int! -} - -input ObtainJSONWebTokenInput { - clientMutationId: String - username: String! - password: String! -} - -type ObtainJSONWebTokenPayload { - payload: GenericScalar! - refreshExpiresIn: Int! - username: String! - clientMutationId: String - token: String! - refreshToken: String! -} - -interface Owner { - globalName: String! -} - -type Package implements Likeable & Node & PackageOwner { +type DeployAppConnection { """ - The ID of the object + Pagination data for this connection. """ - id: ID! - name: String! - namespace: String - private: Boolean! - createdAt: DateTime! - updatedAt: DateTime! - maintainers: [User]! @deprecated(reason: "Please use collaborators instead") - curated: Boolean! - ownerObjectId: Int! - lastVersion: PackageVersion + pageInfo: PageInfo! """ - The app icon. It should be formatted in the same way as Apple icons + Contains the nodes in this connection. """ - icon: String! - totalDownloads: Int! - iconUpdatedAt: DateTime - watchersCount: Int! - versions: [PackageVersion]! - collectionSet: [Collection!]! - likersCount: Int! - viewerHasLiked: Boolean! - globalName: String! - alias: String - displayName: String! + edges: [DeployAppEdge]! """ - The name of the package without the owner + Total number of items in the connection. """ - packageName: String! + totalCount: Int +} +""" +A Relay edge containing a `DeployApp` and its cursor. +""" +type DeployAppEdge { """ - The app icon. It should be formatted in the same way as Apple icons + The item at the end of the edge """ - appIcon: String! @deprecated(reason: "Please use icon instead") + node: DeployApp """ - The total number of downloads of the package + A cursor for use in pagination """ - downloadsCount: Int + cursor: String! +} +type DeployApp implements Node & Owner { """ - The public keys for all the published versions + The ID of the object """ - publicKeys: [PublicKey!]! - collaborators( + id: ID! + createdBy: User! + createdAt: DateTime! + updatedAt: DateTime! + activeVersion: DeployAppVersion! + globalName: String! + url: String! + adminUrl: String! + permalink: String! + urls: [String]! + description: String + name: String! + owner: Owner! + versions( + sortBy: DeployAppVersionsSortBy + createdAfter: DateTime + offset: Int before: String after: String first: Int last: Int - ): PackageCollaboratorConnection! - pendingInvites( + ): DeployAppVersionConnection! + aggregateMetrics: AggregateMetrics! + aliases( + offset: Int before: String after: String first: Int last: Int - ): PackageCollaboratorInviteConnection! - viewerHasRole(role: GrapheneRole!): Boolean! - owner: PackageOwner! - isTransferring: Boolean! - activeTransferRequest: PackageTransferRequest - isArchived: Boolean! - viewerIsWatching: Boolean! + ): AppAliasConnection! + usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]! } -type PackageCollaborator implements Node { +type DeployAppVersion implements Node { """ The ID of the object """ id: ID! - user: User! - role: RegistryPackageMaintainerRoleChoices! - package: Package! + app: DeployApp! + yamlConfig: String! + userYamlConfig: String! + signature: String + description: String + publishedBy: User! createdAt: DateTime! - updatedAt: DateTime! - invite: PackageCollaboratorInvite + configWebc: String + @deprecated(reason: "webc support has been deprecated for apps") + config: String! @deprecated(reason: "Please use jsonConfig instead") + jsonConfig: String! + url: String! + permalink: String! + urls: [String]! + version: String! + isActive: Boolean! + manifest: String! + logs( + """ + Get logs starting from this timestamp. Takes EPOCH timestamp in seconds. + """ + startingFrom: Float! + + """ + Fetch logs until this timestamp. Takes EPOCH timestamp in seconds. + """ + until: Float + before: String + after: String + first: Int + last: Int + ): LogConnection! + usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]! + sourcePackageVersion: PackageVersion! + aggregateMetrics: AggregateMetrics! } -type PackageCollaboratorConnection { +type LogConnection { """ Pagination data for this connection. """ @@ -1104,17 +1424,17 @@ type PackageCollaboratorConnection { """ Contains the nodes in this connection. """ - edges: [PackageCollaboratorEdge]! + edges: [LogEdge]! } """ -A Relay edge containing a `PackageCollaborator` and its cursor. +A Relay edge containing a `Log` and its cursor. """ -type PackageCollaboratorEdge { +type LogEdge { """ The item at the end of the edge """ - node: PackageCollaborator + node: Log """ A cursor for use in pagination @@ -1122,52 +1442,67 @@ type PackageCollaboratorEdge { cursor: String! } -type PackageCollaboratorInvite implements Node { +type UsageMetric { + variant: MetricType! + value: Float! + unit: MetricUnit! + timestamp: DateTime! +} + +enum MetricType { + cpu_time + memory_time + network_egress + network_ingress + no_of_requests + cost +} + +""" +Units for metrics +""" +enum MetricUnit { """ - The ID of the object + represents the unit of "seconds". """ - id: ID! - requestedBy: User! - user: User - inviteEmail: String - package: Package! - role: RegistryPackageMaintainerInviteRoleChoices! - accepted: PackageCollaborator - approvedBy: User - declinedBy: User - createdAt: DateTime! - expiresAt: DateTime! - closedAt: DateTime -} + SEC -type PackageCollaboratorInviteConnection { """ - Pagination data for this connection. + represents the unit of "kilobytes". """ - pageInfo: PageInfo! + KB """ - Contains the nodes in this connection. + represents the unit of "kilobytes per second". """ - edges: [PackageCollaboratorInviteEdge]! -} + KBS -""" -A Relay edge containing a `PackageCollaboratorInvite` and its cursor. -""" -type PackageCollaboratorInviteEdge { """ - The item at the end of the edge + represents the unit of "number of requests". """ - node: PackageCollaboratorInvite + NO_REQUESTS """ - A cursor for use in pagination + represents the unit of "cost" in USD. """ - cursor: String! + DOLLARS } -type PackageConnection { +enum MetricRange { + LAST_24_HOURS + LAST_30_DAYS +} + +type AggregateMetrics { + cpuTime: String! + memoryTime: String! + ingress: String! + egress: String! + noRequests: String! + monthlyCost: String! +} + +type DeployAppVersionConnection { """ Pagination data for this connection. """ @@ -1176,24 +1511,22 @@ type PackageConnection { """ Contains the nodes in this connection. """ - edges: [PackageEdge]! -} + edges: [DeployAppVersionEdge]! -type PackageDistribution { - downloadUrl: String! - size: Int! - piritaDownloadUrl: String - piritaSize: Int! + """ + Total number of items in the connection. + """ + totalCount: Int } """ -A Relay edge containing a `Package` and its cursor. +A Relay edge containing a `DeployAppVersion` and its cursor. """ -type PackageEdge { +type DeployAppVersionEdge { """ The item at the end of the edge """ - node: Package + node: DeployAppVersion """ A cursor for use in pagination @@ -1201,32 +1534,12 @@ type PackageEdge { cursor: String! } -""" -Setup for backwards compatibility with existing frontends. -""" -interface PackageOwner { - globalName: String! -} - -type PackageTransferRequest implements Node { - """ - The ID of the object - """ - id: ID! - requestedBy: User! - previousOwnerObjectId: Int! - newOwnerObjectId: Int! - package: Package! - approvedBy: User - declinedBy: User - createdAt: DateTime! - expiresAt: DateTime! - closedAt: DateTime - previousOwner: PackageOwner! - newOwner: PackageOwner! +enum DeployAppVersionsSortBy { + NEWEST + OLDEST } -type PackageTransferRequestConnection { +type AppAliasConnection { """ Pagination data for this connection. """ @@ -1235,17 +1548,22 @@ type PackageTransferRequestConnection { """ Contains the nodes in this connection. """ - edges: [PackageTransferRequestEdge]! + edges: [AppAliasEdge]! + + """ + Total number of items in the connection. + """ + totalCount: Int } """ -A Relay edge containing a `PackageTransferRequest` and its cursor. +A Relay edge containing a `AppAlias` and its cursor. """ -type PackageTransferRequestEdge { +type AppAliasEdge { """ The item at the end of the edge """ - node: PackageTransferRequest + node: AppAlias """ A cursor for use in pagination @@ -1253,97 +1571,72 @@ type PackageTransferRequestEdge { cursor: String! } -type PackageVersion implements Node { +type AppAlias implements Node { + name: String! + app: DeployConfigInfo! + isDefault: Boolean! + """ The ID of the object """ id: ID! - package: Package! - version: String! - description: String! - manifest: String! - license: String - licenseFile: String - readme: String - witMd: String - repository: String - homepage: String + url: String! +} + +type DeployConfigInfo implements Node { + """ + The ID of the object + """ + id: ID! + createdBy: User! createdAt: DateTime! updatedAt: DateTime! - staticObjectsCompiled: Boolean! - nativeExecutablesCompiled: Boolean! - publishedBy: User! - signature: Signature - isArchived: Boolean! - file: String! + versions: [DeployConfigVersion] + publishedBy: User + namespace: String! + name: String! +} + +type DeployConfigVersion implements Node { + """ + The ID of the object + """ + id: ID! + signature: String + description: String + createdAt: DateTime! + + """ + """ + versionNumber: BigInt! + updatedAt: DateTime! + webcUrl: String! + @deprecated( + reason: "webc support for apps has been deprecated. Use DeployAppVersion.yamlConfig directly." + ) fileSize: BigInt! - piritaFile: String - piritaFileSize: BigInt! - piritaManifest: JSONString - piritaVolumes: JSONString - totalDownloads: Int! - pirita256hash: String - bindingsState: RegistryPackageVersionBindingsStateChoices! - nativeExecutablesState: RegistryPackageVersionNativeExecutablesStateChoices! - lastversionPackage( - offset: Int - before: String - after: String - first: Int - last: Int - ): PackageConnection! - commands: [Command!]! - nativeexecutableSet( - offset: Int - before: String - after: String - first: Int - last: Int - ): NativeExecutableConnection! - bindingsgeneratorSet( - offset: Int - before: String - after: String - first: Int - last: Int - ): BindingsGeneratorConnection! - javascriptlanguagebindingSet( - offset: Int - before: String - after: String - first: Int - last: Int - ): PackageVersionNPMBindingConnection! - pythonlanguagebindingSet( - offset: Int - before: String - after: String - first: Int - last: Int - ): PackageVersionPythonBindingConnection! - distribution: PackageDistribution! - filesystem: [PackageVersionFilesystem]! - isLastVersion: Boolean! - witFile: String - isSigned: Boolean! - moduleInterfaces: [InterfaceVersion!]! - modules: [PackageVersionModule!]! - getPiritaContents( - volume: String! = "atom" - root: String! = "" - ): [PiritaFilesystemItem!]! - nativeExecutables( - triple: String - wasmerCompilerVersion: String - ): [NativeExecutable] - bindings: [PackageVersionLanguageBinding]! - npmBindings: PackageVersionNPMBinding - pythonBindings: PackageVersionPythonBinding - hasBindings: Boolean! - hasCommands: Boolean! + @deprecated( + reason: "webc support for apps has been deprecated. Use DeployAppVersion.yamlConfig directly." + ) + fileOffset: BigInt! + @deprecated( + reason: "webc support for apps has been deprecated. Use DeployAppVersion.yamlConfig directly." + ) + config: String! + manifest: String + @deprecated( + reason: "webc support for apps as been deprecated. use DeployAppVersion.yamlConfig directly." + ) + info: DeployConfigInfo } -type PackageVersionConnection { +enum DeployAppsSortBy { + NEWEST + OLDEST + MOST_ACTIVE +} + +type NamespaceCollaboratorConnection { """ Pagination data for this connection. """ @@ -1352,17 +1645,17 @@ type PackageVersionConnection { """ Contains the nodes in this connection. """ - edges: [PackageVersionEdge]! + edges: [NamespaceCollaboratorEdge]! } """ -A Relay edge containing a `PackageVersion` and its cursor. +A Relay edge containing a `NamespaceCollaborator` and its cursor. """ -type PackageVersionEdge { +type NamespaceCollaboratorEdge { """ The item at the end of the edge """ - node: PackageVersion + node: NamespaceCollaborator """ A cursor for use in pagination @@ -1370,98 +1663,124 @@ type PackageVersionEdge { cursor: String! } -type PackageVersionFilesystem { - wasm: String! - host: String! +type PackageTransferRequestConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + + """ + Contains the nodes in this connection. + """ + edges: [PackageTransferRequestEdge]! } -interface PackageVersionLanguageBinding { - id: ID! - language: ProgrammingLanguage! +""" +A Relay edge containing a `PackageTransferRequest` and its cursor. +""" +type PackageTransferRequestEdge { + """ + The item at the end of the edge + """ + node: PackageTransferRequest """ - The URL of the generated artifacts on WAPM's CDN. + A cursor for use in pagination """ - url: String! + cursor: String! +} +type APITokenConnection { """ - When the binding was generated + Pagination data for this connection. """ - createdAt: DateTime! + pageInfo: PageInfo! """ - Package version used to generate this binding + Contains the nodes in this connection. """ - generator: BindingsGenerator! - name: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) - kind: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) + edges: [APITokenEdge]! +} +""" +A Relay edge containing a `APIToken` and its cursor. +""" +type APITokenEdge { """ - Name of package source + The item at the end of the edge """ - packageName: String! - module: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) + node: APIToken + + """ + A cursor for use in pagination + """ + cursor: String! } -type PackageVersionModule { - name: String! - source: String! - abi: String - publicUrl: String! +type APIToken { + id: ID! + user: User! + identifier: String + createdAt: DateTime! + revokedAt: DateTime + lastUsedAt: DateTime + nonceSet( + offset: Int + before: String + after: String + first: Int + last: Int + ): NonceConnection! } -type PackageVersionNPMBinding implements PackageVersionLanguageBinding & Node { +type NonceConnection { """ - The ID of the object + Pagination data for this connection. """ - id: ID! - language: ProgrammingLanguage! + pageInfo: PageInfo! """ - The URL of the generated artifacts on WAPM's CDN. + Contains the nodes in this connection. """ - url: String! + edges: [NonceEdge]! """ - When the binding was generated + Total number of items in the connection. """ - createdAt: DateTime! + totalCount: Int +} +""" +A Relay edge containing a `Nonce` and its cursor. +""" +type NonceEdge { """ - Package version used to generate this binding + The item at the end of the edge """ - generator: BindingsGenerator! - name: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) - kind: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) + node: Nonce """ - Name of package source + A cursor for use in pagination """ - packageName: String! - module: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) - npmDefaultInstallPackageName(url: String): String! - @deprecated(reason: "Please use packageName instead") + cursor: String! } -type PackageVersionNPMBindingConnection { +type Nonce implements Node { + """ + The ID of the object + """ + id: ID! + name: String! + callbackUrl: String! + createdAt: DateTime! + isValidated: Boolean! + secret: String! + token: String! + expired: Boolean! + authUrl: String! +} + +type UserNotificationConnection { """ Pagination data for this connection. """ @@ -1470,17 +1789,18 @@ type PackageVersionNPMBindingConnection { """ Contains the nodes in this connection. """ - edges: [PackageVersionNPMBindingEdge]! + edges: [UserNotificationEdge]! + hasPendingNotifications: Boolean! } """ -A Relay edge containing a `PackageVersionNPMBinding` and its cursor. +A Relay edge containing a `UserNotification` and its cursor. """ -type PackageVersionNPMBindingEdge { +type UserNotificationEdge { """ The item at the end of the edge """ - node: PackageVersionNPMBinding + node: UserNotification """ A cursor for use in pagination @@ -1488,198 +1808,301 @@ type PackageVersionNPMBindingEdge { cursor: String! } -type PackageVersionPythonBinding implements PackageVersionLanguageBinding & Node { +type UserNotification implements Node { """ The ID of the object """ id: ID! - language: ProgrammingLanguage! + icon: String + body: UserNotificationBody! + seenState: UserNotificationSeenState! + kind: UserNotificationKind + createdAt: DateTime! +} - """ - The URL of the generated artifacts on WAPM's CDN. - """ - url: String! +type UserNotificationBody { + text: String! + ranges: [NodeBodyRange]! +} + +enum UserNotificationSeenState { + UNSEEN + SEEN + SEEN_AND_READ +} + +union UserNotificationKind = + UserNotificationKindPublishedPackageVersion + | UserNotificationKindIncomingPackageTransfer + | UserNotificationKindIncomingPackageInvite + | UserNotificationKindIncomingNamespaceInvite + +type UserNotificationKindPublishedPackageVersion { + packageVersion: PackageVersion! +} + +type UserNotificationKindIncomingNamespaceInvite { + namespaceInvite: NamespaceCollaboratorInvite! +} + +type Signature { + id: ID! + publicKey: PublicKey! + data: String! + createdAt: DateTime! +} + +type UserNotificationKindIncomingPackageTransfer { + packageTransferRequest: PackageTransferRequest! +} + +type UserNotificationKindIncomingPackageInvite { + packageInvite: PackageCollaboratorInvite! +} + +input DeploymentV1 { + name: String! + workload: WorkloadV1! +} + +input WorkloadV1 { + capability: CapabilityMapV1 + name: String = null + runner: WorkloadRunnerV1! +} + +input AppV1Spec { + aliases: [String] = [] + workload: WorkloadV2! +} + +input WorkloadV2 { + source: String! +} + +input CapabilityCpuV1 { + maximumThreads: Int + maximumUsage: Int +} + +input FileSystemPermissionsV1 { + delete: Boolean + read: Boolean + write: Boolean +} + +input FileSystemVolumeMountV1 { + path: String! + permissions: [FileSystemPermissionsV1] +} + +input FileSystemVolumeSourceLocalV1 { + maximumSize: String! +} + +input FileSystemVolumeSourceV1 { + local: FileSystemVolumeSourceLocalV1! +} + +input FileSystemVolumeConfigV1 { + mounts: [FileSystemVolumeMountV1]! + name: String! + source: FileSystemVolumeSourceV1! +} + +input CapabilityFileSystemV1 { + volumes: [FileSystemVolumeConfigV1]! +} + +input CapabilityPersistentMemoryV1 { + volumes: [String] +} + +input CapabilityMemorySwapV1 { + maximumSize: String + memoryId: String +} + +input CapabilityNetworkV1 { + egress: NetworkEgressV1 +} + +input NetworkEgressV1 { + enabled: Boolean +} + +input CapabilityNetworkDnsV1 { + enabled: Boolean + servers: [String] + allowedHosts: NetworkDnsAllowedHostsV1 +} + +input NetworkDnsAllowedHostsV1 { + allowAllHosts: Boolean + hosts: [String] + regexPatterns: [String] + wildcardPatterns: [String] +} + +input CapabilityNetworkGatewayV1 { + domains: [String] + enforceHttps: Boolean +} + +input CapabilityMapV1 { + memorySwap: CapabilityCpuV1 +} + +input WebcSourceV1 { + name: String! + namespace: String! + repository: String! = "https://registry.wasmer.wtf" + tag: String + authToken: String +} + +input WorkloadRunnerV1 { + webProxy: RunnerWebProxyV1 + wcgi: RunnerWCGIV1 +} + +""" +Run a webassembly file. +""" +input RunnerWCGIV1 { + source: WorkloadRunnerWasmSourceV1! + dialect: String +} + +input RunnerWebProxyV1 { + source: WorkloadRunnerWasmSourceV1! +} + +input WorkloadRunnerWasmSourceV1 { + webc: WebcSourceV1! +} + +type StripeCustomer { + id: ID! +} + +type Billing { + stripeCustomer: StripeCustomer! + payments: [PaymentIntent]! + paymentMethods: [PaymentMethod]! +} +type PaymentIntent implements Node { """ - When the binding was generated + Three-letter ISO currency code """ - createdAt: DateTime! + currency: String! """ - Package version used to generate this binding + Status of this PaymentIntent, one of requires_payment_method, requires_confirmation, requires_action, processing, requires_capture, canceled, or succeeded. You can read more about PaymentIntent statuses here. """ - generator: BindingsGenerator! - name: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) - kind: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) + status: DjstripePaymentIntentStatusChoices! """ - Name of package source + The ID of the object """ - packageName: String! - module: String! - @deprecated( - reason: "Do not use this field, since bindings for all modules are generated at once now." - ) - pythonDefaultInstallPackageName(url: String): String! + id: ID! + amount: String! } -type PackageVersionPythonBindingConnection { - """ - Pagination data for this connection. - """ - pageInfo: PageInfo! - +enum DjstripePaymentIntentStatusChoices { """ - Contains the nodes in this connection. + Cancellation invalidates the intent for future confirmation and cannot be undone. """ - edges: [PackageVersionPythonBindingEdge]! -} + CANCELED -""" -A Relay edge containing a `PackageVersionPythonBinding` and its cursor. -""" -type PackageVersionPythonBindingEdge { """ - The item at the end of the edge + Required actions have been handled. """ - node: PackageVersionPythonBinding + PROCESSING """ - A cursor for use in pagination + Payment Method require additional action, such as 3D secure. """ - cursor: String! -} + REQUIRES_ACTION -""" -The Relay compliant `PageInfo` type, containing data necessary to paginate this connection. -""" -type PageInfo { """ - When paginating forwards, are there more items? + Capture the funds on the cards which have been put on holds. """ - hasNextPage: Boolean! + REQUIRES_CAPTURE """ - When paginating backwards, are there more items? + Intent is ready to be confirmed. """ - hasPreviousPage: Boolean! + REQUIRES_CONFIRMATION """ - When paginating backwards, the cursor to continue. + Intent created and requires a Payment Method to be attached. """ - startCursor: String + REQUIRES_PAYMENT_METHOD """ - When paginating forwards, the cursor to continue. + The funds are in your account. """ - endCursor: String -} - -type PiritaFilesystemDir { - name(display: PiritaFilesystemNameDisplay): String! -} - -type PiritaFilesystemFile { - name(display: PiritaFilesystemNameDisplay): String! - size: Int! - offset: Int! -} - -union PiritaFilesystemItem = PiritaFilesystemFile | PiritaFilesystemDir - -enum PiritaFilesystemNameDisplay { - RELATIVE - ABSOLUTE + SUCCEEDED } -enum ProgrammingLanguage { - PYTHON - JAVASCRIPT -} +union PaymentMethod = CardPaymentMethod -type PublicKey implements Node { +type CardPaymentMethod implements Node { """ The ID of the object """ id: ID! - owner: User! - keyId: String! - key: String! - revokedAt: DateTime - uploadedAt: DateTime! - verifyingSignature: Signature - revoked: Boolean! -} - -input PublishDeployAppInput { - config: JSONString! - name: ID - owner: ID - description: String - clientMutationId: String + brand: CardBrand! + country: String! + expMonth: Int! + expYear: Int! + funding: CardFunding! + last4: String! + isDefault: Boolean! } -type PublishDeployAppPayload { - deployAppVersion: DeployAppVersion! - clientMutationId: String -} - -input PublishDeployConfigInput { - content: String! - name: ID - description: String - clientMutationId: String -} +""" +Card brand. -type PublishDeployConfigPayload { - deployConfigVersion: DeployConfigVersion! - clientMutationId: String +Can be amex, diners, discover, jcb, mastercard, unionpay, visa, or unknown. +""" +enum CardBrand { + AMEX + DINERS + DISCOVER + JCB + MASTERCARD + UNIONPAY + VISA + UNKNOWN } -input PublishPackageInput { - name: String! - version: String! - description: String! - manifest: String! - license: String - licenseFile: String - readme: String - repository: String - homepage: String - file: String - signedUrl: String - signature: InputSignature - - """ - The package icon - """ - icon: String - clientMutationId: String -} +""" +Card funding type. -type PublishPackagePayload { - success: Boolean! - packageVersion: PackageVersion! - clientMutationId: String +Can be credit, debit, prepaid, or unknown. +""" +enum CardFunding { + CREDIT + DEBIT + PREPAID + UNKNOWN } -input PublishPublicKeyInput { - keyId: String! - key: String! - verifyingSignatureId: String - clientMutationId: String +type Payment { + id: ID + amount: String + paidOn: DateTime } -type PublishPublicKeyPayload { - success: Boolean! - publicKey: PublicKey! - clientMutationId: String +""" +Log entry for deploy app. +""" +type Log { + timestamp: Float! + message: String! } type Query { @@ -1716,9 +2139,20 @@ type Query { version: String ): DeployAppVersion getDeployApp(name: String!, owner: String!): DeployApp + getAppByGlobalAlias(alias: String!): DeployApp + getDeployApps( + sortBy: DeployAppsSortBy + updatedAfter: DateTime + offset: Int + before: String + after: String + first: Int + last: Int + ): DeployAppConnection! viewer: User getUser(username: String!): User getPasswordResetToken(token: String!): GetPasswordResetToken + getAuthNonce(name: String!): Nonce packages( before: String after: String @@ -1794,209 +2228,537 @@ type Query { """ id: ID! ): Node + info: RegistryInfo } -input ReadNotificationInput { - notificationId: ID! - clientMutationId: String +type GetPasswordResetToken { + valid: Boolean! + user: User } -type ReadNotificationPayload { - notification: UserNotification - clientMutationId: String -} +type CollectionConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! -type Refresh { - payload: GenericScalar! - refreshExpiresIn: Int! - token: String! - refreshToken: String! + """ + Contains the nodes in this connection. + """ + edges: [CollectionEdge]! } -input RegisterUserInput { - fullName: String! - email: String! - username: String! - password: String! - clientMutationId: String +""" +A Relay edge containing a `Collection` and its cursor. +""" +type CollectionEdge { + """ + The item at the end of the edge + """ + node: Collection + + """ + A cursor for use in pagination + """ + cursor: String! } -type RegisterUserPayload { - token: String - clientMutationId: String +type SignedUrl { + url: String! } -enum RegistryNamespaceMaintainerInviteRoleChoices { +type SearchConnection { """ - Admin + Pagination data for this connection. """ - ADMIN + pageInfo: PageInfo! """ - Editor + Contains the nodes in this connection. """ - EDITOR + edges: [SearchEdge]! +} + +""" +A Relay edge containing a `Search` and its cursor. +""" +type SearchEdge { + """ + The item at the end of the edge + """ + node: SearchResult """ - Viewer + A cursor for use in pagination """ - VIEWER + cursor: String! } -enum RegistryNamespaceMaintainerRoleChoices { +union SearchResult = PackageVersion | User | Namespace + +enum SearchOrderBy { + ALPHABETICALLY + SIZE + TOTAL_DOWNLOADS + PUBLISHED_DATE +} + +enum SearchOrderSort { + ASC + DESC +} + +enum SearchKind { + PACKAGE + NAMESPACE + USER +} + +enum SearchPublishDate { + LAST_DAY + LAST_WEEK + LAST_MONTH + LAST_YEAR +} + +union GlobalObject = User | Namespace + +type RegistryInfo { """ - Admin + Base URL for this registry + """ + baseUrl: String! + + """ + Base URL for the default frontend + """ + defaultFrontend: String! + + """ + URL to the graphql endpoint """ - ADMIN + graphqlUrl: String! """ - Editor + Public metadata about packages """ - EDITOR + packages: PackageInfo! """ - Viewer + Public metadata about the graphql schema """ - VIEWER + schema: SchemaInfo! } -enum RegistryPackageMaintainerInviteRoleChoices { +type PackageInfo { """ - Admin + Number of package versions published this month """ - ADMIN + versionsPublishedThisMonth: Int! """ - Editor + Number of new packages published this month """ - EDITOR + newPackagesThisMonth: Int! """ - Viewer + Number of package downloads this month """ - VIEWER + packageDownloadsThisMonth: Int! } -enum RegistryPackageMaintainerRoleChoices { +type SchemaInfo { """ - Admin + Download link for graphql schema """ - ADMIN + downloadUrl: String! """ - Editor + SHA256 hash of the schema data """ - EDITOR + SHA256Hash: String! """ - Viewer + Timestamp when the schema was last updated """ - VIEWER + lastUpdated: DateTime! } -enum RegistryPackageVersionBindingsStateChoices { - """ - Bindings are not detected - """ - NOT_PRESENT +type Mutation { + publishDeployConfig( + input: PublishDeployConfigInput! + ): PublishDeployConfigPayload + @deprecated(reason: "Please use publishDeployApp instead.") + publishDeployApp(input: PublishDeployAppInput!): PublishDeployAppPayload """ - Bindings are being built + Add current user to the waitlist. """ - GENERATING + joinWaitlist(input: JoinWaitlistInput!): JoinWaitlistPayload """ - Bindings generation has failed + Add stripe payment to the user """ - ERROR + addPayment(input: AddPaymentInput!): AddPaymentPayload """ - Bindings are built and present + Mutation to change the active version of a DeployApp to another DeployAppVersion. """ - GENERATED_AND_PRESENT -} + markAppVersionAsActive( + input: MarkAppVersionAsActiveInput! + ): MarkAppVersionAsActivePayload -enum RegistryPackageVersionNativeExecutablesStateChoices { """ - Native Executables are not detected + Set a payment method as default for the user. """ - NOT_PRESENT + makePaymentDefault( + input: SetDefaultPaymentMethodInput! + ): SetDefaultPaymentMethodPayload """ - Native Executables are being built + Try to detach a payment method from customer. + Fails if trying to detach a default method, + or if it's the only payment method. """ - GENERATING + detachPaymentMethod( + input: DetachPaymentMethodInput! + ): DetachPaymentMethodPayload + generateDeployConfigToken( + input: GenerateDeployConfigTokenInput! + ): GenerateDeployConfigTokenPayload + tokenAuth(input: ObtainJSONWebTokenInput!): ObtainJSONWebTokenPayload + generateDeployToken( + input: GenerateDeployTokenInput! + ): GenerateDeployTokenPayload + verifyAccessToken(token: String): Verify + refreshAccessToken(refreshToken: String): Refresh + revokeAccessToken(refreshToken: String): Revoke + registerUser(input: RegisterUserInput!): RegisterUserPayload + socialAuth(input: SocialAuthJWTInput!): SocialAuthJWTPayload + validateUserEmail(input: ValidateUserEmailInput!): ValidateUserEmailPayload + requestPasswordReset( + input: RequestPasswordResetInput! + ): RequestPasswordResetPayload + requestValidationEmail( + input: RequestValidationEmailInput! + ): RequestValidationEmailPayload + changeUserPassword(input: ChangeUserPasswordInput!): ChangeUserPasswordPayload + changeUserUsername(input: ChangeUserUsernameInput!): ChangeUserUsernamePayload + changeUserEmail(input: ChangeUserEmailInput!): ChangeUserEmailPayload + updateUserInfo(input: UpdateUserInfoInput!): UpdateUserInfoPayload + validateUserPassword( + input: ValidateUserPasswordInput! + ): ValidateUserPasswordPayload + generateApiToken(input: GenerateAPITokenInput!): GenerateAPITokenPayload + revokeApiToken(input: RevokeAPITokenInput!): RevokeAPITokenPayload + checkUserExists(input: CheckUserExistsInput!): CheckUserExistsPayload + readNotification(input: ReadNotificationInput!): ReadNotificationPayload + seePendingNotifications( + input: SeePendingNotificationsInput! + ): SeePendingNotificationsPayload + newNonce(input: NewNonceInput!): NewNoncePayload + validateNonce(input: ValidateNonceInput!): ValidateNoncePayload + publishPublicKey(input: PublishPublicKeyInput!): PublishPublicKeyPayload + publishPackage(input: PublishPackageInput!): PublishPackagePayload + updatePackage(input: UpdatePackageInput!): UpdatePackagePayload + likePackage(input: LikePackageInput!): LikePackagePayload + unlikePackage(input: UnlikePackageInput!): UnlikePackagePayload + watchPackage(input: WatchPackageInput!): WatchPackagePayload + unwatchPackage(input: UnwatchPackageInput!): UnwatchPackagePayload + archivePackage(input: ArchivePackageInput!): ArchivePackagePayload + changePackageVersionArchivedStatus( + input: ChangePackageVersionArchivedStatusInput! + ): ChangePackageVersionArchivedStatusPayload + createNamespace(input: CreateNamespaceInput!): CreateNamespacePayload + updateNamespace(input: UpdateNamespaceInput!): UpdateNamespacePayload + deleteNamespace(input: DeleteNamespaceInput!): DeleteNamespacePayload + inviteNamespaceCollaborator( + input: InviteNamespaceCollaboratorInput! + ): InviteNamespaceCollaboratorPayload + acceptNamespaceCollaboratorInvite( + input: AcceptNamespaceCollaboratorInviteInput! + ): AcceptNamespaceCollaboratorInvitePayload + removeNamespaceCollaboratorInvite( + input: RemoveNamespaceCollaboratorInviteInput! + ): RemoveNamespaceCollaboratorInvitePayload + removeNamespaceCollaborator( + input: RemoveNamespaceCollaboratorInput! + ): RemoveNamespaceCollaboratorPayload + updateNamespaceCollaboratorRole( + input: UpdateNamespaceCollaboratorRoleInput! + ): UpdateNamespaceCollaboratorRolePayload + updateNamespaceCollaboratorInviteRole( + input: UpdateNamespaceCollaboratorInviteRoleInput! + ): UpdateNamespaceCollaboratorInviteRolePayload + invitePackageCollaborator( + input: InvitePackageCollaboratorInput! + ): InvitePackageCollaboratorPayload + acceptPackageCollaboratorInvite( + input: AcceptPackageCollaboratorInviteInput! + ): AcceptPackageCollaboratorInvitePayload + removePackageCollaboratorInvite( + input: RemovePackageCollaboratorInviteInput! + ): RemovePackageCollaboratorInvitePayload + updatePackageCollaboratorRole( + input: UpdatePackageCollaboratorRoleInput! + ): UpdatePackageCollaboratorRolePayload + updatePackageCollaboratorInviteRole( + input: UpdatePackageCollaboratorInviteRoleInput! + ): UpdatePackageCollaboratorInviteRolePayload + removePackageCollaborator( + input: RemovePackageCollaboratorInput! + ): RemovePackageCollaboratorPayload + requestPackageTransfer( + input: RequestPackageTransferInput! + ): RequestPackageTransferPayload + acceptPackageTransferRequest( + input: AcceptPackageTransferRequestInput! + ): AcceptPackageTransferRequestPayload + removePackageTransferRequest( + input: RemovePackageTransferRequestInput! + ): RemovePackageTransferRequestPayload + generateBindingsForAllPackages( + input: GenerateBindingsForAllPackagesInput! + ): GenerateBindingsForAllPackagesPayload +} - """ - Native Executables generation has failed - """ - ERROR +type PublishDeployConfigPayload { + deployConfigVersion: DeployConfigVersion! + clientMutationId: String +} + +input PublishDeployConfigInput { + content: String! + name: ID + description: String + clientMutationId: String +} + +type PublishDeployAppPayload { + deployAppVersion: DeployAppVersion! + clientMutationId: String +} + +input PublishDeployAppInput { + config: Configuration! + name: ID + owner: ID + description: String + makeDefault: Boolean = true + clientMutationId: String +} + +input Configuration { + deployment: AppV0 + yamlConfig: String +} + +input AppV0 { + kind: String = "wasmer.io/App.v0" + appId: ID + name: String! + description: String + package: String! +} + +""" +Add current user to the waitlist. +""" +type JoinWaitlistPayload { + waitlistMember: WaitlistMember! + clientMutationId: String +} + +input JoinWaitlistInput { + name: String! + clientMutationId: String +} + +""" +Add stripe payment to the user +""" +type AddPaymentPayload { + customerSecret: String! + clientMutationId: String +} + +input AddPaymentInput { + clientMutationId: String +} + +""" +Mutation to change the active version of a DeployApp to another DeployAppVersion. +""" +type MarkAppVersionAsActivePayload { + app: DeployApp! + clientMutationId: String +} +input MarkAppVersionAsActiveInput { """ - Native Executables are built and present + The ID of the DeployAppVersion to set as the new active version. """ - GENERATED_AND_PRESENT + appVersion: ID! + clientMutationId: String +} + +""" +Set a payment method as default for the user. +""" +type SetDefaultPaymentMethodPayload { + success: Boolean! + billing: Billing! + clientMutationId: String +} + +input SetDefaultPaymentMethodInput { + paymentMethod: ID! + clientMutationId: String +} + +""" +Try to detach a payment method from customer. +Fails if trying to detach a default method, +or if it's the only payment method. +""" +type DetachPaymentMethodPayload { + success: Boolean! + billing: Billing! + clientMutationId: String +} + +input DetachPaymentMethodInput { + paymentMethod: ID! + clientMutationId: String +} + +type GenerateDeployConfigTokenPayload { + token: String! + config: String! + clientMutationId: String +} + +input GenerateDeployConfigTokenInput { + config: String! + clientMutationId: String +} + +type ObtainJSONWebTokenPayload { + payload: GenericScalar! + refreshExpiresIn: Int! + username: CaseInsensitiveString! + clientMutationId: String + token: String! + refreshToken: String! +} + +""" +The `GenericScalar` scalar type represents a generic +GraphQL scalar value that could be: +String, Boolean, Int, Float, List or Object. +""" +scalar GenericScalar + +""" +The `CaseInsensitiveString` scalar type represents textual data, represented as UTF-8 +character sequences. The String type is most often used by GraphQL to +represent free-form human-readable text. +""" +scalar CaseInsensitiveString + +input ObtainJSONWebTokenInput { + clientMutationId: String + username: String! + password: String! +} + +type GenerateDeployTokenPayload { + token: String! + deployConfigVersion: DeployConfigVersion! + clientMutationId: String +} + +input GenerateDeployTokenInput { + deployConfigVersionId: String! + clientMutationId: String } -input RemoveNamespaceCollaboratorInput { - namespaceCollaboratorId: ID! - clientMutationId: String +type Verify { + payload: GenericScalar! } -input RemoveNamespaceCollaboratorInviteInput { - inviteId: ID! - clientMutationId: String +type Refresh { + payload: GenericScalar! + refreshExpiresIn: Int! + token: String! + refreshToken: String! } -type RemoveNamespaceCollaboratorInvitePayload { - namespace: Namespace! - clientMutationId: String +type Revoke { + revoked: Int! } -type RemoveNamespaceCollaboratorPayload { - namespace: Namespace! +type RegisterUserPayload { + token: String clientMutationId: String } -input RemovePackageCollaboratorInput { - packageCollaboratorId: ID! +input RegisterUserInput { + fullName: String! + email: String! + username: CaseInsensitiveString! + password: String! clientMutationId: String } -input RemovePackageCollaboratorInviteInput { - inviteId: ID! +type SocialAuthJWTPayload { + social: SocialAuth + token: String clientMutationId: String } -type RemovePackageCollaboratorInvitePayload { - package: Package! - clientMutationId: String +type SocialAuth implements Node { + """ + The ID of the object + """ + id: ID! + user: User! + provider: String! + uid: String! + extraData: String! + created: DateTime! + modified: DateTime! } -type RemovePackageCollaboratorPayload { - package: Package! +input SocialAuthJWTInput { + provider: String! + accessToken: String! clientMutationId: String } -input RemovePackageTransferRequestInput { - packageTransferRequestId: ID! +type ValidateUserEmailPayload { + user: User clientMutationId: String } -type RemovePackageTransferRequestPayload { - package: Package! +input ValidateUserEmailInput { + """ + The user id + """ + userId: ID + challenge: String! clientMutationId: String } -input RequestPackageTransferInput { - packageId: ID! - newOwnerId: ID! +type RequestPasswordResetPayload { + email: String! + errors: [ErrorType] clientMutationId: String } -type RequestPackageTransferPayload { - package: Package! - clientMutationId: String +type ErrorType { + field: String! + messages: [String!]! } input RequestPasswordResetInput { @@ -2004,9 +2766,9 @@ input RequestPasswordResetInput { clientMutationId: String } -type RequestPasswordResetPayload { - email: String! - errors: [ErrorType] +type RequestValidationEmailPayload { + user: User + success: Boolean! clientMutationId: String } @@ -2018,526 +2780,556 @@ input RequestValidationEmailInput { clientMutationId: String } -type RequestValidationEmailPayload { - user: User - success: Boolean! +type ChangeUserPasswordPayload { + token: String clientMutationId: String } -type Revoke { - revoked: Int! +input ChangeUserPasswordInput { + """ + The token associated to change the password. If not existing it will use the request user by default + """ + token: String + oldPassword: String + password: String! + clientMutationId: String } -input RevokeAPITokenInput { +type ChangeUserUsernamePayload { + user: User + token: String + clientMutationId: String +} + +input ChangeUserUsernameInput { """ - The API token ID + The new user username """ - tokenId: ID! + username: CaseInsensitiveString! clientMutationId: String } -type RevokeAPITokenPayload { - token: APIToken - success: Boolean +type ChangeUserEmailPayload { + user: User! clientMutationId: String } -type SearchConnection { +input ChangeUserEmailInput { + newEmail: String! + clientMutationId: String +} + +type UpdateUserInfoPayload { + user: User + clientMutationId: String +} + +input UpdateUserInfoInput { """ - Pagination data for this connection. + The user id """ - pageInfo: PageInfo! + userId: ID """ - Contains the nodes in this connection. + The user full name """ - edges: [SearchEdge]! -} + fullName: String -""" -A Relay edge containing a `Search` and its cursor. -""" -type SearchEdge { """ - The item at the end of the edge + The user bio """ - node: SearchResult + bio: String """ - A cursor for use in pagination + The user avatar """ - cursor: String! -} + avatar: String -enum SearchKind { - PACKAGE - NAMESPACE - USER -} + """ + The user Twitter (it can be the url, or the handle with or without the @) + """ + twitter: String -enum SearchOrderBy { - ALPHABETICALLY - SIZE - TOTAL_DOWNLOADS - PUBLISHED_DATE + """ + The user Github (it can be the url, or the handle with or without the @) + """ + github: String + + """ + The user website (it must be a valid url) + """ + websiteUrl: String + + """ + The user location + """ + location: String + clientMutationId: String } -enum SearchOrderSort { - ASC - DESC +type ValidateUserPasswordPayload { + success: Boolean + clientMutationId: String } -enum SearchPublishDate { - LAST_DAY - LAST_WEEK - LAST_MONTH - LAST_YEAR +input ValidateUserPasswordInput { + password: String! + clientMutationId: String } -union SearchResult = PackageVersion | User | Namespace +type GenerateAPITokenPayload { + token: APIToken + tokenRaw: String + user: User + clientMutationId: String +} -input SeePendingNotificationsInput { +input GenerateAPITokenInput { + identifier: String clientMutationId: String } -type SeePendingNotificationsPayload { +type RevokeAPITokenPayload { + token: APIToken success: Boolean clientMutationId: String } -type Signature { - id: ID! - publicKey: PublicKey! - data: String! - createdAt: DateTime! +input RevokeAPITokenInput { + """ + The API token ID + """ + tokenId: ID! + clientMutationId: String } -type SignedUrl { - url: String! -} +type CheckUserExistsPayload { + exists: Boolean! -type SocialAuth implements Node { """ - The ID of the object + The user is only returned if the user input was the username """ - id: ID! - user: User! - provider: String! - uid: String! - extraData: String! - created: DateTime! - modified: DateTime! + user: User + clientMutationId: String } -input SocialAuthJWTInput { - provider: String! - accessToken: String! +input CheckUserExistsInput { + """ + The user + """ + user: String! clientMutationId: String } -type SocialAuthJWTPayload { - social: SocialAuth - token: String +type ReadNotificationPayload { + notification: UserNotification clientMutationId: String } -type Subscription { - usageMetrics: [UsageMetric]! - packageVersionCreated(publishedBy: ID, ownerId: ID): PackageVersion! - userNotificationCreated(userId: ID!): UserNotificationCreated! +input ReadNotificationInput { + notificationId: ID! + clientMutationId: String } -input UnlikePackageInput { - packageId: ID! +type SeePendingNotificationsPayload { + success: Boolean + clientMutationId: String +} + +input SeePendingNotificationsInput { clientMutationId: String } -type UnlikePackagePayload { - package: Package! +type NewNoncePayload { + nonce: Nonce! clientMutationId: String } -input UnwatchPackageInput { - packageId: ID! +input NewNonceInput { + name: String! + callbackUrl: String! clientMutationId: String } -type UnwatchPackagePayload { - package: Package! +type ValidateNoncePayload { + nonce: Nonce! clientMutationId: String } -input UpdateNamespaceCollaboratorInviteRoleInput { - namespaceCollaboratorInviteId: ID! - role: GrapheneRole! +input ValidateNonceInput { + id: ID! + secret: String! clientMutationId: String } -type UpdateNamespaceCollaboratorInviteRolePayload { - collaboratorInvite: NamespaceCollaboratorInvite! +type PublishPublicKeyPayload { + success: Boolean! + publicKey: PublicKey! clientMutationId: String } -input UpdateNamespaceCollaboratorRoleInput { - namespaceCollaboratorId: ID! - role: GrapheneRole! +input PublishPublicKeyInput { + keyId: String! + key: String! + verifyingSignatureId: String clientMutationId: String } -type UpdateNamespaceCollaboratorRolePayload { - collaborator: NamespaceCollaborator! +type PublishPackagePayload { + success: Boolean! + packageVersion: PackageVersion! clientMutationId: String } -input UpdateNamespaceInput { - namespaceId: ID! +input PublishPackageInput { + name: String! + version: String! + description: String! + manifest: String! + license: String + licenseFile: String + readme: String + repository: String + homepage: String + file: String + signedUrl: String + signature: InputSignature """ - The namespace slug name + The package icon """ - name: String + icon: String + clientMutationId: String +} - """ - The namespace display name - """ - displayName: String +input InputSignature { + publicKeyKeyId: String! + data: String! +} - """ - The namespace description - """ - description: String +type UpdatePackagePayload { + package: Package! + clientMutationId: String +} + +input UpdatePackageInput { + packageId: ID! """ - The namespace avatar + The package icon """ - avatar: String + icon: String clientMutationId: String } -type UpdateNamespacePayload { - namespace: Namespace! +type LikePackagePayload { + package: Package! clientMutationId: String } -input UpdatePackageCollaboratorInviteRoleInput { - packageCollaboratorInviteId: ID! - role: GrapheneRole! +input LikePackageInput { + packageId: ID! clientMutationId: String } -type UpdatePackageCollaboratorInviteRolePayload { - collaboratorInvite: PackageCollaboratorInvite! +type UnlikePackagePayload { + package: Package! clientMutationId: String } -input UpdatePackageCollaboratorRoleInput { - packageCollaboratorId: ID! - role: GrapheneRole! +input UnlikePackageInput { + packageId: ID! clientMutationId: String } -type UpdatePackageCollaboratorRolePayload { - collaborator: PackageCollaborator! +type WatchPackagePayload { + package: Package! clientMutationId: String } -input UpdatePackageInput { +input WatchPackageInput { packageId: ID! - - """ - The package icon - """ - icon: String clientMutationId: String } -type UpdatePackagePayload { +type UnwatchPackagePayload { package: Package! clientMutationId: String } -input UpdateUserInfoInput { - """ - The user id - """ - userId: ID - - """ - The user full name - """ - fullName: String - - """ - The user bio - """ - bio: String - - """ - The user avatar - """ - avatar: String - - """ - The user Twitter (it can be the url, or the handle with or without the @) - """ - twitter: String +input UnwatchPackageInput { + packageId: ID! + clientMutationId: String +} - """ - The user Github (it can be the url, or the handle with or without the @) - """ - github: String +type ArchivePackagePayload { + package: Package! + clientMutationId: String +} - """ - The user website (it must be a valid url) - """ - websiteUrl: String +input ArchivePackageInput { + packageId: ID! + clientMutationId: String +} - """ - The user location - """ - location: String +type ChangePackageVersionArchivedStatusPayload { + packageVersion: PackageVersion! clientMutationId: String } -type UpdateUserInfoPayload { - user: User +input ChangePackageVersionArchivedStatusInput { + packageVersionId: ID! + isArchived: Boolean clientMutationId: String } -type UsageMetric { - metricType: String! - metricValue: String! - metricDatetime: DateTime! +type CreateNamespacePayload { + namespace: Namespace! + user: User! + clientMutationId: String } -type User implements Node & PackageOwner & Owner { +input CreateNamespaceInput { + name: String! + """ - Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only. + The namespace display name """ - username: String! - firstName: String! - lastName: String! - email: String! - dateJoined: DateTime! - isEmailValidated: Boolean! - bio: String - location: String - websiteUrl: String + displayName: String """ - The ID of the object + The namespace description """ - id: ID! - globalName: String! - avatar(size: Int = 80): String! - isViewer: Boolean! - hasUsablePassword: Boolean - fullName: String! - githubUrl: String - twitterUrl: String - publicActivity( - before: String - after: String - first: Int - last: Int - ): ActivityEventConnection! - namespaces( - before: String - after: String - first: Int - last: Int - ): NamespaceConnection! - packages( - collaborating: Boolean = false - before: String - after: String - first: Int - last: Int - ): PackageConnection! - apps( - collaborating: Boolean = false - before: String - after: String - first: Int - last: Int - ): AppConnection! - packageVersions( - before: String - after: String - first: Int - last: Int - ): PackageVersionConnection! - packageTransfersIncoming( - before: String - after: String - first: Int - last: Int - ): PackageTransferRequestConnection! - packageInvitesIncoming( - before: String - after: String - first: Int - last: Int - ): PackageCollaboratorInviteConnection! - namespaceInvitesIncoming( - before: String - after: String - first: Int - last: Int - ): NamespaceCollaboratorInviteConnection! - apiTokens( - before: String - after: String - first: Int - last: Int - ): APITokenConnection! - notifications( - before: String - after: String - first: Int - last: Int - ): UserNotificationConnection! + description: String + + """ + The namespace avatar + """ + avatar: String + clientMutationId: String } -type UserConnection { +type UpdateNamespacePayload { + namespace: Namespace! + clientMutationId: String +} + +input UpdateNamespaceInput { + namespaceId: ID! + """ - Pagination data for this connection. + The namespace slug name """ - pageInfo: PageInfo! + name: String """ - Contains the nodes in this connection. + The namespace display name """ - edges: [UserEdge]! -} + displayName: String -""" -A Relay edge containing a `User` and its cursor. -""" -type UserEdge { """ - The item at the end of the edge + The namespace description """ - node: User + description: String """ - A cursor for use in pagination + The namespace avatar """ - cursor: String! + avatar: String + clientMutationId: String } -type UserNotification implements Node { - """ - The ID of the object - """ - id: ID! - icon: String - body: UserNotificationBody! - seenState: UserNotificationSeenState! - kind: UserNotificationKind - createdAt: DateTime! +type DeleteNamespacePayload { + success: Boolean! + clientMutationId: String } -type UserNotificationBody { - text: String! - ranges: [NodeBodyRange]! +input DeleteNamespaceInput { + namespaceId: ID! + clientMutationId: String } -type UserNotificationConnection { - """ - Pagination data for this connection. - """ - pageInfo: PageInfo! +type InviteNamespaceCollaboratorPayload { + invite: NamespaceCollaboratorInvite! + namespace: Namespace! + clientMutationId: String +} - """ - Contains the nodes in this connection. - """ - edges: [UserNotificationEdge]! - hasPendingNotifications: Boolean! +input InviteNamespaceCollaboratorInput { + namespaceId: ID! + role: GrapheneRole! + username: String + email: String + clientMutationId: String } -type UserNotificationCreated { - notification: UserNotification - notificationDeletedId: ID +type AcceptNamespaceCollaboratorInvitePayload { + namespaceCollaboratorInvite: NamespaceCollaboratorInvite! + clientMutationId: String } -""" -A Relay edge containing a `UserNotification` and its cursor. -""" -type UserNotificationEdge { - """ - The item at the end of the edge - """ - node: UserNotification +input AcceptNamespaceCollaboratorInviteInput { + inviteId: ID! + clientMutationId: String +} - """ - A cursor for use in pagination - """ - cursor: String! +type RemoveNamespaceCollaboratorInvitePayload { + namespace: Namespace! + clientMutationId: String } -union UserNotificationKind = - UserNotificationKindPublishedPackageVersion - | UserNotificationKindIncomingPackageTransfer - | UserNotificationKindIncomingPackageInvite - | UserNotificationKindIncomingNamespaceInvite +input RemoveNamespaceCollaboratorInviteInput { + inviteId: ID! + clientMutationId: String +} -type UserNotificationKindIncomingNamespaceInvite { - namespaceInvite: NamespaceCollaboratorInvite! +type RemoveNamespaceCollaboratorPayload { + namespace: Namespace! + clientMutationId: String } -type UserNotificationKindIncomingPackageInvite { - packageInvite: PackageCollaboratorInvite! +input RemoveNamespaceCollaboratorInput { + namespaceCollaboratorId: ID! + clientMutationId: String } -type UserNotificationKindIncomingPackageTransfer { - packageTransferRequest: PackageTransferRequest! +type UpdateNamespaceCollaboratorRolePayload { + collaborator: NamespaceCollaborator! + clientMutationId: String } -type UserNotificationKindPublishedPackageVersion { - packageVersion: PackageVersion! +input UpdateNamespaceCollaboratorRoleInput { + namespaceCollaboratorId: ID! + role: GrapheneRole! + clientMutationId: String } -enum UserNotificationSeenState { - UNSEEN - SEEN - SEEN_AND_READ +type UpdateNamespaceCollaboratorInviteRolePayload { + collaboratorInvite: NamespaceCollaboratorInvite! + clientMutationId: String } -input ValidateUserEmailInput { - """ - The user id - """ - userId: ID - challenge: String! +input UpdateNamespaceCollaboratorInviteRoleInput { + namespaceCollaboratorInviteId: ID! + role: GrapheneRole! clientMutationId: String } -type ValidateUserEmailPayload { - user: User +type InvitePackageCollaboratorPayload { + invite: PackageCollaboratorInvite! + package: Package! clientMutationId: String } -input ValidateUserPasswordInput { - password: String! +input InvitePackageCollaboratorInput { + packageName: String! + role: GrapheneRole! + username: String + email: String clientMutationId: String } -type ValidateUserPasswordPayload { - success: Boolean +type AcceptPackageCollaboratorInvitePayload { + packageCollaboratorInvite: PackageCollaboratorInvite! clientMutationId: String } -type Verify { - payload: GenericScalar! +input AcceptPackageCollaboratorInviteInput { + inviteId: ID! + clientMutationId: String } -input WatchPackageInput { +type RemovePackageCollaboratorInvitePayload { + package: Package! + clientMutationId: String +} + +input RemovePackageCollaboratorInviteInput { + inviteId: ID! + clientMutationId: String +} + +type UpdatePackageCollaboratorRolePayload { + collaborator: PackageCollaborator! + clientMutationId: String +} + +input UpdatePackageCollaboratorRoleInput { + packageCollaboratorId: ID! + role: GrapheneRole! + clientMutationId: String +} + +type UpdatePackageCollaboratorInviteRolePayload { + collaboratorInvite: PackageCollaboratorInvite! + clientMutationId: String +} + +input UpdatePackageCollaboratorInviteRoleInput { + packageCollaboratorInviteId: ID! + role: GrapheneRole! + clientMutationId: String +} + +type RemovePackageCollaboratorPayload { + package: Package! + clientMutationId: String +} + +input RemovePackageCollaboratorInput { + packageCollaboratorId: ID! + clientMutationId: String +} + +type RequestPackageTransferPayload { + package: Package! + clientMutationId: String +} + +input RequestPackageTransferInput { packageId: ID! + newOwnerId: ID! clientMutationId: String } -type WatchPackagePayload { +type AcceptPackageTransferRequestPayload { + package: Package! + packageTransferRequest: PackageTransferRequest! + clientMutationId: String +} + +input AcceptPackageTransferRequestInput { + packageTransferRequestId: ID! + clientMutationId: String +} + +type RemovePackageTransferRequestPayload { package: Package! clientMutationId: String } + +input RemovePackageTransferRequestInput { + packageTransferRequestId: ID! + clientMutationId: String +} + +type GenerateBindingsForAllPackagesPayload { + message: String! + clientMutationId: String +} + +input GenerateBindingsForAllPackagesInput { + bindingsGeneratorId: ID + bindingsGeneratorCommand: String + clientMutationId: String +} + +type Subscription { + packageVersionCreated(publishedBy: ID, ownerId: ID): PackageVersion! + userNotificationCreated(userId: ID!): UserNotificationCreated! +} + +type UserNotificationCreated { + notification: UserNotification + notificationDeletedId: ID +} diff --git a/lib/registry/src/api.rs b/lib/registry/src/api.rs index 378c961ad01..5c107cea7d4 100644 --- a/lib/registry/src/api.rs +++ b/lib/registry/src/api.rs @@ -2,8 +2,8 @@ use anyhow::Context; use crate::RegistryClient; -use crate::graphql::mutations; -use crate::types::{PublishDeployAppOutput, PublishDeployAppRawVars}; +use crate::graphql::mutations::{self}; +use crate::types::{NewNonceOutput, PublishDeployAppOutput, PublishDeployAppRawVars}; /// Generate a Deploy token for for the given Deploy app version id. pub async fn generate_deploy_token( @@ -42,7 +42,9 @@ pub async fn publish_deploy_app_raw( .publish_deploy_app .context("Query did not return data")? .deploy_app_version; - let app = version.app.context("Query did not return expected data")?; + + let app = version.app; + // let app = version.app.context("Query did not return expected data")?; Ok(PublishDeployAppOutput { app_id: app.id, @@ -52,3 +54,24 @@ pub async fn publish_deploy_app_raw( owner_name: app.owner.global_name, }) } + +/// Generate a new Nonce +/// +/// Takes a name and a callbackUrl and returns a nonce +pub async fn create_nonce( + client: &RegistryClient, + name: String, + callback_url: String, +) -> Result { + let vars = mutations::new_nonce::Variables { name, callback_url }; + let nonce = client + .execute::(vars) + .await? + .new_nonce + .context("Query did not return a nonce")? + .nonce; + + Ok(NewNonceOutput { + auth_url: nonce.auth_url, + }) +} diff --git a/lib/registry/src/graphql/mutations.rs b/lib/registry/src/graphql/mutations.rs index b5611c98555..6bed4afb116 100644 --- a/lib/registry/src/graphql/mutations.rs +++ b/lib/registry/src/graphql/mutations.rs @@ -25,3 +25,11 @@ pub type JSONString = String; response_derives = "Debug" )] pub(crate) struct PublishDeployApp; + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "graphql/schema.graphql", + query_path = "graphql/mutations/new_nonce.graphql", + response_derives = "Debug" +)] +pub(crate) struct NewNonce; diff --git a/lib/registry/src/types.rs b/lib/registry/src/types.rs index 6e9f6b0d1dd..3db9a2bf8c5 100644 --- a/lib/registry/src/types.rs +++ b/lib/registry/src/types.rs @@ -24,3 +24,8 @@ pub struct PublishDeployAppOutput { pub version_name: String, pub owner_name: String, } + +#[derive(Clone, Debug)] +pub struct NewNonceOutput { + pub auth_url: String, +} diff --git a/tests/integration/cli/tests/login.rs b/tests/integration/cli/tests/login.rs index 7980f774cad..e06951fd5c8 100644 --- a/tests/integration/cli/tests/login.rs +++ b/tests/integration/cli/tests/login.rs @@ -15,6 +15,7 @@ fn login_works() -> anyhow::Result<()> { if wapm_dev_token.is_empty() { return Ok(()); } + // FIXME: Change the registry to wasmer.wtf and all the associated terms with WAPM let output = Command::new(get_wasmer_path()) .arg("login") .arg("--registry") @@ -37,7 +38,7 @@ fn login_works() -> anyhow::Result<()> { } let stdout_output = std::str::from_utf8(&output.stdout).unwrap(); - let expected = "Login for Wasmer user \"ciuser\" saved\n"; + let expected = "Done!\n✅ Login for Wasmer user \"ciuser\" saved\n"; if stdout_output != expected { println!("expected:"); println!("{expected}"); diff --git a/tests/wasmer-web/tests/wasi-web.rs b/tests/wasmer-web/tests/wasi-web.rs index 61a90aba5ee..10abf868cec 100644 --- a/tests/wasmer-web/tests/wasi-web.rs +++ b/tests/wasmer-web/tests/wasi-web.rs @@ -58,6 +58,7 @@ async fn run_a_webc_package_that_involves_the_filesystem(client: Client) { ); } +#[ignore] // FIXME: This test is flaky on CI - @Michael-F-Bryan #[macro_rules_attribute::apply(browser_test)] async fn pure_webc_package(client: Client) { client.wait_for_xterm(str::contains(PROMPT)).await;