@ttoss/appsync-api 0.22.15 → 0.23.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 +52 -0
- package/dist/esm/index.js +11 -3
- package/dist/index.d.mts +34 -3
- package/dist/index.d.ts +34 -3
- package/dist/index.js +11 -3
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -69,6 +69,58 @@ The `createAppSyncResolverHandler` function adds the `context` object to the res
|
|
|
69
69
|
- `request` - AppSync request object (see [Request section](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)).
|
|
70
70
|
- `identity` - AppSync identity object (see [Identity section](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)).
|
|
71
71
|
|
|
72
|
+
### createContext
|
|
73
|
+
|
|
74
|
+
Use `createContext` to enrich the resolver context once per request. Its return value is shallow-merged into the base context, making it available to every resolver. This is the recommended way to resolve per-request values like a `userId` from Cognito:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { createAppSyncResolverHandler } from '@ttoss/appsync-api';
|
|
78
|
+
import { schemaComposer } from './schemaComposer';
|
|
79
|
+
import { getUserIdFromCognitoSub } from './auth';
|
|
80
|
+
|
|
81
|
+
export const handler = createAppSyncResolverHandler({
|
|
82
|
+
schemaComposer,
|
|
83
|
+
createContext: async ({ identity }) => ({
|
|
84
|
+
userId: await getUserIdFromCognitoSub(identity?.sub),
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Every resolver then receives `context.userId` without having to derive it individually.
|
|
90
|
+
|
|
91
|
+
### Middlewares
|
|
92
|
+
|
|
93
|
+
You can use [`graphql-middleware`](https://github.com/dimatill/graphql-middleware)-compatible middlewares via the `middlewares` option. Each middleware wraps the resolver — code before `resolve()` runs **before** the resolver, code after runs **after**.
|
|
94
|
+
|
|
95
|
+
In AppSync, each Lambda invocation handles a single field, so a middleware runs exactly once per request.
|
|
96
|
+
Use `middlewares` for authorization rules or cross-cutting logic (logging, tracing). Combine with `createContext` for per-request context enrichment:
|
|
97
|
+
|
|
98
|
+
| | `createContext` | `middlewares` |
|
|
99
|
+
| ------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
100
|
+
| Runs | Once per request | Once per resolver call |
|
|
101
|
+
| Purpose | Enrich context (e.g. `userId`) | Auth rules, logging, before/after logic |
|
|
102
|
+
| Can block execution | On error (request fails if `createContext` rejects/throws) | Yes (can conditionally block by not calling `resolve` or throwing) |
|
|
103
|
+
|
|
104
|
+
#### Authorization with GraphQL Shield
|
|
105
|
+
|
|
106
|
+
Use [GraphQL Shield](https://the-guild.dev/graphql/shield) to add authorization rules:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { allow, deny, shield } from '@ttoss/graphql-api/shield';
|
|
110
|
+
|
|
111
|
+
const permissions = shield(
|
|
112
|
+
{
|
|
113
|
+
Query: { '*': deny, me: allow },
|
|
114
|
+
},
|
|
115
|
+
{ fallbackRule: deny }
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
export const handler = createAppSyncResolverHandler({
|
|
119
|
+
schemaComposer,
|
|
120
|
+
middlewares: [permissions],
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
72
124
|
### Custom domain name
|
|
73
125
|
|
|
74
126
|
You can add a custom domain name to your API using the `customDomain` option.
|
package/dist/esm/index.js
CHANGED
|
@@ -100,12 +100,15 @@ var createApiTemplate = /* @__PURE__ */__name(({
|
|
|
100
100
|
Layers: lambdaFunction.layers,
|
|
101
101
|
MemorySize: 512,
|
|
102
102
|
Role: lambdaFunction.roleArn,
|
|
103
|
-
|
|
103
|
+
/**
|
|
104
|
+
* https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-supported
|
|
105
|
+
*/
|
|
106
|
+
Runtime: "nodejs24.x",
|
|
104
107
|
/**
|
|
105
108
|
* https://docs.aws.amazon.com/general/latest/gr/appsync.html
|
|
106
109
|
* Request execution time for mutations, queries, and subscriptions: 30 seconds
|
|
107
110
|
*/
|
|
108
|
-
Timeout:
|
|
111
|
+
Timeout: 30
|
|
109
112
|
}
|
|
110
113
|
},
|
|
111
114
|
[AppSyncLambdaFunctionAppSyncDataSourceLogicalId]: {
|
|
@@ -281,6 +284,7 @@ var createApiTemplate = /* @__PURE__ */__name(({
|
|
|
281
284
|
// src/createAppSyncResolverHandler.ts
|
|
282
285
|
import { buildSchema } from "@ttoss/graphql-api";
|
|
283
286
|
var createAppSyncResolverHandler = /* @__PURE__ */__name(({
|
|
287
|
+
createContext,
|
|
284
288
|
...buildSchemaInput
|
|
285
289
|
}) => {
|
|
286
290
|
return async (event, appSyncHandlerContext) => {
|
|
@@ -297,11 +301,15 @@ var createAppSyncResolverHandler = /* @__PURE__ */__name(({
|
|
|
297
301
|
parentTypeName,
|
|
298
302
|
fieldName
|
|
299
303
|
} = info;
|
|
300
|
-
const
|
|
304
|
+
const baseContext = {
|
|
301
305
|
handler: appSyncHandlerContext,
|
|
302
306
|
request,
|
|
303
307
|
identity: event.identity
|
|
304
308
|
};
|
|
309
|
+
const context = createContext ? {
|
|
310
|
+
...baseContext,
|
|
311
|
+
...(await createContext(baseContext))
|
|
312
|
+
} : baseContext;
|
|
305
313
|
const schema = buildSchema(buildSchemaInput);
|
|
306
314
|
const parentType = schema.getType(parentTypeName);
|
|
307
315
|
if (!parentType) {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _ttoss_graphql_api from '@ttoss/graphql-api';
|
|
2
2
|
import { SchemaComposer, BuildSchemaInput } from '@ttoss/graphql-api';
|
|
3
|
-
import { AppSyncResolverHandler as AppSyncResolverHandler$1 } from 'aws-lambda';
|
|
3
|
+
import { AppSyncResolverHandler as AppSyncResolverHandler$1, Context, AppSyncIdentity } from 'aws-lambda';
|
|
4
4
|
export { AppSyncIdentityCognito } from 'aws-lambda';
|
|
5
5
|
|
|
6
6
|
type CloudFormationRef = {
|
|
@@ -110,7 +110,38 @@ declare const createApiTemplate: ({ additionalAuthenticationProviders, authentic
|
|
|
110
110
|
}) => CloudFormationTemplate;
|
|
111
111
|
|
|
112
112
|
type AppSyncResolverHandler<TArguments, TResult, TSource = Record<string, any> | null> = AppSyncResolverHandler$1<TArguments, TResult, TSource>;
|
|
113
|
-
|
|
113
|
+
/**
|
|
114
|
+
* The base context object passed to all AppSync resolvers.
|
|
115
|
+
*/
|
|
116
|
+
type BaseAppSyncContext = {
|
|
117
|
+
/** The raw Lambda invocation context. */
|
|
118
|
+
handler: Context;
|
|
119
|
+
/** The AppSync request object (includes headers). */
|
|
120
|
+
request: any;
|
|
121
|
+
/** The caller's identity (Cognito, IAM, Lambda, or OIDC). Null when using API key auth. */
|
|
122
|
+
identity: AppSyncIdentity | null | undefined;
|
|
123
|
+
};
|
|
124
|
+
declare const createAppSyncResolverHandler: ({ createContext, ...buildSchemaInput }: BuildSchemaInput & {
|
|
125
|
+
/**
|
|
126
|
+
* Optional async function called once per request to enrich the resolver
|
|
127
|
+
* context. The returned object is shallow-merged into the base context and
|
|
128
|
+
* made available to every resolver.
|
|
129
|
+
*
|
|
130
|
+
* Use this for per-request setup such as resolving a `userId` from Cognito.
|
|
131
|
+
* For authorization rules or before/after resolver logic, prefer `middlewares`.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* createAppSyncResolverHandler({
|
|
136
|
+
* schemaComposer,
|
|
137
|
+
* createContext: async ({ identity }) => ({
|
|
138
|
+
* userId: await getUserIdFromCognitoSub(identity?.sub),
|
|
139
|
+
* }),
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
createContext?: (baseContext: BaseAppSyncContext) => Promise<Record<string, any>> | Record<string, any>;
|
|
144
|
+
}) => AppSyncResolverHandler<any, any, any>;
|
|
114
145
|
|
|
115
146
|
/** AWS AppSync scalar for JSON data. Represents a JSON object or array. */
|
|
116
147
|
declare const AWSJSONTC: _ttoss_graphql_api.ScalarTypeComposer<any>;
|
|
@@ -131,4 +162,4 @@ declare const AWSPhoneTC: _ttoss_graphql_api.ScalarTypeComposer<any>;
|
|
|
131
162
|
/** AWS AppSync scalar for IPv4 and IPv6 addresses. */
|
|
132
163
|
declare const AWSIPAddressTC: _ttoss_graphql_api.ScalarTypeComposer<any>;
|
|
133
164
|
|
|
134
|
-
export { AWSDateTC, AWSDateTimeTC, AWSEmailTC, AWSIPAddressTC, AWSJSONTC, AWSPhoneTC, AWSTimeTC, AWSTimestampTC, AWSURLTC, type AppSyncResolverHandler, createApiTemplate, createAppSyncResolverHandler };
|
|
165
|
+
export { AWSDateTC, AWSDateTimeTC, AWSEmailTC, AWSIPAddressTC, AWSJSONTC, AWSPhoneTC, AWSTimeTC, AWSTimestampTC, AWSURLTC, type AppSyncResolverHandler, type BaseAppSyncContext, createApiTemplate, createAppSyncResolverHandler };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _ttoss_graphql_api from '@ttoss/graphql-api';
|
|
2
2
|
import { SchemaComposer, BuildSchemaInput } from '@ttoss/graphql-api';
|
|
3
|
-
import { AppSyncResolverHandler as AppSyncResolverHandler$1 } from 'aws-lambda';
|
|
3
|
+
import { AppSyncResolverHandler as AppSyncResolverHandler$1, Context, AppSyncIdentity } from 'aws-lambda';
|
|
4
4
|
export { AppSyncIdentityCognito } from 'aws-lambda';
|
|
5
5
|
|
|
6
6
|
type CloudFormationRef = {
|
|
@@ -110,7 +110,38 @@ declare const createApiTemplate: ({ additionalAuthenticationProviders, authentic
|
|
|
110
110
|
}) => CloudFormationTemplate;
|
|
111
111
|
|
|
112
112
|
type AppSyncResolverHandler<TArguments, TResult, TSource = Record<string, any> | null> = AppSyncResolverHandler$1<TArguments, TResult, TSource>;
|
|
113
|
-
|
|
113
|
+
/**
|
|
114
|
+
* The base context object passed to all AppSync resolvers.
|
|
115
|
+
*/
|
|
116
|
+
type BaseAppSyncContext = {
|
|
117
|
+
/** The raw Lambda invocation context. */
|
|
118
|
+
handler: Context;
|
|
119
|
+
/** The AppSync request object (includes headers). */
|
|
120
|
+
request: any;
|
|
121
|
+
/** The caller's identity (Cognito, IAM, Lambda, or OIDC). Null when using API key auth. */
|
|
122
|
+
identity: AppSyncIdentity | null | undefined;
|
|
123
|
+
};
|
|
124
|
+
declare const createAppSyncResolverHandler: ({ createContext, ...buildSchemaInput }: BuildSchemaInput & {
|
|
125
|
+
/**
|
|
126
|
+
* Optional async function called once per request to enrich the resolver
|
|
127
|
+
* context. The returned object is shallow-merged into the base context and
|
|
128
|
+
* made available to every resolver.
|
|
129
|
+
*
|
|
130
|
+
* Use this for per-request setup such as resolving a `userId` from Cognito.
|
|
131
|
+
* For authorization rules or before/after resolver logic, prefer `middlewares`.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* createAppSyncResolverHandler({
|
|
136
|
+
* schemaComposer,
|
|
137
|
+
* createContext: async ({ identity }) => ({
|
|
138
|
+
* userId: await getUserIdFromCognitoSub(identity?.sub),
|
|
139
|
+
* }),
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
createContext?: (baseContext: BaseAppSyncContext) => Promise<Record<string, any>> | Record<string, any>;
|
|
144
|
+
}) => AppSyncResolverHandler<any, any, any>;
|
|
114
145
|
|
|
115
146
|
/** AWS AppSync scalar for JSON data. Represents a JSON object or array. */
|
|
116
147
|
declare const AWSJSONTC: _ttoss_graphql_api.ScalarTypeComposer<any>;
|
|
@@ -131,4 +162,4 @@ declare const AWSPhoneTC: _ttoss_graphql_api.ScalarTypeComposer<any>;
|
|
|
131
162
|
/** AWS AppSync scalar for IPv4 and IPv6 addresses. */
|
|
132
163
|
declare const AWSIPAddressTC: _ttoss_graphql_api.ScalarTypeComposer<any>;
|
|
133
164
|
|
|
134
|
-
export { AWSDateTC, AWSDateTimeTC, AWSEmailTC, AWSIPAddressTC, AWSJSONTC, AWSPhoneTC, AWSTimeTC, AWSTimestampTC, AWSURLTC, type AppSyncResolverHandler, createApiTemplate, createAppSyncResolverHandler };
|
|
165
|
+
export { AWSDateTC, AWSDateTimeTC, AWSEmailTC, AWSIPAddressTC, AWSJSONTC, AWSPhoneTC, AWSTimeTC, AWSTimestampTC, AWSURLTC, type AppSyncResolverHandler, type BaseAppSyncContext, createApiTemplate, createAppSyncResolverHandler };
|
package/dist/index.js
CHANGED
|
@@ -140,12 +140,15 @@ var createApiTemplate = /* @__PURE__ */__name(({
|
|
|
140
140
|
Layers: lambdaFunction.layers,
|
|
141
141
|
MemorySize: 512,
|
|
142
142
|
Role: lambdaFunction.roleArn,
|
|
143
|
-
|
|
143
|
+
/**
|
|
144
|
+
* https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-supported
|
|
145
|
+
*/
|
|
146
|
+
Runtime: "nodejs24.x",
|
|
144
147
|
/**
|
|
145
148
|
* https://docs.aws.amazon.com/general/latest/gr/appsync.html
|
|
146
149
|
* Request execution time for mutations, queries, and subscriptions: 30 seconds
|
|
147
150
|
*/
|
|
148
|
-
Timeout:
|
|
151
|
+
Timeout: 30
|
|
149
152
|
}
|
|
150
153
|
},
|
|
151
154
|
[AppSyncLambdaFunctionAppSyncDataSourceLogicalId]: {
|
|
@@ -321,6 +324,7 @@ var createApiTemplate = /* @__PURE__ */__name(({
|
|
|
321
324
|
// src/createAppSyncResolverHandler.ts
|
|
322
325
|
var import_graphql_api2 = require("@ttoss/graphql-api");
|
|
323
326
|
var createAppSyncResolverHandler = /* @__PURE__ */__name(({
|
|
327
|
+
createContext,
|
|
324
328
|
...buildSchemaInput
|
|
325
329
|
}) => {
|
|
326
330
|
return async (event, appSyncHandlerContext) => {
|
|
@@ -337,11 +341,15 @@ var createAppSyncResolverHandler = /* @__PURE__ */__name(({
|
|
|
337
341
|
parentTypeName,
|
|
338
342
|
fieldName
|
|
339
343
|
} = info;
|
|
340
|
-
const
|
|
344
|
+
const baseContext = {
|
|
341
345
|
handler: appSyncHandlerContext,
|
|
342
346
|
request,
|
|
343
347
|
identity: event.identity
|
|
344
348
|
};
|
|
349
|
+
const context = createContext ? {
|
|
350
|
+
...baseContext,
|
|
351
|
+
...(await createContext(baseContext))
|
|
352
|
+
} : baseContext;
|
|
345
353
|
const schema = (0, import_graphql_api2.buildSchema)(buildSchemaInput);
|
|
346
354
|
const parentType = schema.getType(parentTypeName);
|
|
347
355
|
if (!parentType) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/appsync-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "A library for building GraphQL APIs for AWS AppSync.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ttoss",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"graphql-shield": "^7.6.5",
|
|
37
37
|
"jest": "^30.2.0",
|
|
38
38
|
"tsup": "^8.5.1",
|
|
39
|
+
"@ttoss/graphql-api": "^0.8.17",
|
|
39
40
|
"@ttoss/config": "^1.36.0",
|
|
40
|
-
"@ttoss/ids": "^0.3.14"
|
|
41
|
-
"@ttoss/graphql-api": "^0.8.17"
|
|
41
|
+
"@ttoss/ids": "^0.3.14"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"api",
|