@effect-gql/persisted-queries 0.1.0 → 1.0.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/README.md +100 -0
- package/index.cjs +385 -0
- package/index.cjs.map +1 -0
- package/index.d.cts +403 -0
- package/index.d.ts +403 -0
- package/index.js +372 -0
- package/index.js.map +1 -0
- package/package.json +14 -26
- package/dist/config.d.ts +0 -106
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -27
- package/dist/config.js.map +0 -1
- package/dist/errors.d.ts +0 -77
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -77
- package/dist/errors.js.map +0 -1
- package/dist/index.d.ts +0 -56
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -71
- package/dist/index.js.map +0 -1
- package/dist/memory-store.d.ts +0 -67
- package/dist/memory-store.d.ts.map +0 -1
- package/dist/memory-store.js +0 -104
- package/dist/memory-store.js.map +0 -1
- package/dist/persisted-queries-router.d.ts +0 -58
- package/dist/persisted-queries-router.d.ts.map +0 -1
- package/dist/persisted-queries-router.js +0 -277
- package/dist/persisted-queries-router.js.map +0 -1
- package/dist/store.d.ts +0 -49
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -29
- package/dist/store.js.map +0 -1
- package/dist/utils.d.ts +0 -51
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -73
- package/dist/utils.js.map +0 -1
- package/src/config.ts +0 -122
- package/src/errors.ts +0 -107
- package/src/index.ts +0 -77
- package/src/memory-store.ts +0 -133
- package/src/persisted-queries-router.ts +0 -421
- package/src/store.ts +0 -54
- package/src/utils.ts +0 -111
package/index.d.ts
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { HttpRouter } from '@effect/platform';
|
|
2
|
+
import { Effect, Option, Context, Layer, Config } from 'effect';
|
|
3
|
+
import { GraphQLSchema } from 'graphql';
|
|
4
|
+
import { MakeGraphQLRouterOptions } from '@effect-gql/core/server';
|
|
5
|
+
import * as effect_Cause from 'effect/Cause';
|
|
6
|
+
import * as effect_Types from 'effect/Types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Interface for persisted query storage.
|
|
10
|
+
*
|
|
11
|
+
* Implementations can be in-memory LRU cache, Redis, database, etc.
|
|
12
|
+
* The interface uses Effect for consistency with the rest of the framework.
|
|
13
|
+
*/
|
|
14
|
+
interface PersistedQueryStore {
|
|
15
|
+
/**
|
|
16
|
+
* Get a query by its hash.
|
|
17
|
+
* Returns Option.none() if not found.
|
|
18
|
+
*/
|
|
19
|
+
readonly get: (hash: string) => Effect.Effect<Option.Option<string>>;
|
|
20
|
+
/**
|
|
21
|
+
* Store a query with its hash.
|
|
22
|
+
* In safelist mode, this may be a no-op.
|
|
23
|
+
*/
|
|
24
|
+
readonly set: (hash: string, query: string) => Effect.Effect<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a hash exists in the store without retrieving the query.
|
|
27
|
+
* More efficient for large queries when you only need existence check.
|
|
28
|
+
*/
|
|
29
|
+
readonly has: (hash: string) => Effect.Effect<boolean>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Service tag for the PersistedQueryStore.
|
|
33
|
+
*
|
|
34
|
+
* Use this tag to provide a store implementation via Effect's dependency injection.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* import { PersistedQueryStore, makeMemoryStore } from "@effect-gql/persisted-queries"
|
|
39
|
+
*
|
|
40
|
+
* // Create a layer with the memory store
|
|
41
|
+
* const storeLayer = makeMemoryStore({ maxSize: 1000 })
|
|
42
|
+
*
|
|
43
|
+
* // Use in an Effect
|
|
44
|
+
* const program = Effect.gen(function* () {
|
|
45
|
+
* const store = yield* PersistedQueryStore
|
|
46
|
+
* yield* store.set("abc123", "query { hello }")
|
|
47
|
+
* const query = yield* store.get("abc123")
|
|
48
|
+
* // query: Option.some("query { hello }")
|
|
49
|
+
* })
|
|
50
|
+
*
|
|
51
|
+
* Effect.runPromise(Effect.provide(program, storeLayer))
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
declare const PersistedQueryStore: Context.Tag<PersistedQueryStore, PersistedQueryStore>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Operating mode for persisted queries.
|
|
58
|
+
*
|
|
59
|
+
* - `"apq"`: Automatic Persisted Queries - clients can register queries at runtime
|
|
60
|
+
* - `"safelist"`: Only pre-registered queries are allowed (security mode)
|
|
61
|
+
*/
|
|
62
|
+
type PersistedQueryMode = "apq" | "safelist";
|
|
63
|
+
/**
|
|
64
|
+
* Hash algorithm used for query hashing.
|
|
65
|
+
* Must match what clients use - Apollo clients use SHA-256.
|
|
66
|
+
*/
|
|
67
|
+
type HashAlgorithm = "sha256" | "sha512";
|
|
68
|
+
/**
|
|
69
|
+
* Configuration for the persisted queries feature.
|
|
70
|
+
*/
|
|
71
|
+
interface PersistedQueriesConfig {
|
|
72
|
+
/**
|
|
73
|
+
* Operating mode.
|
|
74
|
+
*
|
|
75
|
+
* - `"apq"`: Automatic Persisted Queries - clients can register queries at runtime.
|
|
76
|
+
* Unknown hashes trigger PERSISTED_QUERY_NOT_FOUND, prompting clients to retry with query.
|
|
77
|
+
*
|
|
78
|
+
* - `"safelist"`: Only pre-registered queries are allowed.
|
|
79
|
+
* Unknown hashes return PERSISTED_QUERY_NOT_ALLOWED error.
|
|
80
|
+
* Use with `makeSafelistStore()` for production security.
|
|
81
|
+
*
|
|
82
|
+
* Default: `"apq"`
|
|
83
|
+
*/
|
|
84
|
+
readonly mode?: PersistedQueryMode;
|
|
85
|
+
/**
|
|
86
|
+
* Layer providing the PersistedQueryStore service.
|
|
87
|
+
*
|
|
88
|
+
* Defaults to in-memory LRU store with 1000 entries.
|
|
89
|
+
* Use `makeMemoryStore()` for custom size or `makeSafelistStore()` for safelist mode.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* // Custom memory store
|
|
94
|
+
* store: makeMemoryStore({ maxSize: 5000 })
|
|
95
|
+
*
|
|
96
|
+
* // Safelist store
|
|
97
|
+
* store: makeSafelistStore({ "hash1": "query {...}", "hash2": "query {...}" })
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
readonly store?: Layer.Layer<PersistedQueryStore>;
|
|
101
|
+
/**
|
|
102
|
+
* Whether to support GET requests with query parameters.
|
|
103
|
+
*
|
|
104
|
+
* When enabled, the router accepts:
|
|
105
|
+
* ```
|
|
106
|
+
* GET /graphql?extensions={"persistedQuery":{"version":1,"sha256Hash":"..."}}&variables={...}&operationName=...
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* This enables CDN caching since the same hash always maps to the same URL.
|
|
110
|
+
*
|
|
111
|
+
* Default: `true`
|
|
112
|
+
*/
|
|
113
|
+
readonly enableGet?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Validate that the provided query matches its hash when storing.
|
|
116
|
+
*
|
|
117
|
+
* This prevents hash collision attacks where a malicious client could
|
|
118
|
+
* register a different query under someone else's hash.
|
|
119
|
+
*
|
|
120
|
+
* Has a slight performance overhead for computing the hash.
|
|
121
|
+
*
|
|
122
|
+
* Default: `true`
|
|
123
|
+
*/
|
|
124
|
+
readonly validateHash?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Hash algorithm to use for validation.
|
|
127
|
+
* Must match what clients use - Apollo clients use SHA-256.
|
|
128
|
+
*
|
|
129
|
+
* Default: `"sha256"`
|
|
130
|
+
*/
|
|
131
|
+
readonly hashAlgorithm?: HashAlgorithm;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Options for the persisted queries router.
|
|
135
|
+
*
|
|
136
|
+
* Extends the standard GraphQL router options with persisted query configuration.
|
|
137
|
+
*/
|
|
138
|
+
interface PersistedQueriesRouterOptions extends MakeGraphQLRouterOptions, PersistedQueriesConfig {
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Effect Config for loading persisted queries settings from environment variables.
|
|
142
|
+
*
|
|
143
|
+
* Environment variables:
|
|
144
|
+
* - `PERSISTED_QUERIES_MODE`: `"apq"` | `"safelist"` (default: `"apq"`)
|
|
145
|
+
* - `PERSISTED_QUERIES_ENABLE_GET`: boolean (default: `true`)
|
|
146
|
+
* - `PERSISTED_QUERIES_VALIDATE_HASH`: boolean (default: `true`)
|
|
147
|
+
*
|
|
148
|
+
* Note: The store must still be provided programmatically.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* import { PersistedQueriesConfigFromEnv } from "@effect-gql/persisted-queries"
|
|
153
|
+
*
|
|
154
|
+
* const config = yield* Config.unwrap(PersistedQueriesConfigFromEnv)
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
declare const PersistedQueriesConfigFromEnv: Config.Config<Omit<PersistedQueriesConfig, "store">>;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Create a GraphQL router with Apollo Persisted Queries support.
|
|
161
|
+
*
|
|
162
|
+
* This creates a complete GraphQL router that includes:
|
|
163
|
+
* - Apollo Persisted Queries (APQ) support
|
|
164
|
+
* - GET request support for CDN caching
|
|
165
|
+
* - All standard GraphQL router features (validation, execution, extensions)
|
|
166
|
+
*
|
|
167
|
+
* ## Apollo APQ Protocol
|
|
168
|
+
*
|
|
169
|
+
* 1. Client sends request with `extensions.persistedQuery.sha256Hash`
|
|
170
|
+
* 2. If hash found in store, execute the stored query
|
|
171
|
+
* 3. If hash NOT found and query provided (APQ mode), store it and execute
|
|
172
|
+
* 4. If hash NOT found and NO query, return `PERSISTED_QUERY_NOT_FOUND`
|
|
173
|
+
* 5. Client retries with both hash and query
|
|
174
|
+
*
|
|
175
|
+
* ## Modes
|
|
176
|
+
*
|
|
177
|
+
* - **APQ mode** (`mode: "apq"`): Automatic runtime registration.
|
|
178
|
+
* Unknown queries trigger NOT_FOUND, prompting client retry with full query.
|
|
179
|
+
*
|
|
180
|
+
* - **Safelist mode** (`mode: "safelist"`): Pre-registered queries only.
|
|
181
|
+
* Unknown queries return NOT_ALLOWED error. Use with `makeSafelistStore()`.
|
|
182
|
+
*
|
|
183
|
+
* @example APQ Mode (default)
|
|
184
|
+
* ```typescript
|
|
185
|
+
* import { makePersistedQueriesRouter } from "@effect-gql/persisted-queries"
|
|
186
|
+
*
|
|
187
|
+
* const router = makePersistedQueriesRouter(schema, serviceLayer, {
|
|
188
|
+
* mode: "apq",
|
|
189
|
+
* enableGet: true,
|
|
190
|
+
* graphiql: { path: "/graphiql" },
|
|
191
|
+
* })
|
|
192
|
+
* ```
|
|
193
|
+
*
|
|
194
|
+
* @example Safelist Mode
|
|
195
|
+
* ```typescript
|
|
196
|
+
* import { makePersistedQueriesRouter, makeSafelistStore } from "@effect-gql/persisted-queries"
|
|
197
|
+
*
|
|
198
|
+
* const router = makePersistedQueriesRouter(schema, serviceLayer, {
|
|
199
|
+
* mode: "safelist",
|
|
200
|
+
* store: makeSafelistStore({
|
|
201
|
+
* "abc123...": "query GetUser($id: ID!) { user(id: $id) { name } }",
|
|
202
|
+
* }),
|
|
203
|
+
* })
|
|
204
|
+
* ```
|
|
205
|
+
*
|
|
206
|
+
* @param schema - The GraphQL schema
|
|
207
|
+
* @param layer - Effect layer providing services required by resolvers
|
|
208
|
+
* @param options - Router and persisted query configuration
|
|
209
|
+
* @returns An HttpRouter with persisted query support
|
|
210
|
+
*/
|
|
211
|
+
declare const makePersistedQueriesRouter: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: PersistedQueriesRouterOptions) => HttpRouter.HttpRouter<never, never>;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Configuration for the in-memory LRU store
|
|
215
|
+
*/
|
|
216
|
+
interface MemoryStoreConfig {
|
|
217
|
+
/**
|
|
218
|
+
* Maximum number of queries to cache.
|
|
219
|
+
* When exceeded, least recently used queries are evicted.
|
|
220
|
+
* Default: 1000
|
|
221
|
+
*/
|
|
222
|
+
readonly maxSize?: number;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Create an in-memory LRU (Least Recently Used) store for persisted queries.
|
|
226
|
+
*
|
|
227
|
+
* This implementation uses Map's natural insertion order for O(1) LRU operations:
|
|
228
|
+
* - get: O(1) - delete and re-insert to move to end (most recently used)
|
|
229
|
+
* - set: O(1) - insert at end, evict from front if needed
|
|
230
|
+
* - eviction: O(1) - delete first entry (least recently used)
|
|
231
|
+
*
|
|
232
|
+
* This is the default store implementation suitable for single-instance servers.
|
|
233
|
+
* For multi-instance deployments, consider using a shared store like Redis.
|
|
234
|
+
*
|
|
235
|
+
* @param config - Optional configuration for cache size
|
|
236
|
+
* @returns A Layer providing the PersistedQueryStore service
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* import { makeMemoryStore, makePersistedQueriesRouter } from "@effect-gql/persisted-queries"
|
|
241
|
+
*
|
|
242
|
+
* // Default store with 1000 entry limit
|
|
243
|
+
* const router1 = makePersistedQueriesRouter(schema, serviceLayer)
|
|
244
|
+
*
|
|
245
|
+
* // Custom store with larger cache
|
|
246
|
+
* const router2 = makePersistedQueriesRouter(schema, serviceLayer, {
|
|
247
|
+
* store: makeMemoryStore({ maxSize: 5000 })
|
|
248
|
+
* })
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
declare const makeMemoryStore: (config?: MemoryStoreConfig) => Layer.Layer<PersistedQueryStore>;
|
|
252
|
+
/**
|
|
253
|
+
* Create a pre-populated safelist store.
|
|
254
|
+
*
|
|
255
|
+
* This store only allows queries that were provided at creation time.
|
|
256
|
+
* Any attempt to store new queries is silently ignored.
|
|
257
|
+
* Use this for production security where you want to allowlist specific operations.
|
|
258
|
+
*
|
|
259
|
+
* @param queries - Record mapping SHA-256 hashes to query strings
|
|
260
|
+
* @returns A Layer providing the PersistedQueryStore service
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* import { makeSafelistStore, makePersistedQueriesRouter } from "@effect-gql/persisted-queries"
|
|
265
|
+
*
|
|
266
|
+
* // Pre-register allowed queries
|
|
267
|
+
* const router = makePersistedQueriesRouter(schema, serviceLayer, {
|
|
268
|
+
* mode: "safelist",
|
|
269
|
+
* store: makeSafelistStore({
|
|
270
|
+
* "ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38": "query GetUser($id: ID!) { user(id: $id) { name email } }",
|
|
271
|
+
* "a1b2c3d4...": "query GetPosts { posts { title } }",
|
|
272
|
+
* }),
|
|
273
|
+
* })
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
declare const makeSafelistStore: (queries: Record<string, string>) => Layer.Layer<PersistedQueryStore>;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* GraphQL error format for APQ responses.
|
|
280
|
+
* Compatible with Apollo Client's error handling.
|
|
281
|
+
*/
|
|
282
|
+
interface PersistedQueryGraphQLError {
|
|
283
|
+
readonly message: string;
|
|
284
|
+
readonly extensions: {
|
|
285
|
+
readonly code: string;
|
|
286
|
+
readonly [key: string]: unknown;
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
declare const PersistedQueryNotFoundError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
|
|
290
|
+
readonly _tag: "PersistedQueryNotFoundError";
|
|
291
|
+
} & Readonly<A>;
|
|
292
|
+
/**
|
|
293
|
+
* Error returned when a persisted query hash is not found in the store
|
|
294
|
+
* and no query body was provided.
|
|
295
|
+
*
|
|
296
|
+
* Apollo clients recognize this error and automatically retry with the full query.
|
|
297
|
+
* This is the expected flow for Automatic Persisted Queries (APQ).
|
|
298
|
+
*/
|
|
299
|
+
declare class PersistedQueryNotFoundError extends PersistedQueryNotFoundError_base<{
|
|
300
|
+
readonly hash: string;
|
|
301
|
+
}> {
|
|
302
|
+
/**
|
|
303
|
+
* Convert to GraphQL error format compatible with Apollo protocol.
|
|
304
|
+
*/
|
|
305
|
+
toGraphQLError(): PersistedQueryGraphQLError;
|
|
306
|
+
}
|
|
307
|
+
declare const PersistedQueryVersionError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
|
|
308
|
+
readonly _tag: "PersistedQueryVersionError";
|
|
309
|
+
} & Readonly<A>;
|
|
310
|
+
/**
|
|
311
|
+
* Error returned when the persisted query protocol version is not supported.
|
|
312
|
+
*
|
|
313
|
+
* Currently only version 1 is supported, which uses SHA-256 hashing.
|
|
314
|
+
*/
|
|
315
|
+
declare class PersistedQueryVersionError extends PersistedQueryVersionError_base<{
|
|
316
|
+
readonly version: number;
|
|
317
|
+
}> {
|
|
318
|
+
toGraphQLError(): PersistedQueryGraphQLError;
|
|
319
|
+
}
|
|
320
|
+
declare const PersistedQueryHashMismatchError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
|
|
321
|
+
readonly _tag: "PersistedQueryHashMismatchError";
|
|
322
|
+
} & Readonly<A>;
|
|
323
|
+
/**
|
|
324
|
+
* Error returned when the provided query doesn't match its hash.
|
|
325
|
+
*
|
|
326
|
+
* This can indicate a client bug or a potential hash collision attack.
|
|
327
|
+
* Hash validation is enabled by default and can be disabled if needed.
|
|
328
|
+
*/
|
|
329
|
+
declare class PersistedQueryHashMismatchError extends PersistedQueryHashMismatchError_base<{
|
|
330
|
+
readonly providedHash: string;
|
|
331
|
+
readonly computedHash: string;
|
|
332
|
+
}> {
|
|
333
|
+
toGraphQLError(): PersistedQueryGraphQLError;
|
|
334
|
+
}
|
|
335
|
+
declare const PersistedQueryNotAllowedError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
|
|
336
|
+
readonly _tag: "PersistedQueryNotAllowedError";
|
|
337
|
+
} & Readonly<A>;
|
|
338
|
+
/**
|
|
339
|
+
* Error returned when trying to execute a query that is not in the safelist.
|
|
340
|
+
*
|
|
341
|
+
* In safelist mode, only pre-registered queries are allowed.
|
|
342
|
+
* This error is returned when a client tries to register a new query.
|
|
343
|
+
*/
|
|
344
|
+
declare class PersistedQueryNotAllowedError extends PersistedQueryNotAllowedError_base<{
|
|
345
|
+
readonly hash: string;
|
|
346
|
+
}> {
|
|
347
|
+
toGraphQLError(): PersistedQueryGraphQLError;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Union type of all APQ-related errors
|
|
351
|
+
*/
|
|
352
|
+
type PersistedQueryError = PersistedQueryNotFoundError | PersistedQueryVersionError | PersistedQueryHashMismatchError | PersistedQueryNotAllowedError;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Compute the hash of a query string.
|
|
356
|
+
*
|
|
357
|
+
* @param query - The GraphQL query string to hash
|
|
358
|
+
* @param algorithm - Hash algorithm to use (default: sha256)
|
|
359
|
+
* @returns Effect that resolves to the hex-encoded hash
|
|
360
|
+
*/
|
|
361
|
+
declare const computeHash: (query: string, algorithm?: HashAlgorithm) => Effect.Effect<string>;
|
|
362
|
+
/**
|
|
363
|
+
* Structure of the persisted query extension in GraphQL requests.
|
|
364
|
+
* This follows the Apollo APQ protocol.
|
|
365
|
+
*/
|
|
366
|
+
interface PersistedQueryExtension {
|
|
367
|
+
readonly version: number;
|
|
368
|
+
readonly sha256Hash: string;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Parse and validate the persisted query extension from request extensions.
|
|
372
|
+
*
|
|
373
|
+
* @param extensions - The extensions object from the GraphQL request
|
|
374
|
+
* @returns The parsed persisted query extension, or null if not present/invalid
|
|
375
|
+
*/
|
|
376
|
+
declare const parsePersistedQueryExtension: (extensions: unknown) => PersistedQueryExtension | null;
|
|
377
|
+
/**
|
|
378
|
+
* GraphQL request body structure with optional persisted query extension.
|
|
379
|
+
*/
|
|
380
|
+
interface GraphQLRequestBody {
|
|
381
|
+
query?: string;
|
|
382
|
+
variables?: Record<string, unknown>;
|
|
383
|
+
operationName?: string;
|
|
384
|
+
extensions?: {
|
|
385
|
+
persistedQuery?: PersistedQueryExtension;
|
|
386
|
+
[key: string]: unknown;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Parse a GET request's query parameters into a GraphQL request body.
|
|
391
|
+
*
|
|
392
|
+
* Supports the following query parameters:
|
|
393
|
+
* - `query`: The GraphQL query string (optional with persisted queries)
|
|
394
|
+
* - `variables`: JSON-encoded variables object
|
|
395
|
+
* - `operationName`: Name of the operation to execute
|
|
396
|
+
* - `extensions`: JSON-encoded extensions object containing persistedQuery
|
|
397
|
+
*
|
|
398
|
+
* @param searchParams - URLSearchParams from the request URL
|
|
399
|
+
* @returns Effect that resolves to the parsed request body or fails with parse error
|
|
400
|
+
*/
|
|
401
|
+
declare const parseGetRequestBody: (searchParams: URLSearchParams) => Effect.Effect<GraphQLRequestBody, Error>;
|
|
402
|
+
|
|
403
|
+
export { type GraphQLRequestBody, type HashAlgorithm, type MemoryStoreConfig, type PersistedQueriesConfig, PersistedQueriesConfigFromEnv, type PersistedQueriesRouterOptions, type PersistedQueryError, type PersistedQueryExtension, type PersistedQueryGraphQLError, PersistedQueryHashMismatchError, type PersistedQueryMode, PersistedQueryNotAllowedError, PersistedQueryNotFoundError, PersistedQueryStore, PersistedQueryStore as PersistedQueryStoreInterface, PersistedQueryVersionError, computeHash, makeMemoryStore, makePersistedQueriesRouter, makeSafelistStore, parseGetRequestBody, parsePersistedQueryExtension };
|