diff --git a/.github/workflows/landing.yml b/.github/workflows/landing.yml index 23ecf776..002684b7 100644 --- a/.github/workflows/landing.yml +++ b/.github/workflows/landing.yml @@ -18,3 +18,4 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./doc/out + cname: zeus.graphqleditor.com diff --git a/.github/workflows/beta.yml b/.github/workflows/tree.yml similarity index 85% rename from .github/workflows/beta.yml rename to .github/workflows/tree.yml index 15485205..790152c1 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/tree.yml @@ -1,7 +1,7 @@ on: push: branches: - - v3.0.0 + - tree-011 jobs: build: runs-on: ubuntu-latest @@ -14,6 +14,6 @@ jobs: registry-url: 'https://registry.npmjs.org' - run: npm install - run: npm run build - - run: npm publish --access public --tag beta + - run: npm publish --access public --tag tree env: NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} diff --git a/README.md b/README.md index ad421dd2..69f2966b 100644 --- a/README.md +++ b/README.md @@ -35,17 +35,17 @@ Example using a generated `chain` client. Queries, mutations and subscriptions a ![](images/example.png) -## Support And Community +## Join the Zeus Community and Spread the Word -[Join our GraphQL Editor Channel on Slack!](https://join.slack.com/t/graphqleditor/shared_invite/enQtNDkwOTgyOTM5OTc1LWI4YjU3N2U5NGVkNzQ2NzY5MGUxMTJiNjFlZDM1Zjc2OWRmNTI0NDM3OWUxYTk4Yjk3MzZlY2QwOWUzZmM2NDI) +⚡️ [Join the Discussion forum on GitHub](https://github.com/graphql-editor/graphql-zeus/discussions) 📣 -Leave a GitHub star ⭐️ 😊 +⚡️ Leave a GitHub star ⭐️ 👆 -Spread the word! +⚡️ Spread the word on your socials and with your networks! 🗣 ## Contribute -For a complete guide to contributing to GraphQL Editor, see the [Contribution Guide](CONTRIBUTING.md). +For a complete guide to contributing to GraphQL Zeus, see the [Contribution Guide](CONTRIBUTING.md). 1. Fork this repo 2. Create your feature branch: git checkout -b feature-name @@ -55,4 +55,4 @@ For a complete guide to contributing to GraphQL Editor, see the [Contribution Gu ## License -MIT 🕊 +[MIT](https://opensource.org/licenses/MIT) 🕊 diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 00000000..c585e193 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +out \ No newline at end of file diff --git a/doc/.purplehaze/Layout/index.js b/doc/.purplehaze/Layout/index.js index b3c64815..ac254235 100644 --- a/doc/.purplehaze/Layout/index.js +++ b/doc/.purplehaze/Layout/index.js @@ -26,7 +26,7 @@ var Layout = ({children, routes, activeRoute, prefix = ""}) => { className: "text-gray-400 block ml-2 text-md mt-1" }, "Autocomplete client for GraphQL"), /* @__PURE__ */ React.createElement("span", { className: "ml-auto mr-2 text-gray-500" - }, "4.0.4"), /* @__PURE__ */ React.createElement("a", { + }, "5.1.x"), /* @__PURE__ */ React.createElement("a", { href: "https://github.com/graphql-editor/graphql-zeus", className: "text-purple-500", title: "Github repository" @@ -42,7 +42,7 @@ var Layout = ({children, routes, activeRoute, prefix = ""}) => { }), /* @__PURE__ */ React.createElement("div", { className: "h-2 w-10 bg-purple-500 mb-2 rounded" })), mobileMenuOpen && /* @__PURE__ */ React.createElement("div", { - className: "py-10 px-20 bg-gray-100 h-full w-80 sm:hidden block absolute top-0 left-0" + className: "py-10 px-10 sm:px-20 bg-gray-100 h-full w-80 sm:hidden block absolute top-0 left-0 overflow-y-auto" }, /* @__PURE__ */ React.createElement("a", { className: "block py-4 text-lg text-purple-900 font-black", href: `${prefix}/` @@ -65,7 +65,7 @@ var Layout = ({children, routes, activeRoute, prefix = ""}) => { href: `${prefix}/page/${r.link}.html` }, r.title)))); })), /* @__PURE__ */ React.createElement("div", { - className: "container mx-auto px-20 py-6 pb-20 h-full overflow-auto" + className: "container mx-auto px-6 sm:px-20 py-6 pb-20 h-full overflow-auto" }, children))); }; export { diff --git a/doc/.purplehaze/ssg/markdown.js b/doc/.purplehaze/ssg/markdown.js index c6da306c..fb0e005a 100644 --- a/doc/.purplehaze/ssg/markdown.js +++ b/doc/.purplehaze/ssg/markdown.js @@ -1,15 +1,5 @@ // src/ssg/markdown.ts var htmlContent = { - "markdown/plugins/stucco.md": { - "content": "\n## Usage with Stucco Subscriptions\n\nZeus can generate types for the Stucco Subscription library by adding the --stuccoSubscriptions flag to the CLI. All types in `data` are then inherited from the Zeus Query\n\n```sh\n$ zeus schema.graphql ./ --stuccoSubscriptions\n```\n\n```typescript\nstuccoSubscriptions(\n (apiFetchResult) => [apiFetchResult.url],\n 'https://my.backend/graphql',\n)({ drawCard: { Attack: true } }).on((args) => args.drawCard.Attack);\n```\n", - "data": { - "link": "plugins/stucco", - "title": "Stucco", - "order": 3, - "category": "Plugins" - }, - "excerpt": "" - }, "markdown/plugins/apollo.md": { "content": "\n## Usage with Apollo GraphQL\n\nZeus can generate type-safe versions of Apollo Client's `useQuery`, `useMutation`, `useSubscription` and `useLazyQuery` React hooks as `useTypedQuery`, `useTypedMutation` etc... by adding the `--apollo` flag to the CLI. All types in the `data` response are then inherited from the Zeus query. \u{1F680}\n\n### Generate Type-Safe Zeus Schema And Apollo Client Type-Safe Hooks\n\n```sh\n$ zeus schema.graphql ./ --apollo\n# apollo.ts file with typed hooks is now in the output destination\n```\n\n### Apollo Client `useTypedQuery` Hook Example\n\n```tsx\nimport { useTypedQuery } from './zeus/apollo';\n\nconst Main = () => {\n const { data } = useTypedQuery({\n // Get autocomplete here:\n drawCard: {\n name: true,\n },\n });\n // data response is now typed\n return
Strongly Typed GraphQL from the team at GraphQL Editor
-GraphQL Zeus is the absolute best way to interact with your GraphQL endpoints in a type-safe way. Zeus uses your schema to generate Typescript types and strongly typed clients to unlock the power, efficiency, productivity and safety of Typescript on your GraphQL requests.
-⚡️ Types mapped from your schema
-⚡️ Works with Apollo Client, React Query, Stucco Subscriptions (*more coming soon...)
-⚡️ Works with Subscriptions
-⚡️ Infer complex response types
-⚡️ Create reusable selection sets (like fragments) for use across multiple queries
-⚡️ Supports GraphQL Unions, Interfaces, Aliases and Variables
-⚡️ Handles massive schemas
-⚡️ Supports Browsers, Node.js and React Native in Javascript and Typescript
-⚡️ Schema downloader
-⚡️ JSON schema generation
Simply run Zeus in your terminal to output your types file based on your graphql schema
- -Example using a generated chain
client. Queries, mutations and subscriptions are now type-safe in arguments, field selections and response types.
Join our GraphQL Editor Channel on Slack!
-Leave a GitHub star ⭐️ 😊
-Spread the word!
-For a complete guide to contributing to GraphQL Editor, see the Contribution Guide.
-MIT 🕊
-With Zeus Thunder
you have total control of fetch function but will not lose the result type. ⚡️
import { Thunder } from './zeus';
-
-// Create thunder fetch client with endpoint, options and response handlers
-const thunder = Thunder(async (query) => {
- const response = await fetch('https://faker.graphqleditor.com/a-team/olympus/graphql', {
- body: JSON.stringify({ query }),
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- });
-
- if (!response.ok) {
- return new Promise((resolve, reject) => {
- response
- .text()
- .then((text) => {
- try {
- reject(JSON.parse(text));
- } catch (err) {
- reject(text);
- }
- })
- .catch(reject);
- });
- }
-
- const json = await response.json();
-
- return json.data;
-});
-
-// Call thunder client with type-safe arguments, fields and get type-safe result type
-const listCardsAndDraw = await thunder('query')({
- cardById: [
- {
- cardId: 'sdsd',
- },
- {
- description: true,
- },
- ],
- listCards: {
- name: true,
- skills: true,
- attack: [
- { cardID: ['s', 'sd'] },
- {
- name: true,
- },
- ],
- },
- drawCard: {
- name: true,
- skills: true,
- Attack: true,
- },
-});
-
-Due to validity of .js
imports in TS for esmodules you can use flag es
to generate .js
imports
$ zeus schema.graphql ./ --es
-
-To run the included examples navigate to: ./examples
and install packages with:
$ npm i
-# OR
-# yarn
-
-then run the examples with
-$ npm run start
-# OR
-# yarn start
-
-Use the Zeus CLI to generate types and GraphQL clients based on your schema which you can then import into your projects to autocomplete, query and use GraphQL responses in a type-safe way.
-$ npm i -g graphql-zeus
-# OR
-# yarn global add graphql-zeus
-
-You can also install locally to a project and then use as a npm or yarn script command or with npx
or yarn
directly eg:
$ npx zeus schema.graphql ./
-# OR
-# yarn zeus schema.graphql ./
-
-Zeus is Typescript native, you can refer to imported types directly from the generated output of the CLI
-$ zeus schema.graphql ./
-
-All demo code here is using the demo GraphQL endpoint of Olympus Cards built with GraphQL Editor. Feel free to check out the GraphiQL interface too.
-You can now use the Zeus Chain
client from the generated output to make type-safe queries and mutations to your endpoint and receive type-safe responses.
import { Chain } from './zeus';
-
-// Create a Chain client instance with the endpoint
-const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');
-
-// Query the endpoint with Typescript autocomplete for arguments and response fields
-const listCardsAndDraw = await chain('query')({
- cardById: [
- {
- cardId: 'da21ce0a-40a0-43ba-85c2-6eec2bf1ae21',
- },
- {
- name: true,
- description: true,
- },
- ],
- listCards: {
- name: true,
- skills: true,
- attack: [
- { cardID: ['66c1af53-7d5e-4d89-94b5-1ebf593508f6', 'fc0e5757-4d8a-4f6a-a23b-356ce167f873'] },
- {
- name: true,
- },
- ],
- },
- drawCard: {
- name: true,
- skills: true,
- Attack: true,
- },
-});
-// listCardsAndDraw is now typed as the response of the query.
-
-When querying a GraphQL field which takes an argument such as cardById
above, then the fields are defined in terms of a tuple eg: cardById: [ {...arguments} , {...response_selection_set} ]
the equivalent in gql syntax would be:
cardById (cardId: "da21ce0a-40a0-43ba-85c2-6eec2bf1ae21") {
- name
- description
-}
-
-For fields which have no argument they receive only the response selection set object values.
-Note: Chain
will also accept a second argument of fetch-like options to configure the client with properties such as credentials
, mode
, headers
etc...
Note: There is also an exported Zeus Gql
convenience function is a Chain client pre-configured with the endpoint specified in the CLI.
Use the Zeus Subscription
client creator in your generated output to create WebSocket connections to your GraphQL socket.
import { Subscription } from './zeus';
-
-// Create a Subscription client instance with the endpoint
-const sub = Subscription('https://faker.graphqleditor.com/a-team/olympus/graphql');
-
-// Call the client instance and listen for responses
-sub('subscription')({
- deck: {
- id: true,
- },
-}).on((response) => {
- console.log(response.deck);
-});
-
-Generates clients for use with Node.js
-$ zeus schema.graphql ./ --node
-
-As normal
-$ zeus schema.graphql ./
-
-Specify the output folder with second argument
-$ zeus schema.graphql ./generated
-
-Output Typescript Only with --typescript
flag
$ zeus schema.graphql ./ --typescript
-
-Load your schema from an URL with an URL in the first argument
-$ zeus https://faker.graphqleditor.com/a-team/olympus/graphql ./
-
-Download and save GraphQL schema to a local path with --graphql=savePath
flag
$ zeus https://faker.graphqleditor.com/a-team/olympus/graphql ./ --graphql=generated
-
-Generate and save a JSON schema to a local path with --jsonSchema=savePath
flag
$ zeus https://faker.graphqleditor.com/a-team/olympus/graphql ./ --graphql=generated
-
-Add a header value with --header=value
flag
$ zeus https://faker.graphqleditor.com/a-team/olympus/graphql ./ --header=Authorization:myNiceAuthHeader
-
-Get help with Zeus CLI with:
-$ zeus help
-
-Add a script entry in your package.json
file for quickly calling Zeus generation:
"scripts": {
-//...
-"generate": "zeus https://faker.graphqleditor.com/a-team/olympus/graphql zeusGenerated --typescript --header='My-Auth-Secret:JsercjjJY5MmghtHww6UF' --apollo"
-},
-
-Zeus supports declaring aliases 🥸
-const aliasedQueryExecute = await chain('query')({
- listCards: {
- __alias: {
- atak: {
- attack: [
- { cardID: ['1'] },
- {
- name: true,
- description: true,
- },
- ],
- },
- },
- },
-});
-
-Response:
-{
- "listCards": [
- {
- "atak": {
- "attack": [
- {
- "name": "Zelma",
- "description": "Central"
- }
- ]
- }
- }
- ]
-}
-
-Now you can access properties type-safe like this
-aliasedQueryExecute.listCards.map((c) => c.atak.attack);
-
-Use the Zeus
function to generate a gql string
import { Zeus } from './zeus';
-
-const stringGql = Zeus('query', {
- listCards: {
- name: true,
- skills: true,
- Attack: true,
- },
-});
-
-// stringGql value:
-// query{listCards{name skills Attack}}
-
-You can use Zeus with GraphQL Unions:
-const { drawChangeCard } = await chain('query')({
- drawChangeCard: {
- __typename: true,
- '...on EffectCard': {
- effectSize: true,
- name: true,
- },
- '...on SpecialCard': {
- effect: true,
- name: true,
- },
- },
-});
-
-Response:
-{
- "effectSize": 195.99532210956377,
- "name": "Destinee",
- "__typename": "EffectCard"
-}
-
-Zeus works with GraphQL Interfaces
-const { nameables } = await Gql('query')({
- nameables: {
- __typename: true,
- name: true,
- '...on CardStack': {
- cards: {
- Defense: true,
- },
- },
- '...on Card': {
- Attack: true,
- },
- },
-});
-
-Response:
-{
- "nameables": [
- {
- "__typename": "EffectCard",
- "name": "Hector"
- },
- {
- "__typename": "CardStack",
- "name": "Scotty",
- "cards": [
- {
- "Defense": 1950
- },
- {
- "Defense": 76566
- }
- ]
- },
- {
- "__typename": "SpecialCard",
- "name": "Itzel"
- }
- ]
-}
-
-It's simple to perform queries with variables by importing and using the $
function from the Zeus output and calling it with the variable name in backticks.
import { Gql, $ } from './zeus';
-
-const addCardResult = await Gql('mutation')(
- {
- addCard: [
- {
- card: $`card`,
- },
- {
- id: true,
- description: true,
- name: true,
- Attack: true,
- skills: true,
- Children: true,
- Defense: true,
- cardImage: {
- bucket: true,
- region: true,
- key: true,
- },
- },
- ],
- },
- {
- variables: {
- card: {
- Attack: 2,
- Defense: 3,
- description: 'Lord of the mountains',
- name: 'Golrog',
- },
- },
- },
-);
-
-Note: The mutation function created by the Zeus versions of React Hooks like the Apollo Client version of useTypedMutation
can be supplied with variable values at invocation eg:
const [addCard, { data, loading, error }] = useTypedMutation({ ...myMutation });
-
-await addCard({
- variables: {
- card: {
- Attack: 2,
- Defense: 3,
- description: 'Lord of the mountains',
- name: 'Golrog',
- },
- },
-});
-
-To use with Javascript as an autocomplete tool you need to install Typescript, run the Zeus CLI, and then transform the result to JS using tsc
$ npm i -D typescript
-# OR
-# yarn add -D typescript
-
-Generate Zeus:
-$ zeus schema.graphql ./
-
-And transform it using Typescript:
-$ npx tsc ./zeus/*.ts --declaration --target es5 --skipLibCheck
-# OR
-# yarn tsc ./zeus/*.ts --declaration --target es5 --skipLibCheck
-
-This will generate an out.d.ts
file so that you can have autocompletion.
This will be rarely used, but here you are! Generate Typescript and Javascript from GraphQL definitions
-import { TreeToTS } from 'graphql-zeus';
-import { Parser } from 'graphql-js-tree';
-
-const schemaFileContents = `
-type Query{
- hello: String!
-}
-schema{
- query: Query
-}
-`;
-
-const typeScriptDefinition = TreeToTS.resolveTree(Parser.parse(schemaFileContents));
-
-const jsDefinition = TreeToTS.javascript(Parser.parse(schemaFileContents));
-
-This is useful when you need your schema fetched from your GraphQL endpoint in-code
-import { Utils } from 'graphql-zeus';
-
-Utils.getFromUrl('https://faker.graphqleditor.com/a-team/olympus/graphql').then((schemaContent) => {
- // Use schema content here
-});
-
-Zeus can generate type-safe versions of Apollo Client's useQuery
, useMutation
, useSubscription
and useLazyQuery
React hooks as useTypedQuery
, useTypedMutation
etc... by adding the --apollo
flag to the CLI. All types in the data
response are then inherited from the Zeus query. 🚀
$ zeus schema.graphql ./ --apollo
-# apollo.ts file with typed hooks is now in the output destination
-
-useTypedQuery
Hook Exampleimport { useTypedQuery } from './zeus/apollo';
-
-const Main = () => {
- const { data } = useTypedQuery({
- // Get autocomplete here:
- drawCard: {
- name: true,
- },
- });
- // data response is now typed
- return <div>{data.drawCard.name}</div>;
-};
-
-If you would like to infer the response type of your query for Apollo Client you can use the Zeus Selector
function and InputType
utility from the Zeus generated library
import { Selector, InputType, GraphQLTypes } from './zeus';
-
-export const drawCardQuery = Selector('Card')({
- drawCard: {
- id: true,
- name: true,
- Attack: true,
- Children: true,
- },
-});
-
-type DrawCardResponseType = InputType<GraphQLTypes['Card'], typeof drawCardQuery>;
-// DrawCardResponseType is now the response type from the query
-
-Now drawCardQuery
can be reused directly in the typed Apollo Client useTypedQuery
later
import { useTypedQuery } from './zeus/apollo';
-import { drawCardQuery } from './';
-
-const Main = () => {
- const { data } = useTypedQuery(drawCardQuery);
- // data is of type DrawCardResponseType as per the above example
- return <div>{data.drawCard.name}</div>;
-};
-
-Zeus can generate type-safe versions of React Query's useQuery
, useMutation
etc.. React hooks as useTypedQuery
, useTypedMutation
etc... by adding the --reactQuery
flag to the CLI. All types data
response are then inherited from the Zeus query. 🚀
$ zeus schema.graphql ./ --reactQuery
-
-import { useTypedQuery } from './zeus/reactQuery';
-
-const Main = () => {
- const { data } = useTypedQuery({
- // Get autocomplete here:
- drawCard: {
- name: true,
- },
- });
- // data response is now typed
- return <div>{data.drawCard.name}</div>;
-};
-
-Zeus can generate types for the Stucco Subscription library by adding the --stuccoSubscriptions flag to the CLI. All types in data
are then inherited from the Zeus Query
$ zeus schema.graphql ./ --stuccoSubscriptions
-
-stuccoSubscriptions(
- (apiFetchResult) => [apiFetchResult.url],
- 'https://my.backend/graphql',
-)({ drawCard: { Attack: true } }).on((args) => args.drawCard.Attack);
-
-In TypeScript Zeus can help make type-safe Zeus selection sets to reuse across queries.
-import { Selector, Chain } from './zeus';
-
-const chain = Chain('https://faker.graphqleditor.com/a-team/olympus/graphql');
-
-const cardSelector = Selector('Card')({
- name: true,
- description: true,
- Attack: true,
- skills: true,
- Defense: true,
- cardImage: {
- key: true,
- bucket: true,
- },
-});
-
-const queryWithSelectionSet = await chain('query')({
- drawCard: cardSelector,
-});
-
-Sometimes you would like to infer the response type. The it is best to use selectors
-import { Selector, InputType, GraphQLTypes } from './zeus';
-
-export const drawCardQuery = Selector("Query"){
- drawCard: {
- Attack: true,
- Children: true,
- id: true,
- },
-});
-
-type InferredResponseType = InputType<GraphQLTypes['Query'], typeof drawCardQuery>;
-
-Promise of type query data object is returned.
-PROMISE_RETURNING_OBJECT = Chain.[OPERATION_NAME]({
- ...FUNCTION_FIELD_PARAMS
-})(
- ...QUERY_OBJECT
-).then ( RESPONSE_OBJECT => RESPONSE_OBJECT[OPERATION_FIELD] )
-
-Simple function params object
-FUNCTION_FIELD_PARAMS = {
- KEY: VALUE
-}
-
-Query object
-QUERY_OBJECT = {
- ...RETURN_PARAMS
-}
-
-Return params is an object containing RETURN_KEY - true if it is a scalar
, RETURN_PARAMS if type
otherwise it is a function where you pass field params and type return params.
RETURN_PARAMS = {
- RETURN_KEY: true,
- RETURN_KEY: {
- ...RETURN_PARAMS
- },
- RETURN_FUNCTION_KEY:[
- {
- ...FUNCTION_FIELD_PARAMS
- },
- {
- ...RETURN_PARAMS
- }
- ]
-}
-
-RETURN_PARAMS = {
- __alias: RETURN_PARAMS
-}
-
-Access aliased operation type-safe
-PROMISE_RETURNING_OBJECT[ALIAS_STRING][OPERATION_NAME]
-
-