Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .changeset/cli-hive-json-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@graphql-hive/cli': minor
---

Add a JSON Schema for the `hive.json` configuration file.

The CLI now ships a `hive-config.schema.json` describing the supported `hive.json` shapes (the modern
`registry`/`cdn` format, the deprecated flat format, and namespaced/space configurations). Reference
it from your config to get autocompletion, inline documentation, and validation in editors that
support JSON Schema:

```json
{
"$schema": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The repository name is platform, not console. Update the schema URL to use graphql-hive/platform.

Suggested change
"$schema": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",
"$schema": "https://raw.githubusercontent.com/graphql-hive/platform/main/packages/libraries/cli/hive-config.schema.json",

"registry": {
"endpoint": "<yourRegistryURL>",
"accessToken": "<yourtoken>"
}
}
```
4 changes: 4 additions & 0 deletions packages/libraries/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ This is how the structure of the config file should look like:

```json
{
"$schema": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The repository name is platform, not console. Update the schema URL to use graphql-hive/platform.

Suggested change
"$schema": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",
"$schema": "https://raw.githubusercontent.com/graphql-hive/platform/main/packages/libraries/cli/hive-config.schema.json",

"registry": {
"endpoint": "<yourRegistryURL>",
"accessToken": "<yourtoken>"
Expand All @@ -594,3 +595,6 @@ This is how the structure of the config file should look like:
}
}
```

The optional `$schema` property enables autocompletion, inline documentation, and validation for
`hive.json` in editors that support JSON Schema (such as VS Code).
94 changes: 94 additions & 0 deletions packages/libraries/cli/hive-config.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The repository name is platform, not console. Update the $id URL to use graphql-hive/platform.

Suggested change
"$id": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",
"$id": "https://raw.githubusercontent.com/graphql-hive/platform/main/packages/libraries/cli/hive-config.schema.json",

"title": "GraphQL Hive CLI configuration (hive.json)",
"description": "Configuration file for the GraphQL Hive CLI (`hive`). Configuration is resolved with the priority: CLI arguments > environment variables > hive.json. See https://the-guild.dev/graphql/hive/docs/api-reference/cli for details.",
"$comment": "Keep this schema in sync with ConfigModel and LegacyConfigModel in packages/libraries/cli/src/helpers/config.ts.",
"anyOf": [
{ "$ref": "#/definitions/modernConfig" },
{ "$ref": "#/definitions/legacyConfig" },
{ "$ref": "#/definitions/namespacedConfig" }
],
"definitions": {
"registry": {
"type": "object",
"additionalProperties": false,
"description": "Schema registry connection settings.",
"properties": {
"endpoint": {
"type": "string",
"format": "uri",
"description": "GraphQL endpoint of the Hive schema registry. Defaults to https://app.graphql-hive.com/graphql. Set this when self-hosting Hive. Can also be provided via the HIVE_REGISTRY environment variable or the --registry.endpoint argument."
},
"accessToken": {
"type": "string",
"description": "Registry access token used to authenticate registry commands such as schema:publish and schema:check. Can also be provided via the HIVE_TOKEN environment variable or the --registry.accessToken argument."
}
}
},
"cdn": {
"type": "object",
"additionalProperties": false,
"description": "High-availability CDN settings used by artifact:fetch.",
"properties": {
"endpoint": {
"type": "string",
"format": "uri",
"description": "High-availability CDN endpoint for fetching artifacts. Can also be provided via the HIVE_CDN_ENDPOINT environment variable or the --cdn.endpoint argument."
},
"accessToken": {
"type": "string",
"description": "CDN access token used by artifact:fetch. Can also be provided via the --cdn.accessToken argument."
}
}
},
"modernConfig": {
"type": "object",
"additionalProperties": false,
"description": "Hive CLI configuration.",
"properties": {
"$schema": {
"type": "string",
"description": "URL of the JSON Schema used to validate this file."
},
"registry": { "$ref": "#/definitions/registry" },
"cdn": { "$ref": "#/definitions/cdn" }
}
},
"legacyConfig": {
"type": "object",
"additionalProperties": false,
"description": "Deprecated flat configuration format. Use the `registry` object (modernConfig) instead.",
"properties": {
"$schema": {
"type": "string",
"description": "URL of the JSON Schema used to validate this file."
},
"registry": {
"type": "string",
"description": "Deprecated. Registry endpoint URL. Use `registry.endpoint` instead."
},
"token": {
"type": "string",
"description": "Deprecated. Registry access token. Use `registry.accessToken` instead."
}
}
},
"namespacedConfig": {
"type": "object",
"description": "Multiple named configurations ('spaces'). The active space is selected with the HIVE_SPACE environment variable, falling back to the `default` space. Each value is a Hive CLI configuration.",
"properties": {
"$schema": {
"type": "string",
"description": "URL of the JSON Schema used to validate this file."
}
},
"additionalProperties": {
"anyOf": [
{ "$ref": "#/definitions/modernConfig" },
{ "$ref": "#/definitions/legacyConfig" }
]
}
}
}
}
1 change: 1 addition & 0 deletions packages/libraries/cli/hive.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The repository name is platform, not console. Update the schema URL to use graphql-hive/platform.

