Skip to content

Commit 09b9bb8

Browse files
committed
fix: more fixes and smoke test
1 parent 3d55f2b commit 09b9bb8

File tree

7 files changed

+400
-17
lines changed

7 files changed

+400
-17
lines changed

src/index.spec.ts

Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
import { describe, it } from 'mocha'
2+
import * as t from './'
3+
4+
type ServiceScalingParameters = {
5+
DesiredCount?: number | null | undefined
6+
MaximumPercent?: number | null | undefined
7+
}
8+
9+
const ServiceScalingParametersType = t.object<ServiceScalingParameters>({
10+
DesiredCount: t.nullable(t.number()),
11+
MaximumPercent: t.nullable(t.number()),
12+
})
13+
14+
export type DeployConfig = {
15+
CloudFormationTemplateBucket?: string | null | undefined
16+
DeploymentName: string
17+
AppName?: string | null | undefined
18+
/**
19+
* The base domain name of the app, for example: clarity.foo.com
20+
*/
21+
BaseDomainName?: string | null | undefined
22+
/**
23+
* The domain name of the Route 53 hosted zone, for example: foo.com
24+
*/
25+
HostedZoneDomainName: string
26+
/**
27+
* The id of the VPC to deploy into
28+
*/
29+
VpcId: string
30+
/**
31+
* The AWS region to deploy into
32+
*/
33+
region: string
34+
/**
35+
* The subnet ids for the Vpc. Defaults to all available for VpcId
36+
*/
37+
SubnetIds?: string[] | null | undefined
38+
/**
39+
* Name of an existing EC2 KeyPair to enable SSH access to the ECS instances
40+
*/
41+
EC2KeyName?: string | null | undefined
42+
VPN?:
43+
| {
44+
CidrIp?: string | null | undefined
45+
SecurityGroupId?: string | null | undefined
46+
}
47+
| null
48+
| undefined
49+
/**
50+
* Settings for the user upload/download S3 buckets that Clarity uses.
51+
* Not applicable to CloudFormationTemplateBucket or CertificateProvider.S3BucketName.
52+
*/
53+
S3?: {
54+
/**
55+
* The origin URLs that the S3 buckets will allow.
56+
* For prod, just the public URL of the app. For staging,
57+
* you probably want a wildcard pattern like https://clarity-staging-*.foo.com
58+
*/
59+
AllowedOrigin?: string | null | undefined
60+
}
61+
Redis:
62+
| {
63+
Type: 'External'
64+
Host: string
65+
Port?: number | null | undefined
66+
DB?: number | null | undefined
67+
SecurityGroupId?: string | null | undefined
68+
}
69+
| {
70+
Type: 'ElastiCache'
71+
AvailabilityZone: string
72+
}
73+
DB:
74+
| {
75+
Type: 'External'
76+
Host: string
77+
Port?: number | null | undefined
78+
User: string
79+
Name: string
80+
Password: string
81+
RootDBName?: string | null | undefined
82+
SecurityGroupId?: string | null | undefined
83+
}
84+
| {
85+
Type: 'RDS'
86+
MasterUserPassword: string
87+
AvailabilityZone: string
88+
}
89+
Historian: {
90+
DB: {
91+
Host: string
92+
Port?: number | null | undefined
93+
User: string
94+
Password: string
95+
Name: string
96+
SecurityGroupId?: string | null | undefined
97+
}
98+
Redis?:
99+
| {
100+
Host: string
101+
Port?: number | null | undefined
102+
SecurityGroupId?: string | null | undefined
103+
}
104+
| null
105+
| undefined
106+
}
107+
ECSCluster?:
108+
| {
109+
ClusterId?: string | null | undefined
110+
MinSize?: number | null | undefined
111+
MaxSize?: number | null | undefined
112+
DesiredCapacity?: number | null | undefined
113+
InstanceType?: string | null | undefined
114+
}
115+
| null
116+
| undefined
117+
CertificateProvider?:
118+
| {
119+
StackName?: string | null | undefined
120+
S3BucketName?: string | null | undefined
121+
CFNCustomProviderZipFileName?: string | null | undefined
122+
LambdaFunctionName?: string | null | undefined
123+
}
124+
| undefined
125+
Services: {
126+
Webapp?: ServiceScalingParameters | null | undefined
127+
RedirectHttps?: ServiceScalingParameters | null | undefined
128+
MQTT: {
129+
DesiredCount?: number | null | undefined
130+
MaximumPercent?: number | null | undefined
131+
RateLimit: number
132+
}
133+
NotificationSender?: ServiceScalingParameters | null | undefined
134+
ActivityHistorian?: ServiceScalingParameters | null | undefined
135+
ZeroMinimumHealthyPercent?: boolean | null | undefined
136+
}
137+
ReCaptcha: {
138+
LoginMinScore: number
139+
SignupMinScore: number
140+
SiteKey: string
141+
SecretKey: string
142+
}
143+
Stripe: {
144+
PublishableKey: string
145+
SecretKey: string
146+
}
147+
LiveChat: {
148+
License: string
149+
}
150+
NotificationsApi: {
151+
Url: string
152+
Token: string
153+
}
154+
ClarityDockerImageTag: string
155+
JCoreIOLink?: string | null | undefined
156+
JWT: {
157+
SecretKey: string
158+
}
159+
Superadmin?:
160+
| {
161+
Email?: string | null | undefined
162+
Password?: string | null | undefined
163+
}
164+
| null
165+
| undefined
166+
}
167+
168+
const DeployConfigType = t.object<DeployConfig>({
169+
CloudFormationTemplateBucket: t.nullable(t.string()),
170+
DeploymentName: t.string(),
171+
AppName: t.nullable(t.string()),
172+
/**
173+
* The base domain name of the app, for example: clarity.foo.com
174+
*/
175+
BaseDomainName: t.nullable(t.string()),
176+
/**
177+
* The domain name of the Route 53 hosted zone, for example: foo.com
178+
*/
179+
HostedZoneDomainName: t.string(),
180+
/**
181+
* The id of the VPC to deploy into
182+
*/
183+
VpcId: t.string(),
184+
/**
185+
* The AWS region to deploy into
186+
*/
187+
region: t.string(),
188+
/**
189+
* The subnet ids for the Vpc. Defaults to all available for VpcId
190+
*/
191+
SubnetIds: t.nullable(t.array(t.string())),
192+
/**
193+
* Name of an existing EC2 KeyPair to enable SSH access to the ECS instances
194+
*/
195+
EC2KeyName: t.nullable(t.string()),
196+
VPN: t.nullable(
197+
t.object<DeployConfig['VPN']>({
198+
CidrIp: t.nullable(t.string()),
199+
SecurityGroupId: t.nullable(t.string()),
200+
})
201+
),
202+
/**
203+
* Settings for the user upload/download S3 buckets that Clarity uses.
204+
* Not applicable to CloudFormationTemplateBucket or CertificateProvider.S3BucketName.
205+
*/
206+
S3: t.nullable(
207+
t.object<DeployConfig['S3']>({
208+
/**
209+
* The origin URLs that the S3 buckets will allow.
210+
* For prod, just the public URL of the app. For staging,
211+
* you probably want a wildcard pattern like https://clarity-staging-*.foo.com
212+
*/
213+
AllowedOrigin: t.nullable(t.string()),
214+
})
215+
),
216+
Redis: t.union(
217+
t.object({
218+
Type: t.stringLiteral('External'),
219+
Host: t.string(),
220+
Port: t.nullable(t.number()),
221+
DB: t.nullable(t.number()),
222+
SecurityGroupId: t.nullable(t.string()),
223+
}),
224+
t.object({
225+
Type: t.stringLiteral('ElastiCache'),
226+
AvailabilityZone: t.string(),
227+
})
228+
),
229+
DB: t.union(
230+
t.object({
231+
Type: t.stringLiteral('External'),
232+
Host: t.string(),
233+
Port: t.nullable(t.number()),
234+
User: t.string(),
235+
Name: t.string(),
236+
Password: t.string(),
237+
RootDBName: t.nullable(t.string()),
238+
SecurityGroupId: t.nullable(t.string()),
239+
}),
240+
t.object({
241+
Type: t.stringLiteral('RDS'),
242+
MasterUserPassword: t.string(),
243+
AvailabilityZone: t.string(),
244+
})
245+
),
246+
Historian: t.object({
247+
DB: t.object({
248+
Host: t.string(),
249+
Port: t.nullable(t.number()),
250+
User: t.string(),
251+
Password: t.string(),
252+
Name: t.string(),
253+
SecurityGroupId: t.nullable(t.string()),
254+
}),
255+
Redis: t.nullable(
256+
t.object({
257+
Host: t.string(),
258+
Port: t.nullable(t.number()),
259+
SecurityGroupId: t.nullable(t.string()),
260+
})
261+
),
262+
}),
263+
ECSCluster: t.nullable(
264+
t.object({
265+
ClusterId: t.nullable(t.string()),
266+
MinSize: t.nullable(t.number()),
267+
MaxSize: t.nullable(t.number()),
268+
DesiredCapacity: t.nullable(t.number()),
269+
InstanceType: t.nullable(t.string()),
270+
})
271+
),
272+
CertificateProvider: t.nullable(
273+
t.object({
274+
StackName: t.nullable(t.string()),
275+
S3BucketName: t.nullable(t.string()),
276+
CFNCustomProviderZipFileName: t.nullable(t.string()),
277+
LambdaFunctionName: t.nullable(t.string()),
278+
})
279+
),
280+
Services: t.object({
281+
Webapp: t.nullable(ServiceScalingParametersType),
282+
RedirectHttps: t.nullable(ServiceScalingParametersType),
283+
MQTT: t.object({
284+
DesiredCount: t.nullable(t.number()),
285+
MaximumPercent: t.nullable(t.number()),
286+
RateLimit: t.number(),
287+
}),
288+
NotificationSender: t.nullable(ServiceScalingParametersType),
289+
ActivityHistorian: t.nullable(ServiceScalingParametersType),
290+
ZeroMinimumHealthyPercent: t.nullable(t.boolean()),
291+
}),
292+
ReCaptcha: t.object({
293+
LoginMinScore: t.number(),
294+
SignupMinScore: t.number(),
295+
SiteKey: t.string(),
296+
SecretKey: t.string(),
297+
}),
298+
Stripe: t.object({
299+
PublishableKey: t.string(),
300+
SecretKey: t.string(),
301+
}),
302+
LiveChat: t.object({
303+
License: t.string(),
304+
}),
305+
NotificationsApi: t.object({
306+
Url: t.string(),
307+
Token: t.string(),
308+
}),
309+
ClarityDockerImageTag: t.string(),
310+
JCoreIOLink: t.nullable(t.string()),
311+
JWT: t.object({
312+
SecretKey: t.string(),
313+
}),
314+
Superadmin: t.nullable(
315+
t.object({
316+
Email: t.nullable(t.string()),
317+
Password: t.nullable(t.string()),
318+
})
319+
),
320+
})
321+
322+
describe(`smoke test`, function() {
323+
it(`works`, function() {
324+
const config: DeployConfig = {
325+
CloudFormationTemplateBucket: 'templates.clarity.foo.com',
326+
DeploymentName: 'clarity-new',
327+
HostedZoneDomainName: 'foo.com',
328+
VpcId: 'vpc-222222222',
329+
region: 'us-west-2',
330+
SubnetIds: ['subnet-222222222'],
331+
VPN: {
332+
CidrIp: '172.0.0.0/32',
333+
},
334+
Redis: {
335+
Type: 'ElastiCache',
336+
AvailabilityZone: 'us-west-2a',
337+
},
338+
DB: {
339+
Type: 'RDS',
340+
AvailabilityZone: 'us-west-2a',
341+
MasterUserPassword: 'blah',
342+
},
343+
Historian: {
344+
DB: {
345+
Host: 'historian-staging-db-01.foo.com',
346+
Password: '22222222222222222222222',
347+
User: 'postgres',
348+
Name: 'historian',
349+
SecurityGroupId: 'sg-22222222222',
350+
},
351+
},
352+
ECSCluster: {
353+
DesiredCapacity: 2,
354+
},
355+
Services: {
356+
MQTT: {
357+
RateLimit: 10000,
358+
},
359+
},
360+
ReCaptcha: {
361+
LoginMinScore: 0.15,
362+
SignupMinScore: 0.15,
363+
SiteKey: '22222222222222',
364+
SecretKey: '22222222222222',
365+
},
366+
Stripe: {
367+
PublishableKey: '22222222222222',
368+
SecretKey: '22222222222222',
369+
},
370+
LiveChat: {
371+
License: '10730772',
372+
},
373+
NotificationsApi: {
374+
Url: 'https://notifications-api.foo.com',
375+
Token: '22222222222222',
376+
},
377+
ClarityDockerImageTag: 'master',
378+
JCoreIOLink: 'http://foo.com',
379+
JWT: {
380+
SecretKey: '222222222222222',
381+
},
382+
Superadmin: {
383+
Email: 'dev@foo.com',
384+
},
385+
}
386+
387+
DeployConfigType.assert(config)
388+
})
389+
})

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,6 @@ export function union<T1, T2, T3, T4, T5, T6, T7, T8>(
173173
export function union(...types: Type<any>[]): Type<any> {
174174
return new UnionType(types)
175175
}
176+
177+
export const constrain = <T>(name: string, type: Type<T>): ConstrainedType<T> =>
178+
new ConstrainedType(name, type)

0 commit comments

Comments
 (0)