mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-23 18:01:08 +01:00
Initial frontend for gRPC UI
This commit is contained in:
302
package-lock.json
generated
302
package-lock.json
generated
@@ -28,6 +28,8 @@
|
||||
"classnames": "^2.3.2",
|
||||
"cm6-graphql": "^0.0.9",
|
||||
"codemirror": "^6.0.1",
|
||||
"codemirror-json-schema": "^0.6.1",
|
||||
"codemirror-json5": "^1.0.3",
|
||||
"focus-trap-react": "^10.1.1",
|
||||
"format-graphql": "^1.4.0",
|
||||
"framer-motion": "^9.0.4",
|
||||
@@ -469,6 +471,30 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@changesets/changelog-github": {
|
||||
"version": "0.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.4.8.tgz",
|
||||
"integrity": "sha512-jR1DHibkMAb5v/8ym77E4AMNWZKB5NPzw5a5Wtqm1JepAuIF+hrKp2u04NKM14oBZhHglkCfrla9uq8ORnK/dw==",
|
||||
"dependencies": {
|
||||
"@changesets/get-github-info": "^0.5.2",
|
||||
"@changesets/types": "^5.2.1",
|
||||
"dotenv": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@changesets/get-github-info": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.5.2.tgz",
|
||||
"integrity": "sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==",
|
||||
"dependencies": {
|
||||
"dataloader": "^1.4.0",
|
||||
"node-fetch": "^2.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@changesets/types": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@changesets/types/-/types-5.2.1.tgz",
|
||||
"integrity": "sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg=="
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.2.0.tgz",
|
||||
@@ -511,16 +537,6 @@
|
||||
"@lezer/javascript": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-javascript/node_modules/@codemirror/view": {
|
||||
"version": "6.21.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.21.4.tgz",
|
||||
"integrity": "sha512-WKVZ7nvN0lwWPfAf05WxWqTpwjC8YN3q5goj3CsSig7//DD81LULgOx3nBegqpqP0iygBqRmW8z0KSc2QTAdAg==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.1.4",
|
||||
"style-mod": "^4.1.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-json": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
|
||||
@@ -556,9 +572,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lint": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.2.1.tgz",
|
||||
"integrity": "sha512-y1muai5U/uUPAGRyHMx9mHuHLypPcHWxzlZGknp/U5Mdb5Ol8Q5ZLp67UqyTbNFJJ3unVxZ8iX3g1fMN79S1JQ==",
|
||||
"version": "6.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.4.2.tgz",
|
||||
"integrity": "sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
@@ -576,17 +592,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.0.tgz",
|
||||
"integrity": "sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA=="
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz",
|
||||
"integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A=="
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.2.1.tgz",
|
||||
"integrity": "sha512-r1svbtAj2Lp/86F3yy1TfDAOAtJRGLINLSEqByETyUaGo1EnLS+P+bbGCVHV62z46BzZYm16noDid69+4bzn0g==",
|
||||
"version": "6.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.23.1.tgz",
|
||||
"integrity": "sha512-J2Xnn5lFYT1ZN/5ewEoMBCmLlL71lZ3mBdb7cUEuHhX2ESoSrNEucpsDXpX22EuTGm9LOgC9v4Z0wx+Ez8QmGA==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"style-mod": "^4.0.0",
|
||||
"@codemirror/state": "^6.4.0",
|
||||
"style-mod": "^4.1.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
@@ -1350,6 +1366,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@sagold/json-pointer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@sagold/json-pointer/-/json-pointer-5.1.1.tgz",
|
||||
"integrity": "sha512-/iskWuyGNu09qy09HYmyLnvzpKryymH9T+vTBi2LdFp1TuKvERDADvPMv2ZkQKsrRklOzivmOz9QXof0dKqvgA=="
|
||||
},
|
||||
"node_modules/@sagold/json-query": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@sagold/json-query/-/json-query-6.1.1.tgz",
|
||||
"integrity": "sha512-5/Wu0rTnXmO5Uvtm9Of16Vx3mKjSnYA0Um9LgBtyPhIucYlppKgKC4N3g8gD0Fk00a5kizQTs4gwxKPXCpmeww==",
|
||||
"dependencies": {
|
||||
"@sagold/json-pointer": "^5.1.1",
|
||||
"ebnf": "^1.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||
@@ -2174,8 +2204,7 @@
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz",
|
||||
"integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw=="
|
||||
},
|
||||
"node_modules/@types/json5": {
|
||||
"version": "0.0.29",
|
||||
@@ -3537,6 +3566,53 @@
|
||||
"@codemirror/view": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/codemirror-json-schema": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/codemirror-json-schema/-/codemirror-json-schema-0.6.1.tgz",
|
||||
"integrity": "sha512-QG12Jy917eStZzxurpAE9QUQxF8SS/AYJ9DDteyJZcRGH8ePaBCfQ4KLCNtY6cUKjFeNBgcd5+c6FPAri6pPQg==",
|
||||
"dependencies": {
|
||||
"@changesets/changelog-github": "^0.4.8",
|
||||
"@sagold/json-pointer": "^5.1.1",
|
||||
"@types/json-schema": "^7.0.12",
|
||||
"@types/node": "^20.4.2",
|
||||
"json-schema": "^0.4.0",
|
||||
"json-schema-library": "^9.1.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@codemirror/lang-json": "^6.0.1",
|
||||
"codemirror-json5": "^1.0.3",
|
||||
"json5": "^2.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/language": "^6.8.0",
|
||||
"@codemirror/lint": "^6.4.0",
|
||||
"@codemirror/state": "^6.2.1",
|
||||
"@codemirror/view": "^6.14.1",
|
||||
"@lezer/common": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/codemirror-json-schema/node_modules/@types/node": {
|
||||
"version": "20.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.10.tgz",
|
||||
"integrity": "sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/codemirror-json5": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/codemirror-json5/-/codemirror-json5-1.0.3.tgz",
|
||||
"integrity": "sha512-HmmoYO2huQxoaoG5ARKjqQc9mz7/qmNPvMbISVfIE2Gk1+4vZQg9X3G6g49MYM5IK00Ol3aijd7OKrySuOkA7Q==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"json5": "^2.2.1",
|
||||
"lezer-json5": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
@@ -3724,6 +3800,11 @@
|
||||
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/dataloader": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz",
|
||||
"integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
@@ -3803,6 +3884,14 @@
|
||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/defer-to-connect": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||
@@ -3885,6 +3974,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/discontinuous-range": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
|
||||
"integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ=="
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||
@@ -3924,6 +4018,14 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "8.6.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
|
||||
"integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/duplexer3": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
|
||||
@@ -3936,6 +4038,14 @@
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ebnf": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ebnf/-/ebnf-1.9.1.tgz",
|
||||
"integrity": "sha512-uW2UKSsuty9ANJ3YByIQE4ANkD8nqUPO7r6Fwcc1ADKPe9FRdcPpMl3VEput4JSvKBJ4J86npIC2MLP0pYkCuw==",
|
||||
"bin": {
|
||||
"ebnf": "dist/bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "23.3.13",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-23.3.13.tgz",
|
||||
@@ -4777,6 +4887,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-copy": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz",
|
||||
"integrity": "sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA=="
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
@@ -6097,6 +6212,25 @@
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-schema": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
||||
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
|
||||
},
|
||||
"node_modules/json-schema-library": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-library/-/json-schema-library-9.1.2.tgz",
|
||||
"integrity": "sha512-uQnFb2V+VakLl6XIGGtUQzfjkP31f/dCT5lJq9NOUdypSSpjbWL/V0R2KvoNJp3hU8VErwh9DqVoZPqlC+B3IA==",
|
||||
"dependencies": {
|
||||
"@sagold/json-pointer": "^5.1.1",
|
||||
"@sagold/json-query": "^6.1.1",
|
||||
"deepmerge": "^4.3.1",
|
||||
"fast-copy": "^3.0.1",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"smtp-address-parser": "1.0.10",
|
||||
"valid-url": "^1.0.9"
|
||||
}
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
@@ -6120,7 +6254,6 @@
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
@@ -6207,6 +6340,14 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lezer-json5": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lezer-json5/-/lezer-json5-2.0.2.tgz",
|
||||
"integrity": "sha512-NRmtBlKW/f8mA7xatKq8IUOq045t8GVHI4kZXrUtYYUdiVeGiO6zKGAV7/nUAnf5q+rYTY+SWX/gvQdFXMjNxQ==",
|
||||
"dependencies": {
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
||||
@@ -6590,6 +6731,11 @@
|
||||
"ufo": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/moo": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
|
||||
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
@@ -6654,12 +6800,57 @@
|
||||
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nearley": {
|
||||
"version": "2.20.1",
|
||||
"resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
|
||||
"integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
|
||||
"dependencies": {
|
||||
"commander": "^2.19.0",
|
||||
"moo": "^0.5.0",
|
||||
"railroad-diagrams": "^1.0.0",
|
||||
"randexp": "0.4.6"
|
||||
},
|
||||
"bin": {
|
||||
"nearley-railroad": "bin/nearley-railroad.js",
|
||||
"nearley-test": "bin/nearley-test.js",
|
||||
"nearley-unparse": "bin/nearley-unparse.js",
|
||||
"nearleyc": "bin/nearleyc.js"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://nearley.js.org/#give-to-nearley"
|
||||
}
|
||||
},
|
||||
"node_modules/nearley/node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"node_modules/nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"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/node-releases": {
|
||||
"version": "2.0.13",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
|
||||
@@ -7606,6 +7797,23 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/railroad-diagrams": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
|
||||
"integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A=="
|
||||
},
|
||||
"node_modules/randexp": {
|
||||
"version": "0.4.6",
|
||||
"resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
|
||||
"integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
|
||||
"dependencies": {
|
||||
"discontinuous-range": "1.0.0",
|
||||
"ret": "~0.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
@@ -8114,6 +8322,14 @@
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ret": {
|
||||
"version": "0.1.15",
|
||||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
@@ -8523,6 +8739,17 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/smtp-address-parser": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/smtp-address-parser/-/smtp-address-parser-1.0.10.tgz",
|
||||
"integrity": "sha512-Osg9LmvGeAG/hyao4mldbflLOkkr3a+h4m1lwKCK5U8M6ZAr7tdXEz/+/vr752TSGE4MNUlUl9cIK2cB8cgzXg==",
|
||||
"dependencies": {
|
||||
"nearley": "^2.20.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
@@ -9253,6 +9480,11 @@
|
||||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
|
||||
},
|
||||
"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-easing": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz",
|
||||
@@ -9448,8 +9680,7 @@
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"devOptional": true
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/unique-string": {
|
||||
"version": "1.0.0",
|
||||
@@ -9578,6 +9809,11 @@
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/valid-url": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
|
||||
"integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA=="
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
@@ -9780,6 +10016,20 @@
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
|
||||
},
|
||||
"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-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",
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
"classnames": "^2.3.2",
|
||||
"cm6-graphql": "^0.0.9",
|
||||
"codemirror": "^6.0.1",
|
||||
"codemirror-json-schema": "^0.6.1",
|
||||
"codemirror-json5": "^1.0.3",
|
||||
"focus-trap-react": "^10.1.1",
|
||||
"format-graphql": "^1.4.0",
|
||||
"framer-motion": "^9.0.4",
|
||||
|
||||
@@ -84,7 +84,11 @@ async fn grpc_reflect(
|
||||
// app_handle: AppHandle<Wry>,
|
||||
// db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||
) -> Result<Vec<ServiceDefinition>, String> {
|
||||
let uri = Uri::from_str(endpoint).map_err(|e| e.to_string())?;
|
||||
let uri = if endpoint.starts_with("http://") || endpoint.starts_with("https://") {
|
||||
Uri::from_str(endpoint).map_err(|e| e.to_string())?
|
||||
} else {
|
||||
Uri::from_str(&format!("http://{}", endpoint)).map_err(|e| e.to_string())?
|
||||
};
|
||||
Ok(grpc::callable(&uri).await)
|
||||
}
|
||||
|
||||
@@ -97,7 +101,11 @@ async fn grpc_call_unary(
|
||||
// app_handle: AppHandle<Wry>,
|
||||
// db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||
) -> Result<String, String> {
|
||||
let uri = Uri::from_str(endpoint).map_err(|e| e.to_string())?;
|
||||
let uri = if endpoint.starts_with("http://") || endpoint.starts_with("https://") {
|
||||
Uri::from_str(endpoint).map_err(|e| e.to_string())?
|
||||
} else {
|
||||
Uri::from_str(&format!("http://{}", endpoint)).map_err(|e| e.to_string())?
|
||||
};
|
||||
Ok(grpc::call(&uri, service, method, message).await)
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,19 @@ pub struct EnvironmentVariable {
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct Folder {
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub folder_id: Option<String>,
|
||||
pub model: String,
|
||||
pub name: String,
|
||||
pub sort_priority: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct HttpRequestHeader {
|
||||
@@ -139,19 +152,6 @@ pub struct HttpRequest {
|
||||
pub headers: Json<Vec<HttpRequestHeader>>,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct Folder {
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub folder_id: Option<String>,
|
||||
pub model: String,
|
||||
pub name: String,
|
||||
pub sort_priority: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct HttpResponseHeader {
|
||||
@@ -190,6 +190,64 @@ impl HttpResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct GrpcEndpoint {
|
||||
pub id: String,
|
||||
pub model: String,
|
||||
pub workspace_id: String,
|
||||
pub request_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub endpoint: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct GrpcMessage {
|
||||
pub created_at: NaiveDateTime,
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct GrpcConnection {
|
||||
pub id: String,
|
||||
pub model: String,
|
||||
pub workspace_id: String,
|
||||
pub grpc_endpoint_id: String,
|
||||
pub request_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub messages: Json<Vec<GrpcMessage>>,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct GrpcRequest {
|
||||
pub id: String,
|
||||
pub model: String,
|
||||
pub workspace_id: String,
|
||||
pub grpc_endpoint_id: String,
|
||||
pub grpc_connection_id: String,
|
||||
pub request_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct GrpcResponse {
|
||||
pub id: String,
|
||||
pub model: String,
|
||||
pub workspace_id: String,
|
||||
pub grpc_endpoint_id: String,
|
||||
pub grpc_connection_id: String,
|
||||
pub request_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct KeyValue {
|
||||
|
||||
@@ -72,7 +72,7 @@ export function GraphQLEditor({ defaultValue, onChange, baseRequest, ...extraEdi
|
||||
const dialog = useDialog();
|
||||
|
||||
return (
|
||||
<div className="pb-2 h-full w-full grid grid-cols-1 grid-rows-[minmax(0,100%)_auto_auto_minmax(0,auto)]">
|
||||
<div className="h-full w-full grid grid-cols-1 grid-rows-[minmax(0,100%)_auto_auto_minmax(0,auto)]">
|
||||
<Editor
|
||||
contentType="application/graphql"
|
||||
defaultValue={query ?? ''}
|
||||
@@ -125,7 +125,7 @@ export function GraphQLEditor({ defaultValue, onChange, baseRequest, ...extraEdi
|
||||
{...extraEditorProps}
|
||||
/>
|
||||
<Separator variant="primary" />
|
||||
<p className="pt-1 text-gray-500 text-sm">Variables</p>
|
||||
<p className="py-1 text-gray-500 text-sm">Variables</p>
|
||||
<Editor
|
||||
format={tryFormatJson}
|
||||
contentType="application/json"
|
||||
|
||||
81
src-web/components/GrpcConnectionLayout.tsx
Normal file
81
src-web/components/GrpcConnectionLayout.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import type { Props } from 'focus-trap-react';
|
||||
import type { CSSProperties, FormEvent } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useGrpc } from '../hooks/useGrpc';
|
||||
import { useKeyValue } from '../hooks/useKeyValue';
|
||||
import { Editor } from './core/Editor';
|
||||
import { SplitLayout } from './core/SplitLayout';
|
||||
import { VStack } from './core/Stacks';
|
||||
import { GrpcEditor } from './GrpcEditor';
|
||||
import { UrlBar } from './UrlBar';
|
||||
|
||||
interface Props {
|
||||
style: CSSProperties;
|
||||
}
|
||||
|
||||
export function GrpcConnectionLayout({ style }: Props) {
|
||||
const url = useKeyValue<string>({ namespace: 'debug', key: 'grpc_url', defaultValue: '' });
|
||||
const message = useKeyValue<string>({
|
||||
namespace: 'debug',
|
||||
key: 'grpc_message',
|
||||
defaultValue: '',
|
||||
});
|
||||
const [resp, setResp] = useState<string>('');
|
||||
const grpc = useGrpc(url.value ?? null);
|
||||
const handleConnect = useCallback(
|
||||
async (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
setResp(
|
||||
await grpc.callUnary.mutateAsync({
|
||||
service: 'helloworld.Greeter',
|
||||
method: 'SayHello',
|
||||
message: message.value ?? '',
|
||||
}),
|
||||
);
|
||||
},
|
||||
[grpc.callUnary, message.value],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('REFLECT SCHEMA', grpc.schema);
|
||||
}, [grpc.schema]);
|
||||
|
||||
if (url.isLoading || url.value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SplitLayout
|
||||
style={style}
|
||||
leftSlot={() => (
|
||||
<VStack space={2}>
|
||||
<UrlBar
|
||||
id="foo"
|
||||
url={url.value ?? ''}
|
||||
method={null}
|
||||
placeholder="localhost:50051"
|
||||
onSubmit={handleConnect}
|
||||
isLoading={false}
|
||||
onUrlChange={url.set}
|
||||
forceUpdateKey={''}
|
||||
/>
|
||||
<GrpcEditor
|
||||
url={url.value ?? ''}
|
||||
defaultValue={message.value}
|
||||
onChange={message.set}
|
||||
className="bg-gray-50"
|
||||
/>
|
||||
</VStack>
|
||||
)}
|
||||
rightSlot={() => (
|
||||
<Editor
|
||||
className="bg-gray-50 border border-highlight"
|
||||
contentType="application/json"
|
||||
defaultValue={resp}
|
||||
readOnly
|
||||
forceUpdateKey={resp}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
40
src-web/components/GrpcEditor.tsx
Normal file
40
src-web/components/GrpcEditor.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import type { EditorView } from 'codemirror';
|
||||
import { updateSchema } from 'codemirror-json-schema';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useGrpc } from '../hooks/useGrpc';
|
||||
import { tryFormatJson } from '../lib/formatters';
|
||||
import type { EditorProps } from './core/Editor';
|
||||
import { Editor } from './core/Editor';
|
||||
|
||||
type Props = Pick<
|
||||
EditorProps,
|
||||
'heightMode' | 'onChange' | 'defaultValue' | 'className' | 'forceUpdateKey'
|
||||
> & {
|
||||
url: string;
|
||||
};
|
||||
|
||||
export function GrpcEditor({ url, defaultValue, ...extraEditorProps }: Props) {
|
||||
const editorViewRef = useRef<EditorView>(null);
|
||||
const { schema } = useGrpc(url);
|
||||
|
||||
useEffect(() => {
|
||||
if (editorViewRef.current == null || schema == null) return;
|
||||
const foo = schema[0].methods[0].schema;
|
||||
console.log('UPDATE SCHEMA', foo);
|
||||
updateSchema(editorViewRef.current, JSON.parse(foo));
|
||||
}, [schema]);
|
||||
|
||||
return (
|
||||
<div className="h-full w-full grid grid-cols-1 grid-rows-[minmax(0,100%)_auto_auto_minmax(0,auto)]">
|
||||
<Editor
|
||||
contentType="application/grpc"
|
||||
defaultValue={defaultValue}
|
||||
format={tryFormatJson}
|
||||
heightMode="auto"
|
||||
placeholder="..."
|
||||
ref={editorViewRef}
|
||||
{...extraEditorProps}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
21
src-web/components/HttpRequestLayout.tsx
Normal file
21
src-web/components/HttpRequestLayout.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { CSSProperties } from 'react';
|
||||
import React from 'react';
|
||||
import { SplitLayout } from './core/SplitLayout';
|
||||
import { RequestPane } from './RequestPane';
|
||||
import { ResponsePane } from './ResponsePane';
|
||||
|
||||
interface Props {
|
||||
style: CSSProperties;
|
||||
}
|
||||
|
||||
export function HttpRequestLayout({ style }: Props) {
|
||||
return (
|
||||
<SplitLayout
|
||||
style={style}
|
||||
leftSlot={({ orientation, style }) => (
|
||||
<RequestPane style={style} fullHeight={orientation === 'horizontal'} />
|
||||
)}
|
||||
rightSlot={({ style }) => <ResponsePane style={style} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
import classNames from 'classnames';
|
||||
import type { CSSProperties } from 'react';
|
||||
import type { CSSProperties, FormEvent } from 'react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
import { createGlobalState } from 'react-use';
|
||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
|
||||
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
||||
import { useSendRequest } from '../hooks/useSendRequest';
|
||||
import { useUpdateRequest } from '../hooks/useUpdateRequest';
|
||||
import { tryFormatJson } from '../lib/formatters';
|
||||
import type { HttpHeader, HttpRequest, HttpUrlParameter } from '../lib/models';
|
||||
@@ -33,7 +35,7 @@ import { UrlBar } from './UrlBar';
|
||||
import { UrlParametersEditor } from './UrlParameterEditor';
|
||||
|
||||
interface Props {
|
||||
style?: CSSProperties;
|
||||
style: CSSProperties;
|
||||
fullHeight: boolean;
|
||||
className?: string;
|
||||
}
|
||||
@@ -178,6 +180,27 @@ export const RequestPane = memo(function RequestPane({ style, fullHeight, classN
|
||||
[updateRequest],
|
||||
);
|
||||
|
||||
const sendRequest = useSendRequest(activeRequest?.id ?? null);
|
||||
const handleSend = useCallback(
|
||||
async (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
await sendRequest.mutateAsync();
|
||||
},
|
||||
[sendRequest],
|
||||
);
|
||||
|
||||
const handleMethodChange = useCallback(
|
||||
(method: string) => updateRequest.mutate({ method }),
|
||||
[updateRequest],
|
||||
);
|
||||
const handleUrlChange = useCallback(
|
||||
(url: string) => updateRequest.mutate({ url }),
|
||||
[updateRequest],
|
||||
);
|
||||
|
||||
const isLoading = useIsResponseLoading(activeRequestId ?? null);
|
||||
const { updateKey } = useRequestUpdateKey(activeRequestId ?? null);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={style}
|
||||
@@ -190,6 +213,12 @@ export const RequestPane = memo(function RequestPane({ style, fullHeight, classN
|
||||
id={activeRequest.id}
|
||||
url={activeRequest.url}
|
||||
method={activeRequest.method}
|
||||
placeholder="https://example.com"
|
||||
onSubmit={handleSend}
|
||||
onMethodChange={handleMethodChange}
|
||||
onUrlChange={handleUrlChange}
|
||||
forceUpdateKey={updateKey}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<Tabs
|
||||
value={activeTab}
|
||||
|
||||
@@ -1,43 +1,36 @@
|
||||
import type { EditorView } from 'codemirror';
|
||||
import type { FormEvent } from 'react';
|
||||
import { memo, useCallback, useRef, useState } from 'react';
|
||||
import { memo, useRef, useState } from 'react';
|
||||
import { useHotKey } from '../hooks/useHotKey';
|
||||
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
|
||||
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
||||
import { useSendRequest } from '../hooks/useSendRequest';
|
||||
import { useUpdateRequest } from '../hooks/useUpdateRequest';
|
||||
import type { HttpRequest } from '../lib/models';
|
||||
import { IconButton } from './core/IconButton';
|
||||
import { Input } from './core/Input';
|
||||
import { RequestMethodDropdown } from './RequestMethodDropdown';
|
||||
|
||||
type Props = Pick<HttpRequest, 'id' | 'url' | 'method'> & {
|
||||
type Props = Pick<HttpRequest, 'id' | 'url'> & {
|
||||
className?: string;
|
||||
method: HttpRequest['method'] | null;
|
||||
placeholder: string;
|
||||
onSubmit: (e: FormEvent) => void;
|
||||
onUrlChange: (url: string) => void;
|
||||
onMethodChange?: (method: string) => void;
|
||||
isLoading: boolean;
|
||||
forceUpdateKey: string;
|
||||
};
|
||||
|
||||
export const UrlBar = memo(function UrlBar({ id: requestId, url, method, className }: Props) {
|
||||
export const UrlBar = memo(function UrlBar({
|
||||
forceUpdateKey,
|
||||
onUrlChange,
|
||||
url,
|
||||
method,
|
||||
placeholder,
|
||||
className,
|
||||
onSubmit,
|
||||
onMethodChange,
|
||||
isLoading,
|
||||
}: Props) {
|
||||
const inputRef = useRef<EditorView>(null);
|
||||
const sendRequest = useSendRequest(requestId);
|
||||
const updateRequest = useUpdateRequest(requestId);
|
||||
const [isFocused, setIsFocused] = useState<boolean>(false);
|
||||
const handleMethodChange = useCallback(
|
||||
(method: string) => updateRequest.mutate({ method }),
|
||||
[updateRequest],
|
||||
);
|
||||
const handleUrlChange = useCallback(
|
||||
(url: string) => updateRequest.mutate({ url }),
|
||||
[updateRequest],
|
||||
);
|
||||
const loading = useIsResponseLoading(requestId);
|
||||
const { updateKey } = useRequestUpdateKey(requestId);
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
async (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
sendRequest.mutate();
|
||||
},
|
||||
[sendRequest],
|
||||
);
|
||||
|
||||
useHotKey('urlBar.focus', () => {
|
||||
const head = inputRef.current?.state.doc.length ?? 0;
|
||||
@@ -48,7 +41,7 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
||||
});
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className={className}>
|
||||
<form onSubmit={onSubmit} className={className}>
|
||||
<Input
|
||||
autocompleteVariables
|
||||
ref={inputRef}
|
||||
@@ -60,19 +53,22 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
||||
className="px-0 py-0.5"
|
||||
name="url"
|
||||
label="Enter URL"
|
||||
forceUpdateKey={updateKey}
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onBlur={() => setIsFocused(false)}
|
||||
containerClassName="shadow shadow-gray-100 dark:shadow-gray-50"
|
||||
onChange={handleUrlChange}
|
||||
onChange={onUrlChange}
|
||||
defaultValue={url}
|
||||
placeholder="https://example.com"
|
||||
placeholder={placeholder}
|
||||
leftSlot={
|
||||
<RequestMethodDropdown
|
||||
method={method}
|
||||
onChange={handleMethodChange}
|
||||
className="mx-0.5 my-0.5"
|
||||
/>
|
||||
method != null &&
|
||||
onMethodChange != null && (
|
||||
<RequestMethodDropdown
|
||||
method={method}
|
||||
onChange={onMethodChange}
|
||||
className="mx-0.5 my-0.5"
|
||||
/>
|
||||
)
|
||||
}
|
||||
rightSlot={
|
||||
<IconButton
|
||||
@@ -81,8 +77,8 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
||||
title="Send Request"
|
||||
type="submit"
|
||||
className="w-8 mr-0.5 my-0.5"
|
||||
icon={loading ? 'update' : 'sendHorizontal'}
|
||||
spin={loading}
|
||||
icon={isLoading ? 'update' : 'sendHorizontal'}
|
||||
spin={isLoading}
|
||||
hotkeyAction="request.send"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -8,14 +8,16 @@ import type {
|
||||
} from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useWindowSize } from 'react-use';
|
||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||
import { useIsFullscreen } from '../hooks/useIsFullscreen';
|
||||
import { useOsInfo } from '../hooks/useOsInfo';
|
||||
import { useSidebarHidden } from '../hooks/useSidebarHidden';
|
||||
import { useSidebarWidth } from '../hooks/useSidebarWidth';
|
||||
import { Button } from './core/Button';
|
||||
import { HStack } from './core/Stacks';
|
||||
import { GrpcConnectionLayout } from './GrpcConnectionLayout';
|
||||
import { HttpRequestLayout } from './HttpRequestLayout';
|
||||
import { Overlay } from './Overlay';
|
||||
import { RequestResponse } from './RequestResponse';
|
||||
import { ResizeHandle } from './ResizeHandle';
|
||||
import { Sidebar } from './Sidebar';
|
||||
import { SidebarActions } from './SidebarActions';
|
||||
@@ -31,6 +33,7 @@ const WINDOW_FLOATING_SIDEBAR_WIDTH = 600;
|
||||
export default function Workspace() {
|
||||
const { setWidth, width, resetWidth } = useSidebarWidth();
|
||||
const { hide, show, hidden } = useSidebarHidden();
|
||||
const activeRequest = useActiveRequest();
|
||||
|
||||
const windowSize = useWindowSize();
|
||||
const [floating, setFloating] = useState<boolean>(false);
|
||||
@@ -163,7 +166,11 @@ export default function Workspace() {
|
||||
>
|
||||
<WorkspaceHeader className="pointer-events-none" />
|
||||
</HeaderSize>
|
||||
<RequestResponse style={body} />
|
||||
{activeRequest?.name.includes('gRPC') ? (
|
||||
<GrpcConnectionLayout style={body} />
|
||||
) : (
|
||||
<HttpRequestLayout style={body} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import { json } from '@codemirror/lang-json';
|
||||
import { xml } from '@codemirror/lang-xml';
|
||||
import type { LanguageSupport } from '@codemirror/language';
|
||||
import {
|
||||
bracketMatching,
|
||||
foldGutter,
|
||||
foldKeymap,
|
||||
HighlightStyle,
|
||||
@@ -32,6 +31,7 @@ import {
|
||||
} from '@codemirror/view';
|
||||
import { tags as t } from '@lezer/highlight';
|
||||
import { graphql, graphqlLanguageSupport } from 'cm6-graphql';
|
||||
import { jsonSchema } from 'codemirror-json-schema';
|
||||
import type { Environment, Workspace } from '../../../lib/models';
|
||||
import type { EditorProps } from './index';
|
||||
import { text } from './text/extension';
|
||||
@@ -83,6 +83,7 @@ export const myHighlightStyle = HighlightStyle.define([
|
||||
// ]);
|
||||
|
||||
const syntaxExtensions: Record<string, LanguageSupport> = {
|
||||
'application/grpc': jsonSchema() as any, // TODO: Fix this
|
||||
'application/graphql': graphqlLanguageSupport(),
|
||||
'application/json': json(),
|
||||
'application/javascript': javascript(),
|
||||
@@ -119,7 +120,6 @@ export const baseExtensions = [
|
||||
history(),
|
||||
dropCursor(),
|
||||
drawSelection(),
|
||||
bracketMatching(),
|
||||
// TODO: Figure out how to debounce showing of autocomplete in a good way
|
||||
// debouncedAutocompletionDisplay({ millis: 1000 }),
|
||||
// autocompletion({ closeOnBlur: true, interactionDelay: 200, activateOnTyping: false }),
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
import useResizeObserver from '@react-hook/resize-observer';
|
||||
import classNames from 'classnames';
|
||||
import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
|
||||
import React, { memo, useCallback, useMemo, useRef, useState } from 'react';
|
||||
import type { CSSProperties, MouseEvent as ReactMouseEvent, ReactNode } from 'react';
|
||||
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { useLocalStorage } from 'react-use';
|
||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||
import { useActiveWorkspaceId } from '../hooks/useActiveWorkspaceId';
|
||||
import { clamp } from '../lib/clamp';
|
||||
import { HotKeyList } from './core/HotKeyList';
|
||||
import { RequestPane } from './RequestPane';
|
||||
import { ResizeHandle } from './ResizeHandle';
|
||||
import { ResponsePane } from './ResponsePane';
|
||||
import { useActiveRequestId } from '../../hooks/useActiveRequestId';
|
||||
import { useActiveWorkspaceId } from '../../hooks/useActiveWorkspaceId';
|
||||
import { clamp } from '../../lib/clamp';
|
||||
import { ResizeHandle } from '../ResizeHandle';
|
||||
import { HotKeyList } from './HotKeyList';
|
||||
|
||||
interface Props {
|
||||
interface SlotProps {
|
||||
orientation: 'horizontal' | 'vertical';
|
||||
style: CSSProperties;
|
||||
}
|
||||
|
||||
const rqst = { gridArea: 'rqst' };
|
||||
const resp = { gridArea: 'resp' };
|
||||
const drag = { gridArea: 'drag' };
|
||||
interface Props {
|
||||
style: CSSProperties;
|
||||
leftSlot: (props: SlotProps) => ReactNode;
|
||||
rightSlot: (props: SlotProps) => ReactNode;
|
||||
}
|
||||
|
||||
const areaL = { gridArea: 'left' };
|
||||
const areaR = { gridArea: 'right' };
|
||||
const areaD = { gridArea: 'drag' };
|
||||
|
||||
const DEFAULT = 0.5;
|
||||
const MIN_WIDTH_PX = 10;
|
||||
const MIN_HEIGHT_PX = 30;
|
||||
const STACK_VERTICAL_WIDTH = 700;
|
||||
|
||||
export const RequestResponse = memo(function RequestResponse({ style }: Props) {
|
||||
export function SplitLayout({ style, leftSlot, rightSlot }: Props) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const activeRequest = useActiveRequest();
|
||||
const [vertical, setVertical] = useState<boolean>(false);
|
||||
const [widthRaw, setWidth] = useLocalStorage<number>(`body_width::${useActiveWorkspaceId()}`);
|
||||
const [heightRaw, setHeight] = useLocalStorage<number>(`body_height::${useActiveWorkspaceId()}`);
|
||||
@@ -46,13 +50,13 @@ export const RequestResponse = memo(function RequestResponse({ style }: Props) {
|
||||
...style,
|
||||
gridTemplate: vertical
|
||||
? `
|
||||
' ${rqst.gridArea}' minmax(0,${1 - height}fr)
|
||||
' ${drag.gridArea}' 0
|
||||
' ${resp.gridArea}' minmax(0,${height}fr)
|
||||
' ${areaL.gridArea}' minmax(0,${1 - height}fr)
|
||||
' ${areaD.gridArea}' 0
|
||||
' ${areaR.gridArea}' minmax(0,${height}fr)
|
||||
/ 1fr
|
||||
`
|
||||
: `
|
||||
' ${rqst.gridArea} ${drag.gridArea} ${resp.gridArea}' minmax(0,1fr)
|
||||
' ${areaL.gridArea} ${areaD.gridArea} ${areaR.gridArea}' minmax(0,1fr)
|
||||
/ ${1 - width}fr 0 ${width}fr
|
||||
`,
|
||||
}),
|
||||
@@ -117,15 +121,16 @@ export const RequestResponse = memo(function RequestResponse({ style }: Props) {
|
||||
[width, height, vertical, setHeight, setWidth],
|
||||
);
|
||||
|
||||
if (activeRequest === null) {
|
||||
const activeRequestId = useActiveRequestId();
|
||||
if (activeRequestId === null) {
|
||||
return <HotKeyList hotkeys={['request.create', 'sidebar.toggle']} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="grid gap-1.5 w-full h-full p-3" style={styles}>
|
||||
<RequestPane style={rqst} fullHeight={!vertical} />
|
||||
{leftSlot({ style: areaL, orientation: vertical ? 'vertical' : 'horizontal' })}
|
||||
<ResizeHandle
|
||||
style={drag}
|
||||
style={areaD}
|
||||
isResizing={isResizing}
|
||||
className={classNames(vertical ? 'translate-y-0.5' : 'translate-x-0.5')}
|
||||
onResizeStart={handleResizeStart}
|
||||
@@ -133,7 +138,7 @@ export const RequestResponse = memo(function RequestResponse({ style }: Props) {
|
||||
side={vertical ? 'top' : 'left'}
|
||||
justify="center"
|
||||
/>
|
||||
<ResponsePane style={resp} />
|
||||
{rightSlot({ style: areaR, orientation: vertical ? 'vertical' : 'horizontal' })}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { trackEvent } from '../lib/analytics';
|
||||
import type { HttpRequest } from '../lib/models';
|
||||
import type { CookieJar } from '../lib/models';
|
||||
import { useActiveWorkspaceId } from './useActiveWorkspaceId';
|
||||
import { cookieJarsQueryKey } from './useCookieJars';
|
||||
import { usePrompt } from './usePrompt';
|
||||
import { requestsQueryKey } from './useRequests';
|
||||
|
||||
export function useCreateCookieJar() {
|
||||
const workspaceId = useActiveWorkspaceId();
|
||||
const queryClient = useQueryClient();
|
||||
const prompt = usePrompt();
|
||||
|
||||
return useMutation<HttpRequest>({
|
||||
return useMutation<CookieJar>({
|
||||
mutationFn: async () => {
|
||||
if (workspaceId === null) {
|
||||
throw new Error("Cannot create cookie jar when there's no active workspace");
|
||||
@@ -26,10 +26,10 @@ export function useCreateCookieJar() {
|
||||
return invoke('create_cookie_jar', { workspaceId, name });
|
||||
},
|
||||
onSettled: () => trackEvent('CookieJar', 'Create'),
|
||||
onSuccess: async (request) => {
|
||||
queryClient.setQueryData<HttpRequest[]>(
|
||||
requestsQueryKey({ workspaceId: request.workspaceId }),
|
||||
(requests) => [...(requests ?? []), request],
|
||||
onSuccess: async (cookieJar) => {
|
||||
queryClient.setQueryData<CookieJar[]>(
|
||||
cookieJarsQueryKey({ workspaceId: cookieJar.workspaceId }),
|
||||
(items) => [...(items ?? []), cookieJar],
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
35
src-web/hooks/useGrpc.ts
Normal file
35
src-web/hooks/useGrpc.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
|
||||
export function useGrpc(url: string | null) {
|
||||
const callUnary = useMutation<
|
||||
string,
|
||||
unknown,
|
||||
{ service: string; method: string; message: string }
|
||||
>({
|
||||
mutationKey: ['grpc_call_reflect', url],
|
||||
mutationFn: async ({ service, method, message }) => {
|
||||
if (url === null) throw new Error('No URL provided');
|
||||
return (await invoke('grpc_call_unary', {
|
||||
endpoint: url,
|
||||
service,
|
||||
method,
|
||||
message,
|
||||
})) as string;
|
||||
},
|
||||
});
|
||||
|
||||
const reflect = useQuery<string | null>({
|
||||
queryKey: ['grpc_reflect', url ?? ''],
|
||||
queryFn: async () => {
|
||||
if (url === null) return null;
|
||||
console.log('GETTING SCHEMA', url);
|
||||
return (await invoke('grpc_reflect', { endpoint: url })) as string;
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
callUnary,
|
||||
schema: reflect.data,
|
||||
};
|
||||
}
|
||||
@@ -11,20 +11,6 @@ import { setAppearanceOnDocument } from './lib/theme/window';
|
||||
import { appWindow } from '@tauri-apps/api/window';
|
||||
import { type } from '@tauri-apps/api/os';
|
||||
|
||||
try {
|
||||
const services: any = await invoke('grpc_reflect', { endpoint: 'http://localhost:50051' });
|
||||
console.log('SERVICES', services);
|
||||
const response = await invoke('grpc_call_unary', {
|
||||
endpoint: 'http://localhost:50051',
|
||||
service: services[0].name,
|
||||
method: services[0].methods[0].name,
|
||||
message: '{"name": "Greg"}',
|
||||
});
|
||||
console.log('RESPONSE', response);
|
||||
} catch (err) {
|
||||
console.log('ERROR', err);
|
||||
}
|
||||
|
||||
// Hide decorations here because it doesn't work in Rust for some reason (bug?)
|
||||
const osType = await type();
|
||||
if (osType !== 'Darwin') {
|
||||
|
||||
Reference in New Issue
Block a user