{"_id":"@delt4nin3/generate-graphql-query","name":"@delt4nin3/generate-graphql-query","dist-tags":{"latest":"1.1.1"},"versions":{"1.1.1":{"name":"@delt4nin3/generate-graphql-query","description":"Generate GraphQL query from JavaScript object.","version":"1.1.1","main":"lib/index.js","types":"es/index.d.ts","module":"es/index.js","scripts":{"build":"npm run build:es && npm run build:lib && npm run build:browser","build:es":"tsc --outDir es --module esnext --target es2020","build:lib":"tsc --outDir lib","build:browser":"node ./scripts/build-browser.cjs","coverage:badges":"coverage-badges","dev":"tsc && node ./lib/example/index.js","format":"prettier --write .","lint":"eslint --ext .js,.ts,.tsx ./src","lint:fix":"eslint --fix --ext .js,.ts,.tsx ./src","minify:lib":"uglifyjs -o ./lib/index.js -c -m -- ./lib/index.js","minify:browser":"uglifyjs -o ./browser/index.js -c -m -- ./browser/index.js","minify":"npm run minify:lib && npm run minify:browser","test":"jest --coverage"},"devDependencies":{"@eslint/create-config":"^0.4.6","@types/jest":"^29.5.5","@typescript-eslint/eslint-plugin":"^5.62.0","@typescript-eslint/parser":"^5.62.0","coverage-badges-cli":"^1.1.1","eslint":"^8.49.0","eslint-config-prettier":"^8.10.0","jest":"^29.7.0","prettier":"2.8.8","ts-jest":"^29.1.1","typescript":"5.1.6","uglify-js":"^3.17.4"},"repository":{"type":"git","url":"git+https://github.com/john-yuan/graphql-toolkit.git","directory":"packages/generate-graphql-query"},"keywords":["generate","graphql","query","gql","generator","codegen","builder","stringify"],"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"license":"MIT","packageManager":"pnpm@9.8.0+sha512.8e4c3550fb500e808dbc30bb0ce4dd1eb614e30b1c55245f211591ec2cdf9c611cabd34e1364b42f564bd54b3945ed0f49d61d1bbf2ec9bd74b866fcdc723276","_id":"@delt4nin3/generate-graphql-query@1.1.1","gitHead":"6c6ab7dbb3a1eae1706ce3d2c179098ba5dd3087","bugs":{"url":"https://github.com/john-yuan/graphql-toolkit/issues"},"homepage":"https://github.com/john-yuan/graphql-toolkit#readme","_nodeVersion":"20.16.0","_npmVersion":"10.8.1","dist":{"integrity":"sha512-D28GZsOjUq9MKW69VvrAT3tjH7oR0Zkd5ezkMee5AZcAfH4SafWhCMp98JzlDpAMGlA9yw8nz6llTFXgAGuirA==","shasum":"0c59073187611dfc78612c90607647e4d24bda88","tarball":"https://registry.npmjs.org/@delt4nin3/generate-graphql-query/-/generate-graphql-query-1.1.1.tgz","fileCount":64,"unpackedSize":110098,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAtQdKHC6vCMoC0j84o8bVs6A4DwPq5i+Xv6SZJGPi+rAiAURGfZzfw+93/v64VQ9PCifMP/nYTt6MfJ1oE4fEv5Og=="}]},"_npmUser":{"name":"delt4nin3","email":"alexander.anding@gmail.com"},"directories":{},"maintainers":[{"name":"delt4nin3","email":"alexander.anding@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/generate-graphql-query_1.1.1_1724414878449_0.7433692169317443"},"_hasShrinkwrap":false}},"time":{"created":"2024-08-23T12:07:58.354Z","1.1.1":"2024-08-23T12:07:58.582Z","modified":"2024-08-23T12:07:58.851Z"},"maintainers":[{"name":"delt4nin3","email":"alexander.anding@gmail.com"}],"description":"Generate GraphQL query from JavaScript object.","homepage":"https://github.com/john-yuan/graphql-toolkit#readme","keywords":["generate","graphql","query","gql","generator","codegen","builder","stringify"],"repository":{"type":"git","url":"git+https://github.com/john-yuan/graphql-toolkit.git","directory":"packages/generate-graphql-query"},"bugs":{"url":"https://github.com/john-yuan/graphql-toolkit/issues"},"license":"MIT","readme":"# README\n\n[![npm version](https://img.shields.io/npm/v/generate-graphql-query.svg)](https://www.npmjs.com/package/generate-graphql-query)\n[![coverage](https://cdn.jsdelivr.net/gh/john-yuan/graphql-toolkit@main/packages/generate-graphql-query/coverage/badges.svg)](./coverage/coverage.txt)\n\n<!-- [![npm downloads](https://img.shields.io/npm/dm/generate-graphql-query.svg)](http://npm-stat.com/charts.html?package=generate-graphql-query) -->\n\n```bash\nnpm i generate-graphql-query\n```\n\nGenerate GraphQL query from JavaScript object.\n\nExample:\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    countries: {\n      code: true,\n      name: true,\n      continent: {\n        name: true\n      }\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nOutput:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  countries {\n    code\n    name\n    continent {\n      name\n    }\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\nThis module supports queries, mutations, aliases, arguments, directives, enumerations, fragments and variables.\n\n> You can use the [`generate-graphql-client`](https://www.npmjs.com/package/generate-graphql-client) module to generate TypeScript code from your GraphQL introspection and use this module to generate the GraphQL query that to be sent to the server.\n\nTo get started with GraphQL Toolkit , [you can click here to read the documentation](https://github.com/john-yuan/graphql-toolkit#readme). To try GraphQL Toolkit online, [you can click here to visit our online playground](https://mygqljs.github.io/playground/).\n\nTable of contents:\n\n- [Usage](#usage)\n  - [Basic usage](#basic-usage)\n  - [Using alias](#using-alias)\n  - [Arguments](#arguments)\n  - [Arguments for sub-fields](#arguments-for-sub-fields)\n  - [Passing empty objects in the arguments with `$raw` or `$keep`](#passing-empty-objects-in-the-arguments-with-raw-or-keep)\n  - [Enumerations](#enumerations)\n  - [Variables](#variables)\n  - [Directives](#directives)\n  - [Fragments](#fragments)\n  - [Inline fragments](#inline-fragments)\n  - [Mutations](#mutations)\n  - [Multiple fields in mutations](#multiple-fields-in-mutations)\n  - [Using CDN](#using-cdn)\n\n## Usage\n\n### Basic usage\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    /**\n     * Optional operation name.\n     */\n    $name: 'CountriesQuery',\n\n    // Querying `countries`.\n    countries: {\n      // Specify arguments for `countries`.\n      $args: {\n        filter: {\n          continent: {\n            in: ['AF']\n          }\n        }\n      },\n\n      // Selecting the fields we want to fetch.\n      code: true,\n\n      // We can also use numbers, for they are shorter than booleans.\n      // Zero will be treated as `false`. Any other value will be\n      // treated as `true`.\n      name: 1,\n\n      // Selecting nested object.\n      continent: {\n        code: 1,\n\n        // If the value is string, the string will be used as alias.\n        name: 'continent_name'\n      }\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery CountriesQuery {\n  countries (\n    filter: {\n      continent: {\n        in: [\"AF\"]\n      }\n    }\n  ) {\n    code\n    name\n    continent {\n      code\n      continent_name: name\n    }\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Using alias\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    // Example of defining alias for the field.\n    country: {\n      $alias: 'country_fr',\n      $args: { code: 'FR' },\n\n      // We can use string to set alias.\n      code: 'country_code',\n      // We can also use object to set alias.\n      name: { $alias: 'country_name' }\n    },\n\n    // Example of defining two aliases for the same field.\n    countries: [\n      {\n        $alias: 'af_countries',\n        $args: { filter: { continent: { eq: 'AF' } } },\n        code: true,\n        name: true\n      },\n      {\n        $alias: 'as_countries',\n        $args: { filter: { continent: { eq: 'AS' } } },\n        code: true,\n        name: true\n      }\n    ]\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  country_fr: country (\n    code: \"FR\"\n  ) {\n    country_code: code\n    country_name: name\n  }\n  af_countries: countries (\n    filter: {\n      continent: {\n        eq: \"AF\"\n      }\n    }\n  ) {\n    code\n    name\n  }\n  as_countries: countries (\n    filter: {\n      continent: {\n        eq: \"AS\"\n      }\n    }\n  ) {\n    code\n    name\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Arguments\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    users: {\n      $args: {\n        // Values will be encoded to corresponding types in GraphQL.\n        nameContains: 'a',\n        verified: true,\n        deletedAt: null,\n        status: 1,\n\n        // Argument can be nested object.\n        hasFriendsWith: {\n          nameContains: 'b',\n          deletedAt: null\n        },\n\n        orderBy: {\n          field: 'created_at',\n\n          // If the value is an object with a key named `$enum`, the value\n          // will be processed as enumeration. In our example, the value\n          // `DESC` will not be double-quoted in the result for it is a\n          // enumeration value.\n          direction: { $enum: 'DESC' }\n        },\n\n        // If the value is `undefined` or if the argument is empty,\n        // the argument will be skipped.\n        role: undefined,\n        hasRoleWith: {}\n      },\n\n      id: true,\n      name: true\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  users (\n    nameContains: \"a\"\n    verified: true\n    deletedAt: null\n    status: 1\n    hasFriendsWith: {\n      nameContains: \"b\"\n      deletedAt: null\n    }\n    orderBy: {\n      field: \"created_at\"\n      direction: DESC\n    }\n  ) {\n    id\n    name\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Arguments for sub-fields\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    country: {\n      $args: { code: 'CN' },\n\n      // Set arguments for the field.\n      name: {\n        $args: { lang: 'zh' }\n      }\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  country (\n    code: \"CN\"\n  ) {\n    name (\n      lang: \"zh\"\n    )\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Passing empty objects in the arguments with `$raw` or `$keep`\n\nAs you can see in the previous example of arguments, the value with an empty object in the arguments will be skipped. But sometimes we need to pass empty object to the server, for example clearing all fields in a JSON field. To achieve that, we can use `$raw` or `$keep` to pass empty objects.\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  mutation: {\n    someAction: {\n      $args: {\n        // The following two objects will be skipped, for they are empty.\n        skippedEmptyObject1: {},\n        skippedEmptyObject2: { undefinedField: undefined },\n\n        // To keep empty object, we can use the `$keep` flag.\n        emptyObject1: { $keep: true },\n        emptyObject2: { $keep: true, undefinedField: undefined },\n\n        // We can also use `$raw` to pass objects.\n        emptyObject3: { $raw: '{}' },\n\n        // Actually, we can pass any type of value with `$raw`.\n        numberWithRaw: { $raw: 1 },\n        boolWithRaw: { $raw: true }\n      }\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nmutation {\n  someAction (\n    emptyObject1: {}\n    emptyObject2: {}\n    emptyObject3: {}\n    numberWithRaw: 1\n    boolWithRaw: true\n  )\n}\n```\n<!-- prettier-ignore-end -->\n\n### Enumerations\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    users: {\n      $args: {\n        // Enum is an object with a key named `$enum`.\n        // The enum value will not be double-quoted.\n        statusIn: [{ $enum: 'VERIFIED' }],\n\n        orderBy: {\n          field: 'created_at',\n          direction: { $enum: 'DESC' }\n        }\n      },\n\n      id: 1,\n      name: 1\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  users (\n    statusIn: [VERIFIED]\n    orderBy: {\n      field: \"created_at\"\n      direction: DESC\n    }\n  ) {\n    id\n    name\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Variables\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    $variables: {\n      // Declare a variable named `$codes`.\n      $codes: `[String!]! = []`\n    },\n\n    countries: {\n      // Use the variable named `$codes`.\n      $args: {\n        filter: {\n          code: {\n            // Variable is an object with a key named `$var`.\n            in: { $var: '$codes' }\n          }\n        }\n      },\n\n      code: true,\n      name: true\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery (\n  $codes: [String!]! = []\n) {\n  countries (\n    filter: {\n      code: {\n        in: $codes\n      }\n    }\n  ) {\n    code\n    name\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Directives\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    directivesExample: {\n      // Use string to set directive.\n      field1: {\n        $directives: '@skip(if: false)'\n      },\n\n      // Use object to set directive.\n      field2: {\n        $directives: {\n          name: '@include',\n          args: { if: true }\n        }\n      },\n\n      // Use array to set multiple directives.\n      field3: {\n        $directives: [\n          '@skip(if: false)',\n          {\n            name: '@my_directive',\n            args: { arg: 'value' }\n          }\n        ]\n      }\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  directivesExample {\n    field1 @skip(if: false)\n    field2 @include (\n      if: true\n    )\n    field3 @skip(if: false) @my_directive (\n      arg: \"value\"\n    )\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Fragments\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  fragments: {\n    // Declare a fragment named `countryFields` on the type `Country`.\n    countryFields: {\n      $on: 'Country',\n      code: true,\n      name: true\n    }\n  },\n  query: {\n    countries: {\n      // Use the fragment named `countryFields`.\n      $fragments: [{ spread: 'countryFields' }]\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  countries {\n    ...countryFields\n  }\n}\n\nfragment countryFields on Country {\n  code\n  name\n}\n```\n<!-- prettier-ignore-end -->\n\n### Inline fragments\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  query: {\n    countries: {\n      $fragments: [\n        // Inline fragment on the type `Country`.\n        {\n          inline: {\n            $on: 'Country',\n            // Set directives for the fragment.\n            $directives: {\n              name: '@skip',\n              args: { if: false }\n            },\n            name: true\n          }\n        },\n        // The type can be omitted.\n        {\n          inline: {\n            code: true\n          }\n        }\n      ]\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nquery {\n  countries {\n    ... on Country @skip (\n      if: false\n    ) {\n      name\n    }\n    ... {\n      code\n    }\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Mutations\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  mutation: {\n    updateUser: {\n      $args: {\n        id: '1000',\n        name: 'joe'\n      },\n\n      name: true\n    }\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nmutation {\n  updateUser (\n    id: \"1000\"\n    name: \"joe\"\n  ) {\n    name\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n### Multiple fields in mutations\n\nBecause [**mutation fields run in series, one after the other**](https://graphql.org/learn/queries/#multiple-fields-in-mutations). So the order of the fields in a mutation is very important to avoid race condition. To make sure the field order is correct, we should use the `$fields` array to ensure the order. Below is an example:\n\n```ts\nimport { generateQuery } from 'generate-graphql-query'\n\nconst query = generateQuery({\n  mutation: {\n    // Use `$fields` array to make sure the order of multiple fields\n    // is correct. In this example, the mutation `operationB` is\n    // guaranteed to finish before the mutation `operationA` begins.\n    $fields: [\n      {\n        operationB: {\n          $args: { id: '1000' },\n          status: true\n        }\n      },\n      {\n        operationA: {\n          $args: { id: '1000' },\n          status: true\n        }\n      }\n    ]\n  }\n})\n\nconsole.log(query)\n```\n\nThe output is:\n\n<!-- prettier-ignore-start -->\n```gql\nmutation {\n  operationB (\n    id: \"1000\"\n  ) {\n    status\n  }\n  operationA (\n    id: \"1000\"\n  ) {\n    status\n  }\n}\n```\n<!-- prettier-ignore-end -->\n\n## Using CDN\n\nFrom the version `1.1.0`, we can load this module by a CDN like unpkg directly.\n\nExample:\n\n<!-- prettier-ignore-start -->\n```html\n<script src=\"https://unpkg.com/generate-graphql-query/browser/index.js\"></script>\n<script>\n  var query = GraphQLToolkit.generateQuery({\n    query: {\n      countries: {\n        code: true,\n        name: true\n      }\n    }\n  })\n\n  console.log(query)\n</script>\n```\n<!-- prettier-ignore-end -->\n","readmeFilename":"README.md"}