@ttoss/appsync-api 0.23.0 → 0.23.7

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 CHANGED
@@ -14,22 +14,25 @@ You can create and deploy an AppSync API in four steps:
14
14
 
15
15
  1. Create a `schemaComposer` object using [`graphql-compose`](https://graphql-compose.github.io/docs/intro/quick-start.html), that the next steps will use to create the API.
16
16
 
17
- 2. Create a `cloudformation.ts` file that exports a CloudFormation template using `createApiTemplate`:
17
+ 2. Create a `cloudformation.ts` file that exports a CloudFormation template using `createApiTemplate`. Use `importValueFromParameter` from `@ttoss/cloudformation` to import cross-stack values whose export names come from template parameters:
18
18
 
19
19
  ```typescript
20
+ import { importValueFromParameter } from '@ttoss/cloudformation';
20
21
  import { createApiTemplate } from '@ttoss/appsync-api';
21
22
  import { schemaComposer } from './schemaComposer';
22
23
 
23
24
  const template = createApiTemplate({
24
25
  schemaComposer,
25
26
  dataSource: {
26
- roleArn: {
27
- 'Fn::ImportValue': 'AppSyncLambdaDataSourceIAMRoleArn',
28
- },
27
+ roleArn: importValueFromParameter('AppSyncLambdaDataSourceIAMRoleArn'),
29
28
  },
30
29
  lambdaFunction: {
31
- roleArn: {
32
- 'Fn::ImportValue': 'AppSyncLambdaFunctionIAMRoleArn',
30
+ roleArn: importValueFromParameter('AppSyncLambdaFunctionIAMRoleArn'),
31
+ environment: {
32
+ variables: {
33
+ TABLE_NAME: { Ref: 'DynamoTableName' },
34
+ SHARED_SECRET: importValueFromParameter('SharedSecretExportedName'),
35
+ },
33
36
  },
34
37
  },
35
38
  });
package/dist/esm/index.js CHANGED
@@ -228,8 +228,44 @@ var createApiTemplate = /* @__PURE__ */__name(({
228
228
  }
229
229
  if (customDomain) {
230
230
  const AppSyncDomainNameLogicalId = "AppSyncDomainName";
231
+ const HasCustomDomainCondition = "HasCustomDomain";
232
+ const domainNameRef = typeof customDomain.domainName === "object" && "Ref" in customDomain.domainName ? customDomain.domainName.Ref : null;
233
+ const certificateArnRef = typeof customDomain.certificateArn === "object" && "Ref" in customDomain.certificateArn ? customDomain.certificateArn.Ref : null;
234
+ if (domainNameRef || certificateArnRef) {
235
+ if (!template.Parameters) {
236
+ template.Parameters = {};
237
+ }
238
+ }
239
+ if (domainNameRef && !template.Parameters?.[domainNameRef]) {
240
+ template.Parameters[domainNameRef] = {
241
+ Default: "",
242
+ Type: "String"
243
+ };
244
+ }
245
+ if (certificateArnRef && !template.Parameters?.[certificateArnRef]) {
246
+ template.Parameters[certificateArnRef] = {
247
+ Default: "",
248
+ Type: "String"
249
+ };
250
+ }
251
+ if (domainNameRef) {
252
+ if (!template.Conditions) {
253
+ template.Conditions = {};
254
+ }
255
+ template.Conditions[HasCustomDomainCondition] = {
256
+ "Fn::Not": [{
257
+ "Fn::Equals": [{
258
+ Ref: domainNameRef
259
+ }, ""]
260
+ }]
261
+ };
262
+ }
263
+ const customDomainCondition = domainNameRef ? {
264
+ Condition: HasCustomDomainCondition
265
+ } : {};
231
266
  template.Resources[AppSyncDomainNameLogicalId] = {
232
267
  Type: "AWS::AppSync::DomainName",
268
+ ...customDomainCondition,
233
269
  Properties: {
234
270
  CertificateArn: customDomain.certificateArn,
235
271
  Description: "Custom domain for AppSync API",
@@ -240,6 +276,7 @@ var createApiTemplate = /* @__PURE__ */__name(({
240
276
  const hostedZoneName = customDomain.hostedZoneName.endsWith(".") ? customDomain.hostedZoneName : `${customDomain.hostedZoneName}.`;
241
277
  template.Resources.AppSyncDomainNameRoute53RecordSet = {
242
278
  Type: "AWS::Route53::RecordSet",
279
+ ...customDomainCondition,
243
280
  Properties: {
244
281
  HostedZoneName: hostedZoneName,
245
282
  Name: customDomain.domainName,
@@ -253,6 +290,7 @@ var createApiTemplate = /* @__PURE__ */__name(({
253
290
  }
254
291
  template.Resources.AppSyncDomainNameApiAssociation = {
255
292
  Type: "AWS::AppSync::DomainNameApiAssociation",
293
+ ...customDomainCondition,
256
294
  Properties: {
257
295
  ApiId: {
258
296
  "Fn::GetAtt": [AppSyncGraphQLApiLogicalId, "ApiId"]
@@ -267,12 +305,14 @@ var createApiTemplate = /* @__PURE__ */__name(({
267
305
  }
268
306
  template.Outputs.DomainName = {
269
307
  Description: "Custom domain name for AppSync API",
308
+ ...customDomainCondition,
270
309
  Value: {
271
310
  "Fn::GetAtt": [AppSyncDomainNameLogicalId, "DomainName"]
272
311
  }
273
312
  };
274
313
  template.Outputs.CloudFrontDomainName = {
275
314
  Description: "CloudFront domain name for AppSync API",
315
+ ...customDomainCondition,
276
316
  Value: {
277
317
  "Fn::GetAtt": [AppSyncDomainNameLogicalId, "AppSyncDomainName"]
278
318
  }
package/dist/index.d.mts CHANGED
@@ -21,7 +21,10 @@ type CloudFormationSelect = {
21
21
  type CloudFormationSplit = {
22
22
  'Fn::Split': [string, string];
23
23
  };
24
- type CloudFormationIntrinsic = CloudFormationRef | CloudFormationGetAtt | CloudFormationJoin | CloudFormationSub | CloudFormationSelect | CloudFormationSplit;
24
+ type CloudFormationImportValue = {
25
+ 'Fn::ImportValue': string | CloudFormationSub;
26
+ };
27
+ type CloudFormationIntrinsic = CloudFormationRef | CloudFormationGetAtt | CloudFormationJoin | CloudFormationSub | CloudFormationSelect | CloudFormationSplit | CloudFormationImportValue;
25
28
  type CloudFormationValue<T = any> = T | CloudFormationIntrinsic;
26
29
  type Parameter = {
27
30
  AllowedValues?: string[];
@@ -75,9 +78,6 @@ type CloudFormationTemplate = {
75
78
  Outputs?: Outputs;
76
79
  };
77
80
 
78
- type StringOrImport = string | {
79
- 'Fn::ImportValue': string;
80
- };
81
81
  /**
82
82
  * https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html
83
83
  */
@@ -86,26 +86,30 @@ declare const createApiTemplate: ({ additionalAuthenticationProviders, authentic
86
86
  additionalAuthenticationProviders?: AuthenticationType[];
87
87
  authenticationType?: AuthenticationType;
88
88
  customDomain?: {
89
- domainName: string;
90
- certificateArn: string;
89
+ domainName: string | {
90
+ Ref: string;
91
+ };
92
+ certificateArn: string | {
93
+ Ref: string;
94
+ };
91
95
  hostedZoneName?: string;
92
96
  };
93
97
  dataSource: {
94
- roleArn: StringOrImport;
98
+ roleArn: CloudFormationValue<string>;
95
99
  };
96
100
  lambdaFunction: {
97
101
  environment?: {
98
- variables: Record<string, string>;
102
+ variables: Record<string, CloudFormationValue<string>>;
99
103
  };
100
104
  layers?: any;
101
- roleArn: StringOrImport;
105
+ roleArn: CloudFormationValue<string>;
102
106
  };
103
107
  schemaComposer: SchemaComposer<any>;
104
108
  userPoolConfig?: {
105
- appIdClientRegex: StringOrImport;
106
- awsRegion: StringOrImport;
109
+ appIdClientRegex: CloudFormationValue<string>;
110
+ awsRegion: CloudFormationValue<string>;
107
111
  defaultAction: "ALLOW" | "DENY";
108
- userPoolId: StringOrImport;
112
+ userPoolId: CloudFormationValue<string>;
109
113
  };
110
114
  }) => CloudFormationTemplate;
111
115
 
package/dist/index.d.ts CHANGED
@@ -21,7 +21,10 @@ type CloudFormationSelect = {
21
21
  type CloudFormationSplit = {
22
22
  'Fn::Split': [string, string];
23
23
  };
24
- type CloudFormationIntrinsic = CloudFormationRef | CloudFormationGetAtt | CloudFormationJoin | CloudFormationSub | CloudFormationSelect | CloudFormationSplit;
24
+ type CloudFormationImportValue = {
25
+ 'Fn::ImportValue': string | CloudFormationSub;
26
+ };
27
+ type CloudFormationIntrinsic = CloudFormationRef | CloudFormationGetAtt | CloudFormationJoin | CloudFormationSub | CloudFormationSelect | CloudFormationSplit | CloudFormationImportValue;
25
28
  type CloudFormationValue<T = any> = T | CloudFormationIntrinsic;
26
29
  type Parameter = {
27
30
  AllowedValues?: string[];
@@ -75,9 +78,6 @@ type CloudFormationTemplate = {
75
78
  Outputs?: Outputs;
76
79
  };
77
80
 
78
- type StringOrImport = string | {
79
- 'Fn::ImportValue': string;
80
- };
81
81
  /**
82
82
  * https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html
83
83
  */
@@ -86,26 +86,30 @@ declare const createApiTemplate: ({ additionalAuthenticationProviders, authentic
86
86
  additionalAuthenticationProviders?: AuthenticationType[];
87
87
  authenticationType?: AuthenticationType;
88
88
  customDomain?: {
89
- domainName: string;
90
- certificateArn: string;
89
+ domainName: string | {
90
+ Ref: string;
91
+ };
92
+ certificateArn: string | {
93
+ Ref: string;
94
+ };
91
95
  hostedZoneName?: string;
92
96
  };
93
97
  dataSource: {
94
- roleArn: StringOrImport;
98
+ roleArn: CloudFormationValue<string>;
95
99
  };
96
100
  lambdaFunction: {
97
101
  environment?: {
98
- variables: Record<string, string>;
102
+ variables: Record<string, CloudFormationValue<string>>;
99
103
  };
100
104
  layers?: any;
101
- roleArn: StringOrImport;
105
+ roleArn: CloudFormationValue<string>;
102
106
  };
103
107
  schemaComposer: SchemaComposer<any>;
104
108
  userPoolConfig?: {
105
- appIdClientRegex: StringOrImport;
106
- awsRegion: StringOrImport;
109
+ appIdClientRegex: CloudFormationValue<string>;
110
+ awsRegion: CloudFormationValue<string>;
107
111
  defaultAction: "ALLOW" | "DENY";
108
- userPoolId: StringOrImport;
112
+ userPoolId: CloudFormationValue<string>;
109
113
  };
110
114
  }) => CloudFormationTemplate;
111
115
 
package/dist/index.js CHANGED
@@ -268,8 +268,44 @@ var createApiTemplate = /* @__PURE__ */__name(({
268
268
  }
269
269
  if (customDomain) {
270
270
  const AppSyncDomainNameLogicalId = "AppSyncDomainName";
271
+ const HasCustomDomainCondition = "HasCustomDomain";
272
+ const domainNameRef = typeof customDomain.domainName === "object" && "Ref" in customDomain.domainName ? customDomain.domainName.Ref : null;
273
+ const certificateArnRef = typeof customDomain.certificateArn === "object" && "Ref" in customDomain.certificateArn ? customDomain.certificateArn.Ref : null;
274
+ if (domainNameRef || certificateArnRef) {
275
+ if (!template.Parameters) {
276
+ template.Parameters = {};
277
+ }
278
+ }
279
+ if (domainNameRef && !template.Parameters?.[domainNameRef]) {
280
+ template.Parameters[domainNameRef] = {
281
+ Default: "",
282
+ Type: "String"
283
+ };
284
+ }
285
+ if (certificateArnRef && !template.Parameters?.[certificateArnRef]) {
286
+ template.Parameters[certificateArnRef] = {
287
+ Default: "",
288
+ Type: "String"
289
+ };
290
+ }
291
+ if (domainNameRef) {
292
+ if (!template.Conditions) {
293
+ template.Conditions = {};
294
+ }
295
+ template.Conditions[HasCustomDomainCondition] = {
296
+ "Fn::Not": [{
297
+ "Fn::Equals": [{
298
+ Ref: domainNameRef
299
+ }, ""]
300
+ }]
301
+ };
302
+ }
303
+ const customDomainCondition = domainNameRef ? {
304
+ Condition: HasCustomDomainCondition
305
+ } : {};
271
306
  template.Resources[AppSyncDomainNameLogicalId] = {
272
307
  Type: "AWS::AppSync::DomainName",
308
+ ...customDomainCondition,
273
309
  Properties: {
274
310
  CertificateArn: customDomain.certificateArn,
275
311
  Description: "Custom domain for AppSync API",
@@ -280,6 +316,7 @@ var createApiTemplate = /* @__PURE__ */__name(({
280
316
  const hostedZoneName = customDomain.hostedZoneName.endsWith(".") ? customDomain.hostedZoneName : `${customDomain.hostedZoneName}.`;
281
317
  template.Resources.AppSyncDomainNameRoute53RecordSet = {
282
318
  Type: "AWS::Route53::RecordSet",
319
+ ...customDomainCondition,
283
320
  Properties: {
284
321
  HostedZoneName: hostedZoneName,
285
322
  Name: customDomain.domainName,
@@ -293,6 +330,7 @@ var createApiTemplate = /* @__PURE__ */__name(({
293
330
  }
294
331
  template.Resources.AppSyncDomainNameApiAssociation = {
295
332
  Type: "AWS::AppSync::DomainNameApiAssociation",
333
+ ...customDomainCondition,
296
334
  Properties: {
297
335
  ApiId: {
298
336
  "Fn::GetAtt": [AppSyncGraphQLApiLogicalId, "ApiId"]
@@ -307,12 +345,14 @@ var createApiTemplate = /* @__PURE__ */__name(({
307
345
  }
308
346
  template.Outputs.DomainName = {
309
347
  Description: "Custom domain name for AppSync API",
348
+ ...customDomainCondition,
310
349
  Value: {
311
350
  "Fn::GetAtt": [AppSyncDomainNameLogicalId, "DomainName"]
312
351
  }
313
352
  };
314
353
  template.Outputs.CloudFrontDomainName = {
315
354
  Description: "CloudFront domain name for AppSync API",
355
+ ...customDomainCondition,
316
356
  Value: {
317
357
  "Fn::GetAtt": [AppSyncDomainNameLogicalId, "AppSyncDomainName"]
318
358
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/appsync-api",
3
- "version": "0.23.0",
3
+ "version": "0.23.7",
4
4
  "description": "A library for building GraphQL APIs for AWS AppSync.",
5
5
  "license": "MIT",
6
6
  "author": "ttoss",
@@ -24,21 +24,21 @@
24
24
  ],
25
25
  "sideEffects": false,
26
26
  "dependencies": {
27
- "@ttoss/cloudformation": "^0.12.0"
27
+ "@ttoss/cloudformation": "^0.12.7"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "graphql": "^16.6.0",
31
- "@ttoss/graphql-api": "^0.8.17"
31
+ "@ttoss/graphql-api": "^0.9.5"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/aws-lambda": "^8.10.152",
35
35
  "graphql": "^16.11.0",
36
36
  "graphql-shield": "^7.6.5",
37
- "jest": "^30.2.0",
37
+ "jest": "^30.3.0",
38
38
  "tsup": "^8.5.1",
39
- "@ttoss/graphql-api": "^0.8.17",
40
- "@ttoss/config": "^1.36.0",
41
- "@ttoss/ids": "^0.3.14"
39
+ "@ttoss/graphql-api": "^0.9.5",
40
+ "@ttoss/config": "^1.37.5",
41
+ "@ttoss/ids": "^0.4.5"
42
42
  },
43
43
  "keywords": [
44
44
  "api",