@infoxchange/make-it-so 2.0.1 → 2.1.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 +22 -1
- package/dist/cdk-constructs/IxApi.d.ts +12 -0
- package/dist/cdk-constructs/IxApi.d.ts.map +1 -0
- package/dist/cdk-constructs/IxApi.js +56 -0
- package/dist/cdk-constructs/IxNextjsSite.d.ts.map +1 -1
- package/dist/cdk-constructs/IxNextjsSite.js +1 -13
- package/dist/cdk-constructs/index.d.ts +1 -0
- package/dist/cdk-constructs/index.d.ts.map +1 -1
- package/dist/cdk-constructs/index.js +1 -0
- package/dist/shared.d.ts +1 -0
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +13 -0
- package/package.json +1 -1
- package/src/cdk-constructs/IxApi.ts +81 -0
- package/src/cdk-constructs/IxNextjsSite.ts +1 -15
- package/src/cdk-constructs/index.ts +1 -0
- package/src/shared.ts +15 -0
package/README.md
CHANGED
|
@@ -64,6 +64,23 @@ const site = new IxNextjsSite(stack, "Site", {
|
|
|
64
64
|
});
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
### CDK Construct - IxApi
|
|
68
|
+
|
|
69
|
+
Deploys an instance of API Gateway. IxApi extends [SST's Api](https://docs.sst.dev/constructs/Api) and takes the exact same props.
|
|
70
|
+
|
|
71
|
+
It will automatically create certificates and DNS records for a single domain that the API should deploy to. If the props `customDomain` is not set the first site domain provided by the IX deployment pipeline will be used as the domain. Explicitly setting `customDomain` to `undefined` will ensure no customDomain is used. Regardless of if a custom domain is set, the API Gateway will still be accessible via the 'api-id.execute-api.region.amazonaws.com' url.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { IxApi } from "@infoxchange/make-it-so/cdk-constructs";
|
|
75
|
+
|
|
76
|
+
const site = new IxApi(stack, "api", {
|
|
77
|
+
// Included by default:
|
|
78
|
+
// customDomain: {
|
|
79
|
+
// domainName: ixDeployConfig.siteDomains[0],
|
|
80
|
+
// },
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
67
84
|
### CDK Construct - IxElasticache
|
|
68
85
|
|
|
69
86
|
Deploys an AWS Elasticache cluster, either the redis or the memcached flavour.
|
|
@@ -204,8 +221,12 @@ important that sst and aws lib version match those used in ix-deploy-support
|
|
|
204
221
|
|
|
205
222
|
Honestly I've never seen Star Trek but I figured the name is appropriate since the goal of this library is to allow you, the user, to deploy applications by stating what you want and letting someone else handle the nitty gritty details of how to actually implement it.
|
|
206
223
|
|
|
207
|
-
# Contributing
|
|
224
|
+
# Development and Contributing
|
|
208
225
|
|
|
209
226
|
Changes to the main branch automatically trigger the CI to build and publish to npm. We do this with [semantic-release](https://semantic-release.gitbook.io/) which uses commit messages to determine what the new version number should be.
|
|
210
227
|
|
|
211
228
|
Commit messages must be formatted in the [Conventional Commits](https://www.conventionalcommits.org) style to allow semantic-release to generate release notes based on the git history. To help with this the CLI tool for creating a commit with a valid commit message can be used via `npm run commit`.
|
|
229
|
+
|
|
230
|
+
If adding a new construct the easiest way to develop it maybe by building it in whatever app repo it is intended to be used in. When it appears to be working correctly it can be moved into make-it-so and the app can be updated to import that construct from make-it-so.
|
|
231
|
+
|
|
232
|
+
To test change a change in make-it-so create a branch starting with the prefix "internal-testing-". When pushed the CI will release a new package with a pre-release version. It'll look a little something like `2.1.3-internal-testing-name-of-feature.3`. A serverless app using make-it-so can be modified to use this package version and then deployed to a dev environment to test that the make-it-so changes are functioning correctly. Once a change has been merged into main and there are no serverless apps using the pre-release package any more it's a good idea to [delete that version](https://docs.npmjs.com/unpublishing-packages-from-the-registry#unpublishing-a-single-version-of-a-package) to keep the [npm package version history clean](https://www.npmjs.com/package/@infoxchange/make-it-so?activeTab=versions).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Api } from "sst/constructs";
|
|
2
|
+
type ConstructScope = ConstructorParameters<typeof Api>[0];
|
|
3
|
+
type ConstructId = ConstructorParameters<typeof Api>[1];
|
|
4
|
+
type ConstructProps = Exclude<ConstructorParameters<typeof Api>[2], undefined>;
|
|
5
|
+
export declare class IxApi extends Api {
|
|
6
|
+
constructor(scope: ConstructScope, id: ConstructId, props?: ConstructProps);
|
|
7
|
+
private static setupCustomDomain;
|
|
8
|
+
private static setupCertificate;
|
|
9
|
+
private createDnsRecords;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=IxApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IxApi.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/IxApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAMrC,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,KAAK,WAAW,GAAG,qBAAqB,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,KAAK,cAAc,GAAG,OAAO,CAAC,qBAAqB,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAE/E,qBAAa,KAAM,SAAQ,GAAG;gBAE1B,KAAK,EAAE,cAAc,EACrB,EAAE,EAAE,WAAW,EACf,KAAK,GAAE,cAAmB;IAc5B,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgBhC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAuB/B,OAAO,CAAC,gBAAgB;CAazB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Api } from "sst/constructs";
|
|
2
|
+
import { IxCertificate } from "./IxCertificate.js";
|
|
3
|
+
import { IxDnsRecord } from "./IxDnsRecord.js";
|
|
4
|
+
import ixDeployConfig from "../deployConfig.js";
|
|
5
|
+
import { convertToBase62Hash } from "../shared.js";
|
|
6
|
+
export class IxApi extends Api {
|
|
7
|
+
constructor(scope, id, props = {}) {
|
|
8
|
+
if (ixDeployConfig.isIxDeploy) {
|
|
9
|
+
IxApi.setupCustomDomain(scope, id, props);
|
|
10
|
+
}
|
|
11
|
+
super(scope, id, props);
|
|
12
|
+
if (ixDeployConfig.isIxDeploy) {
|
|
13
|
+
this.createDnsRecords(scope);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// This must be static because we need to call it in the constructor before super
|
|
17
|
+
static setupCustomDomain(scope, id, props) {
|
|
18
|
+
// Default to using domains names passed in by the pipeline as the custom domain
|
|
19
|
+
if (ixDeployConfig.isIxDeploy && !("customDomain" in props)) {
|
|
20
|
+
props.customDomain = {
|
|
21
|
+
domainName: ixDeployConfig.siteDomains[0],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
this.setupCertificate(scope, id, props);
|
|
25
|
+
}
|
|
26
|
+
// This must be static because we need to call it in the constructor before super
|
|
27
|
+
static setupCertificate(scope, id, props) {
|
|
28
|
+
if (!props?.customDomain)
|
|
29
|
+
return;
|
|
30
|
+
if (typeof props.customDomain === "string") {
|
|
31
|
+
props.customDomain = { domainName: props.customDomain };
|
|
32
|
+
}
|
|
33
|
+
const domainName = props.customDomain.domainName;
|
|
34
|
+
if (domainName) {
|
|
35
|
+
const domainCert = new IxCertificate(scope, id + "-IxCertificate", {
|
|
36
|
+
domainName,
|
|
37
|
+
region: "ap-southeast-2", // API Gateway wants southeast-2.
|
|
38
|
+
});
|
|
39
|
+
props.customDomain.isExternalDomain = true;
|
|
40
|
+
props.customDomain.cdk = props.customDomain.cdk ?? {};
|
|
41
|
+
props.customDomain.cdk.certificate = domainCert.acmCertificate;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
createDnsRecords(scope) {
|
|
45
|
+
if (this.cdk.domainName?.name && this.cdk.domainName?.regionalDomainName) {
|
|
46
|
+
const domainNameLogicalId = convertToBase62Hash(this.cdk.domainName.name);
|
|
47
|
+
// API Gateway has a separate domain for using with a CNAME (regionalDomainName)
|
|
48
|
+
new IxDnsRecord(scope, `DnsRecord-${domainNameLogicalId}`, {
|
|
49
|
+
type: "CNAME",
|
|
50
|
+
name: this.cdk.domainName.name,
|
|
51
|
+
value: this.cdk.domainName?.regionalDomainName,
|
|
52
|
+
ttl: 900,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IxNextjsSite.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/IxNextjsSite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"IxNextjsSite.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/IxNextjsSite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQ5C,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,KAAK,WAAW,GAAG,qBAAqB,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,KAAK,cAAc,GAAG,OAAO,CAC3B,qBAAqB,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,EAC3C,SAAS,CACV,CAAC;AAEF,qBAAa,YAAa,SAAQ,UAAU;gBAExC,KAAK,EAAE,cAAc,EACrB,EAAE,EAAE,WAAW,EACf,KAAK,GAAE,cAAmB;IAiB5B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAuBnC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAiBhC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAgC/B,OAAO,CAAC,gBAAgB;IAgBxB,IAAW,aAAa,IAAI,MAAM,EAAE,CASnC;IAED,IAAW,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAO9C;IAED,IAAW,WAAW,IAAI,MAAM,GAAG,IAAI,CAKtC;IAED,IAAW,kBAAkB,IAAI,MAAM,EAAE,CAKxC;IAEM,aAAa,qBACwD;IAErE,aAAa,SAAmC;CACxD"}
|
|
@@ -4,6 +4,7 @@ import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
|
|
|
4
4
|
import { IxVpcDetails } from "./IxVpcDetails.js";
|
|
5
5
|
import { IxDnsRecord } from "./IxDnsRecord.js";
|
|
6
6
|
import ixDeployConfig from "../deployConfig.js";
|
|
7
|
+
import { convertToBase62Hash } from "../shared.js";
|
|
7
8
|
export class IxNextjsSite extends NextjsSite {
|
|
8
9
|
constructor(scope, id, props = {}) {
|
|
9
10
|
const isIxDeploy = !!process.env.IX_APP_NAME;
|
|
@@ -118,16 +119,3 @@ export class IxNextjsSite extends NextjsSite {
|
|
|
118
119
|
primaryDomain = this.primaryCustomDomain ?? this.cdk?.distribution.distributionDomainName;
|
|
119
120
|
primaryOrigin = `https://${this.primaryDomain}`;
|
|
120
121
|
}
|
|
121
|
-
function convertToBase62Hash(string) {
|
|
122
|
-
const base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
123
|
-
let hash = "";
|
|
124
|
-
let num = 0;
|
|
125
|
-
for (let i = 0; i < string.length; i++) {
|
|
126
|
-
num += string.charCodeAt(i);
|
|
127
|
-
}
|
|
128
|
-
while (num > 0) {
|
|
129
|
-
hash = base62Chars[num % 62] + hash;
|
|
130
|
-
num = Math.floor(num / 62);
|
|
131
|
-
}
|
|
132
|
-
return hash;
|
|
133
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC"}
|
package/dist/shared.d.ts
CHANGED
package/dist/shared.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;EAQ/B"}
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAa1D;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;EAQ/B"}
|
package/dist/shared.js
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
export function convertToBase62Hash(string) {
|
|
2
|
+
const base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
3
|
+
let hash = "";
|
|
4
|
+
let num = 0;
|
|
5
|
+
for (let i = 0; i < string.length; i++) {
|
|
6
|
+
num += string.charCodeAt(i);
|
|
7
|
+
}
|
|
8
|
+
while (num > 0) {
|
|
9
|
+
hash = base62Chars[num % 62] + hash;
|
|
10
|
+
num = Math.floor(num / 62);
|
|
11
|
+
}
|
|
12
|
+
return hash;
|
|
13
|
+
}
|
|
1
14
|
export function remapKeys(object, keyMap) {
|
|
2
15
|
return Object.fromEntries(Object.entries(object).map(([key, value]) => {
|
|
3
16
|
const newKey = keyMap[key] ?? key;
|
package/package.json
CHANGED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Api } from "sst/constructs";
|
|
2
|
+
import { IxCertificate } from "./IxCertificate.js";
|
|
3
|
+
import { IxDnsRecord } from "./IxDnsRecord.js";
|
|
4
|
+
import ixDeployConfig from "../deployConfig.js";
|
|
5
|
+
import { convertToBase62Hash } from "../shared.js";
|
|
6
|
+
|
|
7
|
+
type ConstructScope = ConstructorParameters<typeof Api>[0];
|
|
8
|
+
type ConstructId = ConstructorParameters<typeof Api>[1];
|
|
9
|
+
type ConstructProps = Exclude<ConstructorParameters<typeof Api>[2], undefined>;
|
|
10
|
+
|
|
11
|
+
export class IxApi extends Api {
|
|
12
|
+
constructor(
|
|
13
|
+
scope: ConstructScope,
|
|
14
|
+
id: ConstructId,
|
|
15
|
+
props: ConstructProps = {},
|
|
16
|
+
) {
|
|
17
|
+
if (ixDeployConfig.isIxDeploy) {
|
|
18
|
+
IxApi.setupCustomDomain(scope, id, props);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
super(scope, id, props);
|
|
22
|
+
|
|
23
|
+
if (ixDeployConfig.isIxDeploy) {
|
|
24
|
+
this.createDnsRecords(scope);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// This must be static because we need to call it in the constructor before super
|
|
29
|
+
private static setupCustomDomain(
|
|
30
|
+
scope: ConstructScope,
|
|
31
|
+
id: ConstructId,
|
|
32
|
+
props: ConstructProps,
|
|
33
|
+
): void {
|
|
34
|
+
// Default to using domains names passed in by the pipeline as the custom domain
|
|
35
|
+
if (ixDeployConfig.isIxDeploy && !("customDomain" in props)) {
|
|
36
|
+
props.customDomain = {
|
|
37
|
+
domainName: ixDeployConfig.siteDomains[0],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.setupCertificate(scope, id, props);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// This must be static because we need to call it in the constructor before super
|
|
45
|
+
private static setupCertificate(
|
|
46
|
+
scope: ConstructScope,
|
|
47
|
+
id: ConstructId,
|
|
48
|
+
props: ConstructProps,
|
|
49
|
+
): void {
|
|
50
|
+
if (!props?.customDomain) return;
|
|
51
|
+
|
|
52
|
+
if (typeof props.customDomain === "string") {
|
|
53
|
+
props.customDomain = { domainName: props.customDomain };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const domainName = props.customDomain.domainName;
|
|
57
|
+
if (domainName) {
|
|
58
|
+
const domainCert = new IxCertificate(scope, id + "-IxCertificate", {
|
|
59
|
+
domainName,
|
|
60
|
+
region: "ap-southeast-2", // API Gateway wants southeast-2.
|
|
61
|
+
});
|
|
62
|
+
props.customDomain.isExternalDomain = true;
|
|
63
|
+
props.customDomain.cdk = props.customDomain.cdk ?? {};
|
|
64
|
+
props.customDomain.cdk.certificate = domainCert.acmCertificate;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private createDnsRecords(scope: ConstructScope) {
|
|
69
|
+
if (this.cdk.domainName?.name && this.cdk.domainName?.regionalDomainName) {
|
|
70
|
+
const domainNameLogicalId = convertToBase62Hash(this.cdk.domainName.name);
|
|
71
|
+
|
|
72
|
+
// API Gateway has a separate domain for using with a CNAME (regionalDomainName)
|
|
73
|
+
new IxDnsRecord(scope, `DnsRecord-${domainNameLogicalId}`, {
|
|
74
|
+
type: "CNAME",
|
|
75
|
+
name: this.cdk.domainName.name,
|
|
76
|
+
value: this.cdk.domainName?.regionalDomainName,
|
|
77
|
+
ttl: 900,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -4,6 +4,7 @@ import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
|
|
|
4
4
|
import { IxVpcDetails } from "./IxVpcDetails.js";
|
|
5
5
|
import { IxDnsRecord } from "./IxDnsRecord.js";
|
|
6
6
|
import ixDeployConfig from "../deployConfig.js";
|
|
7
|
+
import { convertToBase62Hash } from "../shared.js";
|
|
7
8
|
|
|
8
9
|
type ConstructScope = ConstructorParameters<typeof NextjsSite>[0];
|
|
9
10
|
type ConstructId = ConstructorParameters<typeof NextjsSite>[1];
|
|
@@ -160,18 +161,3 @@ export class IxNextjsSite extends NextjsSite {
|
|
|
160
161
|
|
|
161
162
|
public primaryOrigin = `https://${this.primaryDomain}`;
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
-
function convertToBase62Hash(string: string): string {
|
|
165
|
-
const base62Chars =
|
|
166
|
-
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
167
|
-
let hash = "";
|
|
168
|
-
let num = 0;
|
|
169
|
-
for (let i = 0; i < string.length; i++) {
|
|
170
|
-
num += string.charCodeAt(i);
|
|
171
|
-
}
|
|
172
|
-
while (num > 0) {
|
|
173
|
-
hash = base62Chars[num % 62] + hash;
|
|
174
|
-
num = Math.floor(num / 62);
|
|
175
|
-
}
|
|
176
|
-
return hash;
|
|
177
|
-
}
|
package/src/shared.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
export function convertToBase62Hash(string: string): string {
|
|
2
|
+
const base62Chars =
|
|
3
|
+
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
4
|
+
let hash = "";
|
|
5
|
+
let num = 0;
|
|
6
|
+
for (let i = 0; i < string.length; i++) {
|
|
7
|
+
num += string.charCodeAt(i);
|
|
8
|
+
}
|
|
9
|
+
while (num > 0) {
|
|
10
|
+
hash = base62Chars[num % 62] + hash;
|
|
11
|
+
num = Math.floor(num / 62);
|
|
12
|
+
}
|
|
13
|
+
return hash;
|
|
14
|
+
}
|
|
15
|
+
|
|
1
16
|
export function remapKeys(
|
|
2
17
|
object: Record<string, unknown>,
|
|
3
18
|
keyMap: Record<string, string>,
|