@vladimirdev635/gql-client 0.0.97 → 0.0.99
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/executor.js +20 -16
- package/package.json +23 -17
- package/parsers/parseBodySubscription.js +8 -14
- package/parsers/parser.js +10 -5
- package/serializers/json.js +2 -2
- package/serializers/multipart.js +10 -8
- package/serializers/tests/json.spec.js +4 -4
- package/serializers/tests/multipart.spec.js +9 -9
- package/types/index.d.ts +2 -2
package/executor.js
CHANGED
|
@@ -32,22 +32,23 @@ export class Executor {
|
|
|
32
32
|
clientContext: this.config.context,
|
|
33
33
|
requestContext,
|
|
34
34
|
operation,
|
|
35
|
-
variables
|
|
35
|
+
variables,
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
let init = await this.config.serializer.serializeRequest({
|
|
39
39
|
clientContext: this.config.context,
|
|
40
40
|
requestContext,
|
|
41
41
|
operation,
|
|
42
|
-
variables
|
|
42
|
+
variables,
|
|
43
43
|
});
|
|
44
|
-
for (const middleware of this.config.middlewares.afterSerialization
|
|
44
|
+
for (const middleware of this.config.middlewares.afterSerialization
|
|
45
|
+
.sync) {
|
|
45
46
|
init = await middleware({
|
|
46
47
|
clientContext: this.config.context,
|
|
47
48
|
requestContext,
|
|
48
49
|
operation,
|
|
49
50
|
variables,
|
|
50
|
-
init
|
|
51
|
+
init,
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
let response = await this.config.fetcher(init);
|
|
@@ -58,14 +59,14 @@ export class Executor {
|
|
|
58
59
|
operation,
|
|
59
60
|
variables,
|
|
60
61
|
init,
|
|
61
|
-
response
|
|
62
|
+
response,
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
65
|
let result = await this.config.parser.parseBodySync({
|
|
65
66
|
clientContext: this.config.context,
|
|
66
67
|
requestContext,
|
|
67
68
|
operation,
|
|
68
|
-
response
|
|
69
|
+
response,
|
|
69
70
|
});
|
|
70
71
|
for (const middleware of this.config.middlewares.afterParsing.sync) {
|
|
71
72
|
result = await middleware({
|
|
@@ -75,7 +76,7 @@ export class Executor {
|
|
|
75
76
|
variables,
|
|
76
77
|
init,
|
|
77
78
|
response,
|
|
78
|
-
result
|
|
79
|
+
result,
|
|
79
80
|
});
|
|
80
81
|
}
|
|
81
82
|
return { result, response };
|
|
@@ -95,28 +96,30 @@ export class Executor {
|
|
|
95
96
|
clientContext: this.config.context,
|
|
96
97
|
requestContext,
|
|
97
98
|
operation,
|
|
98
|
-
variables
|
|
99
|
+
variables,
|
|
99
100
|
});
|
|
100
101
|
}
|
|
101
102
|
let init = await this.config.serializer.serializeRequest({
|
|
102
103
|
clientContext: this.config.context,
|
|
103
104
|
requestContext,
|
|
104
105
|
operation,
|
|
105
|
-
variables
|
|
106
|
+
variables,
|
|
106
107
|
});
|
|
107
|
-
for (const middleware of this.config.middlewares.afterSerialization
|
|
108
|
+
for (const middleware of this.config.middlewares.afterSerialization
|
|
109
|
+
.subscription) {
|
|
108
110
|
init = await middleware({
|
|
109
111
|
clientContext: this.config.context,
|
|
110
112
|
requestContext,
|
|
111
113
|
operation,
|
|
112
114
|
variables,
|
|
113
115
|
init,
|
|
114
|
-
controller
|
|
116
|
+
controller,
|
|
115
117
|
});
|
|
116
118
|
}
|
|
117
119
|
init.signal = controller.signal;
|
|
118
120
|
let response = await this.config.fetcher(init);
|
|
119
|
-
for (const middleware of this.config.middlewares.beforeParsing
|
|
121
|
+
for (const middleware of this.config.middlewares.beforeParsing
|
|
122
|
+
.subscription) {
|
|
120
123
|
response = await middleware({
|
|
121
124
|
clientContext: this.config.context,
|
|
122
125
|
requestContext,
|
|
@@ -124,7 +127,7 @@ export class Executor {
|
|
|
124
127
|
variables,
|
|
125
128
|
init,
|
|
126
129
|
response,
|
|
127
|
-
controller
|
|
130
|
+
controller,
|
|
128
131
|
});
|
|
129
132
|
}
|
|
130
133
|
let result = await this.config.parser.parseBodySubscription({
|
|
@@ -132,9 +135,10 @@ export class Executor {
|
|
|
132
135
|
requestContext,
|
|
133
136
|
operation,
|
|
134
137
|
response,
|
|
135
|
-
controller
|
|
138
|
+
controller,
|
|
136
139
|
});
|
|
137
|
-
for (const middleware of this.config.middlewares.afterParsing
|
|
140
|
+
for (const middleware of this.config.middlewares.afterParsing
|
|
141
|
+
.subscription) {
|
|
138
142
|
result = await middleware({
|
|
139
143
|
clientContext: this.config.context,
|
|
140
144
|
requestContext,
|
|
@@ -143,7 +147,7 @@ export class Executor {
|
|
|
143
147
|
init,
|
|
144
148
|
response,
|
|
145
149
|
result,
|
|
146
|
-
controller
|
|
150
|
+
controller,
|
|
147
151
|
});
|
|
148
152
|
}
|
|
149
153
|
return { result, response };
|
package/package.json
CHANGED
|
@@ -1,37 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vladimirdev635/gql-client",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"types": "./index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"./"
|
|
9
|
-
],
|
|
3
|
+
"version": "0.0.99",
|
|
4
|
+
"description": "",
|
|
5
|
+
"keywords": [],
|
|
10
6
|
"homepage": "https://github.com/Voldemat/graphql-plus-plus#readme",
|
|
7
|
+
"license": "ISC",
|
|
8
|
+
"author": "",
|
|
11
9
|
"repository": {
|
|
12
10
|
"type": "git",
|
|
13
11
|
"url": "git+https://github.com/Voldemat/graphql-plus-plus.git"
|
|
14
12
|
},
|
|
13
|
+
"files": [
|
|
14
|
+
"./"
|
|
15
|
+
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./index.js",
|
|
18
|
+
"types": "./index.d.ts",
|
|
15
19
|
"scripts": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"lint
|
|
20
|
+
"fmt": "oxfmt .",
|
|
21
|
+
"fmt:check": "oxfmt --check .",
|
|
22
|
+
"lint": "oxlint .",
|
|
23
|
+
"lint:fix": "oxlint --fix .",
|
|
24
|
+
"lint:ci": "npm run fmt:check && npm run lint",
|
|
19
25
|
"test": "vitest",
|
|
20
26
|
"build": "tsc && cp package.json ./dist/"
|
|
21
27
|
},
|
|
22
|
-
"keywords": [],
|
|
23
|
-
"author": "",
|
|
24
|
-
"license": "ISC",
|
|
25
|
-
"description": "",
|
|
26
28
|
"devDependencies": {
|
|
27
|
-
"@eslint/compat": "^1.3.0",
|
|
28
29
|
"@types/node": "^24.0.1",
|
|
29
|
-
"@typescript-eslint/eslint-plugin": "^8.34.0",
|
|
30
|
-
"eslint": "^9.28.0",
|
|
31
30
|
"jiti": "^2.4.2",
|
|
31
|
+
"oxfmt": "^0.62.0",
|
|
32
|
+
"oxlint": "^1.77.0",
|
|
33
|
+
"typescript": "<7.0.0",
|
|
32
34
|
"vitest": "^3.2.4"
|
|
33
35
|
},
|
|
34
36
|
"peerDependencies": {
|
|
35
37
|
"zod": ">=3.25.76"
|
|
38
|
+
},
|
|
39
|
+
"allowScripts": {
|
|
40
|
+
"esbuild@0.25.5": true,
|
|
41
|
+
"fsevents@2.3.3": true
|
|
36
42
|
}
|
|
37
43
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
2
|
export function buildParseBodySubscriptionFunc() {
|
|
3
|
-
return async (options
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
-
) => {
|
|
3
|
+
return async (options) => {
|
|
6
4
|
if (options.response.status !== 200) {
|
|
7
5
|
throw new Error(await options.response.text());
|
|
8
6
|
}
|
|
@@ -14,23 +12,19 @@ export function buildParseBodySubscriptionFunc() {
|
|
|
14
12
|
const decoder = new TextDecoder();
|
|
15
13
|
let shouldClose = false;
|
|
16
14
|
let resolve;
|
|
17
|
-
const signal = new Promise(res => resolve = res);
|
|
15
|
+
const signal = new Promise((res) => (resolve = res));
|
|
18
16
|
const close = () => {
|
|
19
17
|
shouldClose = true;
|
|
20
18
|
resolve({ done: true, value: undefined });
|
|
21
19
|
options.controller.abort();
|
|
22
20
|
};
|
|
23
|
-
const stream = async function* () {
|
|
21
|
+
const stream = (async function* () {
|
|
24
22
|
while (!shouldClose) {
|
|
25
|
-
const readResult = await Promise.race([
|
|
26
|
-
reader.read(),
|
|
27
|
-
signal
|
|
28
|
-
]);
|
|
23
|
+
const readResult = await Promise.race([reader.read(), signal]);
|
|
29
24
|
if (readResult.done)
|
|
30
25
|
return;
|
|
31
|
-
const lines = decoder.decode(readResult.value)
|
|
32
|
-
|
|
33
|
-
for (const line of lines.filter(c => c !== '')) {
|
|
26
|
+
const lines = decoder.decode(readResult.value).split('\n');
|
|
27
|
+
for (const line of lines.filter((c) => c !== '')) {
|
|
34
28
|
if (shouldClose)
|
|
35
29
|
break;
|
|
36
30
|
const [name, value] = line.split(/:(.*)/s, 2);
|
|
@@ -39,11 +33,11 @@ export function buildParseBodySubscriptionFunc() {
|
|
|
39
33
|
yield options.operation.resultSchema.parse(JSON.parse(value).data);
|
|
40
34
|
}
|
|
41
35
|
}
|
|
42
|
-
}();
|
|
36
|
+
})();
|
|
43
37
|
return {
|
|
44
38
|
stream,
|
|
45
39
|
close,
|
|
46
|
-
[Symbol.dispose]: close
|
|
40
|
+
[Symbol.dispose]: close,
|
|
47
41
|
};
|
|
48
42
|
};
|
|
49
43
|
}
|
package/parsers/parser.js
CHANGED
|
@@ -6,15 +6,20 @@ const defaultParserOptions = {
|
|
|
6
6
|
};
|
|
7
7
|
export function createParser(parserOptions = defaultParserOptions) {
|
|
8
8
|
return {
|
|
9
|
-
parseBodySync: async (options
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
parseBodySync: async (options) => {
|
|
10
|
+
const text = await options.response.text();
|
|
11
|
+
let json;
|
|
12
|
+
try {
|
|
13
|
+
json = JSON.parse(text);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
throw new Error(`Failed to parse response as json: ${error}, text: ${text}`);
|
|
17
|
+
}
|
|
13
18
|
if (json.errors) {
|
|
14
19
|
await parserOptions.onErrors(options, json.errors);
|
|
15
20
|
}
|
|
16
21
|
return options.operation.resultSchema.parse(json.data);
|
|
17
22
|
},
|
|
18
|
-
parseBodySubscription: buildParseBodySubscriptionFunc()
|
|
23
|
+
parseBodySubscription: buildParseBodySubscriptionFunc(),
|
|
19
24
|
};
|
|
20
25
|
}
|
package/serializers/json.js
CHANGED
|
@@ -13,13 +13,13 @@ export function createJSONSerializer() {
|
|
|
13
13
|
method: 'POST',
|
|
14
14
|
body: JSON.stringify({
|
|
15
15
|
query: operation.document,
|
|
16
|
-
variables: operation.variablesSchema.parse(variables)
|
|
16
|
+
variables: operation.variablesSchema.parse(variables),
|
|
17
17
|
}, (key, value) => {
|
|
18
18
|
assert(!(value instanceof File), 'jsonSerializer cannot encode File objects, ' +
|
|
19
19
|
`key: "${key}"`);
|
|
20
20
|
return value;
|
|
21
21
|
}),
|
|
22
|
-
...requestContext.fetchOptions
|
|
22
|
+
...requestContext.fetchOptions,
|
|
23
23
|
};
|
|
24
24
|
},
|
|
25
25
|
};
|
package/serializers/multipart.js
CHANGED
|
@@ -8,8 +8,9 @@ function getFilesKeysAndPayload(variables, initialPath = '', shouldTreatAsObject
|
|
|
8
8
|
newObject[key] = null;
|
|
9
9
|
continue;
|
|
10
10
|
}
|
|
11
|
-
if (typeof value === 'object' &&
|
|
12
|
-
|
|
11
|
+
if (typeof value === 'object' &&
|
|
12
|
+
value !== null &&
|
|
13
|
+
(shouldTreatAsObject === undefined || shouldTreatAsObject(value))) {
|
|
13
14
|
const [valueFilesKeys, valueObj] = getFilesKeysAndPayload(value, initialPath + key + '.', shouldTreatAsObject);
|
|
14
15
|
filesKeys.push(...valueFilesKeys);
|
|
15
16
|
newObject[key] = valueObj;
|
|
@@ -35,12 +36,13 @@ function buildFormData(operation, variables, shouldTreatAsObject) {
|
|
|
35
36
|
assert(filesKeys.length !== 0, 'Dont use multipartSerializer for regular bodies');
|
|
36
37
|
formData.append('operations', JSON.stringify({
|
|
37
38
|
query: operation.document,
|
|
38
|
-
variables: finalVariables
|
|
39
|
+
variables: finalVariables,
|
|
39
40
|
}));
|
|
40
|
-
const properties = filesKeys
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const properties = filesKeys.map((key, index) => [
|
|
42
|
+
String(index),
|
|
43
|
+
key,
|
|
44
|
+
]);
|
|
45
|
+
const finalMap = Object.fromEntries(properties.map(([index, key]) => {
|
|
44
46
|
return [index, ['variables.' + key]];
|
|
45
47
|
}));
|
|
46
48
|
formData.append('map', JSON.stringify(finalMap));
|
|
@@ -64,7 +66,7 @@ export function createMultipartSerializer() {
|
|
|
64
66
|
method: 'POST',
|
|
65
67
|
headers,
|
|
66
68
|
body: buildFormData(operation, operation.variablesSchema.parse(variables)),
|
|
67
|
-
...requestContext.fetchOptions
|
|
69
|
+
...requestContext.fetchOptions,
|
|
68
70
|
};
|
|
69
71
|
},
|
|
70
72
|
};
|
|
@@ -16,13 +16,13 @@ describe('Json serializer', () => {
|
|
|
16
16
|
};
|
|
17
17
|
const variables = {
|
|
18
18
|
name: 'test-name',
|
|
19
|
-
file: new File([], '')
|
|
19
|
+
file: new File([], ''),
|
|
20
20
|
};
|
|
21
21
|
expect(() => jsonSerializer.serializeRequest({
|
|
22
22
|
operation,
|
|
23
23
|
variables,
|
|
24
24
|
clientContext: {},
|
|
25
|
-
requestContext: {}
|
|
25
|
+
requestContext: {},
|
|
26
26
|
})).toThrowError('jsonSerializer cannot encode File objects, key: "file"');
|
|
27
27
|
});
|
|
28
28
|
it('Should json stringify variables', async () => {
|
|
@@ -42,7 +42,7 @@ describe('Json serializer', () => {
|
|
|
42
42
|
clientContext: {},
|
|
43
43
|
requestContext: {},
|
|
44
44
|
operation,
|
|
45
|
-
variables
|
|
45
|
+
variables,
|
|
46
46
|
});
|
|
47
47
|
const headers = new Headers(init.headers);
|
|
48
48
|
expect(headers.get('Content-Type')).toBe('application/json');
|
|
@@ -50,7 +50,7 @@ describe('Json serializer', () => {
|
|
|
50
50
|
query: operation.document,
|
|
51
51
|
variables: {
|
|
52
52
|
name: 'test-name',
|
|
53
|
-
}
|
|
53
|
+
},
|
|
54
54
|
}));
|
|
55
55
|
});
|
|
56
56
|
});
|
|
@@ -10,18 +10,18 @@ describe('Multipart serializer', () => {
|
|
|
10
10
|
name: '',
|
|
11
11
|
type: 'QUERY',
|
|
12
12
|
variablesSchema: z.object({
|
|
13
|
-
name: z.string()
|
|
13
|
+
name: z.string(),
|
|
14
14
|
}),
|
|
15
15
|
resultSchema: z.void(),
|
|
16
16
|
};
|
|
17
17
|
const variables = {
|
|
18
|
-
name: 'test-name'
|
|
18
|
+
name: 'test-name',
|
|
19
19
|
};
|
|
20
20
|
expect(() => multipartSerializer.serializeRequest({
|
|
21
21
|
clientContext: {},
|
|
22
22
|
requestContext: {},
|
|
23
23
|
operation,
|
|
24
|
-
variables
|
|
24
|
+
variables,
|
|
25
25
|
})).toThrowError('Dont use multipartSerializer for regular bodies');
|
|
26
26
|
});
|
|
27
27
|
it('Should build proper form data', async () => {
|
|
@@ -31,19 +31,19 @@ describe('Multipart serializer', () => {
|
|
|
31
31
|
type: 'QUERY',
|
|
32
32
|
variablesSchema: z.object({
|
|
33
33
|
name: z.string(),
|
|
34
|
-
file: z.file()
|
|
34
|
+
file: z.file(),
|
|
35
35
|
}),
|
|
36
36
|
resultSchema: z.void(),
|
|
37
37
|
};
|
|
38
38
|
const variables = {
|
|
39
39
|
name: 'test-name',
|
|
40
|
-
file: new File([], 'check.txt')
|
|
40
|
+
file: new File([], 'check.txt'),
|
|
41
41
|
};
|
|
42
42
|
const init = await multipartSerializer.serializeRequest({
|
|
43
43
|
clientContext: {},
|
|
44
44
|
requestContext: {},
|
|
45
45
|
operation,
|
|
46
|
-
variables
|
|
46
|
+
variables,
|
|
47
47
|
});
|
|
48
48
|
const headers = new Headers(init.headers);
|
|
49
49
|
expect(headers.get('Content-Type')).toBe(null);
|
|
@@ -53,11 +53,11 @@ describe('Multipart serializer', () => {
|
|
|
53
53
|
query: operation.document,
|
|
54
54
|
variables: {
|
|
55
55
|
name: 'test-name',
|
|
56
|
-
file: null
|
|
57
|
-
}
|
|
56
|
+
file: null,
|
|
57
|
+
},
|
|
58
58
|
}));
|
|
59
59
|
expect(init.body.get('map')).toBe(JSON.stringify({
|
|
60
|
-
'0': ['variables.file']
|
|
60
|
+
'0': ['variables.file'],
|
|
61
61
|
}));
|
|
62
62
|
expect(init.body.get('0')).toStrictEqual(variables.file);
|
|
63
63
|
});
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export type { Operation, SyncOperation, SubscriptionOperation, RequestContext, OperationVariables, OperationResult } from './base.js';
|
|
1
|
+
export type { Operation, SyncOperation, SubscriptionOperation, RequestContext, OperationVariables, OperationResult, } from './base.js';
|
|
2
2
|
export * as middlewares from './middlewares/index.js';
|
|
3
|
-
export type { ClientParser, ClientParserParseBodySyncOptions, ClientParserParseBodySubscriptionOptions, SubOpAsyncIterable } from './parser.js';
|
|
3
|
+
export type { ClientParser, ClientParserParseBodySyncOptions, ClientParserParseBodySubscriptionOptions, SubOpAsyncIterable, } from './parser.js';
|
|
4
4
|
export type { ClientSerializer } from './serializer.js';
|
|
5
5
|
export type { ClientConfig } from './config.js';
|
|
6
6
|
export type { OpResultBasedOnOp } from './utils.js';
|