Skip to content

Commit

Permalink
allow specifying headers to get introspection (#87)
Browse files Browse the repository at this point in the history
* allow specifying headers to get introspection

* general improvements
  • Loading branch information
JoviDeCroock authored Jun 27, 2023
1 parent 01844cf commit 313cb3b
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 51 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-lobsters-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@0no-co/graphqlsp': minor
---

Allow specifying headers for fetching the introspection
4 changes: 1 addition & 3 deletions packages/example/src/Pokemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export const PokemonFields = gql`
fragment pokemonFields on Pokemon {
id
name
...someUnknownFragment
attacks {
fast {
damage
Expand All @@ -18,9 +17,8 @@ export const PokemonFields = gql`
export const WeakFields = gql`
fragment weaknessFields on Pokemon {
weaknesses
someUnknownField
}
` as typeof import('./Pokemon.generated').PokemonFieldsFragmentDoc;
` as typeof import('./Pokemon.generated').WeaknessFieldsFragmentDoc;

export const Pokemon = (data: any) => {
const pokemon = useFragment(PokemonFields, data);
Expand Down
41 changes: 11 additions & 30 deletions packages/example/src/index.generated.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions packages/example/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ const PokemonsQuery = gql`
id
name
fleeRate
__typenam
__typename
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/graphqlsp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ when on a TypeScript file or adding a file like [this](https://github.com/0no-co
### Configuration

- `schema` allows you to specify a url, `.json` or `.graphql` file as your schema
- `schema` allows you to specify a url, `.json` or `.graphql` file as your schema. If you need to specify headers for your introspection
you can opt into the object notation i.e. `{ "schema": { "url": "x", "headers": { "Authorization": "y" } }}`
- `disableTypegen` disables type-generation in general
- `scalars` allows you to pass an object of scalars that we'll feed into `graphql-code-generator`
- `extraTypes` allows you to specify imports or declare types to help with `scalar` definitions
Expand Down
33 changes: 26 additions & 7 deletions packages/graphqlsp/src/graphql/getSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ import fs from 'fs';
import { Logger } from '../index';
import { generateBaseTypes } from './generateTypes';

export type SchemaOrigin = {
url: string;
headers: Record<string, unknown>;
};

export const loadSchema = (
root: string,
schema: string,
schema: SchemaOrigin | string,
logger: Logger,
baseTypesPath: string,
shouldTypegen: boolean,
Expand All @@ -24,21 +29,34 @@ export const loadSchema = (
const ref: { current: GraphQLSchema | null } = { current: null };
let url: URL | undefined;

let isJSON = false;
let config: undefined | SchemaOrigin;

try {
url = new URL(schema);
if (typeof schema === 'object') {
url = new URL(schema.url);
} else {
url = new URL(schema);
}
} catch (e) {}

if (url) {
logger(`Fetching introspection from ${url.toString()}`);
fetch(url.toString(), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
headers:
isJSON && config
? {
...(config.headers || {}),
'Content-Type': 'application/json',
}
: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: getIntrospectionQuery({
descriptions: true,
schemaDescription: true,
schemaDescription: false,
inputValueDeprecation: false,
directiveIsRepeatable: false,
specifiedByUrl: false,
Expand All @@ -51,6 +69,7 @@ export const loadSchema = (
else return response.text();
})
.then(result => {
logger(`Got result ${JSON.stringify(result)}`);
if (typeof result === 'string') {
logger(`Got error while fetching introspection ${result}`);
} else if (result.data) {
Expand All @@ -73,7 +92,7 @@ export const loadSchema = (
logger(`Got invalid response ${JSON.stringify(result)}`);
}
});
} else {
} else if (typeof schema === 'string') {
const isJson = schema.endsWith('json');
const resolvedPath = path.resolve(path.dirname(root), schema);
logger(`Getting schema from ${resolvedPath}`);
Expand Down
25 changes: 18 additions & 7 deletions packages/graphqlsp/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ts from 'typescript/lib/tsserverlibrary';

import { loadSchema } from './graphql/getSchema';
import { SchemaOrigin, loadSchema } from './graphql/getSchema';
import { getGraphQLCompletions } from './autoComplete';
import { getGraphQLQuickInfo } from './quickInfo';
import { getGraphQLDiagnostics } from './diagnostics';
Expand All @@ -20,20 +20,31 @@ function createBasicDecorator(info: ts.server.PluginCreateInfo) {

export type Logger = (msg: string) => void;

type Config = {
schema: SchemaOrigin | string;
template?: string;
disableTypegen?: boolean;
extraTypes?: string;
scalars?: Record<string, unknown>;
shouldCheckForColocatedFragments?: boolean;
};

function create(info: ts.server.PluginCreateInfo) {
const logger: Logger = (msg: string) =>
info.project.projectService.logger.info(`[GraphQLSP] ${msg}`);
logger('config: ' + JSON.stringify(info.config));
if (!info.config.schema) {
const config: Config = info.config;

logger('config: ' + JSON.stringify(config));
if (!config.schema) {
logger('Missing "schema" option in configuration.');
throw new Error('Please provide a GraphQL Schema!');
}

logger('Setting up the GraphQL Plugin');

const scalars = info.config.scalars || {};
const extraTypes = info.config.extraTypes;
const disableTypegen = info.config.disableTypegen;
const scalars = config.scalars || {};
const extraTypes = config.extraTypes || '';
const disableTypegen = config.disableTypegen || false;

const proxy = createBasicDecorator(info);

Expand All @@ -42,7 +53,7 @@ function create(info: ts.server.PluginCreateInfo) {

const schema = loadSchema(
info.project.getProjectName(),
info.config.schema,
config.schema,
logger,
baseTypesPath,
!disableTypegen,
Expand Down
1 change: 0 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 313cb3b

Please sign in to comment.