Skip to content

Commit fa687d6

Browse files
authored
feat: preflight check all request methods (#1278)
1 parent 82fba60 commit fa687d6

File tree

665 files changed

+22743
-16624
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

665 files changed

+22743
-16624
lines changed

examples/65_preset/preset_minimal.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* This example shows use of the `minimal` preset which is the
3+
* default preset used when importing Graffle. It bundles the
4+
* Transport HTTP extension.
5+
*/
6+
7+
import { Graffle } from '../../src/entrypoints/main.js'
8+
import { create } from '../../src/entrypoints/presets/minimal.js'
9+
10+
console.log(`Is the default preset`, Graffle.create === create)
11+
12+
const graffle = create()
13+
14+
console.log(`The current transport is`, graffle._.transports.current)

examples/65_preset/preset_none.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* This example shows use of the `bare` preset which is Graffle at
3+
* its most minimal. It uses no extensions, not even a transport.
4+
*/
5+
6+
import { create } from '../../src/entrypoints/presets/bare.js'
7+
import { Introspection } from '../../src/extensions/Introspection/Introspection.js'
8+
9+
const graffle = create()
10+
11+
/**
12+
* Because we have no transports registered, the `transport` method
13+
* is not available to us. Nor are the request methods.
14+
*
15+
* As well, request methods from extensions also check the status of the transport.
16+
*/
17+
18+
const _t: never = graffle.transport
19+
const _e1: 'Error: You cannot send requests yet. You must setup a transport.' = graffle.gql
20+
const _e2: 'Error: You cannot send requests yet. You must setup a transport.' = graffle.document
21+
const _e3: 'Error: You cannot send requests yet. You must setup a transport.' = graffle.query.$batch
22+
const _e4: 'Error: You cannot send requests yet. You must setup a transport.' = graffle.query.id
23+
const _e5: 'Error: You cannot send requests yet. You must setup a transport.' = graffle.mutation.$batch
24+
const _e6: 'Error: You cannot send requests yet. You must setup a transport.' = graffle.mutation.id
25+
const _e7: 'Error: You cannot send requests yet. You must setup a transport.' = graffle.use(Introspection()).introspect

examples/__outputs__/10_transport-http/transport-http_extension_headers__dynamicHeaders.output.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
headers: Headers {
55
accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8',
66
'content-type': 'application/json',
7-
'x-sent-at-time': '1731961845707'
7+
'x-sent-at-time': '1734293284713'
88
},
99
method: 'post',
1010
url: 'http://localhost:3000/graphql',

examples/__outputs__/10_transport-http/transport-http_headers_raw__headers.output.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ Headers {
44
'content-type': 'application/json',
55
authorization: 'Bearer MY_TOKEN',
66
'x-from-raw': 'true'
7-
}
7+
}

examples/__outputs__/20_output/output_envelope.output.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
headers: Headers {
1717
'content-type': 'application/graphql-response+json; charset=utf-8',
1818
'content-length': '142',
19-
date: 'Mon, 18 Nov 2024 20:30:46 GMT',
19+
date: 'Sun, 15 Dec 2024 20:08:05 GMT',
2020
connection: 'keep-alive',
2121
'keep-alive': 'timeout=5'
2222
},

