Skip to content

Commit 700a831

Browse files
committed
Promote docs
1 parent 510dfe3 commit 700a831

File tree

6 files changed

+123
-16
lines changed

6 files changed

+123
-16
lines changed

postgraphile/website/versioned_docs/version-5/add-pg-table-order-by.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,62 @@ use a simpler expression for comparisons which is not null-capable, and this
226226
will break cursor pagination when nulls occur.
227227

228228
:::
229+
230+
### Using context or other steps in the addPgTableOrderBy plugin
231+
232+
You can use the `applyScope` method to access the context of the query. This
233+
method is called with the `PgSelectQueryBuilder` and can be used to apply
234+
additional filtering or ordering based on the context.
235+
236+
```ts
237+
import { addPgTableOrderBy, orderByAscDesc } from "postgraphile/utils";
238+
239+
// Apply scope for the specific type.
240+
const applyScopePlugin: GraphileConfig.Plugin = {
241+
name: "applyScopePlugin",
242+
schema: {
243+
hooks: {
244+
GraphQLEnumType(config, build) {
245+
const { TYPES } = build.dataplanPg;
246+
if (config.name === "CityOrderBy") {
247+
const {
248+
grafast: { context },
249+
} = build;
250+
config.extensions ??= {};
251+
// @ts-expect-error The type is readonly by types you may get an error here.
252+
config.extensions.grafast ??= {};
253+
config.extensions.grafast.applyScope = () => context(); // Or any other unary step.
254+
}
255+
return config;
256+
},
257+
},
258+
},
259+
};
260+
261+
export default addPgTableOrderBy(
262+
{ schemaName: "app_public", tableName: "users" },
263+
({ sql }) => {
264+
return orderByAscDesc(
265+
"CITY_NAME",
266+
(queryBuilder, info) => {
267+
const { scope } = info;
268+
269+
const context = scope; // As we applied context as scope.
270+
271+
const orderByFrag = sql`(
272+
select coalesce(
273+
(select value from public.transactions t where t.key = ${queryBuilder.alias}.name and language = ${sqlValueWithCodec(
274+
context?.locale,
275+
TYPES.text,
276+
)}),
277+
${queryBuilder.alias}.name
278+
)
279+
)`;
280+
281+
return { fragment: orderByFrag, codec: TYPES.text };
282+
},
283+
{ nulls: "last-iff-ascending" },
284+
);
285+
},
286+
);
287+
```

