@ttoss/appsync-api 0.4.4 → 0.5.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 +79 -0
- package/dist/cli.js +0 -3688
- package/dist/esm/chunk-5MBGDEAO.js +750 -0
- package/dist/esm/chunk-NQOARNEJ.js +27 -0
- package/dist/esm/cli.js +2 -2
- package/dist/esm/index.js +5 -4
- package/dist/esm/server.js +43 -0
- package/dist/index.d.ts +15 -5
- package/dist/index.js +62 -3786
- package/dist/server.d.ts +8 -0
- package/dist/server.js +66 -0
- package/package.json +39 -7
- package/src/cli.ts +0 -3
- package/src/createApiTemplate.ts +32 -92
- package/src/{appSyncResolverHandler.ts → createAppSyncResolverHandler.ts} +8 -2
- package/src/index.ts +4 -1
- package/src/server.ts +47 -0
- package/dist/esm/chunk-OVEYUNNE.js +0 -4498
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as express_serve_static_core from 'express-serve-static-core';
|
|
2
|
+
import { SchemaComposer } from 'graphql-compose';
|
|
3
|
+
|
|
4
|
+
declare const createServer: ({ schemaComposer, }: {
|
|
5
|
+
schemaComposer: SchemaComposer<any>;
|
|
6
|
+
}) => express_serve_static_core.Express;
|
|
7
|
+
|
|
8
|
+
export { createServer };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
26
|
+
|
|
27
|
+
// src/server.ts
|
|
28
|
+
var server_exports = {};
|
|
29
|
+
__export(server_exports, {
|
|
30
|
+
createServer: () => createServer
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(server_exports);
|
|
33
|
+
var import_graphql_helix = require("graphql-helix");
|
|
34
|
+
var import_express = __toESM(require("express"));
|
|
35
|
+
var createServer = ({
|
|
36
|
+
schemaComposer
|
|
37
|
+
}) => {
|
|
38
|
+
const server = (0, import_express.default)();
|
|
39
|
+
server.use(import_express.default.json());
|
|
40
|
+
server.use("/graphql", async (req, res) => {
|
|
41
|
+
const request = {
|
|
42
|
+
body: req.body,
|
|
43
|
+
headers: req.headers,
|
|
44
|
+
method: req.method,
|
|
45
|
+
query: req.query
|
|
46
|
+
};
|
|
47
|
+
if ((0, import_graphql_helix.shouldRenderGraphiQL)(request)) {
|
|
48
|
+
res.send((0, import_graphql_helix.renderGraphiQL)());
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const { operationName, query, variables } = (0, import_graphql_helix.getGraphQLParameters)(request);
|
|
52
|
+
const result = await (0, import_graphql_helix.processRequest)({
|
|
53
|
+
operationName,
|
|
54
|
+
query,
|
|
55
|
+
variables,
|
|
56
|
+
request,
|
|
57
|
+
schema: schemaComposer.buildSchema()
|
|
58
|
+
});
|
|
59
|
+
(0, import_graphql_helix.sendResult)(result, res);
|
|
60
|
+
});
|
|
61
|
+
return server;
|
|
62
|
+
};
|
|
63
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
64
|
+
0 && (module.exports = {
|
|
65
|
+
createServer
|
|
66
|
+
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/appsync-api",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "A library for building GraphQL APIs for AWS AppSync.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "ttoss",
|
|
7
7
|
"contributors": [
|
|
8
8
|
"Pedro Arantes <pedro@arantespp.com> (https://arantespp.com)"
|
|
9
9
|
],
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/esm/index.js",
|
|
13
|
+
"require": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./server": {
|
|
16
|
+
"import": "./dist/esm/server.js",
|
|
17
|
+
"require": "./dist/server.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
10
20
|
"main": "dist/index.js",
|
|
11
21
|
"module": "dist/esm/index.js",
|
|
12
22
|
"bin": {
|
|
@@ -20,21 +30,43 @@
|
|
|
20
30
|
"build": "tsup",
|
|
21
31
|
"test": "jest"
|
|
22
32
|
},
|
|
33
|
+
"sideEffects": false,
|
|
23
34
|
"typings": "dist/index.d.ts",
|
|
24
35
|
"dependencies": {
|
|
25
36
|
"@ttoss/cloudformation": "^0.3.0",
|
|
26
|
-
"
|
|
27
|
-
"graphql-
|
|
37
|
+
"express": "^4.18.2",
|
|
38
|
+
"graphql-helix": "^1.13.0",
|
|
28
39
|
"minimist": "^1.2.7"
|
|
29
40
|
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"graphql": "^16.6.0",
|
|
43
|
+
"graphql-compose": "^9.0.10"
|
|
44
|
+
},
|
|
30
45
|
"devDependencies": {
|
|
31
46
|
"@ttoss/config": "^1.26.0",
|
|
32
47
|
"@types/aws-lambda": "^8.10.109",
|
|
33
|
-
"carlin": "^1.21.4"
|
|
48
|
+
"carlin": "^1.21.4",
|
|
49
|
+
"graphql": "^16.6.0",
|
|
50
|
+
"graphql-compose": "^9.0.10"
|
|
34
51
|
},
|
|
35
|
-
"keywords": [
|
|
52
|
+
"keywords": [
|
|
53
|
+
"api",
|
|
54
|
+
"appsync",
|
|
55
|
+
"aws",
|
|
56
|
+
"graphql"
|
|
57
|
+
],
|
|
36
58
|
"publishConfig": {
|
|
37
59
|
"access": "public"
|
|
38
60
|
},
|
|
39
|
-
"
|
|
61
|
+
"typesVersions": {
|
|
62
|
+
"*": {
|
|
63
|
+
".": [
|
|
64
|
+
"./dist/index.d.ts"
|
|
65
|
+
],
|
|
66
|
+
"server": [
|
|
67
|
+
"./dist/server.d.ts"
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"gitHead": "702cb6f1dd3411f53c5172eb50ce9d5e3fa5c3cc"
|
|
40
72
|
}
|
package/src/cli.ts
CHANGED
|
@@ -11,9 +11,6 @@ if (argv._.includes('build-schema')) {
|
|
|
11
11
|
const sdl =
|
|
12
12
|
template.Resources[AppSyncGraphQLSchemaLogicalId].Properties.Definition;
|
|
13
13
|
|
|
14
|
-
// eslint-disable-next-line no-console
|
|
15
|
-
console.log(sdl);
|
|
16
|
-
|
|
17
14
|
/**
|
|
18
15
|
* Save to schema/schema.graphql. schema folder might not exist.
|
|
19
16
|
*/
|
package/src/createApiTemplate.ts
CHANGED
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import { type SchemaComposer, graphql } from 'graphql-compose';
|
|
2
2
|
import { getPackageLambdaLayerStackName } from 'carlin/src/deploy/lambdaLayer/getPackageLambdaLayerStackName';
|
|
3
|
-
import { readPackageJson } from 'carlin/src/utils/packageJson';
|
|
4
3
|
import packageJson from '../package.json';
|
|
5
|
-
import type { CloudFormationTemplate } from '
|
|
4
|
+
import type { CloudFormationTemplate } from '@ttoss/cloudformation';
|
|
6
5
|
|
|
7
6
|
const AppSyncGraphQLApiLogicalId = 'AppSyncGraphQLApi';
|
|
8
7
|
|
|
9
8
|
export const AppSyncGraphQLSchemaLogicalId = 'AppSyncGraphQLSchema';
|
|
10
9
|
|
|
11
|
-
const AppSyncLambdaFunctionIAMRoleLogicalId = 'AppSyncLambdaFunctionIAMRole';
|
|
12
|
-
|
|
13
10
|
export const AppSyncLambdaFunctionLogicalId = 'AppSyncLambdaFunction';
|
|
14
11
|
|
|
15
|
-
const AppSyncLambdaFunctionAppSyncDataSourceIAMRoleLogicalId =
|
|
16
|
-
'AppSyncLambdaFunctionAppSyncDataSourceIAMRole';
|
|
17
|
-
|
|
18
12
|
const AppSyncLambdaFunctionAppSyncDataSourceLogicalId =
|
|
19
13
|
'AppSyncLambdaFunctionAppSyncDataSource';
|
|
20
14
|
|
|
15
|
+
type Role =
|
|
16
|
+
| string
|
|
17
|
+
| {
|
|
18
|
+
'Fn::ImportValue': string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
21
|
export const createApiTemplate = ({
|
|
22
22
|
schemaComposer,
|
|
23
|
+
dataSource,
|
|
24
|
+
lambdaFunction,
|
|
23
25
|
}: {
|
|
24
26
|
schemaComposer: SchemaComposer<any>;
|
|
27
|
+
dataSource: {
|
|
28
|
+
roleArn: Role;
|
|
29
|
+
};
|
|
30
|
+
lambdaFunction: {
|
|
31
|
+
roleArn: Role;
|
|
32
|
+
};
|
|
25
33
|
}): CloudFormationTemplate => {
|
|
26
34
|
/**
|
|
27
35
|
* It should be on top of the file, otherwise it will have empty Mutation
|
|
@@ -48,21 +56,23 @@ export const createApiTemplate = ({
|
|
|
48
56
|
}
|
|
49
57
|
);
|
|
50
58
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const { dependencies } = readPackageJson();
|
|
54
|
-
|
|
55
|
-
const dependencyVersion = dependencies[name];
|
|
59
|
+
const getGraphQLComposeDependenciesLambdaLayers = () => {
|
|
60
|
+
const { peerDependencies } = packageJson;
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
const lambdaLayerStackNames = Object.entries(peerDependencies).map(
|
|
63
|
+
([dependencyName, dependencyVersion]) => {
|
|
64
|
+
return getPackageLambdaLayerStackName(
|
|
65
|
+
[dependencyName, dependencyVersion].join('@')
|
|
66
|
+
);
|
|
67
|
+
}
|
|
60
68
|
);
|
|
61
|
-
}
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
return lambdaLayerStackNames.map((lambdaLayerStackName) => {
|
|
71
|
+
return {
|
|
72
|
+
'Fn::ImportValue': lambdaLayerStackName,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
};
|
|
66
76
|
|
|
67
77
|
const template: CloudFormationTemplate = {
|
|
68
78
|
AWSTemplateFormatVersion: '2010-09-09',
|
|
@@ -102,27 +112,6 @@ export const createApiTemplate = ({
|
|
|
102
112
|
Definition: sdl,
|
|
103
113
|
},
|
|
104
114
|
},
|
|
105
|
-
[AppSyncLambdaFunctionIAMRoleLogicalId]: {
|
|
106
|
-
Type: 'AWS::IAM::Role',
|
|
107
|
-
Properties: {
|
|
108
|
-
AssumeRolePolicyDocument: {
|
|
109
|
-
Version: '2012-10-17',
|
|
110
|
-
Statement: [
|
|
111
|
-
{
|
|
112
|
-
Effect: 'Allow',
|
|
113
|
-
Action: 'sts:AssumeRole',
|
|
114
|
-
Principal: {
|
|
115
|
-
Service: 'lambda.amazonaws.com',
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
],
|
|
119
|
-
},
|
|
120
|
-
ManagedPolicyArns: [
|
|
121
|
-
'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole',
|
|
122
|
-
],
|
|
123
|
-
Path: '/custom-iam/',
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
115
|
[AppSyncLambdaFunctionLogicalId]: {
|
|
127
116
|
Type: 'AWS::Lambda::Function',
|
|
128
117
|
Properties: {
|
|
@@ -132,15 +121,9 @@ export const createApiTemplate = ({
|
|
|
132
121
|
S3ObjectVersion: { Ref: 'LambdaS3ObjectVersion' },
|
|
133
122
|
},
|
|
134
123
|
Handler: 'index.handler',
|
|
135
|
-
Layers:
|
|
136
|
-
{
|
|
137
|
-
'Fn::ImportValue': lambdaLayerStackName,
|
|
138
|
-
},
|
|
139
|
-
],
|
|
124
|
+
Layers: getGraphQLComposeDependenciesLambdaLayers(),
|
|
140
125
|
MemorySize: 512,
|
|
141
|
-
Role:
|
|
142
|
-
'Fn::GetAtt': [AppSyncLambdaFunctionIAMRoleLogicalId, 'Arn'],
|
|
143
|
-
},
|
|
126
|
+
Role: lambdaFunction.roleArn,
|
|
144
127
|
Runtime: 'nodejs18.x',
|
|
145
128
|
/**
|
|
146
129
|
* https://docs.aws.amazon.com/general/latest/gr/appsync.html
|
|
@@ -149,44 +132,6 @@ export const createApiTemplate = ({
|
|
|
149
132
|
Timeout: 29,
|
|
150
133
|
},
|
|
151
134
|
},
|
|
152
|
-
[AppSyncLambdaFunctionAppSyncDataSourceIAMRoleLogicalId]: {
|
|
153
|
-
Type: 'AWS::IAM::Role',
|
|
154
|
-
Properties: {
|
|
155
|
-
AssumeRolePolicyDocument: {
|
|
156
|
-
Version: '2012-10-17',
|
|
157
|
-
Statement: [
|
|
158
|
-
{
|
|
159
|
-
Effect: 'Allow',
|
|
160
|
-
Action: 'sts:AssumeRole',
|
|
161
|
-
Principal: {
|
|
162
|
-
Service: 'appsync.amazonaws.com',
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
},
|
|
167
|
-
ManagedPolicyArns: [
|
|
168
|
-
'arn:aws:iam::aws:policy/service-role/AWSAppSyncPushToCloudWatchLogs',
|
|
169
|
-
],
|
|
170
|
-
Path: '/custom-iam/',
|
|
171
|
-
Policies: [
|
|
172
|
-
{
|
|
173
|
-
PolicyName: 'AppSyncGraphQLApiIAMRolePolicyName',
|
|
174
|
-
PolicyDocument: {
|
|
175
|
-
Version: '2012-10-17',
|
|
176
|
-
Statement: [
|
|
177
|
-
{
|
|
178
|
-
Effect: 'Allow',
|
|
179
|
-
Action: ['lambda:InvokeFunction'],
|
|
180
|
-
Resource: [
|
|
181
|
-
{ 'Fn::GetAtt': [AppSyncLambdaFunctionLogicalId, 'Arn'] },
|
|
182
|
-
],
|
|
183
|
-
},
|
|
184
|
-
],
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
],
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
135
|
[AppSyncLambdaFunctionAppSyncDataSourceLogicalId]: {
|
|
191
136
|
Type: 'AWS::AppSync::DataSource',
|
|
192
137
|
Properties: {
|
|
@@ -197,12 +142,7 @@ export const createApiTemplate = ({
|
|
|
197
142
|
},
|
|
198
143
|
},
|
|
199
144
|
Name: 'AppSyncLambdaFunctionAppSyncDataSource',
|
|
200
|
-
ServiceRoleArn:
|
|
201
|
-
'Fn::GetAtt': [
|
|
202
|
-
AppSyncLambdaFunctionAppSyncDataSourceIAMRoleLogicalId,
|
|
203
|
-
'Arn',
|
|
204
|
-
],
|
|
205
|
-
},
|
|
145
|
+
ServiceRoleArn: dataSource.roleArn,
|
|
206
146
|
Type: 'AWS_LAMBDA',
|
|
207
147
|
},
|
|
208
148
|
},
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import type { AppSyncResolverHandler } from 'aws-lambda';
|
|
1
|
+
import type { AppSyncResolverHandler as AwsAppSyncResolverHandler } from 'aws-lambda';
|
|
2
2
|
import type { SchemaComposer } from 'graphql-compose';
|
|
3
3
|
|
|
4
|
-
export
|
|
4
|
+
export type AppSyncResolverHandler<
|
|
5
|
+
TArguments,
|
|
6
|
+
TResult,
|
|
7
|
+
TSource = Record<string, any> | null
|
|
8
|
+
> = AwsAppSyncResolverHandler<TArguments, TResult, TSource>;
|
|
9
|
+
|
|
10
|
+
export const createAppSyncResolverHandler = ({
|
|
5
11
|
schemaComposer,
|
|
6
12
|
}: {
|
|
7
13
|
schemaComposer: SchemaComposer<any>;
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export { type ResolverResolveParams, schemaComposer } from 'graphql-compose';
|
|
2
2
|
export { createApiTemplate } from './createApiTemplate';
|
|
3
|
-
export {
|
|
3
|
+
export {
|
|
4
|
+
type AppSyncResolverHandler,
|
|
5
|
+
createAppSyncResolverHandler,
|
|
6
|
+
} from './createAppSyncResolverHandler';
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type SchemaComposer } from 'graphql-compose';
|
|
2
|
+
import {
|
|
3
|
+
getGraphQLParameters,
|
|
4
|
+
processRequest,
|
|
5
|
+
renderGraphiQL,
|
|
6
|
+
sendResult,
|
|
7
|
+
shouldRenderGraphiQL,
|
|
8
|
+
} from 'graphql-helix';
|
|
9
|
+
import express from 'express';
|
|
10
|
+
|
|
11
|
+
export const createServer = ({
|
|
12
|
+
schemaComposer,
|
|
13
|
+
}: {
|
|
14
|
+
schemaComposer: SchemaComposer<any>;
|
|
15
|
+
}) => {
|
|
16
|
+
const server = express();
|
|
17
|
+
|
|
18
|
+
server.use(express.json());
|
|
19
|
+
|
|
20
|
+
server.use('/graphql', async (req, res) => {
|
|
21
|
+
const request = {
|
|
22
|
+
body: req.body,
|
|
23
|
+
headers: req.headers,
|
|
24
|
+
method: req.method,
|
|
25
|
+
query: req.query,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (shouldRenderGraphiQL(request)) {
|
|
29
|
+
res.send(renderGraphiQL());
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { operationName, query, variables } = getGraphQLParameters(request);
|
|
34
|
+
|
|
35
|
+
const result = await processRequest({
|
|
36
|
+
operationName,
|
|
37
|
+
query,
|
|
38
|
+
variables,
|
|
39
|
+
request,
|
|
40
|
+
schema: schemaComposer.buildSchema(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
sendResult(result, res);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return server;
|
|
47
|
+
};
|