
Security News
vlt Launches "reproduce": A New Tool Challenging the Limits of Package Provenance
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
@khanacademy/graphql-flow
Advanced tools
This is a tool for generating flow types from graphql queries in javascript frontends.
This is a tool for generating flow types from graphql queries in javascript frontends.
Write a config file, with the following options:
{
// Response to the "introspection query" (see below), or a .graphql schema file.
// The file extension indicates the format, .json or .graphql (default .json).
// This path is resolved relative to the config file location.
"schemaFilePath": "../some/schema-file.json",
// List of regexes
"excludes": ["\\bsome-thing", "_test.jsx?$"],
// Options for type generation (see below)
"options": {
"scalars": {
"JSONString": "string"
}
}
}
Optionally add subconfig files to subdirectories for granular control of behavior, with the following options:
{
// Note that this file must be named, or end with, "graphql-flow.config.json"
// I.e., "my-service.graphql.config.json" would also work.
// These files will affect the directory in which they are located and all subdirectories, unless overridden by a deeper subconfig.
// Optionally add the path of another config file. Can be the root config (provided when running the script) or any other subconfig to merge options.
// If a chain of extends are provided, will resolve in order. Be sure not to extend in a circle-- currently, this will just cause a stack overflow error.
// Cannot currently override `schemaFilePath`.
"extends": "./another/config/from/root.config.json",
// Can extend or override `excludes` and `options`.
"excludes": ["\\bsome-thing", "_test.jsx?$"],
"options": {
...
}
}
Then run from the CLI, like so:
$ graphql-flow path/to/config.json
Files will be discovered relative to the current working directory.
To specify what file should be checked, pass them in as subsequent cli arguments.
type Options = {
// These are from the `documentToFlowTypes` options object above
strictNullability: boolean = true,
readOnlyArray: boolean = true,
scalars: {[key: string]: 'string' | 'boolean' | 'number'}
// Specify the name of the generated types directory. If this
// is a relative path, then this is used to suffix the output
// directory; if it's an absolute path it's used to prefix the
// output directory. For instance, if a gql directive is
// found in /foo/bar/baz/query.js and you run the cli (or
// jest) from directory /foo, then:
// * if `generatedDirectory` is "__generated__", the output will
// be in /foo/bar/baz/__generated__/index.js and sibling files
// * if `generatedDirectory` is "/tmp/__generated__", the output
// will be in /tmp/__generated__/bar/baz/index.js and sibling
// files.
generatedDirectory: string = '__generated__',
// The default generated type contains both the types of the response
// and the variables, combined as [operatioName]Type. Setting
// `splitTypes = true` adds the additional exports [operationName]
// (for the response) and [operationName]Variables (for the variables).
splitTypes?: boolean,
// Specify an opt-in pragma that must be present in a graphql string source
// in order for it to be picked up and processed
// e.g. set this to `"# @autogen\n"` to only generate types for queries that
// have the comment `# @autogen` in them.
pragma?: string,
// Specify a pragma that will turn off `strictNullability` for that
// source file. e.g. `"# @autogen-loose\n"`.
loosePragma?: string,
// If neither pragma nor loosePragma are specified, all graphql documents
// that contain a query or mutation will be processed.
// Any graphql operations containing ignorePragma will be skipped
ignorePragma?: string,
// Set to true to mirror gqlgen's behavior of exporting all
// nested object types within the response type.
// Names are generated by concatenating the attribute names
// of the path to the object type, separated by underscores.
exportAllObjectTypes?: boolean,
// A template for the name of generated files
// default: [operationName].js
typeFileName?: string,
// Generate flow enums to replace literal unions in generated types. Exports
// each set of enums from each file regardless of other options. Designated
// "experimental" because of bug in eslint that requires config comments.
experimentalEnums?: boolean,
}
You can also use jest to do the heavy lifting, running all of your code and collecting queries
by mocking out the graphql-tag
function itself. This requires that all graphql operations are
defined at the top level (no queries defined in functions or components, for example), but does
support complicated things like returning a fragment from a function (which is probably
not a great idea code-style-wise anyway).
Add the following snippet to your jest-setup.js
if (process.env.GRAPHQL_FLOW) {
jest.mock('graphql-tag', () => {
const introspectionData = jest.requireActual(
'./server-introspection-response.json',
);
return jest.requireActual('../tools/graphql-flow/jest-mock-graphql-tag.js')(
introspectionData,
// See "Options" type above
{
pragma: '# @autogen\n',
loosePragma: '# @autogen-loose\n',
}
);
});
}
That will mock out the graphql-tag
function, so that everywhere you call 'gqlsome-query
', we'll pick it up and
generate a type for it! As written, the mocking only happens if the GRAPHQL_FLOW
env variable is set, so that it won't run every time.
By default, all queries are processed. To have them 'opt-in', use the pragma
and loosePragma
options. Queries with loosePragma
in the source will have types generated that ignore nullability.
Then you'll want to make a pseudo-'test' that makes sure to 'require' all of the files that define queries, so that jest will process them and our mock will see them.
// generate-types.test.js
import {findGraphqlTagReferences} from '../tools/graphql-flow/find-files-with-gql';
import path from 'path';
if (process.env.GRAPHQL_FLOW) {
findGraphqlTagReferences(path.join(__dirname, '..')).forEach(name => {
require(name);
});
it('should have found queries', () => {
const gql = require('graphql-tag')
expect(gql.collectedQueries.length).toBeGreaterThan(0)
})
} else {
it(`not generating graphql types because the env flag isn't set`, () => {
// not doing anything because the env flag isn't set.
})
}
You can add a script to package.json, like so:
"scripts": {
"generate-types": "env GRAPHQL_FLOW=1 jest generate-types.test.js"
}
And then yarn generate-types
or npm run generate-types
gets your types generated!
🚀
Here's how to get your backend's schema in the way that this tool expects, using the builtin 'graphql introspection query':
import {getIntrospectionQuery} from 'graphql';
import fs from 'fs';
import fetch from 'node-fetch';
const query = getIntrospectionQuery({descriptions: true}),
const response = await fetch(`https://my-backend.com`, {
method: 'POST',
body: query,
headers: {
// You definitely shouldn't be allowing arbitrary queries without
// some strict access control.
'X-header-that-allows-arbitrary-queries': 'my-secret-key',
},
contentType: 'application/json',
});
const fullResponse = await response.json();
fs.writeFileSync('./server-introspection-response.json', JSON.stringify(fullResponse.data, null, 2));
FAQs
This is a tool for generating flow types from graphql queries in javascript frontends.
The npm package @khanacademy/graphql-flow receives a total of 288 weekly downloads. As such, @khanacademy/graphql-flow popularity was classified as not popular.
We found that @khanacademy/graphql-flow demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.