@schema-hub/zod-graphql-client 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/package.json +33 -0
- package/readme.md +186 -0
- package/zod-graphql-client/client.d.ts +27 -0
- package/zod-graphql-client/client.d.ts.map +1 -0
- package/zod-graphql-client/client.js +149 -0
- package/zod-graphql-client/client.js.map +1 -0
- package/zod-graphql-client/entry-point.d.ts +13 -0
- package/zod-graphql-client/entry-point.d.ts.map +1 -0
- package/zod-graphql-client/entry-point.js +11 -0
- package/zod-graphql-client/entry-point.js.map +1 -0
- package/zod-graphql-client/graphql-error.js +51 -0
- package/zod-graphql-client/graphql-error.js.map +1 -0
- package/zod-graphql-client/graphql-response.js +35 -0
- package/zod-graphql-client/graphql-response.js.map +1 -0
- package/zod-graphql-client/query-error.d.ts +30 -0
- package/zod-graphql-client/query-error.d.ts.map +1 -0
- package/zod-graphql-client/query-error.js +11 -0
- package/zod-graphql-client/query-error.js.map +1 -0
- package/zod-graphql-client/query-result.d.ts +17 -0
- package/zod-graphql-client/query-result.d.ts.map +1 -0
- package/zod-graphql-client/variables.d.ts +9 -0
- package/zod-graphql-client/variables.d.ts.map +1 -0
- package/zod-graphql-client/variables.js +15 -0
- package/zod-graphql-client/variables.js.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2024]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Mathias Schreck <schreck.mathias@gmail.com>",
|
|
3
|
+
"dependencies": {
|
|
4
|
+
"@schema-hub/zod-error-formatter": "0.0.5",
|
|
5
|
+
"@schema-hub/zod-graphql-query-builder": "0.0.2",
|
|
6
|
+
"ky": "1.2.3"
|
|
7
|
+
},
|
|
8
|
+
"description": "A lightweight and type-safe zod-based GraphQL client",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": "^20"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"graphql",
|
|
14
|
+
"graphql-builder",
|
|
15
|
+
"graphql-client",
|
|
16
|
+
"graphql-query",
|
|
17
|
+
"zod",
|
|
18
|
+
"zod-graphql"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"main": "zod-graphql-client/entry-point.js",
|
|
22
|
+
"name": "@schema-hub/zod-graphql-client",
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"zod": "3.22.4"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+ssh://git@github.com/enormora/schema-hub.git"
|
|
29
|
+
},
|
|
30
|
+
"type": "module",
|
|
31
|
+
"types": "zod-graphql-client/entry-point.d.ts",
|
|
32
|
+
"version": "0.0.1"
|
|
33
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# zod-graphql-client
|
|
2
|
+
|
|
3
|
+
A lightweight and type-safe GraphQL client. It utilizes [`zod`](https://github.com/colinhacks/zod) schemas to define GraphQL queries, providing developers with a single source of truth for their queries and enabling strict runtime validation.
|
|
4
|
+
|
|
5
|
+
## Key Benefits
|
|
6
|
+
|
|
7
|
+
- **Type Safety**: Define GraphQL queries using `zod` schemas, ensuring type safety and preventing hard-to-debug errors.
|
|
8
|
+
- **Single Source of Truth**: Keep your schema and queries in sync by using `zod` schemas for both runtime validation and query definition.
|
|
9
|
+
- **Ease of Use**: Simplify the process of sending GraphQL queries with a clean and intuitive API.
|
|
10
|
+
- **Error Handling**: Handle network errors, server errors, and response validation errors gracefully, providing detailed error messages for easy debugging.
|
|
11
|
+
|
|
12
|
+
## Example
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { createGraphqlClient } from '@schema-hub/zod-graphql-client';
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
|
|
18
|
+
// Create a GraphQL client
|
|
19
|
+
const client = createGraphqlClient({ endpoint: 'https://example.com/graphql' });
|
|
20
|
+
|
|
21
|
+
// Define a Zod schema for the GraphQL query
|
|
22
|
+
const querySchema = z
|
|
23
|
+
.object({
|
|
24
|
+
foo: z.string()
|
|
25
|
+
})
|
|
26
|
+
.strict();
|
|
27
|
+
|
|
28
|
+
// Send a GraphQL query using the client
|
|
29
|
+
const result = await client.query(querySchema);
|
|
30
|
+
|
|
31
|
+
// Output the result
|
|
32
|
+
console.log(result);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install @schema-hub/zod-graphql-client
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Creating a Client
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { createGraphqlClient } from '@schema-hub/zod-graphql-client';
|
|
47
|
+
|
|
48
|
+
const client = createGraphqlClient({
|
|
49
|
+
endpoint: 'https://example.com/graphql'
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Options
|
|
54
|
+
|
|
55
|
+
- `endpoint` (required): The full URL of the GraphQL API endpoint. This is where the client will send its GraphQL requests.
|
|
56
|
+
|
|
57
|
+
You can further customize the client by providing additional options:
|
|
58
|
+
|
|
59
|
+
- `headers` (optional): A key-value map of additional headers that should be sent with every request. This can be useful for passing authentication tokens or other metadata to the server.
|
|
60
|
+
- `timeout` (optional): The request timeout in milliseconds. This determines how long the client will wait for a response before considering the request failed. If not specified, a default timeout of 10 seconds (10,000 milliseconds) will be used.
|
|
61
|
+
- `fetch` (optional): Allows you to inject a custom `fetch` function instead of using the global `fetch`. This can be useful in environments where the global `fetch` function is not available, or if you need to customize the behavior of the HTTP requests.
|
|
62
|
+
|
|
63
|
+
### Sending a Query
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { createGraphqlClient, graphqlFieldOptions, variablePlaceholder } from '@schema-hub/zod-graphql-client';
|
|
67
|
+
import { z } from 'zod';
|
|
68
|
+
|
|
69
|
+
// Define your query schema using Zod
|
|
70
|
+
const schema = z
|
|
71
|
+
.object({
|
|
72
|
+
// Provide graphql-specific metadata to your zod schema
|
|
73
|
+
foo: graphqlFieldOptions(z.string(), {
|
|
74
|
+
parameters: {
|
|
75
|
+
bar: variablePlaceholder('$bar')
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
.strict();
|
|
80
|
+
|
|
81
|
+
// Send the query using the client
|
|
82
|
+
const client = createGraphqlClient({ endpoint: 'https://example.com/graphql' });
|
|
83
|
+
const result = await client.query(schema, {
|
|
84
|
+
queryName: 'YourQueryName', // Optional query name
|
|
85
|
+
variables: {
|
|
86
|
+
bar: {
|
|
87
|
+
type: 'String!',
|
|
88
|
+
value: 'the-actual-value-for-bar'
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
console.log(result);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### Options
|
|
97
|
+
|
|
98
|
+
- `queryName` (optional): The name of the query. This is useful for debugging and introspection purposes.
|
|
99
|
+
- `variables` (optional): A record of all variable values and types that should be included in the query. This allows you to parameterize your queries and provide dynamic values at runtime.
|
|
100
|
+
- `headers` (optional): A key-value map of additional headers that should be sent with the request. These headers will be merged with any headers specified when creating the client.
|
|
101
|
+
- `timeout` (optional): The request timeout in milliseconds. This determines how long the client will wait for a response before considering the request failed. If not specified, the default timeout specified when creating the client will be used.
|
|
102
|
+
|
|
103
|
+
Adjust these options according to your specific requirements and the needs of your GraphQL API.
|
|
104
|
+
|
|
105
|
+
Adding a section to elaborate on the return value of the `query()` method would be beneficial under the "Sending a Query" section. This would provide users with a clear understanding of what to expect when making a query and how to handle the response.
|
|
106
|
+
|
|
107
|
+
Here's a suggestion for the content of this section:
|
|
108
|
+
|
|
109
|
+
### Query Result
|
|
110
|
+
|
|
111
|
+
When you send a query using the `query()` method of the GraphQL client, you receive a `QueryResult` object representing the outcome of the query. This object contains information about whether the query was successful and, if so, the data returned by the GraphQL server.
|
|
112
|
+
|
|
113
|
+
The `QueryResult` object has the following structure:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
type FailureQueryResult = {
|
|
117
|
+
success: false;
|
|
118
|
+
errorDetails: QueryErrorDetails;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
type SuccessQueryResult<Schema extends QuerySchema> = {
|
|
122
|
+
success: true;
|
|
123
|
+
data: z.infer<Schema>;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
type QueryResult<Schema extends QuerySchema> = FailureQueryResult | SuccessQueryResult<Schema>;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- If the query was successful, the `success` property will be `true`, and the `data` property will contain the response data, inferred based on the provided Zod schema.
|
|
130
|
+
|
|
131
|
+
- If the query failed, the `success` property will be `false`, and the `errorDetails` property will contain information about the error encountered during the query. This includes details such as the error type, status code (if applicable), and error message.
|
|
132
|
+
|
|
133
|
+
Here's how you can handle the query result:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
const result = await client.query(schema, options);
|
|
137
|
+
|
|
138
|
+
if (result.success) {
|
|
139
|
+
// Query was successful, handle the response data
|
|
140
|
+
console.log(result.data);
|
|
141
|
+
} else {
|
|
142
|
+
// Query failed, handle the error
|
|
143
|
+
console.error('Query failed:', result.errorDetails);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Certainly! Here's the updated explanation along with the modifications to the error types section:
|
|
148
|
+
|
|
149
|
+
#### Error Types
|
|
150
|
+
|
|
151
|
+
Errors distinguishable based on the `type` property within the `errorDetails` object. The possible error types are:
|
|
152
|
+
|
|
153
|
+
- **`network`**: Occurs when there are issues with the network connection, such as timeouts or unexpected network problems.
|
|
154
|
+
- **`server`**: Indicates an error response from the server, typically due to unexpected status codes like `500`.
|
|
155
|
+
- **`graphql`**: Indicates errors in the GraphQL response, such as invalid query syntax or execution errors on the server.
|
|
156
|
+
- **`validation`**: Occurs when the data in the query response does not match the given `zod` schema, indicating a validation failure.
|
|
157
|
+
- **`unknown`**: Represents any other unexpected errors that do not fall into the above categories.
|
|
158
|
+
|
|
159
|
+
#### `queryOrThrow()`
|
|
160
|
+
|
|
161
|
+
The `queryOrThrow()` function behaves similarly to `query()`, but with one key difference in its return type. If the query execution is successful, the function returns the query result data directly. However, if an error occurs during the query execution, it throws an instance of `GraphqlQueryError`. This custom error contains detailed information about the encountered error in its `details` property, which aligns with the `errorDetails` structure returned by the `query()` function.
|
|
162
|
+
|
|
163
|
+
### Re-exported Functions
|
|
164
|
+
|
|
165
|
+
Some functions from `@schema-hub/zod-graphql-query-builder` are re-exported for convenience:
|
|
166
|
+
|
|
167
|
+
- `graphqlFieldOptions()`
|
|
168
|
+
- `enumValue()`
|
|
169
|
+
- `variablePlaceholder()`
|
|
170
|
+
|
|
171
|
+
For more details, see the [`@schema-hub/zod-graphql-query-builder` documentation](../zod-graphql-query-builder/readme.md).
|
|
172
|
+
|
|
173
|
+
### Testing
|
|
174
|
+
|
|
175
|
+
If you're writing tests for your code, consider using the `@schema-hub/zod-graphql-fake-client` package for testing. It provides a fake GraphQL client that can be used in place of the real client. This allows you to control the behavior of the client and inspect the queries sent without making actual network requests.
|
|
176
|
+
|
|
177
|
+
Here's a quick example of how you can use it:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { createFakeGraphqlClient } from '@schema-hub/zod-graphql-fake-client';
|
|
181
|
+
|
|
182
|
+
// Create a fake GraphQL client for testing
|
|
183
|
+
const client = createFakeGraphqlClient();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Replace the real client with the fake client in your test environment to isolate your tests and ensure predictable behavior.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type KyInstance } from 'ky';
|
|
2
|
+
import type { TypeOf } from 'zod';
|
|
3
|
+
import { type QuerySchema } from '@schema-hub/zod-graphql-query-builder/zod-graphql-query-builder/entry-point.d.ts';
|
|
4
|
+
import type { QueryResult } from './query-result.js';
|
|
5
|
+
import { type Variables } from './variables.js';
|
|
6
|
+
export type QueryOptions = {
|
|
7
|
+
queryName?: string;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
headers?: Record<string, string | undefined>;
|
|
10
|
+
variables?: Variables;
|
|
11
|
+
};
|
|
12
|
+
export type ClientOptions = {
|
|
13
|
+
endpoint: string;
|
|
14
|
+
headers?: Record<string, string | undefined>;
|
|
15
|
+
timeout?: number;
|
|
16
|
+
};
|
|
17
|
+
export type GraphqlClient = {
|
|
18
|
+
readonly query: <Schema extends QuerySchema>(schema: Schema, options?: QueryOptions) => Promise<QueryResult<Schema>>;
|
|
19
|
+
readonly queryOrThrow: <Schema extends QuerySchema>(schema: Schema, options?: QueryOptions) => Promise<TypeOf<Schema>>;
|
|
20
|
+
};
|
|
21
|
+
type CreateClientFn = (clientOptions: ClientOptions) => GraphqlClient;
|
|
22
|
+
export type CreateClientDependencies = {
|
|
23
|
+
ky: KyInstance;
|
|
24
|
+
};
|
|
25
|
+
export declare function createClientFactory(dependencies: CreateClientDependencies): CreateClientFn;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../source/zod-graphql-client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAkD,MAAM,IAAI,CAAC;AACrF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAElC,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAGlG,OAAO,KAAK,EAAsB,WAAW,EAAsB,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEnG,MAAM,MAAM,YAAY,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,SAAS,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,SAAS,WAAW,EACvC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,YAAY,KACrB,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,SAAS,WAAW,EAC9C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,YAAY,KACrB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF,KAAK,cAAc,GAAG,CAAC,aAAa,EAAE,aAAa,KAAK,aAAa,CAAC;AAEtE,MAAM,MAAM,wBAAwB,GAAG;IACnC,EAAE,EAAE,UAAU,CAAC;CAClB,CAAC;AAiCF,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,wBAAwB,GAAG,cAAc,CAwI1F"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { TimeoutError } from 'ky';
|
|
2
|
+
import { safeParse } from '@schema-hub/zod-error-formatter/zod-error-formatter/formatter.js';
|
|
3
|
+
import { buildGraphqlQuery } from '@schema-hub/zod-graphql-query-builder/zod-graphql-query-builder/entry-point.js';
|
|
4
|
+
import { parseGraphqlResponse } from './graphql-response.js';
|
|
5
|
+
import { GraphqlQueryError } from './query-error.js';
|
|
6
|
+
import { extractVariableDefinitions, extractVariableValues } from './variables.js';
|
|
7
|
+
const defaultRequestTimeout = 10_000;
|
|
8
|
+
const successResponseStatusCode = 200;
|
|
9
|
+
function mapUnknownNetworkErrorToFailureResult(error, timeout) {
|
|
10
|
+
if (error instanceof TimeoutError) {
|
|
11
|
+
return {
|
|
12
|
+
success: false,
|
|
13
|
+
errorDetails: {
|
|
14
|
+
type: 'network',
|
|
15
|
+
message: `Request timed out after ${timeout}ms`
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
return {
|
|
21
|
+
success: false,
|
|
22
|
+
errorDetails: {
|
|
23
|
+
type: 'network',
|
|
24
|
+
message: error.message
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
success: false,
|
|
30
|
+
errorDetails: {
|
|
31
|
+
type: 'unknown',
|
|
32
|
+
message: 'Unknown error occurred'
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function createClientFactory(dependencies) {
|
|
37
|
+
const { ky } = dependencies;
|
|
38
|
+
return function createClient(clientOptions) {
|
|
39
|
+
function buildBaseRequestOptions(queryOptions) {
|
|
40
|
+
const timeout = queryOptions.timeout ?? clientOptions.timeout ?? defaultRequestTimeout;
|
|
41
|
+
return {
|
|
42
|
+
headers: {
|
|
43
|
+
...clientOptions.headers,
|
|
44
|
+
...queryOptions.headers
|
|
45
|
+
},
|
|
46
|
+
timeout,
|
|
47
|
+
throwHttpErrors: false,
|
|
48
|
+
retry: 0
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function prepareRequestPayload(schema, options) {
|
|
52
|
+
const { variables = {} } = options;
|
|
53
|
+
const variableDefinitions = extractVariableDefinitions(variables);
|
|
54
|
+
const variableValues = extractVariableValues(variables);
|
|
55
|
+
const serializedQuery = buildGraphqlQuery(schema, {
|
|
56
|
+
queryName: options.queryName,
|
|
57
|
+
variableDefinitions
|
|
58
|
+
});
|
|
59
|
+
return {
|
|
60
|
+
query: serializedQuery,
|
|
61
|
+
variables: variableValues,
|
|
62
|
+
operationName: options.queryName
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async function parseServerResponse(response) {
|
|
66
|
+
try {
|
|
67
|
+
const responseBody = await response.json();
|
|
68
|
+
return {
|
|
69
|
+
success: true,
|
|
70
|
+
data: responseBody
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
const causedByMessage = error instanceof Error ? `: ${error.message}` : '';
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
errorDetails: {
|
|
78
|
+
type: 'server',
|
|
79
|
+
statusCode: response.status,
|
|
80
|
+
message: `Failed to parse response body${causedByMessage}`
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function parseResponseData(schema, data) {
|
|
86
|
+
const dataParseResult = safeParse(schema, data);
|
|
87
|
+
if (dataParseResult.success) {
|
|
88
|
+
return {
|
|
89
|
+
success: true,
|
|
90
|
+
data: dataParseResult.data
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
errorDetails: {
|
|
96
|
+
type: 'validation',
|
|
97
|
+
message: 'GraphQL response data doesn’t match the expected schema',
|
|
98
|
+
issues: dataParseResult.error.issues
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function fetchGraphqlEndpoint(options, payload) {
|
|
103
|
+
const baseRequestOptions = buildBaseRequestOptions(options);
|
|
104
|
+
try {
|
|
105
|
+
const response = await ky.post(clientOptions.endpoint, {
|
|
106
|
+
...baseRequestOptions,
|
|
107
|
+
json: payload
|
|
108
|
+
});
|
|
109
|
+
if (response.status !== successResponseStatusCode) {
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
errorDetails: {
|
|
113
|
+
type: 'server',
|
|
114
|
+
statusCode: response.status,
|
|
115
|
+
message: `Received response with unexpected status ${response.status} code from GraphQL server`
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return parseServerResponse(response);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
return mapUnknownNetworkErrorToFailureResult(error, baseRequestOptions.timeout);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function query(schema, options = {}) {
|
|
126
|
+
const payload = prepareRequestPayload(schema, options);
|
|
127
|
+
const serverResponseParseResult = await fetchGraphqlEndpoint(options, payload);
|
|
128
|
+
if (serverResponseParseResult.success) {
|
|
129
|
+
const graphqlResponseParseResult = parseGraphqlResponse(serverResponseParseResult.data);
|
|
130
|
+
if (graphqlResponseParseResult.success) {
|
|
131
|
+
return parseResponseData(schema, graphqlResponseParseResult.data);
|
|
132
|
+
}
|
|
133
|
+
return graphqlResponseParseResult;
|
|
134
|
+
}
|
|
135
|
+
return serverResponseParseResult;
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
query,
|
|
139
|
+
async queryOrThrow(schema, options) {
|
|
140
|
+
const result = await query(schema, options);
|
|
141
|
+
if (result.success) {
|
|
142
|
+
return result.data;
|
|
143
|
+
}
|
|
144
|
+
throw new GraphqlQueryError(result.errorDetails);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../source/zod-graphql-client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,YAAY,EAAE,MAAM,IAAI,CAAC;AAErF,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAoB,MAAM,6CAA6C,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAkB,MAAM,gBAAgB,CAAC;AAgCnG,MAAM,qBAAqB,GAAG,MAAM,CAAC;AACrC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAEtC,SAAS,qCAAqC,CAAC,KAAc,EAAE,OAAe;IAC1E,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QAChC,OAAO;YACH,OAAO,EAAE,KAAK;YACd,YAAY,EAAE;gBACV,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,2BAA2B,OAAO,IAAI;aAClD;SACJ,CAAC;IACN,CAAC;IACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO;YACH,OAAO,EAAE,KAAK;YACd,YAAY,EAAE;gBACV,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,KAAK,CAAC,OAAO;aACzB;SACJ,CAAC;IACN,CAAC;IACD,OAAO;QACH,OAAO,EAAE,KAAK;QACd,YAAY,EAAE;YACV,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,wBAAwB;SACpC;KACJ,CAAC;AACN,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAsC;IACtE,MAAM,EAAE,EAAE,EAAE,GAAG,YAAY,CAAC;IAE5B,OAAO,SAAS,YAAY,CAAC,aAAa;QACtC,SAAS,uBAAuB,CAAC,YAA0B;YACvD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,IAAI,qBAAqB,CAAC;YACvF,OAAO;gBACH,OAAO,EAAE;oBACL,GAAG,aAAa,CAAC,OAAO;oBACxB,GAAG,YAAY,CAAC,OAAO;iBAC1B;gBACD,OAAO;gBACP,eAAe,EAAE,KAAK;gBACtB,KAAK,EAAE,CAAC;aACX,CAAC;QACN,CAAC;QAED,SAAS,qBAAqB,CAA6B,MAAc,EAAE,OAAqB;YAC5F,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;YACnC,MAAM,mBAAmB,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;YAClE,MAAM,cAAc,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;YAExD,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,EAAE;gBAC9C,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,mBAAmB;aACtB,CAAC,CAAC;YAEH,OAAO;gBACH,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,cAAc;gBACzB,aAAa,EAAE,OAAO,CAAC,SAAS;aACnC,CAAC;QACN,CAAC;QAED,KAAK,UAAU,mBAAmB,CAAC,QAAkB;YACjD,IAAI,CAAC;gBACD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAa,CAAC;gBACtD,OAAO;oBACH,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,YAAY;iBACrB,CAAC;YACN,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACtB,MAAM,eAAe,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAE3E,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE,QAAQ,CAAC,MAAM;wBAC3B,OAAO,EAAE,gCAAgC,eAAe,EAAE;qBAC7D;iBACJ,CAAC;YACN,CAAC;QACL,CAAC;QAED,SAAS,iBAAiB,CAA6B,MAAc,EAAE,IAAa;YAChF,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAEhD,IAAI,eAAe,CAAC,OAAO,EAAE,CAAC;gBAC1B,OAAO;oBACH,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,eAAe,CAAC,IAAsB;iBAC/C,CAAC;YACN,CAAC;YAED,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE;oBACV,IAAI,EAAE,YAAY;oBAClB,OAAO,EAAE,yDAAyD;oBAClE,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,MAAM;iBACvC;aACJ,CAAC;QACN,CAAC;QAED,KAAK,UAAU,oBAAoB,CAC/B,OAAqB,EACrB,OAAgB;YAEhB,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAC5D,IAAI,CAAC;gBACD,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;oBACnD,GAAG,kBAAkB;oBACrB,IAAI,EAAE,OAAO;iBAChB,CAAC,CAAC;gBAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,yBAAyB,EAAE,CAAC;oBAChD,OAAO;wBACH,OAAO,EAAE,KAAK;wBACd,YAAY,EAAE;4BACV,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE,QAAQ,CAAC,MAAM;4BAC3B,OAAO,EACH,4CAA4C,QAAQ,CAAC,MAAM,2BAA2B;yBAC7F;qBACJ,CAAC;gBACN,CAAC;gBACD,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACtB,OAAO,qCAAqC,CAAC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACpF,CAAC;QACL,CAAC;QAED,KAAK,UAAU,KAAK,CAChB,MAAc,EACd,UAAwB,EAAE;YAE1B,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAEvD,MAAM,yBAAyB,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAE/E,IAAI,yBAAyB,CAAC,OAAO,EAAE,CAAC;gBACpC,MAAM,0BAA0B,GAAG,oBAAoB,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;gBAExF,IAAI,0BAA0B,CAAC,OAAO,EAAE,CAAC;oBACrC,OAAO,iBAAiB,CAAC,MAAM,EAAE,0BAA0B,CAAC,IAAI,CAAC,CAAC;gBACtE,CAAC;gBACD,OAAO,0BAA0B,CAAC;YACtC,CAAC;YAED,OAAO,yBAAyB,CAAC;QACrC,CAAC;QAED,OAAO;YACH,KAAK;YAEL,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO;gBAC9B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC5C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjB,OAAO,MAAM,CAAC,IAAI,CAAC;gBACvB,CAAC;gBAED,MAAM,IAAI,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACrD,CAAC;SACJ,CAAC;IACN,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Options as KyOptions } from 'ky';
|
|
2
|
+
import { type ClientOptions, type GraphqlClient } from './client.js';
|
|
3
|
+
export type GraphqlClientOptions = ClientOptions & {
|
|
4
|
+
readonly fetch?: KyOptions['fetch'];
|
|
5
|
+
};
|
|
6
|
+
export declare function createGraphqlClient(clientOptions: GraphqlClientOptions): GraphqlClient;
|
|
7
|
+
export type { QuerySchema } from '@schema-hub/zod-graphql-query-builder/zod-graphql-query-builder/entry-point.d.ts';
|
|
8
|
+
export { enumValue, graphqlFieldOptions, variablePlaceholder } from '@schema-hub/zod-graphql-query-builder/zod-graphql-query-builder/entry-point.d.ts';
|
|
9
|
+
export type { GraphqlClient } from './client.js';
|
|
10
|
+
export type { QueryErrorDetails } from './query-error.js';
|
|
11
|
+
export { GraphqlQueryError } from './query-error.js';
|
|
12
|
+
export type { QueryResult } from './query-result.js';
|
|
13
|
+
//# sourceMappingURL=entry-point.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-point.d.ts","sourceRoot":"","sources":["../../../../source/zod-graphql-client/entry-point.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,OAAO,IAAI,SAAS,EAAE,MAAM,IAAI,CAAC;AACvD,OAAO,EAAE,KAAK,aAAa,EAAuB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE1F,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;CACvC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,oBAAoB,GAAG,aAAa,CAMtF;AAED,YAAY,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClH,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import baseKy, {} from 'ky';
|
|
2
|
+
import { createClientFactory } from './client.js';
|
|
3
|
+
export function createGraphqlClient(clientOptions) {
|
|
4
|
+
const { fetch: fetchFn, ...remainingOptions } = clientOptions;
|
|
5
|
+
const ky = fetchFn === undefined ? baseKy : baseKy.create({ fetch: fetchFn });
|
|
6
|
+
const createClient = createClientFactory({ ky });
|
|
7
|
+
return createClient(remainingOptions);
|
|
8
|
+
}
|
|
9
|
+
export { enumValue, graphqlFieldOptions, variablePlaceholder } from '@schema-hub/zod-graphql-query-builder/zod-graphql-query-builder/entry-point.js';
|
|
10
|
+
export { GraphqlQueryError } from './query-error.js';
|
|
11
|
+
//# sourceMappingURL=entry-point.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-point.js","sourceRoot":"","sources":["../../../../source/zod-graphql-client/entry-point.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAA6B,MAAM,IAAI,CAAC;AACvD,OAAO,EAAsB,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AAM1F,MAAM,UAAU,mBAAmB,CAAC,aAAmC;IACnE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,EAAE,GAAG,aAAa,CAAC;IAC9D,MAAM,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAE9E,MAAM,YAAY,GAAG,mBAAmB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,OAAO,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAC1C,CAAC;AAGD,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAGlH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { mapTuple } from '@schema-hub/zod-error-formatter/tuple/non-empty-array.js';
|
|
3
|
+
const locationSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
line: z.number().int().positive(),
|
|
6
|
+
column: z.number().int().positive()
|
|
7
|
+
})
|
|
8
|
+
.strict();
|
|
9
|
+
const pathSegmentSchema = z.union([z.string(), z.number()]);
|
|
10
|
+
export const graphqlErrorSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
message: z.string(),
|
|
13
|
+
locations: z.array(locationSchema).optional(),
|
|
14
|
+
path: z.array(pathSegmentSchema).optional()
|
|
15
|
+
})
|
|
16
|
+
.strip();
|
|
17
|
+
function formatLocations(locations) {
|
|
18
|
+
if (locations === undefined) {
|
|
19
|
+
return '';
|
|
20
|
+
}
|
|
21
|
+
const [firstLocation] = locations;
|
|
22
|
+
if (firstLocation === undefined) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
return `${firstLocation.line}:${firstLocation.column}`;
|
|
26
|
+
}
|
|
27
|
+
function formatPath(path) {
|
|
28
|
+
return path === undefined ? '' : path.join('.');
|
|
29
|
+
}
|
|
30
|
+
function formatPrefix(error) {
|
|
31
|
+
const formattedPath = formatPath(error.path);
|
|
32
|
+
const formattedLocation = formatLocations(error.locations);
|
|
33
|
+
if (formattedPath.length > 0 && formattedLocation.length > 0) {
|
|
34
|
+
return `Error at ${formattedPath}:${formattedLocation} - `;
|
|
35
|
+
}
|
|
36
|
+
if (formattedPath.length > 0) {
|
|
37
|
+
return `Error at ${formattedPath} - `;
|
|
38
|
+
}
|
|
39
|
+
if (formattedLocation.length > 0) {
|
|
40
|
+
return `Error at ${formattedLocation} - `;
|
|
41
|
+
}
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
function formatGraphqlError(error) {
|
|
45
|
+
const prefix = formatPrefix(error);
|
|
46
|
+
return `${prefix}${error.message}`;
|
|
47
|
+
}
|
|
48
|
+
export function formatAllErrors(errors) {
|
|
49
|
+
return mapTuple(errors, formatGraphqlError);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=graphql-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql-error.js","sourceRoot":"","sources":["../../../../source/zod-graphql-client/graphql-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAsB,MAAM,6BAA6B,CAAC;AAE3E,MAAM,cAAc,GAAG,CAAC;KACnB,MAAM,CAAC;IACJ,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CACtC,CAAC;KACD,MAAM,EAAE,CAAC;AAId,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAI5D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACJ,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE;IAC7C,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;CAC9C,CAAC;KACD,KAAK,EAAE,CAAC;AAIb,SAAS,eAAe,CAAC,SAAkC;IACvD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;IAClC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACd,CAAC;IACD,OAAO,GAAG,aAAa,CAAC,IAAI,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,UAAU,CAAC,IAAgC;IAChD,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,YAAY,CAAC,KAAmB;IACrC,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAE3D,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,OAAO,YAAY,aAAa,IAAI,iBAAiB,KAAK,CAAC;IAC/D,CAAC;IACD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,YAAY,aAAa,KAAK,CAAC;IAC1C,CAAC;IACD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,YAAY,iBAAiB,KAAK,CAAC;IAC9C,CAAC;IACD,OAAO,EAAE,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAmB;IAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAC3B,MAAmC;IAEnC,OAAO,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { isNonEmptyArray } from '@schema-hub/zod-error-formatter/tuple/non-empty-array.js';
|
|
3
|
+
import { safeParse } from '@schema-hub/zod-error-formatter/zod-error-formatter/formatter.js';
|
|
4
|
+
import { formatAllErrors, graphqlErrorSchema } from './graphql-error.js';
|
|
5
|
+
const graphqlResponseSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
data: z.unknown(),
|
|
8
|
+
errors: z.array(graphqlErrorSchema).optional()
|
|
9
|
+
})
|
|
10
|
+
.strip();
|
|
11
|
+
export function parseGraphqlResponse(responseBody) {
|
|
12
|
+
const graphqlResponseParseResult = safeParse(graphqlResponseSchema, responseBody);
|
|
13
|
+
if (graphqlResponseParseResult.success) {
|
|
14
|
+
const { errors, data } = graphqlResponseParseResult.data;
|
|
15
|
+
if (errors !== undefined && isNonEmptyArray(errors)) {
|
|
16
|
+
return {
|
|
17
|
+
success: false,
|
|
18
|
+
errorDetails: {
|
|
19
|
+
type: 'graphql',
|
|
20
|
+
message: 'GraphQL response contains errors',
|
|
21
|
+
errors: formatAllErrors(errors)
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return { success: true, data };
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
success: false,
|
|
29
|
+
errorDetails: {
|
|
30
|
+
type: 'unknown',
|
|
31
|
+
message: 'GraphQL server responded with an incorrect data structure'
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=graphql-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql-response.js","sourceRoot":"","sources":["../../../../source/zod-graphql-client/graphql-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGzE,MAAM,qBAAqB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACJ,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;CACjD,CAAC;KACD,KAAK,EAAE,CAAC;AAEb,MAAM,UAAU,oBAAoB,CAAC,YAAqB;IACtD,MAAM,0BAA0B,GAAG,SAAS,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;IAElF,IAAI,0BAA0B,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,0BAA0B,CAAC,IAAI,CAAC;QAEzD,IAAI,MAAM,KAAK,SAAS,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE;oBACV,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,kCAAkC;oBAC3C,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;iBAClC;aACJ,CAAC;QACN,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,OAAO;QACH,OAAO,EAAE,KAAK;QACd,YAAY,EAAE;YACV,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,2DAA2D;SACvE;KACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { NonEmptyArray } from '@schema-hub/zod-error-formatter/tuple/non-empty-array.d.ts';
|
|
2
|
+
type BaseError = {
|
|
3
|
+
message: string;
|
|
4
|
+
};
|
|
5
|
+
type GraphqlResponseError = BaseError & {
|
|
6
|
+
type: 'graphql';
|
|
7
|
+
errors: NonEmptyArray<string>;
|
|
8
|
+
};
|
|
9
|
+
type ServerError = BaseError & {
|
|
10
|
+
type: 'server';
|
|
11
|
+
statusCode: number;
|
|
12
|
+
};
|
|
13
|
+
type ValidationError = BaseError & {
|
|
14
|
+
type: 'validation';
|
|
15
|
+
issues: NonEmptyArray<string>;
|
|
16
|
+
};
|
|
17
|
+
type NetworkError = BaseError & {
|
|
18
|
+
type: 'network';
|
|
19
|
+
};
|
|
20
|
+
type UnknownError = BaseError & {
|
|
21
|
+
type: 'unknown';
|
|
22
|
+
};
|
|
23
|
+
export type QueryErrorDetails = GraphqlResponseError | NetworkError | ServerError | UnknownError | ValidationError;
|
|
24
|
+
export type QueryErrorType = QueryErrorDetails['type'];
|
|
25
|
+
export declare class GraphqlQueryError extends Error {
|
|
26
|
+
readonly details: Omit<QueryErrorDetails, 'message'>;
|
|
27
|
+
constructor(details: QueryErrorDetails);
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=query-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-error.d.ts","sourceRoot":"","sources":["../../../../source/zod-graphql-client/query-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,KAAK,SAAS,GAAG;IACb,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,oBAAoB,GAAG,SAAS,GAAG;IACpC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,KAAK,WAAW,GAAG,SAAS,GAAG;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,eAAe,GAAG,SAAS,GAAG;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,KAAK,YAAY,GAAG,SAAS,GAAG;IAC5B,IAAI,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,KAAK,YAAY,GAAG,SAAS,GAAG;IAC5B,IAAI,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,eAAe,CAAC;AACnH,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAEvD,qBAAa,iBAAkB,SAAQ,KAAK;IAExC,SAAgB,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;gBAEhD,OAAO,EAAE,iBAAiB;CAMzC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class GraphqlQueryError extends Error {
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/ban-types -- no type-fest installed
|
|
3
|
+
details;
|
|
4
|
+
constructor(details) {
|
|
5
|
+
const { message, ...remainingDetails } = details;
|
|
6
|
+
super(message);
|
|
7
|
+
// eslint-disable-next-line functional/no-this-expressions -- sub-classing errors is ok
|
|
8
|
+
this.details = remainingDetails;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=query-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-error.js","sourceRoot":"","sources":["../../../../source/zod-graphql-client/query-error.ts"],"names":[],"mappings":"AAgCA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACxC,kFAAkF;IAClE,OAAO,CAAqC;IAE5D,YAAY,OAA0B;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAC;QACjD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,uFAAuF;QACvF,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC;IACpC,CAAC;CACJ"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TypeOf } from 'zod';
|
|
2
|
+
import type { QuerySchema } from '@schema-hub/zod-graphql-query-builder/zod-graphql-query-builder/entry-point.d.ts';
|
|
3
|
+
import type { QueryErrorDetails } from './query-error.js';
|
|
4
|
+
export type FailureQueryResult = {
|
|
5
|
+
data?: undefined;
|
|
6
|
+
success: false;
|
|
7
|
+
errorDetails: QueryErrorDetails;
|
|
8
|
+
};
|
|
9
|
+
type SuccessQueryResult<Data> = {
|
|
10
|
+
errorDetails?: undefined;
|
|
11
|
+
success: true;
|
|
12
|
+
data: Data;
|
|
13
|
+
};
|
|
14
|
+
export type QueryResultForType<Data> = FailureQueryResult | SuccessQueryResult<Data>;
|
|
15
|
+
export type QueryResult<Schema extends QuerySchema> = QueryResultForType<TypeOf<Schema>>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=query-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-result.d.ts","sourceRoot":"","sources":["../../../../source/zod-graphql-client/query-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,MAAM,kBAAkB,GAAG;IAC7B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;IACf,YAAY,EAAE,iBAAiB,CAAC;CACnC,CAAC;AAEF,KAAK,kBAAkB,CAAC,IAAI,IAAI;IAC5B,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,CAAC,IAAI,IAAI,kBAAkB,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAErF,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,WAAW,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Variable = {
|
|
2
|
+
type: string;
|
|
3
|
+
value: unknown;
|
|
4
|
+
};
|
|
5
|
+
export type Variables = Record<string, Variable>;
|
|
6
|
+
export declare function extractVariableDefinitions(variables: Variables): Record<string, string>;
|
|
7
|
+
export declare function extractVariableValues(variables: Variables): Record<string, unknown>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=variables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../../../source/zod-graphql-client/variables.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEjD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMvF;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMnF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function extractVariableDefinitions(variables) {
|
|
2
|
+
const entries = Object.entries(variables);
|
|
3
|
+
const entriesWithTypeOnly = entries.map(([name, variable]) => {
|
|
4
|
+
return [`$${name}`, variable.type];
|
|
5
|
+
});
|
|
6
|
+
return Object.fromEntries(entriesWithTypeOnly);
|
|
7
|
+
}
|
|
8
|
+
export function extractVariableValues(variables) {
|
|
9
|
+
const entries = Object.entries(variables);
|
|
10
|
+
const entriesWithTypeOnly = entries.map(([name, variable]) => {
|
|
11
|
+
return [name, variable.value];
|
|
12
|
+
});
|
|
13
|
+
return Object.fromEntries(entriesWithTypeOnly);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.js","sourceRoot":"","sources":["../../../../source/zod-graphql-client/variables.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,0BAA0B,CAAC,SAAoB;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAoB,EAAE;QAC3E,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,SAAoB;IACtD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAqB,EAAE;QAC5E,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;AACnD,CAAC"}
|