Skip to content

Commit 32fad71

Browse files
authored
feat(extension-system): builder return properties (#1299)
1 parent 9870f55 commit 32fad71

File tree

5 files changed

+59
-68
lines changed

5 files changed

+59
-68
lines changed

src/client/client.ts

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { requestMethodsProperties } from '../documentBuilder/requestMethods/requestMethods.js'
22
import type { Extension } from '../extension/__.js'
33
import type { Anyware } from '../lib/anyware/__.js'
4-
import { proxyGet } from '../lib/prelude.js'
54
import type { TypeFunction } from '../lib/type-function/__.js'
65
import { type ClientTransports, Context } from '../types/context.js'
76
import type { GlobalRegistry } from '../types/GlobalRegistry/GlobalRegistry.js'
@@ -153,29 +152,19 @@ export const createWithContext = (
153152
...useProperties(createWithContext, context),
154153
...anywareProperties(createWithContext, context),
155154
...scalarProperties(createWithContext, context),
156-
}
157-
158-
// todo test that access to this works without generation in a unit like test. We discovered bug and covered this in an e2e test.
159-
Object.assign(clientDirect, {
155+
// todo test that access to this works without generation in a unit like test. We discovered bug and covered this in an e2e test.
160156
...requestMethodsProperties(createWithContext, context),
161-
})
162-
163-
const clientProxy = proxyGet(clientDirect, ({ path, property }) => {
164-
// eslint-disable-next-line
165-
// @ts-ignore fixme "Type instantiation is excessively deep and possibly infinite"
166-
const onGetHandlers = context.extensions.map(_ => _.builder).filter(_ => _ !== undefined)
157+
}
167158

168-
for (const onGetHandler of onGetHandlers) {
169-
const result = onGetHandler({
159+
context.extensions.forEach(_ => {
160+
Object.assign(
161+
clientDirect,
162+
_.builder?.({
170163
client: clientDirect,
171-
path,
172-
property,
173-
})
174-
if (result !== undefined) return result
175-
}
176-
177-
return undefined
178-
}) as any
164+
context,
165+
}) ?? {},
166+
)
167+
})
179168

180-
return clientProxy
169+
return clientDirect
181170
}

src/extension/builder.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
import type { ClientEmpty, ExtensionChainable } from '../client/client.js'
22
import { identity } from '../lib/prelude.js'
3+
import type { Context } from '../types/context.js'
34

45
export type BuilderExtension<
56
$BuilderExtension extends ExtensionChainable | undefined = ExtensionChainable | undefined,
67
> =
7-
& BuilderExtension.Interceptor
8+
& BuilderExtension.Create
89
& { type: $BuilderExtension }
910

