From 0af62933bff8f09d87c977cd40cae653bd4b990c Mon Sep 17 00:00:00 2001 From: laststylebender <43403528+laststylebender14@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:35:13 +0530 Subject: [PATCH 01/77] fix: treat null responses as JSON scalars (#2784) --- .../tests/snapshots/json_to_config_spec__null.json.snap | 2 +- src/core/helpers/gql_type.rs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__null.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__null.json.snap index eb01d1a972..1a01bf6c9c 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__null.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__null.json.snap @@ -7,5 +7,5 @@ schema @server @upstream { } type Query { - usersAge(age: Int): Empty @http(baseURL: "https://example.com", path: "/users", query: [{key: "age", value: "{{.args.age}}"}]) + usersAge(age: Int): JSON @http(baseURL: "https://example.com", path: "/users", query: [{key: "age", value: "{{.args.age}}"}]) } diff --git a/src/core/helpers/gql_type.rs b/src/core/helpers/gql_type.rs index 46bc24b32f..8d4da11518 100644 --- a/src/core/helpers/gql_type.rs +++ b/src/core/helpers/gql_type.rs @@ -25,7 +25,11 @@ pub fn is_valid_field_name(property_name: &str) -> bool { pub fn to_gql_type(value: &Value) -> String { match value { - Value::Null => "Empty", + Value::Null => { + // treat null values as JSON scalars as we don't know the exact shape of the + // output. + "JSON" + } Value::Bool(_) => "Boolean", Value::Number(_) => "Int", Value::String(_) => "String", @@ -81,7 +85,7 @@ mod test { assert_eq!(to_gql_type(&json!(false)), "Boolean"); assert_eq!(to_gql_type(&json!([1, 2, 3])), "List"); assert_eq!(to_gql_type(&json!({"name":"test", "age": 12})), "Object"); - assert_eq!(to_gql_type(&Value::Null), "Empty"); + assert_eq!(to_gql_type(&Value::Null), "JSON"); assert_eq!(to_gql_type(&json!([])), "List"); assert_eq!(to_gql_type(&json!({})), "Object"); From 1eb224b6c72f3a616474a5978a3dfced982c7690 Mon Sep 17 00:00:00 2001 From: Kiryl Mialeshka <8974488+meskill@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:18:49 +0200 Subject: [PATCH 02/77] refactor: simplify json_like trait (#2780) --- src/core/ir/discriminator.rs | 1 - src/core/jit/common/jp.rs | 9 +-------- src/core/jit/exec.rs | 3 +-- src/core/jit/synth/synth.rs | 1 - src/core/json/borrow.rs | 12 ++++++------ src/core/json/graphql.rs | 12 ++++++------ src/core/json/json_like.rs | 27 ++++++--------------------- src/core/json/serde.rs | 12 ++++++------ src/core/scalar.rs | 8 ++++---- 9 files changed, 30 insertions(+), 55 deletions(-) diff --git a/src/core/ir/discriminator.rs b/src/core/ir/discriminator.rs index ee8f08057c..127cc59414 100644 --- a/src/core/ir/discriminator.rs +++ b/src/core/ir/discriminator.rs @@ -23,7 +23,6 @@ const TYPENAME_FIELD: &str = "__typename"; impl<'json, T> TypedValue<'json> for T where T: JsonLike<'json>, - T::JsonObject<'json>: JsonObjectLike<'json, Value = T>, { type Error = anyhow::Error; diff --git a/src/core/jit/common/jp.rs b/src/core/jit/common/jp.rs index 521ecdfc8c..815d3a5311 100644 --- a/src/core/jit/common/jp.rs +++ b/src/core/jit/common/jp.rs @@ -83,14 +83,7 @@ impl<'a, Value: JsonLike<'a> + Deserialize<'a> + Clone + 'a> TestData { } } -impl< - 'a, - Value: Deserialize<'a> - + Clone - + 'a - + JsonLike<'a, JsonObject<'a>: JsonObjectLike<'a, Value = Value>>, - > JP -{ +impl<'a, Value: Deserialize<'a> + Clone + 'a + JsonLike<'a>> JP { const CONFIG: &'static str = include_str!("../fixtures/jsonplaceholder-mutation.graphql"); fn plan(query: &str, variables: &Variables) -> OperationPlan { diff --git a/src/core/jit/exec.rs b/src/core/jit/exec.rs index ee9a890bb2..f8d0da9331 100644 --- a/src/core/jit/exec.rs +++ b/src/core/jit/exec.rs @@ -25,8 +25,7 @@ pub struct Executor { impl Executor where - Output: - for<'b> JsonLike<'b, JsonObject<'b>: JsonObjectLike<'b, Value = Output>> + Debug + Clone, + Output: for<'b> JsonLike<'b> + Debug + Clone, Input: Clone + Debug, Exec: IRExecutor, { diff --git a/src/core/jit/synth/synth.rs b/src/core/jit/synth/synth.rs index 446fc8f00a..b5a9d4c7ad 100644 --- a/src/core/jit/synth/synth.rs +++ b/src/core/jit/synth/synth.rs @@ -26,7 +26,6 @@ impl Synth { impl<'a, Value> Synth where Value: JsonLike<'a> + Clone + std::fmt::Debug, - Value::JsonObject<'a>: JsonObjectLike<'a, Value = Value>, { #[inline(always)] fn include(&self, field: &Field) -> bool { diff --git a/src/core/json/borrow.rs b/src/core/json/borrow.rs index 59fd376d7c..1a38196ca8 100644 --- a/src/core/json/borrow.rs +++ b/src/core/json/borrow.rs @@ -12,7 +12,7 @@ impl<'ctx> JsonObjectLike<'ctx> for ObjectAsVec<'ctx> { ObjectAsVec::default() } - fn get_key(&'ctx self, key: &str) -> Option<&Value> { + fn get_key(&self, key: &str) -> Option<&Self::Value> { self.get(key) } @@ -22,13 +22,13 @@ impl<'ctx> JsonObjectLike<'ctx> for ObjectAsVec<'ctx> { } impl<'ctx> JsonLike<'ctx> for Value<'ctx> { - type JsonObject<'obj> = ObjectAsVec<'obj>; + type JsonObject = ObjectAsVec<'ctx>; fn null() -> Self { Value::Null } - fn object(obj: Self::JsonObject<'ctx>) -> Self { + fn object(obj: Self::JsonObject) -> Self { Value::Object(obj) } @@ -54,18 +54,18 @@ impl<'ctx> JsonLike<'ctx> for Value<'ctx> { } } - fn as_object(&self) -> Option<&Self::JsonObject<'_>> { + fn as_object(&self) -> Option<&Self::JsonObject> { self.as_object() } - fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject<'ctx>> { + fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject> { match self { Value::Object(obj) => Some(obj), _ => None, } } - fn into_object(self) -> Option> { + fn into_object(self) -> Option { match self { Value::Object(obj) => Some(obj), _ => None, diff --git a/src/core/json/graphql.rs b/src/core/json/graphql.rs index a41609a80a..aa049a8ed8 100644 --- a/src/core/json/graphql.rs +++ b/src/core/json/graphql.rs @@ -14,7 +14,7 @@ impl<'obj, Value: JsonLike<'obj> + Clone> JsonObjectLike<'obj> for IndexMap Option<&Self::Value> { + fn get_key(&self, key: &str) -> Option<&Self::Value> { self.get(key) } @@ -24,7 +24,7 @@ impl<'obj, Value: JsonLike<'obj> + Clone> JsonObjectLike<'obj> for IndexMap JsonLike<'json> for ConstValue { - type JsonObject<'obj> = IndexMap; + type JsonObject = IndexMap; fn as_array(&self) -> Option<&Vec> { match self { @@ -110,28 +110,28 @@ impl<'json> JsonLike<'json> for ConstValue { Default::default() } - fn as_object(&self) -> Option<&Self::JsonObject<'_>> { + fn as_object(&self) -> Option<&Self::JsonObject> { match self { ConstValue::Object(map) => Some(map), _ => None, } } - fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject<'_>> { + fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject> { match self { ConstValue::Object(map) => Some(map), _ => None, } } - fn into_object(self) -> Option> { + fn into_object(self) -> Option { match self { ConstValue::Object(map) => Some(map), _ => None, } } - fn object(obj: Self::JsonObject<'json>) -> Self { + fn object(obj: Self::JsonObject) -> Self { ConstValue::Object(obj) } diff --git a/src/core/json/json_like.rs b/src/core/json/json_like.rs index 2b10d39eb0..6452036e4a 100644 --- a/src/core/json/json_like.rs +++ b/src/core/json/json_like.rs @@ -6,35 +6,20 @@ impl JsonLikeOwned for T where T: for<'json> JsonLike<'json> {} /// A trait for objects that can be used as JSON values pub trait JsonLike<'json>: Sized { - type JsonObject<'obj>: JsonObjectLike< - 'obj, - // generally we want to specify `Self` instead of generic here - // and `Self` is used anyway through JsonObjectLike for - // current implementations. - // But `Self` means the very specific type with some specific lifetime - // which doesn't work in case we want to return self type but with different - // lifetime. Currently, it affects only `as_object` fn because `serde_json_borrow` - // returns smaller lifetime for Value in its `as_object` fn that either forces to - // use `&'json self` in the fn (that leads to error "variable does not live long enough") - // or generic like this. - // TODO: perhaps it could be fixed on `serde_json_borrow` side if we return `Value<'ctx>` - // instead of `Value<'_>` in its functions like `as_object`. In that case we can specify - // `Self` here and simplify usages of this trait - Value: JsonLike<'obj>, - >; + type JsonObject: JsonObjectLike<'json, Value = Self>; // Constructors fn null() -> Self; - fn object(obj: Self::JsonObject<'json>) -> Self; + fn object(obj: Self::JsonObject) -> Self; fn array(arr: Vec) -> Self; fn string(s: Cow<'json, str>) -> Self; // Operators fn as_array(&self) -> Option<&Vec>; fn into_array(self) -> Option>; - fn as_object(&self) -> Option<&Self::JsonObject<'_>>; - fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject<'json>>; - fn into_object(self) -> Option>; + fn as_object(&self) -> Option<&Self::JsonObject>; + fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject>; + fn into_object(self) -> Option; fn as_str(&self) -> Option<&str>; fn as_i64(&self) -> Option; fn as_u64(&self) -> Option; @@ -50,7 +35,7 @@ pub trait JsonLike<'json>: Sized { pub trait JsonObjectLike<'obj>: Sized { type Value; fn new() -> Self; - fn get_key(&'obj self, key: &str) -> Option<&Self::Value>; + fn get_key(&self, key: &str) -> Option<&Self::Value>; fn insert_key(&mut self, key: &'obj str, value: Self::Value); } diff --git a/src/core/json/serde.rs b/src/core/json/serde.rs index 8ee36499c8..4f6fad6609 100644 --- a/src/core/json/serde.rs +++ b/src/core/json/serde.rs @@ -10,7 +10,7 @@ impl<'obj> JsonObjectLike<'obj> for serde_json::Map { serde_json::Map::new() } - fn get_key(&'obj self, key: &str) -> Option<&serde_json::Value> { + fn get_key(&self, key: &str) -> Option<&serde_json::Value> { self.get(key) } @@ -20,7 +20,7 @@ impl<'obj> JsonObjectLike<'obj> for serde_json::Map { } impl<'json> JsonLike<'json> for serde_json::Value { - type JsonObject<'obj> = serde_json::Map; + type JsonObject = serde_json::Map; fn as_array(&self) -> Option<&Vec> { self.as_array() @@ -89,15 +89,15 @@ impl<'json> JsonLike<'json> for serde_json::Value { Self::Null } - fn as_object(&self) -> Option<&Self::JsonObject<'_>> { + fn as_object(&self) -> Option<&Self::JsonObject> { self.as_object() } - fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject<'_>> { + fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject> { self.as_object_mut() } - fn into_object(self) -> Option> { + fn into_object(self) -> Option { if let Self::Object(obj) = self { Some(obj) } else { @@ -105,7 +105,7 @@ impl<'json> JsonLike<'json> for serde_json::Value { } } - fn object(obj: Self::JsonObject<'json>) -> Self { + fn object(obj: Self::JsonObject) -> Self { serde_json::Value::Object(obj) } diff --git a/src/core/scalar.rs b/src/core/scalar.rs index 1cffeffb39..44e7a4b35a 100644 --- a/src/core/scalar.rs +++ b/src/core/scalar.rs @@ -75,14 +75,14 @@ pub enum Scalar { Bytes, } -fn eval_str<'a, Value: JsonLike<'a> + 'a, F: Fn(&str) -> bool>(val: &'a Value, fxn: F) -> bool { +fn eval_str<'a, Value: JsonLike<'a>, F: Fn(&str) -> bool>(val: &'a Value, fxn: F) -> bool { val.as_str().map_or(false, fxn) } fn eval_signed< 'a, Num, - Value: JsonLike<'a> + 'a, + Value: JsonLike<'a>, F: Fn(i64) -> Result, >( val: &'a Value, @@ -94,7 +94,7 @@ fn eval_signed< fn eval_unsigned< 'a, Num, - Value: JsonLike<'a> + 'a, + Value: JsonLike<'a>, F: Fn(u64) -> Result, >( val: &'a Value, @@ -114,7 +114,7 @@ impl Scalar { } } - pub fn validate<'a, Value: JsonLike<'a> + 'a>(&self, value: &'a Value) -> bool { + pub fn validate<'a, Value: JsonLike<'a>>(&self, value: &'a Value) -> bool { match self { Scalar::JSON => true, Scalar::Empty => true, From a3f1a673c9a73fc20688721179de3eb752b2a961 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:20:59 +0000 Subject: [PATCH 03/77] chore(deps): update dependency miniflare to v3.20240821.1 --- tailcall-cloudflare/package-lock.json | 58 ++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index c3e1278a7b..d350c745f9 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1454,9 +1454,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240821.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.0.tgz", - "integrity": "sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==", + "version": "3.20240821.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", + "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -2635,6 +2635,32 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "3.20240821.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.0.tgz", + "integrity": "sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==", + "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.4", + "workerd": "1.20240821.1", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3588,9 +3614,9 @@ "dev": true }, "miniflare": { - "version": "3.20240821.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.0.tgz", - "integrity": "sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==", + "version": "3.20240821.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", + "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", @@ -4294,6 +4320,26 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } + }, + "miniflare": { + "version": "3.20240821.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.0.tgz", + "integrity": "sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==", + "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.4", + "workerd": "1.20240821.1", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + } } } }, From 2a6d38d8a706d053f2bbac2130138fdb2dd561a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 00:45:36 +0000 Subject: [PATCH 04/77] fix(deps): update dependency yaml to v2.5.1 --- npm/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/npm/package-lock.json b/npm/package-lock.json index 7835e97807..ac8923d780 100644 --- a/npm/package-lock.json +++ b/npm/package-lock.json @@ -903,9 +903,9 @@ } }, "node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", "license": "ISC", "bin": { "yaml": "bin.mjs" From 0647148063afcf28100f266d25aae382385aba55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 04:07:07 +0000 Subject: [PATCH 05/77] chore(deps): update dependency wrangler to v3.74.0 --- tailcall-cloudflare/package-lock.json | 62 ++++----------------------- 1 file changed, 8 insertions(+), 54 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index d350c745f9..6d12ff472f 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -2203,9 +2203,9 @@ } }, "node_modules/wrangler": { - "version": "3.73.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.73.0.tgz", - "integrity": "sha512-VrdDR2OpvsCQp+r5Of3rDP1W64cNN/LHLVx1roULOlPS8PZiv7rUYgkwhdCQ61+HICAaeSxWYIzkL5+B9+8W3g==", + "version": "3.74.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.74.0.tgz", + "integrity": "sha512-wmtb+tQrgb61yN+Wa2JM98G1Gt4tKFRYPw6xwuyzUcA74L+Dum1A13w22/manl9Gq1jA3dPn+7UzT5sYEVHRog==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -2216,7 +2216,7 @@ "chokidar": "^3.5.3", "date-fns": "^3.6.0", "esbuild": "0.17.19", - "miniflare": "3.20240821.0", + "miniflare": "3.20240821.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -2635,32 +2635,6 @@ "@esbuild/win32-x64": "0.17.19" } }, - "node_modules/wrangler/node_modules/miniflare": { - "version": "3.20240821.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.0.tgz", - "integrity": "sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==", - "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.4", - "workerd": "1.20240821.1", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -4111,9 +4085,9 @@ } }, "wrangler": { - "version": "3.73.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.73.0.tgz", - "integrity": "sha512-VrdDR2OpvsCQp+r5Of3rDP1W64cNN/LHLVx1roULOlPS8PZiv7rUYgkwhdCQ61+HICAaeSxWYIzkL5+B9+8W3g==", + "version": "3.74.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.74.0.tgz", + "integrity": "sha512-wmtb+tQrgb61yN+Wa2JM98G1Gt4tKFRYPw6xwuyzUcA74L+Dum1A13w22/manl9Gq1jA3dPn+7UzT5sYEVHRog==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -4125,7 +4099,7 @@ "date-fns": "^3.6.0", "esbuild": "0.17.19", "fsevents": "~2.3.2", - "miniflare": "3.20240821.0", + "miniflare": "3.20240821.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -4320,26 +4294,6 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } - }, - "miniflare": { - "version": "3.20240821.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.0.tgz", - "integrity": "sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==", - "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.4", - "workerd": "1.20240821.1", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - } } } }, From 36aba8fd22414de4c76d98a8c47950b6d5ae930c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:07:41 +0000 Subject: [PATCH 06/77] chore(deps): update dependency @cloudflare/workers-types to v4.20240903.0 --- tailcall-cloudflare/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 6d12ff472f..bee89f9106 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -139,9 +139,9 @@ } }, "node_modules/@cloudflare/workers-types": { - "version": "4.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240821.1.tgz", - "integrity": "sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==", + "version": "4.20240903.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240903.0.tgz", + "integrity": "sha512-a4mqgtVsPWg3JNNlQdLRE0Z6/mHr/uXa1ANDw6Zd7in438UCbeb+j7Z954Sf93G24jExpAn9VZ8kUUml0RwZbQ==", "dev": true }, "node_modules/@cspotcode/source-map-support": { @@ -2757,9 +2757,9 @@ "dev": true }, "@cloudflare/workers-types": { - "version": "4.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240821.1.tgz", - "integrity": "sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==", + "version": "4.20240903.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240903.0.tgz", + "integrity": "sha512-a4mqgtVsPWg3JNNlQdLRE0Z6/mHr/uXa1ANDw6Zd7in438UCbeb+j7Z954Sf93G24jExpAn9VZ8kUUml0RwZbQ==", "dev": true }, "@cspotcode/source-map-support": { From 751759fff3c659386e9d1f26aa7a641e6e5e0f8c Mon Sep 17 00:00:00 2001 From: Sandipsinh Dilipsinh Rathod <62684960+ssddOnTop@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:47:19 +0000 Subject: [PATCH 07/77] fix: `cargo build` throwing fallback error (#2800) --- src/cli/javascript/runtime.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cli/javascript/runtime.rs b/src/cli/javascript/runtime.rs index b3cdb492b2..e568a060b8 100644 --- a/src/cli/javascript/runtime.rs +++ b/src/cli/javascript/runtime.rs @@ -31,12 +31,14 @@ fn setup_builtins(ctx: &Ctx<'_>) -> rquickjs::Result<()> { Ok(()) } -impl LocalRuntime { - fn try_new(script: blueprint::Script) -> anyhow::Result { +impl TryFrom for LocalRuntime { + type Error = anyhow::Error; + + fn try_from(script: blueprint::Script) -> Result { let source = script.source; let js_runtime = rquickjs::Runtime::new()?; let context = Context::full(&js_runtime)?; - context.with(|ctx| { + let _: () = context.with(|ctx| { setup_builtins(&ctx)?; ctx.eval(source) })?; @@ -126,7 +128,7 @@ fn init_rt(script: blueprint::Script) -> anyhow::Result<()> { // exit if failed to initialize LOCAL_RUNTIME.with(move |cell| { if cell.borrow().get().is_none() { - LocalRuntime::try_new(script).and_then(|runtime| { + LocalRuntime::try_from(script).and_then(|runtime| { cell.borrow().set(runtime).map_err(|_| { anyhow::anyhow!("trying to reinitialize an already initialized QuickJS runtime") }) From 006502e385c365d63a3f83307a4449c5889a1fc5 Mon Sep 17 00:00:00 2001 From: Sandipsinh Dilipsinh Rathod <62684960+ssddOnTop@users.noreply.github.com> Date: Mon, 9 Sep 2024 19:04:23 +0000 Subject: [PATCH 08/77] fix: onRequest returns No such file or directory (#2797) --- src/cli/javascript/runtime.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cli/javascript/runtime.rs b/src/cli/javascript/runtime.rs index e568a060b8..a3c2fc6933 100644 --- a/src/cli/javascript/runtime.rs +++ b/src/cli/javascript/runtime.rs @@ -24,9 +24,11 @@ fn qjs_print(msg: String, is_err: bool) { } } +static CONSOLE_JS: &[u8] = include_bytes!("shim/console.js"); + fn setup_builtins(ctx: &Ctx<'_>) -> rquickjs::Result<()> { ctx.globals().set("__qjs_print", js_qjs_print)?; - let _: Value = ctx.eval_file("src/cli/javascript/shim/console.js")?; + let _: Value = ctx.eval(CONSOLE_JS)?; Ok(()) } From 8f2f51945f29cd98c68d502cc308a818c2aef55b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 19:07:11 +0000 Subject: [PATCH 09/77] fix(deps): update dependency type-fest to v4.26.1 --- npm/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/npm/package-lock.json b/npm/package-lock.json index ac8923d780..2fca465b6d 100644 --- a/npm/package-lock.json +++ b/npm/package-lock.json @@ -863,9 +863,9 @@ } }, "node_modules/type-fest": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", - "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" From 2d0abae371b52ce8e683296471aa46bdd7c6e694 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:27:01 +0000 Subject: [PATCH 10/77] chore(deps): update dependency wrangler to v3.75.0 --- tailcall-cloudflare/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index bee89f9106..99a894a10e 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -2203,9 +2203,9 @@ } }, "node_modules/wrangler": { - "version": "3.74.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.74.0.tgz", - "integrity": "sha512-wmtb+tQrgb61yN+Wa2JM98G1Gt4tKFRYPw6xwuyzUcA74L+Dum1A13w22/manl9Gq1jA3dPn+7UzT5sYEVHRog==", + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.75.0.tgz", + "integrity": "sha512-CitNuNj0O1z6qbonUXmpUbxeWpU3nx28Kc4ZT33tMdeooQssb063Ie7+ZCdfS3kPhRHSwGdtOV22xFYytHON8w==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -4085,9 +4085,9 @@ } }, "wrangler": { - "version": "3.74.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.74.0.tgz", - "integrity": "sha512-wmtb+tQrgb61yN+Wa2JM98G1Gt4tKFRYPw6xwuyzUcA74L+Dum1A13w22/manl9Gq1jA3dPn+7UzT5sYEVHRog==", + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.75.0.tgz", + "integrity": "sha512-CitNuNj0O1z6qbonUXmpUbxeWpU3nx28Kc4ZT33tMdeooQssb063Ie7+ZCdfS3kPhRHSwGdtOV22xFYytHON8w==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", From 5f0032de8119ef9622bf51c65558e3b9f6895b01 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 13:48:35 +0000 Subject: [PATCH 11/77] chore(deps): update dependency @cloudflare/workers-types to v4.20240909.0 --- tailcall-cloudflare/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 99a894a10e..93b4d6907a 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -139,9 +139,9 @@ } }, "node_modules/@cloudflare/workers-types": { - "version": "4.20240903.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240903.0.tgz", - "integrity": "sha512-a4mqgtVsPWg3JNNlQdLRE0Z6/mHr/uXa1ANDw6Zd7in438UCbeb+j7Z954Sf93G24jExpAn9VZ8kUUml0RwZbQ==", + "version": "4.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240909.0.tgz", + "integrity": "sha512-4knwtX6efxIsIxawdmPyynU9+S8A78wntU8eUIEldStWP4gNgxGkeWcfCMXulTx8oxr3DU4aevHyld9HGV8VKQ==", "dev": true }, "node_modules/@cspotcode/source-map-support": { @@ -2757,9 +2757,9 @@ "dev": true }, "@cloudflare/workers-types": { - "version": "4.20240903.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240903.0.tgz", - "integrity": "sha512-a4mqgtVsPWg3JNNlQdLRE0Z6/mHr/uXa1ANDw6Zd7in438UCbeb+j7Z954Sf93G24jExpAn9VZ8kUUml0RwZbQ==", + "version": "4.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240909.0.tgz", + "integrity": "sha512-4knwtX6efxIsIxawdmPyynU9+S8A78wntU8eUIEldStWP4gNgxGkeWcfCMXulTx8oxr3DU4aevHyld9HGV8VKQ==", "dev": true }, "@cspotcode/source-map-support": { From bfcc6e9c707bedb4576bff32a44377343449c1b2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 22:38:17 +0000 Subject: [PATCH 12/77] chore(deps): update dependency miniflare to v3.20240821.2 --- tailcall-cloudflare/package-lock.json | 58 ++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 93b4d6907a..54a24f3b00 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1454,9 +1454,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240821.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", - "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", + "version": "3.20240821.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", + "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -2635,6 +2635,32 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "3.20240821.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", + "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", + "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.4", + "workerd": "1.20240821.1", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3588,9 +3614,9 @@ "dev": true }, "miniflare": { - "version": "3.20240821.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", - "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", + "version": "3.20240821.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", + "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", @@ -4294,6 +4320,26 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } + }, + "miniflare": { + "version": "3.20240821.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", + "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", + "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.4", + "workerd": "1.20240821.1", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + } } } }, From 1c195c59dd3388f94afa52b1c9d473004b8c0cd2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 07:25:34 +0000 Subject: [PATCH 13/77] chore(deps): update dependency tsx to v4.19.1 --- npm/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/npm/package-lock.json b/npm/package-lock.json index 2fca465b6d..6dcf132c46 100644 --- a/npm/package-lock.json +++ b/npm/package-lock.json @@ -843,9 +843,9 @@ } }, "node_modules/tsx": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", - "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz", + "integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==", "dev": true, "license": "MIT", "dependencies": { From 5d7e27540dea183dc6d0e80d3a7c3618beb687c5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:24:07 +0000 Subject: [PATCH 14/77] chore(deps): update dependency wrangler to v3.76.0 --- tailcall-cloudflare/package-lock.json | 62 ++++----------------------- 1 file changed, 8 insertions(+), 54 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 54a24f3b00..2f35b97981 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -2203,9 +2203,9 @@ } }, "node_modules/wrangler": { - "version": "3.75.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.75.0.tgz", - "integrity": "sha512-CitNuNj0O1z6qbonUXmpUbxeWpU3nx28Kc4ZT33tMdeooQssb063Ie7+ZCdfS3kPhRHSwGdtOV22xFYytHON8w==", + "version": "3.76.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.76.0.tgz", + "integrity": "sha512-HQWJm5/RUHVr+Vg2KM55pjDSbcEh5WxR6Swcpz1jQ5o+ytoLoj31IHMsl4cJFfM/JtzjBXSpRbS00lDnGfFc2A==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -2216,7 +2216,7 @@ "chokidar": "^3.5.3", "date-fns": "^3.6.0", "esbuild": "0.17.19", - "miniflare": "3.20240821.1", + "miniflare": "3.20240821.2", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -2635,32 +2635,6 @@ "@esbuild/win32-x64": "0.17.19" } }, - "node_modules/wrangler/node_modules/miniflare": { - "version": "3.20240821.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", - "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", - "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.4", - "workerd": "1.20240821.1", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -4111,9 +4085,9 @@ } }, "wrangler": { - "version": "3.75.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.75.0.tgz", - "integrity": "sha512-CitNuNj0O1z6qbonUXmpUbxeWpU3nx28Kc4ZT33tMdeooQssb063Ie7+ZCdfS3kPhRHSwGdtOV22xFYytHON8w==", + "version": "3.76.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.76.0.tgz", + "integrity": "sha512-HQWJm5/RUHVr+Vg2KM55pjDSbcEh5WxR6Swcpz1jQ5o+ytoLoj31IHMsl4cJFfM/JtzjBXSpRbS00lDnGfFc2A==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -4125,7 +4099,7 @@ "date-fns": "^3.6.0", "esbuild": "0.17.19", "fsevents": "~2.3.2", - "miniflare": "3.20240821.1", + "miniflare": "3.20240821.2", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -4320,26 +4294,6 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } - }, - "miniflare": { - "version": "3.20240821.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.1.tgz", - "integrity": "sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==", - "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.4", - "workerd": "1.20240821.1", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - } } } }, From 1f62858c08f2572f56377c7907680b2f5dbaa5e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 16:37:43 +0000 Subject: [PATCH 15/77] chore(deps): update dependency vitest to v2.1.0 --- tailcall-cloudflare/package-lock.json | 754 ++++++-------------------- 1 file changed, 178 insertions(+), 576 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 2f35b97981..b54f81a23a 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -14,29 +14,6 @@ "wrangler": "^3.24.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@ampproject/remapping/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@cloudflare/kv-asset-handler": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz", @@ -555,30 +532,6 @@ "node": ">=14" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", @@ -588,19 +541,10 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -833,13 +777,13 @@ } }, "node_modules/@vitest/expect": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", - "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.0.tgz", + "integrity": "sha512-N3/xR4fSu0+6sVZETEtPT1orUs2+Y477JOXTcU3xKuu3uBlsgbD7/7Mz2LZ1Jr1XjwilEWlrIgSCj4N1+5ZmsQ==", "dev": true, "dependencies": { - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", + "@vitest/spy": "2.1.0", + "@vitest/utils": "2.1.0", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" }, @@ -847,10 +791,37 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@vitest/mocker": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.0.tgz", + "integrity": "sha512-ZxENovUqhzl+QiOFpagiHUNUuZ1qPd5yYTCYHomGIZOFArzn4mgX2oxZmiAItJWAaXHG6bbpb/DpSPhlk5DgtA==", + "dev": true, + "dependencies": { + "@vitest/spy": "^2.1.0-beta.1", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.11" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/spy": "2.1.0", + "msw": "^2.3.5", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, "node_modules/@vitest/pretty-format": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", - "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.0.tgz", + "integrity": "sha512-7sxf2F3DNYatgmzXXcTh6cq+/fxwB47RIQqZJFoSH883wnVAoccSRT6g+dTKemUBo8Q5N4OYYj1EBXLuRKvp3Q==", "dev": true, "dependencies": { "tinyrainbow": "^1.2.0" @@ -860,12 +831,12 @@ } }, "node_modules/@vitest/runner": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", - "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.0.tgz", + "integrity": "sha512-D9+ZiB8MbMt7qWDRJc4CRNNUlne/8E1X7dcKhZVAbcOKG58MGGYVDqAq19xlhNfMFZsW0bpVKgztBwks38Ko0w==", "dev": true, "dependencies": { - "@vitest/utils": "2.0.5", + "@vitest/utils": "2.1.0", "pathe": "^1.1.2" }, "funding": { @@ -873,13 +844,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", - "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.0.tgz", + "integrity": "sha512-x69CygGMzt9VCO283K2/FYQ+nBrOj66OTKpsPykjCR4Ac3lLV+m85hj9reaIGmjBSsKzVvbxWmjWE3kF5ha3uQ==", "dev": true, "dependencies": { - "@vitest/pretty-format": "2.0.5", - "magic-string": "^0.30.10", + "@vitest/pretty-format": "2.1.0", + "magic-string": "^0.30.11", "pathe": "^1.1.2" }, "funding": { @@ -887,9 +858,9 @@ } }, "node_modules/@vitest/spy": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", - "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.0.tgz", + "integrity": "sha512-IXX5NkbdgTYTog3F14i2LgnBc+20YmkXMx0IWai84mcxySUDRgm0ihbOfR4L0EVRBDFG85GjmQQEZNNKVVpkZw==", "dev": true, "dependencies": { "tinyspy": "^3.0.0" @@ -899,13 +870,12 @@ } }, "node_modules/@vitest/utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", - "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.0.tgz", + "integrity": "sha512-rreyfVe0PuNqJfKYUwfPDfi6rrp0VSu0Wgvp5WBqJonP+4NvXHk48X6oBam1Lj47Hy6jbJtnMj3OcRdrkTP0tA==", "dev": true, "dependencies": { - "@vitest/pretty-format": "2.0.5", - "estree-walker": "^3.0.3", + "@vitest/pretty-format": "2.1.0", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" }, @@ -1072,20 +1042,6 @@ "node": ">= 0.6" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/data-uri-to-buffer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz", @@ -1103,12 +1059,12 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1193,29 +1149,6 @@ "@types/estree": "^1.0.0" } }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, "node_modules/exit-hook": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", @@ -1282,18 +1215,6 @@ "source-map": "^0.6.1" } }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1324,15 +1245,6 @@ "node": ">= 0.4" } }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1387,24 +1299,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -1415,20 +1309,14 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, "node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", @@ -1441,18 +1329,6 @@ "node": ">=10.0.0" } }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/miniflare": { "version": "3.20240821.2", "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", @@ -1480,9 +1356,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/mustache": { @@ -1530,63 +1406,12 @@ "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ohash": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", "dev": true }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -1802,45 +1627,12 @@ "node": ">=10" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1898,18 +1690,6 @@ "npm": ">=6" } }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -1923,9 +1703,15 @@ } }, "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true + }, + "node_modules/tinyexec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", + "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==", "dev": true }, "node_modules/tinypool": { @@ -1947,9 +1733,9 @@ } }, "node_modules/tinyspy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", - "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, "engines": { "node": ">=14.0.0" @@ -2066,15 +1852,14 @@ } }, "node_modules/vite-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", - "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.0.tgz", + "integrity": "sha512-+ybYqBVUjYyIscoLzMWodus2enQDZOpGhcU6HdOVD6n8WZdk12w1GFL3mbnxLs7hPtRtqs1Wo5YF6/Tsr6fmhg==", "dev": true, "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.5", + "debug": "^4.3.6", "pathe": "^1.1.2", - "tinyrainbow": "^1.2.0", "vite": "^5.0.0" }, "bin": { @@ -2088,29 +1873,29 @@ } }, "node_modules/vitest": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", - "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.0.tgz", + "integrity": "sha512-XuuEeyNkqbfr0FtAvd9vFbInSSNY1ykCQTYQ0sj9wPy4hx+1gR7gqVNdW0AX2wrrM1wWlN5fnJDjF9xG6mYRSQ==", "dev": true, "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.5", - "@vitest/pretty-format": "^2.0.5", - "@vitest/runner": "2.0.5", - "@vitest/snapshot": "2.0.5", - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", + "@vitest/expect": "2.1.0", + "@vitest/mocker": "2.1.0", + "@vitest/pretty-format": "^2.1.0", + "@vitest/runner": "2.1.0", + "@vitest/snapshot": "2.1.0", + "@vitest/spy": "2.1.0", + "@vitest/utils": "2.1.0", "chai": "^5.1.1", - "debug": "^4.3.5", - "execa": "^8.0.1", - "magic-string": "^0.30.10", + "debug": "^4.3.6", + "magic-string": "^0.30.11", "pathe": "^1.1.2", "std-env": "^3.7.0", - "tinybench": "^2.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.0", "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.0.5", + "vite-node": "2.1.0", "why-is-node-running": "^2.3.0" }, "bin": { @@ -2125,8 +1910,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.5", - "@vitest/ui": "2.0.5", + "@vitest/browser": "2.1.0", + "@vitest/ui": "2.1.0", "happy-dom": "*", "jsdom": "*" }, @@ -2151,21 +1936,6 @@ } } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -2684,28 +2454,6 @@ } }, "dependencies": { - "@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, "@cloudflare/kv-asset-handler": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz", @@ -2955,45 +2703,16 @@ "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", "dev": true }, - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, "@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true - }, "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "@jridgewell/trace-mapping": { @@ -3136,64 +2855,74 @@ } }, "@vitest/expect": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", - "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.0.tgz", + "integrity": "sha512-N3/xR4fSu0+6sVZETEtPT1orUs2+Y477JOXTcU3xKuu3uBlsgbD7/7Mz2LZ1Jr1XjwilEWlrIgSCj4N1+5ZmsQ==", "dev": true, "requires": { - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", + "@vitest/spy": "2.1.0", + "@vitest/utils": "2.1.0", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" } }, + "@vitest/mocker": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.0.tgz", + "integrity": "sha512-ZxENovUqhzl+QiOFpagiHUNUuZ1qPd5yYTCYHomGIZOFArzn4mgX2oxZmiAItJWAaXHG6bbpb/DpSPhlk5DgtA==", + "dev": true, + "requires": { + "@vitest/spy": "^2.1.0-beta.1", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.11" + } + }, "@vitest/pretty-format": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", - "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.0.tgz", + "integrity": "sha512-7sxf2F3DNYatgmzXXcTh6cq+/fxwB47RIQqZJFoSH883wnVAoccSRT6g+dTKemUBo8Q5N4OYYj1EBXLuRKvp3Q==", "dev": true, "requires": { "tinyrainbow": "^1.2.0" } }, "@vitest/runner": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", - "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.0.tgz", + "integrity": "sha512-D9+ZiB8MbMt7qWDRJc4CRNNUlne/8E1X7dcKhZVAbcOKG58MGGYVDqAq19xlhNfMFZsW0bpVKgztBwks38Ko0w==", "dev": true, "requires": { - "@vitest/utils": "2.0.5", + "@vitest/utils": "2.1.0", "pathe": "^1.1.2" } }, "@vitest/snapshot": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", - "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.0.tgz", + "integrity": "sha512-x69CygGMzt9VCO283K2/FYQ+nBrOj66OTKpsPykjCR4Ac3lLV+m85hj9reaIGmjBSsKzVvbxWmjWE3kF5ha3uQ==", "dev": true, "requires": { - "@vitest/pretty-format": "2.0.5", - "magic-string": "^0.30.10", + "@vitest/pretty-format": "2.1.0", + "magic-string": "^0.30.11", "pathe": "^1.1.2" } }, "@vitest/spy": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", - "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.0.tgz", + "integrity": "sha512-IXX5NkbdgTYTog3F14i2LgnBc+20YmkXMx0IWai84mcxySUDRgm0ihbOfR4L0EVRBDFG85GjmQQEZNNKVVpkZw==", "dev": true, "requires": { "tinyspy": "^3.0.0" } }, "@vitest/utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", - "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.0.tgz", + "integrity": "sha512-rreyfVe0PuNqJfKYUwfPDfi6rrp0VSu0Wgvp5WBqJonP+4NvXHk48X6oBam1Lj47Hy6jbJtnMj3OcRdrkTP0tA==", "dev": true, "requires": { - "@vitest/pretty-format": "2.0.5", - "estree-walker": "^3.0.3", + "@vitest/pretty-format": "2.1.0", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" } @@ -3313,17 +3042,6 @@ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "data-uri-to-buffer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz", @@ -3337,12 +3055,12 @@ "dev": true }, "debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "deep-eql": { @@ -3403,23 +3121,6 @@ "@types/estree": "^1.0.0" } }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, "exit-hook": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", @@ -3464,12 +3165,6 @@ "source-map": "^0.6.1" } }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -3494,12 +3189,6 @@ "function-bind": "^1.1.2" } }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3539,18 +3228,6 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, "loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -3561,32 +3238,20 @@ } }, "magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, "mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "dev": true }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, "miniflare": { "version": "3.20240821.2", "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", @@ -3608,9 +3273,9 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "mustache": { @@ -3637,44 +3302,12 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - }, - "dependencies": { - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - } - } - }, "ohash": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", "dev": true }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -3843,33 +3476,12 @@ "node-forge": "^1" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, "siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3916,12 +3528,6 @@ "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", "dev": true }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -3929,9 +3535,15 @@ "dev": true }, "tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true + }, + "tinyexec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", + "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==", "dev": true }, "tinypool": { @@ -3947,9 +3559,9 @@ "dev": true }, "tinyspy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", - "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true }, "to-regex-range": { @@ -4013,54 +3625,44 @@ } }, "vite-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", - "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.0.tgz", + "integrity": "sha512-+ybYqBVUjYyIscoLzMWodus2enQDZOpGhcU6HdOVD6n8WZdk12w1GFL3mbnxLs7hPtRtqs1Wo5YF6/Tsr6fmhg==", "dev": true, "requires": { "cac": "^6.7.14", - "debug": "^4.3.5", + "debug": "^4.3.6", "pathe": "^1.1.2", - "tinyrainbow": "^1.2.0", "vite": "^5.0.0" } }, "vitest": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", - "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.0.tgz", + "integrity": "sha512-XuuEeyNkqbfr0FtAvd9vFbInSSNY1ykCQTYQ0sj9wPy4hx+1gR7gqVNdW0AX2wrrM1wWlN5fnJDjF9xG6mYRSQ==", "dev": true, "requires": { - "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.5", - "@vitest/pretty-format": "^2.0.5", - "@vitest/runner": "2.0.5", - "@vitest/snapshot": "2.0.5", - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", + "@vitest/expect": "2.1.0", + "@vitest/mocker": "2.1.0", + "@vitest/pretty-format": "^2.1.0", + "@vitest/runner": "2.1.0", + "@vitest/snapshot": "2.1.0", + "@vitest/spy": "2.1.0", + "@vitest/utils": "2.1.0", "chai": "^5.1.1", - "debug": "^4.3.5", - "execa": "^8.0.1", - "magic-string": "^0.30.10", + "debug": "^4.3.6", + "magic-string": "^0.30.11", "pathe": "^1.1.2", "std-env": "^3.7.0", - "tinybench": "^2.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.0", "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.0.5", + "vite-node": "2.1.0", "why-is-node-running": "^2.3.0" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", From 56bdf27e11d09471c532f86e210eb174d5508e2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 22:19:12 +0000 Subject: [PATCH 16/77] chore(deps): update dependency miniflare to v3.20240909.0 --- tailcall-cloudflare/package-lock.json | 212 +++++++++++++++++++++++++- 1 file changed, 204 insertions(+), 8 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index b54f81a23a..80c0588bdd 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1330,9 +1330,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240821.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", - "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", + "version": "3.20240909.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.0.tgz", + "integrity": "sha512-20eJCCToBvxohLW0vWZHPRL6JPbqJQ4nkCK6MelgTRkw4CLd7MUYbY70M8olJjTuBDK/84/1CkNC4Q/OrbHIDA==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -1343,7 +1343,7 @@ "glob-to-regexp": "^0.4.1", "stoppable": "^1.1.0", "undici": "^5.28.4", - "workerd": "1.20240821.1", + "workerd": "1.20240909.0", "ws": "^8.17.1", "youch": "^3.2.2", "zod": "^3.22.3" @@ -1355,6 +1355,106 @@ "node": ">=16.13" } }, + "node_modules/miniflare/node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240909.0.tgz", + "integrity": "sha512-nJ8jm/6PR8DPzVb4QifNAfSdrFZXNblwIdOhLTU5FpSvFFocmzFX5WgzQagvtmcC9/ZAQyxuf7WynDNyBcoe0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/miniflare/node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240909.0.tgz", + "integrity": "sha512-gJqKa811oSsoxy9xuoQn7bS0Hr1sY+o3EUORTcEnulG6Kz9NQ6nd8QNdp2Hrk2jmmSqwrNkn+a6PZkWzk6Q0Gw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/miniflare/node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240909.0.tgz", + "integrity": "sha512-sJrmtccfMg73sZljiBpe4R+lhF58TqzqhF2pQG8HRjyxkzkM1sjpZqfEFaIkNUDqd3/Ibji49fklhPCGXljKSg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/miniflare/node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240909.0.tgz", + "integrity": "sha512-dTbSdceyRXPOSER+18AwYRbPQG0e/Dwl2trmfMMCETkfJhNLv1fU3FFMJPjfILijKnhTZHSnHCx0+xwHdon2fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/miniflare/node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240909.0.tgz", + "integrity": "sha512-/d4BT0kcWFa7Qc0K4K9+cwVQ1qyPNKiO42JZUijlDlco+TYTPkLO3qGEohmwbfMq+BieK7JTMSgjO81ZHpA0HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/miniflare/node_modules/workerd": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240909.0.tgz", + "integrity": "sha512-NwuYh/Fgr/MK0H+Ht687sHl/f8tumwT5CWzYR0MZMHri8m3CIYu2IaY4tBFWoKE/tOU1Z5XjEXECa9zXY4+lwg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20240909.0", + "@cloudflare/workerd-darwin-arm64": "1.20240909.0", + "@cloudflare/workerd-linux-64": "1.20240909.0", + "@cloudflare/workerd-linux-arm64": "1.20240909.0", + "@cloudflare/workerd-windows-64": "1.20240909.0" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2405,6 +2505,32 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "3.20240821.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", + "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", + "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.4", + "workerd": "1.20240821.1", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3253,9 +3379,9 @@ "dev": true }, "miniflare": { - "version": "3.20240821.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", - "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", + "version": "3.20240909.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.0.tgz", + "integrity": "sha512-20eJCCToBvxohLW0vWZHPRL6JPbqJQ4nkCK6MelgTRkw4CLd7MUYbY70M8olJjTuBDK/84/1CkNC4Q/OrbHIDA==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", @@ -3266,10 +3392,60 @@ "glob-to-regexp": "^0.4.1", "stoppable": "^1.1.0", "undici": "^5.28.4", - "workerd": "1.20240821.1", + "workerd": "1.20240909.0", "ws": "^8.17.1", "youch": "^3.2.2", "zod": "^3.22.3" + }, + "dependencies": { + "@cloudflare/workerd-darwin-64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240909.0.tgz", + "integrity": "sha512-nJ8jm/6PR8DPzVb4QifNAfSdrFZXNblwIdOhLTU5FpSvFFocmzFX5WgzQagvtmcC9/ZAQyxuf7WynDNyBcoe0Q==", + "dev": true, + "optional": true + }, + "@cloudflare/workerd-darwin-arm64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240909.0.tgz", + "integrity": "sha512-gJqKa811oSsoxy9xuoQn7bS0Hr1sY+o3EUORTcEnulG6Kz9NQ6nd8QNdp2Hrk2jmmSqwrNkn+a6PZkWzk6Q0Gw==", + "dev": true, + "optional": true + }, + "@cloudflare/workerd-linux-64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240909.0.tgz", + "integrity": "sha512-sJrmtccfMg73sZljiBpe4R+lhF58TqzqhF2pQG8HRjyxkzkM1sjpZqfEFaIkNUDqd3/Ibji49fklhPCGXljKSg==", + "dev": true, + "optional": true + }, + "@cloudflare/workerd-linux-arm64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240909.0.tgz", + "integrity": "sha512-dTbSdceyRXPOSER+18AwYRbPQG0e/Dwl2trmfMMCETkfJhNLv1fU3FFMJPjfILijKnhTZHSnHCx0+xwHdon2fg==", + "dev": true, + "optional": true + }, + "@cloudflare/workerd-windows-64": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240909.0.tgz", + "integrity": "sha512-/d4BT0kcWFa7Qc0K4K9+cwVQ1qyPNKiO42JZUijlDlco+TYTPkLO3qGEohmwbfMq+BieK7JTMSgjO81ZHpA0HQ==", + "dev": true, + "optional": true + }, + "workerd": { + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240909.0.tgz", + "integrity": "sha512-NwuYh/Fgr/MK0H+Ht687sHl/f8tumwT5CWzYR0MZMHri8m3CIYu2IaY4tBFWoKE/tOU1Z5XjEXECa9zXY4+lwg==", + "dev": true, + "requires": { + "@cloudflare/workerd-darwin-64": "1.20240909.0", + "@cloudflare/workerd-darwin-arm64": "1.20240909.0", + "@cloudflare/workerd-linux-64": "1.20240909.0", + "@cloudflare/workerd-linux-arm64": "1.20240909.0", + "@cloudflare/workerd-windows-64": "1.20240909.0" + } + } } }, "ms": { @@ -3896,6 +4072,26 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } + }, + "miniflare": { + "version": "3.20240821.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", + "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", + "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.4", + "workerd": "1.20240821.1", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + } } } }, From bf8236f12d63b219af2327891cd6102e3beb1b75 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 16:32:48 +0000 Subject: [PATCH 17/77] chore(deps): update dependency vitest to v2.1.1 --- tailcall-cloudflare/package-lock.json | 166 +++++++++++++------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 80c0588bdd..209d94e094 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -777,13 +777,13 @@ } }, "node_modules/@vitest/expect": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.0.tgz", - "integrity": "sha512-N3/xR4fSu0+6sVZETEtPT1orUs2+Y477JOXTcU3xKuu3uBlsgbD7/7Mz2LZ1Jr1XjwilEWlrIgSCj4N1+5ZmsQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.1.tgz", + "integrity": "sha512-YeueunS0HiHiQxk+KEOnq/QMzlUuOzbU1Go+PgAsHvvv3tUkJPm9xWt+6ITNTlzsMXUjmgm5T+U7KBPK2qQV6w==", "dev": true, "dependencies": { - "@vitest/spy": "2.1.0", - "@vitest/utils": "2.1.0", + "@vitest/spy": "2.1.1", + "@vitest/utils": "2.1.1", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" }, @@ -792,9 +792,9 @@ } }, "node_modules/@vitest/mocker": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.0.tgz", - "integrity": "sha512-ZxENovUqhzl+QiOFpagiHUNUuZ1qPd5yYTCYHomGIZOFArzn4mgX2oxZmiAItJWAaXHG6bbpb/DpSPhlk5DgtA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.1.tgz", + "integrity": "sha512-LNN5VwOEdJqCmJ/2XJBywB11DLlkbY0ooDJW3uRX5cZyYCrc4PI/ePX0iQhE3BiEGiQmK4GE7Q/PqCkkaiPnrA==", "dev": true, "dependencies": { "@vitest/spy": "^2.1.0-beta.1", @@ -805,7 +805,7 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/spy": "2.1.0", + "@vitest/spy": "2.1.1", "msw": "^2.3.5", "vite": "^5.0.0" }, @@ -819,9 +819,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.0.tgz", - "integrity": "sha512-7sxf2F3DNYatgmzXXcTh6cq+/fxwB47RIQqZJFoSH883wnVAoccSRT6g+dTKemUBo8Q5N4OYYj1EBXLuRKvp3Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.1.tgz", + "integrity": "sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==", "dev": true, "dependencies": { "tinyrainbow": "^1.2.0" @@ -831,12 +831,12 @@ } }, "node_modules/@vitest/runner": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.0.tgz", - "integrity": "sha512-D9+ZiB8MbMt7qWDRJc4CRNNUlne/8E1X7dcKhZVAbcOKG58MGGYVDqAq19xlhNfMFZsW0bpVKgztBwks38Ko0w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.1.tgz", + "integrity": "sha512-uTPuY6PWOYitIkLPidaY5L3t0JJITdGTSwBtwMjKzo5O6RCOEncz9PUN+0pDidX8kTHYjO0EwUIvhlGpnGpxmA==", "dev": true, "dependencies": { - "@vitest/utils": "2.1.0", + "@vitest/utils": "2.1.1", "pathe": "^1.1.2" }, "funding": { @@ -844,12 +844,12 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.0.tgz", - "integrity": "sha512-x69CygGMzt9VCO283K2/FYQ+nBrOj66OTKpsPykjCR4Ac3lLV+m85hj9reaIGmjBSsKzVvbxWmjWE3kF5ha3uQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.1.tgz", + "integrity": "sha512-BnSku1WFy7r4mm96ha2FzN99AZJgpZOWrAhtQfoxjUU5YMRpq1zmHRq7a5K9/NjqonebO7iVDla+VvZS8BOWMw==", "dev": true, "dependencies": { - "@vitest/pretty-format": "2.1.0", + "@vitest/pretty-format": "2.1.1", "magic-string": "^0.30.11", "pathe": "^1.1.2" }, @@ -858,9 +858,9 @@ } }, "node_modules/@vitest/spy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.0.tgz", - "integrity": "sha512-IXX5NkbdgTYTog3F14i2LgnBc+20YmkXMx0IWai84mcxySUDRgm0ihbOfR4L0EVRBDFG85GjmQQEZNNKVVpkZw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.1.tgz", + "integrity": "sha512-ZM39BnZ9t/xZ/nF4UwRH5il0Sw93QnZXd9NAZGRpIgj0yvVwPpLd702s/Cx955rGaMlyBQkZJ2Ir7qyY48VZ+g==", "dev": true, "dependencies": { "tinyspy": "^3.0.0" @@ -870,12 +870,12 @@ } }, "node_modules/@vitest/utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.0.tgz", - "integrity": "sha512-rreyfVe0PuNqJfKYUwfPDfi6rrp0VSu0Wgvp5WBqJonP+4NvXHk48X6oBam1Lj47Hy6jbJtnMj3OcRdrkTP0tA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.1.tgz", + "integrity": "sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==", "dev": true, "dependencies": { - "@vitest/pretty-format": "2.1.0", + "@vitest/pretty-format": "2.1.1", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" }, @@ -1952,9 +1952,9 @@ } }, "node_modules/vite-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.0.tgz", - "integrity": "sha512-+ybYqBVUjYyIscoLzMWodus2enQDZOpGhcU6HdOVD6n8WZdk12w1GFL3mbnxLs7hPtRtqs1Wo5YF6/Tsr6fmhg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.1.tgz", + "integrity": "sha512-N/mGckI1suG/5wQI35XeR9rsMsPqKXzq1CdUndzVstBj/HvyxxGctwnK6WX43NGt5L3Z5tcRf83g4TITKJhPrA==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -1973,18 +1973,18 @@ } }, "node_modules/vitest": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.0.tgz", - "integrity": "sha512-XuuEeyNkqbfr0FtAvd9vFbInSSNY1ykCQTYQ0sj9wPy4hx+1gR7gqVNdW0AX2wrrM1wWlN5fnJDjF9xG6mYRSQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.1.tgz", + "integrity": "sha512-97We7/VC0e9X5zBVkvt7SGQMGrRtn3KtySFQG5fpaMlS+l62eeXRQO633AYhSTC3z7IMebnPPNjGXVGNRFlxBA==", "dev": true, "dependencies": { - "@vitest/expect": "2.1.0", - "@vitest/mocker": "2.1.0", - "@vitest/pretty-format": "^2.1.0", - "@vitest/runner": "2.1.0", - "@vitest/snapshot": "2.1.0", - "@vitest/spy": "2.1.0", - "@vitest/utils": "2.1.0", + "@vitest/expect": "2.1.1", + "@vitest/mocker": "2.1.1", + "@vitest/pretty-format": "^2.1.1", + "@vitest/runner": "2.1.1", + "@vitest/snapshot": "2.1.1", + "@vitest/spy": "2.1.1", + "@vitest/utils": "2.1.1", "chai": "^5.1.1", "debug": "^4.3.6", "magic-string": "^0.30.11", @@ -1995,7 +1995,7 @@ "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.1.0", + "vite-node": "2.1.1", "why-is-node-running": "^2.3.0" }, "bin": { @@ -2010,8 +2010,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.0", - "@vitest/ui": "2.1.0", + "@vitest/browser": "2.1.1", + "@vitest/ui": "2.1.1", "happy-dom": "*", "jsdom": "*" }, @@ -2981,21 +2981,21 @@ } }, "@vitest/expect": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.0.tgz", - "integrity": "sha512-N3/xR4fSu0+6sVZETEtPT1orUs2+Y477JOXTcU3xKuu3uBlsgbD7/7Mz2LZ1Jr1XjwilEWlrIgSCj4N1+5ZmsQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.1.tgz", + "integrity": "sha512-YeueunS0HiHiQxk+KEOnq/QMzlUuOzbU1Go+PgAsHvvv3tUkJPm9xWt+6ITNTlzsMXUjmgm5T+U7KBPK2qQV6w==", "dev": true, "requires": { - "@vitest/spy": "2.1.0", - "@vitest/utils": "2.1.0", + "@vitest/spy": "2.1.1", + "@vitest/utils": "2.1.1", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" } }, "@vitest/mocker": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.0.tgz", - "integrity": "sha512-ZxENovUqhzl+QiOFpagiHUNUuZ1qPd5yYTCYHomGIZOFArzn4mgX2oxZmiAItJWAaXHG6bbpb/DpSPhlk5DgtA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.1.tgz", + "integrity": "sha512-LNN5VwOEdJqCmJ/2XJBywB11DLlkbY0ooDJW3uRX5cZyYCrc4PI/ePX0iQhE3BiEGiQmK4GE7Q/PqCkkaiPnrA==", "dev": true, "requires": { "@vitest/spy": "^2.1.0-beta.1", @@ -3004,51 +3004,51 @@ } }, "@vitest/pretty-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.0.tgz", - "integrity": "sha512-7sxf2F3DNYatgmzXXcTh6cq+/fxwB47RIQqZJFoSH883wnVAoccSRT6g+dTKemUBo8Q5N4OYYj1EBXLuRKvp3Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.1.tgz", + "integrity": "sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==", "dev": true, "requires": { "tinyrainbow": "^1.2.0" } }, "@vitest/runner": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.0.tgz", - "integrity": "sha512-D9+ZiB8MbMt7qWDRJc4CRNNUlne/8E1X7dcKhZVAbcOKG58MGGYVDqAq19xlhNfMFZsW0bpVKgztBwks38Ko0w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.1.tgz", + "integrity": "sha512-uTPuY6PWOYitIkLPidaY5L3t0JJITdGTSwBtwMjKzo5O6RCOEncz9PUN+0pDidX8kTHYjO0EwUIvhlGpnGpxmA==", "dev": true, "requires": { - "@vitest/utils": "2.1.0", + "@vitest/utils": "2.1.1", "pathe": "^1.1.2" } }, "@vitest/snapshot": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.0.tgz", - "integrity": "sha512-x69CygGMzt9VCO283K2/FYQ+nBrOj66OTKpsPykjCR4Ac3lLV+m85hj9reaIGmjBSsKzVvbxWmjWE3kF5ha3uQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.1.tgz", + "integrity": "sha512-BnSku1WFy7r4mm96ha2FzN99AZJgpZOWrAhtQfoxjUU5YMRpq1zmHRq7a5K9/NjqonebO7iVDla+VvZS8BOWMw==", "dev": true, "requires": { - "@vitest/pretty-format": "2.1.0", + "@vitest/pretty-format": "2.1.1", "magic-string": "^0.30.11", "pathe": "^1.1.2" } }, "@vitest/spy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.0.tgz", - "integrity": "sha512-IXX5NkbdgTYTog3F14i2LgnBc+20YmkXMx0IWai84mcxySUDRgm0ihbOfR4L0EVRBDFG85GjmQQEZNNKVVpkZw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.1.tgz", + "integrity": "sha512-ZM39BnZ9t/xZ/nF4UwRH5il0Sw93QnZXd9NAZGRpIgj0yvVwPpLd702s/Cx955rGaMlyBQkZJ2Ir7qyY48VZ+g==", "dev": true, "requires": { "tinyspy": "^3.0.0" } }, "@vitest/utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.0.tgz", - "integrity": "sha512-rreyfVe0PuNqJfKYUwfPDfi6rrp0VSu0Wgvp5WBqJonP+4NvXHk48X6oBam1Lj47Hy6jbJtnMj3OcRdrkTP0tA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.1.tgz", + "integrity": "sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==", "dev": true, "requires": { - "@vitest/pretty-format": "2.1.0", + "@vitest/pretty-format": "2.1.1", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" } @@ -3801,9 +3801,9 @@ } }, "vite-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.0.tgz", - "integrity": "sha512-+ybYqBVUjYyIscoLzMWodus2enQDZOpGhcU6HdOVD6n8WZdk12w1GFL3mbnxLs7hPtRtqs1Wo5YF6/Tsr6fmhg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.1.tgz", + "integrity": "sha512-N/mGckI1suG/5wQI35XeR9rsMsPqKXzq1CdUndzVstBj/HvyxxGctwnK6WX43NGt5L3Z5tcRf83g4TITKJhPrA==", "dev": true, "requires": { "cac": "^6.7.14", @@ -3813,18 +3813,18 @@ } }, "vitest": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.0.tgz", - "integrity": "sha512-XuuEeyNkqbfr0FtAvd9vFbInSSNY1ykCQTYQ0sj9wPy4hx+1gR7gqVNdW0AX2wrrM1wWlN5fnJDjF9xG6mYRSQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.1.tgz", + "integrity": "sha512-97We7/VC0e9X5zBVkvt7SGQMGrRtn3KtySFQG5fpaMlS+l62eeXRQO633AYhSTC3z7IMebnPPNjGXVGNRFlxBA==", "dev": true, "requires": { - "@vitest/expect": "2.1.0", - "@vitest/mocker": "2.1.0", - "@vitest/pretty-format": "^2.1.0", - "@vitest/runner": "2.1.0", - "@vitest/snapshot": "2.1.0", - "@vitest/spy": "2.1.0", - "@vitest/utils": "2.1.0", + "@vitest/expect": "2.1.1", + "@vitest/mocker": "2.1.1", + "@vitest/pretty-format": "^2.1.1", + "@vitest/runner": "2.1.1", + "@vitest/snapshot": "2.1.1", + "@vitest/spy": "2.1.1", + "@vitest/utils": "2.1.1", "chai": "^5.1.1", "debug": "^4.3.6", "magic-string": "^0.30.11", @@ -3835,7 +3835,7 @@ "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.1.0", + "vite-node": "2.1.1", "why-is-node-running": "^2.3.0" } }, From 56657f48265a539fc1ef8282b254c6bfdad58f50 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:21:49 +0000 Subject: [PATCH 18/77] chore(deps): update dependency miniflare to v3.20240909.1 --- tailcall-cloudflare/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 209d94e094..92cb683da0 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1330,9 +1330,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240909.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.0.tgz", - "integrity": "sha512-20eJCCToBvxohLW0vWZHPRL6JPbqJQ4nkCK6MelgTRkw4CLd7MUYbY70M8olJjTuBDK/84/1CkNC4Q/OrbHIDA==", + "version": "3.20240909.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", + "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -3379,9 +3379,9 @@ "dev": true }, "miniflare": { - "version": "3.20240909.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.0.tgz", - "integrity": "sha512-20eJCCToBvxohLW0vWZHPRL6JPbqJQ4nkCK6MelgTRkw4CLd7MUYbY70M8olJjTuBDK/84/1CkNC4Q/OrbHIDA==", + "version": "3.20240909.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", + "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", From c6ec713c9e25e0227679d47eb70d1c6971d1d414 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 02:15:41 +0000 Subject: [PATCH 19/77] chore(deps): update dependency wrangler to v3.78.2 --- tailcall-cloudflare/package-lock.json | 336 ++++++-------------------- 1 file changed, 74 insertions(+), 262 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 92cb683da0..9b0a26d65a 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -27,9 +27,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240821.1.tgz", - "integrity": "sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240909.0.tgz", + "integrity": "sha512-nJ8jm/6PR8DPzVb4QifNAfSdrFZXNblwIdOhLTU5FpSvFFocmzFX5WgzQagvtmcC9/ZAQyxuf7WynDNyBcoe0Q==", "cpu": [ "x64" ], @@ -43,9 +43,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240821.1.tgz", - "integrity": "sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240909.0.tgz", + "integrity": "sha512-gJqKa811oSsoxy9xuoQn7bS0Hr1sY+o3EUORTcEnulG6Kz9NQ6nd8QNdp2Hrk2jmmSqwrNkn+a6PZkWzk6Q0Gw==", "cpu": [ "arm64" ], @@ -59,9 +59,9 @@ } }, "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240821.1.tgz", - "integrity": "sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240909.0.tgz", + "integrity": "sha512-sJrmtccfMg73sZljiBpe4R+lhF58TqzqhF2pQG8HRjyxkzkM1sjpZqfEFaIkNUDqd3/Ibji49fklhPCGXljKSg==", "cpu": [ "x64" ], @@ -75,9 +75,9 @@ } }, "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240821.1.tgz", - "integrity": "sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240909.0.tgz", + "integrity": "sha512-dTbSdceyRXPOSER+18AwYRbPQG0e/Dwl2trmfMMCETkfJhNLv1fU3FFMJPjfILijKnhTZHSnHCx0+xwHdon2fg==", "cpu": [ "arm64" ], @@ -91,9 +91,9 @@ } }, "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240821.1.tgz", - "integrity": "sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240909.0.tgz", + "integrity": "sha512-/d4BT0kcWFa7Qc0K4K9+cwVQ1qyPNKiO42JZUijlDlco+TYTPkLO3qGEohmwbfMq+BieK7JTMSgjO81ZHpA0HQ==", "cpu": [ "x64" ], @@ -107,10 +107,14 @@ } }, "node_modules/@cloudflare/workers-shared": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.4.1.tgz", - "integrity": "sha512-nYh4r8JwOOjYIdH2zub++CmIKlkYFlpxI1nBHimoiHcytJXD/b7ldJ21TtfzUZMCgI78mxVlymMHA/ReaOxKlA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.5.3.tgz", + "integrity": "sha512-Yk5Im7zsyKbzd7qi+DrL7ZJR9+bdZwq9BqZWS4muDIWA8MCUeSLsUC+C9u+jdwfPSi5It2AcQG4f0iwZr6jkkQ==", "dev": true, + "dependencies": { + "mime": "^3.0.0", + "zod": "^3.22.3" + }, "engines": { "node": ">=16.7.0" } @@ -1355,106 +1359,6 @@ "node": ">=16.13" } }, - "node_modules/miniflare/node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240909.0.tgz", - "integrity": "sha512-nJ8jm/6PR8DPzVb4QifNAfSdrFZXNblwIdOhLTU5FpSvFFocmzFX5WgzQagvtmcC9/ZAQyxuf7WynDNyBcoe0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/miniflare/node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240909.0.tgz", - "integrity": "sha512-gJqKa811oSsoxy9xuoQn7bS0Hr1sY+o3EUORTcEnulG6Kz9NQ6nd8QNdp2Hrk2jmmSqwrNkn+a6PZkWzk6Q0Gw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/miniflare/node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240909.0.tgz", - "integrity": "sha512-sJrmtccfMg73sZljiBpe4R+lhF58TqzqhF2pQG8HRjyxkzkM1sjpZqfEFaIkNUDqd3/Ibji49fklhPCGXljKSg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/miniflare/node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240909.0.tgz", - "integrity": "sha512-dTbSdceyRXPOSER+18AwYRbPQG0e/Dwl2trmfMMCETkfJhNLv1fU3FFMJPjfILijKnhTZHSnHCx0+xwHdon2fg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/miniflare/node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240909.0.tgz", - "integrity": "sha512-/d4BT0kcWFa7Qc0K4K9+cwVQ1qyPNKiO42JZUijlDlco+TYTPkLO3qGEohmwbfMq+BieK7JTMSgjO81ZHpA0HQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/miniflare/node_modules/workerd": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240909.0.tgz", - "integrity": "sha512-NwuYh/Fgr/MK0H+Ht687sHl/f8tumwT5CWzYR0MZMHri8m3CIYu2IaY4tBFWoKE/tOU1Z5XjEXECa9zXY4+lwg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "workerd": "bin/workerd" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20240909.0", - "@cloudflare/workerd-darwin-arm64": "1.20240909.0", - "@cloudflare/workerd-linux-64": "1.20240909.0", - "@cloudflare/workerd-linux-arm64": "1.20240909.0", - "@cloudflare/workerd-windows-64": "1.20240909.0" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2053,9 +1957,9 @@ } }, "node_modules/workerd": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240821.1.tgz", - "integrity": "sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240909.0.tgz", + "integrity": "sha512-NwuYh/Fgr/MK0H+Ht687sHl/f8tumwT5CWzYR0MZMHri8m3CIYu2IaY4tBFWoKE/tOU1Z5XjEXECa9zXY4+lwg==", "dev": true, "hasInstallScript": true, "bin": { @@ -2065,28 +1969,28 @@ "node": ">=16" }, "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20240821.1", - "@cloudflare/workerd-darwin-arm64": "1.20240821.1", - "@cloudflare/workerd-linux-64": "1.20240821.1", - "@cloudflare/workerd-linux-arm64": "1.20240821.1", - "@cloudflare/workerd-windows-64": "1.20240821.1" + "@cloudflare/workerd-darwin-64": "1.20240909.0", + "@cloudflare/workerd-darwin-arm64": "1.20240909.0", + "@cloudflare/workerd-linux-64": "1.20240909.0", + "@cloudflare/workerd-linux-arm64": "1.20240909.0", + "@cloudflare/workerd-windows-64": "1.20240909.0" } }, "node_modules/wrangler": { - "version": "3.76.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.76.0.tgz", - "integrity": "sha512-HQWJm5/RUHVr+Vg2KM55pjDSbcEh5WxR6Swcpz1jQ5o+ytoLoj31IHMsl4cJFfM/JtzjBXSpRbS00lDnGfFc2A==", + "version": "3.78.2", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.2.tgz", + "integrity": "sha512-PL7GchswGrNm2OvdSw5yG3ZAqNjpaQIO++p8E1TaCi63DSyssKFYeYqTvfFshsQPP2u1dox5JFXtLc6IE/m1xw==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", - "@cloudflare/workers-shared": "0.4.1", + "@cloudflare/workers-shared": "0.5.3", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "blake3-wasm": "^2.1.5", "chokidar": "^3.5.3", "date-fns": "^3.6.0", "esbuild": "0.17.19", - "miniflare": "3.20240821.2", + "miniflare": "3.20240909.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -2094,7 +1998,7 @@ "selfsigned": "^2.0.1", "source-map": "^0.6.1", "unenv": "npm:unenv-nightly@2.0.0-1724863496.70db6f1", - "workerd": "1.20240821.1", + "workerd": "1.20240909.0", "xxhash-wasm": "^1.0.1" }, "bin": { @@ -2108,7 +2012,7 @@ "fsevents": "~2.3.2" }, "peerDependencies": { - "@cloudflare/workers-types": "^4.20240821.1" + "@cloudflare/workers-types": "^4.20240909.0" }, "peerDependenciesMeta": { "@cloudflare/workers-types": { @@ -2505,32 +2409,6 @@ "@esbuild/win32-x64": "0.17.19" } }, - "node_modules/wrangler/node_modules/miniflare": { - "version": "3.20240821.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", - "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", - "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.4", - "workerd": "1.20240821.1", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -2590,45 +2468,49 @@ } }, "@cloudflare/workerd-darwin-64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240821.1.tgz", - "integrity": "sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240909.0.tgz", + "integrity": "sha512-nJ8jm/6PR8DPzVb4QifNAfSdrFZXNblwIdOhLTU5FpSvFFocmzFX5WgzQagvtmcC9/ZAQyxuf7WynDNyBcoe0Q==", "dev": true, "optional": true }, "@cloudflare/workerd-darwin-arm64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240821.1.tgz", - "integrity": "sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240909.0.tgz", + "integrity": "sha512-gJqKa811oSsoxy9xuoQn7bS0Hr1sY+o3EUORTcEnulG6Kz9NQ6nd8QNdp2Hrk2jmmSqwrNkn+a6PZkWzk6Q0Gw==", "dev": true, "optional": true }, "@cloudflare/workerd-linux-64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240821.1.tgz", - "integrity": "sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240909.0.tgz", + "integrity": "sha512-sJrmtccfMg73sZljiBpe4R+lhF58TqzqhF2pQG8HRjyxkzkM1sjpZqfEFaIkNUDqd3/Ibji49fklhPCGXljKSg==", "dev": true, "optional": true }, "@cloudflare/workerd-linux-arm64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240821.1.tgz", - "integrity": "sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240909.0.tgz", + "integrity": "sha512-dTbSdceyRXPOSER+18AwYRbPQG0e/Dwl2trmfMMCETkfJhNLv1fU3FFMJPjfILijKnhTZHSnHCx0+xwHdon2fg==", "dev": true, "optional": true }, "@cloudflare/workerd-windows-64": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240821.1.tgz", - "integrity": "sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240909.0.tgz", + "integrity": "sha512-/d4BT0kcWFa7Qc0K4K9+cwVQ1qyPNKiO42JZUijlDlco+TYTPkLO3qGEohmwbfMq+BieK7JTMSgjO81ZHpA0HQ==", "dev": true, "optional": true }, "@cloudflare/workers-shared": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.4.1.tgz", - "integrity": "sha512-nYh4r8JwOOjYIdH2zub++CmIKlkYFlpxI1nBHimoiHcytJXD/b7ldJ21TtfzUZMCgI78mxVlymMHA/ReaOxKlA==", - "dev": true + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.5.3.tgz", + "integrity": "sha512-Yk5Im7zsyKbzd7qi+DrL7ZJR9+bdZwq9BqZWS4muDIWA8MCUeSLsUC+C9u+jdwfPSi5It2AcQG4f0iwZr6jkkQ==", + "dev": true, + "requires": { + "mime": "^3.0.0", + "zod": "^3.22.3" + } }, "@cloudflare/workers-types": { "version": "4.20240909.0", @@ -3396,56 +3278,6 @@ "ws": "^8.17.1", "youch": "^3.2.2", "zod": "^3.22.3" - }, - "dependencies": { - "@cloudflare/workerd-darwin-64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240909.0.tgz", - "integrity": "sha512-nJ8jm/6PR8DPzVb4QifNAfSdrFZXNblwIdOhLTU5FpSvFFocmzFX5WgzQagvtmcC9/ZAQyxuf7WynDNyBcoe0Q==", - "dev": true, - "optional": true - }, - "@cloudflare/workerd-darwin-arm64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240909.0.tgz", - "integrity": "sha512-gJqKa811oSsoxy9xuoQn7bS0Hr1sY+o3EUORTcEnulG6Kz9NQ6nd8QNdp2Hrk2jmmSqwrNkn+a6PZkWzk6Q0Gw==", - "dev": true, - "optional": true - }, - "@cloudflare/workerd-linux-64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240909.0.tgz", - "integrity": "sha512-sJrmtccfMg73sZljiBpe4R+lhF58TqzqhF2pQG8HRjyxkzkM1sjpZqfEFaIkNUDqd3/Ibji49fklhPCGXljKSg==", - "dev": true, - "optional": true - }, - "@cloudflare/workerd-linux-arm64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240909.0.tgz", - "integrity": "sha512-dTbSdceyRXPOSER+18AwYRbPQG0e/Dwl2trmfMMCETkfJhNLv1fU3FFMJPjfILijKnhTZHSnHCx0+xwHdon2fg==", - "dev": true, - "optional": true - }, - "@cloudflare/workerd-windows-64": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240909.0.tgz", - "integrity": "sha512-/d4BT0kcWFa7Qc0K4K9+cwVQ1qyPNKiO42JZUijlDlco+TYTPkLO3qGEohmwbfMq+BieK7JTMSgjO81ZHpA0HQ==", - "dev": true, - "optional": true - }, - "workerd": { - "version": "1.20240909.0", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240909.0.tgz", - "integrity": "sha512-NwuYh/Fgr/MK0H+Ht687sHl/f8tumwT5CWzYR0MZMHri8m3CIYu2IaY4tBFWoKE/tOU1Z5XjEXECa9zXY4+lwg==", - "dev": true, - "requires": { - "@cloudflare/workerd-darwin-64": "1.20240909.0", - "@cloudflare/workerd-darwin-arm64": "1.20240909.0", - "@cloudflare/workerd-linux-64": "1.20240909.0", - "@cloudflare/workerd-linux-arm64": "1.20240909.0", - "@cloudflare/workerd-windows-64": "1.20240909.0" - } - } } }, "ms": { @@ -3850,26 +3682,26 @@ } }, "workerd": { - "version": "1.20240821.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240821.1.tgz", - "integrity": "sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==", + "version": "1.20240909.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240909.0.tgz", + "integrity": "sha512-NwuYh/Fgr/MK0H+Ht687sHl/f8tumwT5CWzYR0MZMHri8m3CIYu2IaY4tBFWoKE/tOU1Z5XjEXECa9zXY4+lwg==", "dev": true, "requires": { - "@cloudflare/workerd-darwin-64": "1.20240821.1", - "@cloudflare/workerd-darwin-arm64": "1.20240821.1", - "@cloudflare/workerd-linux-64": "1.20240821.1", - "@cloudflare/workerd-linux-arm64": "1.20240821.1", - "@cloudflare/workerd-windows-64": "1.20240821.1" + "@cloudflare/workerd-darwin-64": "1.20240909.0", + "@cloudflare/workerd-darwin-arm64": "1.20240909.0", + "@cloudflare/workerd-linux-64": "1.20240909.0", + "@cloudflare/workerd-linux-arm64": "1.20240909.0", + "@cloudflare/workerd-windows-64": "1.20240909.0" } }, "wrangler": { - "version": "3.76.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.76.0.tgz", - "integrity": "sha512-HQWJm5/RUHVr+Vg2KM55pjDSbcEh5WxR6Swcpz1jQ5o+ytoLoj31IHMsl4cJFfM/JtzjBXSpRbS00lDnGfFc2A==", + "version": "3.78.2", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.2.tgz", + "integrity": "sha512-PL7GchswGrNm2OvdSw5yG3ZAqNjpaQIO++p8E1TaCi63DSyssKFYeYqTvfFshsQPP2u1dox5JFXtLc6IE/m1xw==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", - "@cloudflare/workers-shared": "0.4.1", + "@cloudflare/workers-shared": "0.5.3", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "blake3-wasm": "^2.1.5", @@ -3877,7 +3709,7 @@ "date-fns": "^3.6.0", "esbuild": "0.17.19", "fsevents": "~2.3.2", - "miniflare": "3.20240821.2", + "miniflare": "3.20240909.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", @@ -3885,7 +3717,7 @@ "selfsigned": "^2.0.1", "source-map": "^0.6.1", "unenv": "npm:unenv-nightly@2.0.0-1724863496.70db6f1", - "workerd": "1.20240821.1", + "workerd": "1.20240909.0", "xxhash-wasm": "^1.0.1" }, "dependencies": { @@ -4072,26 +3904,6 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } - }, - "miniflare": { - "version": "3.20240821.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.2.tgz", - "integrity": "sha512-mgWekp437zD5l2Rz/in/OGBAISNB3rWr69DhR5Iq3WoToUNeAnkbW/CWPBpJiw5WHzZfHHOT+sVjSksAGRJitg==", - "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.4", - "workerd": "1.20240821.1", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - } } } }, From 530a45721fc07af8e340142d1e40c1c463123a67 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 03:08:05 +0000 Subject: [PATCH 20/77] fix(deps): update rust crate worker to 0.4.0 --- Cargo.lock | 12 ++++++------ tailcall-cloudflare/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3daea4f8fd..c61db028c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7040,9 +7040,9 @@ dependencies = [ [[package]] name = "worker" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bd73bd2ea409ae91df99293cbed8b892d39c4c0df5039b646be7586df62c6b" +checksum = "bc0c3cbf492ef952fff8c150c08a892751e0d7efcb6a27890416dcb6bccb4d37" dependencies = [ "async-trait", "bytes", @@ -7086,9 +7086,9 @@ dependencies = [ [[package]] name = "worker-macros" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bbf47d65e77652febb28abedac18b317d8dfe4e57f0d8d9998c4e991fca8e23" +checksum = "e50bf9ca065428da2315e26928d595d374c1610c208ee8a71a7efdae0ecc3f66" dependencies = [ "async-trait", "proc-macro2", @@ -7102,9 +7102,9 @@ dependencies = [ [[package]] name = "worker-sys" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4fbb72a85a6509e5ac5dcd1361543468be089ff5ea5c932043b6d0aeac7b6a5" +checksum = "7ced149c39dcec13a185e494a8bf3176f6c1cfee2224d875b2d78279f3b63a6a" dependencies = [ "cfg-if", "js-sys", diff --git a/tailcall-cloudflare/Cargo.toml b/tailcall-cloudflare/Cargo.toml index 17dd930ee8..0462c793fa 100644 --- a/tailcall-cloudflare/Cargo.toml +++ b/tailcall-cloudflare/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] hyper = { version = "0.14.28", default-features = false } -worker = "0.3.0" +worker = "0.4.0" tailcall = { path = "..", default-features = false } lazy_static = "1.4.0" anyhow = "1.0.82" From a25d2dff0223f922f17b7d0364febf0d97a5883f Mon Sep 17 00:00:00 2001 From: Sandipsinh Dilipsinh Rathod <62684960+ssddOnTop@users.noreply.github.com> Date: Sat, 14 Sep 2024 15:13:32 -0400 Subject: [PATCH 21/77] fix: remove unused deps (#2810) Co-authored-by: Tushar Mathur --- Cargo.lock | 14 ++------------ Cargo.toml | 9 +++------ 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c61db028c1..1cb036a7a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -828,9 +828,9 @@ checksum = "1bf2a5fb3207c12b5d208ebc145f967fea5cac41a021c37417ccc31ba40f39ee" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" [[package]] name = "cast" @@ -5550,7 +5550,6 @@ dependencies = [ "tailcall-tracker", "tailcall-typedefs-common", "tailcall-version", - "temp-env", "tempfile", "test-log", "thiserror", @@ -5766,15 +5765,6 @@ dependencies = [ "pin-utils", ] -[[package]] -name = "temp-env" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96374855068f47402c3121c6eed88d29cb1de8f3ab27090e273e420bdabcf050" -dependencies = [ - "parking_lot", -] - [[package]] name = "tempfile" version = "3.12.0" diff --git a/Cargo.toml b/Cargo.toml index b387d921ac..8b66584699 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,7 +84,6 @@ cache_control = "0.2.0" nom = "7.1.3" exitcode = "1.1.2" resource = "0.5.0" -stripmargin = "0.1.1" num_cpus = "1.16.0" fnv = "1.0.7" futures-channel = { version = "0.3.30" } @@ -156,8 +155,6 @@ tailcall-macros = { path = "tailcall-macros" } tailcall-tracker = { path = "tailcall-tracker", optional = true } tailcall-typedefs-common = { path = "./tailcall-typedefs-common" } tonic-types = "0.12.1" -datatest-stable = "0.2.9" -tokio-test = "0.4.4" base64 = "0.22.1" tailcall-hasher = { path = "tailcall-hasher" } serde_json_borrow = "0.6.0" @@ -167,11 +164,12 @@ pathdiff = "0.2.1" num = "0.4.3" indenter = "0.3.3" derive_more = { workspace = true } -enum_dispatch = "0.3.13" strum = "0.26.2" -maplit = "1.0.2" [dev-dependencies] +datatest-stable = "0.2.9" +enum_dispatch = "0.3.0" +tokio-test = "0.4.4" tailcall-prettier = { path = "tailcall-prettier" } criterion = "0.5.1" httpmock = "0.7.0" @@ -180,7 +178,6 @@ stripmargin = "0.1.1" markdown = "1.0.0-alpha.17" insta = { workspace = true } tempfile = "3.10.1" -temp-env = "0.3.6" maplit = "1.0.2" tailcall-fixtures = { path = "./tailcall-fixtures" } http-cache-semantics = { version = "1.0.1", default-features = false, features = [ From d02b6e6c6944ea549a525c31f2a333c1b347e28d Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 14 Sep 2024 12:18:32 -0700 Subject: [PATCH 22/77] fix: drop enum_dispatch --- Cargo.lock | 13 ------------- Cargo.toml | 1 - 2 files changed, 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cb036a7a1..aa60426719 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1486,18 +1486,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "enum_dispatch" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.76", -] - [[package]] name = "env_filter" version = "0.1.0" @@ -5471,7 +5459,6 @@ dependencies = [ "derive_more 0.99.18", "derive_setters", "dotenvy", - "enum_dispatch", "exitcode", "flate2", "fnv", diff --git a/Cargo.toml b/Cargo.toml index 8b66584699..ac3c4c5dca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,7 +168,6 @@ strum = "0.26.2" [dev-dependencies] datatest-stable = "0.2.9" -enum_dispatch = "0.3.0" tokio-test = "0.4.4" tailcall-prettier = { path = "tailcall-prettier" } criterion = "0.5.1" From 106f17051780a6f6ec4c888e5234a3525f28380e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:20:21 +0000 Subject: [PATCH 23/77] fix(deps): update tokio-prost monorepo to 0.13.0 --- Cargo.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa60426719..3a69906c92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3715,7 +3715,7 @@ dependencies = [ "bincode", "either", "fnv", - "itertools 0.11.0", + "itertools 0.10.5", "lazy_static", "nom", "quick-xml", @@ -3962,12 +3962,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc" +checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" dependencies = [ "bytes", - "prost-derive 0.13.1", + "prost-derive 0.13.2", ] [[package]] @@ -3978,7 +3978,7 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck", - "itertools 0.11.0", + "itertools 0.10.5", "log", "multimap", "once_cell", @@ -3998,7 +3998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.76", @@ -4006,12 +4006,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca" +checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.76", @@ -4040,7 +4040,7 @@ dependencies = [ "logos", "miette 7.2.0", "once_cell", - "prost 0.13.1", + "prost 0.13.2", "prost-types 0.13.1", "serde", "serde-value", @@ -4061,7 +4061,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2" dependencies = [ - "prost 0.13.1", + "prost 0.13.2", ] [[package]] @@ -4194,7 +4194,7 @@ checksum = "873f359bdecdfe6e353752f97cb9ee69368df55b16363ed2216da85e03232a58" dependencies = [ "bytes", "miette 7.2.0", - "prost 0.13.1", + "prost 0.13.2", "prost-reflect 0.14.0", "prost-types 0.13.1", "protox-parse 0.7.0", @@ -5505,7 +5505,7 @@ dependencies = [ "pluralizer", "pretty_assertions", "prometheus", - "prost 0.13.1", + "prost 0.13.2", "prost-reflect 0.14.0", "protox 0.7.1", "protox-parse 0.7.0", @@ -6161,7 +6161,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5563899ec5aa5f0ec48e37457461ffbbc184c9a0f413f715dacd154f46408a10" dependencies = [ - "prost 0.13.1", + "prost 0.13.2", "prost-types 0.13.1", "tonic 0.12.1", ] From cd67315e01debcccb73cd82032fa514008162349 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:06:17 +0000 Subject: [PATCH 24/77] fix(deps): update rust crate anyhow to v1.0.89 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a69906c92..fe7cf73f0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "anymap2" From 87c4c7c1573cce5405f97e305e4f1a2aae46186a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 14:54:42 +0000 Subject: [PATCH 25/77] fix(deps): update rust crate async-trait to v0.1.82 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe7cf73f0f..ab3b8b6021 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -519,9 +519,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", From 49f3f82f4c33c88c522ee9e5ef20860d3a3aab42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:43:21 +0000 Subject: [PATCH 26/77] fix(deps): update rust crate async-graphql-value to v7.0.9 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab3b8b6021..608ce6d55d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "async-graphql-value" -version = "7.0.7" +version = "7.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69117c43c01d81a69890a9f5dd6235f2f027ca8d1ec62d6d3c5e01ca0edb4f2b" +checksum = "3b0206011cad065420c27988f17dd7fe201a0e056b20c262209b7bffcd6fa176" dependencies = [ "bytes", "indexmap 2.4.0", From 618342f90f8892f15d925720ddcbe6219b44fb62 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 17:33:38 +0000 Subject: [PATCH 27/77] chore(deps): update rust crate pretty_assertions to v1.4.1 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 608ce6d55d..e02350ea76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3865,9 +3865,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -7109,9 +7109,9 @@ checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" From 9fb10e523e7f30c0c8af4fc8335427842960172f Mon Sep 17 00:00:00 2001 From: Sandipsinh Dilipsinh Rathod <62684960+ssddOnTop@users.noreply.github.com> Date: Mon, 16 Sep 2024 16:55:04 -0400 Subject: [PATCH 28/77] chore: bump async-graphql version (#2837) --- Cargo.lock | 44 ++++++++++++++++---------------- Cargo.toml | 4 +-- src/core/jit/graphql_executor.rs | 3 ++- src/core/jit/request.rs | 2 +- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e02350ea76..4fd3945b62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "async-graphql" -version = "7.0.7" +version = "7.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b76aba2f176af685c2229633881a3adeae51f87ae1811781e73910b7001c93e" +checksum = "9d37c3e9ba322eb00e9e5e997d58f08e8b6de037325b9367ac59bca8e3cd46af" dependencies = [ "async-graphql-derive", "async-graphql-parser", @@ -275,13 +275,13 @@ dependencies = [ [[package]] name = "async-graphql-derive" -version = "7.0.7" +version = "7.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e2e26a6b44bc61df3ca8546402cf9204c28e30c06084cc8e75cd5e34d4f150" +checksum = "f1141703c11c6ad4fa9b3b0e1e476dea01dbd18a44db00f949b804afaab2f344" dependencies = [ "Inflector", "async-graphql-parser", - "darling 0.20.9", + "darling 0.20.10", "proc-macro-crate 3.1.0", "proc-macro2", "quote", @@ -325,9 +325,9 @@ dependencies = [ [[package]] name = "async-graphql-parser" -version = "7.0.7" +version = "7.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f801451484b4977d6fe67b29030f81353cabdcbb754e5a064f39493582dac0cf" +checksum = "2f66edcce4c38c18f7eb181fdf561c3d3aa2d644ce7358fc7a928c00a4ffef17" dependencies = [ "async-graphql-value", "pest", @@ -1189,12 +1189,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.9", - "darling_macro 0.20.9", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -1213,9 +1213,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", @@ -1238,11 +1238,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.9", + "darling_core 0.20.10", "quote", "syn 2.0.76", ] @@ -1370,7 +1370,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling 0.20.9", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.76", @@ -3715,7 +3715,7 @@ dependencies = [ "bincode", "either", "fnv", - "itertools 0.10.5", + "itertools 0.11.0", "lazy_static", "nom", "quick-xml", @@ -3978,7 +3978,7 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck", - "itertools 0.10.5", + "itertools 0.11.0", "log", "multimap", "once_cell", @@ -3998,7 +3998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.11.0", "proc-macro2", "quote", "syn 2.0.76", @@ -4011,7 +4011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.11.0", "proc-macro2", "quote", "syn 2.0.76", @@ -7095,7 +7095,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76ff259533532054cfbaefb115c613203c73707017459206380f03b3b3f266e" dependencies = [ - "darling 0.20.9", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.76", diff --git a/Cargo.toml b/Cargo.toml index ac3c4c5dca..a94f413728 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ path = "src/main.rs" [workspace.dependencies] anyhow = "1.0.82" -async-graphql = { version = "7.0.3" } +async-graphql = { version = "7.0.9" } futures-util = { version = "0.3.30" } indexmap = "2.2.6" insta = { version = "1.38.0", features = ["json"] } @@ -141,7 +141,7 @@ headers = "0.3.9" # previous version until hyper is updated to 1+ 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-value = "7.0.9" async-graphql = { workspace = true, features = [ "dynamic-schema", "dataloader", diff --git a/src/core/jit/graphql_executor.rs b/src/core/jit/graphql_executor.rs index 5e582432c8..06ab3eaf98 100644 --- a/src/core/jit/graphql_executor.rs +++ b/src/core/jit/graphql_executor.rs @@ -3,6 +3,7 @@ use std::future::Future; use std::sync::Arc; use async_graphql::{Data, Executor, Response, Value}; +use async_graphql_value::Extensions; use futures_util::stream::BoxStream; use crate::core::app_context::AppContext; @@ -34,7 +35,7 @@ impl From> for async_graphql::Request { .map(|(k, v)| (async_graphql::Name::new(k), v)) .collect::>(), ); - request.extensions = value.extensions; + request.extensions = Extensions(value.extensions); request.operation_name = value.operation_name; request } diff --git a/src/core/jit/request.rs b/src/core/jit/request.rs index 8eec9cb387..e352164744 100644 --- a/src/core/jit/request.rs +++ b/src/core/jit/request.rs @@ -28,7 +28,7 @@ impl From for Request { query: value.query, operation_name: value.operation_name, variables: Variables::from_iter(variables.into_iter().map(|(k, v)| (k.to_string(), v))), - extensions: value.extensions, + extensions: value.extensions.0, } } } From 297a4457a513fd794f55689051a65cda8a28982e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 20:55:54 +0000 Subject: [PATCH 29/77] fix(deps): update rust crate hyper-util to v0.1.8 --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fd3945b62..ccf16c63ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -760,9 +760,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" dependencies = [ "serde", ] @@ -2364,7 +2364,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -2453,9 +2453,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" dependencies = [ "bytes", "futures-channel", From 3a8d1e8bbec8e790cb6535ab1530f213348407bf Mon Sep 17 00:00:00 2001 From: Sandipsinh Dilipsinh Rathod <62684960+ssddOnTop@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:43:13 -0400 Subject: [PATCH 30/77] chore(link): add `meta` support (#2824) --- generated/.tailcallrc.graphql | 4 ++ generated/.tailcallrc.schema.json | 3 + src/core/config/link.rs | 3 + src/core/generator/generator.rs | 1 + src/core/grpc/data_loader_request.rs | 1 + src/core/grpc/protobuf.rs | 1 + src/core/grpc/request_template.rs | 1 + .../test-link-support.md_client.snap | 55 +++++++++++++++++++ .../test-link-support.md_merged.snap | 26 +++++++++ tests/execution/test-link-support.md | 50 +++++++++++++++++ 10 files changed, 145 insertions(+) create mode 100644 tests/core/snapshots/test-link-support.md_client.snap create mode 100644 tests/core/snapshots/test-link-support.md_merged.snap create mode 100644 tests/execution/test-link-support.md diff --git a/generated/.tailcallrc.graphql b/generated/.tailcallrc.graphql index a2ba1acf44..d41a58121e 100644 --- a/generated/.tailcallrc.graphql +++ b/generated/.tailcallrc.graphql @@ -207,6 +207,10 @@ directive @link( """ id: String """ + Additional metadata pertaining to the linked resource. + """ + meta: JSON + """ The source of the link. It can be a URL or a path to a file. If a path is provided, it is relative to the file that imports the link. """ diff --git a/generated/.tailcallrc.schema.json b/generated/.tailcallrc.schema.json index 76e5cab3c2..654c30eedf 100644 --- a/generated/.tailcallrc.schema.json +++ b/generated/.tailcallrc.schema.json @@ -803,6 +803,9 @@ "null" ] }, + "meta": { + "description": "Additional metadata pertaining to the linked resource." + }, "src": { "description": "The source of the link. It can be a URL or a path to a file. If a path is provided, it is relative to the file that imports the link.", "type": "string" diff --git a/src/core/config/link.rs b/src/core/config/link.rs index d8cf0ecd1c..a71003b331 100644 --- a/src/core/config/link.rs +++ b/src/core/config/link.rs @@ -57,4 +57,7 @@ pub struct Link { /// The type of the link. It can be `Config`, or `Protobuf`. #[serde(default, skip_serializing_if = "is_default", rename = "type")] pub type_of: LinkType, + /// Additional metadata pertaining to the linked resource. + #[serde(default, skip_serializing_if = "is_default")] + pub meta: Option, } diff --git a/src/core/generator/generator.rs b/src/core/generator/generator.rs index ce04350304..bd5fc0387c 100644 --- a/src/core/generator/generator.rs +++ b/src/core/generator/generator.rs @@ -90,6 +90,7 @@ impl Generator { id: None, src: metadata.path.to_owned(), type_of: LinkType::Protobuf, + meta: None, }); Ok(config) } diff --git a/src/core/grpc/data_loader_request.rs b/src/core/grpc/data_loader_request.rs index 7179a19005..b8b02c3f35 100644 --- a/src/core/grpc/data_loader_request.rs +++ b/src/core/grpc/data_loader_request.rs @@ -73,6 +73,7 @@ mod tests { id: None, src: test_file.to_string(), type_of: LinkType::Protobuf, + meta: None, }]); let method = GrpcMethod { package: "greetings".to_string(), diff --git a/src/core/grpc/protobuf.rs b/src/core/grpc/protobuf.rs index adcea67407..df28845dbd 100644 --- a/src/core/grpc/protobuf.rs +++ b/src/core/grpc/protobuf.rs @@ -266,6 +266,7 @@ pub mod tests { id: Some(id.clone()), src: path.to_string(), type_of: LinkType::Protobuf, + meta: None, }]); let method = GrpcMethod { package: id, service: "a".to_owned(), name: "b".to_owned() }; diff --git a/src/core/grpc/request_template.rs b/src/core/grpc/request_template.rs index ceddf1ac2a..c96bd1a2f5 100644 --- a/src/core/grpc/request_template.rs +++ b/src/core/grpc/request_template.rs @@ -160,6 +160,7 @@ mod tests { id: Some(id.clone()), src: test_file.to_string(), type_of: LinkType::Protobuf, + meta: None, }]); let method = GrpcMethod { package: id.to_string(), diff --git a/tests/core/snapshots/test-link-support.md_client.snap b/tests/core/snapshots/test-link-support.md_client.snap new file mode 100644 index 0000000000..3127ff26a7 --- /dev/null +++ b/tests/core/snapshots/test-link-support.md_client.snap @@ -0,0 +1,55 @@ +--- +source: tests/core/spec.rs +expression: formatted +--- +scalar Bytes + +scalar Date + +scalar DateTime + +scalar Email + +scalar Empty + +scalar Int128 + +scalar Int16 + +scalar Int32 + +scalar Int64 + +scalar Int8 + +scalar JSON + +type News { + id: Int +} + +input NewsInput { + id: Int +} + +scalar PhoneNumber + +type Query { + newsById(news: NewsInput!): News! +} + +scalar UInt128 + +scalar UInt16 + +scalar UInt32 + +scalar UInt64 + +scalar UInt8 + +scalar Url + +schema { + query: Query +} diff --git a/tests/core/snapshots/test-link-support.md_merged.snap b/tests/core/snapshots/test-link-support.md_merged.snap new file mode 100644 index 0000000000..b0c2cce6d2 --- /dev/null +++ b/tests/core/snapshots/test-link-support.md_merged.snap @@ -0,0 +1,26 @@ +--- +source: tests/core/spec.rs +expression: formatter +--- +schema + @server(port: 8000) + @upstream(baseURL: "http://localhost:50051", batch: {delay: 10, headers: [], maxSize: 1000}) + @link(id: "news", src: "news.proto", meta: {description: "Test"}, type: Protobuf) { + query: Query +} + +input NewsInput { + id: Int +} + +type News { + id: Int +} + +type NewsData { + news: [News] +} + +type Query { + newsById(news: NewsInput!): News! @grpc(body: "{{.args.news}}", method: "news.NewsService.GetNews") +} diff --git a/tests/execution/test-link-support.md b/tests/execution/test-link-support.md new file mode 100644 index 0000000000..fc9e497887 --- /dev/null +++ b/tests/execution/test-link-support.md @@ -0,0 +1,50 @@ +--- +identity: true +--- + +# test-link-support + +```protobuf @file:news.proto +syntax = "proto3"; + +import "google/protobuf/empty.proto"; + +package news; + +message News { + int32 id = 1; +} + +service NewsService { + rpc GetNews (NewsId) returns (News) {} +} + +message NewsId { + int32 id = 1; +} +``` + +```graphql @config +schema + @server(port: 8000) + @upstream(baseURL: "http://localhost:50051", batch: {delay: 10, headers: [], maxSize: 1000}) + @link(id: "news", src: "news.proto", meta: {description: "Test"}, type: Protobuf) { + query: Query +} + +input NewsInput { + id: Int +} + +type News { + id: Int +} + +type NewsData { + news: [News] +} + +type Query { + newsById(news: NewsInput!): News! @grpc(body: "{{.args.news}}", method: "news.NewsService.GetNews") +} +``` From 794387519abac3701a0dfdf5fc4607fa4215157e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 22:44:57 +0000 Subject: [PATCH 31/77] fix(deps): update rust crate prost-reflect to v0.14.2 --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccf16c63ab..9c694adf0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3715,7 +3715,7 @@ dependencies = [ "bincode", "either", "fnv", - "itertools 0.11.0", + "itertools 0.10.5", "lazy_static", "nom", "quick-xml", @@ -3978,7 +3978,7 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck", - "itertools 0.11.0", + "itertools 0.10.5", "log", "multimap", "once_cell", @@ -3998,7 +3998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.76", @@ -4011,7 +4011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.76", @@ -4032,9 +4032,9 @@ dependencies = [ [[package]] name = "prost-reflect" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a6a9143ae25c25fa7b6a48d6cc08b10785372060009c25140a4e7c340e95af" +checksum = "4b7535b02f0e5efe3e1dbfcb428be152226ed0c66cad9541f2274c8ba8d4cd40" dependencies = [ "base64 0.22.1", "logos", @@ -4195,7 +4195,7 @@ dependencies = [ "bytes", "miette 7.2.0", "prost 0.13.2", - "prost-reflect 0.14.0", + "prost-reflect 0.14.2", "prost-types 0.13.1", "protox-parse 0.7.0", "thiserror", @@ -5506,7 +5506,7 @@ dependencies = [ "pretty_assertions", "prometheus", "prost 0.13.2", - "prost-reflect 0.14.0", + "prost-reflect 0.14.2", "protox 0.7.1", "protox-parse 0.7.0", "rand", From 43ec85ef5bbd38bc663175b64ec917b318ebd9a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 23:16:52 +0000 Subject: [PATCH 32/77] chore(deps): update dependency miniflare to v3.20240909.2 --- tailcall-cloudflare/package-lock.json | 58 ++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 9b0a26d65a..62bf89f1f5 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1334,9 +1334,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240909.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", - "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", + "version": "3.20240909.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", + "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -2409,6 +2409,32 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "3.20240909.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", + "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3261,9 +3287,9 @@ "dev": true }, "miniflare": { - "version": "3.20240909.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", - "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", + "version": "3.20240909.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", + "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", @@ -3904,6 +3930,26 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } + }, + "miniflare": { + "version": "3.20240909.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", + "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + } } } }, From 02af0a4cf91008b56d1a355068ac81c6e572fcf7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 01:04:46 +0000 Subject: [PATCH 33/77] chore(deps): update dependency wrangler to v3.78.3 --- tailcall-cloudflare/package-lock.json | 78 ++++++--------------------- 1 file changed, 16 insertions(+), 62 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 62bf89f1f5..f1cc9c4473 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1423,9 +1423,9 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, "node_modules/pathe": { @@ -1977,9 +1977,9 @@ } }, "node_modules/wrangler": { - "version": "3.78.2", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.2.tgz", - "integrity": "sha512-PL7GchswGrNm2OvdSw5yG3ZAqNjpaQIO++p8E1TaCi63DSyssKFYeYqTvfFshsQPP2u1dox5JFXtLc6IE/m1xw==", + "version": "3.78.3", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.3.tgz", + "integrity": "sha512-IRQ0HCmaVGeQVsW+4kqJfYuA1uBIAtjSCu8/aLRBXzdpiQ+0VSSj/uQ54wBRS08n4twFXTLiPAsYiNVF1aHyyA==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -1990,9 +1990,9 @@ "chokidar": "^3.5.3", "date-fns": "^3.6.0", "esbuild": "0.17.19", - "miniflare": "3.20240909.1", + "miniflare": "3.20240909.2", "nanoid": "^3.3.3", - "path-to-regexp": "^6.2.0", + "path-to-regexp": "^6.3.0", "resolve": "^1.22.8", "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", @@ -2409,32 +2409,6 @@ "@esbuild/win32-x64": "0.17.19" } }, - "node_modules/wrangler/node_modules/miniflare": { - "version": "3.20240909.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", - "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", - "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.4", - "workerd": "1.20240909.0", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3349,9 +3323,9 @@ "dev": true }, "path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, "pathe": { @@ -3721,9 +3695,9 @@ } }, "wrangler": { - "version": "3.78.2", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.2.tgz", - "integrity": "sha512-PL7GchswGrNm2OvdSw5yG3ZAqNjpaQIO++p8E1TaCi63DSyssKFYeYqTvfFshsQPP2u1dox5JFXtLc6IE/m1xw==", + "version": "3.78.3", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.3.tgz", + "integrity": "sha512-IRQ0HCmaVGeQVsW+4kqJfYuA1uBIAtjSCu8/aLRBXzdpiQ+0VSSj/uQ54wBRS08n4twFXTLiPAsYiNVF1aHyyA==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -3735,9 +3709,9 @@ "date-fns": "^3.6.0", "esbuild": "0.17.19", "fsevents": "~2.3.2", - "miniflare": "3.20240909.1", + "miniflare": "3.20240909.2", "nanoid": "^3.3.3", - "path-to-regexp": "^6.2.0", + "path-to-regexp": "^6.3.0", "resolve": "^1.22.8", "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", @@ -3930,26 +3904,6 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } - }, - "miniflare": { - "version": "3.20240909.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.1.tgz", - "integrity": "sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==", - "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.4", - "workerd": "1.20240909.0", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - } } } }, From 9b7a7ce42e6c62040bc164d5be32c08dbe944e42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 04:18:31 +0000 Subject: [PATCH 34/77] fix(deps): update rust crate clap to v4.5.17 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c694adf0a..1e9176e5f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -923,9 +923,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", From 976649cf9c4c4433650807e90d67109e1aee5d5f Mon Sep 17 00:00:00 2001 From: Kiryl Mialeshka <8974488+meskill@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:02:04 +0200 Subject: [PATCH 35/77] fix(jit): handling nested lists (#2779) Co-authored-by: Tushar Mathur --- src/core/ir/eval.rs | 2 +- src/core/ir/resolver_context_like.rs | 3 +- src/core/jit/common/jp.rs | 33 +++--- src/core/jit/context.rs | 10 ++ src/core/jit/exec.rs | 100 ++++++------------ src/core/jit/exec_const.rs | 70 ++++++++++-- src/core/jit/model.rs | 30 +++--- ...l__core__jit__response__test__merging.snap | 30 ------ src/core/jit/store.rs | 74 ++----------- src/core/jit/synth/synth.rs | 65 +++++------- src/core/json/json_like_list.rs | 83 ++++++++++++++- ...rator__gen_json_proto_mix_config.json.snap | 81 -------------- ...onformance-nested-lists-fragment.md_0.snap | 43 ++++++++ ...mance-nested-lists-fragment.md_client.snap | 60 +++++++++++ ...mance-nested-lists-fragment.md_merged.snap | 26 +++++ ...l-conformance-nested-lists-http.md_0.snap} | 18 ++-- ...l-conformance-nested-lists-http.md_1.snap} | 0 ...l-conformance-nested-lists-http.md_2.snap} | 0 ...formance-nested-lists-http.md_client.snap} | 1 + ...formance-nested-lists-http.md_merged.snap} | 1 + ...raphql-conformance-nested-lists.md_0.snap} | 18 ++-- ...raphql-conformance-nested-lists.md_1.snap} | 0 ...raphql-conformance-nested-lists.md_2.snap} | 0 ...l-conformance-nested-lists.md_client.snap} | 1 + ...l-conformance-nested-lists.md_merged.snap} | 1 + ...aphql-conformance-nested-lists-fragment.md | 86 +++++++++++++++ ... graphql-conformance-nested-lists-http.md} | 2 + ...md => graphql-conformance-nested-lists.md} | 2 + 28 files changed, 497 insertions(+), 343 deletions(-) delete mode 100644 src/core/jit/snapshots/tailcall__core__jit__response__test__merging.snap delete mode 100644 tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.json.snap create mode 100644 tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_0.snap create mode 100644 tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_client.snap create mode 100644 tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_merged.snap rename tests/core/snapshots/{graphql-conformance-http-016.md_0.snap => graphql-conformance-nested-lists-http.md_0.snap} (54%) rename tests/core/snapshots/{graphql-conformance-016.md_1.snap => graphql-conformance-nested-lists-http.md_1.snap} (100%) rename tests/core/snapshots/{graphql-conformance-016.md_2.snap => graphql-conformance-nested-lists-http.md_2.snap} (100%) rename tests/core/snapshots/{graphql-conformance-http-016.md_client.snap => graphql-conformance-nested-lists-http.md_client.snap} (95%) rename tests/core/snapshots/{graphql-conformance-http-016.md_merged.snap => graphql-conformance-nested-lists-http.md_merged.snap} (85%) rename tests/core/snapshots/{graphql-conformance-016.md_0.snap => graphql-conformance-nested-lists.md_0.snap} (54%) rename tests/core/snapshots/{graphql-conformance-http-016.md_1.snap => graphql-conformance-nested-lists.md_1.snap} (100%) rename tests/core/snapshots/{graphql-conformance-http-016.md_2.snap => graphql-conformance-nested-lists.md_2.snap} (100%) rename tests/core/snapshots/{graphql-conformance-016.md_client.snap => graphql-conformance-nested-lists.md_client.snap} (95%) rename tests/core/snapshots/{graphql-conformance-016.md_merged.snap => graphql-conformance-nested-lists.md_merged.snap} (86%) create mode 100644 tests/execution/graphql-conformance-nested-lists-fragment.md rename tests/execution/{graphql-conformance-http-016.md => graphql-conformance-nested-lists-http.md} (94%) rename tests/execution/{graphql-conformance-016.md => graphql-conformance-nested-lists.md} (94%) diff --git a/src/core/ir/eval.rs b/src/core/ir/eval.rs index c0d8c2356a..6c5cc40433 100644 --- a/src/core/ir/eval.rs +++ b/src/core/ir/eval.rs @@ -86,7 +86,7 @@ impl IR { second.eval(ctx).await } IR::Discriminate(discriminator, expr) => expr.eval(ctx).await.and_then(|value| { - let value = value.map(|mut value| { + let value = value.map(&mut |mut value| { let type_name = discriminator.resolve_type(&value)?; value.set_type_name(type_name.to_string())?; diff --git a/src/core/ir/resolver_context_like.rs b/src/core/ir/resolver_context_like.rs index 93dfaaf1a1..4ee1dafc78 100644 --- a/src/core/ir/resolver_context_like.rs +++ b/src/core/ir/resolver_context_like.rs @@ -98,7 +98,8 @@ impl SelectionField { let name = field.output_name.to_string(); let type_name = field.type_of.name(); let selection_set = field - .iter_only(|field| match &field.type_condition { + .iter() + .filter(|field| match &field.type_condition { Some(type_condition) => type_condition == type_name, None => true, }) diff --git a/src/core/jit/common/jp.rs b/src/core/jit/common/jp.rs index 815d3a5311..80d912d082 100644 --- a/src/core/jit/common/jp.rs +++ b/src/core/jit/common/jp.rs @@ -5,9 +5,9 @@ use serde::Deserialize; use crate::core::blueprint::Blueprint; use crate::core::config::{Config, ConfigModule}; use crate::core::jit::builder::Builder; -use crate::core::jit::store::{Data, Store}; +use crate::core::jit::store::Store; use crate::core::jit::synth::Synth; -use crate::core::jit::{self, OperationPlan, Positioned, Variables}; +use crate::core::jit::{OperationPlan, Variables}; use crate::core::json::{JsonLike, JsonObjectLike}; use crate::core::valid::Validator; @@ -25,11 +25,9 @@ struct TestData { users: Vec, } -type Entry = Data>>; - struct ProcessedTestData { posts: Value, - users: HashMap>, + users: Value, } impl<'a, Value: JsonLike<'a> + Deserialize<'a> + Clone + 'a> TestData { @@ -56,7 +54,7 @@ impl<'a, Value: JsonLike<'a> + Deserialize<'a> + Clone + 'a> TestData { map }); - let users: HashMap<_, _> = posts + let users: Vec<_> = posts .iter() .map(|post| { let user_id = post @@ -74,12 +72,12 @@ impl<'a, Value: JsonLike<'a> + Deserialize<'a> + Clone + 'a> TestData { Value::null() } }) - .map(Ok) - .map(Data::Single) - .enumerate() .collect(); - ProcessedTestData { posts: Value::array(posts.clone()), users } + ProcessedTestData { + posts: Value::array(posts.clone()), + users: Value::array(users), + } } } @@ -120,15 +118,12 @@ impl<'a, Value: Deserialize<'a> + Clone + 'a + JsonLike<'a>> JP { .id .to_owned(); - let store = [ - (posts_id, Data::Single(Ok(posts))), - (users_id, Data::Multiple(users)), - ] - .into_iter() - .fold(Store::new(), |mut store, (id, data)| { - store.set_data(id, data); - store - }); + let store = [(posts_id, Ok(posts)), (users_id, Ok(users))] + .into_iter() + .fold(Store::new(), |mut store, (id, data)| { + store.set_data(id, data); + store + }); Synth::new(plan, store, vars) } diff --git a/src/core/jit/context.rs b/src/core/jit/context.rs index f52b34223b..dc208eaf86 100644 --- a/src/core/jit/context.rs +++ b/src/core/jit/context.rs @@ -44,6 +44,16 @@ impl<'a, Input: Clone, Output> Context<'a, Input, Output> { Self { request, value: None, args: Self::build_args(field), field } } + pub fn with_value(&self, value: &'a Output) -> Self { + Self { + request: self.request, + // TODO: no need to build again? + args: Self::build_args(self.field), + value: Some(value), + field: self.field, + } + } + pub fn with_value_and_field( &self, value: &'a Output, diff --git a/src/core/jit/exec.rs b/src/core/jit/exec.rs index f8d0da9331..cfff9a948d 100644 --- a/src/core/jit/exec.rs +++ b/src/core/jit/exec.rs @@ -6,12 +6,12 @@ use derive_getters::Getters; use futures_util::future::join_all; use super::context::{Context, RequestContext}; -use super::{DataPath, OperationPlan, Positioned, Response, Store}; +use super::{OperationPlan, Positioned, Response, Store}; use crate::core::ir::model::IR; use crate::core::ir::TypedValue; use crate::core::jit; use crate::core::jit::synth::Synth; -use crate::core::json::{JsonLike, JsonObjectLike}; +use crate::core::json::{JsonLike, JsonLikeList}; type SharedStore = Arc>>>>; @@ -58,7 +58,7 @@ struct ExecutorInner<'a, Input, Output, Error, Exec> { impl<'a, Input, Output, Error, Exec> ExecutorInner<'a, Input, Output, Error, Exec> where - for<'i> Output: JsonLike<'i> + TypedValue<'i> + Debug, + for<'i> Output: JsonLike<'i> + JsonLikeList<'i> + TypedValue<'i> + Debug + Clone, Input: Clone + Debug, Exec: IRExecutor, { @@ -75,7 +75,7 @@ where let ctx = Context::new(field, self.request); // TODO: with_args should be called on inside iter_field on any level, not only // for root fields - self.execute(&ctx, DataPath::new()).await + self.execute(&ctx).await })) .await; } @@ -83,89 +83,55 @@ where async fn iter_field<'b>( &'b self, ctx: &'b Context<'b, Input, Output>, - data_path: &DataPath, value: &'b Output, ) -> Result<(), Error> { let field = ctx.field(); - // Array - // Check if the field expects a list - if field.type_of.is_list() { - // Check if the value is an array - if let Some(array) = value.as_array() { - join_all(array.iter().enumerate().map(|(index, value)| { - join_all( - self.request - .plan() - .field_iter_only(field, value) - .map(|field| { - let ctx = ctx.with_value_and_field(value, field); - let data_path = data_path.clone().with_index(index); - async move { self.execute(&ctx, data_path).await } - }), - ) - })) - .await; - } - // TODO: We should throw an error stating that we expected - // a list type here but because the `Error` is a - // type-parameter, its not possible - } // TODO: Validate if the value is an Object // Has to be an Object, we don't do anything while executing if its a Scalar - else { - join_all( - self.request - .plan() - .field_iter_only(field, value) - .map(|child| { - let ctx = ctx.with_value_and_field(value, child); - let data_path = data_path.clone(); - async move { self.execute(&ctx, data_path).await } - }), - ) - .await; - } + join_all(field.iter().map(|child| { + let ctx = ctx.with_value_and_field(value, child); + async move { self.execute(&ctx).await } + })) + .await; Ok(()) } - async fn execute<'b>( - &'b self, - ctx: &'b Context<'b, Input, Output>, - data_path: DataPath, - ) -> Result<(), Error> { + async fn execute<'b>(&'b self, ctx: &'b Context<'b, Input, Output>) -> Result<(), Error> { let field = ctx.field(); if let Some(ir) = &field.ir { let result = self.ir_exec.execute(ir, ctx).await; if let Ok(value) = &result { - self.iter_field(ctx, &data_path, value).await?; + self.iter_field(ctx, value).await?; } let mut store = self.store.lock().unwrap(); - store.set( - &field.id, - &data_path, - result.map_err(|e| Positioned::new(e, field.pos)), - ); + store.set(&field.id, result.map_err(|e| Positioned::new(e, field.pos))); } else { - // if the present field doesn't have IR, still go through it's extensions to see - // if they've IR. - let default_obj = Output::object(Output::JsonObject::new()); - let value = ctx - .value() - .and_then(|v| v.get_key(&field.output_name)) - // in case there is no value we still put some dumb empty value anyway - // to force execution of the nested fields even when parent object is not present. - // For async_graphql it's done by `fix_dangling_resolvers` fn that basically creates - // fake IR that resolves to empty object. The `fix_dangling_resolvers` is also - // working here, but eventually it can be replaced by this logic - // here without doing the "fix" - .unwrap_or(&default_obj); - - self.iter_field(ctx, &data_path, value).await?; + let value = match ctx.value() { + Some(value) => value.map_ref(&mut |value| { + Ok(value + .get_key(&field.output_name) + .cloned() + // in case there is no value we still put some dumb empty value anyway + // to force execution of the nested fields even when parent object is not + // present. For async_graphql it's done by + // `fix_dangling_resolvers` fn that basically creates + // fake IR that resolves to empty object. The `fix_dangling_resolvers` is + // also working here, but eventually it can be + // replaced by this logic here without doing the + // "fix" + .unwrap_or(Output::null())) + })?, + // if the present field doesn't have IR, still go through nested fields to check + // if they've IR. + None => Output::null(), + }; + + self.iter_field(ctx, &value).await?; } Ok(()) diff --git a/src/core/jit/exec_const.rs b/src/core/jit/exec_const.rs index 6e1c74682f..fac7b626a6 100644 --- a/src/core/jit/exec_const.rs +++ b/src/core/jit/exec_const.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use async_graphql_value::ConstValue; +use futures_util::future::join_all; use super::context::Context; use super::exec::{Executor, IRExecutor}; @@ -8,8 +9,9 @@ use super::{Error, OperationPlan, Request, Response, Result}; use crate::core::app_context::AppContext; use crate::core::http::RequestContext; use crate::core::ir::model::IR; -use crate::core::ir::EvalContext; +use crate::core::ir::{self, EvalContext}; use crate::core::jit::synth::Synth; +use crate::core::json::{JsonLike, JsonLikeList}; /// A specialized executor that executes with async_graphql::Value pub struct ConstValueExecutor { @@ -26,9 +28,9 @@ impl ConstValueExecutor { req_ctx: &RequestContext, request: &Request, ) -> Response { - let exec = ConstValueExec::new(req_ctx); let plan = self.plan; // TODO: drop the clones in plan + let exec = ConstValueExec::new(plan.clone(), req_ctx); let vars = request.variables.clone(); let exe = Executor::new(plan.clone(), exec); let store = exe.store().await; @@ -38,12 +40,28 @@ impl ConstValueExecutor { } struct ConstValueExec<'a> { + plan: OperationPlan, req_context: &'a RequestContext, } impl<'a> ConstValueExec<'a> { - pub fn new(ctx: &'a RequestContext) -> Self { - Self { req_context: ctx } + pub fn new(plan: OperationPlan, req_context: &'a RequestContext) -> Self { + Self { req_context, plan } + } + + async fn call( + &self, + ctx: &'a Context< + 'a, + as IRExecutor>::Input, + as IRExecutor>::Output, + >, + ir: &'a IR, + ) -> Result< as IRExecutor>::Output> { + let req_context = &self.req_context; + let mut eval_ctx = EvalContext::new(req_context, ctx); + + Ok(ir.eval(&mut eval_ctx).await?) } } @@ -57,9 +75,47 @@ impl<'ctx> IRExecutor for ConstValueExec<'ctx> { ir: &'a IR, ctx: &'a Context<'a, Self::Input, Self::Output>, ) -> Result { - let req_context = &self.req_context; - let mut eval_ctx = EvalContext::new(req_context, ctx); + let field = ctx.field(); - Ok(ir.eval(&mut eval_ctx).await?) + match ctx.value() { + // TODO: check that field is expected list and it's a list of the required deepness + Some(value) if value.as_array().is_some() => { + let mut tasks = Vec::new(); + + // collect the async tasks first before creating the final result + value.for_each(&mut |value| { + // execute the resolver only for fields that are related to current value + // for fragments on union/interface + if self.plan.field_is_part_of_value(field, value) { + let ctx = ctx.with_value(value); + tasks.push(async move { + let req_context = &self.req_context; + let mut eval_ctx = EvalContext::new(req_context, &ctx); + ir.eval(&mut eval_ctx).await + }) + } + }); + + let results = join_all(tasks).await; + + let mut iter = results.into_iter(); + + // map input value to the calculated results preserving the shape + // of the input + Ok(value.map_ref(&mut |value| { + // for fragments on union/interface we will + // have less entries for resolved values based on the type + // pull from the result only field is related and fill with null otherwise + if self.plan.field_is_part_of_value(field, value) { + iter.next().unwrap_or(Err(ir::Error::IO( + "Expected value to be present".to_string(), + ))) + } else { + Ok(Self::Output::default()) + } + })?) + } + _ => Ok(self.call(ctx, ir).await?), + } } } diff --git a/src/core/jit/model.rs b/src/core/jit/model.rs index 824e02e756..2936676cb8 100644 --- a/src/core/jit/model.rs +++ b/src/core/jit/model.rs @@ -247,15 +247,11 @@ impl Field { } impl Field, Input> { - /// iters over children fields that satisfies - /// passed filter_fn - pub fn iter_only<'a>( - &'a self, - mut filter_fn: impl FnMut(&'a Field, Input>) -> bool + 'a, - ) -> impl Iterator, Input>> + 'a { + /// iters over children fields + pub fn iter(&self) -> impl Iterator, Input>> { self.extensions .as_ref() - .map(move |nested| nested.0.iter().filter(move |&field| filter_fn(field))) + .map(move |nested| nested.0.iter()) .into_iter() .flatten() } @@ -487,23 +483,25 @@ impl OperationPlan { self.index.validate_enum_value(field.type_of.name(), value) } - /// Iterate over nested fields that are related to the __typename of the - /// value - pub fn field_iter_only<'a, Output>( + pub fn field_is_part_of_value<'a, Output>( &'a self, field: &'a Field, Input>, value: &'a Output, - ) -> impl Iterator, Input>> + ) -> bool where Output: TypedValue<'a>, { - let value_type = field.value_type(value); - - field.iter_only(move |field| match &field.type_condition { - Some(type_condition) => self.index.is_type_implements(value_type, type_condition), + match &field.type_condition { + Some(type_condition) => match value.get_type_name() { + Some(value_type) => self.index.is_type_implements(value_type, type_condition), + // if there is no __typename in value that means there is a bug in implementation + // such we haven't resolved the concrete type or type shouldn't be + // inferred here at all and we should just use the field + None => true, + }, // if there is no type_condition restriction then use this field None => true, - }) + } } } diff --git a/src/core/jit/snapshots/tailcall__core__jit__response__test__merging.snap b/src/core/jit/snapshots/tailcall__core__jit__response__test__merging.snap deleted file mode 100644 index dbed1326e0..0000000000 --- a/src/core/jit/snapshots/tailcall__core__jit__response__test__merging.snap +++ /dev/null @@ -1,30 +0,0 @@ ---- -source: src/core/jit/response.rs -expression: merged_response ---- -{ - "data": { - "me": { - "id": 1, - "name": "John Smith", - "birthday": "2023-03-08T12:45:26-05:00" - }, - "__type": { - "name": "User", - "fields": [ - { - "name": "birthday", - "type": { - "name": "Date" - } - }, - { - "name": "id", - "type": { - "name": "String" - } - } - ] - } - } -} diff --git a/src/core/jit/store.rs b/src/core/jit/store.rs index 513a1f0fff..e0e288d32e 100644 --- a/src/core/jit/store.rs +++ b/src/core/jit/store.rs @@ -35,88 +35,30 @@ impl DataPath { } #[derive(Debug)] -pub struct Store { - data: HashMap>, +pub struct Store { + data: HashMap, } -#[derive(Clone, Default)] -pub enum Data { - /// Represents that the value was computed only once for the associated - /// field - Single(A), - /// Represents that the value was computed multiple times for the associated - /// field. The order is guaranteed by the executor to be the same as the - /// other of invocation and not the other of completion. - Multiple(HashMap>), - /// Represents that the value is yet to be computed - #[default] - Pending, -} - -impl std::fmt::Debug for Data { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Single(_) => f.debug_tuple("Single").finish(), - Self::Multiple(arg0) => f.debug_tuple("Multiple").field(&arg0.len()).finish(), - Self::Pending => write!(f, "Pending"), - } - } -} - -impl Data { - pub fn map(self, ab: impl Fn(A) -> B + Copy) -> Data { - match self { - Data::Single(a) => Data::Single(ab(a)), - Data::Multiple(values) => Data::Multiple( - values - .into_iter() - .map(|(index, e)| (index, e.map(ab))) - .collect(), - ), - Data::Pending => Data::Pending, - } - } -} - -impl Default for Store { +impl Default for Store { fn default() -> Self { Self::new() } } -impl Store { +impl Store { pub fn new() -> Self { Store { data: HashMap::new() } } - pub fn set_data(&mut self, field_id: FieldId, data: Data) { + pub fn set_data(&mut self, field_id: FieldId, data: Data) { self.data.insert(field_id.as_usize(), data); } - pub fn set(&mut self, field_id: &FieldId, path: &DataPath, data: A) { - let path = path.as_slice(); - let mut current_entry = self.data.entry(field_id.as_usize()); - - for index in path { - let entry = current_entry - .and_modify(|e| match e { - Data::Multiple(_) => {} - // force replacing to multiple data in case store has something else - _ => *e = Data::Multiple(HashMap::new()), - }) - .or_insert(Data::Multiple(HashMap::new())); - - if let Data::Multiple(map) = entry { - current_entry = map.entry(*index); - } else { - unreachable!("Map should contain only Data::Multiple at this point"); - } - } - - *current_entry.or_insert(Data::Pending) = Data::Single(data); + pub fn set(&mut self, field_id: &FieldId, data: Data) { + self.data.insert(field_id.as_usize(), data); } - pub fn get(&self, field_id: &FieldId) -> Option<&Data> { + pub fn get(&self, field_id: &FieldId) -> Option<&Data> { self.data.get(&field_id.as_usize()) } } diff --git a/src/core/jit/synth/synth.rs b/src/core/jit/synth/synth.rs index b5a9d4c7ad..4a037c363b 100644 --- a/src/core/jit/synth/synth.rs +++ b/src/core/jit/synth/synth.rs @@ -1,5 +1,5 @@ use crate::core::jit::model::{Field, Nested, OperationPlan, Variables}; -use crate::core::jit::store::{Data, DataPath, Store}; +use crate::core::jit::store::{DataPath, Store}; use crate::core::jit::{Error, PathSegment, Positioned, ValidationError}; use crate::core::json::{JsonLike, JsonObjectLike}; use crate::core::scalar; @@ -62,33 +62,21 @@ where path.push(PathSegment::Field(node.output_name.clone())); let result = match self.store.get(&node.id) { - Some(val) => { - let mut data = val; + Some(value) => { + let mut value = value.as_ref().map_err(Clone::clone)?; for index in data_path.as_slice() { - match data { - Data::Multiple(v) => { - data = &v[index]; - } - _ => return Ok(Value::null()), + if let Some(arr) = value.as_array() { + value = &arr[*index]; + } else { + return Ok(Value::null()); } } - match data { - Data::Single(result) => { - let value = result.as_ref().map_err(Clone::clone)?; - - if node.type_of.is_list() != value.as_array().is_some() { - self.node_nullable_guard(node, path) - } else { - self.iter_inner(node, value, data_path, path) - } - } - _ => { - // TODO: should bailout instead of returning Null - Ok(Value::null()) - } + if node.type_of.is_list() != value.as_array().is_some() { + return self.node_nullable_guard(node, path); } + self.iter_inner(node, value, data_path, path) } None => match value { Some(result) => self.iter_inner(node, result, data_path, path), @@ -174,7 +162,10 @@ where (_, Some(obj)) => { let mut ans = Value::JsonObject::new(); - for child in self.plan.field_iter_only(node, value) { + for child in node + .iter() + .filter(|field| self.plan.field_is_part_of_value(field, value)) + { // all checks for skip must occur in `iter_inner` // and include be checked before calling `iter` or recursing. if self.include(child) { @@ -228,8 +219,9 @@ mod tests { use crate::core::jit::builder::Builder; use crate::core::jit::common::JP; use crate::core::jit::model::{FieldId, Variables}; - use crate::core::jit::store::{Data, Store}; + use crate::core::jit::store::Store; use crate::core::jit::synth::Synth; + use crate::core::json::JsonLike; use crate::core::valid::Validator; const POSTS: &str = r#" @@ -282,20 +274,15 @@ mod tests { } impl TestData { - fn into_value<'a, Value: Deserialize<'a>>(self) -> Data { + fn into_value<'a, Value: Deserialize<'a> + JsonLike<'a>>(self) -> Value { match self { - Self::Posts => Data::Single(serde_json::from_str(POSTS).unwrap()), - Self::User1 => Data::Single(serde_json::from_str(USER1).unwrap()), - TestData::UsersData => Data::Multiple( - vec![ - Data::Single(serde_json::from_str(USER1).unwrap()), - Data::Single(serde_json::from_str(USER2).unwrap()), - ] - .into_iter() - .enumerate() - .collect(), - ), - TestData::Users => Data::Single(serde_json::from_str(USERS).unwrap()), + Self::Posts => serde_json::from_str(POSTS).unwrap(), + Self::User1 => serde_json::from_str(USER1).unwrap(), + TestData::UsersData => Value::array(vec![ + serde_json::from_str(USER1).unwrap(), + serde_json::from_str(USER2).unwrap(), + ]), + TestData::Users => serde_json::from_str(USERS).unwrap(), } } } @@ -304,7 +291,7 @@ mod tests { fn make_store<'a, Value>(query: &str, store: Vec<(FieldId, TestData)>) -> Synth where - Value: Deserialize<'a> + Serialize + Clone + std::fmt::Debug, + Value: Deserialize<'a> + JsonLike<'a> + Serialize + Clone + std::fmt::Debug, { let store = store .into_iter() @@ -322,7 +309,7 @@ mod tests { let store = store .into_iter() .fold(Store::new(), |mut store, (id, data)| { - store.set_data(id, data.map(Ok)); + store.set_data(id, Ok(data)); store }); let vars = Variables::new(); diff --git a/src/core/json/json_like_list.rs b/src/core/json/json_like_list.rs index 6743b380a8..851ec38bed 100644 --- a/src/core/json/json_like_list.rs +++ b/src/core/json/json_like_list.rs @@ -1,13 +1,13 @@ use super::JsonLike; pub trait JsonLikeList<'json>: JsonLike<'json> { - fn map(self, mut mapper: impl FnMut(Self) -> Result) -> Result { + fn map(self, mapper: &mut impl FnMut(Self) -> Result) -> Result { if self.as_array().is_some() { let new = self .into_array() .unwrap() .into_iter() - .map(mapper) + .map(|value| value.map(mapper)) .collect::>()?; Ok(Self::array(new)) @@ -16,9 +16,27 @@ pub trait JsonLikeList<'json>: JsonLike<'json> { } } - fn try_for_each(&self, mut f: impl FnMut(&Self) -> Result<(), Err>) -> Result<(), Err> { + fn map_ref( + &self, + mapper: &mut impl FnMut(&Self) -> Result, + ) -> Result { + if self.as_array().is_some() { + let new = self + .as_array() + .unwrap() + .iter() + .map(|value| value.map_ref(mapper)) + .collect::>()?; + + Ok(Self::array(new)) + } else { + mapper(self) + } + } + + fn for_each(&'json self, f: &mut impl FnMut(&'json Self)) { if let Some(arr) = self.as_array() { - arr.iter().try_for_each(f) + arr.iter().for_each(|value| value.for_each(f)) } else { f(self) } @@ -26,3 +44,60 @@ pub trait JsonLikeList<'json>: JsonLike<'json> { } impl<'json, T: JsonLike<'json>> JsonLikeList<'json> for T {} + +#[cfg(test)] +mod tests { + use serde_json::json; + + use super::*; + + #[test] + fn test_map() { + let value = json!([ + [[null, null, null], [null, null, null]], + [[null, null, null], [null, null, null]] + ]); + + let value = value + .map(&mut |_| anyhow::Ok(serde_json::Value::Object(Default::default()))) + .unwrap(); + + assert_eq!( + value, + json!([[[{}, {}, {}], [{}, {}, {}]], [[{}, {}, {}], [{}, {}, {}]]]) + ); + } + + #[test] + fn test_map_ref() { + let value = json!([ + [[null, null, null], [null, null, null]], + [[null, null, null], [null, null, null]] + ]); + + let value = value + .map_ref(&mut |_| anyhow::Ok(serde_json::Value::Object(Default::default()))) + .unwrap(); + + assert_eq!( + value, + json!([[[{}, {}, {}], [{}, {}, {}]], [[{}, {}, {}], [{}, {}, {}]]]) + ); + } + + #[test] + fn test_for_each() { + let value = json!([ + [[null, null, null], [null, null, null]], + [[null, null, null], [null, null, null]] + ]); + + let mut store = Vec::new(); + + value.for_each(&mut |value| { + store.push(value); + }); + + assert_eq!(store.len(), 12); + } +} diff --git a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.json.snap b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.json.snap deleted file mode 100644 index 1b2059b5bb..0000000000 --- a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.json.snap +++ /dev/null @@ -1,81 +0,0 @@ ---- -source: tests/cli/gen.rs -expression: config.to_sdl() ---- -schema @server @upstream(baseURL: "https://jsonplaceholder.typicode.com") { - query: Query -} - -input Id { - id: Int -} - -input news__MultipleNewsId { - ids: [Id] -} - -input news__NewsInput { - body: String - id: Int - postImage: String - status: news__Status - title: String -} - -enum news__Status { - DELETED - DRAFT - PUBLISHED -} - -type Address { - city: String - geo: Geo - street: String - suite: String - zipcode: String -} - -type Company { - bs: String - catchPhrase: String - name: String -} - -type Geo { - lat: String - lng: String -} - -type News { - body: String - id: Int - postImage: String - status: news__Status - title: String -} - -type NewsNewsServiceGetMultipleNew { - news: [News] -} - -type Query { - news__NewsService__AddNews(news: news__NewsInput!): News! @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: news__NewsId!): Empty! @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") - news__NewsService__EditNews(news: news__NewsInput!): News! @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") - news__NewsService__GetAllNews: NewsNewsServiceGetMultipleNew! @grpc(method: "news.NewsService.GetAllNews") - news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): NewsNewsServiceGetMultipleNew! @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: news__NewsId!): News! @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") - users: [User] @http(path: "/users") -} - -type User { - address: Address - company: Company - email: String - id: Int - name: String - phone: String - username: String - website: String -} diff --git a/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_0.snap b/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_0.snap new file mode 100644 index 0000000000..8d583dd624 --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_0.snap @@ -0,0 +1,43 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "users": [ + [ + { + "id": 1, + "name": "user-1", + "accountRef": "ref-1-user-1" + }, + { + "id": 2, + "name": "user-2", + "accountRef": "ref-2-user-2" + }, + { + "id": 3, + "name": "user-3", + "accountRef": "ref-3-user-3" + } + ], + [ + { + "name": "admin-1", + "region": "eu" + }, + { + "name": "admin-2", + "region": "us" + } + ] + ] + } + } +} diff --git a/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_client.snap b/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_client.snap new file mode 100644 index 0000000000..abb93793ac --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_client.snap @@ -0,0 +1,60 @@ +--- +source: tests/core/spec.rs +expression: formatted +--- +type Admin { + name: String! + region: String! +} + +scalar Bytes + +scalar Date + +scalar DateTime + +scalar Email + +scalar Empty + +scalar Int128 + +scalar Int16 + +scalar Int32 + +scalar Int64 + +scalar Int8 + +scalar JSON + +scalar PhoneNumber + +type Query { + users: [[Role!]!]! +} + +union Role = Admin | User + +scalar UInt128 + +scalar UInt16 + +scalar UInt32 + +scalar UInt64 + +scalar UInt8 + +scalar Url + +type User { + accountRef: String! + id: ID! + name: String! +} + +schema { + query: Query +} diff --git a/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_merged.snap b/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_merged.snap new file mode 100644 index 0000000000..ed061d025c --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-nested-lists-fragment.md_merged.snap @@ -0,0 +1,26 @@ +--- +source: tests/core/spec.rs +expression: formatter +--- +schema + @server(hostname: "0.0.0.0", port: 8001, queryValidation: false) + @upstream(baseURL: "http://upstream/", httpCache: 42) { + query: Query +} + +union Role = Admin | User + +type Admin { + name: String! + region: String! +} + +type Query { + users: [[Role!]!]! @http(path: "/users") +} + +type User { + accountRef: String! @http(path: "/refs/{{.value.id}}") + id: ID! + name: String! +} diff --git a/tests/core/snapshots/graphql-conformance-http-016.md_0.snap b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_0.snap similarity index 54% rename from tests/core/snapshots/graphql-conformance-http-016.md_0.snap rename to tests/core/snapshots/graphql-conformance-nested-lists-http.md_0.snap index c4f532dc57..09daefec5d 100644 --- a/tests/core/snapshots/graphql-conformance-http-016.md_0.snap +++ b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_0.snap @@ -13,29 +13,35 @@ expression: response [ { "id": 1, - "name": "user-1" + "name": "user-1", + "accountRef": "ref-1-user-1" }, { "id": 2, - "name": "user-2" + "name": "user-2", + "accountRef": "ref-2-user-2" }, { "id": 3, - "name": "user-3" + "name": "user-3", + "accountRef": "ref-3-user-3" } ], [ { "id": 4, - "name": "user-4" + "name": "user-4", + "accountRef": "ref-4-user-4" }, { "id": 5, - "name": "user-5" + "name": "user-5", + "accountRef": "ref-5-user-5" }, { "id": 6, - "name": "user-6" + "name": "user-6", + "accountRef": "ref-6-user-6" } ] ] diff --git a/tests/core/snapshots/graphql-conformance-016.md_1.snap b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_1.snap similarity index 100% rename from tests/core/snapshots/graphql-conformance-016.md_1.snap rename to tests/core/snapshots/graphql-conformance-nested-lists-http.md_1.snap diff --git a/tests/core/snapshots/graphql-conformance-016.md_2.snap b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_2.snap similarity index 100% rename from tests/core/snapshots/graphql-conformance-016.md_2.snap rename to tests/core/snapshots/graphql-conformance-nested-lists-http.md_2.snap diff --git a/tests/core/snapshots/graphql-conformance-http-016.md_client.snap b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_client.snap similarity index 95% rename from tests/core/snapshots/graphql-conformance-http-016.md_client.snap rename to tests/core/snapshots/graphql-conformance-nested-lists-http.md_client.snap index 90e5a57faa..78e475aae3 100644 --- a/tests/core/snapshots/graphql-conformance-http-016.md_client.snap +++ b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_client.snap @@ -44,6 +44,7 @@ scalar UInt8 scalar Url type User { + accountRef: String! id: ID! name: String! } diff --git a/tests/core/snapshots/graphql-conformance-http-016.md_merged.snap b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_merged.snap similarity index 85% rename from tests/core/snapshots/graphql-conformance-http-016.md_merged.snap rename to tests/core/snapshots/graphql-conformance-nested-lists-http.md_merged.snap index affeb02e65..ebb17ef514 100644 --- a/tests/core/snapshots/graphql-conformance-http-016.md_merged.snap +++ b/tests/core/snapshots/graphql-conformance-nested-lists-http.md_merged.snap @@ -14,6 +14,7 @@ type Query { } type User { + accountRef: String! @expr(body: "ref-{{.value.id}}-{{.value.name}}") id: ID! name: String! } diff --git a/tests/core/snapshots/graphql-conformance-016.md_0.snap b/tests/core/snapshots/graphql-conformance-nested-lists.md_0.snap similarity index 54% rename from tests/core/snapshots/graphql-conformance-016.md_0.snap rename to tests/core/snapshots/graphql-conformance-nested-lists.md_0.snap index c4f532dc57..09daefec5d 100644 --- a/tests/core/snapshots/graphql-conformance-016.md_0.snap +++ b/tests/core/snapshots/graphql-conformance-nested-lists.md_0.snap @@ -13,29 +13,35 @@ expression: response [ { "id": 1, - "name": "user-1" + "name": "user-1", + "accountRef": "ref-1-user-1" }, { "id": 2, - "name": "user-2" + "name": "user-2", + "accountRef": "ref-2-user-2" }, { "id": 3, - "name": "user-3" + "name": "user-3", + "accountRef": "ref-3-user-3" } ], [ { "id": 4, - "name": "user-4" + "name": "user-4", + "accountRef": "ref-4-user-4" }, { "id": 5, - "name": "user-5" + "name": "user-5", + "accountRef": "ref-5-user-5" }, { "id": 6, - "name": "user-6" + "name": "user-6", + "accountRef": "ref-6-user-6" } ] ] diff --git a/tests/core/snapshots/graphql-conformance-http-016.md_1.snap b/tests/core/snapshots/graphql-conformance-nested-lists.md_1.snap similarity index 100% rename from tests/core/snapshots/graphql-conformance-http-016.md_1.snap rename to tests/core/snapshots/graphql-conformance-nested-lists.md_1.snap diff --git a/tests/core/snapshots/graphql-conformance-http-016.md_2.snap b/tests/core/snapshots/graphql-conformance-nested-lists.md_2.snap similarity index 100% rename from tests/core/snapshots/graphql-conformance-http-016.md_2.snap rename to tests/core/snapshots/graphql-conformance-nested-lists.md_2.snap diff --git a/tests/core/snapshots/graphql-conformance-016.md_client.snap b/tests/core/snapshots/graphql-conformance-nested-lists.md_client.snap similarity index 95% rename from tests/core/snapshots/graphql-conformance-016.md_client.snap rename to tests/core/snapshots/graphql-conformance-nested-lists.md_client.snap index 90e5a57faa..78e475aae3 100644 --- a/tests/core/snapshots/graphql-conformance-016.md_client.snap +++ b/tests/core/snapshots/graphql-conformance-nested-lists.md_client.snap @@ -44,6 +44,7 @@ scalar UInt8 scalar Url type User { + accountRef: String! id: ID! name: String! } diff --git a/tests/core/snapshots/graphql-conformance-016.md_merged.snap b/tests/core/snapshots/graphql-conformance-nested-lists.md_merged.snap similarity index 86% rename from tests/core/snapshots/graphql-conformance-016.md_merged.snap rename to tests/core/snapshots/graphql-conformance-nested-lists.md_merged.snap index 088141a132..7443c27f80 100644 --- a/tests/core/snapshots/graphql-conformance-016.md_merged.snap +++ b/tests/core/snapshots/graphql-conformance-nested-lists.md_merged.snap @@ -15,6 +15,7 @@ type Query { } type User { + accountRef: String! @expr(body: "ref-{{.value.id}}-{{.value.name}}") id: ID! name: String! } diff --git a/tests/execution/graphql-conformance-nested-lists-fragment.md b/tests/execution/graphql-conformance-nested-lists-fragment.md new file mode 100644 index 0000000000..0bae05c593 --- /dev/null +++ b/tests/execution/graphql-conformance-nested-lists-fragment.md @@ -0,0 +1,86 @@ +# List of lists. + +```graphql @config +schema + @server(port: 8001, queryValidation: false, hostname: "0.0.0.0") + @upstream(baseURL: "http://upstream/", httpCache: 42) { + query: Query +} + +type Query { + users: [[Role!]!]! @http(path: "/users") +} + +type User { + id: ID! + name: String! + accountRef: String! @http(path: "/refs/{{.value.id}}") +} + +type Admin { + name: String! + region: String! +} + +union Role = User | Admin +``` + +```yml @mock +- request: + method: GET + url: http://upstream/users + response: + status: 200 + body: + - - id: 1 + name: user-1 + - id: 2 + name: user-2 + - id: 3 + name: user-3 + - - name: admin-1 + region: eu + - name: admin-2 + region: us + +# refs +- request: + method: GET + url: http://upstream/refs/1 + response: + status: 200 + body: ref-1-user-1 +- request: + method: GET + url: http://upstream/refs/2 + response: + status: 200 + body: ref-2-user-2 +- request: + method: GET + url: http://upstream/refs/3 + response: + status: 200 + body: ref-3-user-3 +``` + +```yml @test +# Positve +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + users { + ... on User { + id + name + accountRef + } + ... on Admin { + name + region + } + } + } +``` diff --git a/tests/execution/graphql-conformance-http-016.md b/tests/execution/graphql-conformance-nested-lists-http.md similarity index 94% rename from tests/execution/graphql-conformance-http-016.md rename to tests/execution/graphql-conformance-nested-lists-http.md index e16f6e4399..ede5b1697e 100644 --- a/tests/execution/graphql-conformance-http-016.md +++ b/tests/execution/graphql-conformance-nested-lists-http.md @@ -15,6 +15,7 @@ type Query { type User { id: ID! name: String! + accountRef: String! @expr(body: "ref-{{.value.id}}-{{.value.name}}") } ``` @@ -63,6 +64,7 @@ type User { userGroups { id name + accountRef } } diff --git a/tests/execution/graphql-conformance-016.md b/tests/execution/graphql-conformance-nested-lists.md similarity index 94% rename from tests/execution/graphql-conformance-016.md rename to tests/execution/graphql-conformance-nested-lists.md index 1d3a35dde9..addef681ba 100644 --- a/tests/execution/graphql-conformance-016.md +++ b/tests/execution/graphql-conformance-nested-lists.md @@ -16,6 +16,7 @@ type Query { type User { id: ID! name: String! + accountRef: String! @expr(body: "ref-{{.value.id}}-{{.value.name}}") } ``` @@ -62,6 +63,7 @@ type User { userGroups { id name + accountRef } } From b0984a902a896921cd33d663461eaca1e61e866e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 08:03:25 +0000 Subject: [PATCH 36/77] fix(deps): update rust crate rustls to v0.23.13 --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e9176e5f8..44b55d6f97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2431,7 +2431,7 @@ dependencies = [ "http 1.1.0", "hyper 1.4.0", "hyper-util", - "rustls 0.23.12", + "rustls 0.23.13", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -4286,7 +4286,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.12", + "rustls 0.23.13", "socket2 0.5.7", "thiserror", "tokio", @@ -4303,7 +4303,7 @@ dependencies = [ "rand", "ring", "rustc-hash", - "rustls 0.23.12", + "rustls 0.23.13", "slab", "thiserror", "tinyvec", @@ -4559,7 +4559,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.12", + "rustls 0.23.13", "rustls-pemfile 2.1.2", "rustls-pki-types", "serde", @@ -4753,21 +4753,21 @@ dependencies = [ "log", "ring", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] @@ -4822,9 +4822,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -5515,7 +5515,7 @@ dependencies = [ "reqwest-middleware", "resource", "rquickjs", - "rustls 0.23.12", + "rustls 0.23.13", "rustls-pemfile 1.0.4", "rustls-pki-types", "schemars", @@ -5977,7 +5977,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.12", + "rustls 0.23.13", "rustls-pki-types", "tokio", ] From 0be3fae9da0b3dfc6891ba07e77592249ea84272 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 09:28:18 +0000 Subject: [PATCH 37/77] fix(deps): update rust crate serde to v1.0.210 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44b55d6f97..51136ee041 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4944,9 +4944,9 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -4994,9 +4994,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", From 8bb288024c53229a66f3afc23a7b36b03340dd0e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:33:22 +0000 Subject: [PATCH 38/77] fix(deps): update rust crate serde_json to v1.0.128 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51136ee041..db02b97fb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5016,9 +5016,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "indexmap 2.4.0", "itoa", From 33c1471569dd067e9e2adb5de5b9ae8e4ff5fa43 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:24:29 +0000 Subject: [PATCH 39/77] fix(deps): update rust crate syn to v2.0.77 --- Cargo.lock | 86 +++++++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db02b97fb6..993c5eecb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,7 +286,7 @@ dependencies = [ "proc-macro2", "quote", "strum", - "syn 2.0.76", + "syn 2.0.77", "thiserror", ] @@ -440,7 +440,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -508,7 +508,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -525,7 +525,7 @@ checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -942,7 +942,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1222,7 +1222,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1244,7 +1244,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1296,7 +1296,7 @@ checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1340,7 +1340,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1360,7 +1360,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "unicode-xid", ] @@ -1373,7 +1373,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -1755,7 +1755,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -2925,7 +2925,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax 0.8.4", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3073,7 +3073,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3084,7 +3084,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3673,7 +3673,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3750,7 +3750,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3880,7 +3880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -3987,7 +3987,7 @@ dependencies = [ "prost 0.12.6", "prost-types 0.12.6", "regex", - "syn 2.0.76", + "syn 2.0.77", "tempfile", ] @@ -4001,7 +4001,7 @@ dependencies = [ "itertools 0.10.5", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -4014,7 +4014,7 @@ dependencies = [ "itertools 0.10.5", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -4672,7 +4672,7 @@ dependencies = [ "proc-macro2", "quote", "rquickjs-core", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -4882,7 +4882,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5000,7 +5000,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5011,7 +5011,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5335,7 +5335,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5357,9 +5357,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.76" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -5631,7 +5631,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5804,7 +5804,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5824,7 +5824,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -5947,7 +5947,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6107,7 +6107,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6120,7 +6120,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6218,7 +6218,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6528,7 +6528,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -6562,7 +6562,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6596,7 +6596,7 @@ checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6774,7 +6774,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -6796,7 +6796,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7070,7 +7070,7 @@ dependencies = [ "async-trait", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-macro-support", @@ -7098,7 +7098,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] @@ -7130,7 +7130,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn 2.0.77", ] [[package]] From e60475e2eceeb96eaafb5f3e1ef67a1d140316db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:06:46 +0000 Subject: [PATCH 40/77] fix(deps): update rust crate sysinfo to v0.31.4 --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 993c5eecb4..28694688d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5395,9 +5395,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.31.3" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b92e0bdf838cbc1c4c9ba14f9c97a7ec6cdcd1ae66b10e1e42775a25553f45d" +checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" dependencies = [ "core-foundation-sys", "libc", @@ -5654,7 +5654,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "sysinfo 0.31.3", + "sysinfo 0.31.4", "tailcall-version", "tokio", "tracing", From 4c1e2765ebf0f9aa85d500b0676c9d0085516277 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:05:46 +0000 Subject: [PATCH 41/77] chore(deps): update rust crate indexmap to v2.5.0 --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28694688d6..aeea158589 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,7 +256,7 @@ dependencies = [ "futures-util", "handlebars", "http 1.1.0", - "indexmap 2.4.0", + "indexmap 2.5.0", "lru", "mime", "multer", @@ -342,7 +342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0206011cad065420c27988f17dd7fe201a0e056b20c262209b7bffcd6fa176" dependencies = [ "bytes", - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_json", ] @@ -2048,7 +2048,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -2528,9 +2528,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -3694,7 +3694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.4.0", + "indexmap 2.5.0", ] [[package]] @@ -4666,7 +4666,7 @@ dependencies = [ "convert_case 0.6.0", "fnv", "ident_case", - "indexmap 2.4.0", + "indexmap 2.5.0", "proc-macro-crate 1.3.1", "proc-macro-error", "proc-macro2", @@ -5020,7 +5020,7 @@ version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa", "memchr", "ryu", @@ -5086,7 +5086,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa", "ryu", "serde", @@ -5475,7 +5475,7 @@ dependencies = [ "hyper 0.14.30", "hyper-rustls 0.25.0", "indenter", - "indexmap 2.4.0", + "indexmap 2.5.0", "inquire", "insta", "jsonwebtoken", @@ -6031,7 +6031,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "toml_datetime", "winnow", ] @@ -6042,7 +6042,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "toml_datetime", "winnow", ] From e592da3094413041880db727debe4894216b6cac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:06:41 +0000 Subject: [PATCH 42/77] chore(deps): update dependency wrangler to v3.78.4 --- tailcall-cloudflare/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index f1cc9c4473..59cfffe490 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1977,9 +1977,9 @@ } }, "node_modules/wrangler": { - "version": "3.78.3", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.3.tgz", - "integrity": "sha512-IRQ0HCmaVGeQVsW+4kqJfYuA1uBIAtjSCu8/aLRBXzdpiQ+0VSSj/uQ54wBRS08n4twFXTLiPAsYiNVF1aHyyA==", + "version": "3.78.4", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.4.tgz", + "integrity": "sha512-tIzfqg9yLk1mCxD2jwczN24vVK1W5CQ+xDCBZPxI24qWyGH5nE0n5xMnS6eknXNw0bhKaHCN7bzfxpE3DP4lPg==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -3695,9 +3695,9 @@ } }, "wrangler": { - "version": "3.78.3", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.3.tgz", - "integrity": "sha512-IRQ0HCmaVGeQVsW+4kqJfYuA1uBIAtjSCu8/aLRBXzdpiQ+0VSSj/uQ54wBRS08n4twFXTLiPAsYiNVF1aHyyA==", + "version": "3.78.4", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.4.tgz", + "integrity": "sha512-tIzfqg9yLk1mCxD2jwczN24vVK1W5CQ+xDCBZPxI24qWyGH5nE0n5xMnS6eknXNw0bhKaHCN7bzfxpE3DP4lPg==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", From 4b30023d939ece168c28fa1643db2cbed21416d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 01:34:13 +0000 Subject: [PATCH 43/77] chore(deps): update rust crate insta to v1.40.0 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aeea158589..a15166d14e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2565,9 +2565,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.39.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" dependencies = [ "console", "lazy_static", From 5ce342cf2f616af008fcd6b4e50b4efde69ae3a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 03:26:49 +0000 Subject: [PATCH 44/77] fix(deps): update rust crate dashmap to v6.1.0 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a15166d14e..367dd9664e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1255,9 +1255,9 @@ checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", From 17ff7b8807a29f0b01bd3409c9a8902b0cbc7d2b Mon Sep 17 00:00:00 2001 From: laststylebender <43403528+laststylebender14@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:52:26 +0530 Subject: [PATCH 45/77] feat: add health check endpoint (#2856) --- src/core/http/request_handler.rs | 42 ++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/core/http/request_handler.rs b/src/core/http/request_handler.rs index 05c72476a2..8357219a2d 100644 --- a/src/core/http/request_handler.rs +++ b/src/core/http/request_handler.rs @@ -321,7 +321,13 @@ async fn handle_request_inner( graphql_request::(req, &Arc::new(app_ctx), req_counter).await } - + hyper::Method::GET if req.uri().path() == "/status" => { + let status_response = Response::builder() + .status(StatusCode::OK) + .header(CONTENT_TYPE, "application/json") + .body(Body::from(r#"{"message": "ready"}"#))?; + Ok(status_response) + } hyper::Method::GET => { if let Some(TelemetryExporter::Prometheus(prometheus)) = app_ctx.blueprint.telemetry.export.as_ref() @@ -330,7 +336,6 @@ async fn handle_request_inner( return prometheus_metrics(prometheus); } }; - not_found() } _ => not_found(), @@ -377,6 +382,39 @@ pub async fn handle_request( #[cfg(test)] mod test { + use super::*; + use crate::core::async_graphql_hyper::GraphQLRequest; + use crate::core::blueprint::Blueprint; + use crate::core::config::{Config, ConfigModule}; + use crate::core::rest::EndpointSet; + use crate::core::runtime::test::init; + use crate::core::valid::Validator; + + #[tokio::test] + async fn test_health_endpoint() -> anyhow::Result<()> { + let sdl = tokio::fs::read_to_string(tailcall_fixtures::configs::JSONPLACEHOLDER).await?; + let config = Config::from_sdl(&sdl).to_result()?; + let blueprint = Blueprint::try_from(&ConfigModule::from(config))?; + let app_ctx = Arc::new(AppContext::new( + blueprint, + init(None), + EndpointSet::default(), + )); + + let req = Request::builder() + .method(Method::GET) + .uri("http://localhost:8000/status".to_string()) + .body(Body::empty())?; + + let resp = handle_request::(req, app_ctx).await?; + + assert_eq!(resp.status(), StatusCode::OK); + let body = hyper::body::to_bytes(resp.into_body()).await?; + assert_eq!(body, r#"{"message": "ready"}"#); + + Ok(()) + } + #[test] fn test_create_allowed_headers() { use std::collections::BTreeSet; From 078cc2767bd7123e95d0eed92324d6a127323850 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 08:24:46 +0000 Subject: [PATCH 46/77] fix(deps): update rust crate tokio to v1.40.0 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 367dd9664e..4ee7435baa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5913,9 +5913,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", From a6310d2d8f0d01fb566571ed6d3bf5afa6438b9a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:45:03 +0000 Subject: [PATCH 47/77] chore(deps): update dependency miniflare to v3.20240909.3 --- tailcall-cloudflare/package-lock.json | 58 ++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 59cfffe490..f84ded8b38 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1334,9 +1334,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240909.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", - "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", + "version": "3.20240909.3", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", + "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -2409,6 +2409,32 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "3.20240909.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", + "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3261,9 +3287,9 @@ "dev": true }, "miniflare": { - "version": "3.20240909.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", - "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", + "version": "3.20240909.3", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", + "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", @@ -3904,6 +3930,26 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } + }, + "miniflare": { + "version": "3.20240909.2", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", + "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + } } } }, From 5e020ae5b834ed7cd8e619a4dd07b0e58ef9c9f6 Mon Sep 17 00:00:00 2001 From: Panagiotis Karatakis Date: Thu, 19 Sep 2024 17:27:07 +0300 Subject: [PATCH 48/77] fix(jit): input arguments required error (#2756) Co-authored-by: Tushar Mathur Co-authored-by: Kiryl Mialeshka <8974488+meskill@users.noreply.github.com> --- src/core/blueprint/index.rs | 8 ++ src/core/jit/context.rs | 9 +- src/core/jit/error.rs | 5 + src/core/jit/input_resolver.rs | 106 +++++++++++++++++- ...e__jit__builder__tests__default_value.snap | 5 + ...builder__tests__resolving_operation-2.snap | 5 + src/core/json/borrow.rs | 7 ++ src/core/json/graphql.rs | 7 ++ src/core/json/json_like.rs | 1 + src/core/json/serde.rs | 4 + .../graphql-conformance-001.md_5.snap | 18 +++ .../graphql-conformance-015.md_10.snap | 18 +++ .../graphql-conformance-015.md_11.snap | 19 ++++ .../graphql-conformance-015.md_5.snap | 2 +- .../graphql-conformance-015.md_9.snap | 18 +++ .../graphql-conformance-015.md_client.snap | 5 + .../graphql-conformance-015.md_merged.snap | 5 + .../graphql-conformance-http-001.md_5.snap | 18 +++ .../graphql-conformance-http-015.md_10.snap | 18 +++ .../graphql-conformance-http-015.md_11.snap | 19 ++++ .../graphql-conformance-http-015.md_5.snap | 2 +- .../graphql-conformance-http-015.md_9.snap | 18 +++ ...raphql-conformance-http-015.md_client.snap | 7 +- ...raphql-conformance-http-015.md_merged.snap | 7 +- tests/core/snapshots/grpc-oneof.md_0.snap | 2 +- tests/execution/graphql-conformance-001.md | 23 ++-- tests/execution/graphql-conformance-015.md | 68 ++++++----- .../execution/graphql-conformance-http-001.md | 23 ++-- .../execution/graphql-conformance-http-015.md | 68 ++++++----- tests/execution/grpc-oneof.md | 2 +- 30 files changed, 422 insertions(+), 95 deletions(-) create mode 100644 tests/core/snapshots/graphql-conformance-001.md_5.snap create mode 100644 tests/core/snapshots/graphql-conformance-015.md_10.snap create mode 100644 tests/core/snapshots/graphql-conformance-015.md_11.snap create mode 100644 tests/core/snapshots/graphql-conformance-015.md_9.snap create mode 100644 tests/core/snapshots/graphql-conformance-http-001.md_5.snap create mode 100644 tests/core/snapshots/graphql-conformance-http-015.md_10.snap create mode 100644 tests/core/snapshots/graphql-conformance-http-015.md_11.snap create mode 100644 tests/core/snapshots/graphql-conformance-http-015.md_9.snap diff --git a/src/core/blueprint/index.rs b/src/core/blueprint/index.rs index d8ebe1a317..3631b932ad 100644 --- a/src/core/blueprint/index.rs +++ b/src/core/blueprint/index.rs @@ -1,5 +1,6 @@ use indexmap::IndexMap; +use super::InputObjectTypeDefinition; use crate::core::blueprint::{ Blueprint, Definition, FieldDefinition, InputFieldDefinition, SchemaDefinition, }; @@ -78,6 +79,13 @@ impl Index { false } } + + pub fn get_input_type_definition(&self, type_name: &str) -> Option<&InputObjectTypeDefinition> { + match self.map.get(type_name) { + Some((Definition::InputObject(input), _)) => Some(input), + _ => None, + } + } } impl From<&Blueprint> for Index { diff --git a/src/core/jit/context.rs b/src/core/jit/context.rs index dc208eaf86..2ff3a54792 100644 --- a/src/core/jit/context.rs +++ b/src/core/jit/context.rs @@ -80,16 +80,9 @@ impl<'a, Input: Clone, Output> Context<'a, Input, Output> { for arg in field.args.iter() { let name = arg.name.as_str(); - let value = arg - .value - .clone() - // TODO: default value resolution should happen in the InputResolver - .or_else(|| arg.default_value.clone()); + let value = arg.value.clone(); if let Some(value) = value { arg_map.insert(Name::new(name), value); - } else if !arg.type_of.is_nullable() { - // TODO: throw error here - todo!() } } Some(arg_map) diff --git a/src/core/jit/error.rs b/src/core/jit/error.rs index b47380097c..fdff5ef18f 100644 --- a/src/core/jit/error.rs +++ b/src/core/jit/error.rs @@ -20,6 +20,11 @@ pub enum BuildError { pub enum ResolveInputError { #[error("Variable `{0}` is not defined")] VariableIsNotFound(String), + #[error("Argument `{arg_name}` for field `{field_name}` is required")] + ArgumentIsRequired { + arg_name: String, + field_name: String, + }, } #[derive(Error, Debug, Clone)] diff --git a/src/core/jit/input_resolver.rs b/src/core/jit/input_resolver.rs index 4e9ccbb776..fcde3c387b 100644 --- a/src/core/jit/input_resolver.rs +++ b/src/core/jit/input_resolver.rs @@ -1,6 +1,8 @@ use async_graphql_value::{ConstValue, Value}; -use super::{OperationPlan, ResolveInputError, Variables}; +use super::{Arg, Field, OperationPlan, ResolveInputError, Variables}; +use crate::core::json::{JsonLikeOwned, JsonObjectLike}; +use crate::core::Type; /// Trait to represent conversion from some dynamic type (with variables) /// to the resolved variant based on the additional provided info. @@ -18,8 +20,6 @@ pub trait InputResolvable { impl InputResolvable for Value { type Output = ConstValue; - // TODO: - // - provide default values fn resolve(self, variables: &Variables) -> Result { self.into_const_with(|name| { variables @@ -45,8 +45,9 @@ impl InputResolver { impl InputResolver where Input: Clone, - Output: Clone, + Output: Clone + JsonLikeOwned + TryFrom, Input: InputResolvable, + >::Error: std::fmt::Debug, { pub fn resolve_input( &self, @@ -57,7 +58,28 @@ where .as_parent() .iter() .map(|field| field.clone().try_map(|value| value.resolve(variables))) - .collect::>()?; + .map(|field| match field { + Ok(field) => { + let args = field + .args + .into_iter() + .map(|arg| { + let value = self.recursive_parse_arg( + &field.name, + &arg.name, + &arg.type_of, + &arg.default_value, + arg.value, + )?; + Ok(Arg { value, ..arg }) + }) + .collect::>()?; + + Ok(Field { args, ..field }) + } + Err(err) => Err(err), + }) + .collect::, _>>()?; Ok(OperationPlan::new( new_fields, @@ -66,4 +88,78 @@ where self.plan.is_introspection_query, )) } + + #[allow(clippy::too_many_arguments)] + fn recursive_parse_arg( + &self, + parent_name: &str, + arg_name: &str, + type_of: &Type, + default_value: &Option, + value: Option, + ) -> Result, ResolveInputError> { + let is_value_null = value.as_ref().map(|val| val.is_null()).unwrap_or(true); + let value = if !type_of.is_nullable() && value.is_none() { + let default_value = default_value.clone(); + + Some(default_value.ok_or(ResolveInputError::ArgumentIsRequired { + arg_name: arg_name.to_string(), + field_name: parent_name.to_string(), + })?) + } else if !type_of.is_nullable() && is_value_null { + return Err(ResolveInputError::ArgumentIsRequired { + arg_name: arg_name.to_string(), + field_name: parent_name.to_string(), + }); + } else if value.is_none() { + default_value.clone() + } else { + value + }; + + let Some(mut value) = value else { + return Ok(None); + }; + + let Some(def) = self.plan.index.get_input_type_definition(type_of.name()) else { + return Ok(Some(value)); + }; + + if let Some(obj) = value.as_object_mut() { + for arg_field in &def.fields { + let parent_name = format!("{}.{}", parent_name, arg_name); + let field_value = obj.get_key(&arg_field.name).cloned(); + let field_default = arg_field + .default_value + .clone() + .map(|value| Output::try_from(value).expect("The conversion cannot fail")); + let value = self.recursive_parse_arg( + &parent_name, + &arg_field.name, + &arg_field.of_type, + &field_default, + field_value, + )?; + if let Some(value) = value { + obj.insert_key(&arg_field.name, value); + } + } + } else if let Some(arr) = value.as_array_mut() { + for (index, item) in arr.iter_mut().enumerate() { + let parent_name = format!("{}.{}.{}", parent_name, arg_name, index); + + *item = self + .recursive_parse_arg( + &parent_name, + &index.to_string(), + type_of, + &None, + Some(item.clone()), + )? + .expect("Because we start with `Some`, we will end with `Some`"); + } + } + + Ok(Some(value)) + } } diff --git a/src/core/jit/snapshots/tailcall__core__jit__builder__tests__default_value.snap b/src/core/jit/snapshots/tailcall__core__jit__builder__tests__default_value.snap index 2ab1e80e91..c1bdc1b33d 100644 --- a/src/core/jit/snapshots/tailcall__core__jit__builder__tests__default_value.snap +++ b/src/core/jit/snapshots/tailcall__core__jit__builder__tests__default_value.snap @@ -35,6 +35,11 @@ expression: plan.into_nested() ): String( "tailcall test", ), + Name( + "id", + ): Number( + Number(101), + ), }, ), ), diff --git a/src/core/jit/snapshots/tailcall__core__jit__builder__tests__resolving_operation-2.snap b/src/core/jit/snapshots/tailcall__core__jit__builder__tests__resolving_operation-2.snap index 1ef844578d..08c1237e9b 100644 --- a/src/core/jit/snapshots/tailcall__core__jit__builder__tests__resolving_operation-2.snap +++ b/src/core/jit/snapshots/tailcall__core__jit__builder__tests__resolving_operation-2.snap @@ -35,6 +35,11 @@ expression: plan.into_nested() ): String( "test-12", ), + Name( + "id", + ): Number( + Number(101), + ), }, ), ), diff --git a/src/core/json/borrow.rs b/src/core/json/borrow.rs index 1a38196ca8..fdc99ea310 100644 --- a/src/core/json/borrow.rs +++ b/src/core/json/borrow.rs @@ -47,6 +47,13 @@ impl<'ctx> JsonLike<'ctx> for Value<'ctx> { } } + fn as_array_mut(&mut self) -> Option<&mut Vec> { + match self { + Value::Array(arr) => Some(arr), + _ => None, + } + } + fn into_array(self) -> Option> { match self { Value::Array(array) => Some(array), diff --git a/src/core/json/graphql.rs b/src/core/json/graphql.rs index aa049a8ed8..2380218b14 100644 --- a/src/core/json/graphql.rs +++ b/src/core/json/graphql.rs @@ -33,6 +33,13 @@ impl<'json> JsonLike<'json> for ConstValue { } } + fn as_array_mut(&mut self) -> Option<&mut Vec> { + match self { + ConstValue::List(seq) => Some(seq), + _ => None, + } + } + fn into_array(self) -> Option> { match self { ConstValue::List(seq) => Some(seq), diff --git a/src/core/json/json_like.rs b/src/core/json/json_like.rs index 6452036e4a..eead31db09 100644 --- a/src/core/json/json_like.rs +++ b/src/core/json/json_like.rs @@ -16,6 +16,7 @@ pub trait JsonLike<'json>: Sized { // Operators fn as_array(&self) -> Option<&Vec>; + fn as_array_mut(&mut self) -> Option<&mut Vec>; fn into_array(self) -> Option>; fn as_object(&self) -> Option<&Self::JsonObject>; fn as_object_mut(&mut self) -> Option<&mut Self::JsonObject>; diff --git a/src/core/json/serde.rs b/src/core/json/serde.rs index 4f6fad6609..647c87448b 100644 --- a/src/core/json/serde.rs +++ b/src/core/json/serde.rs @@ -26,6 +26,10 @@ impl<'json> JsonLike<'json> for serde_json::Value { self.as_array() } + fn as_array_mut(&mut self) -> Option<&mut Vec> { + self.as_array_mut() + } + fn into_array(self) -> Option> { if let Self::Array(vec) = self { Some(vec) diff --git a/tests/core/snapshots/graphql-conformance-001.md_5.snap b/tests/core/snapshots/graphql-conformance-001.md_5.snap new file mode 100644 index 0000000000..92f6de675e --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-001.md_5.snap @@ -0,0 +1,18 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": null, + "errors": [ + { + "message": "Build error: ResolveInputError: Argument `id` for field `user` is required" + } + ] + } +} diff --git a/tests/core/snapshots/graphql-conformance-015.md_10.snap b/tests/core/snapshots/graphql-conformance-015.md_10.snap new file mode 100644 index 0000000000..1431a65d5e --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-015.md_10.snap @@ -0,0 +1,18 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": null, + "errors": [ + { + "message": "Build error: ResolveInputError: Argument `size` for field `profilePic` is required" + } + ] + } +} diff --git a/tests/core/snapshots/graphql-conformance-015.md_11.snap b/tests/core/snapshots/graphql-conformance-015.md_11.snap new file mode 100644 index 0000000000..a24ffcbc5d --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-015.md_11.snap @@ -0,0 +1,19 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "user": { + "id": 4, + "name": "User 4", + "spam": "FIZZ: [{\"bar\":\"BUZZ\"},{\"bar\":\"test\"}]" + } + } + } +} diff --git a/tests/core/snapshots/graphql-conformance-015.md_5.snap b/tests/core/snapshots/graphql-conformance-015.md_5.snap index 02642dd54c..d4492073ee 100644 --- a/tests/core/snapshots/graphql-conformance-015.md_5.snap +++ b/tests/core/snapshots/graphql-conformance-015.md_5.snap @@ -12,7 +12,7 @@ expression: response "user": { "id": 4, "name": "User 4", - "featuredVideo": "video_4_1600_900_" + "featuredVideo": "video_4_1600_900_true" } } } diff --git a/tests/core/snapshots/graphql-conformance-015.md_9.snap b/tests/core/snapshots/graphql-conformance-015.md_9.snap new file mode 100644 index 0000000000..d1fd985eaf --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-015.md_9.snap @@ -0,0 +1,18 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": null, + "errors": [ + { + "message": "Build error: ResolveInputError: Argument `height` for field `featuredVideoPreview.video` is required" + } + ] + } +} diff --git a/tests/core/snapshots/graphql-conformance-015.md_client.snap b/tests/core/snapshots/graphql-conformance-015.md_client.snap index fdbd6e202b..e2c88c1b06 100644 --- a/tests/core/snapshots/graphql-conformance-015.md_client.snap +++ b/tests/core/snapshots/graphql-conformance-015.md_client.snap @@ -12,6 +12,10 @@ scalar Email scalar Empty +input Foo { + bar: String! = "BUZZ" +} + scalar Int128 scalar Int16 @@ -49,6 +53,7 @@ type User { name: String! profilePic(size: Int! = 100, width: Int, height: Int = 100): String! searchComments(query: [[String!]!]! = [["today"]]): String! + spam(foo: [Foo!]!): String! } input VideoSize { diff --git a/tests/core/snapshots/graphql-conformance-015.md_merged.snap b/tests/core/snapshots/graphql-conformance-015.md_merged.snap index d11302e3fc..97a408bc1a 100644 --- a/tests/core/snapshots/graphql-conformance-015.md_merged.snap +++ b/tests/core/snapshots/graphql-conformance-015.md_merged.snap @@ -8,6 +8,10 @@ schema query: Query } +input Foo { + bar: String! = "BUZZ" +} + input VideoSize { hdr: Boolean = true height: Int! @@ -28,4 +32,5 @@ type User { profilePic(size: Int! = 100, width: Int, height: Int = 100): String! @expr(body: "{{.value.id}}_{{.args.size}}_{{.args.width}}_{{.args.height}}") searchComments(query: [[String!]!]! = [["today"]]): String! @expr(body: "video_{{.value.id}}_{{.args.query}}") + spam(foo: [Foo!]!): String! @expr(body: "FIZZ: {{.args.foo}}") } diff --git a/tests/core/snapshots/graphql-conformance-http-001.md_5.snap b/tests/core/snapshots/graphql-conformance-http-001.md_5.snap new file mode 100644 index 0000000000..92f6de675e --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-http-001.md_5.snap @@ -0,0 +1,18 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": null, + "errors": [ + { + "message": "Build error: ResolveInputError: Argument `id` for field `user` is required" + } + ] + } +} diff --git a/tests/core/snapshots/graphql-conformance-http-015.md_10.snap b/tests/core/snapshots/graphql-conformance-http-015.md_10.snap new file mode 100644 index 0000000000..1431a65d5e --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-http-015.md_10.snap @@ -0,0 +1,18 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": null, + "errors": [ + { + "message": "Build error: ResolveInputError: Argument `size` for field `profilePic` is required" + } + ] + } +} diff --git a/tests/core/snapshots/graphql-conformance-http-015.md_11.snap b/tests/core/snapshots/graphql-conformance-http-015.md_11.snap new file mode 100644 index 0000000000..a24ffcbc5d --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-http-015.md_11.snap @@ -0,0 +1,19 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "user": { + "id": 4, + "name": "User 4", + "spam": "FIZZ: [{\"bar\":\"BUZZ\"},{\"bar\":\"test\"}]" + } + } + } +} diff --git a/tests/core/snapshots/graphql-conformance-http-015.md_5.snap b/tests/core/snapshots/graphql-conformance-http-015.md_5.snap index 02642dd54c..d4492073ee 100644 --- a/tests/core/snapshots/graphql-conformance-http-015.md_5.snap +++ b/tests/core/snapshots/graphql-conformance-http-015.md_5.snap @@ -12,7 +12,7 @@ expression: response "user": { "id": 4, "name": "User 4", - "featuredVideo": "video_4_1600_900_" + "featuredVideo": "video_4_1600_900_true" } } } diff --git a/tests/core/snapshots/graphql-conformance-http-015.md_9.snap b/tests/core/snapshots/graphql-conformance-http-015.md_9.snap new file mode 100644 index 0000000000..d1fd985eaf --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-http-015.md_9.snap @@ -0,0 +1,18 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": null, + "errors": [ + { + "message": "Build error: ResolveInputError: Argument `height` for field `featuredVideoPreview.video` is required" + } + ] + } +} diff --git a/tests/core/snapshots/graphql-conformance-http-015.md_client.snap b/tests/core/snapshots/graphql-conformance-http-015.md_client.snap index d275a8ae1d..e2c88c1b06 100644 --- a/tests/core/snapshots/graphql-conformance-http-015.md_client.snap +++ b/tests/core/snapshots/graphql-conformance-http-015.md_client.snap @@ -12,6 +12,10 @@ scalar Email scalar Empty +input Foo { + bar: String! = "BUZZ" +} + scalar Int128 scalar Int16 @@ -49,10 +53,11 @@ type User { name: String! profilePic(size: Int! = 100, width: Int, height: Int = 100): String! searchComments(query: [[String!]!]! = [["today"]]): String! + spam(foo: [Foo!]!): String! } input VideoSize { - hdr: Boolean + hdr: Boolean = true height: Int! width: Int! } diff --git a/tests/core/snapshots/graphql-conformance-http-015.md_merged.snap b/tests/core/snapshots/graphql-conformance-http-015.md_merged.snap index c3b08996ee..0d5cfa528f 100644 --- a/tests/core/snapshots/graphql-conformance-http-015.md_merged.snap +++ b/tests/core/snapshots/graphql-conformance-http-015.md_merged.snap @@ -8,8 +8,12 @@ schema query: Query } +input Foo { + bar: String! = "BUZZ" +} + input VideoSize { - hdr: Boolean + hdr: Boolean = true height: Int! width: Int! } @@ -28,4 +32,5 @@ type User { profilePic(size: Int! = 100, width: Int, height: Int = 100): String! @expr(body: "{{.value.id}}_{{.args.size}}_{{.args.width}}_{{.args.height}}") searchComments(query: [[String!]!]! = [["today"]]): String! @expr(body: "video_{{.value.id}}_{{.args.query}}") + spam(foo: [Foo!]!): String! @expr(body: "FIZZ: {{.args.foo}}") } diff --git a/tests/core/snapshots/grpc-oneof.md_0.snap b/tests/core/snapshots/grpc-oneof.md_0.snap index 4abb776e20..c46a4ee1a1 100644 --- a/tests/core/snapshots/grpc-oneof.md_0.snap +++ b/tests/core/snapshots/grpc-oneof.md_0.snap @@ -9,7 +9,7 @@ expression: response }, "body": { "data": { - "oneof__OneOfService__GetOneOfVar1": { + "oneof__OneOfService__GetOneOfVar3": { "usual": 5, "command": { "command": "end" diff --git a/tests/execution/graphql-conformance-001.md b/tests/execution/graphql-conformance-001.md index c92262e53c..eaf8cbb478 100644 --- a/tests/execution/graphql-conformance-001.md +++ b/tests/execution/graphql-conformance-001.md @@ -114,16 +114,15 @@ type User { } # Negative: missing input -# TODO: expect error that user.id input is missing -# - method: POST -# url: http://localhost:8080/graphql -# body: -# query: | -# query { -# user { -# id -# name -# city -# } -# } +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user { + id + name + city + } + } ``` diff --git a/tests/execution/graphql-conformance-015.md b/tests/execution/graphql-conformance-015.md index 74c802069a..761f9f687d 100644 --- a/tests/execution/graphql-conformance-015.md +++ b/tests/execution/graphql-conformance-015.md @@ -21,6 +21,7 @@ type User { featuredVideoPreview(video: VideoSize! = {}): String! @expr(body: "video_{{.value.id}}_{{.args.video.width}}_{{.args.video.height}}_{{.args.video.hdr}}") searchComments(query: [[String!]!]! = [["today"]]): String! @expr(body: "video_{{.value.id}}_{{.args.query}}") + spam(foo: [Foo!]!): String! @expr(body: "FIZZ: {{.args.foo}}") } input VideoSize { @@ -28,6 +29,10 @@ input VideoSize { height: Int! hdr: Boolean = true } + +input Foo { + bar: String! = "BUZZ" +} ``` ```yml @mock @@ -35,7 +40,7 @@ input VideoSize { method: POST url: http://upstream/graphql textBody: '{ "query": "query { user(id: 4) { id name } }" }' - expectedHits: 9 + expectedHits: 10 response: status: 200 body: @@ -155,31 +160,42 @@ input VideoSize { } } -# # Positve: defaults from input -# TODO: tailcall should use defaults provided from Input Object and hdr should be true -# - method: POST -# url: http://localhost:8080/graphql -# body: -# query: | -# query { -# user(id: 4) { -# id -# name -# featuredVideoPreview -# } -# } +# Positve: defaults from input +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user(id: 4) { + id + name + featuredVideoPreview + } + } # Negative: invalid size -# TODO: tailcall should return error that size cannot be null -# - method: POST -# url: http://localhost:8080/graphql -# body: -# query: | -# query { -# user(id: 4) { -# id -# name -# profilePic(size: null) -# } -# } +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user(id: 4) { + id + name + profilePic(size: null) + } + } + +# Positve: array fields +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user(id: 4) { + id + name + spam(foo: [{}, { bar: "test"}]) + } + } ``` diff --git a/tests/execution/graphql-conformance-http-001.md b/tests/execution/graphql-conformance-http-001.md index cd96426869..559445269c 100644 --- a/tests/execution/graphql-conformance-http-001.md +++ b/tests/execution/graphql-conformance-http-001.md @@ -86,16 +86,15 @@ type User { } # Negative: missing input -# TODO: expect error that user.id input is missing -# - method: POST -# url: http://localhost:8080/graphql -# body: -# query: | -# query { -# user { -# id -# name -# city -# } -# } +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user { + id + name + city + } + } ``` diff --git a/tests/execution/graphql-conformance-http-015.md b/tests/execution/graphql-conformance-http-015.md index d9fc3e7a36..81089c9309 100644 --- a/tests/execution/graphql-conformance-http-015.md +++ b/tests/execution/graphql-conformance-http-015.md @@ -21,12 +21,17 @@ type User { featuredVideoPreview(video: VideoSize! = {}): String! @expr(body: "video_{{.value.id}}_{{.args.video.width}}_{{.args.video.height}}_{{.args.video.hdr}}") searchComments(query: [[String!]!]! = [["today"]]): String! @expr(body: "video_{{.value.id}}_{{.args.query}}") + spam(foo: [Foo!]!): String! @expr(body: "FIZZ: {{.args.foo}}") } input VideoSize { width: Int! height: Int! - hdr: Boolean + hdr: Boolean = true +} + +input Foo { + bar: String! = "BUZZ" } ``` @@ -34,7 +39,7 @@ input VideoSize { - request: method: GET url: http://upstream/user?id=4 - expectedHits: 9 + expectedHits: 10 response: status: 200 body: @@ -153,30 +158,41 @@ input VideoSize { } # # Positve: defaults from input -# TODO: tailcall should use defaults provided from Input Object and hdr should be true -# - method: POST -# url: http://localhost:8080/graphql -# body: -# query: | -# query { -# user(id: 4) { -# id -# name -# featuredVideoPreview -# } -# } +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user(id: 4) { + id + name + featuredVideoPreview + } + } # Negative: invalid size -# TODO: tailcall should return error that size cannot be null -# - method: POST -# url: http://localhost:8080/graphql -# body: -# query: | -# query { -# user(id: 4) { -# id -# name -# profilePic(size: null) -# } -# } +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user(id: 4) { + id + name + profilePic(size: null) + } + } + +# Positve: array fields +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query { + user(id: 4) { + id + name + spam(foo: [{}, { bar: "test"}]) + } + } ``` diff --git a/tests/execution/grpc-oneof.md b/tests/execution/grpc-oneof.md index 3b23f10b19..71636d469e 100644 --- a/tests/execution/grpc-oneof.md +++ b/tests/execution/grpc-oneof.md @@ -172,7 +172,7 @@ type oneof__Response__Var2 implements oneof__Response__Interface { body: query: > query { - oneof__OneOfService__GetOneOfVar1(request: { command: { command: "start" } }) { + oneof__OneOfService__GetOneOfVar3(request: { command: { command: "start" } }) { ... on oneof__Response__Interface { usual } From 333e1edf14d90fe07bb94cfc69f8dc18e4135fb7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:28:11 +0000 Subject: [PATCH 49/77] chore(deps): update dependency wrangler to v3.78.5 --- tailcall-cloudflare/package-lock.json | 78 ++++++--------------------- 1 file changed, 16 insertions(+), 62 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index f84ded8b38..e4938175d6 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1789,9 +1789,9 @@ }, "node_modules/unenv": { "name": "unenv-nightly", - "version": "2.0.0-1724863496.70db6f1", - "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-1724863496.70db6f1.tgz", - "integrity": "sha512-r+VIl1gnsI4WQxluruSQhy8alpAf1AsLRLm4sEKp3otCyTIVD6I6wHEYzeQnwsyWgaD4+3BD4A/eqrgOpdTzhw==", + "version": "2.0.0-1726478054.1e87097", + "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-1726478054.1e87097.tgz", + "integrity": "sha512-uZso8dCkGlJzWQqkyjOA5L4aUqNJl9E9oKRm03V/d+URrg6rFMJwBonlX9AAq538NxwJpPnCX0gAz0IfTxsbFQ==", "dev": true, "dependencies": { "defu": "^6.1.4", @@ -1977,9 +1977,9 @@ } }, "node_modules/wrangler": { - "version": "3.78.4", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.4.tgz", - "integrity": "sha512-tIzfqg9yLk1mCxD2jwczN24vVK1W5CQ+xDCBZPxI24qWyGH5nE0n5xMnS6eknXNw0bhKaHCN7bzfxpE3DP4lPg==", + "version": "3.78.5", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.5.tgz", + "integrity": "sha512-EqCQOuuxHCBHLSjWw7kWT/1PDSw38XUhSxPC3VnDcL7F6TukVBfHHyLFO4NYGTDDoH+G8KVK1bL1q8LXY2Rcbg==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -1990,14 +1990,14 @@ "chokidar": "^3.5.3", "date-fns": "^3.6.0", "esbuild": "0.17.19", - "miniflare": "3.20240909.2", + "miniflare": "3.20240909.3", "nanoid": "^3.3.3", "path-to-regexp": "^6.3.0", "resolve": "^1.22.8", "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@2.0.0-1724863496.70db6f1", + "unenv": "npm:unenv-nightly@2.0.0-1726478054.1e87097", "workerd": "1.20240909.0", "xxhash-wasm": "^1.0.1" }, @@ -2409,32 +2409,6 @@ "@esbuild/win32-x64": "0.17.19" } }, - "node_modules/wrangler/node_modules/miniflare": { - "version": "3.20240909.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", - "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", - "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.4", - "workerd": "1.20240909.0", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3635,9 +3609,9 @@ "dev": true }, "unenv": { - "version": "npm:unenv-nightly@2.0.0-1724863496.70db6f1", - "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-1724863496.70db6f1.tgz", - "integrity": "sha512-r+VIl1gnsI4WQxluruSQhy8alpAf1AsLRLm4sEKp3otCyTIVD6I6wHEYzeQnwsyWgaD4+3BD4A/eqrgOpdTzhw==", + "version": "npm:unenv-nightly@2.0.0-1726478054.1e87097", + "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-1726478054.1e87097.tgz", + "integrity": "sha512-uZso8dCkGlJzWQqkyjOA5L4aUqNJl9E9oKRm03V/d+URrg6rFMJwBonlX9AAq538NxwJpPnCX0gAz0IfTxsbFQ==", "dev": true, "requires": { "defu": "^6.1.4", @@ -3721,9 +3695,9 @@ } }, "wrangler": { - "version": "3.78.4", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.4.tgz", - "integrity": "sha512-tIzfqg9yLk1mCxD2jwczN24vVK1W5CQ+xDCBZPxI24qWyGH5nE0n5xMnS6eknXNw0bhKaHCN7bzfxpE3DP4lPg==", + "version": "3.78.5", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.5.tgz", + "integrity": "sha512-EqCQOuuxHCBHLSjWw7kWT/1PDSw38XUhSxPC3VnDcL7F6TukVBfHHyLFO4NYGTDDoH+G8KVK1bL1q8LXY2Rcbg==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -3735,14 +3709,14 @@ "date-fns": "^3.6.0", "esbuild": "0.17.19", "fsevents": "~2.3.2", - "miniflare": "3.20240909.2", + "miniflare": "3.20240909.3", "nanoid": "^3.3.3", "path-to-regexp": "^6.3.0", "resolve": "^1.22.8", "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@2.0.0-1724863496.70db6f1", + "unenv": "npm:unenv-nightly@2.0.0-1726478054.1e87097", "workerd": "1.20240909.0", "xxhash-wasm": "^1.0.1" }, @@ -3930,26 +3904,6 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } - }, - "miniflare": { - "version": "3.20240909.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.2.tgz", - "integrity": "sha512-rZe7d0GkP02DnsgLD6qT+0K3O1azWCbDQIeHyH7WHJeyfkGPONS8U5FeNJEmus05z+2F6jcMI/Gc/Irc+UFTAA==", - "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.4", - "workerd": "1.20240909.0", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - } } } }, From 224da65cef066ea7ba3e96ed1b67472558d576e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 18:55:12 +0000 Subject: [PATCH 50/77] chore(deps): update dependency miniflare to v3.20240909.4 --- tailcall-cloudflare/package-lock.json | 58 ++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index e4938175d6..21e228d0a0 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1334,9 +1334,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240909.3", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", - "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", + "version": "3.20240909.4", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.4.tgz", + "integrity": "sha512-uiMjmv9vYIMgUn5PovS/2XzvnSgm04GxtoreNb7qiaDdp1YMhPPtnmV+EKOKyPSlVc7fCt/glzqSX9atUBXa2A==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -2409,6 +2409,32 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "3.20240909.3", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", + "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3261,9 +3287,9 @@ "dev": true }, "miniflare": { - "version": "3.20240909.3", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", - "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", + "version": "3.20240909.4", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.4.tgz", + "integrity": "sha512-uiMjmv9vYIMgUn5PovS/2XzvnSgm04GxtoreNb7qiaDdp1YMhPPtnmV+EKOKyPSlVc7fCt/glzqSX9atUBXa2A==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", @@ -3904,6 +3930,26 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } + }, + "miniflare": { + "version": "3.20240909.3", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", + "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + } } } }, From c7404138999f464b5ddf8f236f34abb7eb1f0575 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 01:17:48 +0000 Subject: [PATCH 51/77] chore(deps): update dependency @cloudflare/workers-types to v4.20240919.0 --- tailcall-cloudflare/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 21e228d0a0..5eb991ff50 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -120,9 +120,9 @@ } }, "node_modules/@cloudflare/workers-types": { - "version": "4.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240909.0.tgz", - "integrity": "sha512-4knwtX6efxIsIxawdmPyynU9+S8A78wntU8eUIEldStWP4gNgxGkeWcfCMXulTx8oxr3DU4aevHyld9HGV8VKQ==", + "version": "4.20240919.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240919.0.tgz", + "integrity": "sha512-DZwTpZVAV+fKTLxo6ntC2zMNRL/UJwvtMKUt/U7ZyJdR+t0qcBUZGx8jLi9gOFWYxkzO3s7slajwkR2hQRPXYQ==", "dev": true }, "node_modules/@cspotcode/source-map-support": { @@ -2539,9 +2539,9 @@ } }, "@cloudflare/workers-types": { - "version": "4.20240909.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240909.0.tgz", - "integrity": "sha512-4knwtX6efxIsIxawdmPyynU9+S8A78wntU8eUIEldStWP4gNgxGkeWcfCMXulTx8oxr3DU4aevHyld9HGV8VKQ==", + "version": "4.20240919.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240919.0.tgz", + "integrity": "sha512-DZwTpZVAV+fKTLxo6ntC2zMNRL/UJwvtMKUt/U7ZyJdR+t0qcBUZGx8jLi9gOFWYxkzO3s7slajwkR2hQRPXYQ==", "dev": true }, "@cspotcode/source-map-support": { From 090b8b078260ffc4067dc1837ca594662f453a3c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 05:06:04 +0000 Subject: [PATCH 52/77] chore(deps): update dependency wrangler to v3.78.6 --- tailcall-cloudflare/package-lock.json | 62 ++++----------------------- 1 file changed, 8 insertions(+), 54 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 5eb991ff50..0f6eb527a5 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1977,9 +1977,9 @@ } }, "node_modules/wrangler": { - "version": "3.78.5", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.5.tgz", - "integrity": "sha512-EqCQOuuxHCBHLSjWw7kWT/1PDSw38XUhSxPC3VnDcL7F6TukVBfHHyLFO4NYGTDDoH+G8KVK1bL1q8LXY2Rcbg==", + "version": "3.78.6", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.6.tgz", + "integrity": "sha512-1PaN9FB2D5sTlse15adhMIhm33rCJYCPxeN71h/6siW45F0QjDrv+BxInwy9LBg8gfEqm71eI1iIlTGyV3l+1A==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -1990,7 +1990,7 @@ "chokidar": "^3.5.3", "date-fns": "^3.6.0", "esbuild": "0.17.19", - "miniflare": "3.20240909.3", + "miniflare": "3.20240909.4", "nanoid": "^3.3.3", "path-to-regexp": "^6.3.0", "resolve": "^1.22.8", @@ -2409,32 +2409,6 @@ "@esbuild/win32-x64": "0.17.19" } }, - "node_modules/wrangler/node_modules/miniflare": { - "version": "3.20240909.3", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", - "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", - "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.4", - "workerd": "1.20240909.0", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3721,9 +3695,9 @@ } }, "wrangler": { - "version": "3.78.5", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.5.tgz", - "integrity": "sha512-EqCQOuuxHCBHLSjWw7kWT/1PDSw38XUhSxPC3VnDcL7F6TukVBfHHyLFO4NYGTDDoH+G8KVK1bL1q8LXY2Rcbg==", + "version": "3.78.6", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.6.tgz", + "integrity": "sha512-1PaN9FB2D5sTlse15adhMIhm33rCJYCPxeN71h/6siW45F0QjDrv+BxInwy9LBg8gfEqm71eI1iIlTGyV3l+1A==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -3735,7 +3709,7 @@ "date-fns": "^3.6.0", "esbuild": "0.17.19", "fsevents": "~2.3.2", - "miniflare": "3.20240909.3", + "miniflare": "3.20240909.4", "nanoid": "^3.3.3", "path-to-regexp": "^6.3.0", "resolve": "^1.22.8", @@ -3930,26 +3904,6 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } - }, - "miniflare": { - "version": "3.20240909.3", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.3.tgz", - "integrity": "sha512-HsWMexA4m0Ti8wTjqRdg50otufgoQ/I/rL3AHxf3dI/TN8zJC/5aMApqspW6I88Lzm24C+SRKnW0nm465PStIw==", - "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.4", - "workerd": "1.20240909.0", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - } } } }, From 7464f76c4b46cfb692c48e3aa678ac6de4afc808 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 21:04:05 +0000 Subject: [PATCH 53/77] fix(deps): update rust crate clap to v4.5.18 --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4ee7435baa..1c50ce1380 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -913,9 +913,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -923,9 +923,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -935,9 +935,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", From 38ae551cbdc42f63a0cbd0a86721f1861bbab7ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:57:10 +0000 Subject: [PATCH 54/77] chore(deps): update dependency wrangler to v3.78.7 --- tailcall-cloudflare/package-lock.json | 44 +++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index 0f6eb527a5..d8238d6c48 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1411,9 +1411,9 @@ } }, "node_modules/ohash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", - "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", + "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==", "dev": true }, "node_modules/path-parse": { @@ -1789,13 +1789,13 @@ }, "node_modules/unenv": { "name": "unenv-nightly", - "version": "2.0.0-1726478054.1e87097", - "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-1726478054.1e87097.tgz", - "integrity": "sha512-uZso8dCkGlJzWQqkyjOA5L4aUqNJl9E9oKRm03V/d+URrg6rFMJwBonlX9AAq538NxwJpPnCX0gAz0IfTxsbFQ==", + "version": "2.0.0-20240919-125358-9a64854", + "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20240919-125358-9a64854.tgz", + "integrity": "sha512-XjsgUTrTHR7iw+k/SRTNjh6EQgwpC9voygnoCJo5kh4hKqsSDHUW84MhL9EsHTNfLctvVBHaSw8e2k3R2fKXsQ==", "dev": true, "dependencies": { "defu": "^6.1.4", - "ohash": "^1.1.3", + "ohash": "^1.1.4", "pathe": "^1.1.2", "ufo": "^1.5.4" } @@ -1977,9 +1977,9 @@ } }, "node_modules/wrangler": { - "version": "3.78.6", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.6.tgz", - "integrity": "sha512-1PaN9FB2D5sTlse15adhMIhm33rCJYCPxeN71h/6siW45F0QjDrv+BxInwy9LBg8gfEqm71eI1iIlTGyV3l+1A==", + "version": "3.78.7", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.7.tgz", + "integrity": "sha512-z2ubdgQZ8lh2TEpvihFQOu3HmCNus78sC1LMBiSmgv133i4DeUMuz6SJglles2LayJAKrusjTqFnDYecA2XDDg==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -1997,7 +1997,7 @@ "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@2.0.0-1726478054.1e87097", + "unenv": "npm:unenv-nightly@2.0.0-20240919-125358-9a64854", "workerd": "1.20240909.0", "xxhash-wasm": "^1.0.1" }, @@ -3311,9 +3311,9 @@ "dev": true }, "ohash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", - "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", + "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==", "dev": true }, "path-parse": { @@ -3609,13 +3609,13 @@ "dev": true }, "unenv": { - "version": "npm:unenv-nightly@2.0.0-1726478054.1e87097", - "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-1726478054.1e87097.tgz", - "integrity": "sha512-uZso8dCkGlJzWQqkyjOA5L4aUqNJl9E9oKRm03V/d+URrg6rFMJwBonlX9AAq538NxwJpPnCX0gAz0IfTxsbFQ==", + "version": "npm:unenv-nightly@2.0.0-20240919-125358-9a64854", + "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20240919-125358-9a64854.tgz", + "integrity": "sha512-XjsgUTrTHR7iw+k/SRTNjh6EQgwpC9voygnoCJo5kh4hKqsSDHUW84MhL9EsHTNfLctvVBHaSw8e2k3R2fKXsQ==", "dev": true, "requires": { "defu": "^6.1.4", - "ohash": "^1.1.3", + "ohash": "^1.1.4", "pathe": "^1.1.2", "ufo": "^1.5.4" } @@ -3695,9 +3695,9 @@ } }, "wrangler": { - "version": "3.78.6", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.6.tgz", - "integrity": "sha512-1PaN9FB2D5sTlse15adhMIhm33rCJYCPxeN71h/6siW45F0QjDrv+BxInwy9LBg8gfEqm71eI1iIlTGyV3l+1A==", + "version": "3.78.7", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.78.7.tgz", + "integrity": "sha512-z2ubdgQZ8lh2TEpvihFQOu3HmCNus78sC1LMBiSmgv133i4DeUMuz6SJglles2LayJAKrusjTqFnDYecA2XDDg==", "dev": true, "requires": { "@cloudflare/kv-asset-handler": "0.3.4", @@ -3716,7 +3716,7 @@ "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@2.0.0-1726478054.1e87097", + "unenv": "npm:unenv-nightly@2.0.0-20240919-125358-9a64854", "workerd": "1.20240909.0", "xxhash-wasm": "^1.0.1" }, From 86b26b8328dcfbae836cdf24ad94b026aa7616ed Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 21 Sep 2024 16:25:34 +0530 Subject: [PATCH 55/77] fix: update collectors (#2879) Co-authored-by: Sahil Yeole Co-authored-by: Sahil Yeole <73148455+beelchester@users.noreply.github.com> --- .github/workflows/ci.yml | 1 + Cargo.lock | 1042 +++++++++-------- project-words.txt | 3 + src/cli/tc/run.rs | 5 +- tailcall-tracker/Cargo.toml | 10 +- .../src/{check_tracking.rs => can_track.rs} | 20 +- tailcall-tracker/src/collect/ga.rs | 66 ++ tailcall-tracker/src/collect/mod.rs | 11 + tailcall-tracker/src/collect/posthog.rs | 52 + tailcall-tracker/src/error.rs | 17 +- tailcall-tracker/src/event.rs | 66 +- tailcall-tracker/src/lib.rs | 6 +- tailcall-tracker/src/tracker.rs | 176 ++- 13 files changed, 883 insertions(+), 592 deletions(-) rename tailcall-tracker/src/{check_tracking.rs => can_track.rs} (57%) create mode 100644 tailcall-tracker/src/collect/ga.rs create mode 100644 tailcall-tracker/src/collect/mod.rs create mode 100644 tailcall-tracker/src/collect/posthog.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c0e004af5..d003e17244 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -243,6 +243,7 @@ jobs: GITHUB_TOKEN: ${{secrets.GITHUBTOKEN}} GA_API_SECRET: ${{secrets.GA_API_SECRET}} GA_MEASUREMENT_ID: ${{secrets.GA_MEASUREMENT_ID}} + POSTHOG_API_SECRET: ${{secrets.POSTHOG_API_SECRET}} APP_VERSION: ${{ needs.draft_release.outputs.create_release_name }} steps: diff --git a/Cargo.lock b/Cargo.lock index 1c50ce1380..df57ba56b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,19 +14,13 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.0" @@ -89,9 +83,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -110,27 +104,27 @@ checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -208,14 +202,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.1.0", - "futures-lite 2.3.0", + "fastrand", + "futures-lite", "slab", ] @@ -227,10 +221,10 @@ checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ "async-channel 2.3.1", "async-executor", - "async-io 2.3.3", - "async-lock 3.4.0", + "async-io", + "async-lock", "blocking", - "futures-lite 2.3.0", + "futures-lite", "once_cell", "tokio", ] @@ -282,7 +276,7 @@ dependencies = [ "Inflector", "async-graphql-parser", "darling 0.20.10", - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", "strum", @@ -307,7 +301,7 @@ dependencies = [ "futures-locks", "libflate", "prost-build", - "protobuf 3.4.0", + "protobuf 3.5.1", "protobuf-codegen", "protox 0.6.1", "reqwest 0.11.27", @@ -349,50 +343,21 @@ dependencies = [ [[package]] name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.27", - "slab", - "socket2 0.4.10", - "waker-fn", -] - -[[package]] -name = "async-io" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" dependencies = [ - "async-lock 3.4.0", + "async-lock", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.3.0", + "futures-lite", "parking", - "polling 3.7.2", - "rustix 0.38.34", + "polling", + "rustix", "slab", "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", + "windows-sys 0.59.0", ] [[package]] @@ -408,28 +373,30 @@ dependencies = [ [[package]] name = "async-object-pool" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb901c30ebc2fc4ab46395bbfbdba9542c16559d853645d75190c3056caf3bc" +checksum = "333c456b97c3f2d50604e8b2624253b7f787208cb72eb75e64b0ad11b221652c" dependencies = [ "async-std", ] [[package]] name = "async-process" -version = "1.8.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-channel 2.3.1", + "async-io", + "async-lock", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.34", - "windows-sys 0.48.0", + "event-listener 5.3.1", + "futures-lite", + "rustix", + "tracing", ] [[package]] @@ -445,40 +412,40 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io 2.3.3", - "async-lock 3.4.0", + "async-io", + "async-lock", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.34", + "rustix", "signal-hook-registry", "slab", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "async-std" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" dependencies = [ "async-attributes", "async-channel 1.9.0", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", - "gloo-timers", + "futures-lite", + "gloo-timers 0.3.0", "kv-log-macro", "log", "memchr", @@ -549,7 +516,7 @@ dependencies = [ "base64 0.22.1", "bytes", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-serde 2.1.1", "query_map", "serde", @@ -603,17 +570,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", - "miniz_oxide 0.7.4", + "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -690,9 +657,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -721,7 +688,7 @@ dependencies = [ "async-channel 2.3.1", "async-task", "futures-io", - "futures-lite 2.3.0", + "futures-lite", "piper", ] @@ -760,9 +727,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" dependencies = [ "serde", ] @@ -840,9 +807,12 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.99" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -947,15 +917,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "colored" @@ -1025,9 +995,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core2" @@ -1040,9 +1010,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -1458,9 +1428,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "ena" @@ -1488,18 +1458,18 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", ] [[package]] name = "env_logger" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -1535,17 +1505,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - [[package]] name = "event-listener" version = "5.3.1" @@ -1616,18 +1575,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fixedbitset" @@ -1642,7 +1592,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", - "miniz_oxide 0.8.0", + "miniz_oxide", ] [[package]] @@ -1651,6 +1601,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1708,28 +1673,13 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-lite" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.1.0", + "fastrand", "futures-core", "futures-io", "parking", @@ -1776,7 +1726,7 @@ version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ - "gloo-timers", + "gloo-timers 0.2.6", "send_wrapper", ] @@ -1825,7 +1775,7 @@ dependencies = [ "derive_more 1.0.0", "eventsource-stream", "futures", - "reqwest 0.12.5", + "reqwest 0.12.7", "reqwest-eventsource", "serde", "serde_json", @@ -1858,9 +1808,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -1882,7 +1832,7 @@ dependencies = [ "gloo-net", "gloo-render", "gloo-storage", - "gloo-timers", + "gloo-timers 0.2.6", "gloo-utils", "gloo-worker", ] @@ -2006,6 +1956,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "gloo-utils" version = "0.1.7" @@ -2218,9 +2180,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http 1.1.0", @@ -2235,7 +2197,7 @@ dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -2364,7 +2326,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", @@ -2373,15 +2335,15 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "httparse", "itoa", "pin-project-lite", @@ -2423,20 +2385,20 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.4.0", + "hyper 1.4.1", "hyper-util", "rustls 0.23.13", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots 0.26.3", + "webpki-roots 0.26.6", ] [[package]] @@ -2451,6 +2413,19 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.30", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "hyper-util" version = "0.1.8" @@ -2461,10 +2436,10 @@ dependencies = [ "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", - "hyper 1.4.0", + "http-body 1.0.1", + "hyper 1.4.1", "pin-project-lite", - "socket2 0.5.7", + "socket2", "tokio", "tower", "tower-service", @@ -2473,9 +2448,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2552,7 +2527,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm", "dyn-clone", "fuzzy-matcher", @@ -2576,48 +2551,28 @@ dependencies = [ "similar", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi 0.4.0", "libc", "windows-sys 0.52.0", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -2637,6 +2592,24 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -2720,9 +2693,9 @@ dependencies = [ "futures", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", - "hyper 1.4.0", + "hyper 1.4.1", "lambda_runtime", "mime", "percent-encoding", @@ -2745,10 +2718,10 @@ dependencies = [ "bytes", "futures", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", "http-serde 2.1.1", - "hyper 1.4.0", + "hyper 1.4.1", "hyper-util", "lambda_runtime_api_client", "pin-project", @@ -2772,9 +2745,9 @@ dependencies = [ "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", - "hyper 1.4.0", + "hyper 1.4.1", "hyper-util", "tokio", "tower", @@ -2797,9 +2770,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libflate" @@ -2851,7 +2824,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -2873,12 +2846,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -2897,27 +2864,27 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" dependencies = [ "value-bag", ] [[package]] name = "logos" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e31badd9de5131fdf4921f6473d457e3dd85b11b7f091ceb50e4df7c3eeb12a" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" dependencies = [ "beef", "fnv", @@ -2930,9 +2897,9 @@ dependencies = [ [[package]] name = "logos-derive" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" dependencies = [ "logos-codegen", ] @@ -3104,9 +3071,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -3128,15 +3095,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -3160,9 +3118,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi 0.3.9", "libc", @@ -3176,7 +3134,7 @@ version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" dependencies = [ - "async-lock 3.4.0", + "async-lock", "async-trait", "crossbeam-channel", "crossbeam-epoch", @@ -3217,6 +3175,23 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3277,9 +3252,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -3375,9 +3350,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.0" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -3396,9 +3371,9 @@ checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "opaque-debug" @@ -3406,12 +3381,60 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "300.3.2+3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + [[package]] name = "opentelemetry" version = "0.23.0" @@ -3511,7 +3534,7 @@ dependencies = [ "futures-util", "opentelemetry", "opentelemetry_sdk", - "ordered-float 4.2.0", + "ordered-float 4.2.2", "serde", "serde_json", "thiserror", @@ -3546,7 +3569,7 @@ dependencies = [ "lazy_static", "once_cell", "opentelemetry", - "ordered-float 4.2.0", + "ordered-float 4.2.2", "percent-encoding", "rand", "serde_json", @@ -3572,9 +3595,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "4.2.0" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +checksum = "4a91171844676f8c7990ce64959210cd2eaef32c2612c50f9fae9f8aaa6065a6" dependencies = [ "num-traits", ] @@ -3587,9 +3610,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -3609,7 +3632,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.2", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -3644,9 +3667,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.11" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", "thiserror", @@ -3655,9 +3678,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.10" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" dependencies = [ "pest", "pest_generator", @@ -3665,9 +3688,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.10" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" dependencies = [ "pest", "pest_meta", @@ -3678,9 +3701,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.10" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" dependencies = [ "once_cell", "pest", @@ -3715,7 +3738,7 @@ dependencies = [ "bincode", "either", "fnv", - "itertools 0.10.5", + "itertools 0.12.1", "lazy_static", "nom", "quick-xml", @@ -3767,20 +3790,26 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.1.0", + "fastrand", "futures-io", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -3791,15 +3820,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -3816,33 +3845,29 @@ dependencies = [ [[package]] name = "polling" -version = "2.8.0" +version = "3.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" dependencies = [ - "autocfg", - "bitflags 1.3.2", "cfg-if", "concurrent-queue", - "libc", - "log", + "hermit-abi 0.4.0", "pin-project-lite", - "windows-sys 0.48.0", + "rustix", + "tracing", + "windows-sys 0.59.0", ] [[package]] -name = "polling" -version = "3.7.2" +name = "posthog-rs" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +checksum = "8ad1b35ffe50419992615288c40ee90fbf30da4c6faf251414675ea64e1cdfa3" dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi 0.4.0", - "pin-project-lite", - "rustix 0.38.34", - "tracing", - "windows-sys 0.52.0", + "chrono", + "reqwest 0.11.27", + "serde", + "serde_json", ] [[package]] @@ -3853,9 +3878,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "precomputed-hash" @@ -3875,9 +3903,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", "syn 2.0.77", @@ -3895,11 +3923,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit 0.22.21", ] [[package]] @@ -3978,7 +4006,7 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck", - "itertools 0.10.5", + "itertools 0.12.1", "log", "multimap", "once_cell", @@ -3998,7 +4026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.12.1", "proc-macro2", "quote", "syn 2.0.77", @@ -4011,7 +4039,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.13.0", "proc-macro2", "quote", "syn 2.0.77", @@ -4041,7 +4069,7 @@ dependencies = [ "miette 7.2.0", "once_cell", "prost 0.13.2", - "prost-types 0.13.1", + "prost-types 0.13.2", "serde", "serde-value", ] @@ -4057,9 +4085,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2" +checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" dependencies = [ "prost 0.13.2", ] @@ -4072,9 +4100,9 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" [[package]] name = "protobuf" -version = "3.4.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58678a64de2fced2bdec6bca052a6716a0efe692d6e3f53d1bda6a1def64cfc0" +checksum = "0bcc343da15609eaecd65f8aa76df8dc4209d325131d8219358c0aaaebab0bf6" dependencies = [ "once_cell", "protobuf-support", @@ -4083,13 +4111,13 @@ dependencies = [ [[package]] name = "protobuf-codegen" -version = "3.4.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32777b0b3f6538d9d2e012b3fad85c7e4b9244b5958d04a6415f4333782b7a77" +checksum = "c4d0cde5642ea4df842b13eb9f59ea6fafa26dcb43e3e1ee49120e9757556189" dependencies = [ "anyhow", "once_cell", - "protobuf 3.4.0", + "protobuf 3.5.1", "protobuf-parse", "regex", "tempfile", @@ -4098,14 +4126,14 @@ dependencies = [ [[package]] name = "protobuf-parse" -version = "3.4.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96cb37955261126624a25b5e6bda40ae34cf3989d52a783087ca6091b29b5642" +checksum = "1b0e9b447d099ae2c4993c0cbb03c7a9d6c937b17f2d56cfc0b1550e6fcfdb76" dependencies = [ "anyhow", - "indexmap 1.9.3", + "indexmap 2.5.0", "log", - "protobuf 3.4.0", + "protobuf 3.5.1", "protobuf-support", "tempfile", "thiserror", @@ -4114,9 +4142,9 @@ dependencies = [ [[package]] name = "protobuf-support" -version = "3.4.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1ed294a835b0f30810e13616b1cd34943c6d1e84a8f3b0dcfe466d256c3e7e7" +checksum = "f0766e3675a627c327e4b3964582594b0e8741305d628a98a5de75a1d15f99b9" dependencies = [ "thiserror", ] @@ -4196,7 +4224,7 @@ dependencies = [ "miette 7.2.0", "prost 0.13.2", "prost-reflect 0.14.2", - "prost-types 0.13.1", + "prost-types 0.13.2", "protox-parse 0.7.0", "thiserror", ] @@ -4221,7 +4249,7 @@ checksum = "a3a462d115462c080ae000c29a47f0b3985737e5d3a995fcdbcaa5c782068dde" dependencies = [ "logos", "miette 7.2.0", - "prost-types 0.13.1", + "prost-types 0.13.2", "thiserror", ] @@ -4277,9 +4305,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ "bytes", "pin-project-lite", @@ -4287,7 +4315,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls 0.23.13", - "socket2 0.5.7", + "socket2", "thiserror", "tokio", "tracing", @@ -4295,9 +4323,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ "bytes", "rand", @@ -4312,15 +4340,15 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" dependencies = [ "libc", "once_cell", - "socket2 0.5.7", + "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4364,11 +4392,11 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.0.2" +version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" +checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -4393,27 +4421,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -4422,13 +4441,13 @@ dependencies = [ [[package]] name = "reflink-copy" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d731e7e3ebfcf422d96b8473e507d5b64790900dd5464772d38d1da9da24d3a" +checksum = "dc31414597d1cd7fdd2422798b7652a6329dda0fe0219e6335a13d5bcaa9aeb6" dependencies = [ "cfg-if", - "rustix 0.38.34", - "windows 0.57.0", + "rustix", + "windows 0.58.0", ] [[package]] @@ -4509,11 +4528,13 @@ dependencies = [ "http-body 0.4.6", "hyper 0.14.30", "hyper-rustls 0.24.2", + "hyper-tls", "ipnet", "js-sys", "log", "mime", "mime_guess", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -4525,6 +4546,7 @@ dependencies = [ "sync_wrapper 0.1.2", "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls 0.24.1", "tower-service", "url", @@ -4537,19 +4559,19 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.1", "bytes", "futures-core", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", - "hyper 1.4.0", - "hyper-rustls 0.27.2", + "hyper 1.4.1", + "hyper-rustls 0.27.3", "hyper-util", "ipnet", "js-sys", @@ -4560,7 +4582,7 @@ dependencies = [ "pin-project-lite", "quinn", "rustls 0.23.13", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "rustls-pki-types", "serde", "serde_json", @@ -4575,8 +4597,8 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.3", - "winreg 0.52.0", + "webpki-roots 0.26.6", + "windows-registry", ] [[package]] @@ -4591,7 +4613,7 @@ dependencies = [ "mime", "nom", "pin-project-lite", - "reqwest 0.12.5", + "reqwest 0.12.7", "thiserror", ] @@ -4698,37 +4720,23 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.37.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.14", + "linux-raw-sys", "windows-sys 0.52.0", ] @@ -4774,12 +4782,12 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "rustls-pki-types", "schannel", "security-framework", @@ -4796,9 +4804,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64 0.22.1", "rustls-pki-types", @@ -4854,11 +4862,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4909,11 +4917,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -4922,9 +4930,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -5161,6 +5169,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.17" @@ -5173,9 +5187,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio 0.8.11", @@ -5193,9 +5207,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "simple_asn1" @@ -5230,16 +5244,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.7" @@ -5340,9 +5344,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0208408ba0c3df17ed26eb06992cb1a1268d41b2c0e12e65203fbe3972cee5" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -5377,6 +5381,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "sysinfo" @@ -5648,17 +5655,23 @@ dependencies = [ name = "tailcall-tracker" version = "0.1.0" dependencies = [ + "async-trait", + "chrono", "derive_more 0.99.18", "lazy_static", "machineid-rs", + "openssl", + "posthog-rs", "reqwest 0.11.27", "serde", "serde_json", + "strum", "sysinfo 0.31.4", "tailcall-version", "tokio", "tracing", "url", + "whoami", ] [[package]] @@ -5759,9 +5772,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand 2.1.0", + "fastrand", "once_cell", - "rustix 0.38.34", + "rustix", "windows-sys 0.59.0", ] @@ -5898,9 +5911,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -5920,11 +5933,11 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.1", + "mio 1.0.2", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2", "tokio-macros", "windows-sys 0.52.0", ] @@ -5950,6 +5963,16 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -5984,9 +6007,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -6008,9 +6031,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -6021,9 +6044,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" @@ -6033,18 +6056,18 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.5.0", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap 2.5.0", "toml_datetime", - "winnow", + "winnow 0.6.18", ] [[package]] @@ -6067,7 +6090,7 @@ dependencies = [ "pin-project", "prost 0.12.6", "rustls-native-certs", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", @@ -6080,14 +6103,14 @@ dependencies = [ [[package]] name = "tonic" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38659f4a91aba8598d27821589f5db7dddd94601e7a01b1e485a50e5484c7401" +checksum = "c6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88ad" dependencies = [ "base64 0.22.1", "bytes", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", "percent-encoding", "pin-project", @@ -6157,13 +6180,13 @@ dependencies = [ [[package]] name = "tonic-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5563899ec5aa5f0ec48e37457461ffbbc184c9a0f413f715dacd154f46408a10" +checksum = "9d967793411bc1a5392accf4731114295f0fd122865d22cde46a8584b03402b2" dependencies = [ "prost 0.13.2", - "prost-types 0.13.1", - "tonic 0.12.1", + "prost-types 0.13.2", + "tonic 0.12.2", ] [[package]] @@ -6188,15 +6211,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -6361,42 +6384,42 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-id" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" +checksum = "10103c57044730945224467c09f71a4db0071c123a0648cc3e818913bde6b561" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unsafe-libyaml" @@ -6443,9 +6466,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", "wasm-bindgen", @@ -6464,16 +6487,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" [[package]] -name = "version_check" -version = "0.9.4" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] -name = "waker-fn" -version = "1.2.0" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" @@ -6640,9 +6663,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.3" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] @@ -6656,7 +6679,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.34", + "rustix", ] [[package]] @@ -6667,17 +6690,17 @@ checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" dependencies = [ "either", "home", - "rustix 0.38.34", + "rustix", "winsafe", ] [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall", "wasite", "web-sys", ] @@ -6700,11 +6723,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6734,6 +6757,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -6751,7 +6784,20 @@ checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ "windows-implement 0.57.0", "windows-interface 0.57.0", - "windows-result", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings", "windows-targets 0.52.6", ] @@ -6777,6 +6823,17 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "windows-interface" version = "0.48.0" @@ -6799,6 +6856,28 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result 0.2.0", + "windows-strings", + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -6808,6 +6887,25 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -6966,30 +7064,29 @@ dependencies = [ ] [[package]] -name = "winreg" -version = "0.11.0" +name = "winnow" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a1a57ff50e9b408431e8f97d5456f2807f8eb2a2cd79b06068fc87f8ecf189" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ - "cfg-if", - "winapi", + "memchr", ] [[package]] name = "winreg" -version = "0.50.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "76a1a57ff50e9b408431e8f97d5456f2807f8eb2a2cd79b06068fc87f8ecf189" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "winapi", ] [[package]] name = "winreg" -version = "0.52.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", "windows-sys 0.48.0", @@ -7027,7 +7124,7 @@ dependencies = [ "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "js-sys", "matchit", "pin-project", @@ -7103,9 +7200,9 @@ dependencies = [ [[package]] name = "xxhash-rust" -version = "0.8.10" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" +checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" [[package]] name = "yansi" @@ -7115,18 +7212,19 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/project-words.txt b/project-words.txt index 3a1eddbbb3..6cab4c7ffa 100644 --- a/project-words.txt +++ b/project-words.txt @@ -10,12 +10,15 @@ inlines insta jsonplaceholder Jwks +machineid maplit mdast multispace opentelemetry peekable +posthog schemars +sysinfo tailcall tailcallrc thiserror diff --git a/src/cli/tc/run.rs b/src/cli/tc/run.rs index c180142dfc..78c843addd 100644 --- a/src/cli/tc/run.rs +++ b/src/cli/tc/run.rs @@ -1,6 +1,5 @@ use anyhow::Result; use clap::Parser; -use convert_case::{Case, Casing}; use dotenvy::dotenv; use super::helpers::TRACKER; @@ -26,9 +25,7 @@ pub async fn run() -> Result<()> { .await; // Dispatch the command as an event - let _ = TRACKER - .dispatch(cli.command.to_string().to_case(Case::Snake).as_str()) - .await; + let _ = TRACKER.dispatch(tailcall_tracker::EventKind::Run).await; run_command(cli, config_reader, runtime).await } diff --git a/tailcall-tracker/Cargo.toml b/tailcall-tracker/Cargo.toml index ce138b81e1..b35743eb6b 100644 --- a/tailcall-tracker/Cargo.toml +++ b/tailcall-tracker/Cargo.toml @@ -9,11 +9,17 @@ edition = "2021" reqwest = { workspace = true } derive_more = { workspace = true } url = { workspace = true } -lazy_static = { workspace = true } +lazy_static.workspace = true serde = { workspace = true } serde_json = { workspace = true } machineid-rs = "1.2.4" -tokio = { workspace = true } +tokio = { workspace = true, features = ["rt", "macros"] } tracing = { workspace = true } sysinfo = "0.31.0" tailcall-version = { path = "../tailcall-version" } +posthog-rs = "0.2.2" +async-trait = "0.1.81" +chrono = "0.4.38" +openssl = { version = "0.10", features = ["vendored"] } +whoami = "1.5.2" +strum = "0.26.3" diff --git a/tailcall-tracker/src/check_tracking.rs b/tailcall-tracker/src/can_track.rs similarity index 57% rename from tailcall-tracker/src/check_tracking.rs rename to tailcall-tracker/src/can_track.rs index 0698ae4b38..4c6b951768 100644 --- a/tailcall-tracker/src/check_tracking.rs +++ b/tailcall-tracker/src/can_track.rs @@ -6,17 +6,17 @@ const LONG_ENV_FILTER_VAR_NAME: &str = "TAILCALL_TRACKER"; const SHORT_ENV_FILTER_VAR_NAME: &str = "TC_TRACKER"; /// Checks if tracking is enabled -pub fn check_tracking() -> bool { +pub fn can_track() -> bool { let is_prod = !VERSION.is_dev(); let usage_enabled = env::var(LONG_ENV_FILTER_VAR_NAME) .or(env::var(SHORT_ENV_FILTER_VAR_NAME)) .map(|v| !v.eq_ignore_ascii_case("false")) .ok(); - check_tracking_inner(is_prod, usage_enabled) + can_track_inner(is_prod, usage_enabled) } -fn check_tracking_inner(is_prod_build: bool, tracking_enabled: Option) -> bool { - if let Some(usage_enabled) = tracking_enabled { +fn can_track_inner(is_prod_build: bool, usage_enabled: Option) -> bool { + if let Some(usage_enabled) = usage_enabled { usage_enabled } else { is_prod_build @@ -28,23 +28,23 @@ mod tests { use super::*; #[test] fn usage_enabled_true() { - assert!(check_tracking_inner(true, Some(true))); - assert!(check_tracking_inner(false, Some(true))); + assert!(can_track_inner(true, Some(true))); + assert!(can_track_inner(false, Some(true))); } #[test] fn usage_enabled_false() { - assert!(!check_tracking_inner(true, Some(false))); - assert!(!check_tracking_inner(false, Some(false))); + assert!(!can_track_inner(true, Some(false))); + assert!(!can_track_inner(false, Some(false))); } #[test] fn usage_enabled_none_is_prod_true() { - assert!(check_tracking_inner(true, None)); + assert!(can_track_inner(true, None)); } #[test] fn usage_enabled_none_is_prod_false() { - assert!(!check_tracking_inner(false, None)); + assert!(!can_track_inner(false, None)); } } diff --git a/tailcall-tracker/src/collect/ga.rs b/tailcall-tracker/src/collect/ga.rs new file mode 100644 index 0000000000..917cb987d7 --- /dev/null +++ b/tailcall-tracker/src/collect/ga.rs @@ -0,0 +1,66 @@ +use reqwest::header::{HeaderName, HeaderValue}; +use serde::{Deserialize, Serialize}; + +use super::super::Result; +use super::Collect; +use crate::Event; + +const GA_TRACKER_URL: &str = "https://www.google-analytics.com"; + +/// Event structure to be sent to GA +#[derive(Debug, Serialize, Deserialize)] +struct GaEvent { + client_id: String, + events: Vec, +} + +impl GaEvent { + pub fn new(event: Event) -> Self { + Self { client_id: event.clone().client_id, events: vec![event] } + } +} + +pub struct Tracker { + base_url: String, + api_secret: String, + measurement_id: String, +} + +impl Tracker { + pub fn new(api_secret: String, measurement_id: String) -> Self { + Self { + base_url: GA_TRACKER_URL.to_string(), + api_secret, + measurement_id, + } + } + fn create_request(&self, event: Event) -> Result { + let event = GaEvent::new(event); + let mut url = reqwest::Url::parse(self.base_url.as_str())?; + url.set_path("/mp/collect"); + url.query_pairs_mut() + .append_pair("api_secret", self.api_secret.as_str()) + .append_pair("measurement_id", self.measurement_id.as_str()); + let mut request = reqwest::Request::new(reqwest::Method::POST, url); + let header_name = HeaderName::from_static("content-type"); + let header_value = HeaderValue::from_str("application/json")?; + request.headers_mut().insert(header_name, header_value); + + let _ = request + .body_mut() + .insert(reqwest::Body::from(serde_json::to_string(&event)?)); + + Ok(request) + } +} + +#[async_trait::async_trait] +impl Collect for Tracker { + async fn collect(&self, event: Event) -> Result<()> { + let request = self.create_request(event)?; + let client = reqwest::Client::new(); + client.execute(request).await?; + + Ok(()) + } +} diff --git a/tailcall-tracker/src/collect/mod.rs b/tailcall-tracker/src/collect/mod.rs new file mode 100644 index 0000000000..fda19f8c2f --- /dev/null +++ b/tailcall-tracker/src/collect/mod.rs @@ -0,0 +1,11 @@ +use crate::Event; + +pub mod ga; +pub mod posthog; + +/// +/// Defines the interface for an event collector. +#[async_trait::async_trait] +pub trait Collect: Send + Sync { + async fn collect(&self, event: Event) -> super::Result<()>; +} diff --git a/tailcall-tracker/src/collect/posthog.rs b/tailcall-tracker/src/collect/posthog.rs new file mode 100644 index 0000000000..595832d224 --- /dev/null +++ b/tailcall-tracker/src/collect/posthog.rs @@ -0,0 +1,52 @@ +use serde::de::Error; + +use super::super::Result; +use super::Collect; +use crate::Event; + +pub struct Tracker { + api_secret: &'static str, + client_id_key: &'static str, +} + +impl Tracker { + pub fn new(api_secret: &'static str, client_id_key: &'static str) -> Self { + Self { api_secret, client_id_key } + } +} + +#[async_trait::async_trait] +impl Collect for Tracker { + async fn collect(&self, event: Event) -> Result<()> { + let api_secret = self.api_secret; + let client_id_key = self.client_id_key; + let handle_posthog = tokio::task::spawn_blocking(move || -> Result<()> { + let client = posthog_rs::client(api_secret); + let json = serde_json::to_value(&event)?; + let mut posthog_event = + posthog_rs::Event::new(event.event_name.clone(), event.client_id); + + match json { + serde_json::Value::Object(map) => { + for (mut key, value) in map { + if key == client_id_key { + key = "distinct_id".to_string(); + } + posthog_event.insert_prop(key, value)?; + } + } + _ => { + return Err( + serde_json::Error::custom("Failed to serialize event for posthog").into(), + ); + } + } + + client.capture(posthog_event)?; + Ok(()) + }) + .await; + handle_posthog??; + Ok(()) + } +} diff --git a/tailcall-tracker/src/error.rs b/tailcall-tracker/src/error.rs index d36a66d733..e9ba5f8e74 100644 --- a/tailcall-tracker/src/error.rs +++ b/tailcall-tracker/src/error.rs @@ -1,5 +1,3 @@ -use std::fmt::Display; - use derive_more::{DebugCustom, From}; use reqwest::header::InvalidHeaderValue; @@ -16,17 +14,12 @@ pub enum Error { #[debug(fmt = "Url Parser Error: {}", _0)] UrlParser(url::ParseError), -} -impl Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Error::Reqwest(error) => write!(f, "Reqwest Error: {}", error), - Error::InvalidHeaderValue(error) => write!(f, "Invalid Header Value: {}", error), - Error::SerdeJson(error) => write!(f, "Serde JSON Error: {}", error), - Error::UrlParser(error) => write!(f, "Url Parser Error: {}", error), - } - } + #[debug(fmt = "PostHog Error: {}", _0)] + PostHog(posthog_rs::Error), + + #[debug(fmt = "Tokio Join Error: {}", _0)] + TokioJoin(tokio::task::JoinError), } pub type Result = std::result::Result; diff --git a/tailcall-tracker/src/event.rs b/tailcall-tracker/src/event.rs index 0ae3dd9d59..c858a55d03 100644 --- a/tailcall-tracker/src/event.rs +++ b/tailcall-tracker/src/event.rs @@ -1,52 +1,30 @@ -use machineid_rs::{Encryption, HWIDComponent, IdBuilder}; +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use sysinfo::System; +use strum::IntoStaticStr; -const PARAPHRASE: &str = "tc_key"; -const DEFAULT_CLIENT_ID: &str = ""; - -#[derive(Debug, Serialize, Deserialize)] -struct Params { - cpu_cores: String, - os_name: String, -} - -#[derive(Debug, Serialize, Deserialize)] -struct EventValue { - name: String, - params: Params, -} - -impl EventValue { - fn new(name: &str) -> EventValue { - let sys = System::new_all(); - let cores = sys.physical_core_count().unwrap_or(2).to_string(); - let os_name = System::long_os_version().unwrap_or("Unknown".to_string()); - EventValue { - name: name.to_string(), - params: Params { cpu_cores: cores, os_name }, - } - } -} - -/// Event structure to be sent to GA -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Event { - client_id: String, - events: Vec, + pub event_name: String, + pub start_time: DateTime, + pub cores: usize, + pub client_id: String, + pub os_name: String, + pub up_time: Option, + pub path: Option, + pub cwd: Option, + pub user: String, + pub args: Vec, + pub version: String, } -impl Event { - pub fn new(name: &str) -> Self { - let mut builder = IdBuilder::new(Encryption::SHA256); - builder - .add_component(HWIDComponent::SystemID) - .add_component(HWIDComponent::CPUCores); - - let id = builder - .build(PARAPHRASE) - .unwrap_or(DEFAULT_CLIENT_ID.to_string()); +#[derive(Clone, IntoStaticStr)] +pub enum EventKind { + Ping, + Run, +} - Self { client_id: id, events: vec![EventValue::new(name)] } +impl EventKind { + pub fn as_str(&self) -> &'static str { + self.into() } } diff --git a/tailcall-tracker/src/lib.rs b/tailcall-tracker/src/lib.rs index c39cd081cd..063099044f 100644 --- a/tailcall-tracker/src/lib.rs +++ b/tailcall-tracker/src/lib.rs @@ -1,6 +1,8 @@ -mod check_tracking; +mod can_track; +mod collect; mod error; mod event; mod tracker; -pub use error::{Error, Result}; +use error::Result; +pub use event::{Event, EventKind}; pub use tracker::Tracker; diff --git a/tailcall-tracker/src/tracker.rs b/tailcall-tracker/src/tracker.rs index d30ad0180f..878a3c5ba9 100644 --- a/tailcall-tracker/src/tracker.rs +++ b/tailcall-tracker/src/tracker.rs @@ -1,85 +1,169 @@ -use reqwest::header::{HeaderName, HeaderValue}; +use chrono::{DateTime, Utc}; +use machineid_rs::{Encryption, HWIDComponent, IdBuilder}; +use sysinfo::System; +use tokio::time::Duration; use super::Result; -use crate::check_tracking::check_tracking; -use crate::event::Event; +use crate::can_track::can_track; +use crate::collect::{ga, posthog, Collect}; +use crate::{Event, EventKind}; -const API_SECRET: &str = match option_env!("GA_API_SECRET") { +const GA_API_SECRET: &str = match option_env!("GA_API_SECRET") { Some(val) => val, None => "dev", }; - -const MEASUREMENT_ID: &str = match option_env!("GA_MEASUREMENT_ID") { +const GA_MEASUREMENT_ID: &str = match option_env!("GA_MEASUREMENT_ID") { Some(val) => val, None => "dev", }; +const POSTHOG_API_SECRET: &str = match option_env!("POSTHOG_API_SECRET") { + Some(val) => val, + None => "dev", +}; + +const PARAPHRASE: &str = "tc_key"; -const BASE_URL: &str = "https://www.google-analytics.com"; +const DEFAULT_CLIENT_ID: &str = ""; -/// -/// Base structure to track usage of the CLI application -#[derive(Debug, Clone)] pub struct Tracker { - base_url: String, - api_secret: String, - measurement_id: String, + collectors: Vec>, is_tracking: bool, + start_time: DateTime, } impl Default for Tracker { fn default() -> Self { + let ga_tracker = Box::new(ga::Tracker::new( + GA_API_SECRET.to_string(), + GA_MEASUREMENT_ID.to_string(), + )); + let posthog_tracker = Box::new(posthog::Tracker::new(POSTHOG_API_SECRET, "client_id")); + let start_time = Utc::now(); Self { - base_url: BASE_URL.to_string(), - api_secret: API_SECRET.to_string(), - measurement_id: MEASUREMENT_ID.to_string(), - is_tracking: check_tracking(), + collectors: vec![ga_tracker, posthog_tracker], + is_tracking: can_track(), + start_time, } } } impl Tracker { - /// Initializes the ping event to be sent after the provided duration - pub async fn init_ping(&'static self, duration: tokio::time::Duration) { + pub async fn init_ping(&'static self, duration: Duration) { if self.is_tracking { let mut interval = tokio::time::interval(duration); tokio::task::spawn(async move { loop { interval.tick().await; - let _ = self.dispatch("ping").await; + let _ = self.dispatch(EventKind::Ping).await; } }); } } - fn create_request(&self, event_name: &str) -> Result { - let event = Event::new(event_name); - tracing::debug!("Sending event: {:?}", event); - let mut url = reqwest::Url::parse(self.base_url.as_str())?; - url.set_path("/mp/collect"); - url.query_pairs_mut() - .append_pair("api_secret", self.api_secret.as_str()) - .append_pair("measurement_id", self.measurement_id.as_str()); - let mut request = reqwest::Request::new(reqwest::Method::POST, url); - let header_name = HeaderName::from_static("content-type"); - let header_value = HeaderValue::from_str("application/json")?; - request.headers_mut().insert(header_name, header_value); - - let _ = request - .body_mut() - .insert(reqwest::Body::from(serde_json::to_string(&event)?)); - Ok(request) - } - - pub async fn dispatch(&'static self, name: &str) -> Result<()> { + pub async fn dispatch(&'static self, event_kind: EventKind) -> Result<()> { if self.is_tracking { - let request = self.create_request(name)?; - let client = reqwest::Client::new(); - let response = client.execute(request).await?; - let status = response.status(); - let text = response.text().await?; - tracing::debug!("Tracker: {}, message: {:?}", status.as_str(), text); + // Create a new event + let event = Event { + event_name: event_kind.as_str().to_string(), + start_time: self.start_time, + cores: cores(), + client_id: client_id(), + os_name: os_name(), + up_time: self.up_time(event_kind), + args: args(), + path: path(), + cwd: cwd(), + user: user(), + version: version(), + }; + + // Dispatch the event to all collectors + for collector in &self.collectors { + collector.collect(event.clone()).await?; + } + + tracing::debug!("Event dispatched: {:?}", event); } Ok(()) } + + fn up_time(&self, event_kind: EventKind) -> Option { + match event_kind { + EventKind::Ping => Some(get_uptime(self.start_time)), + _ => None, + } + } +} + +// Generates a random client ID +fn client_id() -> String { + let mut builder = IdBuilder::new(Encryption::SHA256); + builder + .add_component(HWIDComponent::SystemID) + .add_component(HWIDComponent::CPUCores); + builder + .build(PARAPHRASE) + .unwrap_or(DEFAULT_CLIENT_ID.to_string()) +} + +// Get the number of CPU cores +fn cores() -> usize { + let sys = System::new_all(); + sys.physical_core_count().unwrap_or(0) +} + +// Get the uptime in minutes +fn get_uptime(start_time: DateTime) -> String { + let current_time = Utc::now(); + format!( + "{} minutes", + current_time.signed_duration_since(start_time).num_minutes() + ) +} + +fn version() -> String { + tailcall_version::VERSION.as_str().to_string() +} + +fn user() -> String { + whoami::username() +} + +fn cwd() -> Option { + std::env::current_dir() + .ok() + .and_then(|path| path.to_str().map(|s| s.to_string())) +} + +fn path() -> Option { + std::env::current_exe() + .ok() + .and_then(|path| path.to_str().map(|s| s.to_string())) +} + +fn args() -> Vec { + std::env::args().skip(1).collect() +} + +fn os_name() -> String { + System::long_os_version().unwrap_or("Unknown".to_string()) +} + +#[cfg(test)] +mod tests { + use lazy_static::lazy_static; + + use super::*; + + lazy_static! { + static ref TRACKER: Tracker = Tracker::default(); + } + + #[tokio::test] + async fn test_tracker() { + if let Err(e) = TRACKER.dispatch(EventKind::Run).await { + panic!("Tracker dispatch error: {:?}", e); + } + } } From b6ce0cfe0af26fad08f3e4ae11560619d1722a23 Mon Sep 17 00:00:00 2001 From: laststylebender <43403528+laststylebender14@users.noreply.github.com> Date: Sat, 21 Sep 2024 17:00:05 +0530 Subject: [PATCH 56/77] fix: added type rename support for enum, union and interface. (#2793) --- .../config/transformer/improve_type_names.rs | 35 +----- src/core/config/transformer/rename_types.rs | 117 ++++++++++++++++-- ..._rename_types__test__inferface_rename.snap | 20 +++ ...rmer__rename_types__test__rename_type.snap | 8 ++ ...test__should_generate_combined_config.snap | 10 +- ...nerator__gen_json_proto_mix_config.md.snap | 10 +- 6 files changed, 149 insertions(+), 51 deletions(-) create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__inferface_rename.snap diff --git a/src/core/config/transformer/improve_type_names.rs b/src/core/config/transformer/improve_type_names.rs index 93f270eda2..a780a40750 100644 --- a/src/core/config/transformer/improve_type_names.rs +++ b/src/core/config/transformer/improve_type_names.rs @@ -2,6 +2,7 @@ use std::collections::{BTreeMap, HashSet}; use convert_case::{Case, Casing}; +use super::RenameTypes; use crate::core::config::Config; use crate::core::transform::Transform; use crate::core::valid::Valid; @@ -113,42 +114,12 @@ impl<'a> CandidateGeneration<'a> { #[derive(Default)] pub struct ImproveTypeNames; -impl ImproveTypeNames { - /// Generates type names based on inferred candidates from the provided - /// configuration. - fn generate_type_names(&self, mut config: Config) -> Config { - let finalized_candidates = CandidateGeneration::new(&config).generate().converge(); - - for (old_type_name, new_type_name) in finalized_candidates { - if let Some(type_) = config.types.remove(old_type_name.as_str()) { - // Add newly generated type. - config.types.insert(new_type_name.to_owned(), type_); - - // Replace all the instances of old name in config. - for actual_type in config.types.values_mut() { - for actual_field in actual_type.fields.values_mut() { - if actual_field.type_of.name() == &old_type_name { - // Update the field's type with the new name - actual_field.type_of = actual_field - .type_of - .clone() - .with_name(new_type_name.to_owned()); - } - } - } - } - } - config - } -} - impl Transform for ImproveTypeNames { type Value = Config; type Error = String; fn transform(&self, config: Config) -> Valid { - let config = self.generate_type_names(config); - - Valid::succeed(config) + let finalized_candidates = CandidateGeneration::new(&config).generate().converge(); + RenameTypes::new(finalized_candidates.iter()).transform(config) } } diff --git a/src/core/config/transformer/rename_types.rs b/src/core/config/transformer/rename_types.rs index 07a0f90526..1ff72b9c2c 100644 --- a/src/core/config/transformer/rename_types.rs +++ b/src/core/config/transformer/rename_types.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use indexmap::IndexMap; use crate::core::config::Config; @@ -28,12 +30,11 @@ impl Transform for RenameTypes { // Ensure all types exist in the configuration Valid::from_iter(self.0.iter(), |(existing_name, suggested_name)| { - if !config.types.contains_key(existing_name) { - Valid::fail(format!( - "Type '{}' not found in configuration.", - existing_name - )) - } else { + if config.types.contains_key(existing_name) + || config.enums.contains_key(existing_name) + || config.unions.contains_key(existing_name) + { + // handle for the types. if let Some(type_info) = config.types.remove(existing_name) { config.types.insert(suggested_name.to_string(), type_info); lookup.insert(existing_name.clone(), suggested_name.clone()); @@ -46,7 +47,24 @@ impl Transform for RenameTypes { } } + // handle for the enums. + if let Some(type_info) = config.enums.remove(existing_name) { + config.enums.insert(suggested_name.to_string(), type_info); + lookup.insert(existing_name.clone(), suggested_name.clone()); + } + + // handle for the union. + if let Some(type_info) = config.unions.remove(existing_name) { + config.unions.insert(suggested_name.to_string(), type_info); + lookup.insert(existing_name.clone(), suggested_name.clone()); + } + Valid::succeed(()) + } else { + Valid::fail(format!( + "Type '{}' not found in configuration.", + existing_name + )) } }) .map(|_| { @@ -65,6 +83,54 @@ impl Transform for RenameTypes { } } } + + // replace in interface. + type_.implements = type_ + .implements + .iter() + .map(|interface_type_name| { + lookup + .get(interface_type_name) + .cloned() + .unwrap_or_else(|| interface_type_name.to_owned()) + }) + .collect(); + } + + // replace in the union as well. + for union_type_ in config.unions.values_mut() { + // Collect changes to be made + let mut types_to_remove = HashSet::new(); + let mut types_to_add = HashSet::new(); + + for type_name in union_type_.types.iter() { + if let Some(new_type_name) = lookup.get(type_name) { + types_to_remove.insert(type_name.clone()); + types_to_add.insert(new_type_name.clone()); + } + } + // Apply changes + for type_name in types_to_remove { + union_type_.types.remove(&type_name); + } + + for type_name in types_to_add { + union_type_.types.insert(type_name); + } + } + + // replace in union as well. + for union_type_ in config.unions.values_mut() { + union_type_.types = union_type_ + .types + .iter() + .map(|type_name| { + lookup + .get(type_name) + .cloned() + .unwrap_or_else(|| type_name.to_owned()) + }) + .collect(); } config @@ -92,14 +158,20 @@ mod test { id: ID! name: String } + type B { + name: String + username: String + } + union FooBar = A | B type Post { id: ID! title: String body: String } - type B { - name: String - username: String + enum Status { + PENDING + STARTED, + COMPLETED } type Query { posts: [Post] @http(path: "/posts") @@ -116,6 +188,7 @@ mod test { "A" => "User", "B" => "InputUser", "Mutation" => "UserMutation", + "Status" => "TaskStatus" } .iter(), ) @@ -184,4 +257,30 @@ mod test { let expected = Err(b_err.combine(c_err)); assert_eq!(actual, expected); } + + #[test] + fn test_inferface_rename() { + let sdl = r#" + schema { + query: Query + } + interface Node { + id: ID + } + type Post implements Node { + id: ID + title: String + } + type Query { + posts: [Post] @http(path: "/posts") + } + "#; + let config = Config::from_sdl(sdl).to_result().unwrap(); + + let result = RenameTypes::new(hashmap! {"Node" => "NodeTest"}.iter()) + .transform(config) + .to_result() + .unwrap(); + insta::assert_snapshot!(result.to_sdl()) + } } diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__inferface_rename.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__inferface_rename.snap new file mode 100644 index 0000000000..06f20b4e3e --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__inferface_rename.snap @@ -0,0 +1,20 @@ +--- +source: src/core/config/transformer/rename_types.rs +expression: result.to_sdl() +--- +schema @server @upstream { + query: Query +} + +interface NodeTest { + id: ID +} + +type Post implements NodeTest { + id: ID + title: String +} + +type Query { + posts: [Post] @http(path: "/posts") +} diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__rename_type.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__rename_type.snap index 72c1602857..6f3669a884 100644 --- a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__rename_type.snap +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__rename_types__test__rename_type.snap @@ -11,6 +11,14 @@ input InputUser { username: String } +union FooBar = InputUser | User + +enum TaskStatus { + COMPLETED + PENDING + STARTED +} + type Post { body: String id: ID! diff --git a/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap b/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap index 98e1f7616a..991be951e4 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap @@ -18,11 +18,11 @@ input news__NewsInput { body: String id: Int postImage: String - status: news__Status + status: Status title: String } -enum news__Status { +enum Status { DELETED DRAFT PUBLISHED @@ -52,7 +52,7 @@ type News { body: String id: Int postImage: String - status: news__Status + status: Status title: String } @@ -80,11 +80,11 @@ type Post { type Query { inCompatibleProperties: InCompatibleProperty @http(path: "/") news__NewsService__AddNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") + news__NewsService__DeleteNews(newsId: Id!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") news__NewsService__EditNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") news__NewsService__GetAllNews: NewsNewsServiceGetMultipleNew @grpc(method: "news.NewsService.GetAllNews") news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): NewsNewsServiceGetMultipleNew @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: news__NewsId!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") + news__NewsService__GetNews(newsId: Id!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") post(id: Int! = 1): Post @http(path: "/posts/{{.args.id}}") posts: [Post] @http(path: "/posts?_limit=11") user(id: Int!): User @http(path: "/users/{{.args.id}}") diff --git a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap index 74ddc5e649..a0394a0dc8 100644 --- a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap +++ b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap @@ -18,11 +18,11 @@ input news__NewsInput { body: String id: Int postImage: String - status: news__Status + status: Status title: String } -enum news__Status { +enum Status { DELETED DRAFT PUBLISHED @@ -51,7 +51,7 @@ type News { body: String id: Int postImage: String - status: news__Status + status: Status title: String } @@ -61,11 +61,11 @@ type NewsNewsServiceGetMultipleNew { type Query { news__NewsService__AddNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") + news__NewsService__DeleteNews(newsId: Id!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") news__NewsService__EditNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") news__NewsService__GetAllNews: NewsNewsServiceGetMultipleNew @grpc(method: "news.NewsService.GetAllNews") news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): NewsNewsServiceGetMultipleNew @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: news__NewsId!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") + news__NewsService__GetNews(newsId: Id!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") users: [User] @http(path: "/users") } From 2cf0f5834b6b43df58a28a1cd377452b66ab20ed Mon Sep 17 00:00:00 2001 From: laststylebender <43403528+laststylebender14@users.noreply.github.com> Date: Sat, 21 Sep 2024 17:30:00 +0530 Subject: [PATCH 57/77] feat: make health and graphql endpoints to be configurable (#2870) --- generated/.tailcallrc.graphql | 11 ++++ generated/.tailcallrc.schema.json | 24 +++++++++ src/cli/server/mod.rs | 6 +-- src/core/blueprint/server.rs | 4 +- src/core/config/server.rs | 47 +++++++++++++++++ src/core/http/request_handler.rs | 44 ++++++++++++++-- ...routes-param-on-server-directive.md_0.snap | 19 +++++++ ...routes-param-on-server-directive.md_1.snap | 13 +++++ ...s-param-on-server-directive.md_client.snap | 51 +++++++++++++++++++ ...s-param-on-server-directive.md_merged.snap | 15 ++++++ .../routes-param-on-server-directive.md | 38 ++++++++++++++ 11 files changed, 263 insertions(+), 9 deletions(-) create mode 100644 tests/core/snapshots/routes-param-on-server-directive.md_0.snap create mode 100644 tests/core/snapshots/routes-param-on-server-directive.md_1.snap create mode 100644 tests/core/snapshots/routes-param-on-server-directive.md_client.snap create mode 100644 tests/core/snapshots/routes-param-on-server-directive.md_merged.snap create mode 100644 tests/execution/routes-param-on-server-directive.md diff --git a/generated/.tailcallrc.graphql b/generated/.tailcallrc.graphql index d41a58121e..bcb21779c5 100644 --- a/generated/.tailcallrc.graphql +++ b/generated/.tailcallrc.graphql @@ -296,6 +296,12 @@ directive @server( """ responseValidation: Boolean """ + `routes` allows customization of server endpoint paths. It provides options to change + the default paths for status and GraphQL endpoints. Default values are: - status: + "/status" - graphQL: "/graphql" If not specified, these default values will be used. + """ + routes: Routes + """ A link to an external JS file that listens on every HTTP request response event. """ script: ScriptOptions @@ -634,6 +640,11 @@ input Headers { setCookies: Boolean } +input Routes { + graphQL: String! + status: String! +} + input ScriptOptions { timeout: Int } diff --git a/generated/.tailcallrc.schema.json b/generated/.tailcallrc.schema.json index 654c30eedf..ef06397799 100644 --- a/generated/.tailcallrc.schema.json +++ b/generated/.tailcallrc.schema.json @@ -952,6 +952,19 @@ } } }, + "Routes": { + "type": "object", + "properties": { + "graphQL": { + "default": "/graphql", + "type": "string" + }, + "status": { + "default": "/status", + "type": "string" + } + } + }, "ScriptOptions": { "type": "object", "properties": { @@ -1059,6 +1072,17 @@ "null" ] }, + "routes": { + "description": "`routes` allows customization of server endpoint paths. It provides options to change the default paths for status and GraphQL endpoints. Default values are: - status: \"/status\" - graphQL: \"/graphql\" If not specified, these default values will be used.", + "anyOf": [ + { + "$ref": "#/definitions/Routes" + }, + { + "type": "null" + } + ] + }, "script": { "description": "A link to an external JS file that listens on every HTTP request response event.", "anyOf": [ diff --git a/src/cli/server/mod.rs b/src/cli/server/mod.rs index 0d556dacf8..3cd410e27b 100644 --- a/src/cli/server/mod.rs +++ b/src/cli/server/mod.rs @@ -8,8 +8,6 @@ pub use http_server::Server; use self::server_config::ServerConfig; -const GRAPHQL_SLUG: &str = "/graphql"; - fn log_launch(sc: &ServerConfig) { let addr = sc.addr().to_string(); tracing::info!( @@ -18,7 +16,9 @@ fn log_launch(sc: &ServerConfig) { sc.http_version() ); - let graphiql_url = sc.graphiql_url() + GRAPHQL_SLUG; + let gql_slug = sc.app_ctx.blueprint.server.routes.graphql(); + + let graphiql_url = sc.graphiql_url() + gql_slug; let url = playground::build_url(&graphiql_url); tracing::info!("🌍 Playground: {}", url); } diff --git a/src/core/blueprint/server.rs b/src/core/blueprint/server.rs index e8077a1514..df56169784 100644 --- a/src/core/blueprint/server.rs +++ b/src/core/blueprint/server.rs @@ -11,7 +11,7 @@ use rustls_pki_types::{CertificateDer, PrivateKeyDer}; use super::Auth; use crate::core::blueprint::Cors; -use crate::core::config::{self, ConfigModule, HttpVersion}; +use crate::core::config::{self, ConfigModule, HttpVersion, Routes}; use crate::core::valid::{Valid, ValidationError, Validator}; #[derive(Clone, Debug, Setters)] @@ -38,6 +38,7 @@ pub struct Server { pub experimental_headers: HashSet, pub auth: Option, pub dedupe: bool, + pub routes: Routes, } /// Mimic of mini_v8::Script that's wasm compatible @@ -154,6 +155,7 @@ impl TryFrom for Server { cors, auth, dedupe: config_server.get_dedupe(), + routes: config_server.get_routes(), } }, ) diff --git a/src/core/config/server.rs b/src/core/config/server.rs index 960e8ce40e..12087e9cb7 100644 --- a/src/core/config/server.rs +++ b/src/core/config/server.rs @@ -1,5 +1,7 @@ use std::collections::{BTreeMap, BTreeSet}; +use derive_getters::Getters; +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tailcall_macros::DirectiveDefinition; @@ -120,6 +122,47 @@ pub struct Server { /// `workers` sets the number of worker threads. @default the number of /// system cores. pub workers: Option, + + #[serde(default, skip_serializing_if = "is_default")] + /// `routes` allows customization of server endpoint paths. + /// It provides options to change the default paths for status and GraphQL + /// endpoints. Default values are: + /// - status: "/status" + /// - graphQL: "/graphql" If not specified, these default values will be + /// used. + pub routes: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, MergeRight, JsonSchema, Getters)] +pub struct Routes { + #[serde(default = "default_status")] + status: String, + #[serde(rename = "graphQL", default = "default_graphql")] + graphql: String, +} + +fn default_status() -> String { + "/status".into() +} + +fn default_graphql() -> String { + "/graphql".into() +} + +impl Default for Routes { + fn default() -> Self { + Self { status: "/status".into(), graphql: "/graphql".into() } + } +} + +impl Routes { + pub fn with_status>(self, status: T) -> Self { + Self { graphql: self.graphql, status: status.into() } + } + + pub fn with_graphql>(self, graphql: T) -> Self { + Self { status: self.status, graphql: graphql.into() } + } } fn merge_right_vars(mut left: Vec, right: Vec) -> Vec { @@ -231,6 +274,10 @@ impl Server { pub fn enable_jit(&self) -> bool { self.enable_jit.unwrap_or(true) } + + pub fn get_routes(&self) -> Routes { + self.routes.clone().unwrap_or_default() + } } #[cfg(test)] diff --git a/src/core/http/request_handler.rs b/src/core/http/request_handler.rs index 8357219a2d..3208a16cb7 100644 --- a/src/core/http/request_handler.rs +++ b/src/core/http/request_handler.rs @@ -302,11 +302,14 @@ async fn handle_request_inner( return handle_rest_apis(req, app_ctx, req_counter).await; } + let health_check_endpoint = app_ctx.blueprint.server.routes.status(); + let graphql_endpoint = app_ctx.blueprint.server.routes.graphql(); + match *req.method() { // NOTE: // The first check for the route should be for `/graphql` // This is always going to be the most used route. - hyper::Method::POST if req.uri().path() == "/graphql" => { + hyper::Method::POST if req.uri().path() == graphql_endpoint => { graphql_request::(req, &app_ctx, req_counter).await } hyper::Method::POST @@ -321,7 +324,7 @@ async fn handle_request_inner( graphql_request::(req, &Arc::new(app_ctx), req_counter).await } - hyper::Method::GET if req.uri().path() == "/status" => { + hyper::Method::GET if req.uri().path() == health_check_endpoint => { let status_response = Response::builder() .status(StatusCode::OK) .header(CONTENT_TYPE, "application/json") @@ -385,7 +388,7 @@ mod test { use super::*; use crate::core::async_graphql_hyper::GraphQLRequest; use crate::core::blueprint::Blueprint; - use crate::core::config::{Config, ConfigModule}; + use crate::core::config::{Config, ConfigModule, Routes}; use crate::core::rest::EndpointSet; use crate::core::runtime::test::init; use crate::core::valid::Validator; @@ -394,7 +397,8 @@ mod test { async fn test_health_endpoint() -> anyhow::Result<()> { let sdl = tokio::fs::read_to_string(tailcall_fixtures::configs::JSONPLACEHOLDER).await?; let config = Config::from_sdl(&sdl).to_result()?; - let blueprint = Blueprint::try_from(&ConfigModule::from(config))?; + let mut blueprint = Blueprint::try_from(&ConfigModule::from(config))?; + blueprint.server.routes = Routes::default().with_status("/health"); let app_ctx = Arc::new(AppContext::new( blueprint, init(None), @@ -403,7 +407,7 @@ mod test { let req = Request::builder() .method(Method::GET) - .uri("http://localhost:8000/status".to_string()) + .uri("http://localhost:8000/health".to_string()) .body(Body::empty())?; let resp = handle_request::(req, app_ctx).await?; @@ -415,6 +419,36 @@ mod test { Ok(()) } + #[tokio::test] + async fn test_graphql_endpoint() -> anyhow::Result<()> { + let sdl = tokio::fs::read_to_string(tailcall_fixtures::configs::JSONPLACEHOLDER).await?; + let config = Config::from_sdl(&sdl).to_result()?; + let mut blueprint = Blueprint::try_from(&ConfigModule::from(config))?; + blueprint.server.routes = Routes::default().with_graphql("/gql"); + let app_ctx = Arc::new(AppContext::new( + blueprint, + init(None), + EndpointSet::default(), + )); + + let query = r#"{"query": "{ __schema { queryType { name } } }"}"#; + let req = Request::builder() + .method(Method::POST) + .uri("http://localhost:8000/gql".to_string()) + .header("Content-Type", "application/json") + .body(Body::from(query))?; + + let resp = handle_request::(req, app_ctx).await?; + + assert_eq!(resp.status(), StatusCode::OK); + let body = hyper::body::to_bytes(resp.into_body()).await?; + let body_str = String::from_utf8(body.to_vec())?; + assert!(body_str.contains("queryType")); + assert!(body_str.contains("name")); + + Ok(()) + } + #[test] fn test_create_allowed_headers() { use std::collections::BTreeSet; diff --git a/tests/core/snapshots/routes-param-on-server-directive.md_0.snap b/tests/core/snapshots/routes-param-on-server-directive.md_0.snap new file mode 100644 index 0000000000..f683c854d5 --- /dev/null +++ b/tests/core/snapshots/routes-param-on-server-directive.md_0.snap @@ -0,0 +1,19 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "users": [ + { + "name": "Leanne Graham" + } + ] + } + } +} diff --git a/tests/core/snapshots/routes-param-on-server-directive.md_1.snap b/tests/core/snapshots/routes-param-on-server-directive.md_1.snap new file mode 100644 index 0000000000..b5a72701af --- /dev/null +++ b/tests/core/snapshots/routes-param-on-server-directive.md_1.snap @@ -0,0 +1,13 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "message": "ready" + } +} diff --git a/tests/core/snapshots/routes-param-on-server-directive.md_client.snap b/tests/core/snapshots/routes-param-on-server-directive.md_client.snap new file mode 100644 index 0000000000..e05605ebef --- /dev/null +++ b/tests/core/snapshots/routes-param-on-server-directive.md_client.snap @@ -0,0 +1,51 @@ +--- +source: tests/core/spec.rs +expression: formatted +--- +scalar Bytes + +scalar Date + +scalar DateTime + +scalar Email + +scalar Empty + +scalar Int128 + +scalar Int16 + +scalar Int32 + +scalar Int64 + +scalar Int8 + +scalar JSON + +scalar PhoneNumber + +type Query { + users: [User] +} + +scalar UInt128 + +scalar UInt16 + +scalar UInt32 + +scalar UInt64 + +scalar UInt8 + +scalar Url + +type User { + name: String +} + +schema { + query: Query +} diff --git a/tests/core/snapshots/routes-param-on-server-directive.md_merged.snap b/tests/core/snapshots/routes-param-on-server-directive.md_merged.snap new file mode 100644 index 0000000000..bbb4a061d2 --- /dev/null +++ b/tests/core/snapshots/routes-param-on-server-directive.md_merged.snap @@ -0,0 +1,15 @@ +--- +source: tests/core/spec.rs +expression: formatter +--- +schema @server(port: 8000, routes: {status: "/health", graphQL: "/tailcall-gql"}) @upstream { + query: Query +} + +type Query { + users: [User] @http(baseURL: "http://jsonplaceholder.typicode.com", path: "/users") +} + +type User { + name: String +} diff --git a/tests/execution/routes-param-on-server-directive.md b/tests/execution/routes-param-on-server-directive.md new file mode 100644 index 0000000000..049a3dcffc --- /dev/null +++ b/tests/execution/routes-param-on-server-directive.md @@ -0,0 +1,38 @@ +# Sending field index list + +```graphql @config +schema @server(port: 8000, routes: {graphQL: "/tailcall-gql", status: "/health"}) { + query: Query +} + +type User { + name: String +} + +type Query { + users: [User] @http(path: "/users", baseURL: "http://jsonplaceholder.typicode.com") +} +``` + +```yml @mock +- request: + method: GET + url: http://jsonplaceholder.typicode.com/users + response: + status: 200 + body: + - id: 1 + name: Leanne Graham +``` + +```yml @test +- method: POST + url: http://localhost:8080/tailcall-gql + body: + query: query { users { name } } + +- method: GET + url: http://localhost:8080/health + body: + query: query { users { name } } +``` From 7144fd3cdb441e870c165f69d8b34fd8c3dec14b Mon Sep 17 00:00:00 2001 From: laststylebender <43403528+laststylebender14@users.noreply.github.com> Date: Sat, 21 Sep 2024 19:20:06 +0530 Subject: [PATCH 58/77] refactor: use a consistent prefix for auto-generated names (#2783) Co-authored-by: Tushar Mathur --- examples/generate.yml | 47 ++++ src/cli/llm/infer_type_name.rs | 85 +++++-- src/cli/llm/prompts/infer_type_name.md | 4 +- ...ame__test__to_chat_request_conversion.snap | 2 +- .../config/transformer/improve_type_names.rs | 7 +- ..._type_merger__test__cyclic_merge_case.snap | 8 +- ...types__type_merger__test__input_types.snap | 6 +- ...s__type_merger__test__interface_types.snap | 4 +- ...type_merger__test__merge_to_supertype.snap | 6 +- ...types__type_merger__test__type_merger.snap | 10 +- ...types__type_merger__test__union_types.snap | 4 +- .../transformer/merge_types/type_merger.rs | 27 +- ...__tests__resolve_ambiguous_news_types.snap | 38 +-- src/core/generator/generator.rs | 4 +- src/core/generator/graphql_type.rs | 17 +- .../json/http_directive_generator.rs | 3 +- .../generator/json/operation_generator.rs | 6 +- ...__operation_generator__test__mutation.snap | 2 +- src/core/generator/mod.rs | 3 + ...nerator__from_proto__test__from_proto.snap | 62 ++--- ...m_proto__test__from_proto_no_pkg_file.snap | 8 +- ...rom_proto__test__greetings_proto_file.snap | 10 +- ...enerator__from_proto__test__map_types.snap | 10 +- ...__generator__from_proto__test__movies.snap | 100 ++++---- ...rator__from_proto__test__nested_types.snap | 24 +- ...erator__from_proto__test__oneof_types.snap | 72 +++--- ...or__from_proto__test__optional_fields.snap | 30 +-- ...tor__from_proto__test__required_types.snap | 10 +- ...rator__from_proto__test__scalar_types.snap | 16 +- ...test__should_generate_combined_config.snap | 32 +-- ...st__should_generate_config_from_proto.snap | 38 +-- .../json_to_config_spec__add_cart.json.snap | 20 +- .../json_to_config_spec__boolean.json.snap | 2 +- ...json_to_config_spec__create_post.json.snap | 12 +- ...n_to_config_spec__create_product.json.snap | 12 +- ...json_to_config_spec__create_user.json.snap | 12 +- ...config_spec__generate_auth_token.json.snap | 12 +- ...ig_spec__incompatible_properties.json.snap | 10 +- .../json_to_config_spec__list.json.snap | 10 +- ...json_to_config_spec__nested_list.json.snap | 18 +- ...fig_spec__nested_same_properties.json.snap | 22 +- ...i__fixtures__generator__gen_deezer.md.snap | 238 +++++++++--------- ...nerator__gen_json_proto_mix_config.md.snap | 32 +-- ...es__generator__gen_jsonplaceholder.md.snap | 10 +- 44 files changed, 614 insertions(+), 491 deletions(-) create mode 100644 examples/generate.yml diff --git a/examples/generate.yml b/examples/generate.yml new file mode 100644 index 0000000000..13b1a909ea --- /dev/null +++ b/examples/generate.yml @@ -0,0 +1,47 @@ +inputs: + - curl: + src: "https://jsonplaceholder.typicode.com/posts/1" + headers: + Content-Type: application/json + Accept: application/json + fieldName: post + - curl: + src: "https://jsonplaceholder.typicode.com/users/1" + fieldName: user + - curl: + src: "https://jsonplaceholder.typicode.com/users" + fieldName: users + - curl: + src: "https://jsonplaceholder.typicode.com/posts" + fieldName: posts + - curl: + src: "https://jsonplaceholder.typicode.com/comments" + fieldName: comments + - curl: + src: "https://jsonplaceholder.typicode.com/comments/1" + fieldName: comment + - curl: + src: "https://jsonplaceholder.typicode.com/photos" + fieldName: photos + - curl: + src: "https://jsonplaceholder.typicode.com/photos/1" + fieldName: photo + - curl: + src: "https://jsonplaceholder.typicode.com/todos" + fieldName: todos + - curl: + src: "https://jsonplaceholder.typicode.com/todos/1" + fieldName: todo + - curl: + src: "https://jsonplaceholder.typicode.com/comments?postId=1" + fieldName: postComments +preset: + mergeType: 1 + consolidateURL: 0.5 + treeShake: true + inferTypeNames: true +output: + path: "./jsonplaceholder.graphql" + format: graphQL +schema: + query: Query diff --git a/src/cli/llm/infer_type_name.rs b/src/cli/llm/infer_type_name.rs index 975841500e..7183eacbde 100644 --- a/src/cli/llm/infer_type_name.rs +++ b/src/cli/llm/infer_type_name.rs @@ -1,13 +1,17 @@ use std::collections::HashMap; use genai::chat::{ChatMessage, ChatRequest, ChatResponse}; +use indexmap::{indexset, IndexSet}; use serde::{Deserialize, Serialize}; use serde_json::json; use super::{Error, Result, Wizard}; use crate::core::config::Config; +use crate::core::generator::PREFIX; use crate::core::Mustache; +const BASE_TEMPLATE: &str = include_str!("prompts/infer_type_name.md"); + pub struct InferTypeName { wizard: Wizard, } @@ -29,22 +33,31 @@ impl TryFrom for Answer { #[derive(Clone, Serialize)] struct Question { + #[serde(skip_serializing_if = "IndexSet::is_empty")] + ignore: IndexSet, fields: Vec<(String, String)>, } +#[derive(Serialize)] +struct Context { + input: Question, + output: Answer, +} + impl TryInto for Question { type Error = Error; fn try_into(self) -> Result { - let input = serde_json::to_string_pretty(&Question { + let input = Question { + ignore: indexset! { "User".into()}, fields: vec![ ("id".to_string(), "String".to_string()), ("name".to_string(), "String".to_string()), ("age".to_string(), "Int".to_string()), ], - })?; + }; - let output = serde_json::to_string_pretty(&Answer { + let output = Answer { suggestions: vec![ "Person".into(), "Profile".into(), @@ -52,21 +65,19 @@ impl TryInto for Question { "Individual".into(), "Contact".into(), ], - })?; + }; - let template_str = include_str!("prompts/infer_type_name.md"); - let template = Mustache::parse(template_str); + let template = Mustache::parse(BASE_TEMPLATE); - let context = json!({ - "input": input, - "output": output, - }); + let context = Context { input, output }; - let rendered_prompt = template.render(&context); + let rendered_prompt = template.render(&serde_json::to_value(&context)?); Ok(ChatRequest::new(vec![ ChatMessage::system(rendered_prompt), - ChatMessage::user(serde_json::to_string(&self)?), + ChatMessage::user(serde_json::to_string(&json!({ + "fields": &self.fields, + }))?), ])) } } @@ -76,20 +87,35 @@ impl InferTypeName { Self { wizard: Wizard::new(model, secret) } } + /// All generated type names starts with PREFIX + #[inline] + fn is_auto_generated(type_name: &str) -> bool { + type_name.starts_with(PREFIX) + } + pub async fn generate(&mut self, config: &Config) -> Result> { let mut new_name_mappings: HashMap = HashMap::new(); - - // removed root type from types. + // Filter out root operation types and types with non-auto-generated names let types_to_be_processed = config .types .iter() - .filter(|(type_name, _)| !config.is_root_operation_type(type_name)) + .filter(|(type_name, _)| { + !config.is_root_operation_type(type_name) && Self::is_auto_generated(type_name) + }) .collect::>(); + let mut used_type_names = config + .types + .iter() + .filter(|(ty_name, _)| !Self::is_auto_generated(ty_name)) + .map(|(ty_name, _)| ty_name.to_owned()) + .collect::>(); + let total = types_to_be_processed.len(); for (i, (type_name, type_)) in types_to_be_processed.into_iter().enumerate() { // convert type to sdl format. let question = Question { + ignore: used_type_names.clone(), fields: type_ .fields .iter() @@ -104,12 +130,11 @@ impl InferTypeName { Ok(answer) => { let name = &answer.suggestions.join(", "); for name in answer.suggestions { - if config.types.contains_key(&name) - || new_name_mappings.contains_key(&name) - { + if config.types.contains_key(&name) || used_type_names.contains(&name) { continue; } - new_name_mappings.insert(name, type_name.to_owned()); + used_type_names.insert(name.clone()); + new_name_mappings.insert(type_name.to_owned(), name); break; } tracing::info!( @@ -142,19 +167,22 @@ impl InferTypeName { } } - Ok(new_name_mappings.into_iter().map(|(k, v)| (v, k)).collect()) + Ok(new_name_mappings) } } #[cfg(test)] mod test { use genai::chat::{ChatRequest, ChatResponse, MessageContent}; + use indexmap::indexset; use super::{Answer, Question}; + use crate::cli::llm::InferTypeName; #[test] fn test_to_chat_request_conversion() { let question = Question { + ignore: indexset! {"Profile".to_owned(), "Person".to_owned()}, fields: vec![ ("id".to_string(), "String".to_string()), ("name".to_string(), "String".to_string()), @@ -176,4 +204,21 @@ mod test { let answer = Answer::try_from(resp).unwrap(); insta::assert_debug_snapshot!(answer); } + + #[test] + fn test_is_auto_generated() { + assert!(InferTypeName::is_auto_generated("GEN__T1")); + assert!(InferTypeName::is_auto_generated("GEN__T1234")); + assert!(InferTypeName::is_auto_generated("GEN__M1")); + assert!(InferTypeName::is_auto_generated("GEN__M5678")); + assert!(InferTypeName::is_auto_generated("GEN__Some__Type")); + + assert!(!InferTypeName::is_auto_generated("Some__Type")); + assert!(!InferTypeName::is_auto_generated("User")); + assert!(!InferTypeName::is_auto_generated("T123")); + assert!(!InferTypeName::is_auto_generated("M1")); + assert!(!InferTypeName::is_auto_generated("")); + assert!(!InferTypeName::is_auto_generated("123T")); + assert!(!InferTypeName::is_auto_generated("A1234")); + } } diff --git a/src/cli/llm/prompts/infer_type_name.md b/src/cli/llm/prompts/infer_type_name.md index 5b24cff2ce..2593f806b8 100644 --- a/src/cli/llm/prompts/infer_type_name.md +++ b/src/cli/llm/prompts/infer_type_name.md @@ -1,5 +1,5 @@ Given the sample schema of a GraphQL type, suggest 5 meaningful names for it. -The name should be concise and preferably a single word. +The name should be concise, preferably a single word and must not be in the `ignore` list. Example Input: {{input}} @@ -8,5 +8,3 @@ Example Output: {{output}} Ensure the output is in valid JSON format. - -Do not add any additional text before or after the JSON. diff --git a/src/cli/llm/snapshots/tailcall__cli__llm__infer_type_name__test__to_chat_request_conversion.snap b/src/cli/llm/snapshots/tailcall__cli__llm__infer_type_name__test__to_chat_request_conversion.snap index 9551df87fe..d50032444d 100644 --- a/src/cli/llm/snapshots/tailcall__cli__llm__infer_type_name__test__to_chat_request_conversion.snap +++ b/src/cli/llm/snapshots/tailcall__cli__llm__infer_type_name__test__to_chat_request_conversion.snap @@ -8,7 +8,7 @@ ChatRequest { ChatMessage { role: System, content: Text( - "Given the sample schema of a GraphQL type, suggest 5 meaningful names for it.\nThe name should be concise and preferably a single word.\n\nExample Input:\n{\n \"fields\": [\n [\n \"id\",\n \"String\"\n ],\n [\n \"name\",\n \"String\"\n ],\n [\n \"age\",\n \"Int\"\n ]\n ]\n}\n\nExample Output:\n{\n \"suggestions\": [\n \"Person\",\n \"Profile\",\n \"Member\",\n \"Individual\",\n \"Contact\"\n ]\n}\n\nEnsure the output is in valid JSON format.\n\nDo not add any additional text before or after the JSON.\n", + "Given the sample schema of a GraphQL type, suggest 5 meaningful names for it.\nThe name should be concise, preferably a single word and must not be in the `ignore` list.\n\nExample Input:\n{\"ignore\":[\"User\"],\"fields\":[[\"id\",\"String\"],[\"name\",\"String\"],[\"age\",\"Int\"]]}\n\nExample Output:\n{\"suggestions\":[\"Person\",\"Profile\",\"Member\",\"Individual\",\"Contact\"]}\n\nEnsure the output is in valid JSON format.\n", ), extra: None, }, diff --git a/src/core/config/transformer/improve_type_names.rs b/src/core/config/transformer/improve_type_names.rs index a780a40750..1658b95010 100644 --- a/src/core/config/transformer/improve_type_names.rs +++ b/src/core/config/transformer/improve_type_names.rs @@ -4,6 +4,7 @@ use convert_case::{Case, Casing}; use super::RenameTypes; use crate::core::config::Config; +use crate::core::generator::PREFIX; use crate::core::transform::Transform; use crate::core::valid::Valid; @@ -77,8 +78,10 @@ impl<'a> CandidateGeneration<'a> { fn generate(mut self) -> CandidateConvergence<'a> { for (type_name, type_info) in self.config.types.iter() { for (field_name, field_info) in type_info.fields.iter() { - if self.config.is_scalar(field_info.type_of.name()) { - // If field type is scalar then ignore type name inference. + if self.config.is_scalar(field_info.type_of.name()) + || field_name.starts_with(PREFIX) + { + // If field type is scalar or auto generated then ignore type name inference. continue; } diff --git a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__cyclic_merge_case.snap b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__cyclic_merge_case.snap index 397c71fd45..1d258d9b10 100644 --- a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__cyclic_merge_case.snap +++ b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__cyclic_merge_case.snap @@ -6,15 +6,15 @@ schema @server @upstream { query: Query } -type M1 { +type GEN__M1 { body: String id: Int is_verified: Boolean - t1: M1 + t1: GEN__M1 userId: Int } type Query { - q1: M1 - q2: M1 + q1: GEN__M1 + q2: GEN__M1 } diff --git a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__input_types.snap b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__input_types.snap index a97c8c4ead..d2622368ce 100644 --- a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__input_types.snap +++ b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__input_types.snap @@ -11,12 +11,12 @@ input Far { tar: String } -input M1 { +input GEN__M1 { tar: String } type Query { - bar(input: M1): String @http(path: "/bar") + bar(input: GEN__M1): String @http(path: "/bar") far(input: Far): String @http(path: "/far") - foo(input: M1): String @http(path: "/foo") + foo(input: GEN__M1): String @http(path: "/foo") } diff --git a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__interface_types.snap b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__interface_types.snap index 790c94b10a..ffdd47a32d 100644 --- a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__interface_types.snap +++ b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__interface_types.snap @@ -2,10 +2,10 @@ source: src/core/config/transformer/merge_types/type_merger.rs expression: config.to_sdl() --- -interface M1 { +interface GEN__M1 { a: Int } -type C implements M1 { +type C implements GEN__M1 { a: Int } diff --git a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__merge_to_supertype.snap b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__merge_to_supertype.snap index 88ce824973..06ffb453c8 100644 --- a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__merge_to_supertype.snap +++ b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__merge_to_supertype.snap @@ -6,12 +6,12 @@ schema @server @upstream { query: Query } -type M1 { +type GEN__M1 { id: Int name: JSON } type Query { - bar: M1 - foo: M1 + bar: GEN__M1 + foo: GEN__M1 } diff --git a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__type_merger.snap b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__type_merger.snap index bda31bac5c..e6c6bdddce 100644 --- a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__type_merger.snap +++ b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__type_merger.snap @@ -6,7 +6,7 @@ schema @server @upstream { query: Query } -type M1 { +type GEN__M1 { f1: String f2: Int f3: Boolean @@ -15,8 +15,8 @@ type M1 { } type Query { - q1: M1 - q2: M1 - q3: M1 - q4: M1 + q1: GEN__M1 + q2: GEN__M1 + q3: GEN__M1 + q4: GEN__M1 } diff --git a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__union_types.snap b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__union_types.snap index a467739733..9dff6bd02b 100644 --- a/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__union_types.snap +++ b/src/core/config/transformer/merge_types/snapshots/tailcall__core__config__transformer__merge_types__type_merger__test__union_types.snap @@ -6,7 +6,7 @@ schema @server @upstream(baseURL: "http://jsonplacheholder.typicode.com") { query: Query } -union FooBar = Foo | M1 +union FooBar = Foo | GEN__M1 type Foo { a: String @@ -14,7 +14,7 @@ type Foo { foo: String } -type M1 { +type GEN__M1 { bar: String } diff --git a/src/core/config/transformer/merge_types/type_merger.rs b/src/core/config/transformer/merge_types/type_merger.rs index dbd88ffb8f..c5d83950ac 100644 --- a/src/core/config/transformer/merge_types/type_merger.rs +++ b/src/core/config/transformer/merge_types/type_merger.rs @@ -1,8 +1,11 @@ -use std::collections::{BTreeMap, BTreeSet, HashSet}; +use std::collections::HashSet; + +use indexmap::{IndexMap, IndexSet}; use super::mergeable_types::MergeableTypes; use super::similarity::Similarity; use crate::core::config::{Config, Type}; +use crate::core::generator::PREFIX; use crate::core::merge_right::MergeRight; use crate::core::scalar::Scalar; use crate::core::transform::Transform; @@ -31,25 +34,31 @@ impl Default for TypeMerger { impl TypeMerger { fn merger(&self, mut merge_counter: u32, mut config: Config) -> Config { - let mut type_to_merge_type_mapping = BTreeMap::new(); - let mut similar_type_group_list: Vec> = vec![]; + let mut type_to_merge_type_mapping = IndexMap::new(); + let mut similar_type_group_list: Vec> = vec![]; let mut visited_types = HashSet::new(); let mut i = 0; let mut stat_gen = Similarity::new(&config); let mergeable_types = MergeableTypes::new(&config, self.threshold); + // fixes the flaky tests. + let mut types = mergeable_types.iter().collect::>(); + types.sort(); + // step 1: identify all the types that satisfies the thresh criteria and group // them. - for type_name_1 in mergeable_types.iter() { + for type_name_1 in types.iter() { + let type_name_1 = type_name_1.as_str(); if let Some(type_info_1) = config.types.get(type_name_1) { if visited_types.contains(type_name_1) { continue; } - let mut similar_type_set = BTreeSet::new(); + let mut similar_type_set = IndexSet::new(); similar_type_set.insert(type_name_1.to_string()); - for type_name_2 in mergeable_types.iter().skip(i + 1) { + for type_name_2 in types.iter().skip(i + 1) { + let type_name_2 = type_name_2.as_str(); if visited_types.contains(type_name_2) || !mergeable_types.mergeable(type_name_1, type_name_2) { @@ -58,7 +67,7 @@ impl TypeMerger { if let Some(type_info_2) = config.types.get(type_name_2) { let threshold = mergeable_types.get_threshold(type_name_1, type_name_2); - visited_types.insert(type_name_1.clone()); + visited_types.insert(type_name_1.to_owned()); let is_similar = stat_gen .similarity( (type_name_1, type_info_1), @@ -69,7 +78,7 @@ impl TypeMerger { if let Ok(similar) = is_similar { if similar { - visited_types.insert(type_name_2.clone()); + visited_types.insert(type_name_2.to_owned()); similar_type_set.insert(type_name_2.to_owned()); } } @@ -89,7 +98,7 @@ impl TypeMerger { // step 2: merge similar types into single merged type. for same_types in similar_type_group_list { let mut merged_into = Type::default(); - let merged_type_name = format!("M{}", merge_counter); + let merged_type_name = format!("{}M{}", PREFIX, merge_counter); let mut did_we_merge = false; for type_name in same_types { if let Some(type_) = config.types.get(type_name.as_str()) { diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__ambiguous_type__tests__resolve_ambiguous_news_types.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__ambiguous_type__tests__resolve_ambiguous_news_types.snap index 6dfe30f151..54b21b53c8 100644 --- a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__ambiguous_type__tests__resolve_ambiguous_news_types.snap +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__ambiguous_type__tests__resolve_ambiguous_news_types.snap @@ -6,45 +6,45 @@ schema @server @upstream { query: Query } -input news__MultipleNewsId { - ids: [news__NewsId] +input GEN__news__MultipleNewsId { + ids: [GEN__news__NewsId] } -input news__NewsId { +input GEN__news__NewsId { id: Int } -input news__NewsInput { +input GEN__news__NewsInput { body: String id: Int postImage: String - status: news__Status + status: GEN__news__Status title: String } -enum news__Status { +enum GEN__news__Status { DELETED DRAFT PUBLISHED } -type Query { - news__NewsService__AddNews(news: news__NewsInput!): news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") - news__NewsService__EditNews(news: news__NewsInput!): news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") - news__NewsService__GetAllNews: news__NewsList @grpc(method: "news.NewsService.GetAllNews") - news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: news__NewsId!): news__News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") -} - -type news__News { +type GEN__news__News { body: String id: Int postImage: String - status: news__Status + status: GEN__news__Status title: String } -type news__NewsList { - news: [news__News] +type GEN__news__NewsList { + news: [GEN__news__News] +} + +type Query { + GEN__news__NewsService__AddNews(news: GEN__news__NewsInput!): GEN__news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") + GEN__news__NewsService__DeleteNews(newsId: GEN__news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") + GEN__news__NewsService__EditNews(news: GEN__news__NewsInput!): GEN__news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") + GEN__news__NewsService__GetAllNews: GEN__news__NewsList @grpc(method: "news.NewsService.GetAllNews") + GEN__news__NewsService__GetMultipleNews(multipleNewsId: GEN__news__MultipleNewsId!): GEN__news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") + GEN__news__NewsService__GetNews(newsId: GEN__news__NewsId!): GEN__news__News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") } diff --git a/src/core/generator/generator.rs b/src/core/generator/generator.rs index bd5fc0387c..a03c752661 100644 --- a/src/core/generator/generator.rs +++ b/src/core/generator/generator.rs @@ -7,7 +7,7 @@ use serde_json::Value; use url::Url; use super::from_proto::from_proto; -use super::{FromJsonGenerator, NameGenerator, RequestSample}; +use super::{FromJsonGenerator, NameGenerator, RequestSample, PREFIX}; use crate::core::config::{self, Config, ConfigModule, Link, LinkType}; use crate::core::http::Method; use crate::core::merge_right::MergeRight; @@ -57,7 +57,7 @@ impl Generator { query: "Query".into(), mutation: None, inputs: Vec::new(), - type_name_prefix: "T".into(), + type_name_prefix: PREFIX.into(), transformers: Default::default(), } } diff --git a/src/core/generator/graphql_type.rs b/src/core/generator/graphql_type.rs index 6dcd527368..58869b6a6d 100644 --- a/src/core/generator/graphql_type.rs +++ b/src/core/generator/graphql_type.rs @@ -1,6 +1,9 @@ use std::fmt::Display; use convert_case::{Case, Casing}; + +use super::PREFIX; +use crate::core::scalar::Scalar; pub(super) static DEFAULT_SEPARATOR: &str = "__"; static PACKAGE_SEPARATOR: &str = "."; @@ -144,12 +147,15 @@ enum Entity { } impl Display for GraphQLType { + // The PREFIX is used to identify auto-generated type names in the + // LLM-based name correction process. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let parsed = &self.0; match parsed.entity { Entity::EnumVariant => f.write_str(parsed.name.as_str())?, Entity::Field => f.write_str(parsed.name.to_case(Case::Camel).as_str())?, Entity::Method => { + f.write_str(PREFIX)?; if !parsed.namespace.is_empty() { f.write_str(parsed.namespace.to_string().as_str())?; f.write_str(DEFAULT_SEPARATOR)?; @@ -157,6 +163,10 @@ impl Display for GraphQLType { f.write_str(parsed.name.as_str())? } Entity::Enum | Entity::ObjectType => { + // if output type is scalar, then skip the prefix. + if !Scalar::is_predefined(&parsed.name) { + f.write_str(PREFIX)?; + } if !parsed.namespace.is_empty() { f.write_str(parsed.namespace.to_string().as_str())?; f.write_str(DEFAULT_SEPARATOR)?; @@ -300,13 +310,18 @@ mod tests { fn assert_type_names(input: Vec) { for ((entity, namespaces, name), expected) in input { + let prefix = match entity { + Entity::Enum | Entity::ObjectType | Entity::Method => PREFIX, + _ => "", + }; + let mut g = GraphQLType::new(name); for namespace in namespaces { g = g.push(namespace); } let actual = g.parse(entity).to_string(); - assert_eq!(actual, expected); + assert_eq!(actual, format!("{prefix}{expected}")); } } } diff --git a/src/core/generator/json/http_directive_generator.rs b/src/core/generator/json/http_directive_generator.rs index 5dad164164..4d45cd6ad4 100644 --- a/src/core/generator/json/http_directive_generator.rs +++ b/src/core/generator/json/http_directive_generator.rs @@ -5,6 +5,7 @@ use regex::Regex; use url::Url; use crate::core::config::{Arg, Field, Http, URLQuery}; +use crate::core::generator::PREFIX; use crate::core::helpers::gql_type::detect_gql_data_type; use crate::core::Type; @@ -76,7 +77,7 @@ impl<'a> HttpDirectiveGenerator<'a> { .fold(path_url.to_string(), |acc, (regex, type_of)| { regex .replace_all(&acc.to_string(), |_: ®ex::Captures| { - let arg_key = format!("p{}", arg_index); + let arg_key = format!("{}{}", PREFIX, arg_index); let placeholder = format!("/{{{{.args.{}}}}}", arg_key); let arg = Arg { diff --git a/src/core/generator/json/operation_generator.rs b/src/core/generator/json/operation_generator.rs index d80b10c33d..a904ae8679 100644 --- a/src/core/generator/json/operation_generator.rs +++ b/src/core/generator/json/operation_generator.rs @@ -3,7 +3,7 @@ use convert_case::{Case, Casing}; use super::http_directive_generator::HttpDirectiveGenerator; use crate::core::config::{Arg, Config, Field, GraphQLOperationType, Resolver}; use crate::core::generator::json::types_generator::TypeGenerator; -use crate::core::generator::{NameGenerator, RequestSample}; +use crate::core::generator::{NameGenerator, RequestSample, PREFIX}; use crate::core::valid::Valid; use crate::core::{config, Type}; @@ -39,7 +39,9 @@ impl OperationTypeGenerator { let root_ty = TypeGenerator::new(name_generator) .generate_types(&request_sample.req_body, &mut config); // add input type to field. - let arg_name = format!("{}Input", request_sample.field_name).to_case(Case::Camel); + let prefix = format!("{}Input", PREFIX); + let arg_name_gen = NameGenerator::new(prefix.as_str()); + let arg_name = arg_name_gen.next(); if let Some(Resolver::Http(http)) = &mut field.resolver { http.body = Some(format!("{{{{.args.{}}}}}", arg_name)); http.method = request_sample.method.to_owned(); diff --git a/src/core/generator/json/snapshots/tailcall__core__generator__json__operation_generator__test__mutation.snap b/src/core/generator/json/snapshots/tailcall__core__generator__json__operation_generator__test__mutation.snap index 26566ed954..86853a3c98 100644 --- a/src/core/generator/json/snapshots/tailcall__core__generator__json__operation_generator__test__mutation.snap +++ b/src/core/generator/json/snapshots/tailcall__core__generator__json__operation_generator__test__mutation.snap @@ -10,5 +10,5 @@ input Input1 { } type Mutation { - postComments(postCommentsInput: Input1): T44 @http(body: "{{.args.postCommentsInput}}", method: "POST", path: "/posts") + postComments(GEN__Input1: Input1): T44 @http(body: "{{.args.GEN__Input1}}", method: "POST", path: "/posts") } diff --git a/src/core/generator/mod.rs b/src/core/generator/mod.rs index c03d535e5e..b988843f6a 100644 --- a/src/core/generator/mod.rs +++ b/src/core/generator/mod.rs @@ -10,6 +10,9 @@ pub use generator::{Generator, Input}; use crate::core::counter::{Count, Counter}; +// it's used as prefix to all the names which are auto generated. +pub const PREFIX: &str = "GEN__"; + pub struct NameGenerator { counter: Counter, prefix: String, diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto.snap index 04d437a5b4..a32820de20 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto.snap @@ -6,75 +6,75 @@ schema @server @upstream { query: Query } -input greetings__HelloRequest { +input GEN__greetings__HelloRequest { name: String } """ The request message containing the user's name. """ -input greetings_a__b__HelloRequest { +input GEN__greetings_a__b__HelloRequest { name: String } -input news__MultipleNewsId { - ids: [news__NewsId] +input GEN__news__MultipleNewsId { + ids: [GEN__news__NewsId] } -input news__NewsId { +input GEN__news__NewsId { id: Int } -input news__NewsInput { +input GEN__news__NewsInput { body: String id: Int postImage: String - status: news__Status + status: GEN__news__Status title: String } -enum news__Status { +enum GEN__news__Status { DELETED DRAFT PUBLISHED } -type Query { - """ - Sends a greeting - """ - greetings_a__b__Greeter__SayHello(helloRequest: greetings_a__b__HelloRequest!): greetings_a__b__HelloReply @grpc(body: "{{.args.helloRequest}}", method: "greetings_a.b.Greeter.SayHello") - """ - Sends a greeting - """ - greetings_b__c__Greeter__SayHello(helloRequest: greetings__HelloRequest!): greetings__HelloReply @grpc(body: "{{.args.helloRequest}}", method: "greetings_b.c.Greeter.SayHello") - news__NewsService__AddNews(news: news__NewsInput!): news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") - news__NewsService__EditNews(news: news__NewsInput!): news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") - news__NewsService__GetAllNews: news__NewsList @grpc(method: "news.NewsService.GetAllNews") - news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: news__NewsId!): news__News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") -} - -type greetings__HelloReply { +type GEN__greetings__HelloReply { message: String } """ The response message containing the greetings """ -type greetings_a__b__HelloReply { +type GEN__greetings_a__b__HelloReply { message: String } -type news__News { +type GEN__news__News { body: String id: Int postImage: String - status: news__Status + status: GEN__news__Status title: String } -type news__NewsList { - news: [news__News] +type GEN__news__NewsList { + news: [GEN__news__News] +} + +type Query { + """ + Sends a greeting + """ + GEN__greetings_a__b__Greeter__SayHello(helloRequest: GEN__greetings_a__b__HelloRequest!): GEN__greetings_a__b__HelloReply @grpc(body: "{{.args.helloRequest}}", method: "greetings_a.b.Greeter.SayHello") + """ + Sends a greeting + """ + GEN__greetings_b__c__Greeter__SayHello(helloRequest: GEN__greetings__HelloRequest!): GEN__greetings__HelloReply @grpc(body: "{{.args.helloRequest}}", method: "greetings_b.c.Greeter.SayHello") + GEN__news__NewsService__AddNews(news: GEN__news__NewsInput!): GEN__news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") + GEN__news__NewsService__DeleteNews(newsId: GEN__news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") + GEN__news__NewsService__EditNews(news: GEN__news__NewsInput!): GEN__news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") + GEN__news__NewsService__GetAllNews: GEN__news__NewsList @grpc(method: "news.NewsService.GetAllNews") + GEN__news__NewsService__GetMultipleNews(multipleNewsId: GEN__news__MultipleNewsId!): GEN__news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") + GEN__news__NewsService__GetNews(newsId: GEN__news__NewsId!): GEN__news__News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") } diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto_no_pkg_file.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto_no_pkg_file.snap index 42de05c795..29842976af 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto_no_pkg_file.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__from_proto_no_pkg_file.snap @@ -6,17 +6,17 @@ schema @server @upstream { query: Query } -type News { +type GEN__News { body: String id: Int postImage: String title: String } -type NewsList { - news: [News] +type GEN__NewsList { + news: [GEN__News] } type Query { - NewsService__GetAllNews: NewsList @grpc(method: "NewsService.GetAllNews") + GEN__NewsService__GetAllNews: GEN__NewsList @grpc(method: "NewsService.GetAllNews") } diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__greetings_proto_file.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__greetings_proto_file.snap index 28e4651333..1ded2729c0 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__greetings_proto_file.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__greetings_proto_file.snap @@ -6,14 +6,14 @@ schema @server @upstream { query: Query } -input greetings__HelloRequest { +input GEN__greetings__HelloRequest { name: String } -type Query { - greetings__Greeter__SayHello(helloRequest: greetings__HelloRequest!): greetings__HelloReply @grpc(body: "{{.args.helloRequest}}", method: "greetings.Greeter.SayHello") +type GEN__greetings__HelloReply { + message: String } -type greetings__HelloReply { - message: String +type Query { + GEN__greetings__Greeter__SayHello(helloRequest: GEN__greetings__HelloRequest!): GEN__greetings__HelloReply @grpc(body: "{{.args.helloRequest}}", method: "greetings.Greeter.SayHello") } diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__map_types.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__map_types.snap index 3b72b9a798..3ed658011e 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__map_types.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__map_types.snap @@ -6,14 +6,14 @@ schema @server @upstream { query: Query } -input map__MapRequest { +input GEN__map__MapRequest { map: JSON } -type Query { - map__MapService__GetMap(mapRequest: map__MapRequest!): map__MapResponse @grpc(body: "{{.args.mapRequest}}", method: "map.MapService.GetMap") +type GEN__map__MapResponse { + map: JSON } -type map__MapResponse { - map: JSON +type Query { + GEN__map__MapService__GetMap(mapRequest: GEN__map__MapRequest!): GEN__map__MapResponse @grpc(body: "{{.args.mapRequest}}", method: "map.MapService.GetMap") } diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__movies.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__movies.snap index 9f94680191..7deb630559 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__movies.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__movies.snap @@ -31,7 +31,7 @@ with 0 nanoseconds should be encoded in JSON format as "3s", while 3 seconds an 1 nanosecond should be expressed in JSON format as "3.000000001s", and 3 seconds and 1 microsecond should be expressed in JSON format as "3.000001s". """ -input google__protobuf__DurationInput { +input GEN__google__protobuf__DurationInput { """ Signed fractions of a second at nanosecond resolution of the span of time. Durations less than one second are represented with a 0 `seconds` field and a positive or @@ -51,7 +51,7 @@ input google__protobuf__DurationInput { """ Wrapper message for `int32`. The JSON representation for `Int32Value` is JSON number. """ -input google__protobuf__Int32ValueInput { +input GEN__google__protobuf__Int32ValueInput { """ The int32 value. """ @@ -62,7 +62,7 @@ input google__protobuf__Int32ValueInput { Wrapper message for `string`. The JSON representation for `StringValue` is JSON string. """ -input google__protobuf__StringValue { +input GEN__google__protobuf__StringValue { """ The string value. """ @@ -111,7 +111,7 @@ with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can u the Joda Time's [`ISODateTimeFormat.dateTime()`]( http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D ) to obtain a formatter capable of generating timestamps in this format. """ -input google__protobuf__TimestampInput { +input GEN__google__protobuf__TimestampInput { """ Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. @@ -128,49 +128,49 @@ input google__protobuf__TimestampInput { """ movie message payload """ -input movies__MovieInput { +input GEN__movies__MovieInput { """ list of cast """ cast: [String] - duration: google__protobuf__DurationInput - genre: movies__Genre + duration: GEN__google__protobuf__DurationInput + genre: GEN__movies__Genre name: String rating: Float """ SubMovie reference """ - subMovie: movies__Movie__SubMovieInput - time: google__protobuf__TimestampInput - year: google__protobuf__Int32ValueInput + subMovie: GEN__movies__Movie__SubMovieInput + time: GEN__google__protobuf__TimestampInput + year: GEN__google__protobuf__Int32ValueInput } -input movies__MovieRequest { - movie: movies__MovieInput +input GEN__movies__MovieRequest { + movie: GEN__movies__MovieInput } """ This is a comment for submovie """ -input movies__Movie__SubMovieInput { +input GEN__movies__Movie__SubMovieInput { """ This is a comment for movie format in submovie """ - format: movies__Movie__MovieFormat + format: GEN__movies__Movie__MovieFormat """ This is a comment for sub_rating """ subRating: Float } -input movies__SearchByCastRequest { - castName: google__protobuf__StringValue +input GEN__movies__SearchByCastRequest { + castName: GEN__google__protobuf__StringValue } """ This is a comment for Genre enum """ -enum movies__Genre { +enum GEN__movies__Genre { "" This is a comment for DRAMA variant "" @@ -185,32 +185,13 @@ enum movies__Genre { """ Represents the format in which a movie can be released """ -enum movies__Movie__MovieFormat { +enum GEN__movies__Movie__MovieFormat { "" The movie is released in IMAX format "" IMAX } -type Query { - """ - get all movies - """ - movies__AnotherExample__GetMovies(movieRequest: movies__MovieRequest!): movies__MoviesResult @grpc(body: "{{.args.movieRequest}}", method: "movies.AnotherExample.GetMovies") - """ - search movies by the name of the cast - """ - movies__AnotherExample__SearchMoviesByCast(searchByCastRequest: movies__SearchByCastRequest!): movies__Movie @grpc(body: "{{.args.searchByCastRequest}}", method: "movies.AnotherExample.SearchMoviesByCast") - """ - get all movies - """ - movies__Example__GetMovies(movieRequest: movies__MovieRequest!): movies__MoviesResult @grpc(body: "{{.args.movieRequest}}", method: "movies.Example.GetMovies") - """ - search movies by the name of the cast - """ - movies__Example__SearchMoviesByCast(searchByCastRequest: movies__SearchByCastRequest!): movies__Movie @grpc(body: "{{.args.searchByCastRequest}}", method: "movies.Example.SearchMoviesByCast") -} - """ A Duration represents a signed, fixed-length span of time represented as a count of seconds and fractions of seconds at nanosecond @@ -258,7 +239,7 @@ type Query { be expressed in JSON format as "3.000000001s", and 3 seconds and 1 microsecond should be expressed in JSON format as "3.000001s". """ -type google__protobuf__Duration { +type GEN__google__protobuf__Duration { """ Signed fractions of a second at nanosecond resolution of the span of time. Durations less than one second are represented with a 0 @@ -280,7 +261,7 @@ type google__protobuf__Duration { Wrapper message for `int32`. The JSON representation for `Int32Value` is JSON number. """ -type google__protobuf__Int32Value { +type GEN__google__protobuf__Int32Value { """ The int32 value. """ @@ -355,7 +336,7 @@ type google__protobuf__Int32Value { http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D ) to obtain a formatter capable of generating timestamps in this format. """ -type google__protobuf__Timestamp { +type GEN__google__protobuf__Timestamp { """ Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values @@ -374,31 +355,31 @@ type google__protobuf__Timestamp { """ movie message payload """ -type movies__Movie { +type GEN__movies__Movie { """ list of cast """ cast: [String] - duration: google__protobuf__Duration - genre: movies__Genre + duration: GEN__google__protobuf__Duration + genre: GEN__movies__Genre name: String rating: Float """ SubMovie reference """ - subMovie: movies__Movie__SubMovie - time: google__protobuf__Timestamp - year: google__protobuf__Int32Value + subMovie: GEN__movies__Movie__SubMovie + time: GEN__google__protobuf__Timestamp + year: GEN__google__protobuf__Int32Value } """ This is a comment for submovie """ -type movies__Movie__SubMovie { +type GEN__movies__Movie__SubMovie { """ This is a comment for movie format in submovie """ - format: movies__Movie__MovieFormat + format: GEN__movies__Movie__MovieFormat """ This is a comment for sub_rating """ @@ -408,9 +389,28 @@ type movies__Movie__SubMovie { """ movie result message, contains list of movies """ -type movies__MoviesResult { +type GEN__movies__MoviesResult { """ list of movies """ - result: [movies__Movie] + result: [GEN__movies__Movie] +} + +type Query { + """ + get all movies + """ + GEN__movies__AnotherExample__GetMovies(movieRequest: GEN__movies__MovieRequest!): GEN__movies__MoviesResult @grpc(body: "{{.args.movieRequest}}", method: "movies.AnotherExample.GetMovies") + """ + search movies by the name of the cast + """ + GEN__movies__AnotherExample__SearchMoviesByCast(searchByCastRequest: GEN__movies__SearchByCastRequest!): GEN__movies__Movie @grpc(body: "{{.args.searchByCastRequest}}", method: "movies.AnotherExample.SearchMoviesByCast") + """ + get all movies + """ + GEN__movies__Example__GetMovies(movieRequest: GEN__movies__MovieRequest!): GEN__movies__MoviesResult @grpc(body: "{{.args.movieRequest}}", method: "movies.Example.GetMovies") + """ + search movies by the name of the cast + """ + GEN__movies__Example__SearchMoviesByCast(searchByCastRequest: GEN__movies__SearchByCastRequest!): GEN__movies__Movie @grpc(body: "{{.args.searchByCastRequest}}", method: "movies.Example.SearchMoviesByCast") } diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__nested_types.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__nested_types.snap index 6939846bfc..38115b5b19 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__nested_types.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__nested_types.snap @@ -6,31 +6,31 @@ schema @server @upstream { query: Query } -input nested__types__Result__Nested__VeryNestedInput { +input GEN__nested__types__Result__Nested__VeryNestedInput { description: String } -enum nested__types__Result__NestedEnum { +enum GEN__nested__types__Result__NestedEnum { VALUE_0 VALUE_1 VALUE_2 } -type Query { - nested__types__Example__Get(veryNested: nested__types__Result__Nested__VeryNestedInput!): nested__types__Result @grpc(body: "{{.args.veryNested}}", method: "nested.types.Example.Get") -} - -type nested__types__Result { - nestedEnum: nested__types__Result__NestedEnum - nestedUsage: nested__types__Result__Nested +type GEN__nested__types__Result { + nestedEnum: GEN__nested__types__Result__NestedEnum + nestedUsage: GEN__nested__types__Result__Nested value: String } -type nested__types__Result__Nested { - info: nested__types__Result__Nested__VeryNested +type GEN__nested__types__Result__Nested { + info: GEN__nested__types__Result__Nested__VeryNested movie: String } -type nested__types__Result__Nested__VeryNested { +type GEN__nested__types__Result__Nested__VeryNested { description: String } + +type Query { + GEN__nested__types__Example__Get(veryNested: GEN__nested__types__Result__Nested__VeryNestedInput!): GEN__nested__types__Result @grpc(body: "{{.args.veryNested}}", method: "nested.types.Example.Get") +} diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__oneof_types.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__oneof_types.snap index 098e30b2e2..997c16d271 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__oneof_types.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__oneof_types.snap @@ -6,101 +6,101 @@ schema @server @upstream { query: Query } -input oneof__CommandInput { +input GEN__oneof__CommandInput { command: String } -input oneof__PayloadInput { +input GEN__oneof__PayloadInput { payload: String } -input oneof__Request__Var0__Var { - payload: oneof__PayloadInput! +input GEN__oneof__Request__Var0__Var { + payload: GEN__oneof__PayloadInput! usual: String } -input oneof__Request__Var0__Var0 { +input GEN__oneof__Request__Var0__Var0 { flag: Boolean! - payload: oneof__PayloadInput! + payload: GEN__oneof__PayloadInput! usual: String } -input oneof__Request__Var0__Var1 { - optPayload: oneof__PayloadInput! - payload: oneof__PayloadInput! +input GEN__oneof__Request__Var0__Var1 { + optPayload: GEN__oneof__PayloadInput! + payload: GEN__oneof__PayloadInput! usual: String } -input oneof__Request__Var1__Var { - command: oneof__CommandInput! +input GEN__oneof__Request__Var1__Var { + command: GEN__oneof__CommandInput! usual: String } -input oneof__Request__Var1__Var0 { - command: oneof__CommandInput! +input GEN__oneof__Request__Var1__Var0 { + command: GEN__oneof__CommandInput! flag: Boolean! usual: String } -input oneof__Request__Var1__Var1 { - command: oneof__CommandInput! - optPayload: oneof__PayloadInput! +input GEN__oneof__Request__Var1__Var1 { + command: GEN__oneof__CommandInput! + optPayload: GEN__oneof__PayloadInput! usual: String } -input oneof__Request__Var__Var { +input GEN__oneof__Request__Var__Var { usual: String } -input oneof__Request__Var__Var0 { +input GEN__oneof__Request__Var__Var0 { flag: Boolean! usual: String } -input oneof__Request__Var__Var1 { - optPayload: oneof__PayloadInput! +input GEN__oneof__Request__Var__Var1 { + optPayload: GEN__oneof__PayloadInput! usual: String } -interface oneof__Request__Interface { +interface GEN__oneof__Request__Interface { usual: String } -interface oneof__Response__Interface { +interface GEN__oneof__Response__Interface { usual: Int } -union oneof__Request = oneof__Request__Var0__Var | oneof__Request__Var0__Var0 | oneof__Request__Var0__Var1 | oneof__Request__Var1__Var | oneof__Request__Var1__Var0 | oneof__Request__Var1__Var1 | oneof__Request__Var__Var | oneof__Request__Var__Var0 | oneof__Request__Var__Var1 +union GEN__oneof__Request = GEN__oneof__Request__Var0__Var | GEN__oneof__Request__Var0__Var0 | GEN__oneof__Request__Var0__Var1 | GEN__oneof__Request__Var1__Var | GEN__oneof__Request__Var1__Var0 | GEN__oneof__Request__Var1__Var1 | GEN__oneof__Request__Var__Var | GEN__oneof__Request__Var__Var0 | GEN__oneof__Request__Var__Var1 -union oneof__Response = oneof__Response__Var | oneof__Response__Var0 | oneof__Response__Var1 | oneof__Response__Var2 +union GEN__oneof__Response = GEN__oneof__Response__Var | GEN__oneof__Response__Var0 | GEN__oneof__Response__Var1 | GEN__oneof__Response__Var2 -type Query { - oneof__OneOfService__GetOneOf(request: oneof__Request!): oneof__Response @grpc(body: "{{.args.request}}", method: "oneof.OneOfService.GetOneOf") -} - -type oneof__Command { +type GEN__oneof__Command { command: String } -type oneof__Payload { +type GEN__oneof__Payload { payload: String } -type oneof__Response__Var implements oneof__Response__Interface { +type GEN__oneof__Response__Var implements GEN__oneof__Response__Interface { usual: Int } -type oneof__Response__Var0 implements oneof__Response__Interface { - payload: oneof__Payload! +type GEN__oneof__Response__Var0 implements GEN__oneof__Response__Interface { + payload: GEN__oneof__Payload! usual: Int } -type oneof__Response__Var1 implements oneof__Response__Interface { - command: oneof__Command! +type GEN__oneof__Response__Var1 implements GEN__oneof__Response__Interface { + command: GEN__oneof__Command! usual: Int } -type oneof__Response__Var2 implements oneof__Response__Interface { +type GEN__oneof__Response__Var2 implements GEN__oneof__Response__Interface { response: String! usual: Int } + +type Query { + GEN__oneof__OneOfService__GetOneOf(request: GEN__oneof__Request!): GEN__oneof__Response @grpc(body: "{{.args.request}}", method: "oneof.OneOfService.GetOneOf") +} diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__optional_fields.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__optional_fields.snap index 049fb1c5e9..a8631cd06d 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__optional_fields.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__optional_fields.snap @@ -6,18 +6,18 @@ schema @server @upstream { query: Query } -input type__TypeInput { +input GEN__type__TypeInput { id: Int idOpt: Int - nested: type__Type__NestedInput - nestedOpt: type__Type__NestedInput - nestedRep: [type__Type__NestedInput] + nested: GEN__type__Type__NestedInput + nestedOpt: GEN__type__Type__NestedInput + nestedRep: [GEN__type__Type__NestedInput] num: [Float] str: String strOpt: String } -input type__Type__NestedInput { +input GEN__type__Type__NestedInput { id: Int idOpt: Int num: [Float] @@ -25,31 +25,31 @@ input type__Type__NestedInput { strOpt: String } -enum type__Status { +enum GEN__type__Status { FIRST SECOND UNSPECIFIED } -type Query { - type__TypeService__Get(type: type__TypeInput!): type__Type @grpc(body: "{{.args.type}}", method: "type.TypeService.Get") -} - -type type__Type { +type GEN__type__Type { id: Int idOpt: Int - nested: type__Type__Nested - nestedOpt: type__Type__Nested - nestedRep: [type__Type__Nested] + nested: GEN__type__Type__Nested + nestedOpt: GEN__type__Type__Nested + nestedRep: [GEN__type__Type__Nested] num: [Float] str: String strOpt: String } -type type__Type__Nested { +type GEN__type__Type__Nested { id: Int idOpt: Int num: [Float] str: String strOpt: String } + +type Query { + GEN__type__TypeService__Get(type: GEN__type__TypeInput!): GEN__type__Type @grpc(body: "{{.args.type}}", method: "type.TypeService.Get") +} diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__required_types.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__required_types.snap index 3b22841f5d..a600c6428b 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__required_types.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__required_types.snap @@ -6,14 +6,10 @@ schema @server @upstream { query: Query } -type Query { - person__PersonService__GetPerson: person__Person @grpc(method: "person.PersonService.GetPerson") -} - """ Defines a person """ -type person__Person { +type GEN__person__Person { email: String id: Int! name: String! @@ -21,6 +17,10 @@ type person__Person { stringMap: JSON } +type Query { + GEN__person__PersonService__GetPerson: GEN__person__Person @grpc(method: "person.PersonService.GetPerson") +} + """ Defines a phone number """ diff --git a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__scalar_types.snap b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__scalar_types.snap index 55770252e4..1cd6c1f237 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__scalar_types.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__from_proto__test__scalar_types.snap @@ -6,7 +6,7 @@ schema @server @upstream { query: Query } -input scalars__ItemInput { +input GEN__scalars__ItemInput { boolean: Boolean bytesType: Bytes doubleNum: Float @@ -24,11 +24,7 @@ input scalars__ItemInput { uinteger64: UInt64 } -type Query { - scalars__Example__Get(item: scalars__ItemInput!): scalars__Result @grpc(body: "{{.args.item}}", method: "scalars.Example.Get") -} - -type scalars__Item { +type GEN__scalars__Item { boolean: Boolean bytesType: Bytes doubleNum: Float @@ -46,6 +42,10 @@ type scalars__Item { uinteger64: UInt64 } -type scalars__Result { - result: [scalars__Item] +type GEN__scalars__Result { + result: [GEN__scalars__Item] +} + +type Query { + GEN__scalars__Example__Get(item: GEN__scalars__ItemInput!): GEN__scalars__Result @grpc(body: "{{.args.item}}", method: "scalars.Example.Get") } diff --git a/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap b/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap index 991be951e4..c102b794a6 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_combined_config.snap @@ -6,15 +6,11 @@ schema @server(hostname: "0.0.0.0", port: 8000) @upstream(allowedHeaders: ["auth query: Query } -input Id { - id: Int -} - -input news__MultipleNewsId { +input GEN__news__MultipleNewsId { ids: [Id] } -input news__NewsInput { +input GEN__news__NewsInput { body: String id: Int postImage: String @@ -22,6 +18,10 @@ input news__NewsInput { title: String } +input Id { + id: Int +} + enum Status { DELETED DRAFT @@ -43,6 +43,10 @@ type Comment { title: String! @expr(body: "{{.value.email}}: {{.value.name}}") } +type GEN__news__NewsList { + news: [News] +} + type InCompatibleProperty { campaignTemplates: JSON colors: [JSON] @@ -56,10 +60,6 @@ type News { title: String } -type NewsNewsServiceGetMultipleNew { - news: [News] -} - type Photo { albumId: Int! combinedId: String! @expr(body: "Album: {{.value.albumId}}, photo: {{.value.id}}") @@ -78,13 +78,13 @@ type Post { } type Query { + GEN__news__NewsService__AddNews(news: GEN__news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") + GEN__news__NewsService__DeleteNews(newsId: Id!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") + GEN__news__NewsService__EditNews(news: GEN__news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") + GEN__news__NewsService__GetAllNews: GEN__news__NewsList @grpc(method: "news.NewsService.GetAllNews") + GEN__news__NewsService__GetMultipleNews(multipleNewsId: GEN__news__MultipleNewsId!): GEN__news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") + GEN__news__NewsService__GetNews(newsId: Id!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") inCompatibleProperties: InCompatibleProperty @http(path: "/") - news__NewsService__AddNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: Id!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") - news__NewsService__EditNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") - news__NewsService__GetAllNews: NewsNewsServiceGetMultipleNew @grpc(method: "news.NewsService.GetAllNews") - news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): NewsNewsServiceGetMultipleNew @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: Id!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") post(id: Int! = 1): Post @http(path: "/posts/{{.args.id}}") posts: [Post] @http(path: "/posts?_limit=11") user(id: Int!): User @http(path: "/users/{{.args.id}}") diff --git a/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_config_from_proto.snap b/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_config_from_proto.snap index baff7debf6..165aa35022 100644 --- a/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_config_from_proto.snap +++ b/src/core/generator/snapshots/tailcall__core__generator__generator__test__should_generate_config_from_proto.snap @@ -6,45 +6,45 @@ schema @server @upstream @link(src: "../../../tailcall-fixtures/fixtures/protobu query: Query } -input news__MultipleNewsId { - ids: [news__NewsId] +input GEN__news__MultipleNewsId { + ids: [GEN__news__NewsId] } -input news__NewsId { +input GEN__news__NewsId { id: Int } -input news__NewsInput { +input GEN__news__NewsInput { body: String id: Int postImage: String - status: news__Status + status: GEN__news__Status title: String } -enum news__Status { +enum GEN__news__Status { DELETED DRAFT PUBLISHED } -type Query { - news__NewsService__AddNews(news: news__NewsInput!): news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") - news__NewsService__EditNews(news: news__NewsInput!): news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") - news__NewsService__GetAllNews: news__NewsList @grpc(method: "news.NewsService.GetAllNews") - news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: news__NewsId!): news__News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") -} - -type news__News { +type GEN__news__News { body: String id: Int postImage: String - status: news__Status + status: GEN__news__Status title: String } -type news__NewsList { - news: [news__News] +type GEN__news__NewsList { + news: [GEN__news__News] +} + +type Query { + GEN__news__NewsService__AddNews(news: GEN__news__NewsInput!): GEN__news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") + GEN__news__NewsService__DeleteNews(newsId: GEN__news__NewsId!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") + GEN__news__NewsService__EditNews(news: GEN__news__NewsInput!): GEN__news__News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") + GEN__news__NewsService__GetAllNews: GEN__news__NewsList @grpc(method: "news.NewsService.GetAllNews") + GEN__news__NewsService__GetMultipleNews(multipleNewsId: GEN__news__MultipleNewsId!): GEN__news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") + GEN__news__NewsService__GetNews(newsId: GEN__news__NewsId!): GEN__news__News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") } diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__add_cart.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__add_cart.json.snap index 7811cf43a2..05af5a8903 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__add_cart.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__add_cart.json.snap @@ -6,21 +6,17 @@ schema @server @upstream { mutation: Mutation } -input T3 { +input GEN__3 { id: Int quantity: Int } -input T4 { - products: [T3] +input GEN__4 { + products: [GEN__3] userId: Int } -type Mutation { - addCart(code: String, addCartInput: T4): T2 @http(baseURL: "https://dummyjson.com", body: "{{.args.addCartInput}}", method: "POST", path: "/carts/add", query: [{key: "code", value: "{{.args.code}}"}]) -} - -type T1 { +type GEN__1 { discountPercentage: Int discountedPrice: Int id: Int @@ -31,12 +27,16 @@ type T1 { total: Int } -type T2 { +type GEN__2 { discountedTotal: Int id: Int - products: [T1] + products: [GEN__1] total: Int totalProducts: Int totalQuantity: Int userId: Int } + +type Mutation { + addCart(code: String, GEN__Input1: GEN__4): GEN__2 @http(baseURL: "https://dummyjson.com", body: "{{.args.GEN__Input1}}", method: "POST", path: "/carts/add", query: [{key: "code", value: "{{.args.code}}"}]) +} diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__boolean.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__boolean.json.snap index 6d93ef0206..e4615cd9e3 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__boolean.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__boolean.json.snap @@ -7,5 +7,5 @@ schema @server @upstream { } type Query { - userStatus(p1: Int!): Boolean @http(baseURL: "https://example.com", path: "/user/{{.args.p1}}/online") + userStatus(GEN__1: Int!): Boolean @http(baseURL: "https://example.com", path: "/user/{{.args.GEN__1}}/online") } diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__create_post.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__create_post.json.snap index 567b480b64..78312f50cf 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__create_post.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__create_post.json.snap @@ -6,19 +6,19 @@ schema @server @upstream { mutation: Mutation } -input T2 { +input GEN__2 { body: String title: String userId: Int } -type Mutation { - createPost(createPostInput: T2): T1 @http(baseURL: "https://jsonplaceholder.typicode.com", body: "{{.args.createPostInput}}", method: "POST", path: "/posts") -} - -type T1 { +type GEN__1 { body: String id: Int title: String userId: Int } + +type Mutation { + createPost(GEN__Input1: GEN__2): GEN__1 @http(baseURL: "https://jsonplaceholder.typicode.com", body: "{{.args.GEN__Input1}}", method: "POST", path: "/posts") +} diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__create_product.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__create_product.json.snap index ab59449fd6..9426007dfe 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__create_product.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__create_product.json.snap @@ -6,7 +6,7 @@ schema @server @upstream { mutation: Mutation } -input T2 { +input GEN__2 { category: String description: String image: String @@ -14,11 +14,7 @@ input T2 { title: String } -type Mutation { - createProduct(createProductInput: T2): T1 @http(baseURL: "https://fakestoreapi.com", body: "{{.args.createProductInput}}", method: "POST", path: "/products") -} - -type T1 { +type GEN__1 { category: String description: String id: Int @@ -26,3 +22,7 @@ type T1 { price: Int title: String } + +type Mutation { + createProduct(GEN__Input1: GEN__2): GEN__1 @http(baseURL: "https://fakestoreapi.com", body: "{{.args.GEN__Input1}}", method: "POST", path: "/products") +} diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__create_user.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__create_user.json.snap index e4c2954fb0..baad97357a 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__create_user.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__create_user.json.snap @@ -6,7 +6,7 @@ schema @server @upstream { mutation: Mutation } -input T2 { +input GEN__2 { email: String name: String phone: String @@ -14,11 +14,7 @@ input T2 { website: String } -type Mutation { - createPost(createPostInput: T2): T1 @http(baseURL: "https://jsonplaceholder.typicode.com", body: "{{.args.createPostInput}}", method: "POST", path: "/posts") -} - -type T1 { +type GEN__1 { email: String id: Int name: String @@ -26,3 +22,7 @@ type T1 { username: String website: String } + +type Mutation { + createPost(GEN__Input1: GEN__2): GEN__1 @http(baseURL: "https://jsonplaceholder.typicode.com", body: "{{.args.GEN__Input1}}", method: "POST", path: "/posts") +} diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__generate_auth_token.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__generate_auth_token.json.snap index 4e02b074a1..47bea6709f 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__generate_auth_token.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__generate_auth_token.json.snap @@ -6,17 +6,13 @@ schema @server @upstream { mutation: Mutation } -input T2 { +input GEN__2 { expiresInMins: Int password: String username: String } -type Mutation { - login(loginInput: T2): T1 @http(baseURL: "https://dummyjson.com", body: "{{.args.loginInput}}", method: "POST", path: "/auth/login") -} - -type T1 { +type GEN__1 { email: String firstName: String gender: String @@ -27,3 +23,7 @@ type T1 { token: String username: String } + +type Mutation { + login(GEN__Input1: GEN__2): GEN__1 @http(baseURL: "https://dummyjson.com", body: "{{.args.GEN__Input1}}", method: "POST", path: "/auth/login") +} diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__incompatible_properties.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__incompatible_properties.json.snap index e7cf286cff..a0b4217958 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__incompatible_properties.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__incompatible_properties.json.snap @@ -6,11 +6,11 @@ schema @server @upstream(allowedHeaders: ["authorization"]) { query: Query } -type Query { - inCompatibleProperties: T1 @http(baseURL: "https://example.com", path: "/") -} - -type T1 { +type GEN__1 { campaignTemplates: JSON colors: [JSON] } + +type Query { + inCompatibleProperties: GEN__1 @http(baseURL: "https://example.com", path: "/") +} diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__list.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__list.json.snap index 4c9dfc6ec5..dfc869e01a 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__list.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__list.json.snap @@ -6,12 +6,12 @@ schema @server @upstream { query: Query } -type Query { - userData: [T1] @http(baseURL: "https://example.com", path: "/users") -} - -type T1 { +type GEN__1 { adult: Boolean age: Int name: String } + +type Query { + userData: [GEN__1] @http(baseURL: "https://example.com", path: "/users") +} diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__nested_list.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__nested_list.json.snap index 82af15e8ce..e8749fa888 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__nested_list.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__nested_list.json.snap @@ -6,21 +6,21 @@ schema @server @upstream { query: Query } -type Query { - nestedUsers(children: Boolean): T3 @http(baseURL: "https://example.com", path: "/users", query: [{key: "children", value: "{{.args.children}}"}]) -} - -type T1 { +type GEN__1 { age: Int name: String } -type T2 { +type GEN__2 { age: Int - children: [T1] + children: [GEN__1] name: String } -type T3 { - people: [T2] +type GEN__3 { + people: [GEN__2] +} + +type Query { + nestedUsers(children: Boolean): GEN__3 @http(baseURL: "https://example.com", path: "/users", query: [{key: "children", value: "{{.args.children}}"}]) } diff --git a/src/core/generator/tests/snapshots/json_to_config_spec__nested_same_properties.json.snap b/src/core/generator/tests/snapshots/json_to_config_spec__nested_same_properties.json.snap index ec6e7906d9..e5b67d0cb5 100644 --- a/src/core/generator/tests/snapshots/json_to_config_spec__nested_same_properties.json.snap +++ b/src/core/generator/tests/snapshots/json_to_config_spec__nested_same_properties.json.snap @@ -6,24 +6,24 @@ schema @server @upstream { query: Query } -type Query { - nestedSameProperties: T4 @http(baseURL: "https://example.com", path: "/") -} - -type T1 { +type GEN__1 { age: Int } -type T2 { - container: T1 +type GEN__2 { + container: GEN__1 name: String } -type T3 { - container: T2 +type GEN__3 { + container: GEN__2 name: String } -type T4 { - container: T3 +type GEN__4 { + container: GEN__3 +} + +type Query { + nestedSameProperties: GEN__4 @http(baseURL: "https://example.com", path: "/") } diff --git a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_deezer.md.snap b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_deezer.md.snap index 3f1b48ca31..c929f58e18 100644 --- a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_deezer.md.snap +++ b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_deezer.md.snap @@ -7,16 +7,8 @@ schema @server @upstream(baseURL: "https://api.deezer.com") { } type Album { - cover: String - cover_big: String - cover_medium: String - cover_small: String - cover_xl: String - id: Int - md5_image: String - title: String - tracklist: String - type: String + data: [JSON] + total: Int } type Artist { @@ -34,11 +26,11 @@ type Artist { } type Chart { - albums: T167 - artists: T169 - playlists: T181 + albums: Album + artists: GEN__169 + playlists: GEN__181 podcasts: Podcast - tracks: T166 + tracks: GEN__166 } type Contributor { @@ -57,9 +49,16 @@ type Contributor { type: String } +type Creator { + id: Int + name: String + tracklist: String + type: String +} + type Datum { - album: Album - artist: T42 + album: GEN__M2 + artist: GEN__42 duration: Int explicit_content_cover: Int explicit_content_lyrics: Int @@ -78,65 +77,12 @@ type Datum { } type Editorial { - data: [T185] - total: Int -} - -type Genre { - data: [T5] -} - -type Playlist { - checksum: String - collaborative: Boolean - creation_date: String - creator: User - description: String - duration: Int - fans: Int - id: Int - is_loved_track: Boolean - link: String - md5_image: String - nb_tracks: Int - picture: String - picture_big: String - picture_medium: String - picture_small: String - picture_type: String - picture_xl: String - public: Boolean - share: String - title: String - tracklist: String - tracks: Track - type: String -} - -type Podcast { - data: [T182] - total: Int -} - -type Query { - album(p1: Int!): T39 @http(path: "/album/{{.args.p1}}") - artist(p1: Int!): T40 @http(path: "/artist/{{.args.p1}}") - chart: Chart @http(path: "/chart") - editorial: Editorial @http(path: "/editorial") - playlist(p1: Int!): Playlist @http(path: "/playlist/{{.args.p1}}") - search(q: String): Search @http(path: "/search", query: [{key: "q", value: "{{.args.q}}"}]) - track(p1: Int!): T4 @http(path: "/track/{{.args.p1}}") - user(p1: Int!): T187 @http(path: "/user/{{.args.p1}}") -} - -type Search { - data: [JSON] - next: String + data: [GEN__185] total: Int } -type T165 { - album: Album +type GEN__165 { + album: GEN__M2 artist: Artist duration: Int explicit_content_cover: Int @@ -154,17 +100,12 @@ type T165 { type: String } -type T166 { - data: [T165] +type GEN__166 { + data: [GEN__165] total: Int } -type T167 { - data: [JSON] - total: Int -} - -type T168 { +type GEN__168 { id: Int link: String name: String @@ -179,12 +120,12 @@ type T168 { type: String } -type T169 { - data: [T168] +type GEN__169 { + data: [GEN__168] total: Int } -type T180 { +type GEN__180 { checksum: String creation_date: String id: Int @@ -201,15 +142,15 @@ type T180 { title: String tracklist: String type: String - user: User + user: Creator } -type T181 { - data: [T180] +type GEN__181 { + data: [GEN__180] total: Int } -type T182 { +type GEN__182 { available: Boolean description: String fans: Int @@ -225,32 +166,18 @@ type T182 { type: String } -type T185 { - id: Int - name: String - picture: String - picture_big: String - picture_medium: String - picture_small: String - picture_xl: String - type: String -} - -type T187 { - country: String +type GEN__185 { id: Int - link: String name: String picture: String picture_big: String picture_medium: String picture_small: String picture_xl: String - tracklist: String type: String } -type T2 { +type GEN__2 { id: Int link: String name: String @@ -265,7 +192,7 @@ type T2 { type: String } -type T3 { +type GEN__3 { cover: String cover_big: String cover_medium: String @@ -280,9 +207,9 @@ type T3 { type: String } -type T37 { - album: Album - artist: User +type GEN__37 { + album: GEN__M2 + artist: Creator duration: Int explicit_content_cover: Int explicit_content_lyrics: Int @@ -299,12 +226,12 @@ type T37 { type: String } -type T38 { - data: [T37] +type GEN__38 { + data: [GEN__37] } -type T39 { - artist: T8 +type GEN__39 { + artist: GEN__8 available: Boolean contributors: [Contributor] cover: String @@ -329,14 +256,14 @@ type T39 { share: String title: String tracklist: String - tracks: T38 + tracks: GEN__38 type: String upc: String } -type T4 { - album: T3 - artist: T2 +type GEN__4 { + album: GEN__3 + artist: GEN__2 available_countries: [String] bpm: Int contributors: [Contributor] @@ -362,7 +289,7 @@ type T4 { type: String } -type T40 { +type GEN__40 { id: Int link: String name: String @@ -379,7 +306,7 @@ type T40 { type: String } -type T42 { +type GEN__42 { id: Int link: String name: String @@ -387,14 +314,14 @@ type T42 { type: String } -type T5 { +type GEN__5 { id: Int name: String picture: String type: String } -type T8 { +type GEN__8 { id: Int name: String picture: String @@ -406,14 +333,87 @@ type T8 { type: String } +type GEN__M2 { + cover: String + cover_big: String + cover_medium: String + cover_small: String + cover_xl: String + id: Int + md5_image: String + title: String + tracklist: String + type: String +} + +type Genre { + data: [GEN__5] +} + +type Playlist { + checksum: String + collaborative: Boolean + creation_date: String + creator: Creator + description: String + duration: Int + fans: Int + id: Int + is_loved_track: Boolean + link: String + md5_image: String + nb_tracks: Int + picture: String + picture_big: String + picture_medium: String + picture_small: String + picture_type: String + picture_xl: String + public: Boolean + share: String + title: String + tracklist: String + tracks: Track + type: String +} + +type Podcast { + data: [GEN__182] + total: Int +} + +type Query { + album(GEN__1: Int!): GEN__39 @http(path: "/album/{{.args.GEN__1}}") + artist(GEN__1: Int!): GEN__40 @http(path: "/artist/{{.args.GEN__1}}") + chart: Chart @http(path: "/chart") + editorial: Editorial @http(path: "/editorial") + playlist(GEN__1: Int!): Playlist @http(path: "/playlist/{{.args.GEN__1}}") + search(q: String): Search @http(path: "/search", query: [{key: "q", value: "{{.args.q}}"}]) + track(GEN__1: Int!): GEN__4 @http(path: "/track/{{.args.GEN__1}}") + user(GEN__1: Int!): User @http(path: "/user/{{.args.GEN__1}}") +} + +type Search { + data: [JSON] + next: String + total: Int +} + type Track { checksum: String data: [Datum] } type User { + country: String id: Int + link: String name: String + picture: String + picture_big: String + picture_medium: String + picture_small: String + picture_xl: String tracklist: String type: String } diff --git a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap index a0394a0dc8..359ae375b4 100644 --- a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap +++ b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_json_proto_mix_config.md.snap @@ -6,15 +6,11 @@ schema @server @upstream(baseURL: "https://jsonplaceholder.typicode.com") { query: Query } -input Id { - id: Int -} - -input news__MultipleNewsId @addField(name: "ids", path: ["ids", "id"]) { +input GEN__news__MultipleNewsId @addField(name: "ids", path: ["ids", "id"]) { ids: [Id]@omit } -input news__NewsInput { +input GEN__news__NewsInput { body: String id: Int postImage: String @@ -22,6 +18,10 @@ input news__NewsInput { title: String } +input Id { + id: Int +} + enum Status { DELETED DRAFT @@ -42,6 +42,10 @@ type Company { name: String } +type GEN__news__NewsList { + news: [News] +} + type Geo { lat: String lng: String @@ -55,17 +59,13 @@ type News { title: String } -type NewsNewsServiceGetMultipleNew { - news: [News] -} - type Query { - news__NewsService__AddNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") - news__NewsService__DeleteNews(newsId: Id!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") - news__NewsService__EditNews(news: news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") - news__NewsService__GetAllNews: NewsNewsServiceGetMultipleNew @grpc(method: "news.NewsService.GetAllNews") - news__NewsService__GetMultipleNews(multipleNewsId: news__MultipleNewsId!): NewsNewsServiceGetMultipleNew @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") - news__NewsService__GetNews(newsId: Id!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") + GEN__news__NewsService__AddNews(news: GEN__news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.AddNews") + GEN__news__NewsService__DeleteNews(newsId: Id!): Empty @grpc(body: "{{.args.newsId}}", method: "news.NewsService.DeleteNews") + GEN__news__NewsService__EditNews(news: GEN__news__NewsInput!): News @grpc(body: "{{.args.news}}", method: "news.NewsService.EditNews") + GEN__news__NewsService__GetAllNews: GEN__news__NewsList @grpc(method: "news.NewsService.GetAllNews") + GEN__news__NewsService__GetMultipleNews(multipleNewsId: GEN__news__MultipleNewsId!): GEN__news__NewsList @grpc(body: "{{.args.multipleNewsId}}", method: "news.NewsService.GetMultipleNews") + GEN__news__NewsService__GetNews(newsId: Id!): News @grpc(body: "{{.args.newsId}}", method: "news.NewsService.GetNews") users: [User] @http(path: "/users") } diff --git a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_jsonplaceholder.md.snap b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_jsonplaceholder.md.snap index b0d6a758e3..12b65cd93f 100644 --- a/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_jsonplaceholder.md.snap +++ b/tests/cli/snapshots/cli_spec__test__generator_spec__tests__cli__fixtures__generator__gen_jsonplaceholder.md.snap @@ -49,16 +49,16 @@ type Post { } type Query { - comment(p1: Int!): Comment @http(path: "/comments/{{.args.p1}}") + comment(GEN__1: Int!): Comment @http(path: "/comments/{{.args.GEN__1}}") comments: [Comment] @http(path: "/comments") - photo(p1: Int!): Photo @http(path: "/photos/{{.args.p1}}") + photo(GEN__1: Int!): Photo @http(path: "/photos/{{.args.GEN__1}}") photos: [Photo] @http(path: "/photos") - post(p1: Int!): Post @http(path: "/posts/{{.args.p1}}") + post(GEN__1: Int!): Post @http(path: "/posts/{{.args.GEN__1}}") postComments(postId: Int): [Comment] @http(path: "/comments", query: [{key: "postId", value: "{{.args.postId}}"}]) posts: [Post] @http(path: "/posts") - todo(p1: Int!): Todo @http(path: "/todos/{{.args.p1}}") + todo(GEN__1: Int!): Todo @http(path: "/todos/{{.args.GEN__1}}") todos: [Todo] @http(path: "/todos") - user(p1: Int!): User @http(path: "/users/{{.args.p1}}") + user(GEN__1: Int!): User @http(path: "/users/{{.args.GEN__1}}") users: [User] @http(path: "/users") } From cdad55add60e8af7ccdf6dec7991a3ca2b8917d8 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 10:29:16 +0530 Subject: [PATCH 59/77] chore: fix failing tests --- src/core/generator/json/http_directive_generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/generator/json/http_directive_generator.rs b/src/core/generator/json/http_directive_generator.rs index 4d45cd6ad4..51c5584555 100644 --- a/src/core/generator/json/http_directive_generator.rs +++ b/src/core/generator/json/http_directive_generator.rs @@ -211,7 +211,7 @@ mod test { ] .into_iter() .collect::>(); - assert_eq!("/foo/{{.args.p2}}/bar/{{.args.p1}}", http.path); + assert_eq!("/foo/{{.args.GEN__2}}/bar/{{.args.GEN__1}}", http.path); assert_eq!(test_args, args); } } From 57d8943ea8c5b0bd5da8bd43b9d9b3c0776ad8a2 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 10:33:46 +0530 Subject: [PATCH 60/77] chore: add discord failure hook --- .github/workflows/discord.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/discord.yml diff --git a/.github/workflows/discord.yml b/.github/workflows/discord.yml new file mode 100644 index 0000000000..eb4f3f62d9 --- /dev/null +++ b/.github/workflows/discord.yml @@ -0,0 +1,24 @@ +name: Notify on CI Failure + +on: + push: + branches: + - main + workflow_run: + workflows: ["*"] + types: + - completed + +jobs: + notify: + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + runs-on: ubuntu-latest + steps: + - name: Send Discord Notification + env: + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + run: | + curl -H "Content-Type: application/json" \ + -X POST \ + -d '{"content": "CI Failure Detected on Main Branch :x:"}' \ + $DISCORD_WEBHOOK_URL From 0e6574a01c7c5ac3577d906497e45da368440290 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 10:40:39 +0530 Subject: [PATCH 61/77] chore: update discord error message --- .github/workflows/discord.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/discord.yml b/.github/workflows/discord.yml index eb4f3f62d9..05d708a51f 100644 --- a/.github/workflows/discord.yml +++ b/.github/workflows/discord.yml @@ -1,17 +1,14 @@ -name: Notify on CI Failure +name: Notify on Workflow Failure on: - push: - branches: - - main workflow_run: - workflows: ["*"] + workflows: ["*"] # This listens to all workflows types: - completed jobs: notify: - if: ${{ github.event.workflow_run.conclusion == 'failure' }} + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.head_branch == 'main' }} runs-on: ubuntu-latest steps: - name: Send Discord Notification @@ -20,5 +17,15 @@ jobs: run: | curl -H "Content-Type: application/json" \ -X POST \ - -d '{"content": "CI Failure Detected on Main Branch :x:"}' \ + -d '{ + "content": "**:x: Workflow Failure Detected on Main Branch**", + "embeds": [ + { + "title": "Workflow: '${{ github.event.workflow_run.name }}'", + "description": "The workflow **${{ github.event.workflow_run.name }}** has failed on the main branch.", + "url": "${{ github.event.workflow_run.html_url }}", + "color": 15158332 + } + ] + }' \ $DISCORD_WEBHOOK_URL From 8c7112de0ac6c9b56891d3d99f620df7940c3894 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 10:47:22 +0530 Subject: [PATCH 62/77] chore: update discord hook --- .github/workflows/discord.yml | 45 +++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/.github/workflows/discord.yml b/.github/workflows/discord.yml index 05d708a51f..c09eb7677f 100644 --- a/.github/workflows/discord.yml +++ b/.github/workflows/discord.yml @@ -1,4 +1,4 @@ -name: Notify on Workflow Failure +name: Notify on Workflow Failure and Fix on: workflow_run: @@ -8,19 +8,31 @@ on: jobs: notify: - if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.head_branch == 'main' }} runs-on: ubuntu-latest steps: - - name: Send Discord Notification + - name: Check Previous Run Status + id: previous_run + run: | + echo "Checking previous run status..." + PREVIOUS_STATUS=$(gh run list --limit 2 --branch main --workflow "${{ github.event.workflow_run.name }}" --json conclusion --jq '.[1].conclusion') + echo "previous_status=$PREVIOUS_STATUS" >> $GITHUB_ENV + + - name: Send Discord Notification on Failure + if: ${{ github.event.workflow_run.conclusion == 'failure' }} env: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} run: | curl -H "Content-Type: application/json" \ -X POST \ -d '{ - "content": "**:x: Workflow Failure Detected on Main Branch**", + "content": "**Workflow Failure Detected on Main Branch** :x:", "embeds": [ { + "author": { + "name": "GitHub Actions Bot", + "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", + "url": "https://github.com/${{ github.repository }}" + }, "title": "Workflow: '${{ github.event.workflow_run.name }}'", "description": "The workflow **${{ github.event.workflow_run.name }}** has failed on the main branch.", "url": "${{ github.event.workflow_run.html_url }}", @@ -29,3 +41,28 @@ jobs: ] }' \ $DISCORD_WEBHOOK_URL + + - name: Send Discord Notification on Fix + if: ${{ github.event.workflow_run.conclusion == 'success' && env.previous_status == 'failure' }} + env: + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + run: | + curl -H "Content-Type: application/json" \ + -X POST \ + -d '{ + "content": "**Workflow Fixed on Main Branch** :white_check_mark:", + "embeds": [ + { + "author": { + "name": "GitHub Actions Bot", + "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", + "url": "https://github.com/${{ github.repository }}" + }, + "title": "Workflow: '${{ github.event.workflow_run.name }}' Fixed", + "description": "The workflow **${{ github.event.workflow_run.name }}** has been fixed on the main branch.", + "url": "${{ github.event.workflow_run.html_url }}", + "color": 3066993 + } + ] + }' \ + $DISCORD_WEBHOOK_URL From e0216b30764dead6ce13073e6745bd26901b9b85 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 10:49:48 +0530 Subject: [PATCH 63/77] chore: fix failing tests --- src/core/generator/json/http_directive_generator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/generator/json/http_directive_generator.rs b/src/core/generator/json/http_directive_generator.rs index 51c5584555..9c60a809b6 100644 --- a/src/core/generator/json/http_directive_generator.rs +++ b/src/core/generator/json/http_directive_generator.rs @@ -206,8 +206,8 @@ mod test { .map(|(name, arg)| (name.to_string(), arg.type_of.name().to_owned())) .collect::>(); let test_args = vec![ - ("p1".to_string(), "Int".to_string()), - ("p2".to_string(), "String".to_string()), + ("GEN__1".to_string(), "Int".to_string()), + ("GEN__2".to_string(), "String".to_string()), ] .into_iter() .collect::>(); From 574adba46ec08fe796fec7d8badb8cffc4a9457b Mon Sep 17 00:00:00 2001 From: Amit Singh Date: Sun, 22 Sep 2024 14:24:31 +0530 Subject: [PATCH 64/77] fix(deps): remove unused openssl (#2881) --- Cargo.lock | 156 +++++------------------------------- examples/lint.sh | 20 ++--- tailcall-tracker/Cargo.toml | 10 ++- 3 files changed, 34 insertions(+), 152 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df57ba56b0..8bed6eafcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1601,21 +1601,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2413,19 +2398,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper 0.14.30", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "hyper-util" version = "0.1.8" @@ -3175,23 +3147,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3381,60 +3336,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.3.2+3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" -dependencies = [ - "cc", -] - -[[package]] -name = "openssl-sys" -version = "0.9.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" -dependencies = [ - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - [[package]] name = "opentelemetry" version = "0.23.0" @@ -3799,12 +3706,6 @@ dependencies = [ "futures-io", ] -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - [[package]] name = "plotters" version = "0.3.7" @@ -3860,9 +3761,8 @@ dependencies = [ [[package]] name = "posthog-rs" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad1b35ffe50419992615288c40ee90fbf30da4c6faf251414675ea64e1cdfa3" +version = "0.2.3" +source = "git+https://github.com/PostHog/posthog-rs.git?rev=a006a81419031e4889d9c3882d7458d2efa588a8#a006a81419031e4889d9c3882d7458d2efa588a8" dependencies = [ "chrono", "reqwest 0.11.27", @@ -3990,12 +3890,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ "bytes", - "prost-derive 0.13.2", + "prost-derive 0.13.3", ] [[package]] @@ -4034,9 +3934,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" dependencies = [ "anyhow", "itertools 0.13.0", @@ -4068,8 +3968,8 @@ dependencies = [ "logos", "miette 7.2.0", "once_cell", - "prost 0.13.2", - "prost-types 0.13.2", + "prost 0.13.3", + "prost-types 0.13.3", "serde", "serde-value", ] @@ -4085,11 +3985,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" dependencies = [ - "prost 0.13.2", + "prost 0.13.3", ] [[package]] @@ -4222,9 +4122,9 @@ checksum = "873f359bdecdfe6e353752f97cb9ee69368df55b16363ed2216da85e03232a58" dependencies = [ "bytes", "miette 7.2.0", - "prost 0.13.2", + "prost 0.13.3", "prost-reflect 0.14.2", - "prost-types 0.13.2", + "prost-types 0.13.3", "protox-parse 0.7.0", "thiserror", ] @@ -4249,7 +4149,7 @@ checksum = "a3a462d115462c080ae000c29a47f0b3985737e5d3a995fcdbcaa5c782068dde" dependencies = [ "logos", "miette 7.2.0", - "prost-types 0.13.2", + "prost-types 0.13.3", "thiserror", ] @@ -4528,13 +4428,11 @@ dependencies = [ "http-body 0.4.6", "hyper 0.14.30", "hyper-rustls 0.24.2", - "hyper-tls", "ipnet", "js-sys", "log", "mime", "mime_guess", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -4546,7 +4444,6 @@ dependencies = [ "sync_wrapper 0.1.2", "system-configuration", "tokio", - "tokio-native-tls", "tokio-rustls 0.24.1", "tower-service", "url", @@ -5512,7 +5409,7 @@ dependencies = [ "pluralizer", "pretty_assertions", "prometheus", - "prost 0.13.2", + "prost 0.13.3", "prost-reflect 0.14.2", "protox 0.7.1", "protox-parse 0.7.0", @@ -5660,7 +5557,6 @@ dependencies = [ "derive_more 0.99.18", "lazy_static", "machineid-rs", - "openssl", "posthog-rs", "reqwest 0.11.27", "serde", @@ -5963,16 +5859,6 @@ dependencies = [ "syn 2.0.77", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.24.1" @@ -6184,8 +6070,8 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d967793411bc1a5392accf4731114295f0fd122865d22cde46a8584b03402b2" dependencies = [ - "prost 0.13.2", - "prost-types 0.13.2", + "prost 0.13.3", + "prost-types 0.13.3", "tonic 0.12.2", ] @@ -6486,12 +6372,6 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.5" diff --git a/examples/lint.sh b/examples/lint.sh index c12b62f68b..0ff6895547 100755 --- a/examples/lint.sh +++ b/examples/lint.sh @@ -4,20 +4,20 @@ # Function to print an error message and exit error_exit() { - echo "Error: $1" >&2 - exit 1 + echo "Error: $1" >&2 + exit 1 } # Function to check files with the specified extensions using tailcall check_files() { - local path="./examples" - local depth=1 - local -a extensions=("-name" "*.json" -o "-name" "*.yml" -o "-name" "*.yaml" -o "-name" "*.graphql" -o "-name" "*.gql") - local command="./target/debug/tailcall check" - local -a ignore=("!" "-name" "grpc-reflection.graphql") + local path="./examples" + local depth=1 + local -a extensions=("-name" "*.json" -o "-name" "*.yml" -o "-name" "*.yaml" -o "-name" "*.graphql" -o "-name" "*.gql") + local command="./target/debug/tailcall check" + local -a ignore=("!" "-name" "grpc-reflection.graphql" "!" "-name" "generate.yml") - # Execute find command with constructed options and extensions - find "$path" -maxdepth "$depth" \( "${extensions[@]}" \) "${ignore[@]}" -exec sh -c ' + # Execute find command with constructed options and extensions + find "$path" -maxdepth "$depth" \( "${extensions[@]}" \) "${ignore[@]}" -exec sh -c ' for file; do echo "Checking file: $file" '"$command"' "$file" || exit 255 @@ -27,7 +27,7 @@ check_files() { # Main script execution main() { - check_files + check_files } # Start the script diff --git a/tailcall-tracker/Cargo.toml b/tailcall-tracker/Cargo.toml index b35743eb6b..0ff35bde33 100644 --- a/tailcall-tracker/Cargo.toml +++ b/tailcall-tracker/Cargo.toml @@ -6,20 +6,22 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -reqwest = { workspace = true } +reqwest = { workspace = true, features = [ + "json", + "rustls-tls", +], default-features = false } derive_more = { workspace = true } url = { workspace = true } lazy_static.workspace = true serde = { workspace = true } serde_json = { workspace = true } machineid-rs = "1.2.4" -tokio = { workspace = true, features = ["rt", "macros"] } +tokio = { workspace = true, features = ["rt", "time"] } tracing = { workspace = true } sysinfo = "0.31.0" tailcall-version = { path = "../tailcall-version" } -posthog-rs = "0.2.2" +posthog-rs = { git = "https://github.com/PostHog/posthog-rs.git", rev = "a006a81419031e4889d9c3882d7458d2efa588a8" } async-trait = "0.1.81" chrono = "0.4.38" -openssl = { version = "0.10", features = ["vendored"] } whoami = "1.5.2" strum = "0.26.3" From 9128ff06a42f3c6a137679e1c3a179d87d78d38d Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 16:50:47 +0530 Subject: [PATCH 65/77] chore: update ci YML --- .github/workflows/ci.yml | 12 ---------- .github/workflows/discord.yml | 42 +++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d003e17244..06e6fb165f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -473,15 +473,3 @@ jobs: - name: Update Homebrew Formula run: ./update-formula.sh ${{needs.draft_release.outputs.create_release_name }} - - failure-notification: - runs-on: ubuntu-latest - steps: - - name: Notify failure on Discord - if: ${{ always() && contains(needs.*.result, 'failure') }} - uses: discord-actions/message@v2 - with: - webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }} - message: | - Build failed on branch: ${{ github.ref }} - Link: ${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/discord.yml b/.github/workflows/discord.yml index c09eb7677f..1a8244ba66 100644 --- a/.github/workflows/discord.yml +++ b/.github/workflows/discord.yml @@ -1,13 +1,17 @@ name: Notify on Workflow Failure and Fix on: + push: + branches: + - main workflow_run: - workflows: ["*"] # This listens to all workflows + workflows: ["*"] types: - completed jobs: notify: + if: ${{ github.event.workflow_run.conclusion == 'failure' }} runs-on: ubuntu-latest steps: - name: Check Previous Run Status @@ -23,24 +27,24 @@ jobs: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} run: | curl -H "Content-Type: application/json" \ - -X POST \ - -d '{ + -X POST \ + -d '{ "content": "**Workflow Failure Detected on Main Branch** :x:", "embeds": [ - { + { "author": { - "name": "GitHub Actions Bot", - "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", - "url": "https://github.com/${{ github.repository }}" + "name": "GitHub Actions Bot", + "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", + "url": "https://github.com/${{ github.repository }}" }, "title": "Workflow: '${{ github.event.workflow_run.name }}'", "description": "The workflow **${{ github.event.workflow_run.name }}** has failed on the main branch.", "url": "${{ github.event.workflow_run.html_url }}", "color": 15158332 - } + } ] - }' \ - $DISCORD_WEBHOOK_URL + }' \ + $DISCORD_WEBHOOK_URL - name: Send Discord Notification on Fix if: ${{ github.event.workflow_run.conclusion == 'success' && env.previous_status == 'failure' }} @@ -48,21 +52,21 @@ jobs: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} run: | curl -H "Content-Type: application/json" \ - -X POST \ - -d '{ + -X POST \ + -d '{ "content": "**Workflow Fixed on Main Branch** :white_check_mark:", "embeds": [ - { + { "author": { - "name": "GitHub Actions Bot", - "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", - "url": "https://github.com/${{ github.repository }}" + "name": "GitHub Actions Bot", + "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", + "url": "https://github.com/${{ github.repository }}" }, "title": "Workflow: '${{ github.event.workflow_run.name }}' Fixed", "description": "The workflow **${{ github.event.workflow_run.name }}** has been fixed on the main branch.", "url": "${{ github.event.workflow_run.html_url }}", "color": 3066993 - } + } ] - }' \ - $DISCORD_WEBHOOK_URL + }' \ + $DISCORD_WEBHOOK_URL From 6f159ec8a4a74dfd8b8da90c42ac338523d3371d Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 17:13:22 +0530 Subject: [PATCH 66/77] fix: CI --- src/cli/tc/run.rs | 6 +++++- tailcall-tracker/src/event.rs | 11 +++++++---- tailcall-tracker/src/tracker.rs | 20 +++++--------------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/cli/tc/run.rs b/src/cli/tc/run.rs index 78c843addd..dba25a90f0 100644 --- a/src/cli/tc/run.rs +++ b/src/cli/tc/run.rs @@ -25,7 +25,11 @@ pub async fn run() -> Result<()> { .await; // Dispatch the command as an event - let _ = TRACKER.dispatch(tailcall_tracker::EventKind::Run).await; + let _ = TRACKER + .dispatch(tailcall_tracker::EventKind::Command( + cli.command.to_string(), + )) + .await; run_command(cli, config_reader, runtime).await } diff --git a/tailcall-tracker/src/event.rs b/tailcall-tracker/src/event.rs index c858a55d03..b5d7332b46 100644 --- a/tailcall-tracker/src/event.rs +++ b/tailcall-tracker/src/event.rs @@ -9,7 +9,7 @@ pub struct Event { pub cores: usize, pub client_id: String, pub os_name: String, - pub up_time: Option, + pub up_time: i64, pub path: Option, pub cwd: Option, pub user: String, @@ -20,11 +20,14 @@ pub struct Event { #[derive(Clone, IntoStaticStr)] pub enum EventKind { Ping, - Run, + Command(String), } impl EventKind { - pub fn as_str(&self) -> &'static str { - self.into() + pub fn to_string(&self) -> String { + match self { + Self::Ping => "ping".to_string(), + Self::Command(name) => name.clone(), + } } } diff --git a/tailcall-tracker/src/tracker.rs b/tailcall-tracker/src/tracker.rs index 878a3c5ba9..9ae2d85a37 100644 --- a/tailcall-tracker/src/tracker.rs +++ b/tailcall-tracker/src/tracker.rs @@ -64,12 +64,12 @@ impl Tracker { if self.is_tracking { // Create a new event let event = Event { - event_name: event_kind.as_str().to_string(), + event_name: event_kind.to_string().to_string(), start_time: self.start_time, cores: cores(), client_id: client_id(), os_name: os_name(), - up_time: self.up_time(event_kind), + up_time: up_time(self.start_time), args: args(), path: path(), cwd: cwd(), @@ -87,13 +87,6 @@ impl Tracker { Ok(()) } - - fn up_time(&self, event_kind: EventKind) -> Option { - match event_kind { - EventKind::Ping => Some(get_uptime(self.start_time)), - _ => None, - } - } } // Generates a random client ID @@ -114,12 +107,9 @@ fn cores() -> usize { } // Get the uptime in minutes -fn get_uptime(start_time: DateTime) -> String { +fn up_time(start_time: DateTime) -> i64 { let current_time = Utc::now(); - format!( - "{} minutes", - current_time.signed_duration_since(start_time).num_minutes() - ) + current_time.signed_duration_since(start_time).num_minutes() } fn version() -> String { @@ -162,7 +152,7 @@ mod tests { #[tokio::test] async fn test_tracker() { - if let Err(e) = TRACKER.dispatch(EventKind::Run).await { + if let Err(e) = TRACKER.dispatch(EventKind::Command("ping".to_string())).await { panic!("Tracker dispatch error: {:?}", e); } } From fc30fea6d514c71d79e1c2a7f8dde6157dcb7b6c Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 17:29:18 +0530 Subject: [PATCH 67/77] chore: update CI condition --- .github/workflows/discord.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/discord.yml b/.github/workflows/discord.yml index 1a8244ba66..67eef8fd4d 100644 --- a/.github/workflows/discord.yml +++ b/.github/workflows/discord.yml @@ -1,9 +1,6 @@ name: Notify on Workflow Failure and Fix on: - push: - branches: - - main workflow_run: workflows: ["*"] types: @@ -11,7 +8,7 @@ on: jobs: notify: - if: ${{ github.event.workflow_run.conclusion == 'failure' }} + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.head_branch == 'main' }} runs-on: ubuntu-latest steps: - name: Check Previous Run Status From 508597ba065e37abf8ece51f561c5e61c0aa0a82 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 17:30:51 +0530 Subject: [PATCH 68/77] style: lint fixes --- tailcall-tracker/src/tracker.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tailcall-tracker/src/tracker.rs b/tailcall-tracker/src/tracker.rs index 9ae2d85a37..e078565308 100644 --- a/tailcall-tracker/src/tracker.rs +++ b/tailcall-tracker/src/tracker.rs @@ -152,7 +152,10 @@ mod tests { #[tokio::test] async fn test_tracker() { - if let Err(e) = TRACKER.dispatch(EventKind::Command("ping".to_string())).await { + if let Err(e) = TRACKER + .dispatch(EventKind::Command("ping".to_string())) + .await + { panic!("Tracker dispatch error: {:?}", e); } } From a995ab2762b3030256ee843ad40ecd6a09bf9642 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 17:39:24 +0530 Subject: [PATCH 69/77] chore: try discord webhook --- .github/workflows/discord.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/discord.yml b/.github/workflows/discord.yml index 67eef8fd4d..88db466141 100644 --- a/.github/workflows/discord.yml +++ b/.github/workflows/discord.yml @@ -8,7 +8,7 @@ on: jobs: notify: - if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.head_branch == 'main' }} + if: ${{ github.event.workflow_run.head_branch == 'main' }} runs-on: ubuntu-latest steps: - name: Check Previous Run Status From 65cb2ba67fa6e9ca540eac8a6cd4a7f6d3bb634e Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 17:55:55 +0530 Subject: [PATCH 70/77] lint fixes --- tailcall-tracker/src/event.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tailcall-tracker/src/event.rs b/tailcall-tracker/src/event.rs index b5d7332b46..552b576713 100644 --- a/tailcall-tracker/src/event.rs +++ b/tailcall-tracker/src/event.rs @@ -1,6 +1,5 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use strum::IntoStaticStr; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Event { @@ -17,7 +16,7 @@ pub struct Event { pub version: String, } -#[derive(Clone, IntoStaticStr)] +#[derive(Clone)] pub enum EventKind { Ping, Command(String), From 955bf9c976adfc7d7c738682e704249ebed98389 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sun, 22 Sep 2024 17:56:33 +0530 Subject: [PATCH 71/77] chore: drop discord --- .github/workflows/discord.yml | 69 ----------------------------------- 1 file changed, 69 deletions(-) delete mode 100644 .github/workflows/discord.yml diff --git a/.github/workflows/discord.yml b/.github/workflows/discord.yml deleted file mode 100644 index 88db466141..0000000000 --- a/.github/workflows/discord.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Notify on Workflow Failure and Fix - -on: - workflow_run: - workflows: ["*"] - types: - - completed - -jobs: - notify: - if: ${{ github.event.workflow_run.head_branch == 'main' }} - runs-on: ubuntu-latest - steps: - - name: Check Previous Run Status - id: previous_run - run: | - echo "Checking previous run status..." - PREVIOUS_STATUS=$(gh run list --limit 2 --branch main --workflow "${{ github.event.workflow_run.name }}" --json conclusion --jq '.[1].conclusion') - echo "previous_status=$PREVIOUS_STATUS" >> $GITHUB_ENV - - - name: Send Discord Notification on Failure - if: ${{ github.event.workflow_run.conclusion == 'failure' }} - env: - DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} - run: | - curl -H "Content-Type: application/json" \ - -X POST \ - -d '{ - "content": "**Workflow Failure Detected on Main Branch** :x:", - "embeds": [ - { - "author": { - "name": "GitHub Actions Bot", - "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", - "url": "https://github.com/${{ github.repository }}" - }, - "title": "Workflow: '${{ github.event.workflow_run.name }}'", - "description": "The workflow **${{ github.event.workflow_run.name }}** has failed on the main branch.", - "url": "${{ github.event.workflow_run.html_url }}", - "color": 15158332 - } - ] - }' \ - $DISCORD_WEBHOOK_URL - - - name: Send Discord Notification on Fix - if: ${{ github.event.workflow_run.conclusion == 'success' && env.previous_status == 'failure' }} - env: - DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} - run: | - curl -H "Content-Type: application/json" \ - -X POST \ - -d '{ - "content": "**Workflow Fixed on Main Branch** :white_check_mark:", - "embeds": [ - { - "author": { - "name": "GitHub Actions Bot", - "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", - "url": "https://github.com/${{ github.repository }}" - }, - "title": "Workflow: '${{ github.event.workflow_run.name }}' Fixed", - "description": "The workflow **${{ github.event.workflow_run.name }}** has been fixed on the main branch.", - "url": "${{ github.event.workflow_run.html_url }}", - "color": 3066993 - } - ] - }' \ - $DISCORD_WEBHOOK_URL From 9b7beba339ffaadcd6885c5d8a5fc31c20ee0e0a Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Mon, 23 Sep 2024 10:56:17 +0530 Subject: [PATCH 72/77] fix: clean up events (#2883) --- Cargo.lock | 1 + Cargo.toml | 3 +- tailcall-tracker/Cargo.toml | 1 + tailcall-tracker/src/collect/ga.rs | 6 +- tailcall-tracker/src/collect/posthog.rs | 94 ++++++++++++------- .../src/{tracker.rs => dispatch.rs} | 27 +++--- tailcall-tracker/src/event.rs | 34 ++++++- tailcall-tracker/src/lib.rs | 4 +- 8 files changed, 113 insertions(+), 57 deletions(-) rename tailcall-tracker/src/{tracker.rs => dispatch.rs} (88%) diff --git a/Cargo.lock b/Cargo.lock index 8bed6eafcf..ff1b1e3618 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5554,6 +5554,7 @@ version = "0.1.0" dependencies = [ "async-trait", "chrono", + "convert_case 0.6.0", "derive_more 0.99.18", "lazy_static", "machineid-rs", diff --git a/Cargo.toml b/Cargo.toml index a94f413728..89419d77ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ serde = { version = "1.0.200", features = ["derive"] } derive_more = "0.99.18" thiserror = "1.0.59" url = { version = "2.5.0", features = ["serde"] } +convert_case = "0.6.0" [dependencies] # dependencies specific to CLI must have optional = true and the dep should be added to default feature. @@ -149,7 +150,7 @@ async-graphql = { workspace = true, features = [ "opentelemetry", ] } dotenvy = "0.15.7" -convert_case = "0.6.0" +convert_case = { workspace = true } rand = "0.8.5" tailcall-macros = { path = "tailcall-macros" } tailcall-tracker = { path = "tailcall-tracker", optional = true } diff --git a/tailcall-tracker/Cargo.toml b/tailcall-tracker/Cargo.toml index 0ff35bde33..5f0c808f27 100644 --- a/tailcall-tracker/Cargo.toml +++ b/tailcall-tracker/Cargo.toml @@ -25,3 +25,4 @@ async-trait = "0.1.81" chrono = "0.4.38" whoami = "1.5.2" strum = "0.26.3" +convert_case = { workspace = true } diff --git a/tailcall-tracker/src/collect/ga.rs b/tailcall-tracker/src/collect/ga.rs index 917cb987d7..03c2b3e34e 100644 --- a/tailcall-tracker/src/collect/ga.rs +++ b/tailcall-tracker/src/collect/ga.rs @@ -9,12 +9,12 @@ const GA_TRACKER_URL: &str = "https://www.google-analytics.com"; /// Event structure to be sent to GA #[derive(Debug, Serialize, Deserialize)] -struct GaEvent { +struct Payload { client_id: String, events: Vec, } -impl GaEvent { +impl Payload { pub fn new(event: Event) -> Self { Self { client_id: event.clone().client_id, events: vec![event] } } @@ -35,7 +35,7 @@ impl Tracker { } } fn create_request(&self, event: Event) -> Result { - let event = GaEvent::new(event); + let event = Payload::new(event); let mut url = reqwest::Url::parse(self.base_url.as_str())?; url.set_path("/mp/collect"); url.query_pairs_mut() diff --git a/tailcall-tracker/src/collect/posthog.rs b/tailcall-tracker/src/collect/posthog.rs index 595832d224..e1d084c689 100644 --- a/tailcall-tracker/src/collect/posthog.rs +++ b/tailcall-tracker/src/collect/posthog.rs @@ -1,4 +1,9 @@ -use serde::de::Error; +use std::collections::HashMap; + +use chrono::NaiveDateTime; +use reqwest::header::{HeaderName, HeaderValue}; +use serde::Serialize; +use serde_json::Value; use super::super::Result; use super::Collect; @@ -6,47 +11,72 @@ use crate::Event; pub struct Tracker { api_secret: &'static str, - client_id_key: &'static str, } impl Tracker { - pub fn new(api_secret: &'static str, client_id_key: &'static str) -> Self { - Self { api_secret, client_id_key } + pub fn new(api_secret: &'static str) -> Self { + Self { api_secret } + } +} + +#[derive(Debug, Serialize)] +struct Payload { + api_key: String, + event: String, + distinct_id: String, + properties: HashMap, + timestamp: Option, +} + +impl Payload { + fn new(api_key: String, input: Event) -> Self { + let mut properties = HashMap::new(); + let distinct_id = input.client_id.to_string(); + let event = input.event_name.to_string(); + + if let Ok(Value::Object(map)) = serde_json::to_value(input) { + for (key, value) in map { + properties.insert(key, value); + } + } + + Self { + api_key, + event, + distinct_id, + properties, + timestamp: Some(chrono::Utc::now().naive_utc()), + } + } +} + +impl Tracker { + fn create_request(&self, event: Event) -> Result { + let url = reqwest::Url::parse("https://us.i.posthog.com/capture/")?; + let mut request = reqwest::Request::new(reqwest::Method::POST, url); + request.headers_mut().insert( + HeaderName::from_static("content-type"), + HeaderValue::from_static("application/json"), + ); + + let event = Payload::new(self.api_secret.to_string(), event); + + let _ = request + .body_mut() + .insert(reqwest::Body::from(serde_json::to_string(&event)?)); + + Ok(request) } } #[async_trait::async_trait] impl Collect for Tracker { + // TODO: move http request to a dispatch async fn collect(&self, event: Event) -> Result<()> { - let api_secret = self.api_secret; - let client_id_key = self.client_id_key; - let handle_posthog = tokio::task::spawn_blocking(move || -> Result<()> { - let client = posthog_rs::client(api_secret); - let json = serde_json::to_value(&event)?; - let mut posthog_event = - posthog_rs::Event::new(event.event_name.clone(), event.client_id); - - match json { - serde_json::Value::Object(map) => { - for (mut key, value) in map { - if key == client_id_key { - key = "distinct_id".to_string(); - } - posthog_event.insert_prop(key, value)?; - } - } - _ => { - return Err( - serde_json::Error::custom("Failed to serialize event for posthog").into(), - ); - } - } + let request = self.create_request(event)?; + let client = reqwest::Client::new(); + client.execute(request).await?; - client.capture(posthog_event)?; - Ok(()) - }) - .await; - handle_posthog??; Ok(()) } } diff --git a/tailcall-tracker/src/tracker.rs b/tailcall-tracker/src/dispatch.rs similarity index 88% rename from tailcall-tracker/src/tracker.rs rename to tailcall-tracker/src/dispatch.rs index e078565308..36cb313520 100644 --- a/tailcall-tracker/src/tracker.rs +++ b/tailcall-tracker/src/dispatch.rs @@ -27,7 +27,7 @@ const DEFAULT_CLIENT_ID: &str = ""; pub struct Tracker { collectors: Vec>, - is_tracking: bool, + can_track: bool, start_time: DateTime, } @@ -37,11 +37,12 @@ impl Default for Tracker { GA_API_SECRET.to_string(), GA_MEASUREMENT_ID.to_string(), )); - let posthog_tracker = Box::new(posthog::Tracker::new(POSTHOG_API_SECRET, "client_id")); + let posthog_tracker = Box::new(posthog::Tracker::new(POSTHOG_API_SECRET)); let start_time = Utc::now(); + let can_track = can_track(); Self { collectors: vec![ga_tracker, posthog_tracker], - is_tracking: can_track(), + can_track, start_time, } } @@ -49,22 +50,20 @@ impl Default for Tracker { impl Tracker { pub async fn init_ping(&'static self, duration: Duration) { - if self.is_tracking { - let mut interval = tokio::time::interval(duration); - tokio::task::spawn(async move { - loop { - interval.tick().await; - let _ = self.dispatch(EventKind::Ping).await; - } - }); - } + let mut interval = tokio::time::interval(duration); + tokio::task::spawn(async move { + loop { + interval.tick().await; + let _ = self.dispatch(EventKind::Ping).await; + } + }); } pub async fn dispatch(&'static self, event_kind: EventKind) -> Result<()> { - if self.is_tracking { + if self.can_track { // Create a new event let event = Event { - event_name: event_kind.to_string().to_string(), + event_name: event_kind.name(), start_time: self.start_time, cores: cores(), client_id: client_id(), diff --git a/tailcall-tracker/src/event.rs b/tailcall-tracker/src/event.rs index 552b576713..78b24f84ed 100644 --- a/tailcall-tracker/src/event.rs +++ b/tailcall-tracker/src/event.rs @@ -1,9 +1,12 @@ +use std::ops::Deref; + use chrono::{DateTime, Utc}; +use convert_case::{Case, Casing}; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Event { - pub event_name: String, + pub event_name: Name, pub start_time: DateTime, pub cores: usize, pub client_id: String, @@ -16,17 +19,38 @@ pub struct Event { pub version: String, } -#[derive(Clone)] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Name(String); +impl From for Name { + fn from(name: String) -> Self { + Self(name.to_case(Case::Snake)) + } +} +impl Deref for Name { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for String { + fn from(val: Name) -> Self { + val.0 + } +} + +#[derive(Debug, Clone)] pub enum EventKind { Ping, Command(String), } impl EventKind { - pub fn to_string(&self) -> String { + pub fn name(&self) -> Name { match self { - Self::Ping => "ping".to_string(), - Self::Command(name) => name.clone(), + Self::Ping => Name::from("ping".to_string()), + Self::Command(name) => Name::from(name.to_string()), } } } diff --git a/tailcall-tracker/src/lib.rs b/tailcall-tracker/src/lib.rs index 063099044f..2f4d8d6f51 100644 --- a/tailcall-tracker/src/lib.rs +++ b/tailcall-tracker/src/lib.rs @@ -1,8 +1,8 @@ mod can_track; mod collect; +mod dispatch; mod error; mod event; -mod tracker; +pub use dispatch::Tracker; use error::Result; pub use event::{Event, EventKind}; -pub use tracker::Tracker; From 4ff89c8c1fe35c4a2d5b25e9710dc9b4bf1bc3fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 05:27:08 +0000 Subject: [PATCH 73/77] chore(deps): update rust crate thiserror to v1.0.64 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff1b1e3618..36ed662d45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5719,18 +5719,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", From fe97423156813bb5263c65bb2ba92472c2c0ee34 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 09:52:32 +0000 Subject: [PATCH 74/77] chore(deps): update rust crate markdown to v1.0.0-alpha.21 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36ed662d45..2447fa0700 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2922,9 +2922,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "markdown" -version = "1.0.0-alpha.20" +version = "1.0.0-alpha.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "911a8325e6fb87b89890cd4529a2ab34c2669c026279e61c26b7140a3d821ccb" +checksum = "a6491e6c702bf7e3b24e769d800746d5f2c06a6c6a2db7992612e0f429029e81" dependencies = [ "unicode-id", ] From 69f291e511370a4b5ec3cc7a5c653ff2010e18ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 21:07:02 +0000 Subject: [PATCH 75/77] chore(deps): update dependency miniflare to v3.20240909.5 --- tailcall-cloudflare/package-lock.json | 58 ++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tailcall-cloudflare/package-lock.json b/tailcall-cloudflare/package-lock.json index d8238d6c48..b32d72ea10 100644 --- a/tailcall-cloudflare/package-lock.json +++ b/tailcall-cloudflare/package-lock.json @@ -1334,9 +1334,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240909.4", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.4.tgz", - "integrity": "sha512-uiMjmv9vYIMgUn5PovS/2XzvnSgm04GxtoreNb7qiaDdp1YMhPPtnmV+EKOKyPSlVc7fCt/glzqSX9atUBXa2A==", + "version": "3.20240909.5", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.5.tgz", + "integrity": "sha512-3Am3D9LGDljEKWnylSy6hFg3LFnNCo9DlWqZFcL7QkuIhQwN6Sqz1d6xQCkgft7FVXnykG6VNpz0NrjdW+mBjg==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -2409,6 +2409,32 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "3.20240909.4", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.4.tgz", + "integrity": "sha512-uiMjmv9vYIMgUn5PovS/2XzvnSgm04GxtoreNb7qiaDdp1YMhPPtnmV+EKOKyPSlVc7fCt/glzqSX9atUBXa2A==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3261,9 +3287,9 @@ "dev": true }, "miniflare": { - "version": "3.20240909.4", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.4.tgz", - "integrity": "sha512-uiMjmv9vYIMgUn5PovS/2XzvnSgm04GxtoreNb7qiaDdp1YMhPPtnmV+EKOKyPSlVc7fCt/glzqSX9atUBXa2A==", + "version": "3.20240909.5", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.5.tgz", + "integrity": "sha512-3Am3D9LGDljEKWnylSy6hFg3LFnNCo9DlWqZFcL7QkuIhQwN6Sqz1d6xQCkgft7FVXnykG6VNpz0NrjdW+mBjg==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.8.1", @@ -3904,6 +3930,26 @@ "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" } + }, + "miniflare": { + "version": "3.20240909.4", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240909.4.tgz", + "integrity": "sha512-uiMjmv9vYIMgUn5PovS/2XzvnSgm04GxtoreNb7qiaDdp1YMhPPtnmV+EKOKyPSlVc7fCt/glzqSX9atUBXa2A==", + "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.4", + "workerd": "1.20240909.0", + "ws": "^8.17.1", + "youch": "^3.2.2", + "zod": "^3.22.3" + } } } }, From b0bcfcf7c4b41068fffa11eb817a6b37c0a62095 Mon Sep 17 00:00:00 2001 From: Sandipsinh Dilipsinh Rathod <62684960+ssddOnTop@users.noreply.github.com> Date: Tue, 24 Sep 2024 04:15:31 -0400 Subject: [PATCH 76/77] fix: `__typename` do not work at root level (#2840) Co-authored-by: Tushar Mathur --- src/core/jit/builder.rs | 1 + src/core/jit/input_resolver.rs | 1 + src/core/jit/model.rs | 10 + ..._json_placeholder_typename_root_level.snap | 609 ++++++++++++++++++ src/core/jit/synth/synth.rs | 26 +- 5 files changed, 643 insertions(+), 4 deletions(-) create mode 100644 src/core/jit/synth/snapshots/tailcall__core__jit__synth__synth__tests__json_placeholder_typename_root_level.snap diff --git a/src/core/jit/builder.rs b/src/core/jit/builder.rs index 970eef92fb..d7d9a2e080 100644 --- a/src/core/jit/builder.rs +++ b/src/core/jit/builder.rs @@ -354,6 +354,7 @@ impl Builder { }); let plan = OperationPlan::new( + name, fields, operation.ty, self.index.clone(), diff --git a/src/core/jit/input_resolver.rs b/src/core/jit/input_resolver.rs index fcde3c387b..31bc8b498b 100644 --- a/src/core/jit/input_resolver.rs +++ b/src/core/jit/input_resolver.rs @@ -82,6 +82,7 @@ where .collect::, _>>()?; Ok(OperationPlan::new( + self.plan.root_name(), new_fields, self.plan.operation_type(), self.plan.index.clone(), diff --git a/src/core/jit/model.rs b/src/core/jit/model.rs index 2936676cb8..dbec574db6 100644 --- a/src/core/jit/model.rs +++ b/src/core/jit/model.rs @@ -345,6 +345,7 @@ pub struct Nested(Vec, Input>>); #[derive(Clone)] pub struct OperationPlan { + root_name: String, flat: Vec>, operation_type: OperationType, nested: Vec, Input>>, @@ -379,6 +380,7 @@ impl OperationPlan { } Ok(OperationPlan { + root_name: self.root_name, flat, operation_type: self.operation_type, nested, @@ -389,7 +391,9 @@ impl OperationPlan { } impl OperationPlan { + #[allow(clippy::too_many_arguments)] pub fn new( + root_name: &str, fields: Vec>, operation_type: OperationType, index: Arc, @@ -406,6 +410,7 @@ impl OperationPlan { .collect::>(); Self { + root_name: root_name.to_string(), flat: fields, nested, operation_type, @@ -414,6 +419,11 @@ impl OperationPlan { } } + /// Returns the name of the root type + pub fn root_name(&self) -> &str { + &self.root_name + } + /// Returns a graphQL operation type pub fn operation_type(&self) -> OperationType { self.operation_type diff --git a/src/core/jit/synth/snapshots/tailcall__core__jit__synth__synth__tests__json_placeholder_typename_root_level.snap b/src/core/jit/synth/snapshots/tailcall__core__jit__synth__synth__tests__json_placeholder_typename_root_level.snap new file mode 100644 index 0000000000..a48b858ce3 --- /dev/null +++ b/src/core/jit/synth/snapshots/tailcall__core__jit__synth__synth__tests__json_placeholder_typename_root_level.snap @@ -0,0 +1,609 @@ +--- +source: src/core/jit/synth/synth.rs +expression: "serde_json::to_string_pretty(&val).unwrap()" +--- +{ + "__typename": "Query", + "posts": [ + { + "id": 1, + "user": { + "id": 1 + } + }, + { + "id": 2, + "user": { + "id": 1 + } + }, + { + "id": 3, + "user": { + "id": 1 + } + }, + { + "id": 4, + "user": { + "id": 1 + } + }, + { + "id": 5, + "user": { + "id": 1 + } + }, + { + "id": 6, + "user": { + "id": 1 + } + }, + { + "id": 7, + "user": { + "id": 1 + } + }, + { + "id": 8, + "user": { + "id": 1 + } + }, + { + "id": 9, + "user": { + "id": 1 + } + }, + { + "id": 10, + "user": { + "id": 1 + } + }, + { + "id": 11, + "user": { + "id": 2 + } + }, + { + "id": 12, + "user": { + "id": 2 + } + }, + { + "id": 13, + "user": { + "id": 2 + } + }, + { + "id": 14, + "user": { + "id": 2 + } + }, + { + "id": 15, + "user": { + "id": 2 + } + }, + { + "id": 16, + "user": { + "id": 2 + } + }, + { + "id": 17, + "user": { + "id": 2 + } + }, + { + "id": 18, + "user": { + "id": 2 + } + }, + { + "id": 19, + "user": { + "id": 2 + } + }, + { + "id": 20, + "user": { + "id": 2 + } + }, + { + "id": 21, + "user": { + "id": 3 + } + }, + { + "id": 22, + "user": { + "id": 3 + } + }, + { + "id": 23, + "user": { + "id": 3 + } + }, + { + "id": 24, + "user": { + "id": 3 + } + }, + { + "id": 25, + "user": { + "id": 3 + } + }, + { + "id": 26, + "user": { + "id": 3 + } + }, + { + "id": 27, + "user": { + "id": 3 + } + }, + { + "id": 28, + "user": { + "id": 3 + } + }, + { + "id": 29, + "user": { + "id": 3 + } + }, + { + "id": 30, + "user": { + "id": 3 + } + }, + { + "id": 31, + "user": { + "id": 4 + } + }, + { + "id": 32, + "user": { + "id": 4 + } + }, + { + "id": 33, + "user": { + "id": 4 + } + }, + { + "id": 34, + "user": { + "id": 4 + } + }, + { + "id": 35, + "user": { + "id": 4 + } + }, + { + "id": 36, + "user": { + "id": 4 + } + }, + { + "id": 37, + "user": { + "id": 4 + } + }, + { + "id": 38, + "user": { + "id": 4 + } + }, + { + "id": 39, + "user": { + "id": 4 + } + }, + { + "id": 40, + "user": { + "id": 4 + } + }, + { + "id": 41, + "user": { + "id": 5 + } + }, + { + "id": 42, + "user": { + "id": 5 + } + }, + { + "id": 43, + "user": { + "id": 5 + } + }, + { + "id": 44, + "user": { + "id": 5 + } + }, + { + "id": 45, + "user": { + "id": 5 + } + }, + { + "id": 46, + "user": { + "id": 5 + } + }, + { + "id": 47, + "user": { + "id": 5 + } + }, + { + "id": 48, + "user": { + "id": 5 + } + }, + { + "id": 49, + "user": { + "id": 5 + } + }, + { + "id": 50, + "user": { + "id": 5 + } + }, + { + "id": 51, + "user": { + "id": 6 + } + }, + { + "id": 52, + "user": { + "id": 6 + } + }, + { + "id": 53, + "user": { + "id": 6 + } + }, + { + "id": 54, + "user": { + "id": 6 + } + }, + { + "id": 55, + "user": { + "id": 6 + } + }, + { + "id": 56, + "user": { + "id": 6 + } + }, + { + "id": 57, + "user": { + "id": 6 + } + }, + { + "id": 58, + "user": { + "id": 6 + } + }, + { + "id": 59, + "user": { + "id": 6 + } + }, + { + "id": 60, + "user": { + "id": 6 + } + }, + { + "id": 61, + "user": { + "id": 7 + } + }, + { + "id": 62, + "user": { + "id": 7 + } + }, + { + "id": 63, + "user": { + "id": 7 + } + }, + { + "id": 64, + "user": { + "id": 7 + } + }, + { + "id": 65, + "user": { + "id": 7 + } + }, + { + "id": 66, + "user": { + "id": 7 + } + }, + { + "id": 67, + "user": { + "id": 7 + } + }, + { + "id": 68, + "user": { + "id": 7 + } + }, + { + "id": 69, + "user": { + "id": 7 + } + }, + { + "id": 70, + "user": { + "id": 7 + } + }, + { + "id": 71, + "user": { + "id": 8 + } + }, + { + "id": 72, + "user": { + "id": 8 + } + }, + { + "id": 73, + "user": { + "id": 8 + } + }, + { + "id": 74, + "user": { + "id": 8 + } + }, + { + "id": 75, + "user": { + "id": 8 + } + }, + { + "id": 76, + "user": { + "id": 8 + } + }, + { + "id": 77, + "user": { + "id": 8 + } + }, + { + "id": 78, + "user": { + "id": 8 + } + }, + { + "id": 79, + "user": { + "id": 8 + } + }, + { + "id": 80, + "user": { + "id": 8 + } + }, + { + "id": 81, + "user": { + "id": 9 + } + }, + { + "id": 82, + "user": { + "id": 9 + } + }, + { + "id": 83, + "user": { + "id": 9 + } + }, + { + "id": 84, + "user": { + "id": 9 + } + }, + { + "id": 85, + "user": { + "id": 9 + } + }, + { + "id": 86, + "user": { + "id": 9 + } + }, + { + "id": 87, + "user": { + "id": 9 + } + }, + { + "id": 88, + "user": { + "id": 9 + } + }, + { + "id": 89, + "user": { + "id": 9 + } + }, + { + "id": 90, + "user": { + "id": 9 + } + }, + { + "id": 91, + "user": { + "id": 10 + } + }, + { + "id": 92, + "user": { + "id": 10 + } + }, + { + "id": 93, + "user": { + "id": 10 + } + }, + { + "id": 94, + "user": { + "id": 10 + } + }, + { + "id": 95, + "user": { + "id": 10 + } + }, + { + "id": 96, + "user": { + "id": 10 + } + }, + { + "id": 97, + "user": { + "id": 10 + } + }, + { + "id": 98, + "user": { + "id": 10 + } + }, + { + "id": 99, + "user": { + "id": 10 + } + }, + { + "id": 100, + "user": { + "id": 10 + } + } + ] +} diff --git a/src/core/jit/synth/synth.rs b/src/core/jit/synth/synth.rs index 4a037c363b..d02ed6ebc5 100644 --- a/src/core/jit/synth/synth.rs +++ b/src/core/jit/synth/synth.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use crate::core::jit::model::{Field, Nested, OperationPlan, Variables}; use crate::core::jit::store::{DataPath, Store}; use crate::core::jit::{Error, PathSegment, Positioned, ValidationError}; @@ -36,6 +38,7 @@ where pub fn synthesize(&'a self) -> Result> { let mut data = Value::JsonObject::new(); let mut path = Vec::new(); + let root_name = self.plan.root_name(); for child in self.plan.as_nested().iter() { if !self.include(child) { @@ -43,7 +46,7 @@ where } // TODO: in case of error set `child.output_name` to null // and append error to response error array - let val = self.iter(child, None, &DataPath::new(), &mut path)?; + let val = self.iter(child, None, &DataPath::new(), &mut path, Some(root_name))?; data.insert_key(&child.output_name, val); } @@ -58,6 +61,7 @@ where value: Option<&'a Value>, data_path: &DataPath, path: &mut Vec, + root_name: Option<&'a str>, ) -> Result> { path.push(PathSegment::Field(node.output_name.clone())); @@ -74,13 +78,13 @@ where } if node.type_of.is_list() != value.as_array().is_some() { - return self.node_nullable_guard(node, path); + return self.node_nullable_guard(node, path, None); } self.iter_inner(node, value, data_path, path) } None => match value { Some(result) => self.iter_inner(node, result, data_path, path), - None => self.node_nullable_guard(node, path), + None => self.node_nullable_guard(node, path, root_name), }, }; @@ -94,7 +98,13 @@ where &'a self, node: &'a Field, Value>, path: &[PathSegment], + root_name: Option<&'a str>, ) -> Result> { + if let Some(root_name) = root_name { + if node.name.eq("__typename") { + return Ok(Value::string(Cow::Borrowed(root_name))); + } + } // according to GraphQL spec https://spec.graphql.org/October2021/#sec-Handling-Field-Errors if node.type_of.is_nullable() { Ok(Value::null()) @@ -173,7 +183,7 @@ where Value::string(node.value_type(value).into()) } else { let val = obj.get_key(child.name.as_str()); - self.iter(child, val, data_path, path)? + self.iter(child, val, data_path, path, None)? }; ans.insert_key(&child.output_name, value); } @@ -418,4 +428,12 @@ mod tests { let val: serde_json_borrow::Value = synth.synthesize().unwrap(); insta::assert_snapshot!(serde_json::to_string_pretty(&val).unwrap()) } + + #[test] + fn test_json_placeholder_typename_root_level() { + let jp = JP::init("{ __typename posts { id user { id }} }", None); + let synth = jp.synth(); + let val: serde_json_borrow::Value = synth.synthesize().unwrap(); + insta::assert_snapshot!(serde_json::to_string_pretty(&val).unwrap()) + } } From c0620580b8070499fb670ca3abacb7ad5e55aa04 Mon Sep 17 00:00:00 2001 From: Kiryl Mialeshka <8974488+meskill@users.noreply.github.com> Date: Tue, 24 Sep 2024 16:32:46 +0200 Subject: [PATCH 77/77] feat(2639): implement entity resolver (#2693) Co-authored-by: Tushar Mathur Co-authored-by: Amit Singh --- .../apollo_federation_subgraph_post.graphql | 21 + .../apollo_federation_subgraph_user.graphql | 18 + examples/federation/README.md | 28 + examples/federation/gateway.js | 20 + examples/federation/package-lock.json | 3117 +++++++++++++++++ examples/federation/package.json | 18 + examples/federation/rover.sh | 18 + generated/.tailcallrc.graphql | 12 +- generated/.tailcallrc.schema.json | 98 + src/core/app_context.rs | 11 +- src/core/blueprint/definitions.rs | 1 + .../blueprint/operators/apollo_federation.rs | 163 + src/core/blueprint/operators/call.rs | 15 +- src/core/blueprint/operators/expr.rs | 8 +- src/core/blueprint/operators/graphql.rs | 2 +- src/core/blueprint/operators/http.rs | 12 +- src/core/blueprint/operators/js.rs | 8 +- src/core/blueprint/operators/mod.rs | 2 + ...lueprint__index__test__from_blueprint.snap | 8 + src/core/config/config.rs | 314 +- src/core/config/directives/call.rs | 47 + src/core/config/directives/expr.rs | 23 + src/core/config/directives/federation.rs | 21 + src/core/config/directives/graphql.rs | 53 + src/core/config/directives/grpc.rs | 54 + src/core/config/directives/http.rs | 93 + src/core/config/directives/js.rs | 18 + src/core/config/directives/mod.rs | 15 + src/core/config/from_document.rs | 18 +- src/core/config/into_document.rs | 51 +- src/core/config/mod.rs | 4 + src/core/config/resolver.rs | 56 + src/core/config/transformer/mod.rs | 2 + src/core/config/transformer/required.rs | 1 + ...graph__tests__extractor__extract_call.snap | 11 + ...graph__tests__extractor__extract_expr.snap | 11 + ...ph__tests__extractor__extract_graphql.snap | 11 + ...graph__tests__extractor__extract_grpc.snap | 11 + ...graph__tests__extractor__extract_http.snap | 11 + ..._tests__extractor__non_value_template.snap | 28 + ...er__subgraph__tests__keys__keys_merge.snap | 32 + ...rmer__subgraph__tests__keys__keys_set.snap | 32 + src/core/config/transformer/subgraph.rs | 493 +++ src/core/helpers/body.rs | 1 + src/core/ir/error.rs | 5 + src/core/ir/eval.rs | 58 +- src/core/ir/model.rs | 17 +- src/core/mustache/parse.rs | 1 - src/core/valid/valid.rs | 9 + tailcall-macros/src/lib.rs | 6 +- tailcall-macros/src/merge_right.rs | 69 +- tailcall-macros/src/resolver.rs | 80 +- ...apollo-federation-entities-batch.md_0.snap | 26 + ...apollo-federation-entities-batch.md_1.snap | 17 + ...o-federation-entities-batch.md_client.snap | 73 + ...o-federation-entities-batch.md_merged.snap | 43 + ...deration-entities-validation.md_error.snap | 23 + .../apollo-federation-entities.md_0.snap | 36 + .../apollo-federation-entities.md_1.snap | 17 + .../apollo-federation-entities.md_client.snap | 73 + .../apollo-federation-entities.md_merged.snap | 40 + .../apollo-federation-entities-batch.md | 116 + .../apollo-federation-entities-validation.md | 78 + tests/execution/apollo-federation-entities.md | 77 + 64 files changed, 5474 insertions(+), 381 deletions(-) create mode 100644 examples/apollo_federation_subgraph_post.graphql create mode 100644 examples/apollo_federation_subgraph_user.graphql create mode 100644 examples/federation/README.md create mode 100644 examples/federation/gateway.js create mode 100644 examples/federation/package-lock.json create mode 100644 examples/federation/package.json create mode 100755 examples/federation/rover.sh create mode 100644 src/core/blueprint/operators/apollo_federation.rs create mode 100644 src/core/config/directives/call.rs create mode 100644 src/core/config/directives/expr.rs create mode 100644 src/core/config/directives/federation.rs create mode 100644 src/core/config/directives/graphql.rs create mode 100644 src/core/config/directives/grpc.rs create mode 100644 src/core/config/directives/http.rs create mode 100644 src/core/config/directives/js.rs create mode 100644 src/core/config/directives/mod.rs create mode 100644 src/core/config/resolver.rs create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_call.snap create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_expr.snap create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_graphql.snap create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_grpc.snap create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_http.snap create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__non_value_template.snap create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_merge.snap create mode 100644 src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_set.snap create mode 100644 src/core/config/transformer/subgraph.rs create mode 100644 tests/core/snapshots/apollo-federation-entities-batch.md_0.snap create mode 100644 tests/core/snapshots/apollo-federation-entities-batch.md_1.snap create mode 100644 tests/core/snapshots/apollo-federation-entities-batch.md_client.snap create mode 100644 tests/core/snapshots/apollo-federation-entities-batch.md_merged.snap create mode 100644 tests/core/snapshots/apollo-federation-entities-validation.md_error.snap create mode 100644 tests/core/snapshots/apollo-federation-entities.md_0.snap create mode 100644 tests/core/snapshots/apollo-federation-entities.md_1.snap create mode 100644 tests/core/snapshots/apollo-federation-entities.md_client.snap create mode 100644 tests/core/snapshots/apollo-federation-entities.md_merged.snap create mode 100644 tests/execution/apollo-federation-entities-batch.md create mode 100644 tests/execution/apollo-federation-entities-validation.md create mode 100644 tests/execution/apollo-federation-entities.md diff --git a/examples/apollo_federation_subgraph_post.graphql b/examples/apollo_federation_subgraph_post.graphql new file mode 100644 index 0000000000..0546fd7139 --- /dev/null +++ b/examples/apollo_federation_subgraph_post.graphql @@ -0,0 +1,21 @@ +schema + @server(port: 8001) + @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: 42, batch: {delay: 100}) { + query: Query +} + +type Query { + posts: [Post] @http(path: "/posts") +} + +type User @http(path: "/users", query: [{key: "id", value: "{{.value.id}}"}], batchKey: ["id"]) { + id: Int! +} + +type Post @http(path: "/posts", query: [{key: "id", value: "{{.value.id}}"}], batchKey: ["id"]) { + id: Int! + userId: Int! + title: String! + body: String! + user: User @expr(body: {id: "{{.value.userId}}"}) +} diff --git a/examples/apollo_federation_subgraph_user.graphql b/examples/apollo_federation_subgraph_user.graphql new file mode 100644 index 0000000000..f904e58781 --- /dev/null +++ b/examples/apollo_federation_subgraph_user.graphql @@ -0,0 +1,18 @@ +schema + @server(port: 8002) + @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: 42, batch: {delay: 100}) { + query: Query +} + +type Query { + user(id: Int!): User @http(path: "/users/{{.args.id}}") +} + +type User @http(path: "/users", query: [{key: "id", value: "{{.value.id}}"}], batchKey: ["id"]) { + id: Int! + name: String + username: String + email: String + phone: String + website: String +} diff --git a/examples/federation/README.md b/examples/federation/README.md new file mode 100644 index 0000000000..1d8d49842f --- /dev/null +++ b/examples/federation/README.md @@ -0,0 +1,28 @@ +# Apollo Federation example + +1. Start tailcall subgraph examples: + +- `cargo run -- start examples/apollo_federation_subgraph_post.graphql` +- `cargo run -- start examples/apollo_federation_subgraph_user.graphql` + +2. Run Apollo router by one of the following methods: + +- run `@apollo/gateway` with `npm start` (with `npm install` for the first time) from "examples/federation" folder +- start apollo router with `rover.sh` script (install [apollo rover](https://www.apollographql.com/docs/rover) first) + +3. Navigate to `http://localhost:4000` and execute supergraph queries, see [examples](#query-examples) + +# Query examples + +```graphql +{ + posts { + id + title + user { + id + name + } + } +} +``` diff --git a/examples/federation/gateway.js b/examples/federation/gateway.js new file mode 100644 index 0000000000..dcb0b89760 --- /dev/null +++ b/examples/federation/gateway.js @@ -0,0 +1,20 @@ +import {ApolloServer} from "@apollo/server" +import {startStandaloneServer} from "@apollo/server/standalone" +import {ApolloGateway, IntrospectAndCompose} from "@apollo/gateway" + +const gateway = new ApolloGateway({ + supergraphSdl: new IntrospectAndCompose({ + subgraphs: [ + {name: "post", url: "http://localhost:8001/graphql"}, + {name: "user", url: "http://localhost:8002/graphql"}, + ], + }), +}) + +const server = new ApolloServer({ + gateway, + introspection: true, +}) + +const {url} = await startStandaloneServer(server) +console.log(`🚀 Server ready at ${url}`) diff --git a/examples/federation/package-lock.json b/examples/federation/package-lock.json new file mode 100644 index 0000000000..c225c43e3f --- /dev/null +++ b/examples/federation/package-lock.json @@ -0,0 +1,3117 @@ +{ + "name": "federation", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "federation", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@apollo/gateway": "^2.8.4", + "@apollo/server": "^4.11.0", + "graphql": "^16.9.0" + } + }, + "node_modules/@apollo/cache-control-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@apollo/cache-control-types/-/cache-control-types-1.0.3.tgz", + "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==", + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/composition": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@apollo/composition/-/composition-2.8.4.tgz", + "integrity": "sha512-x8USTfHAtauW2BrXZo10gFV9yoF3TIfKUu+s5tJVm/vX/zgw3OG54TC34v5c/5pMsStcZu/aYFnMkeZ54Ay7tQ==", + "dependencies": { + "@apollo/federation-internals": "2.8.4", + "@apollo/query-graphs": "2.8.4" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" + } + }, + "node_modules/@apollo/federation-internals": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@apollo/federation-internals/-/federation-internals-2.8.4.tgz", + "integrity": "sha512-m/vFu5btNfmvxZfe8B1m8jjCN/NxCYctxjdhXgQD4WGbDwtUk59+i7NuVMtX5IfmFMKycwqnbihkv5w2E00XDA==", + "dependencies": { + "@types/uuid": "^9.0.0", + "chalk": "^4.1.0", + "js-levenshtein": "^1.1.6", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" + } + }, + "node_modules/@apollo/gateway": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@apollo/gateway/-/gateway-2.8.4.tgz", + "integrity": "sha512-KxYRvRfSLDMqyOlUu9ZuOaqZLvKwGHR3F6XSw8JmHvMUjcRzVeAY6U9821ruM9g+SdYYdm0q2jYJf4/iYPAcow==", + "dependencies": { + "@apollo/composition": "2.8.4", + "@apollo/federation-internals": "2.8.4", + "@apollo/query-planner": "2.8.4", + "@apollo/server-gateway-interface": "^1.1.0", + "@apollo/usage-reporting-protobuf": "^4.1.0", + "@apollo/utils.createhash": "^2.0.0", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.isnodelike": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0", + "@josephg/resolvable": "^1.0.1", + "@opentelemetry/api": "^1.0.1", + "@types/node-fetch": "^2.6.2", + "async-retry": "^1.3.3", + "loglevel": "^1.6.1", + "make-fetch-happen": "^11.0.0", + "node-abort-controller": "^3.0.1", + "node-fetch": "^2.6.7" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" + } + }, + "node_modules/@apollo/protobufjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", + "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "long": "^4.0.0" + }, + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" + } + }, + "node_modules/@apollo/query-graphs": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@apollo/query-graphs/-/query-graphs-2.8.4.tgz", + "integrity": "sha512-X2Y79efZh1RQ8aNi9iI+3ePWvyBm+oNW83P1xyxy3qBGFOBFne+YnoADK9tHM1FXLJ34cK03xxTdxY76V2Tteg==", + "dependencies": { + "@apollo/federation-internals": "2.8.4", + "deep-equal": "^2.0.5", + "ts-graphviz": "^1.5.4", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" + } + }, + "node_modules/@apollo/query-planner": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@apollo/query-planner/-/query-planner-2.8.4.tgz", + "integrity": "sha512-HNIyYeaIvj9/5Qem7p7w5we3SEaNJeTO77tpP7jkaaYxd+FOHtlwfMM0/5X814kl2eiaMposz78Kv+JF2582Gg==", + "dependencies": { + "@apollo/federation-internals": "2.8.4", + "@apollo/query-graphs": "2.8.4", + "@apollo/utils.keyvaluecache": "^2.1.0", + "chalk": "^4.1.0", + "deep-equal": "^2.0.5", + "pretty-format": "^29.0.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "graphql": "^16.5.0" + } + }, + "node_modules/@apollo/server": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.11.0.tgz", + "integrity": "sha512-SWDvbbs0wl2zYhKG6aGLxwTJ72xpqp0awb2lotNpfezd9VcAvzaUizzKQqocephin2uMoaA8MguoyBmgtPzNWw==", + "dependencies": { + "@apollo/cache-control-types": "^1.0.3", + "@apollo/server-gateway-interface": "^1.1.1", + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.createhash": "^2.0.0", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.isnodelike": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0", + "@apollo/utils.usagereporting": "^2.1.0", + "@apollo/utils.withrequired": "^2.0.0", + "@graphql-tools/schema": "^9.0.0", + "@types/express": "^4.17.13", + "@types/express-serve-static-core": "^4.17.30", + "@types/node-fetch": "^2.6.1", + "async-retry": "^1.2.1", + "cors": "^2.8.5", + "express": "^4.17.1", + "loglevel": "^1.6.8", + "lru-cache": "^7.10.1", + "negotiator": "^0.6.3", + "node-abort-controller": "^3.1.1", + "node-fetch": "^2.6.7", + "uuid": "^9.0.0", + "whatwg-mimetype": "^3.0.0" + }, + "engines": { + "node": ">=14.16.0" + }, + "peerDependencies": { + "graphql": "^16.6.0" + } + }, + "node_modules/@apollo/server-gateway-interface": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@apollo/server-gateway-interface/-/server-gateway-interface-1.1.1.tgz", + "integrity": "sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==", + "dependencies": { + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/usage-reporting-protobuf": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.1.tgz", + "integrity": "sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==", + "dependencies": { + "@apollo/protobufjs": "1.2.7" + } + }, + "node_modules/@apollo/utils.createhash": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.createhash/-/utils.createhash-2.0.1.tgz", + "integrity": "sha512-fQO4/ZOP8LcXWvMNhKiee+2KuKyqIcfHrICA+M4lj/h/Lh1H10ICcUtk6N/chnEo5HXu0yejg64wshdaiFitJg==", + "dependencies": { + "@apollo/utils.isnodelike": "^2.0.1", + "sha.js": "^2.4.11" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.dropunuseddefinitions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-2.0.1.tgz", + "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.fetcher": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.fetcher/-/utils.fetcher-2.0.1.tgz", + "integrity": "sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.isnodelike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.isnodelike/-/utils.isnodelike-2.0.1.tgz", + "integrity": "sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.keyvaluecache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-2.1.1.tgz", + "integrity": "sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==", + "dependencies": { + "@apollo/utils.logger": "^2.0.1", + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.logger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-2.0.1.tgz", + "integrity": "sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.printwithreducedwhitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-2.0.1.tgz", + "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.removealiases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-2.0.1.tgz", + "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.sortast": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-2.0.1.tgz", + "integrity": "sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==", + "dependencies": { + "lodash.sortby": "^4.7.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.stripsensitiveliterals": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-2.0.1.tgz", + "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.usagereporting": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-2.1.0.tgz", + "integrity": "sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==", + "dependencies": { + "@apollo/usage-reporting-protobuf": "^4.1.0", + "@apollo/utils.dropunuseddefinitions": "^2.0.1", + "@apollo/utils.printwithreducedwhitespace": "^2.0.1", + "@apollo/utils.removealiases": "2.0.1", + "@apollo/utils.sortast": "^2.0.1", + "@apollo/utils.stripsensitiveliterals": "^2.0.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.withrequired": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.withrequired/-/utils.withrequired-2.0.1.tgz", + "integrity": "sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@graphql-tools/merge": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.2.tgz", + "integrity": "sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==", + "dependencies": { + "@graphql-tools/utils": "^9.2.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema": { + "version": "9.0.19", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.19.tgz", + "integrity": "sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==", + "dependencies": { + "@graphql-tools/merge": "^8.4.1", + "@graphql-tools/utils": "^9.2.1", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/utils": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@josephg/resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", + "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/node": { + "version": "22.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.2.tgz", + "integrity": "sha512-nAvM3Ey230/XzxtyDcJ+VjvlzpzoHwLsF7JaDRfoI0ytO0mVheerNmM45CtA0yOILXwXXxOrcUWH3wltX+7PSw==", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphql": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", + "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socks-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" + }, + "node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-graphviz": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-1.8.2.tgz", + "integrity": "sha512-5YhbFoHmjxa7pgQLkB07MtGnGJ/yhvjmc9uhsnDBEICME6gkPf83SBwLDQqGDoCa3XzUMWLk1AU2Wn1u1naDtA==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-or-promise": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", + "engines": { + "node": ">=12" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/examples/federation/package.json b/examples/federation/package.json new file mode 100644 index 0000000000..410141cfa2 --- /dev/null +++ b/examples/federation/package.json @@ -0,0 +1,18 @@ +{ + "name": "federation", + "version": "1.0.0", + "main": "gateway.js", + "type": "module", + "scripts": { + "start": "node gateway.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "@apollo/gateway": "^2.8.4", + "@apollo/server": "^4.11.0", + "graphql": "^16.9.0" + } +} diff --git a/examples/federation/rover.sh b/examples/federation/rover.sh new file mode 100755 index 0000000000..aadf665b04 --- /dev/null +++ b/examples/federation/rover.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -eumo pipefail + +function cleanup { + for pid in "${USER_ROVER_PID:-}"; do + # try kill all registered pids + [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null && kill "$pid" || echo "Could not kill $pid" + done +} +trap cleanup EXIT + +rover dev --url http://localhost:8001/graphql --name post & +sleep 1 +rover dev --url http://localhost:8002/graphql --name user & +USER_ROVER_PID=$! +sleep 1 +fg %1 diff --git a/generated/.tailcallrc.graphql b/generated/.tailcallrc.graphql index bcb21779c5..2eb5cf2714 100644 --- a/generated/.tailcallrc.graphql +++ b/generated/.tailcallrc.graphql @@ -40,7 +40,7 @@ directive @call( of the previous step is passed as input to the next step. """ steps: [Step] -) on FIELD_DEFINITION +) on FIELD_DEFINITION | OBJECT """ The `@expr` operators allows you to specify an expression that can evaluate to a @@ -48,7 +48,7 @@ value. The expression can be a static value or built form a Mustache template. s """ directive @expr( body: JSON -) on FIELD_DEFINITION +) on FIELD_DEFINITION | OBJECT """ The @graphQL operator allows to specify GraphQL API server request to fetch data @@ -82,7 +82,7 @@ directive @graphQL( field, Tailcall requests data from the corresponding upstream field. """ name: String! -) on FIELD_DEFINITION +) on FIELD_DEFINITION | OBJECT """ The @grpc operator indicates that a field or node is backed by a gRPC API.For instance, @@ -120,7 +120,7 @@ directive @grpc( This refers to the gRPC method you're going to call. For instance `GetAllNews`. """ method: String! -) on FIELD_DEFINITION +) on FIELD_DEFINITION | OBJECT """ The @http operator indicates that a field or node is backed by a REST API.For instance, @@ -190,11 +190,11 @@ directive @http( is automatically selected as the batching parameter. """ query: [URLQuery] -) on FIELD_DEFINITION +) on FIELD_DEFINITION | OBJECT directive @js( name: String! -) on FIELD_DEFINITION +) on FIELD_DEFINITION | OBJECT """ The @link directive allows you to import external resources, such as configuration diff --git a/generated/.tailcallrc.schema.json b/generated/.tailcallrc.schema.json index ef06397799..2261b63111 100644 --- a/generated/.tailcallrc.schema.json +++ b/generated/.tailcallrc.schema.json @@ -777,6 +777,18 @@ "title": "JSON", "description": "Field whose value conforms to the standard JSON format as specified in RFC 8259 (https://datatracker.ietf.org/doc/html/rfc8259)." }, + "Key": { + "description": "Directive `@key` for Apollo Federation", + "type": "object", + "required": [ + "fields" + ], + "properties": { + "fields": { + "type": "string" + } + } + }, "KeyValue": { "type": "object", "required": [ @@ -1245,6 +1257,80 @@ "Type": { "description": "Represents a GraphQL type. A type can be an object, interface, enum or scalar.", "type": "object", + "oneOf": [ + { + "type": "object", + "required": [ + "http" + ], + "properties": { + "http": { + "$ref": "#/definitions/Http" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "grpc" + ], + "properties": { + "grpc": { + "$ref": "#/definitions/Grpc" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "graphql" + ], + "properties": { + "graphql": { + "$ref": "#/definitions/GraphQL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "call" + ], + "properties": { + "call": { + "$ref": "#/definitions/Call" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "js" + ], + "properties": { + "js": { + "$ref": "#/definitions/JS" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "expr" + ], + "properties": { + "expr": { + "$ref": "#/definitions/Expr" + } + }, + "additionalProperties": false + } + ], "required": [ "fields" ], @@ -1289,6 +1375,18 @@ }, "uniqueItems": true }, + "key": { + "description": "Apollo federation key directive. skip since it's set automatically by config transformer", + "writeOnly": true, + "anyOf": [ + { + "$ref": "#/definitions/Key" + }, + { + "type": "null" + } + ] + }, "protected": { "description": "Marks field as protected by auth providers", "default": null, diff --git a/src/core/app_context.rs b/src/core/app_context.rs index 1e06f46b1d..fcc628a598 100644 --- a/src/core/app_context.rs +++ b/src/core/app_context.rs @@ -43,16 +43,18 @@ impl AppContext { for def in blueprint.definitions.iter_mut() { if let Definition::Object(def) = def { for field in &mut def.fields { - let of_type = field.of_type.clone(); let upstream_batch = &blueprint.upstream.batch; field.map_expr(|expr| { - expr.modify(|expr| match expr { + expr.modify(&mut |expr| match expr { IR::IO(io) => match io { - IO::Http { req_template, group_by, http_filter, .. } => { + IO::Http { + req_template, group_by, http_filter, is_list, .. + } => { + let is_list = *is_list; let data_loader = HttpDataLoader::new( runtime.clone(), group_by.clone(), - of_type.is_list(), + is_list, ) .to_data_loader(upstream_batch.clone().unwrap_or_default()); @@ -61,6 +63,7 @@ impl AppContext { group_by: group_by.clone(), dl_id: Some(DataLoaderId::new(http_data_loaders.len())), http_filter: http_filter.clone(), + is_list, })); http_data_loaders.push(data_loader); diff --git a/src/core/blueprint/definitions.rs b/src/core/blueprint/definitions.rs index 7a029afc08..c7e47650a9 100644 --- a/src/core/blueprint/definitions.rs +++ b/src/core/blueprint/definitions.rs @@ -492,6 +492,7 @@ pub fn to_field_definition( name: &String, ) -> Valid { update_args() + .and(update_apollo_federation(operation_type).trace("_entities")) .and(update_http().trace(config::Http::trace_name().as_str())) .and(update_grpc(operation_type).trace(config::Grpc::trace_name().as_str())) .and(update_const_field().trace(config::Expr::trace_name().as_str())) diff --git a/src/core/blueprint/operators/apollo_federation.rs b/src/core/blueprint/operators/apollo_federation.rs new file mode 100644 index 0000000000..a078e6fe8c --- /dev/null +++ b/src/core/blueprint/operators/apollo_federation.rs @@ -0,0 +1,163 @@ +use std::collections::HashMap; +use std::fmt::Write; + +use async_graphql::parser::types::{SchemaDefinition, ServiceDocument, TypeSystemDefinition}; + +use super::{compile_call, compile_expr, compile_graphql, compile_grpc, compile_http, compile_js}; +use crate::core::blueprint::FieldDefinition; +use crate::core::config::{ + ApolloFederation, Config, ConfigModule, EntityResolver, Field, GraphQLOperationType, Resolver, +}; +use crate::core::ir::model::IR; +use crate::core::try_fold::TryFold; +use crate::core::valid::{Valid, Validator}; +use crate::core::{config, Type}; + +pub struct CompileEntityResolver<'a> { + config_module: &'a ConfigModule, + entity_resolver: &'a EntityResolver, + operation_type: &'a GraphQLOperationType, +} + +pub fn compile_entity_resolver(inputs: CompileEntityResolver<'_>) -> Valid { + let CompileEntityResolver { config_module, entity_resolver, operation_type } = inputs; + let mut resolver_by_type = HashMap::new(); + + Valid::from_iter( + entity_resolver.resolver_by_type.iter(), + |(type_name, resolver)| { + // Fake field that is required for validation in some cases + // TODO: should be a proper way to run the validation both + // on types and fields + let field = &Field { type_of: Type::from(type_name.clone()), ..Default::default() }; + + // TODO: make this code reusable in other operators like call + let ir = match resolver { + // TODO: there are `validate_field` for field, but not for types + // implement validation as shared entity and use it for types + Resolver::Http(http) => compile_http( + config_module, + http, + // inner resolver should resolve only single instance of type, not a list + false, + ), + Resolver::Grpc(grpc) => compile_grpc(super::CompileGrpc { + config_module, + operation_type, + field, + grpc, + validate_with_schema: true, + }), + Resolver::Graphql(graphql) => { + compile_graphql(config_module, operation_type, type_name, graphql) + } + Resolver::Call(call) => { + compile_call(config_module, call, operation_type, type_name) + } + Resolver::Js(js) => { + compile_js(super::CompileJs { js, script: &config_module.extensions().script }) + } + Resolver::Expr(expr) => { + compile_expr(super::CompileExpr { config_module, field, expr, validate: true }) + } + Resolver::ApolloFederation(federation) => match federation { + ApolloFederation::EntityResolver(entity_resolver) => { + compile_entity_resolver(CompileEntityResolver { entity_resolver, ..inputs }) + } + ApolloFederation::Service => Valid::fail( + "Apollo federation resolvers can't be a part of entity resolver" + .to_string(), + ), + }, + }; + + ir.map(|ir| { + resolver_by_type.insert(type_name.to_owned(), ir); + }) + }, + ) + .map_to(IR::Entity(resolver_by_type)) +} + +pub fn compile_service(config: &ConfigModule) -> Valid { + let mut sdl = + crate::core::document::print(filter_conflicting_directives(config.config().into())); + + writeln!(sdl).ok(); + // Add tailcall specific definitions to the sdl output + writeln!( + sdl, + "{}", + crate::core::document::print(filter_conflicting_directives(Config::graphql_schema())) + ) + .ok(); + writeln!(sdl).ok(); + // Mark subgraph as Apollo federation v2 compatible according to [docs](https://www.apollographql.com/docs/apollo-server/using-federation/apollo-subgraph-setup/#2-opt-in-to-federation-2) + // (borrowed from async_graphql) + writeln!(sdl, "extend schema @link(").ok(); + writeln!(sdl, "\turl: \"https://specs.apollo.dev/federation/v2.3\",").ok(); + writeln!(sdl, "\timport: [\"@key\", \"@tag\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@composeDirective\", \"@interfaceObject\"]").ok(); + writeln!(sdl, ")").ok(); + + Valid::succeed(IR::Service(sdl)) +} + +fn filter_conflicting_directives(sd: ServiceDocument) -> ServiceDocument { + fn filter_directive(directive_name: &str) -> bool { + directive_name != "link" + } + + fn filter_map(def: TypeSystemDefinition) -> Option { + match def { + TypeSystemDefinition::Schema(schema) => { + Some(TypeSystemDefinition::Schema(schema.map(|schema| { + SchemaDefinition { + directives: schema + .directives + .into_iter() + .filter(|d| filter_directive(d.node.name.node.as_str())) + .collect(), + ..schema + } + }))) + } + TypeSystemDefinition::Directive(directive) => { + if filter_directive(directive.node.name.node.as_str()) { + Some(TypeSystemDefinition::Directive(directive)) + } else { + None + } + } + ty => Some(ty), + } + } + + ServiceDocument { + definitions: sd.definitions.into_iter().filter_map(filter_map).collect(), + } +} + +pub fn update_apollo_federation<'a>( + operation_type: &'a GraphQLOperationType, +) -> TryFold<'a, (&'a ConfigModule, &'a Field, &'a config::Type, &'a str), FieldDefinition, String> +{ + TryFold::<(&ConfigModule, &Field, &config::Type, &'a str), FieldDefinition, String>::new( + |(config_module, field, _, _), b_field| { + let Some(Resolver::ApolloFederation(federation)) = &field.resolver else { + return Valid::succeed(b_field); + }; + + match federation { + ApolloFederation::EntityResolver(entity_resolver) => { + compile_entity_resolver(CompileEntityResolver { + config_module, + entity_resolver, + operation_type, + }) + } + ApolloFederation::Service => compile_service(config_module), + } + .map(|resolver| b_field.resolver(Some(resolver))) + }, + ) +} diff --git a/src/core/blueprint/operators/call.rs b/src/core/blueprint/operators/call.rs index 3db52535b0..ebf8a2b361 100644 --- a/src/core/blueprint/operators/call.rs +++ b/src/core/blueprint/operators/call.rs @@ -13,23 +13,23 @@ pub fn update_call<'a>( ) -> TryFold<'a, (&'a ConfigModule, &'a Field, &'a config::Type, &'a str), FieldDefinition, String> { TryFold::<(&ConfigModule, &Field, &config::Type, &str), FieldDefinition, String>::new( - move |(config, field, _, name), b_field| { + move |(config, field, _, _), b_field| { let Some(Resolver::Call(call)) = &field.resolver else { return Valid::succeed(b_field); }; compile_call(config, call, operation_type, object_name) - .map(|field| b_field.resolver(field.resolver).name(name.to_string())) + .map(|resolver| b_field.resolver(Some(resolver))) }, ) } -fn compile_call( +pub fn compile_call( config_module: &ConfigModule, call: &config::Call, operation_type: &GraphQLOperationType, object_name: &str, -) -> Valid { +) -> Valid { Valid::from_iter(call.steps.iter(), |step| { get_field_and_field_name(step, config_module).and_then(|(field, field_name, type_of)| { let args = step.args.iter(); @@ -92,8 +92,6 @@ fn compile_call( .and_then(|b_fields| { Valid::from_option( b_fields.into_iter().reduce(|mut b_field, b_field_next| { - b_field.name = b_field_next.name; - b_field.of_type = b_field_next.of_type; b_field.map_expr(|expr| { b_field_next .resolver @@ -107,9 +105,14 @@ fn compile_call( "Steps can't be empty".to_string(), ) }) + .and_then(|field| { + Valid::from_option(field.resolver, "Result resolver can't be empty".to_string()) + }) } fn get_type_and_field(call: &config::Step) -> Option<(String, String)> { + // TODO: type names for query and mutations should be inferred from the + // config_module and should not be static values if let Some(query) = &call.query { Some(("Query".to_string(), query.clone())) } else { diff --git a/src/core/blueprint/operators/expr.rs b/src/core/blueprint/operators/expr.rs index de90d424b8..09dc6b7d7f 100644 --- a/src/core/blueprint/operators/expr.rs +++ b/src/core/blueprint/operators/expr.rs @@ -2,7 +2,7 @@ use async_graphql_value::ConstValue; use crate::core::blueprint::*; use crate::core::config; -use crate::core::config::{Field, Resolver}; +use crate::core::config::{Expr, Field, Resolver}; use crate::core::ir::model::IR; use crate::core::ir::model::IR::Dynamic; use crate::core::try_fold::TryFold; @@ -25,14 +25,14 @@ fn validate_data_with_schema( pub struct CompileExpr<'a> { pub config_module: &'a config::ConfigModule, pub field: &'a config::Field, - pub value: &'a serde_json::Value, + pub expr: &'a Expr, pub validate: bool, } pub fn compile_expr(inputs: CompileExpr) -> Valid { let config_module = inputs.config_module; let field = inputs.field; - let value = inputs.value; + let value = &inputs.expr.body; let validate = inputs.validate; Valid::from( @@ -68,7 +68,7 @@ pub fn update_const_field<'a>( return Valid::succeed(b_field); }; - compile_expr(CompileExpr { config_module, field, value: &expr.body, validate: true }) + compile_expr(CompileExpr { config_module, field, expr, validate: true }) .map(|resolver| b_field.resolver(Some(resolver))) }, ) diff --git a/src/core/blueprint/operators/graphql.rs b/src/core/blueprint/operators/graphql.rs index 0c7fba35af..394b1ca524 100644 --- a/src/core/blueprint/operators/graphql.rs +++ b/src/core/blueprint/operators/graphql.rs @@ -41,7 +41,7 @@ fn create_related_fields( } pub fn compile_graphql( - config: &Config, + config: &ConfigModule, operation_type: &GraphQLOperationType, type_name: &str, graphql: &GraphQL, diff --git a/src/core/blueprint/operators/http.rs b/src/core/blueprint/operators/http.rs index 4db8a2ae02..62ff58f2e1 100644 --- a/src/core/blueprint/operators/http.rs +++ b/src/core/blueprint/operators/http.rs @@ -11,6 +11,7 @@ use crate::core::{config, helpers, Mustache}; pub fn compile_http( config_module: &config::ConfigModule, http: &config::Http, + is_list: bool, ) -> Valid { Valid::<(), String>::fail("GroupBy is only supported for GET requests".to_string()) .when(|| !http.batch_key.is_empty() && http.method != Method::GET) @@ -79,9 +80,16 @@ pub fn compile_http( group_by: Some(GroupBy::new(http.batch_key.clone(), key)), dl_id: None, http_filter, + is_list, }) } else { - IR::IO(IO::Http { req_template, group_by: None, dl_id: None, http_filter }) + IR::IO(IO::Http { + req_template, + group_by: None, + dl_id: None, + http_filter, + is_list, + }) } }) } @@ -95,7 +103,7 @@ pub fn update_http<'a>( return Valid::succeed(b_field); }; - compile_http(config_module, http) + compile_http(config_module, http, field.type_of.is_list()) .map(|resolver| b_field.resolver(Some(resolver))) .and_then(|b_field| { b_field diff --git a/src/core/blueprint/operators/js.rs b/src/core/blueprint/operators/js.rs index cc6b212c60..cf61d20e19 100644 --- a/src/core/blueprint/operators/js.rs +++ b/src/core/blueprint/operators/js.rs @@ -1,17 +1,17 @@ use crate::core::blueprint::FieldDefinition; use crate::core::config; -use crate::core::config::{ConfigModule, Field, Resolver}; +use crate::core::config::{ConfigModule, Field, Resolver, JS}; use crate::core::ir::model::{IO, IR}; use crate::core::try_fold::TryFold; use crate::core::valid::{Valid, Validator}; pub struct CompileJs<'a> { - pub name: &'a str, + pub js: &'a JS, pub script: &'a Option, } pub fn compile_js(inputs: CompileJs) -> Valid { - let name = inputs.name; + let name = &inputs.js.name; Valid::from_option(inputs.script.as_ref(), "script is required".to_string()) .map(|_| IR::IO(IO::Js { name: name.to_string() })) } @@ -25,7 +25,7 @@ pub fn update_js_field<'a>( return Valid::succeed(b_field); }; - compile_js(CompileJs { script: &module.extensions().script, name: &js.name }) + compile_js(CompileJs { script: &module.extensions().script, js }) .map(|resolver| b_field.resolver(Some(resolver))) }, ) diff --git a/src/core/blueprint/operators/mod.rs b/src/core/blueprint/operators/mod.rs index 7ca9bf0e1a..2b4842899e 100644 --- a/src/core/blueprint/operators/mod.rs +++ b/src/core/blueprint/operators/mod.rs @@ -1,3 +1,4 @@ +mod apollo_federation; mod call; mod enum_alias; mod expr; @@ -8,6 +9,7 @@ mod js; mod modify; mod protected; +pub use apollo_federation::*; pub use call::*; pub use enum_alias::*; pub use expr::*; diff --git a/src/core/blueprint/snapshots/tailcall__core__blueprint__index__test__from_blueprint.snap b/src/core/blueprint/snapshots/tailcall__core__blueprint__index__test__from_blueprint.snap index fc441a38e2..1f46ab6ccc 100644 --- a/src/core/blueprint/snapshots/tailcall__core__blueprint__index__test__from_blueprint.snap +++ b/src/core/blueprint/snapshots/tailcall__core__blueprint__index__test__from_blueprint.snap @@ -69,6 +69,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: false, }, ), ), @@ -136,6 +137,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: false, }, ), ), @@ -211,6 +213,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: false, }, ), ), @@ -290,6 +293,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: false, }, ), ), @@ -685,6 +689,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: true, }, ), ), @@ -746,6 +751,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: false, }, ), ), @@ -844,6 +850,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: true, }, ), ), @@ -917,6 +924,7 @@ Index { group_by: None, dl_id: None, http_filter: None, + is_list: false, }, ), ), diff --git a/src/core/config/config.rs b/src/core/config/config.rs index 952de581a3..d04c0f3fe8 100644 --- a/src/core/config/config.rs +++ b/src/core/config/config.rs @@ -3,27 +3,23 @@ use std::fmt::{self, Display}; use std::num::NonZeroU64; use anyhow::Result; -use async_graphql::parser::types::{ConstDirective, ServiceDocument}; -use async_graphql::Positioned; +use async_graphql::parser::types::ServiceDocument; use derive_setters::Setters; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; use serde_json::Value; -use tailcall_macros::{CustomResolver, DirectiveDefinition, InputDefinition}; +use tailcall_macros::{DirectiveDefinition, InputDefinition}; use tailcall_typedefs_common::directive_definition::DirectiveDefinition; use tailcall_typedefs_common::input_definition::InputDefinition; use tailcall_typedefs_common::ServiceDocumentBuilder; +use super::directives::{Call, Expr, GraphQL, Grpc, Http, Key, JS}; +use super::from_document::from_document; use super::telemetry::Telemetry; -use super::{KeyValue, Link, Server, Upstream}; -use crate::core::config::from_document::from_document; +use super::{Link, Resolver, Server, Upstream}; use crate::core::config::npo::QueryPath; use crate::core::config::source::Source; -use crate::core::config::url_query::URLQuery; -use crate::core::directive::DirectiveCodec; -use crate::core::http::Method; use crate::core::is_default; -use crate::core::json::JsonSchema; use crate::core::macros::MergeRight; use crate::core::merge_right::MergeRight; use crate::core::scalar::Scalar; @@ -116,6 +112,17 @@ pub struct Type { /// Marks field as protected by auth providers #[serde(default)] pub protected: Option, + + /// + /// Apollo federation entity resolver. + #[serde(flatten, default, skip_serializing_if = "is_default")] + pub resolver: Option, + + /// + /// Apollo federation key directive. + /// skip since it's set automatically by config transformer + #[serde(skip_serializing)] + pub key: Option, } impl Display for Type { @@ -211,19 +218,6 @@ pub struct RootSchema { /// Used to omit a field from public consumption. pub struct Omit {} -#[derive( - Serialize, Deserialize, Clone, Debug, PartialEq, Eq, schemars::JsonSchema, CustomResolver, -)] -#[serde(rename_all = "camelCase")] -pub enum Resolver { - Http(Http), - Grpc(Grpc), - Graphql(GraphQL), - Call(Call), - Js(JS), - Expr(Expr), -} - /// /// A field definition containing all the metadata information about resolving a /// field. @@ -289,19 +283,12 @@ impl Field { pub fn has_resolver(&self) -> bool { self.resolver.is_some() } + pub fn has_batched_resolver(&self) -> bool { - if let Some(resolver) = &self.resolver { - match resolver { - Resolver::Http(http) => !http.batch_key.is_empty(), - Resolver::Grpc(grpc) => !grpc.batch_key.is_empty(), - Resolver::Graphql(graphql) => graphql.batch, - Resolver::Call(_) => false, - Resolver::Js(_) => false, - Resolver::Expr(_) => false, - } - } else { - false - } + self.resolver + .as_ref() + .map(Resolver::is_batched) + .unwrap_or(false) } pub fn int() -> Self { @@ -334,22 +321,6 @@ impl Field { } } -#[derive( - Serialize, - Deserialize, - Clone, - Debug, - PartialEq, - Eq, - schemars::JsonSchema, - DirectiveDefinition, - InputDefinition, -)] -#[directive_definition(locations = "FieldDefinition", lowercase_name)] -pub struct JS { - pub name: String, -} - #[derive( Serialize, Deserialize, @@ -440,228 +411,6 @@ pub struct Alias { pub options: BTreeSet, } -#[derive( - Serialize, - Deserialize, - Clone, - Debug, - Default, - PartialEq, - Eq, - schemars::JsonSchema, - DirectiveDefinition, - InputDefinition, -)] -#[directive_definition(locations = "FieldDefinition")] -#[serde(deny_unknown_fields)] -/// The @http operator indicates that a field or node is backed by a REST API. -/// -/// For instance, if you add the @http operator to the `users` field of the -/// Query type with a path argument of `"/users"`, it signifies that the `users` -/// field is backed by a REST API. The path argument specifies the path of the -/// REST API. In this scenario, the GraphQL server will make a GET request to -/// the API endpoint specified when the `users` field is queried. -pub struct Http { - #[serde(rename = "onRequest", default, skip_serializing_if = "is_default")] - /// onRequest field in @http directive gives the ability to specify the - /// request interception handler. - pub on_request: Option, - - #[serde(rename = "baseURL", default, skip_serializing_if = "is_default")] - /// This refers to the base URL of the API. If not specified, the default - /// base URL is the one specified in the `@upstream` operator. - pub base_url: Option, - - #[serde(default, skip_serializing_if = "is_default")] - /// The body of the API call. It's used for methods like POST or PUT that - /// send data to the server. You can pass it as a static object or use a - /// Mustache template to substitute variables from the GraphQL variables. - pub body: Option, - - #[serde(default, skip_serializing_if = "is_default")] - /// The `encoding` parameter specifies the encoding of the request body. It - /// can be `ApplicationJson` or `ApplicationXWwwFormUrlEncoded`. @default - /// `ApplicationJson`. - pub encoding: Encoding, - - #[serde(rename = "batchKey", default, skip_serializing_if = "is_default")] - /// The `batchKey` dictates the path Tailcall will follow to group the returned items from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching). - pub batch_key: Vec, - - #[serde(default, skip_serializing_if = "is_default")] - /// The `headers` parameter allows you to customize the headers of the HTTP - /// request made by the `@http` operator. It is used by specifying a - /// key-value map of header names and their values. - pub headers: Vec, - - #[serde(default, skip_serializing_if = "is_default")] - /// Schema of the input of the API call. It is automatically inferred in - /// most cases. - pub input: Option, - - #[serde(default, skip_serializing_if = "is_default")] - /// This refers to the HTTP method of the API call. Commonly used methods - /// include `GET`, `POST`, `PUT`, `DELETE` etc. @default `GET`. - pub method: Method, - - /// This refers to the API endpoint you're going to call. For instance `https://jsonplaceholder.typicode.com/users`. - /// - /// For dynamic segments in your API endpoint, use Mustache templates for - /// variable substitution. For instance, to fetch a specific user, use - /// `/users/{{args.id}}`. - pub path: String, - - #[serde(default, skip_serializing_if = "is_default")] - /// Schema of the output of the API call. It is automatically inferred in - /// most cases. - pub output: Option, - - #[serde(default, skip_serializing_if = "is_default")] - /// This represents the query parameters of your API call. You can pass it - /// as a static object or use Mustache template for dynamic parameters. - /// These parameters will be added to the URL. - /// NOTE: Query parameter order is critical for batching in Tailcall. The - /// first parameter referencing a field in the current value using mustache - /// syntax is automatically selected as the batching parameter. - pub query: Vec, -} - -/// -/// Provides the ability to refer to multiple fields in the Query or -/// Mutation root. -#[derive( - Serialize, - Deserialize, - Clone, - Debug, - Default, - PartialEq, - Eq, - schemars::JsonSchema, - DirectiveDefinition, -)] -#[directive_definition(locations = "FieldDefinition")] -pub struct Call { - /// Steps are composed together to form a call. - /// If you have multiple steps, the output of the previous step is passed as - /// input to the next step. - pub steps: Vec, -} - -/// -/// Provides the ability to refer to a field defined in the root Query or -/// Mutation. -#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, schemars::JsonSchema)] -pub struct Step { - #[serde(default, skip_serializing_if = "is_default")] - /// The name of the field on the `Query` type that you want to call. - pub query: Option, - - #[serde(default, skip_serializing_if = "is_default")] - /// The name of the field on the `Mutation` type that you want to call. - pub mutation: Option, - - /// The arguments that will override the actual arguments of the field. - #[serde(default, skip_serializing_if = "is_default")] - pub args: BTreeMap, -} - -#[derive( - Serialize, - Deserialize, - Clone, - Debug, - Default, - PartialEq, - Eq, - schemars::JsonSchema, - InputDefinition, - DirectiveDefinition, -)] -#[directive_definition(locations = "FieldDefinition")] -#[serde(rename_all = "camelCase")] -#[serde(deny_unknown_fields)] -/// The @grpc operator indicates that a field or node is backed by a gRPC API. -/// -/// For instance, if you add the @grpc operator to the `users` field of the -/// Query type with a service argument of `NewsService` and method argument of -/// `GetAllNews`, it signifies that the `users` field is backed by a gRPC API. -/// The `service` argument specifies the name of the gRPC service. -/// The `method` argument specifies the name of the gRPC method. -/// In this scenario, the GraphQL server will make a gRPC request to the gRPC -/// endpoint specified when the `users` field is queried. -pub struct Grpc { - #[serde(rename = "baseURL", default, skip_serializing_if = "is_default")] - /// This refers to the base URL of the API. If not specified, the default - /// base URL is the one specified in the `@upstream` operator. - pub base_url: Option, - #[serde(default, skip_serializing_if = "is_default")] - /// This refers to the arguments of your gRPC call. You can pass it as a - /// static object or use Mustache template for dynamic parameters. These - /// parameters will be added in the body in `protobuf` format. - pub body: Option, - #[serde(rename = "batchKey", default, skip_serializing_if = "is_default")] - /// The `batchKey` dictates the path Tailcall will follow to group the returned items from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching). - pub batch_key: Vec, - #[serde(default, skip_serializing_if = "is_default")] - /// The `headers` parameter allows you to customize the headers of the HTTP - /// request made by the `@grpc` operator. It is used by specifying a - /// key-value map of header names and their values. Note: content-type is - /// automatically set to application/grpc - pub headers: Vec, - /// This refers to the gRPC method you're going to call. For instance - /// `GetAllNews`. - pub method: String, -} - -#[derive( - Serialize, - Deserialize, - Clone, - Debug, - Default, - PartialEq, - Eq, - schemars::JsonSchema, - DirectiveDefinition, - InputDefinition, -)] -#[directive_definition(locations = "FieldDefinition")] -#[serde(deny_unknown_fields)] -/// The @graphQL operator allows to specify GraphQL API server request to fetch -/// data from. -pub struct GraphQL { - #[serde(default, skip_serializing_if = "is_default")] - /// Named arguments for the requested field. More info [here](https://tailcall.run/docs/guides/operators/#args) - pub args: Option>, - - #[serde(rename = "baseURL", default, skip_serializing_if = "is_default")] - /// This refers to the base URL of the API. If not specified, the default - /// base URL is the one specified in the `@upstream` operator. - pub base_url: Option, - - #[serde(default, skip_serializing_if = "is_default")] - /// If the upstream GraphQL server supports request batching, you can - /// specify the 'batch' argument to batch several requests into a single - /// batch request. - /// - /// Make sure you have also specified batch settings to the `@upstream` and - /// to the `@graphQL` operator. - pub batch: bool, - - #[serde(default, skip_serializing_if = "is_default")] - /// The headers parameter allows you to customize the headers of the GraphQL - /// request made by the `@graphQL` operator. It is used by specifying a - /// key-value map of header names and their values. - pub headers: Vec, - - /// Specifies the root field on the upstream to request data from. This maps - /// a field in your schema to a field in the upstream schema. When a query - /// is received for this field, Tailcall requests data from the - /// corresponding upstream field. - pub name: String, -} - #[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum GraphQLOperationType { @@ -679,26 +428,6 @@ impl Display for GraphQLOperationType { } } -#[derive( - Serialize, - Deserialize, - Clone, - Debug, - PartialEq, - Eq, - schemars::JsonSchema, - DirectiveDefinition, - InputDefinition, -)] -#[directive_definition(locations = "FieldDefinition")] -#[serde(deny_unknown_fields)] -/// The `@expr` operators allows you to specify an expression that can evaluate -/// to a value. The expression can be a static value or built form a Mustache -/// template. schema. -pub struct Expr { - pub body: Value, -} - #[derive( Serialize, Deserialize, Clone, Debug, PartialEq, Eq, schemars::JsonSchema, DirectiveDefinition, )] @@ -1017,6 +746,7 @@ mod tests { use pretty_assertions::assert_eq; use super::*; + use crate::core::directive::DirectiveCodec; #[test] fn test_field_has_or_not_batch_resolver() { diff --git a/src/core/config/directives/call.rs b/src/core/config/directives/call.rs new file mode 100644 index 0000000000..250f7bebf2 --- /dev/null +++ b/src/core/config/directives/call.rs @@ -0,0 +1,47 @@ +use std::collections::BTreeMap; + +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tailcall_macros::DirectiveDefinition; + +use crate::core::is_default; + +/// +/// Provides the ability to refer to a field defined in the root Query or +/// Mutation. +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, schemars::JsonSchema)] +pub struct Step { + #[serde(default, skip_serializing_if = "is_default")] + /// The name of the field on the `Query` type that you want to call. + pub query: Option, + + #[serde(default, skip_serializing_if = "is_default")] + /// The name of the field on the `Mutation` type that you want to call. + pub mutation: Option, + + /// The arguments that will override the actual arguments of the field. + #[serde(default, skip_serializing_if = "is_default")] + pub args: BTreeMap, +} + +/// +/// Provides the ability to refer to multiple fields in the Query or +/// Mutation root. +#[derive( + Serialize, + Deserialize, + Clone, + Debug, + Default, + PartialEq, + Eq, + schemars::JsonSchema, + DirectiveDefinition, +)] +#[directive_definition(locations = "FieldDefinition, Object")] +pub struct Call { + /// Steps are composed together to form a call. + /// If you have multiple steps, the output of the previous step is passed as + /// input to the next step. + pub steps: Vec, +} diff --git a/src/core/config/directives/expr.rs b/src/core/config/directives/expr.rs new file mode 100644 index 0000000000..39dcced1ce --- /dev/null +++ b/src/core/config/directives/expr.rs @@ -0,0 +1,23 @@ +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tailcall_macros::{DirectiveDefinition, InputDefinition}; + +#[derive( + Serialize, + Deserialize, + Clone, + Debug, + PartialEq, + Eq, + schemars::JsonSchema, + DirectiveDefinition, + InputDefinition, +)] +#[directive_definition(locations = "FieldDefinition, Object")] +#[serde(deny_unknown_fields)] +/// The `@expr` operators allows you to specify an expression that can evaluate +/// to a value. The expression can be a static value or built form a Mustache +/// template. schema. +pub struct Expr { + pub body: Value, +} diff --git a/src/core/config/directives/federation.rs b/src/core/config/directives/federation.rs new file mode 100644 index 0000000000..d956e9b6b6 --- /dev/null +++ b/src/core/config/directives/federation.rs @@ -0,0 +1,21 @@ +use std::collections::BTreeMap; + +use serde::{Deserialize, Serialize}; +use tailcall_macros::MergeRight; + +use crate::core::config::Resolver; +use crate::core::merge_right::MergeRight; + +/// Directive `@key` for Apollo Federation +#[derive( + Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, schemars::JsonSchema, MergeRight, +)] +pub struct Key { + pub fields: String, +} + +/// Resolver for `_entities` field for Apollo Federation +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct EntityResolver { + pub resolver_by_type: BTreeMap, +} diff --git a/src/core/config/directives/graphql.rs b/src/core/config/directives/graphql.rs new file mode 100644 index 0000000000..e9bef555d1 --- /dev/null +++ b/src/core/config/directives/graphql.rs @@ -0,0 +1,53 @@ +use serde::{Deserialize, Serialize}; +use tailcall_macros::{DirectiveDefinition, InputDefinition}; + +use crate::core::config::KeyValue; +use crate::core::is_default; + +#[derive( + Serialize, + Deserialize, + Clone, + Debug, + Default, + PartialEq, + Eq, + schemars::JsonSchema, + DirectiveDefinition, + InputDefinition, +)] +#[directive_definition(locations = "FieldDefinition, Object")] +#[serde(deny_unknown_fields)] +/// The @graphQL operator allows to specify GraphQL API server request to fetch +/// data from. +pub struct GraphQL { + #[serde(default, skip_serializing_if = "is_default")] + /// Named arguments for the requested field. More info [here](https://tailcall.run/docs/guides/operators/#args) + pub args: Option>, + + #[serde(rename = "baseURL", default, skip_serializing_if = "is_default")] + /// This refers to the base URL of the API. If not specified, the default + /// base URL is the one specified in the `@upstream` operator. + pub base_url: Option, + + #[serde(default, skip_serializing_if = "is_default")] + /// If the upstream GraphQL server supports request batching, you can + /// specify the 'batch' argument to batch several requests into a single + /// batch request. + /// + /// Make sure you have also specified batch settings to the `@upstream` and + /// to the `@graphQL` operator. + pub batch: bool, + + #[serde(default, skip_serializing_if = "is_default")] + /// The headers parameter allows you to customize the headers of the GraphQL + /// request made by the `@graphQL` operator. It is used by specifying a + /// key-value map of header names and their values. + pub headers: Vec, + + /// Specifies the root field on the upstream to request data from. This maps + /// a field in your schema to a field in the upstream schema. When a query + /// is received for this field, Tailcall requests data from the + /// corresponding upstream field. + pub name: String, +} diff --git a/src/core/config/directives/grpc.rs b/src/core/config/directives/grpc.rs new file mode 100644 index 0000000000..9ee9a6a126 --- /dev/null +++ b/src/core/config/directives/grpc.rs @@ -0,0 +1,54 @@ +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tailcall_macros::{DirectiveDefinition, InputDefinition}; + +use crate::core::config::KeyValue; +use crate::core::is_default; + +#[derive( + Serialize, + Deserialize, + Clone, + Debug, + Default, + PartialEq, + Eq, + schemars::JsonSchema, + InputDefinition, + DirectiveDefinition, +)] +#[directive_definition(locations = "FieldDefinition, Object")] +#[serde(rename_all = "camelCase")] +#[serde(deny_unknown_fields)] +/// The @grpc operator indicates that a field or node is backed by a gRPC API. +/// +/// For instance, if you add the @grpc operator to the `users` field of the +/// Query type with a service argument of `NewsService` and method argument of +/// `GetAllNews`, it signifies that the `users` field is backed by a gRPC API. +/// The `service` argument specifies the name of the gRPC service. +/// The `method` argument specifies the name of the gRPC method. +/// In this scenario, the GraphQL server will make a gRPC request to the gRPC +/// endpoint specified when the `users` field is queried. +pub struct Grpc { + #[serde(rename = "baseURL", default, skip_serializing_if = "is_default")] + /// This refers to the base URL of the API. If not specified, the default + /// base URL is the one specified in the `@upstream` operator. + pub base_url: Option, + #[serde(default, skip_serializing_if = "is_default")] + /// This refers to the arguments of your gRPC call. You can pass it as a + /// static object or use Mustache template for dynamic parameters. These + /// parameters will be added in the body in `protobuf` format. + pub body: Option, + #[serde(rename = "batchKey", default, skip_serializing_if = "is_default")] + /// The `batchKey` dictates the path Tailcall will follow to group the returned items from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching). + pub batch_key: Vec, + #[serde(default, skip_serializing_if = "is_default")] + /// The `headers` parameter allows you to customize the headers of the HTTP + /// request made by the `@grpc` operator. It is used by specifying a + /// key-value map of header names and their values. Note: content-type is + /// automatically set to application/grpc + pub headers: Vec, + /// This refers to the gRPC method you're going to call. For instance + /// `GetAllNews`. + pub method: String, +} diff --git a/src/core/config/directives/http.rs b/src/core/config/directives/http.rs new file mode 100644 index 0000000000..35e4ff3ca4 --- /dev/null +++ b/src/core/config/directives/http.rs @@ -0,0 +1,93 @@ +use serde::{Deserialize, Serialize}; +use tailcall_macros::{DirectiveDefinition, InputDefinition}; + +use crate::core::config::{Encoding, KeyValue, URLQuery}; +use crate::core::http::Method; +use crate::core::is_default; +use crate::core::json::JsonSchema; + +#[derive( + Serialize, + Deserialize, + Clone, + Debug, + Default, + PartialEq, + Eq, + schemars::JsonSchema, + DirectiveDefinition, + InputDefinition, +)] +#[directive_definition(locations = "FieldDefinition, Object")] +#[serde(deny_unknown_fields)] +/// The @http operator indicates that a field or node is backed by a REST API. +/// +/// For instance, if you add the @http operator to the `users` field of the +/// Query type with a path argument of `"/users"`, it signifies that the `users` +/// field is backed by a REST API. The path argument specifies the path of the +/// REST API. In this scenario, the GraphQL server will make a GET request to +/// the API endpoint specified when the `users` field is queried. +pub struct Http { + #[serde(rename = "onRequest", default, skip_serializing_if = "is_default")] + /// onRequest field in @http directive gives the ability to specify the + /// request interception handler. + pub on_request: Option, + + #[serde(rename = "baseURL", default, skip_serializing_if = "is_default")] + /// This refers to the base URL of the API. If not specified, the default + /// base URL is the one specified in the `@upstream` operator. + pub base_url: Option, + + #[serde(default, skip_serializing_if = "is_default")] + /// The body of the API call. It's used for methods like POST or PUT that + /// send data to the server. You can pass it as a static object or use a + /// Mustache template to substitute variables from the GraphQL variables. + pub body: Option, + + #[serde(default, skip_serializing_if = "is_default")] + /// The `encoding` parameter specifies the encoding of the request body. It + /// can be `ApplicationJson` or `ApplicationXWwwFormUrlEncoded`. @default + /// `ApplicationJson`. + pub encoding: Encoding, + + #[serde(rename = "batchKey", default, skip_serializing_if = "is_default")] + /// The `batchKey` dictates the path Tailcall will follow to group the returned items from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching). + pub batch_key: Vec, + + #[serde(default, skip_serializing_if = "is_default")] + /// The `headers` parameter allows you to customize the headers of the HTTP + /// request made by the `@http` operator. It is used by specifying a + /// key-value map of header names and their values. + pub headers: Vec, + + #[serde(default, skip_serializing_if = "is_default")] + /// Schema of the input of the API call. It is automatically inferred in + /// most cases. + pub input: Option, + + #[serde(default, skip_serializing_if = "is_default")] + /// This refers to the HTTP method of the API call. Commonly used methods + /// include `GET`, `POST`, `PUT`, `DELETE` etc. @default `GET`. + pub method: Method, + + /// This refers to the API endpoint you're going to call. For instance `https://jsonplaceholder.typicode.com/users`. + /// + /// For dynamic segments in your API endpoint, use Mustache templates for + /// variable substitution. For instance, to fetch a specific user, use + /// `/users/{{args.id}}`. + pub path: String, + + #[serde(default, skip_serializing_if = "is_default")] + /// Schema of the output of the API call. It is automatically inferred in + /// most cases. + pub output: Option, + + #[serde(default, skip_serializing_if = "is_default")] + /// This represents the query parameters of your API call. You can pass it + /// as a static object or use Mustache template for dynamic parameters. + /// These parameters will be added to the URL. + /// NOTE: Query parameter order is critical for batching in Tailcall. The + /// first parameter referencing a field in the current value using mustache + /// syntax is automatically selected as the batching parameter. + pub query: Vec, +} diff --git a/src/core/config/directives/js.rs b/src/core/config/directives/js.rs new file mode 100644 index 0000000000..60f307befc --- /dev/null +++ b/src/core/config/directives/js.rs @@ -0,0 +1,18 @@ +use serde::{Deserialize, Serialize}; +use tailcall_macros::{DirectiveDefinition, InputDefinition}; + +#[derive( + Serialize, + Deserialize, + Clone, + Debug, + PartialEq, + Eq, + schemars::JsonSchema, + DirectiveDefinition, + InputDefinition, +)] +#[directive_definition(locations = "FieldDefinition, Object", lowercase_name)] +pub struct JS { + pub name: String, +} diff --git a/src/core/config/directives/mod.rs b/src/core/config/directives/mod.rs new file mode 100644 index 0000000000..820286d2c3 --- /dev/null +++ b/src/core/config/directives/mod.rs @@ -0,0 +1,15 @@ +mod call; +mod expr; +mod federation; +mod graphql; +mod grpc; +mod http; +mod js; + +pub use call::*; +pub use expr::*; +pub use federation::*; +pub use graphql::*; +pub use grpc::*; +pub use http::*; +pub use js::*; diff --git a/src/core/config/from_document.rs b/src/core/config/from_document.rs index 3fa2af4a06..50ee61153e 100644 --- a/src/core/config/from_document.rs +++ b/src/core/config/from_document.rs @@ -11,7 +11,7 @@ use async_graphql_value::ConstValue; use indexmap::IndexMap; use super::telemetry::Telemetry; -use super::Alias; +use super::{Alias, Resolver}; use crate::core::config::{ self, Cache, Config, Enum, Link, Modify, Omit, Protected, RootSchema, Server, Union, Upstream, Variant, @@ -242,14 +242,24 @@ where let fields = object.fields(); let implements = object.implements(); - Cache::from_directives(directives.iter()) + Resolver::from_directives(directives) + .fuse(Cache::from_directives(directives.iter())) .fuse(to_fields(fields)) .fuse(Protected::from_directives(directives.iter())) - .map(|(cache, fields, protected)| { + .map(|(resolver, cache, fields, protected)| { let doc = description.to_owned().map(|pos| pos.node); let implements = implements.iter().map(|pos| pos.node.to_string()).collect(); let added_fields = to_add_fields_from_directives(directives); - config::Type { fields, added_fields, doc, implements, cache, protected } + config::Type { + fields, + added_fields, + doc, + implements, + cache, + protected, + resolver, + key: None, + } }) } fn to_input_object( diff --git a/src/core/config/into_document.rs b/src/core/config/into_document.rs index 203c007338..1b1db9e23d 100644 --- a/src/core/config/into_document.rs +++ b/src/core/config/into_document.rs @@ -150,27 +150,38 @@ fn config_document(config: &Config) -> ServiceDocument { .collect::>>(), }) }; + + let directives = type_def + .added_fields + .iter() + .map(|added_field: &super::AddField| pos(added_field.to_directive())) + .chain( + type_def + .cache + .as_ref() + .map(|cache| pos(cache.to_directive())), + ) + .chain( + type_def + .protected + .as_ref() + .map(|protected| pos(protected.to_directive())), + ) + .chain( + type_def + .resolver + .as_ref() + .and_then(|resolver| resolver.to_directive()) + .map(pos), + ) + .chain(type_def.key.as_ref().map(|key| pos(key.to_directive()))) + .collect::>(); + definitions.push(TypeSystemDefinition::Type(pos(TypeDefinition { extend: false, description: type_def.doc.clone().map(pos), name: pos(Name::new(type_name.clone())), - directives: type_def - .added_fields - .iter() - .map(|added_field: &super::AddField| pos(added_field.to_directive())) - .chain( - type_def - .cache - .as_ref() - .map(|cache| pos(cache.to_directive())), - ) - .chain( - type_def - .protected - .as_ref() - .map(|protected| pos(protected.to_directive())), - ) - .collect::>(), + directives, kind, }))); } @@ -220,7 +231,11 @@ fn config_document(config: &Config) -> ServiceDocument { fn get_directives(field: &crate::core::config::Field) -> Vec> { let directives = vec![ - field.resolver.as_ref().map(|d| pos(d.to_directive())), + field + .resolver + .as_ref() + .and_then(|d| d.to_directive()) + .map(pos), field.modify.as_ref().map(|d| pos(d.to_directive())), field.omit.as_ref().map(|d| pos(d.to_directive())), field.cache.as_ref().map(|d| pos(d.to_directive())), diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 6135656368..8288d9485c 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -1,10 +1,12 @@ pub use apollo::*; pub use config::*; pub use config_module::*; +pub use directives::*; pub use key_values::*; pub use link::*; pub use npo::QueryPath; pub use reader_context::*; +pub use resolver::*; pub use server::*; pub use source::*; pub use telemetry::*; @@ -14,6 +16,7 @@ mod apollo; mod config; mod config_module; pub mod cors; +pub mod directives; mod from_document; pub mod group_by; mod headers; @@ -23,6 +26,7 @@ mod link; mod npo; pub mod reader; pub mod reader_context; +mod resolver; mod server; mod source; mod telemetry; diff --git a/src/core/config/resolver.rs b/src/core/config/resolver.rs new file mode 100644 index 0000000000..c8b42c21a0 --- /dev/null +++ b/src/core/config/resolver.rs @@ -0,0 +1,56 @@ +use async_graphql::parser::types::ConstDirective; +use async_graphql::Positioned; +use serde::{Deserialize, Serialize}; +use tailcall_macros::{CustomResolver, MergeRight}; + +use super::{Call, EntityResolver, Expr, GraphQL, Grpc, Http, JS}; +use crate::core::directive::DirectiveCodec; +use crate::core::merge_right::MergeRight; +use crate::core::valid::{Valid, Validator}; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ApolloFederation { + EntityResolver(EntityResolver), + Service, +} + +#[derive( + Serialize, + Deserialize, + Clone, + Debug, + PartialEq, + Eq, + schemars::JsonSchema, + MergeRight, + CustomResolver, +)] +#[serde(rename_all = "camelCase")] +pub enum Resolver { + Http(Http), + Grpc(Grpc), + Graphql(GraphQL), + Call(Call), + Js(JS), + Expr(Expr), + #[serde(skip)] + #[resolver(skip_directive)] + ApolloFederation(ApolloFederation), +} + +impl Resolver { + pub fn is_batched(&self) -> bool { + match self { + Resolver::Http(http) => !http.batch_key.is_empty(), + Resolver::Grpc(grpc) => !grpc.batch_key.is_empty(), + Resolver::Graphql(graphql) => graphql.batch, + Resolver::ApolloFederation(ApolloFederation::EntityResolver(entity_resolver)) => { + entity_resolver + .resolver_by_type + .values() + .any(Resolver::is_batched) + } + _ => false, + } + } +} diff --git a/src/core/config/transformer/mod.rs b/src/core/config/transformer/mod.rs index bf22d6730c..75a1396761 100644 --- a/src/core/config/transformer/mod.rs +++ b/src/core/config/transformer/mod.rs @@ -7,6 +7,7 @@ mod nested_unions; mod preset; mod rename_types; mod required; +mod subgraph; mod tree_shake; mod union_input_type; @@ -19,5 +20,6 @@ pub use nested_unions::NestedUnions; pub use preset::Preset; pub use rename_types::RenameTypes; pub use required::Required; +pub use subgraph::Subgraph; pub use tree_shake::TreeShake; pub use union_input_type::UnionInputType; diff --git a/src/core/config/transformer/required.rs b/src/core/config/transformer/required.rs index 4d38070a5c..e8ba0c2803 100644 --- a/src/core/config/transformer/required.rs +++ b/src/core/config/transformer/required.rs @@ -15,6 +15,7 @@ impl Transform for Required { config: Self::Value, ) -> crate::core::valid::Valid { transform::default() + .pipe(super::Subgraph) .pipe(super::NestedUnions) .pipe(super::UnionInputType) .pipe(super::AmbiguousType::default()) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_call.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_call.snap new file mode 100644 index 0000000000..056418f3e3 --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_call.snap @@ -0,0 +1,11 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys +--- +Valid( + Ok( + Some( + "arg { a b }", + ), + ), +) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_expr.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_expr.snap new file mode 100644 index 0000000000..29c06be101 --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_expr.snap @@ -0,0 +1,11 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys +--- +Valid( + Ok( + Some( + "body { a b }", + ), + ), +) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_graphql.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_graphql.snap new file mode 100644 index 0000000000..ae0c75e46a --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_graphql.snap @@ -0,0 +1,11 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys +--- +Valid( + Ok( + Some( + "header_test input { key }", + ), + ), +) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_grpc.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_grpc.snap new file mode 100644 index 0000000000..a58bbbb93b --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_grpc.snap @@ -0,0 +1,11 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys +--- +Valid( + Ok( + Some( + "body { a b } header_test method", + ), + ), +) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_http.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_http.snap new file mode 100644 index 0000000000..bd776f6c9d --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__extract_http.snap @@ -0,0 +1,11 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys +--- +Valid( + Ok( + Some( + "header { key value } id obj query_key query_value", + ), + ), +) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__non_value_template.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__non_value_template.snap new file mode 100644 index 0000000000..8fabb5a9e6 --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__extractor__non_value_template.snap @@ -0,0 +1,28 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys +--- +Valid( + Err( + ValidationError( + [ + Cause { + message: "Type resolver can't use `.args`, use `.value` instead", + description: None, + trace: [ + "http", + "path", + ], + }, + Cause { + message: "Type resolver can't use `.args`, use `.value` instead", + description: None, + trace: [ + "http", + "query", + ], + }, + ], + ), + ), +) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_merge.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_merge.snap new file mode 100644 index 0000000000..a1a1125ffd --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_merge.snap @@ -0,0 +1,32 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys_a.merge_right(keys_b) +--- +Keys( + { + "a": Keys( + { + "1": Keys( + {}, + ), + "b": Keys( + {}, + ), + }, + ), + "c": Keys( + { + "2": Keys( + {}, + ), + }, + ), + "d": Keys( + { + "3": Keys( + {}, + ), + }, + ), + }, +) diff --git a/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_set.snap b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_set.snap new file mode 100644 index 0000000000..0ca1900d8e --- /dev/null +++ b/src/core/config/transformer/snapshots/tailcall__core__config__transformer__subgraph__tests__keys__keys_set.snap @@ -0,0 +1,32 @@ +--- +source: src/core/config/transformer/subgraph.rs +expression: keys +--- +Keys( + { + "a": Keys( + { + "b": Keys( + { + "c": Keys( + {}, + ), + }, + ), + "d": Keys( + {}, + ), + }, + ), + "e": Keys( + {}, + ), + "f": Keys( + { + "g": Keys( + {}, + ), + }, + ), + }, +) diff --git a/src/core/config/transformer/subgraph.rs b/src/core/config/transformer/subgraph.rs new file mode 100644 index 0000000000..3ef4126ee2 --- /dev/null +++ b/src/core/config/transformer/subgraph.rs @@ -0,0 +1,493 @@ +use std::borrow::Borrow; +use std::collections::BTreeMap; +use std::convert::identity; +use std::fmt::{Display, Write}; +use std::ops::Deref; + +use tailcall_macros::MergeRight; + +use crate::core::config::{ + self, ApolloFederation, Arg, Call, Config, Field, GraphQL, Grpc, Http, Key, KeyValue, Resolver, + Union, +}; +use crate::core::directive::DirectiveCodec; +use crate::core::merge_right::MergeRight; +use crate::core::mustache::Segment; +use crate::core::valid::{Valid, Validator}; +use crate::core::{Mustache, Transform, Type}; + +const ENTITIES_FIELD_NAME: &str = "_entities"; +const SERVICE_FIELD_NAME: &str = "_service"; +const SERVICE_TYPE_NAME: &str = "_Service"; +const UNION_ENTITIES_NAME: &str = "_Entity"; +const ENTITIES_ARG_NAME: &str = "representations"; +const ENTITIES_TYPE_NAME: &str = "_Any"; + +/// Adds compatibility layer for Apollo Federation v2 +/// so tailcall may act as a Federation Subgraph. +/// Followed by [spec](https://www.apollographql.com/docs/federation/subgraph-spec/) +pub struct Subgraph; + +impl Transform for Subgraph { + type Value = Config; + + type Error = String; + + fn transform(&self, mut config: Self::Value) -> Valid { + let mut resolver_by_type = BTreeMap::new(); + + let valid = Valid::from_iter(config.types.iter_mut(), |(type_name, ty)| { + if let Some(resolver) = &ty.resolver { + resolver_by_type.insert(type_name.clone(), resolver.clone()); + + KeysExtractor::extract_keys(resolver).map(|fields| { + fields.map(|fields| { + ty.key = Some(Key { fields }); + }) + }) + } else { + Valid::succeed(None) + } + .trace(type_name) + }); + + if valid.is_fail() { + return valid.map_to(config); + } + + if resolver_by_type.is_empty() { + return Valid::succeed(config); + } + + let entity_union = Union { + types: resolver_by_type.keys().cloned().collect(), + ..Default::default() + }; + + let entity_resolver = config::EntityResolver { resolver_by_type }; + + // union that wraps any possible types for entities + config + .unions + .insert(UNION_ENTITIES_NAME.to_owned(), entity_union); + // any scalar for argument `representations` + config + .types + .insert(ENTITIES_TYPE_NAME.to_owned(), config::Type::default()); + + let service_field = Field { type_of: "String".to_string().into(), ..Default::default() }; + + let service_type = config::Type { + fields: [("sdl".to_string(), service_field)].into_iter().collect(), + ..Default::default() + }; + + // type that represents the response for service + config + .types + .insert(SERVICE_TYPE_NAME.to_owned(), service_type); + + let query_type = match config.schema.query.as_ref() { + Some(name) => name, + None => { + config.schema.query = Some("Query".to_string()); + "Query" + } + }; + + let query_type = config.types.entry(query_type.to_owned()).or_default(); + + let arg = Arg { + type_of: Type::from(ENTITIES_TYPE_NAME.to_string()) + .into_required() + .into_list() + .into_required(), + ..Default::default() + }; + + query_type.fields.insert( + ENTITIES_FIELD_NAME.to_string(), + Field { + type_of: Type::from(UNION_ENTITIES_NAME.to_owned()) + .into_list() + .into_required(), + args: [(ENTITIES_ARG_NAME.to_owned(), arg)].into_iter().collect(), + doc: Some("Apollo federation Query._entities resolver".to_string()), + resolver: Some(Resolver::ApolloFederation( + ApolloFederation::EntityResolver(entity_resolver), + )), + ..Default::default() + }, + ); + + query_type.fields.insert( + SERVICE_FIELD_NAME.to_string(), + Field { + type_of: Type::from(SERVICE_TYPE_NAME.to_owned()).into_required(), + doc: Some("Apollo federation Query._service resolver".to_string()), + resolver: Some(Resolver::ApolloFederation(ApolloFederation::Service)), + ..Default::default() + }, + ); + + Valid::succeed(config) + } +} + +#[derive(Default, Clone, Debug, MergeRight)] +struct Keys(BTreeMap); + +impl Keys { + fn new() -> Self { + Self::default() + } + + fn set_path(&mut self, path: impl Iterator) { + let mut map = &mut self.0; + + for part in path { + map = &mut map.entry(part).or_default().0; + } + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl Display for Keys { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for (i, (key, value)) in self.0.iter().enumerate() { + f.write_str(key)?; + + if !value.0.is_empty() { + write!(f, " {{ {} }}", value)?; + } + + if i < self.0.len() - 1 { + f.write_char(' ')?; + } + } + + Ok(()) + } +} + +fn combine_keys(v: Vec) -> Keys { + v.into_iter() + .fold(Keys::new(), |acc, keys| acc.merge_right(keys)) +} + +struct KeysExtractor; + +impl KeysExtractor { + fn extract_keys(resolver: &Resolver) -> Valid, String> { + // TODO: add validation for available fields from the type + match resolver { + Resolver::Http(http) => { + Valid::from_iter( + [ + Self::parse_str_option(http.base_url.as_deref()).trace("base_url"), + Self::parse_str(&http.path).trace("path"), + Self::parse_str_option(http.body.as_deref()).trace("body"), + Self::parse_key_value_iter(http.headers.iter()).trace("headers"), + Self::parse_key_value_iter(http.query.iter().map(|q| KeyValue { + key: q.key.to_string(), + value: q.value.to_string(), + })) + .trace("query"), + ], + identity, + ) + .trace(Http::directive_name().as_str()) + } + Resolver::Grpc(grpc) => Valid::from_iter( + [ + Self::parse_str_option(grpc.base_url.as_deref()), + Self::parse_str(&grpc.method), + Self::parse_value_option(&grpc.body), + Self::parse_key_value_iter(grpc.headers.iter()), + ], + identity, + ) + .trace(Grpc::directive_name().as_str()), + Resolver::Graphql(graphql) => Valid::from_iter( + [ + Self::parse_key_value_iter(graphql.headers.iter()), + Self::parse_key_value_iter_option(graphql.args.as_ref().map(|v| v.iter())), + ], + identity, + ) + .trace(GraphQL::directive_name().as_str()), + Resolver::Call(call) => Valid::from_option( + call.steps.first(), + "Call should define at least one step".to_string(), + ) + .and_then(|step| { + Valid::from_iter(step.args.iter(), |(key, value)| { + Valid::from_iter([Self::parse_str(key), Self::parse_value(value)], identity) + }) + }) + .map(|v| v.into_iter().flatten().collect()) + .trace(Call::directive_name().as_str()), + Resolver::Expr(expr) => Valid::from_iter([Self::parse_value(&expr.body)], identity) + .trace(Call::directive_name().as_str()), + _ => return Valid::succeed(None), + } + .map(|keys| { + let keys = combine_keys(keys); + + if keys.is_empty() { + None + } else { + Some(keys.to_string()) + } + }) + } + + fn parse_str(s: &str) -> Valid { + let mustache = Mustache::parse(s); + let mut keys = Keys::new(); + + Valid::from_iter(mustache.segments().iter(), |segment| { + if let Segment::Expression(expr) = segment { + match expr.first().map(Deref::deref) { + Some("value") => { + keys.set_path(expr[1..].iter().map(String::to_string)); + } + Some("args") => { + return Valid::fail( + "Type resolver can't use `.args`, use `.value` instead".to_string(), + ); + } + _ => {} + } + } + + Valid::succeed(()) + }) + .map_to(keys) + } + + fn parse_str_option(s: Option<&str>) -> Valid { + if let Some(s) = s { + Self::parse_str(s) + } else { + Valid::succeed(Keys::new()) + } + } + + fn parse_key_value_iter>( + it: impl Iterator, + ) -> Valid { + let mut keys = Keys::new(); + + Valid::from_iter(it, |key_value| { + let key_value = key_value.borrow(); + + Self::parse_str(&key_value.key) + .zip(Self::parse_str(&key_value.value)) + .map(|(key, value)| keys = keys.clone().merge_right(key).merge_right(value)) + }) + .map_to(keys) + } + + fn parse_key_value_iter_option>( + it: Option>, + ) -> Valid { + if let Some(it) = it { + Self::parse_key_value_iter(it) + } else { + Valid::succeed(Keys::new()) + } + } + + fn parse_value(value: &serde_json::Value) -> Valid { + match value { + serde_json::Value::String(s) => return Self::parse_str(s), + serde_json::Value::Array(v) => Valid::from_iter(v.iter(), Self::parse_value), + serde_json::Value::Object(map) => Valid::from_iter(map.iter(), |(k, v)| { + Self::parse_str(k) + .zip(Self::parse_value(v)) + .map(|(k, v)| k.merge_right(v)) + }), + _ => return Valid::succeed(Keys::new()), + } + .map(|keys_vec| { + keys_vec + .into_iter() + .fold(Keys::new(), |acc, keys| acc.merge_right(keys)) + }) + } + + fn parse_value_option(value: &Option) -> Valid { + if let Some(value) = value { + Self::parse_value(value) + } else { + Valid::succeed(Keys::new()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + mod keys { + use insta::assert_debug_snapshot; + + use super::*; + + #[test] + fn test_keys_set() { + let mut keys = Keys::new(); + + keys.set_path(["a", "b", "c"].into_iter().map(str::to_string)); + keys.set_path(["a", "d"].into_iter().map(str::to_string)); + keys.set_path(["e"].into_iter().map(str::to_string)); + keys.set_path(["f", "g"].into_iter().map(str::to_string)); + + assert_debug_snapshot!(keys); + } + + #[test] + fn test_keys_merge() { + let mut keys_a = Keys::new(); + + keys_a.set_path(["a", "b"].into_iter().map(str::to_string)); + keys_a.set_path(["c"].into_iter().map(str::to_string)); + + let mut keys_b = Keys::new(); + + keys_b.set_path(["a", "1"].into_iter().map(str::to_string)); + keys_b.set_path(["c", "2"].into_iter().map(str::to_string)); + keys_b.set_path(["d", "3"].into_iter().map(str::to_string)); + + assert_debug_snapshot!(keys_a.merge_right(keys_b)); + } + } + + mod extractor { + use insta::assert_debug_snapshot; + use serde_json::json; + + use super::config::Http; + use super::{KeyValue, KeysExtractor, Resolver}; + use crate::core::config::{Call, Expr, GraphQL, Grpc, Step, URLQuery}; + use crate::core::http::Method; + + #[test] + fn test_non_value_template() { + let http = Http { + base_url: Some("http://tailcall.run".to_string()), + path: "users/{{.args.id}}".to_string(), + query: vec![URLQuery { + key: "{{.env.query.key}}".to_string(), + value: "{{.args.query.value}}".to_string(), + ..Default::default() + }], + ..Default::default() + }; + let resolver = Resolver::Http(http); + let keys = KeysExtractor::extract_keys(&resolver); + + assert_debug_snapshot!(keys); + } + + #[test] + fn test_extract_http() { + let http = Http { + base_url: Some("http://tailcall.run".to_string()), + body: Some(r#"{ "obj": "{{.value.obj}}"} "#.to_string()), + headers: vec![KeyValue { + key: "{{.value.header.key}}".to_string(), + value: "{{.value.header.value}}".to_string(), + }], + method: Method::POST, + path: "users/{{.value.id}}".to_string(), + query: vec![URLQuery { + key: "{{.value.query_key}}".to_string(), + value: "{{.value.query_value}}".to_string(), + ..Default::default() + }], + ..Default::default() + }; + let resolver = Resolver::Http(http); + let keys = KeysExtractor::extract_keys(&resolver); + + assert_debug_snapshot!(keys); + } + + #[test] + fn test_extract_grpc() { + let grpc = Grpc { + base_url: Some("http://localhost:5051/{{.env.target}}".to_string()), + body: Some(json!({ "a": "{{.value.body.a}}", "b": "{{.value.body.b}}"})), + headers: vec![KeyValue { + key: "test".to_string(), + value: "{{.value.header_test}}".to_string(), + }], + method: "test_{{.value.method}}".to_string(), + ..Default::default() + }; + + let resolver = Resolver::Grpc(grpc); + let keys = KeysExtractor::extract_keys(&resolver); + + assert_debug_snapshot!(keys); + } + + #[test] + fn test_extract_graphql() { + let graphql = GraphQL { + base_url: Some("http://localhost:5051/{{.env.target}}".to_string()), + headers: vec![KeyValue { + key: "test".to_string(), + value: "{{.value.header_test}}".to_string(), + }], + args: Some(vec![KeyValue { + key: "key".to_string(), + value: "test-{{.value.input.key}}".to_string(), + }]), + ..Default::default() + }; + + let resolver = Resolver::Graphql(graphql); + let keys = KeysExtractor::extract_keys(&resolver); + + assert_debug_snapshot!(keys); + } + + #[test] + fn test_extract_call() { + let call = Call { + steps: vec![Step { + query: Some("field".to_string()), + args: [( + "arg".to_string(), + json!(json!({ "a": "{{.value.arg.a}}", "b": "{{.value.arg.b}}"})), + )] + .into_iter() + .collect(), + ..Default::default() + }], + }; + + let resolver = Resolver::Call(call); + let keys = KeysExtractor::extract_keys(&resolver); + + assert_debug_snapshot!(keys); + } + + #[test] + fn test_extract_expr() { + let expr = Expr { + body: json!({ "a": "{{.value.body.a}}", "b": "{{.value.body.b}}"}), + }; + + let resolver = Resolver::Expr(expr); + let keys = KeysExtractor::extract_keys(&resolver); + + assert_debug_snapshot!(keys); + } + } +} diff --git a/src/core/helpers/body.rs b/src/core/helpers/body.rs index aa498644d5..0f2b582577 100644 --- a/src/core/helpers/body.rs +++ b/src/core/helpers/body.rs @@ -13,6 +13,7 @@ pub fn to_body(body: Option<&Value>) -> Valid, String> { let value = body.to_string(); let mustache = Mustache::parse(&value); + // TODO: req_body.mustache is always set making req_body.value useless req_body = req_body.mustache(Some(mustache)); Valid::succeed(Some(req_body.value(value))) diff --git a/src/core/ir/error.rs b/src/core/ir/error.rs index 2bcd513f83..7f026f83a7 100644 --- a/src/core/ir/error.rs +++ b/src/core/ir/error.rs @@ -6,6 +6,7 @@ use derive_more::From; use thiserror::Error; use crate::core::{auth, cache, worker, Errata}; + #[derive(From, Debug, Error, Clone)] pub enum Error { IO(String), @@ -30,6 +31,9 @@ pub enum Error { Worker(worker::Error), Cache(cache::Error), + + #[from(ignore)] + Entity(String), } impl Display for Error { @@ -62,6 +66,7 @@ impl From for Errata { } Error::Worker(err) => Errata::new("Worker Error").description(err.to_string()), Error::Cache(err) => Errata::new("Cache Error").description(err.to_string()), + Error::Entity(message) => Errata::new("Entity Resolver Error").description(message) } } } diff --git a/src/core/ir/eval.rs b/src/core/ir/eval.rs index 6c5cc40433..234197b751 100644 --- a/src/core/ir/eval.rs +++ b/src/core/ir/eval.rs @@ -2,11 +2,13 @@ use std::future::Future; use std::ops::Deref; use async_graphql_value::ConstValue; +use futures_util::future::join_all; +use indexmap::IndexMap; use super::eval_io::eval_io; use super::model::{Cache, CacheKey, Map, IR}; use super::{Error, EvalContext, ResolverContextLike, TypedValue}; -use crate::core::json::{JsonLike, JsonLikeList}; +use crate::core::json::{JsonLike, JsonLikeList, JsonObjectLike}; use crate::core::serde_value_ext::ValueExt; // Fake trait to capture proper lifetimes. @@ -87,6 +89,12 @@ impl IR { } IR::Discriminate(discriminator, expr) => expr.eval(ctx).await.and_then(|value| { let value = value.map(&mut |mut value| { + if value.get_type_name().is_some() { + // if typename is already present in value just reuse it instead + // of recalculating from scratch + return Ok(value); + } + let type_name = discriminator.resolve_type(&value)?; value.set_type_name(type_name.to_string())?; @@ -96,6 +104,54 @@ impl IR { Ok(value) }), + IR::Entity(map) => { + let representations = ctx.path_arg(&["representations"]); + + let representations = representations + .as_ref() + .and_then(|repr| repr.as_array()) + .ok_or(Error::Entity( + "expected `representations` arg as an array of _Any".to_string(), + ))?; + + let mut tasks = Vec::with_capacity(representations.len()); + + for repr in representations { + // TODO: combine errors, instead of fail fast? + let type_name = repr.get_type_name().ok_or(Error::Entity( + "expected __typename to be the part of the representation".to_string(), + ))?; + + let ir = map.get(type_name).ok_or(Error::Entity(format!( + "Cannot find a resolver for type: `{type_name}`" + )))?; + + // pass the input for current representation as value in context + // TODO: can we drop clone? + let mut ctx = ctx.with_value(repr.clone()); + + tasks.push(async move { + ir.eval(&mut ctx).await.and_then(|mut value| { + // set typename explicitly to reuse it if needed + value.set_type_name(type_name.to_owned())?; + Ok(value) + }) + }); + } + + let result = join_all(tasks).await; + + let entities = result.into_iter().collect::>()?; + + Ok(ConstValue::List(entities)) + } + IR::Service(sdl) => { + let mut obj = IndexMap::new(); + + obj.insert_key("sdl", ConstValue::string(sdl.into())); + + Ok(ConstValue::object(obj)) + } } }) } diff --git a/src/core/ir/model.rs b/src/core/ir/model.rs index 89d38ee317..3473d47d96 100644 --- a/src/core/ir/model.rs +++ b/src/core/ir/model.rs @@ -26,6 +26,10 @@ pub enum IR { Map(Map), Pipe(Box, Box), Discriminate(Discriminator, Box), + /// Apollo Federation _entities resolver + Entity(HashMap), + /// Apollo Federation _service resolver + Service(String), } #[derive(Clone, Debug)] @@ -42,6 +46,7 @@ pub enum IO { group_by: Option, dl_id: Option, http_filter: Option, + is_list: bool, }, GraphQL { req_template: graphql::RequestTemplate, @@ -101,7 +106,7 @@ impl Cache { /// Performance DFS on the cache on the expression and identifies all the IO /// nodes. Then wraps each IO node with the cache primitive. pub fn wrap(max_age: NonZeroU64, expr: IR) -> IR { - expr.modify(move |expr| match expr { + expr.modify(&mut move |expr| match expr { IR::IO(io) => Some(IR::Cache(Cache { max_age, io: Box::new(io.to_owned()) })), _ => None, }) @@ -113,8 +118,8 @@ impl IR { IR::Pipe(Box::new(self), Box::new(next)) } - pub fn modify(self, mut f: impl FnMut(&IR) -> Option) -> IR { - self.modify_inner(&mut f) + pub fn modify Option>(self, modifier: &mut F) -> IR { + self.modify_inner(modifier) } fn modify_box Option>(self, modifier: &mut F) -> Box { @@ -149,6 +154,12 @@ impl IR { IR::Discriminate(discriminator, expr) => { IR::Discriminate(discriminator, expr.modify_box(modifier)) } + IR::Entity(map) => IR::Entity( + map.into_iter() + .map(|(k, v)| (k, v.modify(modifier))) + .collect(), + ), + IR::Service(sdl) => IR::Service(sdl), } } } diff --git a/src/core/mustache/parse.rs b/src/core/mustache/parse.rs index 099bb47f5a..a814e22f53 100644 --- a/src/core/mustache/parse.rs +++ b/src/core/mustache/parse.rs @@ -9,7 +9,6 @@ use nom::{Finish, IResult}; use super::*; impl Mustache { - // TODO: infallible function, no need to return Result pub fn parse(str: &str) -> Mustache { let result = parse_mustache(str).finish(); match result { diff --git a/src/core/valid/valid.rs b/src/core/valid/valid.rs index 173897cf85..cda47c82db 100644 --- a/src/core/valid/valid.rs +++ b/src/core/valid/valid.rs @@ -25,6 +25,8 @@ pub trait Validator: Sized { fn is_succeed(&self) -> bool; + fn is_fail(&self) -> bool; + fn and(self, other: Valid) -> Valid { self.zip(other).map(|(_, a1)| a1) } @@ -165,6 +167,10 @@ impl Validator for Valid { fn is_succeed(&self) -> bool { self.0.is_ok() } + + fn is_fail(&self) -> bool { + self.0.is_err() + } } pub struct Fusion(Valid); @@ -184,6 +190,9 @@ impl Validator for Fusion { fn is_succeed(&self) -> bool { self.0.is_succeed() } + fn is_fail(&self) -> bool { + self.0.is_fail() + } } impl From>> for Valid { diff --git a/tailcall-macros/src/lib.rs b/tailcall-macros/src/lib.rs index 377a4ef20e..5508b6235f 100644 --- a/tailcall-macros/src/lib.rs +++ b/tailcall-macros/src/lib.rs @@ -1,6 +1,7 @@ extern crate proc_macro; use proc_macro::TokenStream; +use syn::{parse_macro_input, DeriveInput}; mod document_definition; mod gen; @@ -48,7 +49,10 @@ pub fn input_definition_derive(input: TokenStream) -> TokenStream { expand_input_definition(input) } -#[proc_macro_derive(CustomResolver)] +#[proc_macro_derive(CustomResolver, attributes(resolver))] pub fn resolver_derive(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); expand_resolver_derive(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() } diff --git a/tailcall-macros/src/merge_right.rs b/tailcall-macros/src/merge_right.rs index dce5c428f5..03c8556ca0 100644 --- a/tailcall-macros/src/merge_right.rs +++ b/tailcall-macros/src/merge_right.rs @@ -3,7 +3,7 @@ extern crate proc_macro; use proc_macro::TokenStream; use quote::quote; use syn::spanned::Spanned; -use syn::{parse_macro_input, Data, DeriveInput, Fields}; +use syn::{parse_macro_input, Data, DeriveInput, Fields, Index}; const MERGE_RIGHT_FN: &str = "merge_right_fn"; const MERGE_RIGHT: &str = "merge_right"; @@ -59,29 +59,54 @@ pub fn expand_merge_right_derive(input: TokenStream) -> TokenStream { let gen = match input.data { // Implement for structs Data::Struct(data) => { - let fields = if let Fields::Named(fields) = data.fields { - fields.named - } else { - // Adjust this match arm to handle other kinds of struct fields (unnamed/tuple - // structs, unit structs) - unimplemented!() + let fields = match &data.fields { + Fields::Named(fields) => &fields.named, + Fields::Unnamed(fields) => &fields.unnamed, + Fields::Unit => { + return quote! { + impl MergeRight for #name { + fn merge_right(self, other: Self) -> Self { + other + } + } + } + .into() + } }; - let merge_logic = fields.iter().map(|f| { + let merge_logic = fields.iter().enumerate().map(|(i, f)| { let attrs = get_attrs(&f.attrs); if let Err(err) = attrs { panic!("{}", err); } let attrs = attrs.unwrap(); let name = &f.ident; - if let Some(merge_right_fn) = attrs.merge_right_fn { - quote! { - #name: #merge_right_fn(self.#name, other.#name), + + match &data.fields { + Fields::Named(_) => { + if let Some(merge_right_fn) = attrs.merge_right_fn { + quote! { + #name: #merge_right_fn(self.#name, other.#name), + } + } else { + quote! { + #name: self.#name.merge_right(other.#name), + } + } } - } else { - quote! { - #name: self.#name.merge_right(other.#name), + Fields::Unnamed(_) => { + let name = Index::from(i); + if let Some(merge_right_fn) = attrs.merge_right_fn { + quote! { + #merge_right_fn(self.#name, other.#name), + } + } else { + quote! { + self.#name.merge_right(other.#name), + } + } } + Fields::Unit => unreachable!(), } }); @@ -93,12 +118,22 @@ pub fn expand_merge_right_derive(input: TokenStream) -> TokenStream { #generics_lt #generics_params #generics_gt }; + let initializer = match data.fields { + Fields::Named(_) => quote! { + Self { + #(#merge_logic)* + } + }, + Fields::Unnamed(_) => quote! { + Self(#(#merge_logic)*) + }, + Fields::Unit => unreachable!(), + }; + quote! { impl #generics_del MergeRight for #name #generics_del { fn merge_right(self, other: Self) -> Self { - Self { - #(#merge_logic)* - } + #initializer } } } diff --git a/tailcall-macros/src/resolver.rs b/tailcall-macros/src/resolver.rs index cb6526af1e..99cd446c4f 100644 --- a/tailcall-macros/src/resolver.rs +++ b/tailcall-macros/src/resolver.rs @@ -1,9 +1,36 @@ -use proc_macro::TokenStream; +use proc_macro2::TokenStream; use quote::quote; -use syn::{parse_macro_input, Data, DeriveInput, Fields}; +use syn::{Attribute, Data, DeriveInput, Fields}; -pub fn expand_resolver_derive(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); +const ATTR_NAMESPACE: &str = "resolver"; +const ATTR_SKIP_DIRECTIVE: &str = "skip_directive"; + +#[derive(Default)] +struct Attrs { + skip_directive: bool, +} + +fn parse_attrs(attributes: &Vec) -> syn::Result { + let mut result = Attrs::default(); + + for attr in attributes { + if attr.path().is_ident(ATTR_NAMESPACE) { + attr.parse_nested_meta(|meta| { + if meta.path.is_ident(ATTR_SKIP_DIRECTIVE) { + result.skip_directive = true; + + return Ok(()); + } + + Err(meta.error("unrecognized resolver attribute")) + })?; + } + } + + Ok(result) +} + +pub fn expand_resolver_derive(input: DeriveInput) -> syn::Result { let name = &input.ident; let variants = if let Data::Enum(data_enum) = &input.data { @@ -12,20 +39,27 @@ pub fn expand_resolver_derive(input: TokenStream) -> TokenStream { .iter() .map(|variant| { let variant_name = &variant.ident; + let attrs = &variant.attrs; let ty = match &variant.fields { Fields::Unnamed(fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty, _ => panic!("Resolver variants must have exactly one unnamed field"), }; - (variant_name, ty) + let attrs = parse_attrs(attrs)?; + + Ok((variant_name, ty, attrs)) }) - .collect::>() + .collect::>>()? } else { panic!("Resolver can only be derived for enums"); }; - let variant_parsers = variants.iter().map(|(variant_name, ty)| { - quote! { + let variant_parsers = variants.iter().filter_map(|(variant_name, ty, attrs)| { + if attrs.skip_directive { + return None; + } + + Some(quote! { valid = valid.and(<#ty>::from_directives(directives.iter()).map(|resolver| { if let Some(resolver) = resolver { let directive_name = <#ty>::trace_name(); @@ -35,18 +69,30 @@ pub fn expand_resolver_derive(input: TokenStream) -> TokenStream { result = Some(Self::#variant_name(resolver)); } })); - } + }) }); - let match_arms_to_directive = variants.iter().map(|(variant_name, _ty)| { - quote! { - Self::#variant_name(d) => d.to_directive(), + let match_arms_to_directive = variants.iter().map(|(variant_name, _ty, attrs)| { + if attrs.skip_directive { + quote! { + Self::#variant_name(d) => None, + } + } else { + quote! { + Self::#variant_name(d) => Some(d.to_directive()), + } } }); - let match_arms_directive_name = variants.iter().map(|(variant_name, ty)| { - quote! { - Self::#variant_name(_) => <#ty>::directive_name(), + let match_arms_directive_name = variants.iter().map(|(variant_name, ty, attrs)| { + if attrs.skip_directive { + quote! { + Self::#variant_name(_) => String::new(), + } + } else { + quote! { + Self::#variant_name(_) => <#ty>::directive_name(), + } } }); @@ -73,7 +119,7 @@ pub fn expand_resolver_derive(input: TokenStream) -> TokenStream { }) } - pub fn to_directive(&self) -> ConstDirective { + pub fn to_directive(&self) -> Option { match self { #(#match_arms_to_directive)* } @@ -87,5 +133,5 @@ pub fn expand_resolver_derive(input: TokenStream) -> TokenStream { } }; - TokenStream::from(expanded) + Ok(expanded) } diff --git a/tests/core/snapshots/apollo-federation-entities-batch.md_0.snap b/tests/core/snapshots/apollo-federation-entities-batch.md_0.snap new file mode 100644 index 0000000000..cdd18ea9a9 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities-batch.md_0.snap @@ -0,0 +1,26 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "_entities": [ + { + "__typename": "User", + "id": 1, + "name": "Leanne Graham" + }, + { + "__typename": "User", + "id": 2, + "name": "Ervin Howell" + } + ] + } + } +} diff --git a/tests/core/snapshots/apollo-federation-entities-batch.md_1.snap b/tests/core/snapshots/apollo-federation-entities-batch.md_1.snap new file mode 100644 index 0000000000..311df64dd7 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities-batch.md_1.snap @@ -0,0 +1,17 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "_service": { + "sdl": "schema @server(port: 8000) @upstream(baseURL: \"http://jsonplaceholder.typicode.com\", batch: {delay: 100, headers: []}, httpCache: 42) {\n query: Query\n}\n\nscalar _Any\n\nunion _Entity = Post | User\n\ntype Post @graphQL(args: [{key: \"id\", value: \"{{.value.id}}\"}], baseURL: \"http://upstream/graphql\", batch: true, name: \"post\") @key(fields: \"id\") {\n id: Int!\n title: String!\n}\n\ntype Query {\n \"\"\"\n Apollo federation Query._entities resolver\n \"\"\"\n _entities(representations: [_Any!]!): [_Entity]!\n \"\"\"\n Apollo federation Query._service resolver\n \"\"\"\n _service: _Service!\n user(id: Int!): User @http(path: \"/users/{{.args.id}}\")\n}\n\ntype User @http(batchKey: [\"id\"], path: \"/users\", query: [{key: \"id\", value: \"{{.value.user.id}}\"}]) @key(fields: \"user { id }\") {\n id: Int!\n name: String!\n}\n\ntype _Service {\n sdl: String\n}\n\"\"\"\nThe @addField operator simplifies data structures and queries by adding a field that \ninlines or flattens a nested field or node within your schema. more info [here](https://tailcall.run/docs/guides/operators/#addfield)\n\"\"\"\ndirective @addField(\n \"\"\"\n Name of the new field to be added\n \"\"\"\n name: String!\n \"\"\"\n Path of the data where the field should point to\n \"\"\"\n path: [String!]\n) repeatable on OBJECT\n\n\"\"\"\nThe @alias directive indicates that aliases of one enum value.\n\"\"\"\ndirective @alias(\n options: [String!]\n) on ENUM_VALUE\n\n\"\"\"\nThe @cache operator enables caching for the query, field or type it is applied to.\n\"\"\"\ndirective @cache(\n \"\"\"\n Specifies the duration, in milliseconds, of how long the value has to be stored in \n the cache.\n \"\"\"\n maxAge: Int!\n) on OBJECT | FIELD_DEFINITION\n\n\"\"\"\nProvides the ability to refer to multiple fields in the Query or Mutation root.\n\"\"\"\ndirective @call(\n \"\"\"\n Steps are composed together to form a call. If you have multiple steps, the output \n of the previous step is passed as input to the next step.\n \"\"\"\n steps: [Step]\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe `@expr` operators allows you to specify an expression that can evaluate to a \nvalue. The expression can be a static value or built form a Mustache template. schema.\n\"\"\"\ndirective @expr(\n body: JSON\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe @graphQL operator allows to specify GraphQL API server request to fetch data \nfrom.\n\"\"\"\ndirective @graphQL(\n \"\"\"\n Named arguments for the requested field. More info [here](https://tailcall.run/docs/guides/operators/#args)\n \"\"\"\n args: [KeyValue]\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n If the upstream GraphQL server supports request batching, you can specify the 'batch' \n argument to batch several requests into a single batch request.Make sure you have \n also specified batch settings to the `@upstream` and to the `@graphQL` operator.\n \"\"\"\n batch: Boolean!\n \"\"\"\n The headers parameter allows you to customize the headers of the GraphQL request \n made by the `@graphQL` operator. It is used by specifying a key-value map of header \n names and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Specifies the root field on the upstream to request data from. This maps a field \n in your schema to a field in the upstream schema. When a query is received for this \n field, Tailcall requests data from the corresponding upstream field.\n \"\"\"\n name: String!\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe @grpc operator indicates that a field or node is backed by a gRPC API.For instance, \nif you add the @grpc operator to the `users` field of the Query type with a service \nargument of `NewsService` and method argument of `GetAllNews`, it signifies that \nthe `users` field is backed by a gRPC API. The `service` argument specifies the name \nof the gRPC service. The `method` argument specifies the name of the gRPC method. \nIn this scenario, the GraphQL server will make a gRPC request to the gRPC endpoint \nspecified when the `users` field is queried.\n\"\"\"\ndirective @grpc(\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n This refers to the arguments of your gRPC call. You can pass it as a static object \n or use Mustache template for dynamic parameters. These parameters will be added in \n the body in `protobuf` format.\n \"\"\"\n body: JSON\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@grpc` operator. It is used by specifying a key-value map of header names \n and their values. Note: content-type is automatically set to application/grpc\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n This refers to the gRPC method you're going to call. For instance `GetAllNews`.\n \"\"\"\n method: String!\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe @http operator indicates that a field or node is backed by a REST API.For instance, \nif you add the @http operator to the `users` field of the Query type with a path \nargument of `\"/users\"`, it signifies that the `users` field is backed by a REST API. \nThe path argument specifies the path of the REST API. In this scenario, the GraphQL \nserver will make a GET request to the API endpoint specified when the `users` field \nis queried.\n\"\"\"\ndirective @http(\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n The body of the API call. It's used for methods like POST or PUT that send data to \n the server. You can pass it as a static object or use a Mustache template to substitute \n variables from the GraphQL variables.\n \"\"\"\n body: String\n \"\"\"\n The `encoding` parameter specifies the encoding of the request body. It can be `ApplicationJson` \n or `ApplicationXWwwFormUrlEncoded`. @default `ApplicationJson`.\n \"\"\"\n encoding: Encoding\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@http` operator. It is used by specifying a key-value map of header names \n and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Schema of the input of the API call. It is automatically inferred in most cases.\n \"\"\"\n input: Schema\n \"\"\"\n This refers to the HTTP method of the API call. Commonly used methods include `GET`, \n `POST`, `PUT`, `DELETE` etc. @default `GET`.\n \"\"\"\n method: Method\n \"\"\"\n onRequest field in @http directive gives the ability to specify the request interception \n handler.\n \"\"\"\n onRequest: String\n \"\"\"\n Schema of the output of the API call. It is automatically inferred in most cases.\n \"\"\"\n output: Schema\n \"\"\"\n This refers to the API endpoint you're going to call. For instance `https://jsonplaceholder.typicode.com/users`.For \n dynamic segments in your API endpoint, use Mustache templates for variable substitution. \n For instance, to fetch a specific user, use `/users/{{args.id}}`.\n \"\"\"\n path: String!\n \"\"\"\n This represents the query parameters of your API call. You can pass it as a static \n object or use Mustache template for dynamic parameters. These parameters will be \n added to the URL. NOTE: Query parameter order is critical for batching in Tailcall. \n The first parameter referencing a field in the current value using mustache syntax \n is automatically selected as the batching parameter.\n \"\"\"\n query: [URLQuery]\n) on FIELD_DEFINITION | OBJECT\n\ndirective @js(\n name: String!\n) on FIELD_DEFINITION | OBJECT\n\ndirective @modify(\n name: String\n omit: Boolean\n) on FIELD_DEFINITION\n\n\"\"\"\nUsed to omit a field from public consumption.\n\"\"\"\ndirective @omit on FIELD_DEFINITION\n\ndirective @protected on OBJECT | FIELD_DEFINITION\n\n\"\"\"\nThe `@server` directive, when applied at the schema level, offers a comprehensive \nset of server configurations. It dictates how the server behaves and helps tune tailcall \nfor various use-cases.\n\"\"\"\ndirective @server(\n \"\"\"\n `apolloTracing` exposes GraphQL query performance data, including execution time \n of queries and individual resolvers.\n \"\"\"\n apolloTracing: Boolean\n \"\"\"\n `batchRequests` combines multiple requests into one, improving performance but potentially \n introducing latency and complicating debugging. Use judiciously. @default `false`.\n \"\"\"\n batchRequests: Boolean\n \"\"\"\n Enables deduplication of IO operations to enhance performance.This flag prevents \n duplicate IO requests from being executed concurrently, reducing resource load. Caution: \n May lead to issues with APIs that expect unique results for identical inputs, such \n as nonce-based APIs.\n \"\"\"\n dedupe: Boolean\n enableJIT: Boolean\n \"\"\"\n `globalResponseTimeout` sets the maximum query duration before termination, acting \n as a safeguard against long-running queries.\n \"\"\"\n globalResponseTimeout: Int\n \"\"\"\n `headers` contains key-value pairs that are included as default headers in server \n responses, allowing for consistent header management across all responses.\n \"\"\"\n headers: Headers\n \"\"\"\n `hostname` sets the server hostname.\n \"\"\"\n hostname: String\n \"\"\"\n `introspection` allows clients to fetch schema information directly, aiding tools \n and applications in understanding available types, fields, and operations. @default \n `true`.\n \"\"\"\n introspection: Boolean\n \"\"\"\n `pipelineFlush` allows to control flushing behavior of the server pipeline.\n \"\"\"\n pipelineFlush: Boolean\n \"\"\"\n `port` sets the Tailcall running port. @default `8000`.\n \"\"\"\n port: Int\n \"\"\"\n `queryValidation` checks incoming GraphQL queries against the schema, preventing \n errors from invalid queries. Can be disabled for performance. @default `false`.\n \"\"\"\n queryValidation: Boolean\n \"\"\"\n `responseValidation` Tailcall automatically validates responses from upstream services \n using inferred schema. @default `false`.\n \"\"\"\n responseValidation: Boolean\n \"\"\"\n `routes` allows customization of server endpoint paths. It provides options to change \n the default paths for status and GraphQL endpoints. Default values are: - status: \n \"/status\" - graphQL: \"/graphql\" If not specified, these default values will be used.\n \"\"\"\n routes: Routes\n \"\"\"\n A link to an external JS file that listens on every HTTP request response event.\n \"\"\"\n script: ScriptOptions\n \"\"\"\n `showcase` enables the /showcase/graphql endpoint.\n \"\"\"\n showcase: Boolean\n \"\"\"\n This configuration defines local variables for server operations. Useful for storing \n constant configurations, secrets, or shared information.\n \"\"\"\n vars: [KeyValue]\n \"\"\"\n `version` sets the HTTP version for the server. Options are `HTTP1` and `HTTP2`. \n @default `HTTP1`.\n \"\"\"\n version: HttpVersion\n \"\"\"\n `workers` sets the number of worker threads. @default the number of system cores.\n \"\"\"\n workers: Int\n) on SCHEMA\n\n\"\"\"\nThe @telemetry directive facilitates seamless integration with OpenTelemetry, enhancing \nthe observability of your GraphQL services powered by Tailcall. By leveraging this \ndirective, developers gain access to valuable insights into the performance and behavior \nof their applications.\n\"\"\"\ndirective @telemetry(\n export: TelemetryExporter\n \"\"\"\n The list of headers that will be sent as additional attributes to telemetry exporters \n Be careful about **leaking sensitive information** from requests when enabling the \n headers that may contain sensitive data\n \"\"\"\n requestHeaders: [String!]\n) on SCHEMA\n\n\"\"\"\nThe `upstream` directive allows you to control various aspects of the upstream server \nconnection. This includes settings like connection timeouts, keep-alive intervals, \nand more. If not specified, default values are used.\n\"\"\"\ndirective @upstream(\n \"\"\"\n `allowedHeaders` defines the HTTP headers allowed to be forwarded to upstream services. \n If not set, no headers are forwarded, enhancing security but possibly limiting data \n flow.\n \"\"\"\n allowedHeaders: [String!]\n \"\"\"\n This refers to the default base URL for your APIs. If it's not explicitly mentioned \n in the `@upstream` operator, then each [@http](#http) operator must specify its own \n `baseURL`. If neither `@upstream` nor [@http](#http) provides a `baseURL`, it results \n in a compilation error.\n \"\"\"\n baseURL: String\n \"\"\"\n An object that specifies the batch settings, including `maxSize` (the maximum size \n of the batch), `delay` (the delay in milliseconds between each batch), and `headers` \n (an array of HTTP headers to be included in the batch).\n \"\"\"\n batch: Batch\n \"\"\"\n The time in seconds that the connection will wait for a response before timing out.\n \"\"\"\n connectTimeout: Int\n \"\"\"\n The `http2Only` setting allows you to specify whether the client should always issue \n HTTP2 requests, without checking if the server supports it or not. By default it \n is set to `false` for all HTTP requests made by the server, but is automatically \n set to true for GRPC.\n \"\"\"\n http2Only: Boolean\n \"\"\"\n Providing httpCache size enables Tailcall's HTTP caching, adhering to the [HTTP Caching \n RFC](https://tools.ietf.org/html/rfc7234), to enhance performance by minimizing redundant \n data fetches. Defaults to `0` if unspecified.\n \"\"\"\n httpCache: Int\n \"\"\"\n The time in seconds between each keep-alive message sent to maintain the connection.\n \"\"\"\n keepAliveInterval: Int\n \"\"\"\n The time in seconds that the connection will wait for a keep-alive message before \n closing.\n \"\"\"\n keepAliveTimeout: Int\n \"\"\"\n A boolean value that determines whether keep-alive messages should be sent while \n the connection is idle.\n \"\"\"\n keepAliveWhileIdle: Boolean\n \"\"\"\n onRequest field gives the ability to specify the global request interception handler.\n \"\"\"\n onRequest: String\n \"\"\"\n The time in seconds that the connection pool will wait before closing idle connections.\n \"\"\"\n poolIdleTimeout: Int\n \"\"\"\n The maximum number of idle connections that will be maintained per host.\n \"\"\"\n poolMaxIdlePerHost: Int\n \"\"\"\n The `proxy` setting defines an intermediary server through which the upstream requests \n will be routed before reaching their intended endpoint. By specifying a proxy URL, \n you introduce an additional layer, enabling custom routing and security policies.\n \"\"\"\n proxy: Proxy\n \"\"\"\n The time in seconds between each TCP keep-alive message sent to maintain the connection.\n \"\"\"\n tcpKeepAlive: Int\n \"\"\"\n The maximum time in seconds that the connection will wait for a response.\n \"\"\"\n timeout: Int\n \"\"\"\n The User-Agent header value to be used in HTTP requests. @default `Tailcall/1.0`\n \"\"\"\n userAgent: String\n) on SCHEMA\n\n\"\"\"\nField whose value is a sequence of bytes.\n\"\"\"\nscalar Bytes\n\n\"\"\"\nField whose value conforms to the standard date format as specified in RFC 3339 (https://datatracker.ietf.org/doc/html/rfc3339).\n\"\"\"\nscalar Date\n\n\"\"\"\nField whose value conforms to the standard internet email address format as specified \nin HTML Spec: https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address.\n\"\"\"\nscalar Email\n\n\"\"\"\nEmpty scalar type represents an empty value.\n\"\"\"\nscalar Empty\n\n\"\"\"\nField whose value is a 128-bit signed integer.\n\"\"\"\nscalar Int128\n\n\"\"\"\nField whose value is a 16-bit signed integer.\n\"\"\"\nscalar Int16\n\n\"\"\"\nField whose value is a 32-bit signed integer.\n\"\"\"\nscalar Int32\n\n\"\"\"\nField whose value is a 64-bit signed integer.\n\"\"\"\nscalar Int64\n\n\"\"\"\nField whose value is an 8-bit signed integer.\n\"\"\"\nscalar Int8\n\n\"\"\"\nField whose value conforms to the standard JSON format as specified in RFC 8259 (https://datatracker.ietf.org/doc/html/rfc8259).\n\"\"\"\nscalar JSON\n\n\"\"\"\nField whose value conforms to the standard E.164 format as specified in E.164 specification \n(https://en.wikipedia.org/wiki/E.164).\n\"\"\"\nscalar PhoneNumber\n\n\"\"\"\nField whose value is a 128-bit unsigned integer.\n\"\"\"\nscalar UInt128\n\n\"\"\"\nField whose value is a 16-bit unsigned integer.\n\"\"\"\nscalar UInt16\n\n\"\"\"\nField whose value is a 32-bit unsigned integer.\n\"\"\"\nscalar UInt32\n\n\"\"\"\nField whose value is a 64-bit unsigned integer.\n\"\"\"\nscalar UInt64\n\n\"\"\"\nField whose value is an 8-bit unsigned integer.\n\"\"\"\nscalar UInt8\n\n\"\"\"\nField whose value conforms to the standard URL format as specified in RFC 3986 (https://datatracker.ietf.org/doc/html/rfc3986).\n\"\"\"\nscalar Url\n\n\"\"\"\nProvides the ability to refer to a field defined in the root Query or Mutation.\n\"\"\"\ninput Step {\n \"\"\"\n The arguments that will override the actual arguments of the field.\n \"\"\"\n args: JSON\n \"\"\"\n The name of the field on the `Mutation` type that you want to call.\n \"\"\"\n mutation: String\n \"\"\"\n The name of the field on the `Query` type that you want to call.\n \"\"\"\n query: String\n}\n\ninput KeyValue {\n key: String!\n value: String!\n}\n\n\"\"\"\nThe URLQuery input type represents a query parameter to be included in a URL.\n\"\"\"\ninput URLQuery {\n \"\"\"\n The key or name of the query parameter.\n \"\"\"\n key: String!\n \"\"\"\n Determines whether to ignore query parameters with empty values.\n \"\"\"\n skipEmpty: Boolean\n \"\"\"\n The actual value or a mustache template to resolve the value dynamically for the \n query parameter.\n \"\"\"\n value: String!\n}\n\ninput Schema {\n Obj: JSON\n Arr: Schema\n Opt: Schema\n Enum: [String!]\n}\n\n\"\"\"\nType to configure Cross-Origin Resource Sharing (CORS) for a server.\n\"\"\"\ninput Cors {\n \"\"\"\n Indicates whether the server allows credentials (e.g., cookies, authorization headers) \n to be sent in cross-origin requests.\n \"\"\"\n allowCredentials: Boolean\n \"\"\"\n A list of allowed headers in cross-origin requests. This can be used to specify custom \n headers that are allowed to be included in cross-origin requests.\n \"\"\"\n allowHeaders: [String!]\n \"\"\"\n A list of allowed HTTP methods in cross-origin requests. These methods specify the \n actions that are permitted in cross-origin requests.\n \"\"\"\n allowMethods: [Method]\n \"\"\"\n A list of origins that are allowed to access the server's resources in cross-origin \n requests. An origin can be a domain, a subdomain, or even 'null' for local file schemes.\n \"\"\"\n allowOrigins: [String!]\n \"\"\"\n Indicates whether requests from private network addresses are allowed in cross-origin \n requests. Private network addresses typically include IP addresses reserved for internal \n networks.\n \"\"\"\n allowPrivateNetwork: Boolean\n \"\"\"\n A list of headers that the server exposes to the browser in cross-origin responses. \n Exposing certain headers allows the client-side code to access them in the response.\n \"\"\"\n exposeHeaders: [String!]\n \"\"\"\n The maximum time (in seconds) that the client should cache preflight OPTIONS requests \n in order to avoid sending excessive requests to the server.\n \"\"\"\n maxAge: Int\n \"\"\"\n A list of header names that indicate the values of which might cause the server's \n response to vary, potentially affecting caching.\n \"\"\"\n vary: [String!]\n}\n\ninput Headers {\n \"\"\"\n `cacheControl` sends `Cache-Control` headers in responses when activated. The `max-age` \n value is the least of the values received from upstream services. @default `false`.\n \"\"\"\n cacheControl: Boolean\n \"\"\"\n `cors` allows Cross-Origin Resource Sharing (CORS) for a server.\n \"\"\"\n cors: Cors\n \"\"\"\n `headers` are key-value pairs included in every server response. Useful for setting \n headers like `Access-Control-Allow-Origin` for cross-origin requests or additional \n headers for downstream services.\n \"\"\"\n custom: [KeyValue]\n \"\"\"\n `experimental` allows the use of `X-*` experimental headers in the response. @default \n `[]`.\n \"\"\"\n experimental: [String!]\n \"\"\"\n `setCookies` when enabled stores `set-cookie` headers and all the response will be \n sent with the headers.\n \"\"\"\n setCookies: Boolean\n}\n\ninput Routes {\n graphQL: String!\n status: String!\n}\n\ninput ScriptOptions {\n timeout: Int\n}\n\ninput Apollo {\n \"\"\"\n Setting `apiKey` for Apollo.\n \"\"\"\n apiKey: String!\n \"\"\"\n Setting `graphRef` for Apollo in the format @.\n \"\"\"\n graphRef: String!\n \"\"\"\n Setting `platform` for Apollo.\n \"\"\"\n platform: String\n \"\"\"\n Setting `userVersion` for Apollo.\n \"\"\"\n userVersion: String\n \"\"\"\n Setting `version` for Apollo.\n \"\"\"\n version: String\n}\n\n\"\"\"\nOutput the opentelemetry data to otlp collector\n\"\"\"\ninput OtlpExporter {\n headers: [KeyValue]\n url: String!\n}\n\n\"\"\"\nOutput the telemetry metrics data to prometheus server\n\"\"\"\ninput PrometheusExporter {\n format: PrometheusFormat\n path: String!\n}\n\n\"\"\"\nOutput the opentelemetry data to the stdout. Mostly used for debug purposes\n\"\"\"\ninput StdoutExporter {\n \"\"\"\n Output to stdout in pretty human-readable format\n \"\"\"\n pretty: Boolean!\n}\n\ninput TelemetryExporter {\n stdout: StdoutExporter\n otlp: OtlpExporter\n prometheus: PrometheusExporter\n apollo: Apollo\n}\n\ninput Batch {\n delay: Int!\n headers: [String!]\n maxSize: Int\n}\n\ninput Proxy {\n url: String!\n}\n\n\"\"\"\nThe @graphQL operator allows to specify GraphQL API server request to fetch data \nfrom.\n\"\"\"\ninput GraphQL {\n \"\"\"\n Named arguments for the requested field. More info [here](https://tailcall.run/docs/guides/operators/#args)\n \"\"\"\n args: [KeyValue]\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n If the upstream GraphQL server supports request batching, you can specify the 'batch' \n argument to batch several requests into a single batch request.Make sure you have \n also specified batch settings to the `@upstream` and to the `@graphQL` operator.\n \"\"\"\n batch: Boolean!\n \"\"\"\n The headers parameter allows you to customize the headers of the GraphQL request \n made by the `@graphQL` operator. It is used by specifying a key-value map of header \n names and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Specifies the root field on the upstream to request data from. This maps a field \n in your schema to a field in the upstream schema. When a query is received for this \n field, Tailcall requests data from the corresponding upstream field.\n \"\"\"\n name: String!\n}\n\n\"\"\"\nThe @grpc operator indicates that a field or node is backed by a gRPC API.For instance, \nif you add the @grpc operator to the `users` field of the Query type with a service \nargument of `NewsService` and method argument of `GetAllNews`, it signifies that \nthe `users` field is backed by a gRPC API. The `service` argument specifies the name \nof the gRPC service. The `method` argument specifies the name of the gRPC method. \nIn this scenario, the GraphQL server will make a gRPC request to the gRPC endpoint \nspecified when the `users` field is queried.\n\"\"\"\ninput Grpc {\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n This refers to the arguments of your gRPC call. You can pass it as a static object \n or use Mustache template for dynamic parameters. These parameters will be added in \n the body in `protobuf` format.\n \"\"\"\n body: JSON\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@grpc` operator. It is used by specifying a key-value map of header names \n and their values. Note: content-type is automatically set to application/grpc\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n This refers to the gRPC method you're going to call. For instance `GetAllNews`.\n \"\"\"\n method: String!\n}\n\n\"\"\"\nThe @http operator indicates that a field or node is backed by a REST API.For instance, \nif you add the @http operator to the `users` field of the Query type with a path \nargument of `\"/users\"`, it signifies that the `users` field is backed by a REST API. \nThe path argument specifies the path of the REST API. In this scenario, the GraphQL \nserver will make a GET request to the API endpoint specified when the `users` field \nis queried.\n\"\"\"\ninput Http {\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n The body of the API call. It's used for methods like POST or PUT that send data to \n the server. You can pass it as a static object or use a Mustache template to substitute \n variables from the GraphQL variables.\n \"\"\"\n body: String\n \"\"\"\n The `encoding` parameter specifies the encoding of the request body. It can be `ApplicationJson` \n or `ApplicationXWwwFormUrlEncoded`. @default `ApplicationJson`.\n \"\"\"\n encoding: Encoding\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@http` operator. It is used by specifying a key-value map of header names \n and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Schema of the input of the API call. It is automatically inferred in most cases.\n \"\"\"\n input: Schema\n \"\"\"\n This refers to the HTTP method of the API call. Commonly used methods include `GET`, \n `POST`, `PUT`, `DELETE` etc. @default `GET`.\n \"\"\"\n method: Method\n \"\"\"\n onRequest field in @http directive gives the ability to specify the request interception \n handler.\n \"\"\"\n onRequest: String\n \"\"\"\n Schema of the output of the API call. It is automatically inferred in most cases.\n \"\"\"\n output: Schema\n \"\"\"\n This refers to the API endpoint you're going to call. For instance `https://jsonplaceholder.typicode.com/users`.For \n dynamic segments in your API endpoint, use Mustache templates for variable substitution. \n For instance, to fetch a specific user, use `/users/{{args.id}}`.\n \"\"\"\n path: String!\n \"\"\"\n This represents the query parameters of your API call. You can pass it as a static \n object or use Mustache template for dynamic parameters. These parameters will be \n added to the URL. NOTE: Query parameter order is critical for batching in Tailcall. \n The first parameter referencing a field in the current value using mustache syntax \n is automatically selected as the batching parameter.\n \"\"\"\n query: [URLQuery]\n}\n\n\"\"\"\nThe `@expr` operators allows you to specify an expression that can evaluate to a \nvalue. The expression can be a static value or built form a Mustache template. schema.\n\"\"\"\ninput Expr {\n body: JSON\n}\n\ninput JS {\n name: String!\n}\n\ninput Modify {\n name: String\n omit: Boolean\n}\n\n\"\"\"\nThe @cache operator enables caching for the query, field or type it is applied to.\n\"\"\"\ninput Cache {\n \"\"\"\n Specifies the duration, in milliseconds, of how long the value has to be stored in \n the cache.\n \"\"\"\n maxAge: Int!\n}\n\n\"\"\"\nThe @telemetry directive facilitates seamless integration with OpenTelemetry, enhancing \nthe observability of your GraphQL services powered by Tailcall. By leveraging this \ndirective, developers gain access to valuable insights into the performance and behavior \nof their applications.\n\"\"\"\ninput Telemetry {\n export: TelemetryExporter\n \"\"\"\n The list of headers that will be sent as additional attributes to telemetry exporters \n Be careful about **leaking sensitive information** from requests when enabling the \n headers that may contain sensitive data\n \"\"\"\n requestHeaders: [String!]\n}\n\nenum Encoding {\n ApplicationJson\n ApplicationXWwwFormUrlencoded\n}\n\nenum Method {\n GET\n POST\n PUT\n PATCH\n DELETE\n HEAD\n OPTIONS\n CONNECT\n TRACE\n}\n\nenum LinkType {\n Config\n Protobuf\n Script\n Cert\n Key\n Operation\n Htpasswd\n Jwks\n Grpc\n}\n\nenum HttpVersion {\n HTTP1\n HTTP2\n}\n\n\"\"\"\nOutput format for prometheus data\n\"\"\"\nenum PrometheusFormat {\n text\n protobuf\n}\n\nextend schema @link(\n\turl: \"https://specs.apollo.dev/federation/v2.3\",\n\timport: [\"@key\", \"@tag\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@composeDirective\", \"@interfaceObject\"]\n)\n" + } + } + } +} diff --git a/tests/core/snapshots/apollo-federation-entities-batch.md_client.snap b/tests/core/snapshots/apollo-federation-entities-batch.md_client.snap new file mode 100644 index 0000000000..bf6bfe42a1 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities-batch.md_client.snap @@ -0,0 +1,73 @@ +--- +source: tests/core/spec.rs +expression: formatted +--- +scalar Bytes + +scalar Date + +scalar DateTime + +scalar Email + +scalar Empty + +scalar Int128 + +scalar Int16 + +scalar Int32 + +scalar Int64 + +scalar Int8 + +scalar JSON + +scalar PhoneNumber + +type Post { + id: Int! + title: String! +} + +type Query { + """ + Apollo federation Query._entities resolver + """ + _entities(representations: [_Any!]!): [_Entity]! + """ + Apollo federation Query._service resolver + """ + _service: _Service! + user(id: Int!): User +} + +scalar UInt128 + +scalar UInt16 + +scalar UInt32 + +scalar UInt64 + +scalar UInt8 + +scalar Url + +type User { + id: Int! + name: String! +} + +scalar _Any + +union _Entity = Post | User + +type _Service { + sdl: String +} + +schema { + query: Query +} diff --git a/tests/core/snapshots/apollo-federation-entities-batch.md_merged.snap b/tests/core/snapshots/apollo-federation-entities-batch.md_merged.snap new file mode 100644 index 0000000000..1403201548 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities-batch.md_merged.snap @@ -0,0 +1,43 @@ +--- +source: tests/core/spec.rs +expression: formatter +--- +schema + @server(port: 8000) + @upstream(baseURL: "http://jsonplaceholder.typicode.com", batch: {delay: 100, headers: []}, httpCache: 42) { + query: Query +} + +scalar _Any + +union _Entity = Post | User + +type Post + @graphQL(args: [{key: "id", value: "{{.value.id}}"}], baseURL: "http://upstream/graphql", batch: true, name: "post") + @key(fields: "id") { + id: Int! + title: String! +} + +type Query { + """ + Apollo federation Query._entities resolver + """ + _entities(representations: [_Any!]!): [_Entity]! + """ + Apollo federation Query._service resolver + """ + _service: _Service! + user(id: Int!): User @http(path: "/users/{{.args.id}}") +} + +type User + @http(batchKey: ["id"], path: "/users", query: [{key: "id", value: "{{.value.user.id}}"}]) + @key(fields: "user { id }") { + id: Int! + name: String! +} + +type _Service { + sdl: String +} diff --git a/tests/core/snapshots/apollo-federation-entities-validation.md_error.snap b/tests/core/snapshots/apollo-federation-entities-validation.md_error.snap new file mode 100644 index 0000000000..876c8e3ed9 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities-validation.md_error.snap @@ -0,0 +1,23 @@ +--- +source: tests/core/spec.rs +expression: errors +--- +[ + { + "message": "Type resolver can't use `.args`, use `.value` instead", + "trace": [ + "Post", + "http", + "query" + ], + "description": null + }, + { + "message": "Type resolver can't use `.args`, use `.value` instead", + "trace": [ + "User", + "call" + ], + "description": null + } +] diff --git a/tests/core/snapshots/apollo-federation-entities.md_0.snap b/tests/core/snapshots/apollo-federation-entities.md_0.snap new file mode 100644 index 0000000000..071a6837f3 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities.md_0.snap @@ -0,0 +1,36 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "_entities": [ + { + "__typename": "User", + "id": 1, + "name": "Leanne Graham" + }, + { + "__typename": "User", + "id": 2, + "name": "Ervin Howell" + }, + { + "__typename": "Post", + "id": 3, + "title": "post-title-3" + }, + { + "__typename": "Post", + "id": 5, + "title": "post-title-5" + } + ] + } + } +} diff --git a/tests/core/snapshots/apollo-federation-entities.md_1.snap b/tests/core/snapshots/apollo-federation-entities.md_1.snap new file mode 100644 index 0000000000..33868f4d32 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities.md_1.snap @@ -0,0 +1,17 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "_service": { + "sdl": "schema @server(port: 8000) @upstream(baseURL: \"http://jsonplaceholder.typicode.com\", batch: {delay: 100, headers: []}, httpCache: 42) {\n query: Query\n}\n\nscalar _Any\n\nunion _Entity = Post | User\n\ntype Post @expr(body: {id: \"{{.value.id}}\", title: \"post-title-{{.value.id}}\"}) @key(fields: \"id\") {\n id: Int!\n title: String!\n}\n\ntype Query {\n \"\"\"\n Apollo federation Query._entities resolver\n \"\"\"\n _entities(representations: [_Any!]!): [_Entity]!\n \"\"\"\n Apollo federation Query._service resolver\n \"\"\"\n _service: _Service!\n user(id: Int!): User @http(path: \"/users/{{.args.id}}\")\n}\n\ntype User @call(steps: [{query: \"user\", args: {id: \"{{.value.user.id}}\"}}]) @key(fields: \"user { id }\") {\n id: Int!\n name: String!\n}\n\ntype _Service {\n sdl: String\n}\n\"\"\"\nThe @addField operator simplifies data structures and queries by adding a field that \ninlines or flattens a nested field or node within your schema. more info [here](https://tailcall.run/docs/guides/operators/#addfield)\n\"\"\"\ndirective @addField(\n \"\"\"\n Name of the new field to be added\n \"\"\"\n name: String!\n \"\"\"\n Path of the data where the field should point to\n \"\"\"\n path: [String!]\n) repeatable on OBJECT\n\n\"\"\"\nThe @alias directive indicates that aliases of one enum value.\n\"\"\"\ndirective @alias(\n options: [String!]\n) on ENUM_VALUE\n\n\"\"\"\nThe @cache operator enables caching for the query, field or type it is applied to.\n\"\"\"\ndirective @cache(\n \"\"\"\n Specifies the duration, in milliseconds, of how long the value has to be stored in \n the cache.\n \"\"\"\n maxAge: Int!\n) on OBJECT | FIELD_DEFINITION\n\n\"\"\"\nProvides the ability to refer to multiple fields in the Query or Mutation root.\n\"\"\"\ndirective @call(\n \"\"\"\n Steps are composed together to form a call. If you have multiple steps, the output \n of the previous step is passed as input to the next step.\n \"\"\"\n steps: [Step]\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe `@expr` operators allows you to specify an expression that can evaluate to a \nvalue. The expression can be a static value or built form a Mustache template. schema.\n\"\"\"\ndirective @expr(\n body: JSON\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe @graphQL operator allows to specify GraphQL API server request to fetch data \nfrom.\n\"\"\"\ndirective @graphQL(\n \"\"\"\n Named arguments for the requested field. More info [here](https://tailcall.run/docs/guides/operators/#args)\n \"\"\"\n args: [KeyValue]\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n If the upstream GraphQL server supports request batching, you can specify the 'batch' \n argument to batch several requests into a single batch request.Make sure you have \n also specified batch settings to the `@upstream` and to the `@graphQL` operator.\n \"\"\"\n batch: Boolean!\n \"\"\"\n The headers parameter allows you to customize the headers of the GraphQL request \n made by the `@graphQL` operator. It is used by specifying a key-value map of header \n names and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Specifies the root field on the upstream to request data from. This maps a field \n in your schema to a field in the upstream schema. When a query is received for this \n field, Tailcall requests data from the corresponding upstream field.\n \"\"\"\n name: String!\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe @grpc operator indicates that a field or node is backed by a gRPC API.For instance, \nif you add the @grpc operator to the `users` field of the Query type with a service \nargument of `NewsService` and method argument of `GetAllNews`, it signifies that \nthe `users` field is backed by a gRPC API. The `service` argument specifies the name \nof the gRPC service. The `method` argument specifies the name of the gRPC method. \nIn this scenario, the GraphQL server will make a gRPC request to the gRPC endpoint \nspecified when the `users` field is queried.\n\"\"\"\ndirective @grpc(\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n This refers to the arguments of your gRPC call. You can pass it as a static object \n or use Mustache template for dynamic parameters. These parameters will be added in \n the body in `protobuf` format.\n \"\"\"\n body: JSON\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@grpc` operator. It is used by specifying a key-value map of header names \n and their values. Note: content-type is automatically set to application/grpc\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n This refers to the gRPC method you're going to call. For instance `GetAllNews`.\n \"\"\"\n method: String!\n) on FIELD_DEFINITION | OBJECT\n\n\"\"\"\nThe @http operator indicates that a field or node is backed by a REST API.For instance, \nif you add the @http operator to the `users` field of the Query type with a path \nargument of `\"/users\"`, it signifies that the `users` field is backed by a REST API. \nThe path argument specifies the path of the REST API. In this scenario, the GraphQL \nserver will make a GET request to the API endpoint specified when the `users` field \nis queried.\n\"\"\"\ndirective @http(\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n The body of the API call. It's used for methods like POST or PUT that send data to \n the server. You can pass it as a static object or use a Mustache template to substitute \n variables from the GraphQL variables.\n \"\"\"\n body: String\n \"\"\"\n The `encoding` parameter specifies the encoding of the request body. It can be `ApplicationJson` \n or `ApplicationXWwwFormUrlEncoded`. @default `ApplicationJson`.\n \"\"\"\n encoding: Encoding\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@http` operator. It is used by specifying a key-value map of header names \n and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Schema of the input of the API call. It is automatically inferred in most cases.\n \"\"\"\n input: Schema\n \"\"\"\n This refers to the HTTP method of the API call. Commonly used methods include `GET`, \n `POST`, `PUT`, `DELETE` etc. @default `GET`.\n \"\"\"\n method: Method\n \"\"\"\n onRequest field in @http directive gives the ability to specify the request interception \n handler.\n \"\"\"\n onRequest: String\n \"\"\"\n Schema of the output of the API call. It is automatically inferred in most cases.\n \"\"\"\n output: Schema\n \"\"\"\n This refers to the API endpoint you're going to call. For instance `https://jsonplaceholder.typicode.com/users`.For \n dynamic segments in your API endpoint, use Mustache templates for variable substitution. \n For instance, to fetch a specific user, use `/users/{{args.id}}`.\n \"\"\"\n path: String!\n \"\"\"\n This represents the query parameters of your API call. You can pass it as a static \n object or use Mustache template for dynamic parameters. These parameters will be \n added to the URL. NOTE: Query parameter order is critical for batching in Tailcall. \n The first parameter referencing a field in the current value using mustache syntax \n is automatically selected as the batching parameter.\n \"\"\"\n query: [URLQuery]\n) on FIELD_DEFINITION | OBJECT\n\ndirective @js(\n name: String!\n) on FIELD_DEFINITION | OBJECT\n\ndirective @modify(\n name: String\n omit: Boolean\n) on FIELD_DEFINITION\n\n\"\"\"\nUsed to omit a field from public consumption.\n\"\"\"\ndirective @omit on FIELD_DEFINITION\n\ndirective @protected on OBJECT | FIELD_DEFINITION\n\n\"\"\"\nThe `@server` directive, when applied at the schema level, offers a comprehensive \nset of server configurations. It dictates how the server behaves and helps tune tailcall \nfor various use-cases.\n\"\"\"\ndirective @server(\n \"\"\"\n `apolloTracing` exposes GraphQL query performance data, including execution time \n of queries and individual resolvers.\n \"\"\"\n apolloTracing: Boolean\n \"\"\"\n `batchRequests` combines multiple requests into one, improving performance but potentially \n introducing latency and complicating debugging. Use judiciously. @default `false`.\n \"\"\"\n batchRequests: Boolean\n \"\"\"\n Enables deduplication of IO operations to enhance performance.This flag prevents \n duplicate IO requests from being executed concurrently, reducing resource load. Caution: \n May lead to issues with APIs that expect unique results for identical inputs, such \n as nonce-based APIs.\n \"\"\"\n dedupe: Boolean\n enableJIT: Boolean\n \"\"\"\n `globalResponseTimeout` sets the maximum query duration before termination, acting \n as a safeguard against long-running queries.\n \"\"\"\n globalResponseTimeout: Int\n \"\"\"\n `headers` contains key-value pairs that are included as default headers in server \n responses, allowing for consistent header management across all responses.\n \"\"\"\n headers: Headers\n \"\"\"\n `hostname` sets the server hostname.\n \"\"\"\n hostname: String\n \"\"\"\n `introspection` allows clients to fetch schema information directly, aiding tools \n and applications in understanding available types, fields, and operations. @default \n `true`.\n \"\"\"\n introspection: Boolean\n \"\"\"\n `pipelineFlush` allows to control flushing behavior of the server pipeline.\n \"\"\"\n pipelineFlush: Boolean\n \"\"\"\n `port` sets the Tailcall running port. @default `8000`.\n \"\"\"\n port: Int\n \"\"\"\n `queryValidation` checks incoming GraphQL queries against the schema, preventing \n errors from invalid queries. Can be disabled for performance. @default `false`.\n \"\"\"\n queryValidation: Boolean\n \"\"\"\n `responseValidation` Tailcall automatically validates responses from upstream services \n using inferred schema. @default `false`.\n \"\"\"\n responseValidation: Boolean\n \"\"\"\n `routes` allows customization of server endpoint paths. It provides options to change \n the default paths for status and GraphQL endpoints. Default values are: - status: \n \"/status\" - graphQL: \"/graphql\" If not specified, these default values will be used.\n \"\"\"\n routes: Routes\n \"\"\"\n A link to an external JS file that listens on every HTTP request response event.\n \"\"\"\n script: ScriptOptions\n \"\"\"\n `showcase` enables the /showcase/graphql endpoint.\n \"\"\"\n showcase: Boolean\n \"\"\"\n This configuration defines local variables for server operations. Useful for storing \n constant configurations, secrets, or shared information.\n \"\"\"\n vars: [KeyValue]\n \"\"\"\n `version` sets the HTTP version for the server. Options are `HTTP1` and `HTTP2`. \n @default `HTTP1`.\n \"\"\"\n version: HttpVersion\n \"\"\"\n `workers` sets the number of worker threads. @default the number of system cores.\n \"\"\"\n workers: Int\n) on SCHEMA\n\n\"\"\"\nThe @telemetry directive facilitates seamless integration with OpenTelemetry, enhancing \nthe observability of your GraphQL services powered by Tailcall. By leveraging this \ndirective, developers gain access to valuable insights into the performance and behavior \nof their applications.\n\"\"\"\ndirective @telemetry(\n export: TelemetryExporter\n \"\"\"\n The list of headers that will be sent as additional attributes to telemetry exporters \n Be careful about **leaking sensitive information** from requests when enabling the \n headers that may contain sensitive data\n \"\"\"\n requestHeaders: [String!]\n) on SCHEMA\n\n\"\"\"\nThe `upstream` directive allows you to control various aspects of the upstream server \nconnection. This includes settings like connection timeouts, keep-alive intervals, \nand more. If not specified, default values are used.\n\"\"\"\ndirective @upstream(\n \"\"\"\n `allowedHeaders` defines the HTTP headers allowed to be forwarded to upstream services. \n If not set, no headers are forwarded, enhancing security but possibly limiting data \n flow.\n \"\"\"\n allowedHeaders: [String!]\n \"\"\"\n This refers to the default base URL for your APIs. If it's not explicitly mentioned \n in the `@upstream` operator, then each [@http](#http) operator must specify its own \n `baseURL`. If neither `@upstream` nor [@http](#http) provides a `baseURL`, it results \n in a compilation error.\n \"\"\"\n baseURL: String\n \"\"\"\n An object that specifies the batch settings, including `maxSize` (the maximum size \n of the batch), `delay` (the delay in milliseconds between each batch), and `headers` \n (an array of HTTP headers to be included in the batch).\n \"\"\"\n batch: Batch\n \"\"\"\n The time in seconds that the connection will wait for a response before timing out.\n \"\"\"\n connectTimeout: Int\n \"\"\"\n The `http2Only` setting allows you to specify whether the client should always issue \n HTTP2 requests, without checking if the server supports it or not. By default it \n is set to `false` for all HTTP requests made by the server, but is automatically \n set to true for GRPC.\n \"\"\"\n http2Only: Boolean\n \"\"\"\n Providing httpCache size enables Tailcall's HTTP caching, adhering to the [HTTP Caching \n RFC](https://tools.ietf.org/html/rfc7234), to enhance performance by minimizing redundant \n data fetches. Defaults to `0` if unspecified.\n \"\"\"\n httpCache: Int\n \"\"\"\n The time in seconds between each keep-alive message sent to maintain the connection.\n \"\"\"\n keepAliveInterval: Int\n \"\"\"\n The time in seconds that the connection will wait for a keep-alive message before \n closing.\n \"\"\"\n keepAliveTimeout: Int\n \"\"\"\n A boolean value that determines whether keep-alive messages should be sent while \n the connection is idle.\n \"\"\"\n keepAliveWhileIdle: Boolean\n \"\"\"\n onRequest field gives the ability to specify the global request interception handler.\n \"\"\"\n onRequest: String\n \"\"\"\n The time in seconds that the connection pool will wait before closing idle connections.\n \"\"\"\n poolIdleTimeout: Int\n \"\"\"\n The maximum number of idle connections that will be maintained per host.\n \"\"\"\n poolMaxIdlePerHost: Int\n \"\"\"\n The `proxy` setting defines an intermediary server through which the upstream requests \n will be routed before reaching their intended endpoint. By specifying a proxy URL, \n you introduce an additional layer, enabling custom routing and security policies.\n \"\"\"\n proxy: Proxy\n \"\"\"\n The time in seconds between each TCP keep-alive message sent to maintain the connection.\n \"\"\"\n tcpKeepAlive: Int\n \"\"\"\n The maximum time in seconds that the connection will wait for a response.\n \"\"\"\n timeout: Int\n \"\"\"\n The User-Agent header value to be used in HTTP requests. @default `Tailcall/1.0`\n \"\"\"\n userAgent: String\n) on SCHEMA\n\n\"\"\"\nField whose value is a sequence of bytes.\n\"\"\"\nscalar Bytes\n\n\"\"\"\nField whose value conforms to the standard date format as specified in RFC 3339 (https://datatracker.ietf.org/doc/html/rfc3339).\n\"\"\"\nscalar Date\n\n\"\"\"\nField whose value conforms to the standard internet email address format as specified \nin HTML Spec: https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address.\n\"\"\"\nscalar Email\n\n\"\"\"\nEmpty scalar type represents an empty value.\n\"\"\"\nscalar Empty\n\n\"\"\"\nField whose value is a 128-bit signed integer.\n\"\"\"\nscalar Int128\n\n\"\"\"\nField whose value is a 16-bit signed integer.\n\"\"\"\nscalar Int16\n\n\"\"\"\nField whose value is a 32-bit signed integer.\n\"\"\"\nscalar Int32\n\n\"\"\"\nField whose value is a 64-bit signed integer.\n\"\"\"\nscalar Int64\n\n\"\"\"\nField whose value is an 8-bit signed integer.\n\"\"\"\nscalar Int8\n\n\"\"\"\nField whose value conforms to the standard JSON format as specified in RFC 8259 (https://datatracker.ietf.org/doc/html/rfc8259).\n\"\"\"\nscalar JSON\n\n\"\"\"\nField whose value conforms to the standard E.164 format as specified in E.164 specification \n(https://en.wikipedia.org/wiki/E.164).\n\"\"\"\nscalar PhoneNumber\n\n\"\"\"\nField whose value is a 128-bit unsigned integer.\n\"\"\"\nscalar UInt128\n\n\"\"\"\nField whose value is a 16-bit unsigned integer.\n\"\"\"\nscalar UInt16\n\n\"\"\"\nField whose value is a 32-bit unsigned integer.\n\"\"\"\nscalar UInt32\n\n\"\"\"\nField whose value is a 64-bit unsigned integer.\n\"\"\"\nscalar UInt64\n\n\"\"\"\nField whose value is an 8-bit unsigned integer.\n\"\"\"\nscalar UInt8\n\n\"\"\"\nField whose value conforms to the standard URL format as specified in RFC 3986 (https://datatracker.ietf.org/doc/html/rfc3986).\n\"\"\"\nscalar Url\n\n\"\"\"\nProvides the ability to refer to a field defined in the root Query or Mutation.\n\"\"\"\ninput Step {\n \"\"\"\n The arguments that will override the actual arguments of the field.\n \"\"\"\n args: JSON\n \"\"\"\n The name of the field on the `Mutation` type that you want to call.\n \"\"\"\n mutation: String\n \"\"\"\n The name of the field on the `Query` type that you want to call.\n \"\"\"\n query: String\n}\n\ninput KeyValue {\n key: String!\n value: String!\n}\n\n\"\"\"\nThe URLQuery input type represents a query parameter to be included in a URL.\n\"\"\"\ninput URLQuery {\n \"\"\"\n The key or name of the query parameter.\n \"\"\"\n key: String!\n \"\"\"\n Determines whether to ignore query parameters with empty values.\n \"\"\"\n skipEmpty: Boolean\n \"\"\"\n The actual value or a mustache template to resolve the value dynamically for the \n query parameter.\n \"\"\"\n value: String!\n}\n\ninput Schema {\n Obj: JSON\n Arr: Schema\n Opt: Schema\n Enum: [String!]\n}\n\n\"\"\"\nType to configure Cross-Origin Resource Sharing (CORS) for a server.\n\"\"\"\ninput Cors {\n \"\"\"\n Indicates whether the server allows credentials (e.g., cookies, authorization headers) \n to be sent in cross-origin requests.\n \"\"\"\n allowCredentials: Boolean\n \"\"\"\n A list of allowed headers in cross-origin requests. This can be used to specify custom \n headers that are allowed to be included in cross-origin requests.\n \"\"\"\n allowHeaders: [String!]\n \"\"\"\n A list of allowed HTTP methods in cross-origin requests. These methods specify the \n actions that are permitted in cross-origin requests.\n \"\"\"\n allowMethods: [Method]\n \"\"\"\n A list of origins that are allowed to access the server's resources in cross-origin \n requests. An origin can be a domain, a subdomain, or even 'null' for local file schemes.\n \"\"\"\n allowOrigins: [String!]\n \"\"\"\n Indicates whether requests from private network addresses are allowed in cross-origin \n requests. Private network addresses typically include IP addresses reserved for internal \n networks.\n \"\"\"\n allowPrivateNetwork: Boolean\n \"\"\"\n A list of headers that the server exposes to the browser in cross-origin responses. \n Exposing certain headers allows the client-side code to access them in the response.\n \"\"\"\n exposeHeaders: [String!]\n \"\"\"\n The maximum time (in seconds) that the client should cache preflight OPTIONS requests \n in order to avoid sending excessive requests to the server.\n \"\"\"\n maxAge: Int\n \"\"\"\n A list of header names that indicate the values of which might cause the server's \n response to vary, potentially affecting caching.\n \"\"\"\n vary: [String!]\n}\n\ninput Headers {\n \"\"\"\n `cacheControl` sends `Cache-Control` headers in responses when activated. The `max-age` \n value is the least of the values received from upstream services. @default `false`.\n \"\"\"\n cacheControl: Boolean\n \"\"\"\n `cors` allows Cross-Origin Resource Sharing (CORS) for a server.\n \"\"\"\n cors: Cors\n \"\"\"\n `headers` are key-value pairs included in every server response. Useful for setting \n headers like `Access-Control-Allow-Origin` for cross-origin requests or additional \n headers for downstream services.\n \"\"\"\n custom: [KeyValue]\n \"\"\"\n `experimental` allows the use of `X-*` experimental headers in the response. @default \n `[]`.\n \"\"\"\n experimental: [String!]\n \"\"\"\n `setCookies` when enabled stores `set-cookie` headers and all the response will be \n sent with the headers.\n \"\"\"\n setCookies: Boolean\n}\n\ninput Routes {\n graphQL: String!\n status: String!\n}\n\ninput ScriptOptions {\n timeout: Int\n}\n\ninput Apollo {\n \"\"\"\n Setting `apiKey` for Apollo.\n \"\"\"\n apiKey: String!\n \"\"\"\n Setting `graphRef` for Apollo in the format @.\n \"\"\"\n graphRef: String!\n \"\"\"\n Setting `platform` for Apollo.\n \"\"\"\n platform: String\n \"\"\"\n Setting `userVersion` for Apollo.\n \"\"\"\n userVersion: String\n \"\"\"\n Setting `version` for Apollo.\n \"\"\"\n version: String\n}\n\n\"\"\"\nOutput the opentelemetry data to otlp collector\n\"\"\"\ninput OtlpExporter {\n headers: [KeyValue]\n url: String!\n}\n\n\"\"\"\nOutput the telemetry metrics data to prometheus server\n\"\"\"\ninput PrometheusExporter {\n format: PrometheusFormat\n path: String!\n}\n\n\"\"\"\nOutput the opentelemetry data to the stdout. Mostly used for debug purposes\n\"\"\"\ninput StdoutExporter {\n \"\"\"\n Output to stdout in pretty human-readable format\n \"\"\"\n pretty: Boolean!\n}\n\ninput TelemetryExporter {\n stdout: StdoutExporter\n otlp: OtlpExporter\n prometheus: PrometheusExporter\n apollo: Apollo\n}\n\ninput Batch {\n delay: Int!\n headers: [String!]\n maxSize: Int\n}\n\ninput Proxy {\n url: String!\n}\n\n\"\"\"\nThe @graphQL operator allows to specify GraphQL API server request to fetch data \nfrom.\n\"\"\"\ninput GraphQL {\n \"\"\"\n Named arguments for the requested field. More info [here](https://tailcall.run/docs/guides/operators/#args)\n \"\"\"\n args: [KeyValue]\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n If the upstream GraphQL server supports request batching, you can specify the 'batch' \n argument to batch several requests into a single batch request.Make sure you have \n also specified batch settings to the `@upstream` and to the `@graphQL` operator.\n \"\"\"\n batch: Boolean!\n \"\"\"\n The headers parameter allows you to customize the headers of the GraphQL request \n made by the `@graphQL` operator. It is used by specifying a key-value map of header \n names and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Specifies the root field on the upstream to request data from. This maps a field \n in your schema to a field in the upstream schema. When a query is received for this \n field, Tailcall requests data from the corresponding upstream field.\n \"\"\"\n name: String!\n}\n\n\"\"\"\nThe @grpc operator indicates that a field or node is backed by a gRPC API.For instance, \nif you add the @grpc operator to the `users` field of the Query type with a service \nargument of `NewsService` and method argument of `GetAllNews`, it signifies that \nthe `users` field is backed by a gRPC API. The `service` argument specifies the name \nof the gRPC service. The `method` argument specifies the name of the gRPC method. \nIn this scenario, the GraphQL server will make a gRPC request to the gRPC endpoint \nspecified when the `users` field is queried.\n\"\"\"\ninput Grpc {\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n This refers to the arguments of your gRPC call. You can pass it as a static object \n or use Mustache template for dynamic parameters. These parameters will be added in \n the body in `protobuf` format.\n \"\"\"\n body: JSON\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@grpc` operator. It is used by specifying a key-value map of header names \n and their values. Note: content-type is automatically set to application/grpc\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n This refers to the gRPC method you're going to call. For instance `GetAllNews`.\n \"\"\"\n method: String!\n}\n\n\"\"\"\nThe @http operator indicates that a field or node is backed by a REST API.For instance, \nif you add the @http operator to the `users` field of the Query type with a path \nargument of `\"/users\"`, it signifies that the `users` field is backed by a REST API. \nThe path argument specifies the path of the REST API. In this scenario, the GraphQL \nserver will make a GET request to the API endpoint specified when the `users` field \nis queried.\n\"\"\"\ninput Http {\n \"\"\"\n This refers to the base URL of the API. If not specified, the default base URL is \n the one specified in the `@upstream` operator.\n \"\"\"\n baseURL: String\n \"\"\"\n The `batchKey` dictates the path Tailcall will follow to group the returned items \n from the batch request. For more details please refer out [n + 1 guide](https://tailcall.run/docs/guides/n+1#solving-using-batching).\n \"\"\"\n batchKey: [String!]\n \"\"\"\n The body of the API call. It's used for methods like POST or PUT that send data to \n the server. You can pass it as a static object or use a Mustache template to substitute \n variables from the GraphQL variables.\n \"\"\"\n body: String\n \"\"\"\n The `encoding` parameter specifies the encoding of the request body. It can be `ApplicationJson` \n or `ApplicationXWwwFormUrlEncoded`. @default `ApplicationJson`.\n \"\"\"\n encoding: Encoding\n \"\"\"\n The `headers` parameter allows you to customize the headers of the HTTP request made \n by the `@http` operator. It is used by specifying a key-value map of header names \n and their values.\n \"\"\"\n headers: [KeyValue]\n \"\"\"\n Schema of the input of the API call. It is automatically inferred in most cases.\n \"\"\"\n input: Schema\n \"\"\"\n This refers to the HTTP method of the API call. Commonly used methods include `GET`, \n `POST`, `PUT`, `DELETE` etc. @default `GET`.\n \"\"\"\n method: Method\n \"\"\"\n onRequest field in @http directive gives the ability to specify the request interception \n handler.\n \"\"\"\n onRequest: String\n \"\"\"\n Schema of the output of the API call. It is automatically inferred in most cases.\n \"\"\"\n output: Schema\n \"\"\"\n This refers to the API endpoint you're going to call. For instance `https://jsonplaceholder.typicode.com/users`.For \n dynamic segments in your API endpoint, use Mustache templates for variable substitution. \n For instance, to fetch a specific user, use `/users/{{args.id}}`.\n \"\"\"\n path: String!\n \"\"\"\n This represents the query parameters of your API call. You can pass it as a static \n object or use Mustache template for dynamic parameters. These parameters will be \n added to the URL. NOTE: Query parameter order is critical for batching in Tailcall. \n The first parameter referencing a field in the current value using mustache syntax \n is automatically selected as the batching parameter.\n \"\"\"\n query: [URLQuery]\n}\n\n\"\"\"\nThe `@expr` operators allows you to specify an expression that can evaluate to a \nvalue. The expression can be a static value or built form a Mustache template. schema.\n\"\"\"\ninput Expr {\n body: JSON\n}\n\ninput JS {\n name: String!\n}\n\ninput Modify {\n name: String\n omit: Boolean\n}\n\n\"\"\"\nThe @cache operator enables caching for the query, field or type it is applied to.\n\"\"\"\ninput Cache {\n \"\"\"\n Specifies the duration, in milliseconds, of how long the value has to be stored in \n the cache.\n \"\"\"\n maxAge: Int!\n}\n\n\"\"\"\nThe @telemetry directive facilitates seamless integration with OpenTelemetry, enhancing \nthe observability of your GraphQL services powered by Tailcall. By leveraging this \ndirective, developers gain access to valuable insights into the performance and behavior \nof their applications.\n\"\"\"\ninput Telemetry {\n export: TelemetryExporter\n \"\"\"\n The list of headers that will be sent as additional attributes to telemetry exporters \n Be careful about **leaking sensitive information** from requests when enabling the \n headers that may contain sensitive data\n \"\"\"\n requestHeaders: [String!]\n}\n\nenum Encoding {\n ApplicationJson\n ApplicationXWwwFormUrlencoded\n}\n\nenum Method {\n GET\n POST\n PUT\n PATCH\n DELETE\n HEAD\n OPTIONS\n CONNECT\n TRACE\n}\n\nenum LinkType {\n Config\n Protobuf\n Script\n Cert\n Key\n Operation\n Htpasswd\n Jwks\n Grpc\n}\n\nenum HttpVersion {\n HTTP1\n HTTP2\n}\n\n\"\"\"\nOutput format for prometheus data\n\"\"\"\nenum PrometheusFormat {\n text\n protobuf\n}\n\nextend schema @link(\n\turl: \"https://specs.apollo.dev/federation/v2.3\",\n\timport: [\"@key\", \"@tag\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@composeDirective\", \"@interfaceObject\"]\n)\n" + } + } + } +} diff --git a/tests/core/snapshots/apollo-federation-entities.md_client.snap b/tests/core/snapshots/apollo-federation-entities.md_client.snap new file mode 100644 index 0000000000..bf6bfe42a1 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities.md_client.snap @@ -0,0 +1,73 @@ +--- +source: tests/core/spec.rs +expression: formatted +--- +scalar Bytes + +scalar Date + +scalar DateTime + +scalar Email + +scalar Empty + +scalar Int128 + +scalar Int16 + +scalar Int32 + +scalar Int64 + +scalar Int8 + +scalar JSON + +scalar PhoneNumber + +type Post { + id: Int! + title: String! +} + +type Query { + """ + Apollo federation Query._entities resolver + """ + _entities(representations: [_Any!]!): [_Entity]! + """ + Apollo federation Query._service resolver + """ + _service: _Service! + user(id: Int!): User +} + +scalar UInt128 + +scalar UInt16 + +scalar UInt32 + +scalar UInt64 + +scalar UInt8 + +scalar Url + +type User { + id: Int! + name: String! +} + +scalar _Any + +union _Entity = Post | User + +type _Service { + sdl: String +} + +schema { + query: Query +} diff --git a/tests/core/snapshots/apollo-federation-entities.md_merged.snap b/tests/core/snapshots/apollo-federation-entities.md_merged.snap new file mode 100644 index 0000000000..b88afd6fb4 --- /dev/null +++ b/tests/core/snapshots/apollo-federation-entities.md_merged.snap @@ -0,0 +1,40 @@ +--- +source: tests/core/spec.rs +expression: formatter +--- +schema + @server(port: 8000) + @upstream(baseURL: "http://jsonplaceholder.typicode.com", batch: {delay: 100, headers: []}, httpCache: 42) + @link(src: "./posts.graphql", type: Config) { + query: Query +} + +scalar _Any + +union _Entity = Post | User + +type Post @expr(body: {id: "{{.value.id}}", title: "post-title-{{.value.id}}"}) @key(fields: "id") { + id: Int! + title: String! +} + +type Query { + """ + Apollo federation Query._entities resolver + """ + _entities(representations: [_Any!]!): [_Entity]! + """ + Apollo federation Query._service resolver + """ + _service: _Service! + user(id: Int!): User @http(path: "/users/{{.args.id}}") +} + +type User @call(steps: [{query: "user", args: {id: "{{.value.user.id}}"}}]) @key(fields: "user { id }") { + id: Int! + name: String! +} + +type _Service { + sdl: String +} diff --git a/tests/execution/apollo-federation-entities-batch.md b/tests/execution/apollo-federation-entities-batch.md new file mode 100644 index 0000000000..94c378a52a --- /dev/null +++ b/tests/execution/apollo-federation-entities-batch.md @@ -0,0 +1,116 @@ +# Apollo federation query for batching resolvers + +```graphql @config +schema + @server(port: 8000) + @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: 42, batch: {delay: 100}) { + query: Query +} + +type Query { + user(id: Int!): User @http(path: "/users/{{.args.id}}") +} + +type User @http(path: "/users", query: [{key: "id", value: "{{.value.user.id}}"}], batchKey: ["id"]) { + id: Int! + name: String! +} + +type Post + @graphQL(baseURL: "http://upstream/graphql", batch: true, name: "post", args: [{key: "id", value: "{{.value.id}}"}]) { + id: Int! + title: String! +} +``` + +```yml @mock +- request: + method: GET + url: http://jsonplaceholder.typicode.com/users?id=1&id=2 + assertHits: false + response: + status: 200 + body: + - id: 1 + name: Leanne Graham + - id: 2 + name: Ervin Howell + +- request: + method: GET + url: http://jsonplaceholder.typicode.com/users?id=2&id=1 + assertHits: false + response: + status: 200 + body: + - id: 2 + name: Ervin Howell + - id: 1 + name: Leanne Graham + +- request: + method: POST + url: http://upstream/graphql + textBody: '[{ "query": "query { post(id: 3) { id title } }" },{ "query": "query { post(id: 5) { id title } }" }]' + assertHits: false + response: + status: 200 + body: + - data: + post: + id: 3 + title: ea molestias quasi exercitationem repellat qui ipsa sit aut + - data: + post: + id: 5 + title: nesciunt quas odio + +- request: + method: POST + url: http://upstream/graphql + textBody: '[{ "query": "query { post(id: 5) { id title } }" },{ "query": "query { post(id: 3) { id title } }" }]' + assertHits: false + response: + status: 200 + body: + - data: + post: + id: 5 + title: nesciunt quas odio + - data: + post: + id: 3 + title: ea molestias quasi exercitationem repellat qui ipsa sit aut +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: > + { + _entities(representations: [ + {user: { id: 1 }, __typename: "User"} + {user: { id: 2 }, __typename: "User"} + # TODO: fix selection set of fields for @graphQL directive in jit + # {id: 3, __typename: "Post"} + # {id: 5, __typename: "Post"} + ]) { + __typename + ...on User { + id + name + } + ...on Post { + id + title + } + } + } + +- method: POST + url: http://localhost:8080/graphql + body: + query: > + { _service { sdl } } +``` diff --git a/tests/execution/apollo-federation-entities-validation.md b/tests/execution/apollo-federation-entities-validation.md new file mode 100644 index 0000000000..2d43c04af4 --- /dev/null +++ b/tests/execution/apollo-federation-entities-validation.md @@ -0,0 +1,78 @@ +--- +error: true +--- + +# Apollo federation query validation + +```graphql @config +schema + @server(port: 8000) + @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: 42, batch: {delay: 100}) { + query: Query +} + +type Query { + user(id: Int!): User @http(path: "/users/{{.args.id}}") +} + +type User @call(steps: [{query: "user", args: {id: "{{.args.id}}"}}]) { + id: Int! + name: String! +} + +type Post @http(path: "/users", query: [{key: "id", value: "{{.args.user.id}}"}]) { + id: Int! + title: String! +} +``` + +```yml @mock +- request: + method: GET + url: http://jsonplaceholder.typicode.com/users/1 + response: + status: 200 + body: + id: 1 + name: Leanne Graham + +- request: + method: GET + url: http://jsonplaceholder.typicode.com/users/2 + response: + status: 200 + body: + id: 2 + name: Ervin Howell +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: > + { + _entities(representations: [ + {user: { id: 1 }, __typename: "User"} + {user: { id: 2 }, __typename: "User"} + {user: { id: 3 }, __typename: "Post"} + {user: { id: 5 }, __typename: "Post"} + ]) { + __typename + ...on User { + id + name + } + ...on Post { + id + title + } + } + } + +- method: POST + url: http://localhost:8080/graphql + body: + query: > + { _service { sdl } } +``` diff --git a/tests/execution/apollo-federation-entities.md b/tests/execution/apollo-federation-entities.md new file mode 100644 index 0000000000..8ee332ce6e --- /dev/null +++ b/tests/execution/apollo-federation-entities.md @@ -0,0 +1,77 @@ +# Apollo federation query + +```graphql @config +schema + @server(port: 8000) + @upstream(baseURL: "http://jsonplaceholder.typicode.com", httpCache: 42, batch: {delay: 100}) + @link(src: "./posts.graphql") { + query: Query +} + +type Query { + user(id: Int!): User @http(path: "/users/{{.args.id}}") +} + +type User @call(steps: [{query: "user", args: {id: "{{.value.user.id}}"}}]) { + id: Int! + name: String! +} +``` + +```graphql @file:posts.graphql +type Post @expr(body: {id: "{{.value.id}}", title: "post-title-{{.value.id}}"}) { + id: Int! + title: String! +} +``` + +```yml @mock +- request: + method: GET + url: http://jsonplaceholder.typicode.com/users/1 + response: + status: 200 + body: + id: 1 + name: Leanne Graham + +- request: + method: GET + url: http://jsonplaceholder.typicode.com/users/2 + response: + status: 200 + body: + id: 2 + name: Ervin Howell +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: > + { + _entities(representations: [ + {user: { id: 1 }, __typename: "User"} + {user: { id: 2 }, __typename: "User"} + {id: 3, __typename: "Post"} + {id: 5, __typename: "Post"} + ]) { + __typename + ...on User { + id + name + } + ...on Post { + id + title + } + } + } + +- method: POST + url: http://localhost:8080/graphql + body: + query: > + { _service { sdl } } +```