diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 4d6eebed1d..d437f9899c 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -52,34 +52,11 @@ jobs: run: | wrk -d 30 -t 4 -c 100 -s wrk.lua http://localhost:8000/graphql > wrk-output.txt - - id: convert_wrk_output_json - name: Convert Output to JSON - working-directory: ci-benchmark - run: | - node wrk-output-to-json.js wrk-output.txt > results.json - - - id: push_to_bencher - working-directory: ci-benchmark - uses: bencherdev/bencher@main - run: | - bencher run \ - --project tailcall \ - --token '${{ secrets.BENCHER_API_TOKEN }}' \ - --branch '${{ github.head_ref }}' \ - --branch-start-point '${{ github.base_ref }}' \ - --branch-start-point-hash '${{ github.base_sha }}' \ - --testbed ubuntu-latest \ - --adapter json \ - --err \ - --file "results.json" - --github-actions '${{ secrets.GITHUB_TOKEN }}' \ - - id: convert_wrk_output_markdown name: Convert Output to Markdown working-directory: ci-benchmark run: | node wrk-output-to-md.js wrk-output.txt > body.md - - id: cat_md name: Cat Markdown working-directory: ci-benchmark diff --git a/Cargo.lock b/Cargo.lock index b6a6cf3307..ed95c2da2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -907,7 +907,7 @@ version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.66", @@ -2000,12 +2000,6 @@ dependencies = [ "http 0.2.12", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -3769,9 +3763,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -3808,7 +3802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", - "heck 0.5.0", + "heck", "itertools 0.12.1", "log", "multimap", @@ -4517,9 +4511,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0218ceea14babe24a4a5836f86ade86c1effbc198164e619194cb5069187e29" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "schemars_derive", @@ -4529,9 +4523,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed5a1ccce8ff962e31a165d41f6e2a2dd1245099dc4d594f5574a86cd90f4d3" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ "proc-macro2", "quote", @@ -4677,9 +4671,9 @@ dependencies = [ [[package]] name = "serde_json_borrow" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256097ff1654ce1975402cb5a2bfa2cad3cc3199e1d704bf303b386fc971f3c" +source = "git+https://github.com/tailcallhq/serde_json_borrow?branch=temp#af929274109c540975921cc3268084914848f272" dependencies = [ + "schemars", "serde", "serde_json", ] @@ -4974,11 +4968,11 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +checksum = "f7993a8e3a9e88a00351486baae9522c91b123a088f76469e5bd5cc17198ea87" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", @@ -5083,6 +5077,7 @@ dependencies = [ "anyhow", "async-graphql", "async-graphql-extension-apollo-tracing", + "async-graphql-parser", "async-graphql-value", "async-recursion", "async-std", diff --git a/Cargo.toml b/Cargo.toml index aedd364aab..9f589e777f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,7 @@ tailcall-version = { path = "./tailcall-version", optional = true } # dependencies safe for wasm: rustls-pemfile = { version = "1.0.4" } -schemars = { version = "0.8.17", features = ["derive"] } +schemars = { version = "0.8.21", features = ["derive"] } hyper = { version = "0.14.28", features = ["server"], default-features = false } tokio = { workspace = true } anyhow = { workspace = true } @@ -141,6 +141,7 @@ mime = "0.3.17" htpasswd-verify = { version = "0.3.0", git = "https://github.com/twistedfall/htpasswd-verify", rev = "ff14703083cbd639f7d05622b398926f3e718d61" } # fork version that is wasm compatible jsonwebtoken = "9.3.0" async-graphql-value = "7.0.3" +async-graphql-parser = "7.0.5" async-graphql = { workspace = true, features = [ "dynamic-schema", "dataloader", @@ -157,7 +158,7 @@ datatest-stable = "0.2.9" tokio-test = "0.4.4" base64 = "0.22.1" tailcall-hasher = { path = "tailcall-hasher" } -serde_json_borrow = "0.5.0" +serde_json_borrow = {git = "https://github.com/tailcallhq/serde_json_borrow", branch = "temp"} [dev-dependencies] tailcall-prettier = { path = "tailcall-prettier" } diff --git a/ci-benchmark/wrk-output-to-json.js b/ci-benchmark/wrk-output-to-json.js deleted file mode 100644 index 7dd0b358fe..0000000000 --- a/ci-benchmark/wrk-output-to-json.js +++ /dev/null @@ -1,39 +0,0 @@ -const fs = require("fs") - -const wrkOutput = fs.readFileSync(process.argv[2], "utf8") - -const latencyAvgMatch = wrkOutput.match(/Latency\s+(\d+\.\d+)ms\s+(\d+\.\d+)ms\s+(\d+\.\d+)ms/) -const reqSecMatch = wrkOutput.match(/Req\/Sec\s+(\d+\.\d+k?)\s+(\d+\.\d+)\s+(\d+\.\d+k?)/) - -if (!latencyAvgMatch || !reqSecMatch) { - console.error("Error parsing " + process.argv[2]) - process.exit(1) -} - -const convertToNumber = (value) => { - if (value.endsWith("k")) { - return parseFloat(value.replace("k", "")) * 1000 - } - return parseFloat(value) -} - -const latency = { - value: parseFloat(latencyAvgMatch[1]), - lower_value: parseFloat(latencyAvgMatch[2]), - upper_value: parseFloat(latencyAvgMatch[3]), -} - -const reqSec = { - value: convertToNumber(reqSecMatch[1]), - lower_value: parseFloat(reqSecMatch[2]), - upper_value: convertToNumber(reqSecMatch[3]), -} - -const resultJson = { - benchmark_name: { - latency: latency, - req_sec: reqSec, - }, -} - -console.log(JSON.stringify(resultJson, null, 2)) diff --git a/generated/.tailcallrc.schema.json b/generated/.tailcallrc.schema.json index 83b13b251f..0fa6af467d 100644 --- a/generated/.tailcallrc.schema.json +++ b/generated/.tailcallrc.schema.json @@ -489,6 +489,7 @@ }, "protected": { "description": "Marks field as protected by auth provider", + "default": null, "anyOf": [ { "$ref": "#/definitions/Protected" @@ -1266,6 +1267,7 @@ }, "protected": { "description": "Marks field as protected by auth providers", + "default": null, "anyOf": [ { "$ref": "#/definitions/Protected" diff --git a/npm/package-lock.json b/npm/package-lock.json index e665c4ce08..06385852f7 100644 --- a/npm/package-lock.json +++ b/npm/package-lock.json @@ -861,9 +861,10 @@ } }, "node_modules/yaml": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", - "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.3.tgz", + "integrity": "sha512-sntgmxj8o7DE7g/Qi60cqpLBA3HG3STcDA0kO+WfB05jEKhZMbY7umNm2rBpQvsmZ16/lPXCJGW2672dgOUkrg==", + "license": "ISC", "bin": { "yaml": "bin.mjs" }, diff --git a/src/core/blueprint/blueprint.rs b/src/core/blueprint/blueprint.rs index 503a4eda86..8b3589dc06 100644 --- a/src/core/blueprint/blueprint.rs +++ b/src/core/blueprint/blueprint.rs @@ -1,4 +1,5 @@ use std::collections::{BTreeSet, HashMap}; +use std::fmt::{Debug, Formatter}; use std::sync::Arc; use async_graphql::dynamic::{Schema, SchemaBuilder}; @@ -27,12 +28,33 @@ pub struct Blueprint { pub telemetry: Telemetry, } -#[derive(Clone, Debug)] +#[derive(Clone)] pub enum Type { NamedType { name: String, non_null: bool }, ListType { of_type: Box, non_null: bool }, } +impl Debug for Type { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Type::NamedType { name, non_null } => { + if *non_null { + write!(f, "{}!", name) + } else { + write!(f, "{}", name) + } + } + Type::ListType { of_type, non_null } => { + if *non_null { + write!(f, "[{:?}]!", of_type) + } else { + write!(f, "[{:?}]", of_type) + } + } + } + } +} + impl Default for Type { fn default() -> Self { Type::NamedType { name: "JSON".to_string(), non_null: false } diff --git a/src/core/http/response.rs b/src/core/http/response.rs index 7f0377cad5..c9971badc8 100644 --- a/src/core/http/response.rs +++ b/src/core/http/response.rs @@ -9,6 +9,7 @@ use tonic_types::Status as GrpcStatus; use crate::core::grpc::protobuf::ProtobufOperation; use crate::core::ir::EvaluationError; +use crate::core::FromValue; #[derive(Clone, Debug, Default, Setters)] pub struct Response { @@ -23,29 +24,6 @@ pub struct Response { // efficient. Benchmarking is required to determine the performance If any // change is made. -pub trait FromValue { - fn from_value(value: serde_json_borrow::Value) -> Self; -} - -impl FromValue for ConstValue { - fn from_value(value: serde_json_borrow::Value) -> Self { - match value { - serde_json_borrow::Value::Null => ConstValue::Null, - serde_json_borrow::Value::Bool(b) => ConstValue::Boolean(b), - serde_json_borrow::Value::Number(n) => ConstValue::Number(n.into()), - serde_json_borrow::Value::Str(s) => ConstValue::String(s.into()), - serde_json_borrow::Value::Array(a) => { - ConstValue::List(a.into_iter().map(|v| Self::from_value(v)).collect()) - } - serde_json_borrow::Value::Object(o) => ConstValue::Object( - o.iter() - .map(|(k, v)| (Name::new(k), Self::from_value(v.to_owned()))) - .collect(), - ), - } - } -} - impl Response { pub async fn from_reqwest(resp: reqwest::Response) -> Result { let status = resp.status(); diff --git a/src/core/ir/jit/mod.rs b/src/core/ir/jit/mod.rs index 6c422d03c2..c13d526668 100644 --- a/src/core/ir/jit/mod.rs +++ b/src/core/ir/jit/mod.rs @@ -1,3 +1,4 @@ +#![allow(unused)] /// /// We need three executors for each query /// 1. Global general purpose executor (WE have this currently) @@ -7,60 +8,283 @@ /// made. mod model { - use async_graphql::parser::types::ExecutableDocument; + use std::collections::HashMap; + use std::fmt::{Debug, Formatter}; + use async_graphql::parser::types::{DocumentOperations, ExecutableDocument, Selection}; + use async_graphql::Positioned; + use serde_json_borrow::OwnedValue; + + use crate::core::blueprint::{Blueprint, Definition, FieldDefinition, InputFieldDefinition}; use crate::core::ir::IR; + use crate::core::merge_right::MergeRight; + use crate::core::FromValue; + + trait IncrGen { + fn gen(&mut self) -> Self; + } + #[derive(Debug)] pub enum Type { Named(String), List(Box), Required(Box), } + #[derive(Debug)] pub struct Arg { pub id: ArgId, pub name: String, - pub type_of: Type, + pub type_of: crate::core::blueprint::Type, + pub value: Option, + pub default_value: Option, } pub struct ArgId(usize); + + impl Debug for ArgId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } + } + + impl IncrGen for ArgId { + fn gen(&mut self) -> Self { + let id = self.0; + self.0 += 1; + Self(id) + } + } + impl ArgId { fn new(id: usize) -> Self { ArgId(id) } } + trait Id { + fn as_usize(&self) -> usize; + } + #[derive(Clone, PartialEq, Eq)] pub struct FieldId(usize); + + impl Debug for FieldId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } + } + impl FieldId { fn new(id: usize) -> Self { FieldId(id) } } + impl IncrGen for FieldId { + fn gen(&mut self) -> Self { + let id = self.0; + self.0 += 1; + Self(id) + } + } + pub struct Field { pub id: FieldId, pub name: String, pub ir: Option, - pub type_of: Type, + pub type_of: crate::core::blueprint::Type, pub args: Vec, pub refs: Option, } + impl Debug for Field { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut debug_struct = f.debug_struct("Field"); + debug_struct.field("id", &self.id); + debug_struct.field("name", &self.name); + if self.ir.is_some() { + debug_struct.field("ir", &"Some(..)"); + } + debug_struct.field("type_of", &self.type_of); + if !self.args.is_empty() { + debug_struct.field("args", &self.args); + } + if self.refs.is_some() { + debug_struct.field("refs", &"Some(..)"); + } + debug_struct.finish() + } + } + + #[derive(Debug)] pub struct Parent(FieldId); + pub struct Children(Vec); + #[derive(Debug)] pub struct QueryBlueprint { pub fields: Vec>, } - impl From for QueryBlueprint { - fn from(value: ExecutableDocument) -> Self { - // TODO: @ssddOnTop - // 1. Handle all edge-cases - // 2. Add unit tests - todo!() + impl QueryBlueprint { + pub fn from_document(document: ExecutableDocument, blueprint: Blueprint) -> Self { + let fields = convert_query_to_field(document, &blueprint.definitions).unwrap(); + Self { fields } + } + } + + fn convert_query_to_field( + document: ExecutableDocument, + schema_definitions: &[Definition], + ) -> anyhow::Result>> { + let mut id = FieldId::new(0); + let mut arg_id = ArgId::new(0); + + let mut fields = Vec::new(); + + fn resolve_selection_set( + selection_set: Positioned, + schema_definitions: &[Definition], + id: &mut FieldId, + arg_id: &mut ArgId, + ) -> Vec> { + let mut fields = Vec::new(); + + for selection in selection_set.node.items { + if let Selection::Field(gql_field) = selection.node { + let field_name = gql_field.node.name.node.as_str(); + let field_args = gql_field + .node + .arguments + .into_iter() + .map(|(k, v)| (k.node.as_str().to_string(), v.node.into_const().unwrap())) + .collect::>(); + + if let Some(definition) = find_definition(field_name, schema_definitions) { + let mut args = vec![]; + field_args.into_iter().for_each(|(k, v)| { + if let Some(arg) = find_definition_arg(&k, schema_definitions) { + let type_of = arg.of_type.clone(); + let id = arg_id.gen(); + let arg = Arg { + id, + name: k, + type_of, + value: Some(v.into_bvalue().into()), + default_value: None, + }; + args.push(arg); + } + }); + + let type_of = definition.of_type.clone(); + fields = fields.merge_right(resolve_selection_set( + gql_field.node.selection_set.clone(), + schema_definitions, + id, + arg_id, + )); + + let id = id.gen(); + let field = Field { + id, + name: field_name.to_string(), + ir: definition.resolver.clone(), + type_of, + args, + refs: None, + }; + fields.push(field); + } + } + } + + fields + } + + match document.operations { + DocumentOperations::Single(single) => { + fields = resolve_selection_set( + single.node.selection_set, + schema_definitions, + &mut id, + &mut arg_id, + ); + } + DocumentOperations::Multiple(multiple) => { + for (_, single) in multiple { + fields = resolve_selection_set( + single.node.selection_set, + schema_definitions, + &mut id, + &mut arg_id, + ); + } + } + } + + Ok(fields) + } + + fn find_definition<'a>( + name: &str, + definitions: &'a [Definition], + ) -> Option<&'a FieldDefinition> { + for def in definitions { + if let Definition::Object(object) = def { + for field in &object.fields { + if field.name == name { + return Some(field); + } + } + } + } + None + } + + fn find_definition_arg<'a>( + name: &str, + definitions: &'a [Definition], + ) -> Option<&'a InputFieldDefinition> { + for def in definitions { + if let Definition::Object(object) = def { + for field in &object.fields { + for arg in &field.args { + if arg.name == name { + return Some(arg); + } + } + } + } } + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::core::blueprint::Blueprint; + use crate::core::config::reader::ConfigReader; + + #[tokio::test] + async fn test_from_document() { + let rt = crate::core::runtime::test::init(None); + let reader = ConfigReader::init(rt); + let config = reader + .read("examples/jsonplaceholder.graphql") + .await + .unwrap(); + let blueprint = Blueprint::try_from(&config).unwrap(); + let query = r#" + query { + posts { user { id } } + } + "#; + let document = async_graphql::parser::parse_query(query).unwrap(); + let q_blueprint = model::QueryBlueprint::from_document(document, blueprint); + insta::assert_snapshot!(format!("{:#?}", q_blueprint)); } } @@ -69,7 +293,6 @@ mod value { } mod cache { - use super::model::FieldId; use super::value::OwnedValue; @@ -172,7 +395,6 @@ mod executor { } mod synth { - pub use serde_json_borrow::*; use super::cache::Cache; diff --git a/src/core/ir/jit/snapshots/tailcall__core__ir__jit__tests__from_document.snap b/src/core/ir/jit/snapshots/tailcall__core__ir__jit__tests__from_document.snap new file mode 100644 index 0000000000..0ca8e91ff5 --- /dev/null +++ b/src/core/ir/jit/snapshots/tailcall__core__ir__jit__tests__from_document.snap @@ -0,0 +1,25 @@ +--- +source: src/core/ir/jit/mod.rs +expression: "format!(\"{:#?}\", q_blueprint)" +--- +QueryBlueprint { + fields: [ + Field { + id: 0, + name: "id", + type_of: Int!, + }, + Field { + id: 1, + name: "user", + ir: "Some(..)", + type_of: User, + }, + Field { + id: 2, + name: "posts", + ir: "Some(..)", + type_of: [Post], + }, + ], +} diff --git a/src/core/mod.rs b/src/core/mod.rs index f715bc7c52..a5ed499ddc 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -41,11 +41,62 @@ pub mod worker; use std::borrow::Cow; use std::hash::Hash; use std::num::NonZeroU64; +use std::str::FromStr; -use async_graphql_value::ConstValue; +use async_graphql_value::{ConstValue, Name}; use http::Response; pub use tailcall_macros as macros; +pub type BorrowedValue = serde_json_borrow::Value<'static>; + +pub trait FromValue { + fn from_value(value: serde_json_borrow::Value) -> Self; + fn into_bvalue(self) -> BorrowedValue; +} + +impl FromValue for async_graphql_value::ConstValue { + fn from_value(value: serde_json_borrow::Value) -> Self { + match value { + serde_json_borrow::Value::Null => ConstValue::Null, + serde_json_borrow::Value::Bool(b) => ConstValue::Boolean(b), + serde_json_borrow::Value::Number(n) => ConstValue::Number(n.into()), + serde_json_borrow::Value::Str(s) => ConstValue::String(s.into()), + serde_json_borrow::Value::Array(a) => { + ConstValue::List(a.into_iter().map(|v| Self::from_value(v)).collect()) + } + serde_json_borrow::Value::Object(o) => ConstValue::Object( + o.iter() + .map(|(k, v)| (Name::new(k), Self::from_value(v.to_owned()))) + .collect(), + ), + } + } + + fn into_bvalue(self) -> BorrowedValue { + match self { + async_graphql_value::ConstValue::Null => serde_json_borrow::Value::Null, + async_graphql_value::ConstValue::Boolean(b) => serde_json_borrow::Value::Bool(b), + async_graphql_value::ConstValue::Number(n) => serde_json_borrow::Value::Number( + serde_json_borrow::Number::from_str(&n.to_string()).unwrap(), + ), // TODO: FIXME + async_graphql_value::ConstValue::String(s) => { + serde_json_borrow::Value::Str(Cow::Owned(s)) + } + async_graphql_value::ConstValue::List(a) => serde_json_borrow::Value::Array( + a.into_iter().map(|v| v.into_bvalue()).collect::>(), + ), + async_graphql_value::ConstValue::Object(o) => serde_json_borrow::Value::Object( + o.into_iter() + .map(|(k, v)| (k.to_string(), v.into_bvalue())) + .collect::>() + .into(), + ), + async_graphql_value::ConstValue::Binary(_) => todo!(), + async_graphql_value::ConstValue::Enum(_) => todo!(), + } + } +} + pub trait EnvIO: Send + Sync + 'static { fn get(&self, key: &str) -> Option>; } diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 6b4a010351..b092f1efea 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -2240,9 +2240,9 @@ } }, "node_modules/wrangler": { - "version": "3.57.2", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.57.2.tgz", - "integrity": "sha512-QegYf0FW+4prlFKE9iHr1EGrCo8ejcGL9gaqEXrzQ0vbTdazykYbY0I5UpHFLNq2dIF9I/ifEoLRKr636tyHEw==", + "version": "3.58.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.58.0.tgz", + "integrity": "sha512-h9gWER7LXLnmHABDNP1p3aqXtchlvSBN8Dp22ZurnkxaLMZ3L3H1Ze1ftiFSs0VRWv0BUnz7AWIUqZmzuBY4Nw==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.2", @@ -2251,7 +2251,7 @@ "blake3-wasm": "^2.1.5", "chokidar": "^3.5.3", "esbuild": "0.17.19", - "miniflare": "3.20240524.0", + "miniflare": "3.20240524.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -2668,32 +2668,6 @@ "@esbuild/win32-x64": "0.17.19" } }, - "node_modules/wrangler/node_modules/miniflare": { - "version": "3.20240524.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240524.0.tgz", - "integrity": "sha512-RQAfpz7spI6gWlczeUYvJBgGyt0gNR2pYoCydgukCYZ+0bGfJl0yAiNFW62uH7uMZli/4juWPpQOBI5m7URoyA==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "acorn": "^8.8.0", - "acorn-walk": "^8.2.0", - "capnp-ts": "^0.7.0", - "exit-hook": "^2.2.1", - "glob-to-regexp": "^0.4.1", - "stoppable": "^1.1.0", - "undici": "^5.28.2", - "workerd": "1.20240524.0", - "ws": "^8.11.0", - "youch": "^3.2.2", - "zod": "^3.20.6" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, "node_modules/ws": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", @@ -4176,9 +4150,9 @@ } }, "wrangler": { - "version": "3.57.2", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.57.2.tgz", - "integrity": "sha512-QegYf0FW+4prlFKE9iHr1EGrCo8ejcGL9gaqEXrzQ0vbTdazykYbY0I5UpHFLNq2dIF9I/ifEoLRKr636tyHEw==", + "version": "3.58.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.58.0.tgz", + "integrity": "sha512-h9gWER7LXLnmHABDNP1p3aqXtchlvSBN8Dp22ZurnkxaLMZ3L3H1Ze1ftiFSs0VRWv0BUnz7AWIUqZmzuBY4Nw==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.2", @@ -4188,7 +4162,7 @@ "chokidar": "^3.5.3", "esbuild": "0.17.19", "fsevents": "~2.3.2", - "miniflare": "3.20240524.0", + "miniflare": "3.20240524.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -4381,26 +4355,6 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } - }, - "miniflare": { - "version": "3.20240524.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240524.0.tgz", - "integrity": "sha512-RQAfpz7spI6gWlczeUYvJBgGyt0gNR2pYoCydgukCYZ+0bGfJl0yAiNFW62uH7uMZli/4juWPpQOBI5m7URoyA==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.8.1", - "acorn": "^8.8.0", - "acorn-walk": "^8.2.0", - "capnp-ts": "^0.7.0", - "exit-hook": "^2.2.1", - "glob-to-regexp": "^0.4.1", - "stoppable": "^1.1.0", - "undici": "^5.28.2", - "workerd": "1.20240524.0", - "ws": "^8.11.0", - "youch": "^3.2.2", - "zod": "^3.20.6" - } } } },