1011
export namespace BuilderExtension {
11-
export interface Create {
12+
export interface CreateCallback {
1213
<$BuilderExtension extends ExtensionChainable>(
13-
interceptor: Interceptor,
14+
propertiesConstructor: Create,
1415
): BuilderExtension<$BuilderExtension>
1516
}
16-
export const create: Create = identity as any
17+
export const createCallback: CreateCallback = identity as any
1718

18-
export type Interceptor = (
19-
input: {
20-
path: string[]
21-
property: string
19+
export type Create = (
20+
parameters: {
2221
client: ClientEmpty
22+
context: Context
2323
},
24-
) => unknown
24+
) => object
2525
}

src/extension/extension.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ export const create = <
4949
name: $Name
5050
normalizeConfig?: (...args: $ConfigInputParameters) => $Config
5151
custom?: $Custom
52-
create: (parameters: { config: $Config; builder: BuilderExtension.Create; typeHooks: TypeHooksBuilder }) => {
52+
create: (
53+
parameters: { config: $Config; builder: BuilderExtension.CreateCallback; typeHooks: TypeHooksBuilder },
54+
) => {
5355
builder?: $BuilderExtension
5456
typeHooks?: TypeHooksBuilder<$TypeHooks>
5557
onRequest?: RequestPipelineBaseInterceptor
@@ -82,7 +84,7 @@ export const create = <
8284
const config: $Config = ((definitionInput.normalizeConfig as any)?.(input) ?? {}) as any // eslint-disable-line
8385
const extensionBuilder = definitionInput.create({
8486
config,
85-
builder: BuilderExtension.create,
87+
builder: BuilderExtension.createCallback,
8688
typeHooks: typeHooksBuilder,
8789
})
8890
const builder = extensionBuilder.builder

src/extensions/Introspection/Introspection.ts

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,39 +30,39 @@ export const Introspection = create({
3030
create: ({ config, builder, typeHooks }) => {
3131
return {
3232
typeHooks: typeHooks.requestResultDataTypes<IntrospectionQuery>(),
33-
builder: builder<BuilderExtension>(({ path, property, client }) => {
34-
if (!(path.length === 0 && property === `introspect`)) return
35-
const clientCatching = client.with({ output: { envelope: false, errors: { execution: `return` } } })
33+
builder: builder<BuilderExtension>(({ client }) => {
34+
return {
35+
introspect: async () => {
36+
const c = client.with({ output: { envelope: false, errors: { execution: `return` } } })
37+
let introspectionQueryDocument = getIntrospectionQuery(config.options)
38+
// @ts-expect-error fixme
39+
const result = await c.gql(introspectionQueryDocument).send()
40+
const featuresDropped: string[] = []
41+
const enabledKnownPotentiallyUnsupportedFeatures = knownPotentiallyUnsupportedFeatures.filter(_ =>
42+
config.options[_] !== false
43+
)
3644

37-
return async () => {
38-
let introspectionQueryDocument = getIntrospectionQuery(config.options)
39-
// @ts-expect-error fixme
40-
const result = await clientCatching.gql(introspectionQueryDocument).send()
41-
const featuresDropped: string[] = []
42-
const enabledKnownPotentiallyUnsupportedFeatures = knownPotentiallyUnsupportedFeatures.filter(_ =>
43-
config.options[_] !== false
44-
)
45-
46-
// Try to find a working introspection query.
47-
if (result instanceof Error) {
48-
for (const feature of enabledKnownPotentiallyUnsupportedFeatures) {
49-
featuresDropped.push(feature)
50-
introspectionQueryDocument = getIntrospectionQuery({
51-
...config.options,
52-
[feature]: false,
53-
})
54-
// @ts-expect-error fixme
55-
const result = await clientCatching.gql(introspectionQueryDocument).send()
56-
if (!(result instanceof Error)) break
45+
// Try to find a working introspection query.
46+
if (result instanceof Error) {
47+
for (const feature of enabledKnownPotentiallyUnsupportedFeatures) {
48+
featuresDropped.push(feature)
49+
introspectionQueryDocument = getIntrospectionQuery({
50+
...config.options,
51+
[feature]: false,
52+
})
53+
// @ts-expect-error fixme
54+
const result = await c.gql(introspectionQueryDocument).send()
55+
if (!(result instanceof Error)) break
56+
}
5757
}
58-
}
5958

60-
// Send the query again with the host configuration for output.
61-
// TODO rather than having to make this query again expose a way to send a value through the output handler here.
62-
// TODO expose the featuresDropped info on the envelope so that upstream can communicate to users what happened
63-
// finally at runtime.
64-
// @ts-expect-error fixme
65-
return await client.gql(introspectionQueryDocument).send()
59+
// Send the query again with the host configuration for output.
60+
// TODO rather than having to make this query again expose a way to send a value through the output handler here.
61+
// TODO expose the featuresDropped info on the envelope so that upstream can communicate to users what happened
62+
// finally at runtime.
63+
// @ts-expect-error fixme
64+
return await client.gql(introspectionQueryDocument).send()
65+
},
6666
}
6767
}),
6868
}

src/extensions/Throws/Throws.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ export const Throws = create({
77
name: `Throws`,
88
create: ({ builder }) => {
99
return {
10-
builder: builder<BuilderExtension>(({ client, property, path }) => {
11-
if (property !== `throws` || path.length !== 0) return undefined
12-
10+
builder: builder<BuilderExtension>(({ client, context }) => {
1311
// todo redesign input to allow to force throw always
1412
// todo pull pre-configured config from core
1513
const throwsifiedInput: ConfigInit = {
1614
output: {
1715
envelope: {
18-
enabled: client._.output.envelope.enabled,
16+
enabled: context.output.envelope.enabled,
1917
// @ts-expect-error
2018
errors: { execution: false, other: false, schema: false },
2119
},
2220
// @ts-expect-error
2321
errors: { execution: `throw`, other: `throw`, schema: `throw` },
2422
},
2523
}
26-
return () => client.with(throwsifiedInput)
24+
return {
25+
throws: () => client.with(throwsifiedInput),
26+
}
2727
}),
2828
}
2929
},

0 commit comments

Comments
 (0)