postgraphile/website/versioned_docs/version-5/community-plugins.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ Schema extension plugins for PostGraphile:
8484
foreign relationships to be created. :question:_(Not yet ported to V5, but use the "relay" preset instead?)_
8585
- [postgraphile-plugin-timestamp-format](https://github.com/RedShift1/postgraphile-plugin-timestamp-format) -
8686
Format timestamps with PostgreSQL’s to*char function. Supports timezones too :question:*(Not yet ported to V5)\_
87+
- [@haathie/postgraphile-fancy-mutations](https://github.com/haathie/graphile-tools/tree/main/packages/fancy-mutations) - Plugin for performant bulk upserts with nested relations, bulk updates, and deletes. :white_check_mark:
88+
- [@haathie/postgraphile-targeted-conditions](https://github.com/haathie/graphile-tools/tree/main/packages/targeted-conditions) - Plugin for advanced filtering, including relational conditions, [ParadeDB](https://github.com/paradedb/paradedb) support, and more. :white_check_mark:
89+
- [@haathie/postgraphile-realtime](https://github.com/haathie/graphile-tools/tree/main/packages/realtime) - Plugin for performant, conditional subscriptions, allowing real-time updates from any table in your Postgres database. :white_check_mark:
90+
- [@haathie/postgraphile-rate-limits](https://github.com/haathie/graphile-tools/tree/main/packages/rate-limits) - Plugin for rate limiting queries and mutations. Add rate limits using smart tags and get reasonably friendly error messages. :white_check_mark:
91+
- [@haathie/postgraphile-otel](https://github.com/haathie/graphile-tools/tree/main/packages/otel) - Plugin for OpenTelemetry Tracing Capabilities for GraphQL Requests. :white_check_mark:
92+
- [@haathie/postgraphile-reasonable-limits](https://github.com/haathie/graphile-tools/tree/main/packages/reasonable-limits) - Plugin to enforce reasonable limits on queries, preventing excessive data retrieval. :white_check_mark:
8793

8894
Examples of using these plugins:
8995

postgraphile/website/versioned_docs/version-5/extending.md renamed to postgraphile/website/versioned_docs/version-5/extending.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: GraphQL Schema Plugins
33
---
44

5+
import DocCardList from "@theme/DocCardList";
6+
57
PostGraphile’s schema generator is built from a number of
68
[graphile-build plugins](https://build.graphile.org/graphile-build/5/plugins). You can
79
write your own plugins — either using the helpers available in `graphile-utils`,
@@ -73,3 +75,7 @@ Remember: multiple versions of `graphql` in your `node_modules` will cause
7375
problems; so we **strongly** recommend using the `graphql` object that's
7476
available on the `Build` object (second argument to hooks) rather than requiring
7577
your own version.
78+
79+
### Schema plugins
80+
81+
<DocCardList />

postgraphile/website/versioned_docs/version-5/polymorphism.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,16 @@ comment on table polymorphic.gcp_applications is $$
227227
$$;
228228
```
229229

230+
:::warning[Cannot return mode:union from functions]
231+
232+
You will not be able to return the `mode:union` type from a PostgreSQL function.
233+
Consider the above example - if we receive
234+
`{id: 1, name: "Foo", last_deployed: null}` how can we know if this came from
235+
`aws_applications` or `gcp_applications`? Instead, consider using
236+
[`extendSchema`](./extend-schema.md).
237+
238+
:::
239+
230240
## @unionMember
231241

232242
For cases where you want multiple tables that don't necessarily share any

postgraphile/website/versioned_docs/version-5/requirements.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ experience.
4949
or primary key is defined for a table." --
5050
[PG docs](https://www.postgresql.org/docs/current/static/indexes-unique.html)
5151
- **Use the defaults** for formatting output; we only run tests for the
52-
defaults so you may have an issue if you were to use, for example,
53-
`intervalstyle = 'iso_8601'` rather than the default
54-
`intervalstyle = 'postgres'`.
52+
defaults so if you change them you may face issues. (You may change
53+
`intervalstyle` since we have specific handling code for that.)
5554
- **Use UTF8 encoding**: GraphQL operates over the UTF8 character set, using
5655
different encodings may impact your ability to store/retrieve certain values.
5756

postgraphile/website/versioned_docs/version-5/usage-schema.md

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Here's a full example:
103103

104104
```ts
105105
import { postgraphile } from "postgraphile";
106-
import { grafast } from "postgraphile/grafast";
106+
import { grafast, type ErrorBehavior } from "postgraphile/grafast";
107107
import preset from "./graphile.config.js";
108108

109109
// Make a new PostGraphile instance:
@@ -121,13 +121,15 @@ export async function executeQuery(
121121
source: string,
122122
variableValues?: Record<string, unknown> | null,
123123
operationName?: string,
124+
onError?: ErrorBehavior,
124125
) {
125126
const { schema, resolvedPreset } = await pgl.getSchemaResult();
126127
return await grafast({
127128
schema,
128129
source,
129130
variableValues,
130131
operationName,
132+
onError,
131133
resolvedPreset,
132134
requestContext,
133135
});
@@ -158,7 +160,7 @@ Here's an example using hookArgs:
158160
```ts
159161
import { postgraphile } from "postgraphile";
160162
import { parse, validate } from "postgraphile/graphql";
161-
import { execute, hookArgs } from "postgraphile/grafast";
163+
import { execute, hookArgs, type ErrorBehavior } from "postgraphile/grafast";
162164
import preset from "./graphile.config.js";
163165

164166
// Build a `pgl` instance, with helpers and schema based on our preset.
@@ -174,6 +176,7 @@ export async function executeQuery(
174176
source: string,
175177
variableValues?: Record<string, unknown> | null,
176178
operationName?: string,
179+
onError?: ErrorBehavior,
177180
) {
178181
// We might get a newer schema in "watch" mode
179182
const { schema, resolvedPreset } = await pgl.getSchemaResult();
@@ -193,6 +196,7 @@ export async function executeQuery(
193196
document,
194197
variableValues,
195198
operationName,
199+
onError,
196200
resolvedPreset,
197201
requestContext,
198202
});
@@ -204,28 +208,36 @@ export async function executeQuery(
204208

205209
### Example using `TypedDocumentNode`
206210

207-
You can use GraphQL Code Generator with the client-preset to make your GraphQL
208-
execution function type safe. In this case, rather than passing in a raw
211+
You can use GraphQL Code Generator with the `client-preset` to make your GraphQL
212+
execution function type-safe. In this case, rather than passing in a raw
209213
`source` string, we pass in a `TypedDocumentNode` which is generated by the
210214
`gql` tagged template literal, and this means the result we return will
211-
automatically reflect the correct types thanks to graphql-codegen:
215+
automatically reflect the correct types thanks to `graphql-codegen`:
212216

213217
```ts
214218
import type { DocumentNode, ExecutionResult } from "postgraphile/graphql";
215-
import type { TypedDocumentNode } from "@graphql-typed-document-node/core";
219+
import type {
220+
TypedDocumentNode,
221+
VariablesOf,
222+
ResultOf,
223+
} from "@graphql-typed-document-node/core";
216224
import { postgraphile } from "postgraphile";
217-
import { execute, hookArgs } from "postgraphile/grafast";
225+
import { execute, hookArgs, type ErrorBehavior } from "postgraphile/grafast";
218226
import { validate } from "postgraphile/graphql";
219227
import preset from "./graphile.config.js";
220228

221229
const pgl = postgraphile(preset);
222230

223-
export async function executeDocument<TData = any, TVariables = any>(
231+
export async function executeDocument<
232+
TDoc extends TypedDocumentNode | DocumentNode,
233+
TExtensions = ObjMap<unknown>,
234+
>(
224235
requestContext: Partial<Grafast.RequestContext>,
225-
document: DocumentNode | TypedDocumentNode<TData, TVariables>,
226-
variableValues?: Record<string, unknown> | null,
236+
document: TDoc,
237+
variableValues?: VariablesOf<TDoc>,
227238
operationName?: string,
228-
): Promise<ExecutionResult<TData, TVariables>> {
239+
onError?: ErrorBehavior,
240+
): Promise<ExecutionResult<ResultOf<TDoc>, TExtensions>> {
229241
const { schema, resolvedPreset } = await pgl.getSchemaResult();
230242

231243
// Validate the GraphQL document against the schema:
@@ -240,14 +252,29 @@ export async function executeDocument<TData = any, TVariables = any>(
240252
document,
241253
variableValues,
242254
operationName,
255+
onError,
243256
resolvedPreset,
244257
requestContext,
245-
});
258+
} as any);
246259

247260
// Execute the request using Grafast:
248261
const result = await execute(args);
249262

250263
// Cast the result to the types implied by the TypedDocumentNode:
251-
return result as ExecutionResult<TData, TVariables>;
264+
return result as ExecutionResult<ResultOf<TDoc>, TExtensions>;
252265
}
253266
```
267+
268+
Usage for [`gql.tada`](https://gql-tada.0no.co/guides/typed-documents) is
269+
similar; just import the helpers from `gql.tada` instead and note that
270+
`TypedDocumentNode` is renamed to `TadaDocumentNode`:
271+
272+
```diff
273+
import type {
274+
VariablesOf,
275+
ResultOf,
276+
- TypedDocumentNode,
277+
+ TadaDocumentNode,
278+
-} from "@graphql-typed-document-node/core";
279+
+} from "gql.tada";
280+
```

0 commit comments

Comments
 (0)