diff --git a/src/GraphQL.Client.Abstractions/GraphQL.Client.Abstractions.csproj b/src/GraphQL.Client.Abstractions/GraphQL.Client.Abstractions.csproj
index d7678b66..8e1faee1 100644
--- a/src/GraphQL.Client.Abstractions/GraphQL.Client.Abstractions.csproj
+++ b/src/GraphQL.Client.Abstractions/GraphQL.Client.Abstractions.csproj
@@ -15,4 +15,8 @@
+
+
+
+
diff --git a/src/GraphQL.Client.Abstractions/Utilities/StringExtensions.cs b/src/GraphQL.Client.Abstractions/Utilities/StringExtensions.cs
new file mode 100644
index 00000000..38c718a8
--- /dev/null
+++ b/src/GraphQL.Client.Abstractions/Utilities/StringExtensions.cs
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+
+namespace GraphQL.Client.Abstractions.Utilities
+{
+ ///
+ /// Copied from https://github.com/jquense/StringUtils
+ ///
+ public static class StringExtensions
+ {
+ public static string StripIndent(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.StripIndent(str);
+
+ public static IEnumerable ToWords(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToWords(str);
+
+ public static string ToUpperFirst(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToUpperFirst(str);
+
+ public static string ToLowerFirst(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToLowerFirst(str);
+
+ public static string Capitalize(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.Capitalize(str);
+
+ public static string ToCamelCase(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToCamelCase(str);
+
+ public static string ToConstantCase(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToConstantCase(str);
+
+ public static string ToUpperCase(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToUpperCase(str);
+
+ public static string ToLowerCase(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToLowerCase(str);
+
+
+ public static string ToPascalCase(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToPascalCase(str);
+
+
+ public static string ToKebabCase(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToKebabCase(str);
+
+
+ public static string ToSnakeCase(this string str) => GraphQL.Client.Abstractions.Utilities.StringUtils.ToSnakeCase(str);
+ }
+}
diff --git a/src/GraphQL.Client.Abstractions/Utilities/StringUtils.cs b/src/GraphQL.Client.Abstractions/Utilities/StringUtils.cs
new file mode 100644
index 00000000..c643fd23
--- /dev/null
+++ b/src/GraphQL.Client.Abstractions/Utilities/StringUtils.cs
@@ -0,0 +1,193 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace GraphQL.Client.Abstractions.Utilities
+{
+ ///
+ /// Copied from https://github.com/jquense/StringUtils
+ ///
+ public static class StringUtils
+ {
+ private static readonly Regex _reWords = new Regex(@"[A-Z\xc0-\xd6\xd8-\xde]?[a-z\xdf-\xf6\xf8-\xff]+(?:['’](?:d|ll|m|re|s|t|ve))?(?=[\xac\xb1\xd7\xf7\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf\u2000-\u206f \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000]|[A-Z\xc0-\xd6\xd8-\xde]|$)|(?:[A-Z\xc0-\xd6\xd8-\xde]|[^\ud800-\udfff\xac\xb1\xd7\xf7\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf\u2000-\u206f \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\d+\u2700-\u27bfa-z\xdf-\xf6\xf8-\xffA-Z\xc0-\xd6\xd8-\xde])+(?:['’](?:D|LL|M|RE|S|T|VE))?(?=[\xac\xb1\xd7\xf7\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf\u2000-\u206f \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000]|[A-Z\xc0-\xd6\xd8-\xde](?:[a-z\xdf-\xf6\xf8-\xff]|[^\ud800-\udfff\xac\xb1\xd7\xf7\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf\u2000-\u206f \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\d+\u2700-\u27bfa-z\xdf-\xf6\xf8-\xffA-Z\xc0-\xd6\xd8-\xde])|$)|[A-Z\xc0-\xd6\xd8-\xde]?(?:[a-z\xdf-\xf6\xf8-\xff]|[^\ud800-\udfff\xac\xb1\xd7\xf7\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf\u2000-\u206f \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\d+\u2700-\u27bfa-z\xdf-\xf6\xf8-\xffA-Z\xc0-\xd6\xd8-\xde])+(?:['’](?:d|ll|m|re|s|t|ve))?|[A-Z\xc0-\xd6\xd8-\xde]+(?:['’](?:D|LL|M|RE|S|T|VE))?|\d+|(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*");
+ private static readonly Regex _reIndent = new Regex(@"^[ \t]*(?=\S)", RegexOptions.Multiline);
+
+ ///
+ /// Removes the leading indent from a multi-line string
+ ///
+ /// String
+ ///
+ public static string StripIndent(string str)
+ {
+ int indent = _reIndent.Matches(str).Cast().Select(m => m.Value.Length).Min();
+ return new Regex(@"^[ \t]{" + indent + "}", RegexOptions.Multiline).Replace(str, "");
+ }
+
+ ///
+ /// Split a cased string into a series of "words" excluding the seperator.
+ ///
+ ///
+ ///
+ public static IEnumerable ToWords(string str)
+ {
+ foreach (Match match in _reWords.Matches(str))
+ {
+ yield return match.Value;
+ }
+ }
+
+ ///
+ /// Uppercase the first character in a string, leaving the rest of the string as is
+ ///
+ ///
+ /// a string with the first character uppercased
+ public static string ToUpperFirst(string str) => ChangeCaseFirst(str, c => c.ToUpperInvariant());
+
+ ///
+ /// Lowercase the first character in a string, leaving the rest of the string as is
+ ///
+ ///
+ /// a string with the first character lowercased
+ public static string ToLowerFirst(string str) => ChangeCaseFirst(str, c => c.ToLowerInvariant());
+
+ ///
+ /// Capitalizes a string, lowercasing the entire string and uppercasing the first character
+ ///
+ ///
+ /// a capitalized string
+ public static string Capitalize(string str) => ToUpperFirst(str.ToLowerInvariant());
+
+ ///
+ /// Converts a string to camelCase.
+ ///
+ ///
+ /// StringUtils.ToCamelCase("FOOBAR") // "foobar"
+ /// StringUtils.ToCamelCase("FOO_BAR") // "fooBar"
+ /// StringUtils.ToCamelCase("FooBar") // "fooBar"
+ /// StringUtils.ToCamelCase("foo bar") // "fooBar"
+ ///
+ ///
+ ///
+ public static string ToCamelCase(string str) =>
+ ChangeCase(str, (word, index) =>
+ (index == 0 ? word.ToLowerInvariant() : Capitalize(word)));
+
+ ///
+ /// Convert a string to CONSTANT_CASE
+ ///
+ ///
+ /// StringUtils.ToConstantCase("fOo BaR") // "FOO_BAR"
+ /// StringUtils.ToConstantCase("FooBar") // "FOO_BAR"
+ /// StringUtils.ToConstantCase("Foo Bar") // "FOO_BAR"
+ ///
+ ///
+ ///
+ public static string ToConstantCase(string str) => ChangeCase(str, "_", w => w.ToUpperInvariant());
+
+ ///
+ /// Convert a string to UPPERCASE
+ ///
+ ///
+ /// StringUtils.ToUpperCase("foobar") // "FOOBAR"
+ /// StringUtils.ToUpperCase("FOO_BAR") // "FOO BAR"
+ /// StringUtils.ToUpperCase("FooBar") // "FOO BAR"
+ /// StringUtils.ToUpperCase("Foo Bar") // "FOO BAR"
+ ///
+ ///
+ ///
+ public static string ToUpperCase(string str) => ChangeCase(str, " ", (word) => word.ToUpperInvariant());
+
+ ///
+ /// Convert a string to lowercase
+ ///
+ ///
+ /// StringUtils.ToLowerCase("FOOBAR") // "foobar"
+ /// StringUtils.ToLowerCase("FOO_BAR") // "foo bar"
+ /// StringUtils.ToLowerCase("FooBar") // "foo bar"
+ /// StringUtils.ToLowerCase("Foo Bar") // "foo bar"
+ ///
+ ///
+ ///
+ public static string ToLowerCase(string str) => ChangeCase(str, " ", word => word.ToLowerInvariant());
+
+ ///
+ /// convert a string to PascalCase
+ ///
+ ///
+ /// StringUtils.ToPascalCase("FOOBAR") // "FooBar"
+ /// StringUtils.ToPascalCase("FOO_BAR") // "FooBar"
+ /// StringUtils.ToPascalCase("fooBar") // "FooBar"
+ /// StringUtils.ToPascalCase("Foo Bar") // "FooBar"
+ ///
+ ///
+ ///
+ public static string ToPascalCase(string str) => ChangeCase(str, Capitalize);
+
+ ///
+ /// convert a string to kebab-case
+ ///
+ ///
+ /// StringUtils.ToKebabCase("FOOBAR") // "foo-bar"
+ /// StringUtils.ToKebabCase("FOO_BAR") // "foo-bar"
+ /// StringUtils.ToKebabCase("fooBar") // "foo-bar"
+ /// StringUtils.ToKebabCase("Foo Bar") // "foo-bar"
+ ///
+ ///
+ ///
+ public static string ToKebabCase(string str) => ChangeCase(str, "-", word => word.ToLowerInvariant());
+
+ ///
+ /// convert a string to snake_case
+ ///
+ ///
+ /// StringUtils.ToSnakeCase("FOOBAR") // "foo_bar"
+ /// StringUtils.ToSnakeCase("FOO_BAR") // "foo_bar"
+ /// StringUtils.ToSnakeCase("fooBar") // "foo_bar"
+ /// StringUtils.ToSnakeCase("Foo Bar") // "foo_bar"
+ ///
+ ///
+ ///
+ public static string ToSnakeCase(string str) => ChangeCase(str, "_", word => word.ToLowerInvariant());
+
+ public static string ChangeCase(string str, Func composer) => ChangeCase(str, "", composer);
+
+ public static string ChangeCase(string str, string sep, Func composer) => ChangeCase(str, sep, (w, i) => composer(w));
+
+ public static string ChangeCase(string str, Func composer) => ChangeCase(str, "", composer);
+
+ ///
+ /// Convert a string to a new case
+ ///
+ ///
+ /// Convert a string to inverse camelCase: CAMELcASE
+ ///
+ /// StringUtils.ChangeCase("my string", "", (word, index) => {
+ /// word = word.ToUpperInvariant();
+ /// if (index > 0)
+ /// word = StringUtils.toLowerFirst(word);
+ /// return word
+ /// });
+ /// // "MYsTRING"
+ ///
+ ///
+ /// an input string
+ /// a seperator string used between "words" in the string
+ /// a function that converts individual words to a new case
+ ///
+ public static string ChangeCase(string str, string sep, Func composer)
+ {
+ string result = "";
+ int index = 0;
+
+ foreach (string word in ToWords(str))
+ {
+ result += ((index == 0 ? "" : sep) + composer(word, index++));
+ }
+
+ return result;
+ }
+
+ private static string ChangeCaseFirst(string str, Func change) => change(str.Substring(0, 1)) + str.Substring(1);
+ }
+}
diff --git a/src/GraphQL.Client.Serializer.Newtonsoft/ConstantCaseEnumConverter.cs b/src/GraphQL.Client.Serializer.Newtonsoft/ConstantCaseEnumConverter.cs
index 5eb45f73..d618a490 100644
--- a/src/GraphQL.Client.Serializer.Newtonsoft/ConstantCaseEnumConverter.cs
+++ b/src/GraphQL.Client.Serializer.Newtonsoft/ConstantCaseEnumConverter.cs
@@ -1,9 +1,9 @@
using System;
using System.Linq;
using System.Reflection;
+using GraphQL.Client.Abstractions.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
-using Panic.StringUtils.Extensions;
namespace GraphQL.Client.Serializer.Newtonsoft
{
diff --git a/src/GraphQL.Client.Serializer.Newtonsoft/GraphQL.Client.Serializer.Newtonsoft.csproj b/src/GraphQL.Client.Serializer.Newtonsoft/GraphQL.Client.Serializer.Newtonsoft.csproj
index f603fc93..4bbcb784 100644
--- a/src/GraphQL.Client.Serializer.Newtonsoft/GraphQL.Client.Serializer.Newtonsoft.csproj
+++ b/src/GraphQL.Client.Serializer.Newtonsoft/GraphQL.Client.Serializer.Newtonsoft.csproj
@@ -9,7 +9,6 @@
-
diff --git a/src/GraphQL.Client.Serializer.SystemTextJson/ConstantCaseJsonNamingPolicy.cs b/src/GraphQL.Client.Serializer.SystemTextJson/ConstantCaseJsonNamingPolicy.cs
index b2ea49eb..138b0276 100644
--- a/src/GraphQL.Client.Serializer.SystemTextJson/ConstantCaseJsonNamingPolicy.cs
+++ b/src/GraphQL.Client.Serializer.SystemTextJson/ConstantCaseJsonNamingPolicy.cs
@@ -1,5 +1,5 @@
using System.Text.Json;
-using Panic.StringUtils.Extensions;
+using GraphQL.Client.Abstractions.Utilities;
namespace GraphQL.Client.Serializer.SystemTextJson
{
diff --git a/src/GraphQL.Client.Serializer.SystemTextJson/GraphQL.Client.Serializer.SystemTextJson.csproj b/src/GraphQL.Client.Serializer.SystemTextJson/GraphQL.Client.Serializer.SystemTextJson.csproj
index 93fe58af..9433b8dd 100644
--- a/src/GraphQL.Client.Serializer.SystemTextJson/GraphQL.Client.Serializer.SystemTextJson.csproj
+++ b/src/GraphQL.Client.Serializer.SystemTextJson/GraphQL.Client.Serializer.SystemTextJson.csproj
@@ -15,8 +15,4 @@
-
-
-
-