@ttoss/aws-appsync-nodejs 1.8.0 → 1.8.1

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.
Files changed (2) hide show
  1. package/package.json +13 -6
  2. package/src/index.ts +120 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/aws-appsync-nodejs",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "author": "ttoss",
@@ -12,9 +12,16 @@
12
12
  "url": "https://github.com/ttoss/ttoss.git",
13
13
  "directory": "packages/aws-appsync-nodejs"
14
14
  },
15
- "main": "dist/index.js",
15
+ "exports": {
16
+ ".": {
17
+ "import": "./dist/esm/index.js",
18
+ "require": "./dist/index.js",
19
+ "types": "./dist/index.d.ts"
20
+ }
21
+ },
16
22
  "files": [
17
- "dist/"
23
+ "dist/",
24
+ "src/"
18
25
  ],
19
26
  "dependencies": {
20
27
  "@aws-crypto/sha256-js": "^5.2.0",
@@ -24,10 +31,10 @@
24
31
  },
25
32
  "devDependencies": {
26
33
  "@aws-sdk/types": "^3.502.0",
27
- "@types/jest": "^29.5.11",
34
+ "@types/jest": "^29.5.12",
28
35
  "jest": "^29.7.0",
29
- "tsup": "^8.0.1",
30
- "@ttoss/config": "^1.31.4"
36
+ "tsup": "^8.0.2",
37
+ "@ttoss/config": "^1.31.5"
31
38
  },
32
39
  "keywords": [],
33
40
  "engines": {
package/src/index.ts ADDED
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Implementation of the AppSync client for NodeJS, based on the AWS Amplify
3
+ * documentation: https://docs.amplify.aws/lib/graphqlapi/graphql-from-nodejs/q/platform/js/
4
+ */
5
+ import { AwsCredentialIdentity } from '@aws-sdk/types';
6
+ import { HttpRequest } from '@smithy/protocol-http';
7
+ import { Sha256 } from '@aws-crypto/sha256-js';
8
+ import { SignatureV4 } from '@smithy/signature-v4';
9
+ import { defaultProvider } from '@aws-sdk/credential-provider-node';
10
+
11
+ export type Config = {
12
+ endpoint: string;
13
+ region?: string;
14
+ apiKey?: string;
15
+ credentials?: AwsCredentialIdentity;
16
+ };
17
+
18
+ let _config: Config;
19
+
20
+ const setConfig = (config: Config) => {
21
+ _config = config;
22
+ };
23
+
24
+ export type Query = (
25
+ query: string,
26
+ variables?: Record<string, unknown>
27
+ ) => Promise<{
28
+ data: Record<string, unknown> | null;
29
+ errors?: {
30
+ message: string;
31
+ path: string | null;
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ locations: any[];
34
+ }[];
35
+ }>;
36
+
37
+ const queryWithApiKey: Query = async (query, variables) => {
38
+ const { endpoint, apiKey } = _config;
39
+
40
+ if (!apiKey) {
41
+ throw new Error('No API Key set');
42
+ }
43
+
44
+ const options: RequestInit = {
45
+ method: 'POST',
46
+ headers: {
47
+ 'x-api-key': apiKey,
48
+ },
49
+ body: JSON.stringify({ query, variables }),
50
+ };
51
+
52
+ const request = new Request(endpoint, options);
53
+
54
+ const response = await fetch(request);
55
+
56
+ const body = await response.json();
57
+
58
+ return body;
59
+ };
60
+
61
+ const getRegionFromEndpoint = (endpoint: string): string => {
62
+ const matcher = /\.[a-z]+-[a-z]+-[0-9]\./;
63
+ const regexResponse = endpoint.match(matcher);
64
+ let region = '';
65
+ if (regexResponse) {
66
+ region = regexResponse[0].replace(/\./g, '');
67
+ }
68
+ return region;
69
+ };
70
+
71
+ const queryWithCredentials: Query = async (query, variables) => {
72
+ const endpoint = new URL(_config.endpoint);
73
+
74
+ const region = _config.region || getRegionFromEndpoint(_config.endpoint);
75
+
76
+ const signer = new SignatureV4({
77
+ credentials: _config.credentials || defaultProvider(),
78
+ region,
79
+ service: 'appsync',
80
+ sha256: Sha256,
81
+ });
82
+
83
+ const requestToBeSigned = new HttpRequest({
84
+ method: 'POST',
85
+ headers: {
86
+ 'Content-Type': 'application/json',
87
+ host: endpoint.host,
88
+ },
89
+ hostname: endpoint.host,
90
+ body: JSON.stringify({ query, variables }),
91
+ path: endpoint.pathname,
92
+ protocol: endpoint.protocol,
93
+ });
94
+
95
+ const signed = await signer.sign(requestToBeSigned);
96
+
97
+ const request = new Request(endpoint, signed);
98
+
99
+ const response = await fetch(request);
100
+
101
+ const body = await response.json();
102
+
103
+ return body;
104
+ };
105
+
106
+ const query: Query = async (query, variables) => {
107
+ if (_config.apiKey) {
108
+ return queryWithApiKey(query, variables);
109
+ }
110
+
111
+ return queryWithCredentials(query, variables);
112
+ };
113
+
114
+ export const appSyncClient = {
115
+ query,
116
+ setConfig,
117
+ get config() {
118
+ return _config;
119
+ },
120
+ };