examples/__outputs__/60_extension/extension_opentelemetry__opentelemetry.output.txt

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
'service.name': 'unknown_service:/Users/jasonkuhrt/Library/pnpm/nodejs/22.11.0/bin/node',
66
'telemetry.sdk.language': 'nodejs',
77
'telemetry.sdk.name': 'opentelemetry',
8-
'telemetry.sdk.version': '1.27.0'
8+
'telemetry.sdk.version': '1.28.0'
99
}
1010
},
1111
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
12-
traceId: 'b3ebc1b598698f83310bd235fcb07eab',
13-
parentId: '832b1b8dea636439',
12+
traceId: 'f223876fb94238d6e67c7f5ad5352b14',
13+
parentId: '65825892207135a8',
1414
traceState: undefined,
1515
name: 'encode',
16-
id: 'b4ac64f2faa2f565',
16+
id: 'b4f6b90f9d4cb7f9',
1717
kind: 0,
18-
timestamp: 1731961846500000,
19-
duration: 1634.667,
18+
timestamp: 1734293285758000,
19+
duration: 1165.458,
2020
attributes: {},
2121
status: { code: 0 },
2222
events: [],
@@ -29,18 +29,18 @@
2929
'service.name': 'unknown_service:/Users/jasonkuhrt/Library/pnpm/nodejs/22.11.0/bin/node',
3030
'telemetry.sdk.language': 'nodejs',
3131
'telemetry.sdk.name': 'opentelemetry',
32-
'telemetry.sdk.version': '1.27.0'
32+
'telemetry.sdk.version': '1.28.0'
3333
}
3434
},
3535
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
36-
traceId: 'b3ebc1b598698f83310bd235fcb07eab',
37-
parentId: '832b1b8dea636439',
36+
traceId: 'f223876fb94238d6e67c7f5ad5352b14',
37+
parentId: '65825892207135a8',
3838
traceState: undefined,
3939
name: 'pack',
40-
id: '53e4263bd960a2e0',
40+
id: '28d86e022df6a130',
4141
kind: 0,
42-
timestamp: 1731961846508000,
43-
duration: 16836.25,
42+
timestamp: 1734293285761000,
43+
duration: 123866.625,
4444
attributes: {},
4545
status: { code: 0 },
4646
events: [],
@@ -53,18 +53,18 @@
5353
'service.name': 'unknown_service:/Users/jasonkuhrt/Library/pnpm/nodejs/22.11.0/bin/node',
5454
'telemetry.sdk.language': 'nodejs',
5555
'telemetry.sdk.name': 'opentelemetry',
56-
'telemetry.sdk.version': '1.27.0'
56+
'telemetry.sdk.version': '1.28.0'
5757
}
5858
},
5959
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
60-
traceId: 'b3ebc1b598698f83310bd235fcb07eab',
61-
parentId: '832b1b8dea636439',
60+
traceId: 'f223876fb94238d6e67c7f5ad5352b14',
61+
parentId: '65825892207135a8',
6262
traceState: undefined,
6363
name: 'exchange',
64-
id: '49774b87c330f8a6',
64+
id: '009c240ba45bff12',
6565
kind: 0,
66-
timestamp: 1731961846525000,
67-
duration: 100583.459,
66+
timestamp: 1734293285888000,
67+
duration: 60630.292,
6868
attributes: {},
6969
status: { code: 0 },
7070
events: [],
@@ -77,18 +77,18 @@
7777
'service.name': 'unknown_service:/Users/jasonkuhrt/Library/pnpm/nodejs/22.11.0/bin/node',
7878
'telemetry.sdk.language': 'nodejs',
7979
'telemetry.sdk.name': 'opentelemetry',
80-
'telemetry.sdk.version': '1.27.0'
80+
'telemetry.sdk.version': '1.28.0'
8181
}
8282
},
8383
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
84-
traceId: 'b3ebc1b598698f83310bd235fcb07eab',
85-
parentId: '832b1b8dea636439',
84+
traceId: 'f223876fb94238d6e67c7f5ad5352b14',
85+
parentId: '65825892207135a8',
8686
traceState: undefined,
8787
name: 'unpack',
88-
id: 'b2ab76711cac0cda',
88+
id: '1a49677d316b711e',
8989
kind: 0,
90-
timestamp: 1731961846626000,
91-
duration: 949.5,
90+
timestamp: 1734293285949000,
91+
duration: 1003.209,
9292
attributes: {},
9393
status: { code: 0 },
9494
events: [],
@@ -101,18 +101,18 @@
101101
'service.name': 'unknown_service:/Users/jasonkuhrt/Library/pnpm/nodejs/22.11.0/bin/node',
102102
'telemetry.sdk.language': 'nodejs',
103103
'telemetry.sdk.name': 'opentelemetry',
104-
'telemetry.sdk.version': '1.27.0'
104+
'telemetry.sdk.version': '1.28.0'
105105
}
106106
},
107107
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
108-
traceId: 'b3ebc1b598698f83310bd235fcb07eab',
109-
parentId: '832b1b8dea636439',
108+
traceId: 'f223876fb94238d6e67c7f5ad5352b14',
109+
parentId: '65825892207135a8',
110110
traceState: undefined,
111111
name: 'decode',
112-
id: '02b77d59425b58b8',
112+
id: '3b7f0a2030462e74',
113113
kind: 0,
114-
timestamp: 1731961846627000,
115-
duration: 445,
114+
timestamp: 1734293285950000,
115+
duration: 444.291,
116116
attributes: {},
117117
status: { code: 0 },
118118
events: [],
@@ -125,18 +125,18 @@
125125
'service.name': 'unknown_service:/Users/jasonkuhrt/Library/pnpm/nodejs/22.11.0/bin/node',
126126
'telemetry.sdk.language': 'nodejs',
127127
'telemetry.sdk.name': 'opentelemetry',
128-
'telemetry.sdk.version': '1.27.0'
128+
'telemetry.sdk.version': '1.28.0'
129129
}
130130
},
131131
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
132-
traceId: 'b3ebc1b598698f83310bd235fcb07eab',
132+
traceId: 'f223876fb94238d6e67c7f5ad5352b14',
133133
parentId: undefined,
134134
traceState: undefined,
135135
name: 'request',
136-
id: '832b1b8dea636439',
136+
id: '65825892207135a8',
137137
kind: 0,
138-
timestamp: 1731961846499000,
139-
duration: 128745.833,
138+
timestamp: 1734293285757000,
139+
duration: 193579.292,
140140
attributes: {},
141141
status: { code: 0 },
142142
events: [],
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Is the default preset true
2+
The current transport is http

