nextjs-hasura-auth 0.1.0
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.
- package/APOLLO.md +148 -0
- package/GENERATOR.md +671 -0
- package/README.md +154 -0
- package/dist/lib/apollo.d.ts +45 -0
- package/dist/lib/apollo.js +206 -0
- package/dist/lib/debug.d.ts +12 -0
- package/dist/lib/debug.js +24 -0
- package/dist/lib/generator.d.ts +33 -0
- package/dist/lib/generator.js +548 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.js +20 -0
- package/dist/lib/jwt.d.ts +67 -0
- package/dist/lib/jwt.js +195 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +8 -0
- package/dist/package.json +113 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +116 -0
package/APOLLO.md
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# Apollo Client Setup (`APOLLO.md`)
|
2
|
+
|
3
|
+
This document describes the configured Apollo Client instance used in this project (`lib/apolloClient.ts` or similar) for interacting with the Hasura GraphQL API.
|
4
|
+
|
5
|
+
## Purpose
|
6
|
+
|
7
|
+
The Apollo Client setup provides a unified interface for sending GraphQL queries, mutations, and subscriptions to Hasura, automatically handling authentication based on the user's session.
|
8
|
+
|
9
|
+
## Key Features
|
10
|
+
|
11
|
+
* **Split Link:** Intelligently routes GraphQL operations:
|
12
|
+
* **HTTP Requests (Queries/Mutations):** Sent via a secure Next.js API route (`/api/graphql-proxy` or equivalent). This proxy uses the user's session JWT to make authenticated requests to Hasura using the `HASURA_ADMIN_SECRET`, keeping the admin secret safe.
|
13
|
+
* **WebSocket Connections (Subscriptions):** Establishes a direct WebSocket connection to the Hasura endpoint (`NEXT_PUBLIC_HASURA_WS_ENDPOINT`).
|
14
|
+
* **Automatic Authentication:**
|
15
|
+
* **HTTP:** The proxy handles injecting appropriate `X-Hasura-*` headers based on the user's session JWT.
|
16
|
+
* **WS:** The WebSocket link automatically includes the user's session JWT in the `connectionParams` for Hasura to authenticate the connection.
|
17
|
+
* **Server-Side Rendering (SSR) / Static Site Generation (SSG) Compatibility:** The client can be initialized and used server-side for pre-fetching data.
|
18
|
+
* **Client-Side Usage:** Seamless integration with Apollo Client's React hooks (`useQuery`, `useMutation`, `useSubscription`).
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
### Client-Side (React Components)
|
23
|
+
|
24
|
+
1. **Wrap your application (or relevant layout) with `ApolloProvider`:**
|
25
|
+
This is typically done in your root layout file (`app/layout.tsx` or `pages/_app.tsx`). You'll need a way to get the initialized Apollo Client instance.
|
26
|
+
|
27
|
+
```typescript
|
28
|
+
// Example in app/layout.tsx (simplified)
|
29
|
+
'use client' // ApolloProvider likely requires client-side context
|
30
|
+
|
31
|
+
import { ApolloProvider } from '@apollo/client';
|
32
|
+
import { getClient } from '../lib/apolloClient'; // Adjust path as needed
|
33
|
+
import { SessionProvider } from 'next-auth/react'; // Needed for hooks to get session token
|
34
|
+
|
35
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
36
|
+
// Create Apollo Client using the token from the session if it exists
|
37
|
+
const client = useClient(useMemo(() => ({
|
38
|
+
token: session?.accessToken, // Pass Hasura token from session
|
39
|
+
ws: true // Enable WebSocket support
|
40
|
+
}), [session]));
|
41
|
+
|
42
|
+
return (
|
43
|
+
<html lang="en">
|
44
|
+
<body>
|
45
|
+
{/* SessionProvider needed for auth state access */}
|
46
|
+
<SessionProvider>
|
47
|
+
<ApolloProvider client={client}>
|
48
|
+
{children}
|
49
|
+
</ApolloProvider>
|
50
|
+
</SessionProvider>
|
51
|
+
</body>
|
52
|
+
</html>
|
53
|
+
);
|
54
|
+
}
|
55
|
+
```
|
56
|
+
|
57
|
+
2. **Use Apollo Hooks in Components:**
|
58
|
+
Import and use hooks like `useQuery`, `useMutation`, or `useSubscription` directly in your components. Combine with the `Generator` for dynamic queries (see [`GENERATOR.md`](GENERATOR.md)).
|
59
|
+
|
60
|
+
```typescript
|
61
|
+
import { useQuery } from '@apollo/client';
|
62
|
+
import { Generator, GenerateOptions } from 'nextjs-hasura-auth'; // Assuming Generator is exported
|
63
|
+
// import schema from '...'; // Load schema
|
64
|
+
|
65
|
+
// const generate = Generator(schema);
|
66
|
+
|
67
|
+
function UserProfile({ userId }) {
|
68
|
+
// Example using Generator (assuming you have generate function)
|
69
|
+
// const { query, variables } = generate({
|
70
|
+
// operation: 'query',
|
71
|
+
// table: 'users',
|
72
|
+
// pk_columns: { id: userId },
|
73
|
+
// returning: ['id', 'name', 'email']
|
74
|
+
// });
|
75
|
+
|
76
|
+
// Or use a manually written query
|
77
|
+
const GET_USER = gql`
|
78
|
+
query GetUser($userId: uuid!) {
|
79
|
+
users_by_pk(id: $userId) {
|
80
|
+
id
|
81
|
+
name
|
82
|
+
email
|
83
|
+
}
|
84
|
+
}
|
85
|
+
`;
|
86
|
+
const { loading, error, data } = useQuery(GET_USER, {
|
87
|
+
variables: { userId }
|
88
|
+
});
|
89
|
+
|
90
|
+
if (loading) return <p>Loading...</p>;
|
91
|
+
if (error) return <p>Error: {error.message}</p>;
|
92
|
+
|
93
|
+
return (
|
94
|
+
<div>
|
95
|
+
<h1>{data.users_by_pk.name}</h1>
|
96
|
+
<p>{data.users_by_pk.email}</p>
|
97
|
+
</div>
|
98
|
+
);
|
99
|
+
}
|
100
|
+
```
|
101
|
+
|
102
|
+
### Server-Side (SSR/SSG/Server Components)
|
103
|
+
|
104
|
+
1. **Get Client Instance:** Obtain the Apollo Client instance, potentially re-initializing it for server-side scope if necessary.
|
105
|
+
2. **Fetch Data:** Use `client.query(...)` or `client.mutate(...)` directly.
|
106
|
+
|
107
|
+
```typescript
|
108
|
+
// Example in a Server Component or getStaticProps/getServerSideProps
|
109
|
+
import { getClient } from '../lib/apolloClient'; // Adjust path
|
110
|
+
// import { Generator } from 'nextjs-hasura-auth';
|
111
|
+
// import schema from '...';
|
112
|
+
// const generate = Generator(schema);
|
113
|
+
|
114
|
+
async function getUserData(userId) {
|
115
|
+
const client = getClient(); // Get client instance
|
116
|
+
|
117
|
+
// const { query, variables } = generate({ ... });
|
118
|
+
const GET_USER = gql`...`; // Your query
|
119
|
+
|
120
|
+
try {
|
121
|
+
const { data } = await client.query({
|
122
|
+
query: GET_USER, // Use generated or manual query
|
123
|
+
variables: { userId },
|
124
|
+
// Ensure proper fetch policy for server-side needs
|
125
|
+
fetchPolicy: 'network-only',
|
126
|
+
});
|
127
|
+
return data.users_by_pk;
|
128
|
+
} catch (error) {
|
129
|
+
console.error('Error fetching user data:', error);
|
130
|
+
return null;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
```
|
134
|
+
|
135
|
+
## Configuration (`lib/apolloClient.ts`)
|
136
|
+
|
137
|
+
The core logic resides in `lib/apolloClient.ts` (or a similar file). It typically involves:
|
138
|
+
|
139
|
+
1. **Creating an `HttpLink`:** Points to the Next.js GraphQL proxy (e.g., `/api/graphql-proxy`).
|
140
|
+
2. **Creating a `WebSocketLink`:**
|
141
|
+
* Uses the `graphql-ws` library.
|
142
|
+
* Connects to `NEXT_PUBLIC_HASURA_WS_ENDPOINT`.
|
143
|
+
* Configures `connectionParams` to dynamically fetch the session JWT (e.g., using `getSession()` from `next-auth/react` or a similar mechanism) and include it as `{ headers: { Authorization: Bearer <token> } }`.
|
144
|
+
3. **Using `split`:** Combines the HTTP and WebSocket links, directing operations based on their type (queries/mutations vs. subscriptions).
|
145
|
+
4. **Creating the `ApolloClient` instance:** Initializes the client with the combined link and a cache (e.g., `InMemoryCache`).
|
146
|
+
5. **Handling Singleton Pattern:** Often uses a singleton pattern to avoid creating multiple client instances, especially on the server.
|
147
|
+
|
148
|
+
*(Refer to the actual `lib/apolloClient.ts` file for the precise implementation details.)*
|