@sureshgururajan/aws-console-private-access-validator 1.0.1 → 1.0.2

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
File without changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,87 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
4
+ import { ConsolePrivateAccessValidator } from './validator.js';
5
+ const server = new Server({
6
+ name: 'aws-console-private-access-validator',
7
+ version: '1.0.0',
8
+ }, {
9
+ capabilities: {
10
+ tools: {},
11
+ },
12
+ });
13
+ const tools = [
14
+ {
15
+ name: 'validate-cloudformation',
16
+ description: 'Validates a CloudFormation template for AWS Console Private Access requirements',
17
+ inputSchema: {
18
+ type: 'object',
19
+ properties: {
20
+ template: {
21
+ type: 'string',
22
+ description: 'CloudFormation template as JSON string',
23
+ },
24
+ region: {
25
+ type: 'string',
26
+ description: 'AWS region (default: us-east-1)',
27
+ default: 'us-east-1',
28
+ },
29
+ },
30
+ required: ['template'],
31
+ },
32
+ },
33
+ ];
34
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
35
+ tools,
36
+ }));
37
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
38
+ if (request.params.name === 'validate-cloudformation') {
39
+ const { template, region = 'us-east-1' } = request.params.arguments;
40
+ try {
41
+ const parsedTemplate = JSON.parse(template);
42
+ const validator = new ConsolePrivateAccessValidator(parsedTemplate, region);
43
+ const result = validator.validate();
44
+ return {
45
+ content: [
46
+ {
47
+ type: 'text',
48
+ text: JSON.stringify(result, null, 2),
49
+ },
50
+ ],
51
+ };
52
+ }
53
+ catch (error) {
54
+ const errorMessage = error instanceof Error ? error.message : String(error);
55
+ return {
56
+ content: [
57
+ {
58
+ type: 'text',
59
+ text: JSON.stringify({
60
+ valid: false,
61
+ checks: [],
62
+ summary: `Error parsing template: ${errorMessage}`,
63
+ }, null, 2),
64
+ },
65
+ ],
66
+ isError: true,
67
+ };
68
+ }
69
+ }
70
+ return {
71
+ content: [
72
+ {
73
+ type: 'text',
74
+ text: `Unknown tool: ${request.params.name}`,
75
+ },
76
+ ],
77
+ isError: true,
78
+ };
79
+ });
80
+ async function main() {
81
+ const transport = new StdioServerTransport();
82
+ await server.connect(transport);
83
+ }
84
+ main().catch((error) => {
85
+ process.exit(1);
86
+ });
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/test.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":""}
package/dist/test.js ADDED
@@ -0,0 +1,26 @@
1
+ import fs from 'fs';
2
+ import { ConsolePrivateAccessValidator } from './validator.js';
3
+ // Read the CloudFormation template
4
+ const templatePath = process.argv[2] || '/tmp/template.json';
5
+ const templateContent = fs.readFileSync(templatePath, 'utf-8');
6
+ const template = JSON.parse(templateContent);
7
+ // Run validation
8
+ const validator = new ConsolePrivateAccessValidator(template, 'us-east-1');
9
+ const result = validator.validate();
10
+ // Print results
11
+ console.log('\n=== AWS Console Private Access Validation Results ===\n');
12
+ console.log(`Valid: ${result.valid ? '✓ YES' : '✗ NO'}\n`);
13
+ console.log('Checks:');
14
+ result.checks.forEach((check) => {
15
+ const icon = check.status === 'pass' ? '✓' : check.status === 'fail' ? '✗' : '⚠';
16
+ console.log(` ${icon} ${check.name}`);
17
+ console.log(` Status: ${check.status}`);
18
+ console.log(` Message: ${check.message}`);
19
+ if (check.details) {
20
+ console.log(` Details: ${check.details}`);
21
+ }
22
+ });
23
+ console.log(`\nSummary: ${result.summary}\n`);
24
+ // Exit with appropriate code
25
+ process.exit(result.valid ? 0 : 1);
26
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAE/D,mCAAmC;AACnC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,oBAAoB,CAAC;AAC7D,MAAM,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;AAE7C,iBAAiB;AACjB,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC3E,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;AAEpC,gBAAgB;AAChB,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;AACzE,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;AAE3D,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACvB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;IAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACjF,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;AAE9C,6BAA6B;AAC7B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface ValidationCheck {
2
+ name: string;
3
+ status: 'pass' | 'fail' | 'warning';
4
+ message: string;
5
+ details?: string;
6
+ }
7
+ export interface ValidationResult {
8
+ valid: boolean;
9
+ checks: ValidationCheck[];
10
+ summary: string;
11
+ }
12
+ export interface CloudFormationTemplate {
13
+ Resources?: Record<string, any>;
14
+ Outputs?: Record<string, any>;
15
+ Parameters?: Record<string, any>;
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import { ValidationResult, CloudFormationTemplate } from './types';
2
+ export declare class ConsolePrivateAccessValidator {
3
+ private template;
4
+ private region;
5
+ private checks;
6
+ constructor(template: CloudFormationTemplate, region?: string);
7
+ validate(): ValidationResult;
8
+ private getServiceName;
9
+ private checkVpcEndpoints;
10
+ private checkEndpointPolicies;
11
+ private validatePolicyContent;
12
+ private checkRoute53HostedZones;
13
+ private checkSecurityGroups;
14
+ private checkEc2Instance;
15
+ private checkNatGateway;
16
+ private checkNetworkConfiguration;
17
+ private generateSummary;
18
+ }
19
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEpF,qBAAa,6BAA6B;IACxC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAyB;gBAE3B,QAAQ,EAAE,sBAAsB,EAAE,MAAM,GAAE,MAAoB;IAK1E,QAAQ,IAAI,gBAAgB;IAqB5B,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,iBAAiB;IAiDzB,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,uBAAuB;IAuC/B,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,yBAAyB;IAkCjC,OAAO,CAAC,eAAe;CAUxB"}
@@ -0,0 +1,234 @@
1
+ export class ConsolePrivateAccessValidator {
2
+ constructor(template, region = 'us-east-1') {
3
+ this.checks = [];
4
+ this.template = template;
5
+ this.region = region;
6
+ }
7
+ validate() {
8
+ this.checks = [];
9
+ this.checkVpcEndpoints();
10
+ this.checkEndpointPolicies();
11
+ this.checkRoute53HostedZones();
12
+ this.checkSecurityGroups();
13
+ this.checkEc2Instance();
14
+ this.checkNatGateway();
15
+ this.checkNetworkConfiguration();
16
+ const failCount = this.checks.filter(c => c.status === 'fail').length;
17
+ const valid = failCount === 0;
18
+ return {
19
+ valid,
20
+ checks: this.checks,
21
+ summary: this.generateSummary(valid, failCount),
22
+ };
23
+ }
24
+ getServiceName(serviceName) {
25
+ if (typeof serviceName === 'string') {
26
+ return serviceName;
27
+ }
28
+ if (serviceName?.['Fn::Join']) {
29
+ const parts = serviceName['Fn::Join'][1];
30
+ if (Array.isArray(parts)) {
31
+ // Handle Ref to AWS::Region by replacing with actual region
32
+ return parts
33
+ .map((part) => {
34
+ if (typeof part === 'string') {
35
+ return part;
36
+ }
37
+ if (part?.Ref === 'AWS::Region') {
38
+ return this.region;
39
+ }
40
+ return '';
41
+ })
42
+ .join('');
43
+ }
44
+ }
45
+ return null;
46
+ }
47
+ checkVpcEndpoints() {
48
+ const requiredEndpoints = [
49
+ { name: 'console', service: `com.amazonaws.${this.region}.console` },
50
+ { name: 'signin', service: `com.amazonaws.${this.region}.signin` },
51
+ { name: 'ssm', service: `com.amazonaws.${this.region}.ssm` },
52
+ { name: 'ec2messages', service: `com.amazonaws.${this.region}.ec2messages` },
53
+ { name: 'ssmmessages', service: `com.amazonaws.${this.region}.ssmmessages` },
54
+ ];
55
+ const resources = this.template.Resources || {};
56
+ const interfaceEndpoints = Object.values(resources).filter((r) => r.Type === 'AWS::EC2::VPCEndpoint' && r.Properties?.VpcEndpointType === 'Interface');
57
+ for (const endpoint of requiredEndpoints) {
58
+ const found = interfaceEndpoints.some((e) => {
59
+ const serviceName = this.getServiceName(e.Properties?.ServiceName);
60
+ return serviceName && serviceName.includes(endpoint.service);
61
+ });
62
+ this.checks.push({
63
+ name: `VPC Endpoint: ${endpoint.name}`,
64
+ status: found ? 'pass' : 'fail',
65
+ message: found
66
+ ? `Interface VPC endpoint for ${endpoint.name} found`
67
+ : `Missing interface VPC endpoint for ${endpoint.name}`,
68
+ });
69
+ }
70
+ // Check for S3 Gateway endpoint
71
+ const s3Gateway = Object.values(resources).some((r) => {
72
+ const serviceName = this.getServiceName(r.Properties?.ServiceName);
73
+ return (r.Type === 'AWS::EC2::VPCEndpoint' &&
74
+ r.Properties?.VpcEndpointType === 'Gateway' &&
75
+ serviceName &&
76
+ serviceName.includes('s3'));
77
+ });
78
+ this.checks.push({
79
+ name: 'VPC Endpoint: S3 Gateway',
80
+ status: s3Gateway ? 'pass' : 'fail',
81
+ message: s3Gateway ? 'S3 Gateway VPC endpoint found' : 'Missing S3 Gateway VPC endpoint',
82
+ });
83
+ }
84
+ checkEndpointPolicies() {
85
+ const resources = this.template.Resources || {};
86
+ const consoleEndpoint = Object.entries(resources).find(([_, r]) => {
87
+ const serviceName = this.getServiceName(r.Properties?.ServiceName);
88
+ return (r.Type === 'AWS::EC2::VPCEndpoint' &&
89
+ serviceName &&
90
+ serviceName.includes('console'));
91
+ });
92
+ const signinEndpoint = Object.entries(resources).find(([_, r]) => {
93
+ const serviceName = this.getServiceName(r.Properties?.ServiceName);
94
+ return (r.Type === 'AWS::EC2::VPCEndpoint' &&
95
+ serviceName &&
96
+ serviceName.includes('signin'));
97
+ });
98
+ for (const [name, endpoint] of [
99
+ ['Console', consoleEndpoint],
100
+ ['Signin', signinEndpoint],
101
+ ]) {
102
+ if (!endpoint)
103
+ continue;
104
+ const [_, resource] = endpoint;
105
+ const hasPolicy = resource.Properties?.PolicyDocument;
106
+ this.checks.push({
107
+ name: `Endpoint Policy: ${name}`,
108
+ status: hasPolicy ? 'pass' : 'fail',
109
+ message: hasPolicy
110
+ ? `${name} endpoint has a policy attached`
111
+ : `${name} endpoint is missing a policy`,
112
+ details: hasPolicy
113
+ ? this.validatePolicyContent(resource.Properties.PolicyDocument)
114
+ : undefined,
115
+ });
116
+ }
117
+ }
118
+ validatePolicyContent(policy) {
119
+ if (!policy.Statement || policy.Statement.length === 0) {
120
+ return 'Policy has no statements';
121
+ }
122
+ const statement = policy.Statement[0];
123
+ const hasAccountCondition = statement.Condition?.StringEquals?.['aws:PrincipalAccount'];
124
+ if (hasAccountCondition) {
125
+ return 'Policy restricts access to specific account(s)';
126
+ }
127
+ return 'Policy does not restrict access by account';
128
+ }
129
+ checkRoute53HostedZones() {
130
+ const resources = this.template.Resources || {};
131
+ const hostedZones = Object.values(resources).filter((r) => r.Type === 'AWS::Route53::HostedZone');
132
+ const requiredZones = ['console.aws.amazon.com', 'signin.aws.amazon.com'];
133
+ for (const zone of requiredZones) {
134
+ const found = hostedZones.some((hz) => {
135
+ const zoneName = hz.Properties?.Name;
136
+ // Route53 zone names may have a trailing dot
137
+ return zoneName === zone || zoneName === `${zone}.`;
138
+ });
139
+ this.checks.push({
140
+ name: `Route53 Hosted Zone: ${zone}`,
141
+ status: found ? 'pass' : 'fail',
142
+ message: found
143
+ ? `Private hosted zone for ${zone} found`
144
+ : `Missing private hosted zone for ${zone}`,
145
+ });
146
+ }
147
+ // Check for Route53 records
148
+ const recordSets = Object.values(resources).filter((r) => r.Type === 'AWS::Route53::RecordSet');
149
+ this.checks.push({
150
+ name: 'Route53 Records',
151
+ status: recordSets.length > 0 ? 'pass' : 'warning',
152
+ message: recordSets.length > 0
153
+ ? `Found ${recordSets.length} Route53 records`
154
+ : 'No Route53 records found',
155
+ });
156
+ }
157
+ checkSecurityGroups() {
158
+ const resources = this.template.Resources || {};
159
+ const securityGroups = Object.values(resources).filter((r) => r.Type === 'AWS::EC2::SecurityGroup');
160
+ const hasHttpsIngress = securityGroups.some((sg) => {
161
+ const ingress = sg.Properties?.SecurityGroupIngress || [];
162
+ return ingress.some((rule) => (rule.FromPort === 443 || rule.IpProtocol === 'tcp') &&
163
+ (rule.ToPort === 443 || rule.IpProtocol === 'tcp'));
164
+ });
165
+ this.checks.push({
166
+ name: 'Security Group: HTTPS Access',
167
+ status: hasHttpsIngress ? 'pass' : 'warning',
168
+ message: hasHttpsIngress
169
+ ? 'Security group allows HTTPS (port 443) traffic'
170
+ : 'No security group rule found for HTTPS (port 443)',
171
+ });
172
+ }
173
+ checkEc2Instance() {
174
+ const resources = this.template.Resources || {};
175
+ const instance = Object.values(resources).find((r) => r.Type === 'AWS::EC2::Instance');
176
+ this.checks.push({
177
+ name: 'EC2 Instance',
178
+ status: instance ? 'pass' : 'warning',
179
+ message: instance ? 'EC2 instance found' : 'No EC2 instance found (optional)',
180
+ });
181
+ if (instance) {
182
+ const hasIamRole = instance.Properties?.IamInstanceProfile;
183
+ this.checks.push({
184
+ name: 'EC2 IAM Role',
185
+ status: hasIamRole ? 'pass' : 'warning',
186
+ message: hasIamRole
187
+ ? 'EC2 instance has IAM instance profile'
188
+ : 'EC2 instance missing IAM instance profile',
189
+ });
190
+ }
191
+ }
192
+ checkNatGateway() {
193
+ const resources = this.template.Resources || {};
194
+ const natGateway = Object.values(resources).find((r) => r.Type === 'AWS::EC2::NatGateway');
195
+ this.checks.push({
196
+ name: 'NAT Gateway',
197
+ status: natGateway ? 'pass' : 'warning',
198
+ message: natGateway
199
+ ? 'NAT Gateway found for private subnet egress'
200
+ : 'No NAT Gateway found (required for private subnet internet access)',
201
+ });
202
+ }
203
+ checkNetworkConfiguration() {
204
+ const resources = this.template.Resources || {};
205
+ // Check for private subnets
206
+ const privateSubnets = Object.values(resources).filter((r) => r.Type === 'AWS::EC2::Subnet' &&
207
+ !r.Properties?.MapPublicIpOnLaunch);
208
+ this.checks.push({
209
+ name: 'Private Subnets',
210
+ status: privateSubnets.length > 0 ? 'pass' : 'fail',
211
+ message: privateSubnets.length > 0
212
+ ? `Found ${privateSubnets.length} private subnet(s)`
213
+ : 'No private subnets found',
214
+ });
215
+ // Check for route tables
216
+ const routeTables = Object.values(resources).filter((r) => r.Type === 'AWS::EC2::RouteTable');
217
+ this.checks.push({
218
+ name: 'Route Tables',
219
+ status: routeTables.length > 0 ? 'pass' : 'warning',
220
+ message: routeTables.length > 0
221
+ ? `Found ${routeTables.length} route table(s)`
222
+ : 'No route tables found',
223
+ });
224
+ }
225
+ generateSummary(valid, failCount) {
226
+ const passCount = this.checks.filter(c => c.status === 'pass').length;
227
+ const warningCount = this.checks.filter(c => c.status === 'warning').length;
228
+ if (valid) {
229
+ return `✓ Validation passed. All required checks passed (${passCount} passed, ${warningCount} warnings).`;
230
+ }
231
+ return `✗ Validation failed. ${failCount} check(s) failed, ${passCount} passed, ${warningCount} warnings.`;
232
+ }
233
+ }
234
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@sureshgururajan/aws-console-private-access-validator",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "description": "MCP server for validating AWS Console Private Access CloudFormation templates",
6
6
  "main": "dist/index.js",
7
+ "bin": {
8
+ "aws-console-private-access-validator": "dist/index.js"
9
+ },
7
10
  "scripts": {
8
11
  "build": "tsc",
9
12
  "start": "node dist/index.js",
@@ -23,3 +26,4 @@
23
26
  }
24
27
  }
25
28
 
29
+
package/src/index.ts CHANGED
File without changes
package/src/test.ts CHANGED
File without changes
package/src/types.ts CHANGED
File without changes
package/src/validator.ts CHANGED
File without changes
package/tsconfig.json CHANGED
File without changes