Suggested change
"$schema": "https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json",
"$schema": "https://raw.githubusercontent.com/graphql-hive/platform/main/packages/libraries/cli/hive-config.schema.json",

"registry": {
"endpoint": "http://localhost:3001/graphql",
"accessToken": "905818792799ac1194c1d69d64c94a1a"
Expand Down
2 changes: 2 additions & 0 deletions packages/libraries/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"files": [
"/bin",
"/dist",
"/hive-config.schema.json",
"/oclif.manifest.json"
],
"keywords": [
Expand Down Expand Up @@ -71,6 +72,7 @@
},
"devDependencies": {
"@types/env-ci": "3.1.4",
"ajv": "8.18.0",
"graphql": "16.9.0",
"oclif": "4.22.65",
"rimraf": "6.1.3",
Expand Down
2 changes: 2 additions & 0 deletions packages/libraries/cli/src/helpers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import fs from 'fs';
import path from 'path';
import { z } from 'zod';

// NOTE: When changing these models, update the public JSON Schema at
// packages/libraries/cli/hive-config.schema.json (and the SchemaStore catalog entry) to match.
const LegacyConfigModel = z.object({
registry: z.string().optional(),
token: z.string().optional(),
Expand Down
73 changes: 73 additions & 0 deletions packages/libraries/cli/tests/hive-config.schema.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import Ajv from 'ajv';

// Compiles the shipped JSON Schema and asserts it accepts every `hive.json` shape
// the `Config` class accepts and rejects common typos. Keep the fixtures in sync
// with ConfigModel / LegacyConfigModel in src/helpers/config.ts.
const schema = JSON.parse(
readFileSync(join(__dirname, '..', 'hive-config.schema.json'), 'utf8'),
) as Record<string, unknown>;

// `strict: false`: the schema uses `format: "uri"`, which bare ajv does not
// register. This suite tests structure (shapes + typos), not URI formatting.
const ajv = new Ajv({ strict: false, allErrors: true });
const validate = ajv.compile(schema);

const SCHEMA_URL =
'https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json';
Comment on lines +17 to +18

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The repository name is platform, not console. Update the SCHEMA_URL to use graphql-hive/platform.

Suggested change
const SCHEMA_URL =
'https://raw.githubusercontent.com/graphql-hive/console/main/packages/libraries/cli/hive-config.schema.json';
const SCHEMA_URL =
'https://raw.githubusercontent.com/graphql-hive/platform/main/packages/libraries/cli/hive-config.schema.json';


const registry = {
endpoint: 'https://app.graphql-hive.com/graphql',
accessToken: 'a-registry-token',
};
const cdn = {
endpoint: 'https://cdn.graphql-hive.com/artifacts/v1/target',
accessToken: 'a-cdn-token',
};

const validConfigs: Array<[string, unknown]> = [
['a modern config with registry only', { registry }],
['a modern config with registry and cdn', { registry, cdn }],
['an empty config', {}],
['a modern config with a $schema reference', { $schema: SCHEMA_URL, registry }],
['a legacy flat config', { registry: 'https://app.graphql-hive.com/graphql', token: 'a-token' }],
[
'a legacy flat config with a $schema reference',
{ $schema: SCHEMA_URL, registry: 'https://app.graphql-hive.com/graphql', token: 'a-token' },
],
[
'a namespaced config with default and named spaces',
{ default: { registry }, production: { registry } },
],
['a namespaced config with a $schema reference', { $schema: SCHEMA_URL, default: { registry } }],
];

const invalidConfigs: Array<[string, unknown]> = [
[
'a misspelled top-level "registery" key',
{ registery: { endpoint: 'https://app.graphql-hive.com/graphql' } },
],
[
'a misspelled nested "accesToken" key',
{ registry: { endpoint: 'https://app.graphql-hive.com/graphql', accesToken: 'a-token' } },
],
['a non-string registry endpoint', { registry: { endpoint: 123 } }],
['a registry that is neither an object nor a string', { registry: true }],
];

describe('hive-config.schema.json', () => {
test('compiles as a valid JSON Schema', () => {
expect(typeof validate).toBe('function');
});

test.each(validConfigs)('accepts %s', (_name, config) => {
const isValid = validate(config);
expect(isValid, ajv.errorsText(validate.errors)).toBe(true);
});

test.each(invalidConfigs)('rejects %s', (_name, config) => {
const isValid = validate(config);
expect(isValid).toBe(false);
});
});
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

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