graphql-hive / graphql-hive/envelop

Improve hooks API and separate to input/output

Open
#1,327 0 comments 2 reactions 0 assignees View on GitHub
kind/enhancement
Dominant language
No language data
Stars
827
Forks
132
PR merge metrics
No merged PRs in 30d

Description

At the moment, we don't have a clear distinction between the input and the output of every hook.
We can implement this concept by changing the signature of every hook function (breaking change for sure), to be something like:

```ts
type OnParse = (readonly api: { context: TInputContext }) => ({ contextExtension: TOutputContext });
```

### Improved input/output `context` types

Related: https://github.com/dotansimha/envelop/issues/439

This way, we can use TS conditional types to do TS checks for enforcing some fields in the return value, based on other conditions.

[Here's an example for enforcing context extensions based on `TOutputContext` value](https://www.typescriptlang.org/play#code/MYewdgzgLgBApgWwA5QJ4HkCuUnYMLhRwAeUAyqggEYgA2MAvDBdXQBQBEiKG2uUBMEVIsatDgEoAUFID0AKnlSY8mAElIRAIYATGCABmMTBACWYAOYwABiSJgdg4VGswAFnABOcGFoi+kUwAaGAB3H2AtMBgocK0AaxiPGG8oTE9ogDctWkwfHThgWi1PLShTcBgqVBgdEHMrUGRTWi8YYA9geIgAOhhlVTIQGHN2vx9DX2juNHbCOxg2MBBYCDhYaqSfEzaAWgA+GAQ4KP8oNzKYVBB0mCRci1HTCDAAclgLessY4bs4By2cyEdgkYQiUV8tFoIFCKXW6TADRgHEy9R0HCCAyq2BG0Uia0BO08MDWUDOyRuOBxoGBpB+JJAx3aJigjJiqCQcBC4TG0zABhAnmAPlSCKRHBpzgAoqR-mZwBwelisWYCjBlkQAFzqJLmRKmKCvfwIQURVoQthRPQGTBgYDlcA5AD8oNZRwSPnOPjcIBA3VqXys5zK3PB0SQnhAVByNRyEF+kHSPlMCAQ2C0VBaBpqHm8TpgBYGsikJCQgtgaE5MHQYAACiU1gAxMAAHgAKhp+E47CE21gqQJ5nSmJW4JMZrwB92RJQxIcmJbAtqAN5A5zajtgLtD2AAXxgoIYhz7fHwO-gsocZw5Y6ME-729p5FndBg+dRpj0K+UBbXdhl9jymA2r1p45Q5O2D5nk+hyyLIMC1pG0ZULQNQ8hAPqYLQeg7MilzmtA+hgD48RwKgHD6MS8bHOcSLmNAJx6JMoHgbQTpSLuADcMgKEoKgwDKWjIK0MAAIzagAcsMkoLM8JLrCEGrqnAcB6G6-wCkKIrwhkSIyXSfyQBUkBFlINKEUQ0DidWdYNnAzYtqu3gAI7agASnAzl5NAu7zosWiBIehzLlxcjwb+MAAHrsXIihYoJwk+AATNqUqeJGnghPpsChH46orHCaQZKpSoqMW5kVnA0ApTZoFNq2Tmee5nneVAu4hKuwDpN4QgAKprJ4ag6NqYCYNQbS+Yw-mBYwwWhXBEVRTFvHxcQQn3D4ADM2rZLQn6mRVMRVVA221XZDmNa5MAeV5x3tTAnXdf8UD9V4Q0jWNVATX5i6mEFD0-gWooZADi2-tlAFysZ35g2DXXpc9r2DcNYkAAyA4tu4Y1j83hb+0VSEAA)

### Type Inference

we can infer the return type of `onParse` if it extends `context`, and then change the `InputContext` of `onValidate` to be `ParseContextExtensions & TInputContext`.

This way we can enforce that a plugin actually populates all keys defined in `OutputContext`.

### Core Indicators

We can also use this `hook(readonly input) -> output` to allow plugins to return "indictators" (or, actual values) to the core, and effet how Envelop manages the flow.

Here's an example for short-circuit `onParse` and skip validations:

```ts
{
onParse(api) {
const result = parse(api.source);
return {
parseResult: result, // set the result
shortCircuit: true, // skip all other `onParse` functions,
skipValidatatePhase: true // relevanat for cache plugins
};
}
}
```

### Immutability?

This way we can implement immutability for the context building (so every hook call is similar to `immer` flow, where you return the modifications, and set it in a immutable way)

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by locating the current hook signatures and the onParse and onValidate entry points. Compare how context is passed between hooks with the proposed input/output types, inferred context extensions, and core indicators. Done means the hook API and context flow support the described type checks and returned control values across the relevant hooks.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.