naystack 1.5.9 → 1.5.11

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.
Files changed (114) hide show
  1. package/README.md +646 -91
  2. package/dist/auth/constants.d.mts +4 -0
  3. package/dist/auth/constants.d.ts +4 -0
  4. package/dist/auth/email/client.d.mts +149 -0
  5. package/dist/auth/email/client.d.ts +149 -0
  6. package/dist/auth/email/index.cjs.js +2 -20
  7. package/dist/auth/email/index.d.mts +41 -1
  8. package/dist/auth/email/index.d.ts +41 -1
  9. package/dist/auth/email/index.esm.js +1 -17
  10. package/dist/auth/email/routes/delete.cjs.js +0 -1
  11. package/dist/auth/email/routes/delete.d.mts +5 -0
  12. package/dist/auth/email/routes/delete.d.ts +5 -0
  13. package/dist/auth/email/routes/delete.esm.js +0 -1
  14. package/dist/auth/email/routes/get.d.mts +5 -0
  15. package/dist/auth/email/routes/get.d.ts +5 -0
  16. package/dist/auth/email/routes/post.cjs.js +0 -1
  17. package/dist/auth/email/routes/post.d.mts +5 -0
  18. package/dist/auth/email/routes/post.d.ts +5 -0
  19. package/dist/auth/email/routes/post.esm.js +0 -1
  20. package/dist/auth/email/routes/put.cjs.js +0 -1
  21. package/dist/auth/email/routes/put.d.mts +5 -0
  22. package/dist/auth/email/routes/put.d.ts +5 -0
  23. package/dist/auth/email/routes/put.esm.js +0 -1
  24. package/dist/auth/email/token.d.mts +62 -0
  25. package/dist/auth/email/token.d.ts +62 -0
  26. package/dist/auth/email/types.d.mts +22 -0
  27. package/dist/auth/email/types.d.ts +22 -0
  28. package/dist/auth/email/utils.cjs.js +0 -18
  29. package/dist/auth/email/utils.d.mts +41 -3
  30. package/dist/auth/email/utils.d.ts +41 -3
  31. package/dist/auth/email/utils.esm.js +0 -16
  32. package/dist/auth/google/get.d.mts +5 -0
  33. package/dist/auth/google/get.d.ts +5 -0
  34. package/dist/auth/google/index.d.mts +39 -0
  35. package/dist/auth/google/index.d.ts +39 -0
  36. package/dist/auth/index.cjs.js +4 -22
  37. package/dist/auth/index.d.mts +1 -1
  38. package/dist/auth/index.d.ts +1 -1
  39. package/dist/auth/index.esm.js +3 -19
  40. package/dist/auth/instagram/client.d.mts +19 -0
  41. package/dist/auth/instagram/client.d.ts +19 -0
  42. package/dist/auth/instagram/index.d.mts +37 -0
  43. package/dist/auth/instagram/index.d.ts +37 -0
  44. package/dist/auth/instagram/route.d.mts +5 -0
  45. package/dist/auth/instagram/route.d.ts +5 -0
  46. package/dist/auth/instagram/utils.d.mts +13 -0
  47. package/dist/auth/instagram/utils.d.ts +13 -0
  48. package/dist/auth/types.d.mts +24 -0
  49. package/dist/auth/types.d.ts +24 -0
  50. package/dist/auth/utils/errors.d.mts +10 -0
  51. package/dist/auth/utils/errors.d.ts +10 -0
  52. package/dist/auth/utils/token.d.mts +20 -0
  53. package/dist/auth/utils/token.d.ts +20 -0
  54. package/dist/client/hooks.d.mts +59 -0
  55. package/dist/client/hooks.d.ts +59 -0
  56. package/dist/client/seo.d.mts +46 -0
  57. package/dist/client/seo.d.ts +46 -0
  58. package/dist/env.d.mts +61 -0
  59. package/dist/env.d.ts +61 -0
  60. package/dist/file/client.d.mts +53 -1
  61. package/dist/file/client.d.ts +53 -1
  62. package/dist/file/index.cjs.js +0 -1
  63. package/dist/file/index.esm.js +0 -1
  64. package/dist/file/put.cjs.js +0 -1
  65. package/dist/file/put.d.mts +11 -0
  66. package/dist/file/put.d.ts +11 -0
  67. package/dist/file/put.esm.js +0 -1
  68. package/dist/file/setup.cjs.js +0 -1
  69. package/dist/file/setup.d.mts +48 -0
  70. package/dist/file/setup.d.ts +48 -0
  71. package/dist/file/setup.esm.js +0 -1
  72. package/dist/file/utils.d.mts +41 -0
  73. package/dist/file/utils.d.ts +41 -0
  74. package/dist/graphql/client.d.mts +113 -0
  75. package/dist/graphql/client.d.ts +113 -0
  76. package/dist/graphql/errors.d.mts +26 -0
  77. package/dist/graphql/errors.d.ts +26 -0
  78. package/dist/graphql/index.cjs.js +2 -3
  79. package/dist/graphql/index.esm.js +2 -3
  80. package/dist/graphql/init.cjs.js +0 -1
  81. package/dist/graphql/init.d.mts +33 -0
  82. package/dist/graphql/init.d.ts +33 -0
  83. package/dist/graphql/init.esm.js +0 -1
  84. package/dist/graphql/server.d.mts +88 -0
  85. package/dist/graphql/server.d.ts +88 -0
  86. package/dist/graphql/types.d.mts +21 -0
  87. package/dist/graphql/types.d.ts +21 -0
  88. package/dist/graphql/utils.d.mts +217 -0
  89. package/dist/graphql/utils.d.ts +217 -0
  90. package/dist/index.d.mts +16 -0
  91. package/dist/index.d.ts +16 -0
  92. package/dist/socials/instagram/getters.d.mts +115 -0
  93. package/dist/socials/instagram/getters.d.ts +115 -0
  94. package/dist/socials/instagram/setters.d.mts +18 -0
  95. package/dist/socials/instagram/setters.d.ts +18 -0
  96. package/dist/socials/instagram/types.d.mts +46 -0
  97. package/dist/socials/instagram/types.d.ts +46 -0
  98. package/dist/socials/instagram/utils.d.mts +19 -0
  99. package/dist/socials/instagram/utils.d.ts +19 -0
  100. package/dist/socials/instagram/webhook.d.mts +31 -0
  101. package/dist/socials/instagram/webhook.d.ts +31 -0
  102. package/dist/socials/meta-webhook.d.mts +11 -0
  103. package/dist/socials/meta-webhook.d.ts +11 -0
  104. package/dist/socials/threads/getters.d.mts +57 -0
  105. package/dist/socials/threads/getters.d.ts +57 -0
  106. package/dist/socials/threads/setters.d.mts +59 -0
  107. package/dist/socials/threads/setters.d.ts +59 -0
  108. package/dist/socials/threads/types.d.mts +9 -0
  109. package/dist/socials/threads/types.d.ts +9 -0
  110. package/dist/socials/threads/utils.d.mts +19 -0
  111. package/dist/socials/threads/utils.d.ts +19 -0
  112. package/dist/socials/threads/webhook.d.mts +30 -0
  113. package/dist/socials/threads/webhook.d.ts +30 -0
  114. package/package.json +9 -5
