Skip to content

Commit

Permalink
feat(extension-system): builder return properties (#1299)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt authored Dec 29, 2024
1 parent 9870f55 commit 32fad71
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 68 deletions.
33 changes: 11 additions & 22 deletions src/client/client.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { requestMethodsProperties } from '../documentBuilder/requestMethods/requestMethods.js'
import type { Extension } from '../extension/__.js'
import type { Anyware } from '../lib/anyware/__.js'
import { proxyGet } from '../lib/prelude.js'
import type { TypeFunction } from '../lib/type-function/__.js'
import { type ClientTransports, Context } from '../types/context.js'
import type { GlobalRegistry } from '../types/GlobalRegistry/GlobalRegistry.js'
Expand Down Expand Up @@ -153,29 +152,19 @@ export const createWithContext = (
...useProperties(createWithContext, context),
...anywareProperties(createWithContext, context),
...scalarProperties(createWithContext, context),
}

// todo test that access to this works without generation in a unit like test. We discovered bug and covered this in an e2e test.
Object.assign(clientDirect, {
// todo test that access to this works without generation in a unit like test. We discovered bug and covered this in an e2e test.
...requestMethodsProperties(createWithContext, context),
})

const clientProxy = proxyGet(clientDirect, ({ path, property }) => {
// eslint-disable-next-line
// @ts-ignore fixme "Type instantiation is excessively deep and possibly infinite"
const onGetHandlers = context.extensions.map(_ => _.builder).filter(_ => _ !== undefined)
}

for (const onGetHandler of onGetHandlers) {
const result = onGetHandler({
context.extensions.forEach(_ => {
Object.assign(
clientDirect,
_.builder?.({
client: clientDirect,
path,
property,
})
if (result !== undefined) return result
}

return undefined
}) as any
context,
}) ?? {},
)
})

return clientProxy
return clientDirect
}
18 changes: 9 additions & 9 deletions src/extension/builder.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import type { ClientEmpty, ExtensionChainable } from '../client/client.js'
import { identity } from '../lib/prelude.js'
import type { Context } from '../types/context.js'

export type BuilderExtension<
$BuilderExtension extends ExtensionChainable | undefined = ExtensionChainable | undefined,
> =
& BuilderExtension.Interceptor
& BuilderExtension.Create
& { type: $BuilderExtension }

export namespace BuilderExtension {
export interface Create {
export interface CreateCallback {
<$BuilderExtension extends ExtensionChainable>(
interceptor: Interceptor,
propertiesConstructor: Create,
): BuilderExtension<$BuilderExtension>
}
export const create: Create = identity as any
export const createCallback: CreateCallback = identity as any

export type Interceptor = (
input: {
path: string[]
property: string
export type Create = (
parameters: {
client: ClientEmpty
context: Context
},
) => unknown
) => object
}
6 changes: 4 additions & 2 deletions src/extension/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export const create = <
name: $Name
normalizeConfig?: (...args: $ConfigInputParameters) => $Config
custom?: $Custom
create: (parameters: { config: $Config; builder: BuilderExtension.Create; typeHooks: TypeHooksBuilder }) => {
create: (
parameters: { config: $Config; builder: BuilderExtension.CreateCallback; typeHooks: TypeHooksBuilder },
) => {
builder?: $BuilderExtension
typeHooks?: TypeHooksBuilder<$TypeHooks>
onRequest?: RequestPipelineBaseInterceptor
Expand Down Expand Up @@ -82,7 +84,7 @@ export const create = <
const config: $Config = ((definitionInput.normalizeConfig as any)?.(input) ?? {}) as any // eslint-disable-line
const extensionBuilder = definitionInput.create({
config,
builder: BuilderExtension.create,
builder: BuilderExtension.createCallback,
typeHooks: typeHooksBuilder,
})
const builder = extensionBuilder.builder
Expand Down
60 changes: 30 additions & 30 deletions src/extensions/Introspection/Introspection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,39 +30,39 @@ export const Introspection = create({
create: ({ config, builder, typeHooks }) => {
return {
typeHooks: typeHooks.requestResultDataTypes<IntrospectionQuery>(),
builder: builder<BuilderExtension>(({ path, property, client }) => {
if (!(path.length === 0 && property === `introspect`)) return
const clientCatching = client.with({ output: { envelope: false, errors: { execution: `return` } } })
builder: builder<BuilderExtension>(({ client }) => {
return {
introspect: async () => {
const c = client.with({ output: { envelope: false, errors: { execution: `return` } } })
let introspectionQueryDocument = getIntrospectionQuery(config.options)
// @ts-expect-error fixme
const result = await c.gql(introspectionQueryDocument).send()
const featuresDropped: string[] = []
const enabledKnownPotentiallyUnsupportedFeatures = knownPotentiallyUnsupportedFeatures.filter(_ =>
config.options[_] !== false
)

return async () => {
let introspectionQueryDocument = getIntrospectionQuery(config.options)
// @ts-expect-error fixme
const result = await clientCatching.gql(introspectionQueryDocument).send()
const featuresDropped: string[] = []
const enabledKnownPotentiallyUnsupportedFeatures = knownPotentiallyUnsupportedFeatures.filter(_ =>
config.options[_] !== false
)

// Try to find a working introspection query.
if (result instanceof Error) {
for (const feature of enabledKnownPotentiallyUnsupportedFeatures) {
featuresDropped.push(feature)
introspectionQueryDocument = getIntrospectionQuery({
...config.options,
[feature]: false,
})
// @ts-expect-error fixme
const result = await clientCatching.gql(introspectionQueryDocument).send()
if (!(result instanceof Error)) break
// Try to find a working introspection query.
if (result instanceof Error) {
for (const feature of enabledKnownPotentiallyUnsupportedFeatures) {
featuresDropped.push(feature)
introspectionQueryDocument = getIntrospectionQuery({
...config.options,
[feature]: false,
})
// @ts-expect-error fixme
const result = await c.gql(introspectionQueryDocument).send()
if (!(result instanceof Error)) break
}
}
}

// Send the query again with the host configuration for output.
// TODO rather than having to make this query again expose a way to send a value through the output handler here.
// TODO expose the featuresDropped info on the envelope so that upstream can communicate to users what happened
// finally at runtime.
// @ts-expect-error fixme
return await client.gql(introspectionQueryDocument).send()
// Send the query again with the host configuration for output.
// TODO rather than having to make this query again expose a way to send a value through the output handler here.
// TODO expose the featuresDropped info on the envelope so that upstream can communicate to users what happened
// finally at runtime.
// @ts-expect-error fixme
return await client.gql(introspectionQueryDocument).send()
},
}
}),
}
Expand Down
10 changes: 5 additions & 5 deletions src/extensions/Throws/Throws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ export const Throws = create({
name: `Throws`,
create: ({ builder }) => {
return {
builder: builder<BuilderExtension>(({ client, property, path }) => {
if (property !== `throws` || path.length !== 0) return undefined

builder: builder<BuilderExtension>(({ client, context }) => {
// todo redesign input to allow to force throw always
// todo pull pre-configured config from core
const throwsifiedInput: ConfigInit = {
output: {
envelope: {
enabled: client._.output.envelope.enabled,
enabled: context.output.envelope.enabled,
// @ts-expect-error
errors: { execution: false, other: false, schema: false },
},
// @ts-expect-error
errors: { execution: `throw`, other: `throw`, schema: `throw` },
},
}
return () => client.with(throwsifiedInput)
return {
throws: () => client.with(throwsifiedInput),
}
}),
}
},
Expand Down

0 comments on commit 32fad71

Please sign in to comment.