Skip to content

Commit

Permalink
feat: injects AccountFragment into notifications query
Browse files Browse the repository at this point in the history
  • Loading branch information
cesarenaldi committed Dec 12, 2024
1 parent f2059ec commit c864a8b
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 113 deletions.
2 changes: 1 addition & 1 deletion packages/client/src/actions/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('Given the Account query actions', () => {
const result = await fetchAccount(client, {
address: evmAddress(import.meta.env.TEST_ACCOUNT),
});
console.log(result);

assertOk(result);
});
});
Expand Down
15 changes: 9 additions & 6 deletions packages/client/src/actions/notifications.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { Notification, NotificationsRequest } from '@lens-protocol/graphql';
import { NotificationsQuery } from '@lens-protocol/graphql';
import { notificationsQuery } from '@lens-protocol/graphql';
import type { ResultAsync } from '@lens-protocol/types';

import type { Account } from '@lens-protocol/graphql';
import type { SessionClient } from '../clients';
import type { Context } from '../context';
import type { UnexpectedError } from '../errors';
import type { Paginated } from '../types';

Expand All @@ -17,9 +19,10 @@ import type { Paginated } from '../types';
* @param request - The query request.
* @returns Paginated notifications.
*/
export function fetchNotifications(
client: SessionClient,
request: NotificationsRequest,
): ResultAsync<Paginated<Notification>, UnexpectedError> {
return client.query(NotificationsQuery, { request });
export function fetchNotifications<TAccount extends Account>(
client: SessionClient<Context<TAccount>>,
request: NotificationsRequest = {},
): ResultAsync<Paginated<Notification<TAccount>>, UnexpectedError> {
const document = notificationsQuery(client.context.accountFragment);
return client.query(document, { request });
}
28 changes: 20 additions & 8 deletions packages/graphql/src/accounts/account.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { FragmentOf } from 'gql.tada';
import {
type Account,
AccountAvailable,
AccountBlocked,
AccountFragment,
Expand All @@ -8,17 +9,28 @@ import {
SponsoredTransactionRequest,
TransactionWillFail,
} from '../fragments';
import { type RequestOf, type RequestOfFactory, factory, graphql } from '../graphql';

export const accountQuery = factory(
`query Account($request: AccountRequest!) {
import {
type FragmentDocumentFor,
type RequestFrom,
type RequestOf,
type StandardDocumentNode,
graphql,
} from '../graphql';

const AccountQueryString = `
query Account($request: AccountRequest!) {
value: account(request: $request) {
...Account
}
}`,
);

export type AccountRequest = RequestOfFactory<typeof accountQuery>;
}
`;
export type AccountRequest = RequestFrom<typeof AccountQueryString>;

export function accountQuery<TAccount extends Account>(
fragment: FragmentDocumentFor<TAccount>,
): StandardDocumentNode<TAccount | null, AccountRequest> {
return graphql(AccountQueryString, [fragment]) as StandardDocumentNode;
}

export const SearchAccountsQuery = graphql(
`query SearchAccounts($request: AccountSearchRequest!) {
Expand Down
8 changes: 3 additions & 5 deletions packages/graphql/src/fragments/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,8 @@ export const ReferencedPost = graphql(
operations {
...LoggedInPostOperations
}
}
`,
[AccountFragment, App, Feed, PostMetadata, PostAction, LoggedInPostOperations],
}`,
[App, Feed, PostMetadata, PostAction, LoggedInPostOperations],
);

export const NestedPost = graphql(
Expand Down Expand Up @@ -184,9 +183,8 @@ export const PostFragment = graphql(
}
}
`,
[AccountFragment, App, Feed, PostMetadata, PostAction, NestedPost, LoggedInPostOperations],
[App, Feed, PostMetadata, PostAction, NestedPost, LoggedInPostOperations],
);
export type PostFragment = Post;

export type Post = FragmentOf<typeof PostFragment>;

Expand Down
78 changes: 47 additions & 31 deletions packages/graphql/src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ import type {
} from '@lens-protocol/types';
import {
type DocumentDecoration,
type FragmentOf,
type TadaDocumentNode,
type VariablesOf,
initGraphQLTada,
} from 'gql.tada';
import type { PageSize } from './enums';
import type { PaginatedResultInfo } from './fragments';
import type { introspection } from './graphql-env';

export const graphql = initGraphQLTada<{
Expand Down Expand Up @@ -76,15 +77,11 @@ export type RequestOf<Document> = Document extends DocumentDecoration<
/**
* @internal
*/
export type UnknownFragmentShape = NonNullable<Parameters<typeof graphql>[1]>[number];
export type FragmentShape = NonNullable<Parameters<typeof graphql>[1]>[number];

/**
* @internal
*/

export type TypedDocumentFrom<
In extends string,
Fragments extends UnknownFragmentShape[],
type GetDocumentNode<
In extends string = string,
Fragments extends FragmentShape[] = FragmentShape[],
> = ReturnType<typeof graphql<In, Fragments>>;

export type AnyGqlNode<TTypename extends string = string> = { __typename: TTypename };
Expand Down Expand Up @@ -113,36 +110,55 @@ export type FragmentDocumentFor<TGqlNode extends AnyGqlNode> = TGqlNode extends
*/
export type StandardData<T> = { value: T };

export type Factory<In extends string> = <
Nodes extends AnyGqlNode[],
Fragments extends { [K in keyof Nodes]: FragmentDocumentFor<Nodes[K]> },
Document extends TypedDocumentFrom<In, Fragments>,
>(
...fragments: Fragments
) => TadaDocumentNode<StandardData<First<Nodes>>, VariablesOf<Document>>;
export type RequestFrom<In extends string> = RequestOf<GetDocumentNode<In, FragmentShape[]>>;

// biome-ignore lint/suspicious/noExplicitAny: simplifies necessary type assertions
export type StandardDocumentNode<Value = any, Request = any> = TadaDocumentNode<
StandardData<Value>,
{ request: Request }
>;

type FragmentDocumentFrom<
In extends string,
Fragments extends FragmentShape[],
Document extends GetDocumentNode<In, Fragments> = GetDocumentNode<In, Fragments>,
> = Document extends FragmentShape ? Document : never;

type First<T extends unknown[]> = T extends [infer First, ...unknown[]] ? First : never;
type FragmentDocumentForEach<Nodes extends AnyGqlNode[]> = {
[K in keyof Nodes]: FragmentDocumentFor<Nodes[K]>;
};

/**
* @internal
*/
export function factory<const In extends string>(operation: In): Factory<In> {
return <
Nodes extends AnyGqlNode[],
Fragments extends { [K in keyof Nodes]: FragmentDocumentFor<Nodes[K]> },
Document extends TypedDocumentFrom<In, Fragments>,
Result extends StandardData<First<Nodes>>,
Variables extends VariablesOf<Document>,
>(
...fragments: Fragments
): TadaDocumentNode<Result, Variables> => {
return graphql(operation, fragments) as TadaDocumentNode<Result, Variables>;
};
export type DynamicFragmentDocument<
In extends string,
StaticNodes extends AnyGqlNode[],
> = FragmentDocumentFrom<In, FragmentDocumentForEach<StaticNodes>> & {
__phantom: In;
};

/**
* @internal
*/
export function fragment<In extends string, StaticNodes extends AnyGqlNode[]>(
input: In,
staticFragments: FragmentDocumentForEach<StaticNodes> = [] as FragmentDocumentForEach<StaticNodes>,
): DynamicFragmentDocument<In, StaticNodes> {
return graphql(input, staticFragments) as DynamicFragmentDocument<In, StaticNodes>;
}

/**
* @internal
*/
export type RequestOfFactory<F extends Factory<string>> = F extends Factory<infer In>
? RequestOf<TypedDocumentFrom<In, Parameters<F>>>
export type DynamicFragmentOf<
Document,
DynamicNodes extends AnyGqlNode[],
> = Document extends DynamicFragmentDocument<infer In, infer StaticNodes>
? FragmentOf<FragmentDocumentFrom<In, FragmentDocumentForEach<[...DynamicNodes, ...StaticNodes]>>>
: never;

export type Paginated<T> = {
items: readonly T[];
pageInfo: PaginatedResultInfo;
};
Loading

0 comments on commit c864a8b

Please sign in to comment.