@@ -2,12 +2,67 @@ import { OperationVariables } from '@apollo/client';
2
2
  import { TypedDocumentNode } from '@graphql-typed-document-node/core';
3
3
  import React__default, { FC } from 'react';
4
4
 
5
+ /** Component props type minus loading and data (inferred from Injector Component). */
5
6
  type OmittedProps<Y> = Omit<Omit<Y, "loading">, "data">;
7
+ /** Props for Injector: either optional or required based on remaining Component props. */
6
8
  type ComponentProps<Y> = OmittedProps<Y> extends Record<string, never> ? {
7
9
  props?: object;
8
10
  } : {
9
11
  props: OmittedProps<Y>;
10
12
  };
13
+ /**
14
+ * Server component that wraps a client component with server-fetched data using Suspense.
15
+ *
16
+ * While the `fetch` function is resolving, the `Component` is rendered with `loading={true}` (and no `data`).
17
+ * Once the fetch resolves, the `Component` re-renders with `loading={false}` and `data` set to the result.
18
+ *
19
+ * This is the primary way to inject server-side data into client components in naystack.
20
+ * Use `.authCall()` or `.call()` from your query definitions inside the `fetch` function.
21
+ *
22
+ * @param injectorProps - Configuration object.
23
+ * @param injectorProps.fetch - Async function that returns the data to pass to the component. Runs on the server.
24
+ * @param injectorProps.Component - React component that receives `{ data?: T; loading: boolean }` plus any extra props.
25
+ * @param injectorProps.props - Optional. Any additional props to pass to `Component`. Required if the Component has props other than `data` and `loading`.
26
+ * @returns A React element that suspends until `fetch()` completes, then renders `Component` with the data.
27
+ *
28
+ * @example Simple usage:
29
+ * ```tsx
30
+ * import { Injector } from "naystack/graphql/server";
31
+ * import getCurrentUser from "@/app/api/(graphql)/User/resolvers/get-current-user";
32
+ * import AuthChecker from "./components/auth-checker";
33
+ *
34
+ * export default async function Layout({ children }: { children: React.ReactNode }) {
35
+ * return (
36
+ * <div>
37
+ * {children}
38
+ * <Injector fetch={getCurrentUser.authCall} Component={AuthChecker} />
39
+ * </div>
40
+ * );
41
+ * }
42
+ * ```
43
+ *
44
+ * @example Fetching multiple queries:
45
+ * ```tsx
46
+ * import { Injector } from "naystack/graphql/server";
47
+ * import getCurrentUser from "@/app/api/(graphql)/User/resolvers/get-current-user";
48
+ * import getChats from "@/app/api/(graphql)/Chat/resolvers/get-chats";
49
+ * import { ChatWindow } from "./components/chat-window";
50
+ *
51
+ * export default async function ChatPage() {
52
+ * return (
53
+ * <Injector
54
+ * fetch={async () => ({
55
+ * user: await getCurrentUser.authCall(),
56
+ * chats: await getChats.authCall(),
57
+ * })}
58
+ * Component={ChatWindow}
59
+ * />
60
+ * );
61
+ * }
62
+ * ```
63
+ *
64
+ * @category GraphQL
65
+ */
11
66
  declare function Injector<T, Y>({ fetch, Component, props, }: {
12
67
  fetch: () => Promise<T>;
13
68
  Component: FC<{
@@ -15,6 +70,39 @@ declare function Injector<T, Y>({ fetch, Component, props, }: {
15
70
  loading: boolean;
16
71
  } & Y>;
17
72
  } & ComponentProps<Y>): React__default.JSX.Element;
73
+ /**
74
+ * Runs a raw GraphQL query on the server using the registered Apollo client.
75
+ * Cookies are forwarded automatically so the backend can identify the user.
76
+ *
77
+ * Use this in Server Components, Server Actions, or route handlers when you need to
78
+ * run a query against the GraphQL endpoint (rather than calling a resolver directly with `.call()`/`.authCall()`).
79
+ *
80
+ * Supports Next.js ISR via `revalidate` and on-demand revalidation via `tags`.
81
+ *
82
+ * @param _query - A `TypedDocumentNode` (e.g. from codegen) defining the query and its result type.
83
+ * @param options - Optional query options.
84
+ * @param options.variables - Variables object for the query (must match the document's variable types).
85
+ * @param options.revalidate - Next.js revalidate in seconds; when set, enables caching with this TTL.
86
+ * @param options.tags - Next.js cache tags for on-demand revalidation.
87
+ * @param options.noCookie - If `true`, the request is sent without cookies (unauthenticated).
88
+ * @returns Promise resolving to the query result data (typed by the document).
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * import { query } from "naystack/graphql/server";
93
+ * import { GetUserDocument } from "@/generated/graphql";
94
+ *
95
+ * // In a Server Component:
96
+ * const data = await query(GetUserDocument, {
97
+ * variables: { id: userId },
98
+ * revalidate: 60, // Cache for 60s (Next.js ISR)
99
+ * tags: ["user"], // For on-demand revalidation
100
+ * });
101
+ * return <Profile user={data.user} />;
102
+ * ```
103
+ *
104
+ * @category GraphQL
105
+ */
18
106
  declare const query: <T, V extends OperationVariables>(_query: TypedDocumentNode<T, V>, options?: {
19
107
  variables?: V;
20
108
  revalidate?: number;
@@ -1,7 +1,28 @@
1
+ /**
2
+ * Request context passed to GraphQL resolvers. Built automatically from the request's
3
+ * `Authorization` header or refresh cookie by the built-in `getContext`.
4
+ *
5
+ * @property userId - Authenticated user id, or `null` if the request is unauthenticated.
6
+ * @property isRefreshID - `true` if the user was identified via the refresh cookie (not an access token).
7
+ * When `isRefreshID` is true, mutations are blocked by default (only queries are allowed via refresh cookie).
8
+ *
9
+ * @category GraphQL
10
+ */
1
11
  interface Context {
2
12
  userId: number | null;
3
13
  isRefreshID?: boolean;
4
14
  }
15
+ /**
16
+ * Context for resolvers that require authentication (`authorized: true`). The `userId` is guaranteed to be non-null.
17
+ *
18
+ * When you set `authorized: true` on a `query()` or `field()`, the resolver's `ctx` parameter is typed as `AuthorizedContext`
19
+ * instead of `Context`, so you can safely access `ctx.userId` without null checks.
20
+ *
21
+ * @property userId - Authenticated user id (guaranteed non-null).
22
+ * @property isRefreshID - `true` if identified via refresh cookie.
23
+ *
24
+ * @category GraphQL
25
+ */
5
26
  interface AuthorizedContext {
6
27
  userId: number;
7
28
  isRefreshID?: boolean;
@@ -1,7 +1,28 @@
1
+ /**
2
+ * Request context passed to GraphQL resolvers. Built automatically from the request's
3
+ * `Authorization` header or refresh cookie by the built-in `getContext`.
4
+ *
5
+ * @property userId - Authenticated user id, or `null` if the request is unauthenticated.
6
+ * @property isRefreshID - `true` if the user was identified via the refresh cookie (not an access token).
7
+ * When `isRefreshID` is true, mutations are blocked by default (only queries are allowed via refresh cookie).
8
+ *
9
+ * @category GraphQL
10
+ */
1
11
  interface Context {
2
12
  userId: number | null;
3
13
  isRefreshID?: boolean;
4
14
  }
15
+ /**
16
+ * Context for resolvers that require authentication (`authorized: true`). The `userId` is guaranteed to be non-null.
17
+ *
18
+ * When you set `authorized: true` on a `query()` or `field()`, the resolver's `ctx` parameter is typed as `AuthorizedContext`
19
+ * instead of `Context`, so you can safely access `ctx.userId` without null checks.
20
+ *
21
+ * @property userId - Authenticated user id (guaranteed non-null).
22
+ * @property isRefreshID - `true` if identified via refresh cookie.
23
+ *
24
+ * @category GraphQL
25
+ */
5
26
  interface AuthorizedContext {
6
27
  userId: number;
7
28
  isRefreshID?: boolean;
@@ -2,20 +2,29 @@ import { GraphQLScalarType } from 'graphql';
2
2
  import { ClassType, Query, Arg } from 'type-graphql';
3
3
  import { AuthorizedContext, Context } from './types.mjs';
4
4
 
5
+ /** Options for @Query() / @Mutation() return type (e.g. nullable). */
5
6
  type ReturnOptions = Parameters<typeof Query>[1];
7
+ /** Options for @Arg() (e.g. nullable). */
6
8
  type ArgsOptions = Parameters<typeof Arg>[2];
9
+ /** Maps nullable keys to optional and normalizes null/undefined. */
7
10
  type NormalizeNullUndefined<T> = {
8
11
  [K in keyof T as null extends T[K] ? K : never]?: Exclude<T[K], undefined>;
9
12
  } & {
10
13
  [K in keyof T as null extends T[K] ? never : K]: undefined extends T[K] ? Exclude<T[K], undefined> | null : T[K];
11
14
  };
15
+ /** Adds nullable option to Query/Arg options. */
12
16
  type NullableOptions<T, X extends boolean> = T & {
13
17
  nullable: X;
14
18
  };
19
+ /** Resolves a GraphQL type (class, scalar, primitive) to TS type. */
15
20
  type ParsedGQLType<T, MergeNullUndefined extends boolean> = T extends StringConstructor ? string : T extends NumberConstructor ? number : T extends BooleanConstructor ? boolean : T extends GraphQLScalarType<infer U> ? U : T extends ClassType<infer U> ? MergeNullUndefined extends true ? NormalizeNullUndefined<U> : U : T extends Record<infer K, string | number> ? T[K] : void;
21
+ /** Array-aware ParsedGQLType. */
16
22
  type ParsedGQLTypeWithArray<T, MergeNullUndefined extends boolean> = T extends Array<infer U> ? ParsedGQLType<U, MergeNullUndefined>[] : ParsedGQLType<T, MergeNullUndefined>;
23
+ /** Adds null/undefined when nullable. */
17
24
  type ParsedGQLTypeWithNullability<T, IsNullable extends boolean, MergeNullUndefined extends boolean> = IsNullable extends true ? ParsedGQLTypeWithArray<T, MergeNullUndefined> | null | undefined : ParsedGQLTypeWithArray<T, MergeNullUndefined>;
25
+ /** Allows resolver to return T or Promise<T>. */
18
26
  type Promisify<T> = T | Promise<T>;
27
+ /** Base for query/field definition (output, input, options). */
19
28
  interface BaseDefinition<T, U, IsAuth extends boolean = false, OutputNullable extends boolean = false, InputNullable extends boolean = false> {
20
29
  output: T;
21
30
  outputOptions?: NullableOptions<ReturnOptions, OutputNullable>;
@@ -23,26 +32,234 @@ interface BaseDefinition<T, U, IsAuth extends boolean = false, OutputNullable ex
23
32
  inputOptions?: NullableOptions<ArgsOptions, InputNullable>;
24
33
  authorized?: IsAuth;
25
34
  }
35
+ /**
36
+ * Full query/mutation definition returned by {@link query}. Contains the resolver function,
37
+ * plus `.call()` and `.authCall()` for direct server-side invocation.
38
+ *
39
+ * @category GraphQL
40
+ */
26
41
  interface QueryDefinition<T, U, IsAuth extends boolean = false, OutputNullable extends boolean = false, InputNullable extends boolean = false, R extends Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>> = Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>>> extends BaseDefinition<T, U, IsAuth, OutputNullable, InputNullable> {
27
42
  fn: (ctx: IsAuth extends true ? AuthorizedContext : Context, data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => R;
43
+ /** Calls the resolver server-side. For authorized queries, reads the refresh cookie; for non-authorized, passes null userId. */
28
44
  call: (data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => Promise<Awaited<R>>;
45
+ /** Calls the resolver server-side with authentication (always reads the refresh cookie). Use in Server Components. */
29
46
  authCall: (data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => Promise<Awaited<R>>;
30
47
  mutation?: boolean;
31
48
  }
49
+ /**
50
+ * Defines a type-graphql query or mutation with typed input/output and optional auth.
51
+ * Use with {@link QueryLibrary} to build resolver classes for `initGraphQLServer`.
52
+ *
53
+ * Each query definition gets `.call(data)` and `.authCall(data)` methods for direct server-side invocation
54
+ * (e.g. in Server Components or other resolvers). Both are cached via React's `cache()`.
55
+ *
56
+ * @param fn - Resolver function: `(ctx, data) => result`.
57
+ * - `ctx` is `Context` (or `AuthorizedContext` when `authorized: true`) with `userId`.
58
+ * - `data` is the typed GraphQL input (or `void` if no input).
59
+ * @param options - Configuration for the query/mutation.
60
+ * @param options.output - The GraphQL return type (type-graphql `@ObjectType` class, `String`, `Boolean`, `Number`, etc.).
61
+ * @param options.input - Optional GraphQL input type (`@InputType` class or scalar) for the `input` argument.
62
+ * @param options.outputOptions - Optional. Set `{ nullable: true }` to allow null returns.
63
+ * @param options.inputOptions - Optional. Set `{ nullable: true }` to allow null input.
64
+ * @param options.authorized - If `true`, the resolver requires an authenticated user. `ctx` is typed as `AuthorizedContext` (non-null `userId`).
65
+ * @param options.mutation - If `true`, registers as a `@Mutation`; otherwise registers as a `@Query`.
66
+ * @returns A `QueryDefinition` with `.call(data)` and `.authCall(data)` for server-side invocation.
67
+ *
68
+ * @example Simple query (no input, nullable output):
69
+ * ```ts
70
+ * import { query } from "naystack/graphql";
71
+ *
72
+ * export default query(
73
+ * async (ctx) => {
74
+ * if (!ctx.userId) return null;
75
+ * const [user] = await db.select().from(UserTable).where(eq(UserTable.id, ctx.userId));
76
+ * return user || null;
77
+ * },
78
+ * { output: User, outputOptions: { nullable: true } },
79
+ * );
80
+ * ```
81
+ *
82
+ * @example Mutation with input and authorization:
83
+ * ```ts
84
+ * export default query(
85
+ * async (ctx, input: SubmitFeedbackInput) => {
86
+ * await db.insert(FeedbackTable).values({ userId: ctx.userId, score: input.score, text: input.text });
87
+ * return true;
88
+ * },
89
+ * { output: Boolean, input: SubmitFeedbackInput, authorized: true, mutation: true },
90
+ * );
91
+ * ```
92
+ *
93
+ * @example Server-side invocation in a Server Component:
94
+ * ```ts
95
+ * const user = await getCurrentUser.authCall(); // Reads refresh cookie for auth
96
+ * const planets = await getPlanets.call(); // No auth needed
97
+ * ```
98
+ *
99
+ * @category GraphQL
100
+ */
32
101
  declare function query<T, U, IsAuth extends boolean = false, OutputNullable extends boolean = false, InputNullable extends boolean = false, R extends Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>> = Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>>>(fn: (ctx: IsAuth extends true ? AuthorizedContext : Context, data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => R, options: Omit<QueryDefinition<T, U, IsAuth, OutputNullable, InputNullable, R>, "fn" | "authCall" | "call">): QueryDefinition<T, U, IsAuth, OutputNullable, InputNullable, R>;
102
+ /**
103
+ * Full field resolver definition returned by {@link field}. Contains the resolver function,
104
+ * plus `.call()` and `.authCall()` for direct server-side invocation.
105
+ *
106
+ * @category GraphQL
107
+ */
33
108
  interface FieldResolverDefinition<T, U, Root, IsAuth extends boolean = false, OutputNullable extends boolean = false, InputNullable extends boolean = false, R extends Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>> = Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>>> extends BaseDefinition<T, U, IsAuth, OutputNullable, InputNullable> {
34
109
  fn: (root: Root, ctx: IsAuth extends true ? AuthorizedContext : Context, data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => R;
110
+ /** Calls the field resolver server-side. For authorized fields, reads the refresh cookie. */
35
111
  call: (root: Root, data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => Promise<Awaited<R>>;
112
+ /** Calls the field resolver server-side with authentication (always reads the refresh cookie). */
36
113
  authCall: (root: Root, data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => Promise<Awaited<R>>;
37
114
  }
115
+ /**
116
+ * Defines a type-graphql field resolver with typed root, context, and input.
117
+ * Use with {@link FieldLibrary} to attach computed fields to a parent GraphQL type.
118
+ *
119
+ * Like `query()`, each field definition gets `.call(root, data)` and `.authCall(root, data)` for server-side invocation.
120
+ *
121
+ * @param fn - Resolver function: `(root, ctx, data) => result`.
122
+ * - `root` is the parent object (e.g. the `User` row from the database).
123
+ * - `ctx` is `Context` (or `AuthorizedContext` when `authorized: true`).
124
+ * - `data` is the optional typed input argument.
125
+ * @param options - Configuration (same as `query()` but without `mutation`).
126
+ * @returns A `FieldResolverDefinition` with `.call` and `.authCall` for server-side invocation.
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * import { field } from "naystack/graphql";
131
+ *
132
+ * // Resolve the "seller" field on a Property type
133
+ * const seller = field(
134
+ * async (property: PropertyDB) => {
135
+ * if (!property.sellerId) return null;
136
+ * const [seller] = await db.select().from(ContactTable).where(eq(ContactTable.id, property.sellerId));
137
+ * return seller || null;
138
+ * },
139
+ * { output: ContactGQL, outputOptions: { nullable: true } },
140
+ * );
141
+ * ```
142
+ *
143
+ * @example Inline in a FieldLibrary:
144
+ * ```ts
145
+ * const OrgFields = FieldLibrary<OrgDB>(OrgGQL, {
146
+ * access: field(
147
+ * async (root, ctx) => {
148
+ * if (!ctx.userId) return null;
149
+ * return checkOrgAccess(ctx.userId, root.id);
150
+ * },
151
+ * { output: AccessRole, outputOptions: { nullable: true } },
152
+ * ),
153
+ * });
154
+ * ```
155
+ *
156
+ * @category GraphQL
157
+ */
38
158
  declare function field<T, U, IsAuth extends boolean, Root, OutputNullable extends boolean = false, InputNullable extends boolean = false, R extends Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>> = Promisify<ParsedGQLTypeWithNullability<T, OutputNullable, true>>>(fn: (root: Root, ctx: IsAuth extends true ? AuthorizedContext : Context, data: ParsedGQLTypeWithNullability<U, InputNullable, false>) => R, options: Omit<FieldResolverDefinition<T, U, Root, IsAuth, OutputNullable, InputNullable, R>, "fn" | "authCall" | "call">): FieldResolverDefinition<T, U, Root, IsAuth, OutputNullable, InputNullable, R>;
159
+ /**
160
+ * Builds a type-graphql `@Resolver` class from a map of query/mutation definitions created with {@link query}.
161
+ * Each key in the `queries` object becomes a Query or Mutation field on the GraphQL schema.
162
+ *
163
+ * Pass the returned class in the `resolvers` array of `initGraphQLServer`.
164
+ *
165
+ * @param queries - Object mapping GraphQL field names to `QueryDefinition`s (from `query()`).
166
+ * Each key becomes the field name in the schema. Mutations are determined by `{ mutation: true }` in the definition.
167
+ * @returns A `@Resolver` class suitable for `initGraphQLServer`.
168
+ *
169
+ * @example
170
+ * ```ts
171
+ * import { QueryLibrary, query } from "naystack/graphql";
172
+ * import getCurrentUser from "./resolvers/get-current-user";
173
+ * import updateUser from "./resolvers/update-user";
174
+ * import onboardUser from "./resolvers/onboard-user";
175
+ *
176
+ * export const UserResolvers = QueryLibrary({
177
+ * getCurrentUser, // becomes Query.getCurrentUser
178
+ * updateUser, // becomes Mutation.updateUser (if mutation: true)
179
+ * onboardUser, // becomes Mutation.onboardUser (if mutation: true)
180
+ * });
181
+ * ```
182
+ *
183
+ * @category GraphQL
184
+ */
39
185
  declare function QueryLibrary<T extends Record<string, QueryDefinition<any, any, any, any, any, any>>>(queries: T): {
40
186
  new (): {};
41
187
  };
188
+ /**
189
+ * Builds a type-graphql `@Resolver(() => type)` class that resolves computed fields on a parent GraphQL type.
190
+ * Each key in the `queries` object becomes a `@FieldResolver` on that type.
191
+ *
192
+ * Pass the returned class in the `resolvers` array of `initGraphQLServer`.
193
+ *
194
+ * @typeParam X - The database/plain type of the parent object (e.g. `UserDB`).
195
+ * @param type - The parent GraphQL type class (e.g. `User`). Must be a `@ObjectType` class.
196
+ * @param queries - Object mapping field names to `FieldResolverDefinition`s (from `field()`).
197
+ * @returns A `@Resolver` class for the given type; pass it in `initGraphQLServer`'s resolvers array.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * import { FieldLibrary, field } from "naystack/graphql";
202
+ * import { User } from "./types";
203
+ * import type { UserDB } from "./db";
204
+ * import organizations from "./resolvers/organizations-field";
205
+ *
206
+ * export const UserFieldResolvers = FieldLibrary<UserDB>(User, {
207
+ * organizations, // Resolves User.organizations from the UserDB row
208
+ * });
209
+ * ```
210
+ *
211
+ * @example With inline field definitions:
212
+ * ```ts
213
+ * export const OrgFieldResolvers = FieldLibrary<OrgDB>(OrgGQL, {
214
+ * access: field(
215
+ * async (root, ctx) => checkOrgAccess(ctx.userId, root.id),
216
+ * { output: AccessRole, outputOptions: { nullable: true } },
217
+ * ),
218
+ * });
219
+ * ```
220
+ *
221
+ * @category GraphQL
222
+ */
42
223
  declare function FieldLibrary<X extends object, T extends Record<string, FieldResolverDefinition<any, any, X, any, any, any, any>> = Record<string, FieldResolverDefinition<any, any, X, any, any, any, any>>>(type: ClassType, queries: T): {
43
224
  new (): {};
44
225
  };
226
+ /**
227
+ * Infers the TypeScript return type of a query definition's `.call()` method.
228
+ * Use this to type component props that receive query results, ensuring full type safety.
229
+ *
230
+ * @typeParam T - A `QueryDefinition` (the default export from a resolver file created with `query()`).
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * import type { QueryResponseType } from "naystack/graphql";
235
+ * import type getCurrentUser from "@/app/api/(graphql)/User/resolvers/get-current-user";
236
+ * import type getDeal from "@/app/api/(graphql)/Deal/queries/get-deal";
237
+ *
238
+ * interface Props {
239
+ * user: QueryResponseType<typeof getCurrentUser>;
240
+ * deal: QueryResponseType<typeof getDeal>;
241
+ * }
242
+ * ```
243
+ *
244
+ * @category GraphQL
245
+ */
45
246
  type QueryResponseType<T extends QueryDefinition<any, any, any, any, any, any>> = Awaited<ReturnType<T["call"]>>;
247
+ /**
248
+ * Infers the TypeScript return type of a field resolver definition's `.call()` method.
249
+ * Use this to type the resolved field value.
250
+ *
251
+ * @typeParam T - A `FieldResolverDefinition` (from `field()`).
252
+ *
253
+ * @example
254
+ * ```ts
255
+ * import type { FieldResponseType } from "naystack/graphql";
256
+ * import type organizationsField from "./resolvers/organizations-field";
257
+ *
258
+ * type Orgs = FieldResponseType<typeof organizationsField>;
259
+ * ```
260
+ *
261
+ * @category GraphQL
262
+ */
46
263
  type FieldResponseType<T extends FieldResolverDefinition<any, any, any, any, any, any, any>> = Awaited<ReturnType<T["call"]>>;
47
264
 
48
265
  export { FieldLibrary, type FieldResponseType, QueryLibrary, type QueryResponseType, field, query };