examples/__outputs__/65_preset/preset_none.output.txt

Whitespace-only changes.

src/client/Configuration/ConfigInit.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,15 @@ export type ConfigInitOutput =
8181
}
8282

8383
// dprint-ignore
84-
export type NormalizeConfigInit<$ConfigInit extends ConfigInit> = {
85-
[_ in keyof $ConfigInit]:
86-
_ extends 'output'
87-
? NormalizeConfigInitOutput<$ConfigInit['output']>
88-
: $ConfigInit[_]
89-
}
84+
export type NormalizeConfigInit<$ConfigInit extends ConfigInit> =
85+
ConfigInit extends $ConfigInit
86+
? {}
87+
: {
88+
[_ in keyof $ConfigInit]:
89+
_ extends 'output'
90+
? NormalizeConfigInitOutput<$ConfigInit['output']>
91+
: $ConfigInit[_]
92+
}
9093

9194
// dprint-ignore
9295
type NormalizeConfigInitOutput<$Output extends ConfigInitOutput | undefined> = {

src/client/Configuration/client.create.config.output.test-d.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import { type GraphQLExecutionResultError } from '../../lib/grafaid/graphql.js'
1010

1111
const G = Graffle.create
1212

13-
const defaultGraffle = Graffle.create()
13+
const defaultGraffle = Graffle.create({ checkPreflight: false })
1414

1515
describe('default is errors thrown, no envelope, no schema errors', async () => {
1616
const graffle = G({
17+
checkPreflight: false,
1718
output: {
1819
defaults: {
1920
errorChannel: 'throw',
@@ -55,7 +56,7 @@ describe('.envelope', () => {
5556
// const fieldMethod = <$Graffle extends {query:{__typename:()=>Promise<any>}}>(g: $Graffle) => g.query.__typename()
5657

5758
describe('false disables it ', () => {
58-
const g = G({ output: { envelope: false } })
59+
const g = G({ output: { envelope: false }, checkPreflight: false })
5960

6061
test('query.<fieldMethod>', () => {
6162
expectTypeOf(g.query.__typename()).resolves.toEqualTypeOf<FieldMethodResultDisabled>()
@@ -68,7 +69,7 @@ describe('.envelope', () => {
6869
})
6970
})
7071
describe('true enables it', () => {
71-
const g = Graffle.create({ output: { envelope: true } })
72+
const g = Graffle.create({ output: { envelope: true }, checkPreflight: false })
7273
test('query.<fieldMethod>', () => {
7374
expectTypeOf(g.query.__typename()).resolves.toMatchTypeOf<FieldMethodResultEnabled>()
7475
})
@@ -81,28 +82,29 @@ describe('.envelope', () => {
8182
})
8283
})
8384
test('object enables it', async () => {
84-
const graffle = Graffle.create({ output: { envelope: {} } })
85+
const graffle = Graffle.create({ output: { envelope: {} }, checkPreflight: false })
8586
expectTypeOf(await graffle.query.__typename()).toMatchTypeOf<FieldMethodResultEnabled>()
8687
})
8788
describe('.enabled', () => {
8889
test('false disables it', async () => {
89-
const graffle = Graffle.create({ output: { envelope: { enabled: false } } })
90+
const graffle = Graffle.create({ output: { envelope: { enabled: false } }, checkPreflight: false })
9091
expectTypeOf(await graffle.query.__typename()).toEqualTypeOf<FieldMethodResultDisabled>()
9192
})
9293
test('true enables it', async () => {
93-
const graffle = Graffle.create({ output: { envelope: { enabled: true } } })
94+
const graffle = Graffle.create({ output: { envelope: { enabled: true } }, checkPreflight: false })
9495
expectTypeOf(await graffle.query.__typename()).toMatchTypeOf<FieldMethodResultEnabled>()
9596
})
9697
})
9798
describe('with defaults.errorChannel: "return"', () => {
9899
describe('.errors', () => {
99100
test('defaults to execution errors in envelope', () => {
100-
const g = G({ output: { defaults: { errorChannel: 'return' }, envelope: true } })
101+
const g = G({ output: { defaults: { errorChannel: 'return' }, envelope: true }, checkPreflight: false })
101102
expectTypeOf(g.query.__typename()).resolves.toMatchTypeOf<ExecutionResult<{ __typename: 'Query' }> | Anyware.ResultFailure>()
102103
})
103104
test('.execution:false restores errors to return', async () => {
104105
const g = G({
105106
output: { defaults: { errorChannel: 'return' }, envelope: { errors: { execution: false } } },
107+
checkPreflight: false,
106108
})
107109
expectTypeOf(await g.query.__typename()).toEqualTypeOf<
108110
Omit<ExecutionResult<{ __typename: 'Query' }>, 'errors'> | Anyware.ResultFailure | GraphQLExecutionResultError
@@ -111,6 +113,7 @@ describe('.envelope', () => {
111113
test('.other:true raises them to envelope', () => {
112114
const g = G({
113115
output: { defaults: { errorChannel: 'return' }, envelope: { errors: { other: true } } },
116+
checkPreflight: false,
114117
})
115118
expectTypeOf(g.query.__typename()).resolves.toMatchTypeOf<ExecutionResult<{ __typename: 'Query' }>>()
116119
})
@@ -121,6 +124,7 @@ describe('.envelope', () => {
121124
// todo allow this shorthand
122125
// output: { envelope: false },
123126
output: { envelope: { errors: { execution:false, other:false } } },
127+
checkPreflight: false,
124128
})
125129
const result = await g.query.__typename()
126130
expectTypeOf<keyof typeof result>().toEqualTypeOf<'data'|'extensions'> // no errors
@@ -129,7 +133,7 @@ describe('.envelope', () => {
129133

130134
describe('defaults.errorChannel: "return"', () => {
131135
describe('puts errors into return type', () => {
132-
const g = G({ output: { defaults: { errorChannel: 'return' } } })
136+
const g = G({ output: { defaults: { errorChannel: 'return' } }, checkPreflight: false })
133137
test('query.<fieldMethod>', async () => {
134138
expectTypeOf(await g.query.__typename()).toEqualTypeOf<
135139
'Query' | Anyware.ResultFailure | GraphQLExecutionResultError
@@ -140,18 +144,21 @@ describe('defaults.errorChannel: "return"', () => {
140144
test('.execution: throw', async () => {
141145
const g = G({
142146
output: { defaults: { errorChannel: 'return' }, errors: { execution: 'throw' } },
147+
checkPreflight: false,
143148
})
144149
expectTypeOf(await g.query.__typename()).toEqualTypeOf<'Query' | Anyware.ResultFailure>()
145150
})
146151
test('.other: throw', async () => {
147152
const g = G({
148153
output: { defaults: { errorChannel: 'return' }, errors: { other: 'throw' } },
154+
checkPreflight: false,
149155
})
150156
expectTypeOf(await g.query.__typename()).toEqualTypeOf<'Query' | GraphQLExecutionResultError>()
151157
})
152158
test('.*: throw', async () => {
153159
const g = G({
154160
output: { defaults: { errorChannel: 'return' }, errors: { other: 'throw', execution: 'throw' } },
161+
checkPreflight: false,
155162
})
156163
expectTypeOf(await g.query.__typename()).toEqualTypeOf<'Query'>()
157164
})

0 commit comments

Comments
 (0)