Skip to content

Commit

Permalink
feat: use cosmiconfig, update deps
Browse files Browse the repository at this point in the history
uses smart defaults based on conventional expectations in the JS ecosystem

BREAKING CHANGE: .graphqlconfig -> .graphqlrc, getGraphQLConfig is now async, findGraphQLConfigFile
is removed

fix #119, #116, #115, #110, #109, #108, #107, #99, #98, #95, #93, #92, #89
  • Loading branch information
jednano committed Jul 25, 2019
1 parent 0bdf2d2 commit 86c455b
Show file tree
Hide file tree
Showing 35 changed files with 5,932 additions and 1,634 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
language: node_js
node_js:
- 'lts/*'
- '10'
- '9'
- '8'
- '6'

install:
- yarn
Expand Down
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ The easiest way to configure your development environment with your GraphQL sche

Install [`graphql-cli`](https://github.com/graphcool/graphql-cli) and run `graphql init`. Answer a few simple questions and you are set up!

You can either configure your GraphQL endpoint via a configuration file `.graphqlconfig`
(or `.graphqlconfig.yaml`) which should be put into the root of your project
You can configure your GraphQL endpoint via a configuration file via [cosmiconfig](https://github.com/davidtheclark/cosmiconfig#cosmiconfig) (e.g., `.graphqlrc`), which should be in the root of your project.

### Simplest use case

Expand Down Expand Up @@ -74,7 +73,7 @@ You can specify which files are included/excluded using the corresponding option
#### Specifying endpoint info

You may specify your endpoints info in `.graphqlconfig` which may be used by some tools.
You may specify your endpoints info in a `.graphqlrc` file which may be used by some tools.
The simplest case:

```json
Expand Down Expand Up @@ -113,7 +112,7 @@ an endpoint for subscription, you can use expanded version:
}
```

> Note: do not save secure information in .graphqlconfig file. Use [Environment variables](specification.md#referencing-environment-variables) for that like in the example above.
> Note: do not save secure information in your .graphql file. Use [Environment variables](specification.md#referencing-environment-variables) for that like in the example above.
In case if you have multiple endpoints use the following syntax:

Expand Down
13 changes: 1 addition & 12 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
The library exports the following entities:

**Functions:**
- [`findGraphQLConfigFile`](#findgraphqlconfigfile)
- [`getGraphQLConfig`](#getgraphqlconfig)
- [`getGraphQLProjectConfig`](#getgraphqlprojectconfig)

Expand All @@ -12,21 +11,11 @@ The library exports the following entities:
- [`GraphQLProjectConfig`](#graphqlprojectconfig)
- [`GraphQLEndpointExtension`](#graphqlendpointsextension)

Advanced .graphqlconfig may contain a few `projects` with `includes/excludes` configured,
Advanced `.graphqlrc` file may contain a few `projects` with `includes/excludes` configured,
so if your tool works on per-file basis use `getGraphQLConfig` and `GraphQLConfig`.
For simpler use-cases when your tool needs only a schema `getGraphQLProjectConfig` and
`GraphQLProjectConfig` should be used.

## `findGraphQLConfigFile`

`function findGraphQLConfigFile(filePath: string): string`

Starting from `filePath` and up the directory tree returns path to the first reached `.graphqlconfig`
or `.graphqlconfig.yaml` file. Throws `ConfigNotFoundError` error when config is not found.

**Arguments**:
- `filePath` - file path or directory to start search from

## `getGraphQLConfig`

`function getGraphQLConfig(rootDir: string = process.cwd()): GraphQLConfig`
Expand Down
40 changes: 27 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
"prepublish": "npm run build",
"clean": "rimraf lib",
"build": "npm run clean && tsc",
"copy-test-assets": "cpx \"src/**/{.graphqlconfig*,*.graphql,*.json}\" lib",
"copy-test-assets": "cpx \"src/**/{.graphqlrc*,*.graphql,*.json,*.md,*.snap}\" lib",
"test-only": "npm run build && npm run copy-test-assets && ava --verbose lib/__tests__/**/*.js --serial",
"test": "tslint src/**/*.ts && npm run test-only"
"test": "tslint src/**/*.ts && npm run test-only",
"commit": "git-cz"
},
"repository": {
"type": "git",
Expand All @@ -37,25 +38,38 @@
},
"homepage": "https://github.com/graphcool/graphql-config#readme",
"devDependencies": {
"@types/graphql": "0.13.3",
"@types/node": "9.4.6",
"@types/node-fetch": "1.6.7",
"ava": "0.25.0",
"@types/cosmiconfig": "^5.0.3",
"@types/graphql": "14.2.3",
"@types/js-yaml": "^3.12.1",
"@types/lodash": "^4.14.136",
"@types/minimatch": "^3.0.3",
"@types/node": "12.6.8",
"@types/node-fetch": "2.5.0",
"ava": "2.2.0",
"commitizen": "^4.0.3",
"cpx": "1.5.0",
"graphql": "14.0.2",
"rimraf": "2.6.2",
"tslint": "5.9.1",
"tslint-config-standard": "7.0.0",
"typescript": "2.7.2"
"cz-conventional-changelog": "^3.0.2",
"graphql": "14.4.2",
"rimraf": "2.6.3",
"tslint": "5.18.0",
"tslint-config-standard": "8.0.1",
"typescript": "3.5.3"
},
"dependencies": {
"@endemolshinegroup/cosmiconfig-typescript-loader": "^1.0.1",
"cosmiconfig": "^5.2.1",
"graphql-import": "^0.7.1",
"graphql-request": "^1.5.0",
"graphql-request": "^1.8.2",
"js-yaml": "^3.13.1",
"lodash": "^4.17.4",
"lodash": "^4.17.15",
"minimatch": "^3.0.4"
},
"peerDependencies": {
"graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
16 changes: 8 additions & 8 deletions specification.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# GraphQL Configuration

There are many ways to configure your application to use GraphQL, and while it is often enough to specify configuration options directly in your application code, maintaining and understanding the hard-coded configuration options may become a challenge as the scale grows. We recommend configuring your application with a `.graphqlconfig` file that contains commonly needed GraphQL-related artifacts.
There are many ways to configure your application to use GraphQL, and while it is often enough to specify configuration options directly in your application code, maintaining and understanding the hard-coded configuration options may become a challenge as the scale grows. We recommend configuring your application with a `.graphqlrc` file that contains commonly needed GraphQL-related artifacts.

## GraphQL Configuration Format

Expand Down Expand Up @@ -47,7 +47,7 @@ Usually, for a simple GraphQL applications, the only required configuration is a
}
```

For multiple apps with isolated directories, there are mainly two ways to set up the configuration. Each app can either use the `projects` property to specify each application's configuration, or have a separate `.graphqlconfig` file for each project root.
For multiple apps with isolated directories, there are mainly two ways to set up the configuration. Each app can either use the `projects` property to specify each application's configuration, or have a separate `.graphqlrc` file for each project root.
```json
{
"projects": {
Expand All @@ -61,10 +61,10 @@ For multiple apps with isolated directories, there are mainly two ways to set up
}
```

Or each app can have a separate `.graphqlconfig` file per each application and/or directories:
Or each app can have a separate `.graphqlrc` file per each application and/or directories:
```
./appA/.graphqlconfig
./appB/.graphqlconfig
./appA/.graphql
./appB/.graphql
```

## Default Configuration Properties
Expand Down Expand Up @@ -115,7 +115,7 @@ Since projectA and projectB share the same schema file, we can push the `schemaP
Additionally, we'd like to treat the `extensions` property as a sandbox for improving the overall GraphQL configuration. If there is a configuration option that you think will be useful for general purposes, please let us know! Meanwhile, take advantage of this 'extensions' for testing purposes.

For example, some application may choose to build using Webpack and need to specify Webpack-related configurations in GraphQL configuration. Also, they may need to process additional file types other than `.graphql`. Below suggests one way to configure these options using 'extensions':
For example, some application may choose to build using Webpack and need to specify Webpack-related configurations in GraphQL configuration. Also, they may need to process additional file types other than `.graphqlrc`. Below suggests one way to configure these options using 'extensions':

```
{
Expand Down Expand Up @@ -194,7 +194,7 @@ Additional header values could be added if needed:
}
```

**Note**: Don't specify passwords, tokens, etc. inside your `.graphqlconfig`. Use [Environment variables](#referencing-environment-variables) for that.
**Note**: Don't specify passwords, tokens, etc. inside your `.graphqlrc` file. Use [Environment variables](#referencing-environment-variables) for that.

### Referencing Environment Variables

Expand Down Expand Up @@ -295,7 +295,7 @@ Sometimes a GraphQL application wants to either define an additional set of vali
// In customRules.js,
export const customRules: Array<(context: ValidationContext) => any> = { ... };

// And in .graphqlconfig, specify where the custom rules are:
// And in .graphql, specify where the custom rules are:
{
"schemaPath": "./schema.graphql",
"extensions": {
Expand Down
21 changes: 8 additions & 13 deletions src/GraphQLConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { resolve, dirname } from 'path'
import { dirname } from 'path'
import { validateConfig, writeConfig } from './utils'
import { values } from 'lodash'

Expand All @@ -9,16 +9,11 @@ import {
import { GraphQLProjectConfig } from './GraphQLProjectConfig'

export class GraphQLConfig {
public config: GraphQLConfigData
public configPath: string

constructor(
config: GraphQLConfigData,
configPath: string
public config: GraphQLConfigData,
public configPath: string
) {
validateConfig(config)
this.config = config
this.configPath = configPath
}

get configDir() {
Expand All @@ -43,8 +38,8 @@ export class GraphQLConfig {
}

getProjectNameForFile(filePath: string): string | undefined {
const proj = this.getConfigForFile(filePath);
return proj && proj.projectName || undefined;
const proj = this.getConfigForFile(filePath)
return proj && proj.projectName || undefined
}

getProjects(): { [name: string]: GraphQLProjectConfig } | undefined {
Expand All @@ -59,10 +54,10 @@ export class GraphQLConfig {
}

saveConfig(newConfig: GraphQLConfigData, projectName?: string) {
let config
let config: GraphQLConfigData
if (projectName) {
config = this.config;
config.projects = config.projects || {};
config = this.config
config.projects = config.projects || {}
config.projects[projectName] = config.projects[projectName] || {}
config.projects[projectName] = newConfig
} else {
Expand Down
33 changes: 12 additions & 21 deletions src/GraphQLProjectConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@ import { dirname, resolve, relative, join } from 'path'
import {
GraphQLSchema,
printSchema,
introspectionQuery,
IntrospectionQuery,
buildClientSchema,
} from 'graphql'

import { GraphQLClient } from 'graphql-request'

import {
IntrospectionResult,
GraphQLResolvedConfigData,
Expand All @@ -30,23 +25,19 @@ import {
GraphQLEndpointsExtension
} from './extensions'

/*
* this class can be used for simple usecases where there is no need in per-file API
/**
* This class can be used for simple usecases where there is no need in per-file API.
*/
export class GraphQLProjectConfig {
public config: GraphQLResolvedConfigData
public configPath: string
public projectName?: string

constructor(
config: GraphQLConfigData,
configPath: string,
projectName?: string
public configPath: string,
public projectName?: string
) {
validateConfig(config)
this.config = loadProjectConfig(config, projectName)
this.configPath = configPath
this.projectName = projectName
}

resolveConfigPath(relativePath: string): string {
Expand All @@ -55,10 +46,10 @@ export class GraphQLProjectConfig {

includesFile(fileUri: string): boolean {
const filePath = fileUri.startsWith('file://') ?
fileUri.substr(7) : fileUri;
fileUri.substr(7) : fileUri
const fullFilePath = filePath.startsWith(this.configDir) ?
filePath : resolve(join(this.configDir, filePath));
const relativePath = relative(this.configDir, fullFilePath);
filePath : resolve(join(this.configDir, filePath))
const relativePath = relative(this.configDir, fullFilePath)
return (
(
!this.config.includes ||
Expand Down Expand Up @@ -105,17 +96,17 @@ export class GraphQLProjectConfig {
return this.config.extensions || {}
}

/*
extension related helper functions
/**
* extension related helper functions
*/
get endpointsExtension(): GraphQLEndpointsExtension | null {
if (!this.extensions.endpoints) {
return null
}

const {endpoints} = this.extensions
const { endpoints } = this.extensions

if (typeof endpoints !== 'object' || Array.isArray(endpoints)) {
if (Array.isArray(endpoints)) {
throw new Error(`${this.configPath}: "endpoints" should be an object`)
}

Expand All @@ -136,7 +127,7 @@ function loadProjectConfig(
) {
const { projects, ...configBase } = config

if (projects == null || !Object.keys(projects).length) {
if (projects === undefined || !Object.keys(projects).length) {
return config
}

Expand Down
File renamed without changes.
Loading

0 comments on commit 86c455b

Please sign in to comment.