-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
generateServerClient.ts
110 lines (99 loc) · 3.22 KB
/
generateServerClient.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { generateClientWithAmplifyInstance } from '@aws-amplify/api/internals';
import { generateClient } from 'aws-amplify/api/server';
import {
AmplifyServerContextError,
getAmplifyServerContext,
} from '@aws-amplify/core/internals/adapter-core';
import {
V6ClientSSRCookies,
V6ClientSSRRequest,
} from '@aws-amplify/api-graphql';
import {
GraphQLAuthMode,
parseAmplifyConfig,
} from '@aws-amplify/core/internals/utils';
import { NextServer } from '../types';
import { createServerRunnerForAPI } from './createServerRunnerForAPI';
interface CookiesClientParams {
cookies: NextServer.ServerComponentContext['cookies'];
config: NextServer.CreateServerRunnerInput['config'];
authMode?: GraphQLAuthMode;
authToken?: string;
}
interface ReqClientParams {
config: NextServer.CreateServerRunnerInput['config'];
authMode?: GraphQLAuthMode;
authToken?: string;
}
/**
* Generates an API client that can be used inside a Next.js Server Component with Dynamic Rendering
*
* @example
* import { cookies } from "next/headers"
*
* const client = generateServerClientUsingCookies({ cookies });
* const result = await client.graphql({ query: listPosts });
*/
export function generateServerClientUsingCookies<
T extends Record<any, any> = never,
>({
config,
cookies,
authMode,
authToken,
}: CookiesClientParams): V6ClientSSRCookies<T> {
if (typeof cookies !== 'function') {
throw new AmplifyServerContextError({
message:
'generateServerClientUsingCookies is only compatible with the `cookies` Dynamic Function available in Server Components.',
// TODO: link to docs
recoverySuggestion:
'use `generateServerClient` inside of `runWithAmplifyServerContext` with the `request` object.',
});
}
const { runWithAmplifyServerContext, resourcesConfig } =
createServerRunnerForAPI({ config });
// This function reference gets passed down to InternalGraphQLAPI.ts.graphql
// where this._graphql is passed in as the `fn` argument
// causing it to always get invoked inside `runWithAmplifyServerContext`
const getAmplify = (fn: (amplify: any) => Promise<any>) =>
runWithAmplifyServerContext({
nextServerContext: { cookies },
operation: contextSpec =>
fn(getAmplifyServerContext(contextSpec).amplify),
});
return generateClientWithAmplifyInstance<T, V6ClientSSRCookies<T>>({
amplify: getAmplify,
config: resourcesConfig,
authMode,
authToken,
});
}
/**
* Generates an API client that can be used with both Pages Router and App Router
*
* @example
* import config from './amplifyconfiguration.json';
* import { listPosts } from './graphql/queries';
*
* const client = generateServerClientUsingReqRes({ config });
*
* const result = await runWithAmplifyServerContext({
* nextServerContext: { request, response },
* operation: (contextSpec) => client.graphql(contextSpec, {
* query: listPosts,
* }),
* });
*/
export function generateServerClientUsingReqRes<
T extends Record<any, any> = never,
>({ config, authMode, authToken }: ReqClientParams): V6ClientSSRRequest<T> {
const amplifyConfig = parseAmplifyConfig(config);
return generateClient<T>({
config: amplifyConfig,
authMode,
authToken,
});
}