Skip to content

Commit afe9dc6

Browse files
author
Mark Kuhn
committed
change validator from class to static functions
1 parent a9960ee commit afe9dc6

File tree

4 files changed

+139
-141
lines changed

4 files changed

+139
-141
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"license": "Apache-2.0",
3535
"dependencies": {
3636
"@datastructures-js/heap": "^4.0.2",
37-
"@types/validator": "^13.7.5",
37+
"@types/validator": "^13.7.6",
3838
"validator": "^13.7.0"
3939
},
4040
"devDependencies": {

src/logger/MetricsContext.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import Configuration from '../config/Configuration';
1717
import { LOG } from '../utils/Logger';
18-
import { Validator } from '../utils/Validator';
18+
import { validateNamespace, validateTimestamp, validateDimensionSet, validateMetric } from '../utils/Validator';
1919
import { MetricValues } from './MetricValues';
2020
import { Unit } from './Unit';
2121

@@ -83,7 +83,7 @@ export class MetricsContext {
8383
}
8484

8585
public setNamespace(value: string): void {
86-
Validator.validateNamespace(value);
86+
validateNamespace(value);
8787
this.namespace = value;
8888
}
8989

@@ -92,7 +92,7 @@ export class MetricsContext {
9292
}
9393

9494
public setTimestamp(timestamp: Date | number): void {
95-
Validator.validateTimestamp(timestamp);
95+
validateTimestamp(timestamp);
9696
this.timestamp = timestamp;
9797
this.meta.Timestamp = MetricsContext.resolveMetaTimestamp(timestamp);
9898
}
@@ -114,7 +114,7 @@ export class MetricsContext {
114114
* @param dimensions
115115
*/
116116
public putDimensions(incomingDimensionSet: Record<string, string>): void {
117-
Validator.validateDimensionSet(incomingDimensionSet);
117+
validateDimensionSet(incomingDimensionSet);
118118

119119
// Duplicate dimensions sets are removed before being added to the end of the collection.
120120
// This ensures the latest dimension key-value is used as a target member on the root EMF node.
@@ -139,7 +139,7 @@ export class MetricsContext {
139139
* @param dimensionSets
140140
*/
141141
public setDimensions(dimensionSets: Array<Record<string, string>>, useDefault = false): void {
142-
dimensionSets.forEach((dimensionSet) => Validator.validateDimensionSet(dimensionSet));
142+
dimensionSets.forEach((dimensionSet) => validateDimensionSet(dimensionSet));
143143
this.shouldUseDefaultDimensions = useDefault;
144144
this.dimensions = dimensionSets;
145145
}
@@ -181,7 +181,7 @@ export class MetricsContext {
181181
}
182182

183183
public putMetric(key: string, value: number, unit?: Unit | string): void {
184-
Validator.validateMetric(key, value, unit);
184+
validateMetric(key, value, unit);
185185

186186
const currentMetric = this.metrics.get(key);
187187
if (currentMetric) {

src/utils/Validator.ts

Lines changed: 131 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -22,161 +22,159 @@ import { InvalidMetricError } from '../exceptions/InvalidMetricError';
2222
import { InvalidNamespaceError } from '../exceptions/InvalidNamespaceError';
2323
import { InvalidTimestampError } from '../exceptions/InvalidTimestampError';
2424

25-
export class Validator {
26-
/**
27-
* Validates dimension set.
28-
* @see [CloudWatch Dimensions](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_Dimension.html)
29-
*
30-
* @param dimensionSet
31-
* @throws {DimensionSetExceededError} Dimension set must not exceed 30 dimensions.
32-
* @throws {InvalidDimensionError} Dimension name and value must be valid.
33-
*/
34-
public static validateDimensionSet(dimensionSet: Record<string, string>): void {
35-
// Validates dimension set length
36-
if (Object.keys(dimensionSet).length > Constants.MAX_DIMENSION_SET_SIZE)
37-
throw new DimensionSetExceededError(
38-
`Maximum number of dimensions per dimension set allowed are ${Constants.MAX_DIMENSION_SET_SIZE}`,
39-
);
25+
/**
26+
* Validates dimension set.
27+
* @see [CloudWatch Dimensions](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_Dimension.html)
28+
*
29+
* @param dimensionSet
30+
* @throws {DimensionSetExceededError} Dimension set must not exceed 30 dimensions.
31+
* @throws {InvalidDimensionError} Dimension name and value must be valid.
32+
*/
33+
const validateDimensionSet = (dimensionSet: Record<string, string>): void => {
34+
// Validates dimension set length
35+
if (Object.keys(dimensionSet).length > Constants.MAX_DIMENSION_SET_SIZE)
36+
throw new DimensionSetExceededError(
37+
`Maximum number of dimensions per dimension set allowed are ${Constants.MAX_DIMENSION_SET_SIZE}`,
38+
);
4039

41-
// Validate dimension key and value
42-
Object.entries(dimensionSet).forEach(([key, value]) => {
43-
dimensionSet[key] = value = String(value);
44-
45-
if (!validator.isAscii(key)) {
46-
throw new InvalidDimensionError(`Dimension key ${key} has invalid characters`);
47-
}
48-
if (!validator.isAscii(value)) {
49-
throw new InvalidDimensionError(`Dimension value ${value} has invalid characters`);
50-
}
51-
52-
if (key.trim().length == 0) {
53-
throw new InvalidDimensionError(`Dimension key ${key} must include at least one non-whitespace character`);
54-
}
55-
56-
if (value.trim().length == 0) {
57-
throw new InvalidDimensionError(`Dimension value ${value} must include at least one non-whitespace character`);
58-
}
59-
60-
if (key.length > Constants.MAX_DIMENSION_NAME_LENGTH) {
61-
throw new InvalidDimensionError(
62-
`Dimension key ${key} must not exceed maximum length ${Constants.MAX_DIMENSION_NAME_LENGTH}`,
63-
);
64-
}
65-
66-
if (value.length > Constants.MAX_DIMENSION_VALUE_LENGTH) {
67-
throw new InvalidDimensionError(
68-
`Dimension value ${value} must not exceed maximum length ${Constants.MAX_DIMENSION_VALUE_LENGTH}`,
69-
);
70-
}
71-
72-
if (key.startsWith(':')) {
73-
throw new InvalidDimensionError(`Dimension key ${key} cannot start with ':'`);
74-
}
75-
});
76-
}
40+
// Validate dimension key and value
41+
Object.entries(dimensionSet).forEach(([key, value]) => {
42+
dimensionSet[key] = value = String(value);
7743

78-
/**
79-
* Validates metric.
80-
* @see [CloudWatch Metric](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html)
81-
*
82-
* @param key
83-
* @param value
84-
*
85-
* @throws {InvalidMetricError} Metric name must be valid.
86-
*/
87-
public static validateMetric(key: string, value: number, unit?: Unit | string): void {
88-
if (key.trim().length == 0) {
89-
throw new InvalidMetricError(`Metric key ${key} must include at least one non-whitespace character`);
44+
if (!validator.isAscii(key)) {
45+
throw new InvalidDimensionError(`Dimension key ${key} has invalid characters`);
46+
}
47+
if (!validator.isAscii(value)) {
48+
throw new InvalidDimensionError(`Dimension value ${value} has invalid characters`);
9049
}
9150

92-
if (key.length > Constants.MAX_METRIC_NAME_LENGTH) {
93-
throw new InvalidMetricError(
94-
`Metric key ${key} must not exceed maximum length ${Constants.MAX_METRIC_NAME_LENGTH}`,
95-
);
51+
if (key.trim().length == 0) {
52+
throw new InvalidDimensionError(`Dimension key ${key} must include at least one non-whitespace character`);
9653
}
9754

98-
if (!Number.isFinite(value)) {
99-
throw new InvalidMetricError(`Metric value ${value} is not a number`);
55+
if (value.trim().length == 0) {
56+
throw new InvalidDimensionError(`Dimension value ${value} must include at least one non-whitespace character`);
10057
}
10158

102-
if (value > Number.MAX_SAFE_INTEGER) {
103-
throw new InvalidMetricError(
104-
`Metric value ${value} must not exceed maximum value ${Number.MAX_SAFE_INTEGER}}`,
59+
if (key.length > Constants.MAX_DIMENSION_NAME_LENGTH) {
60+
throw new InvalidDimensionError(
61+
`Dimension key ${key} must not exceed maximum length ${Constants.MAX_DIMENSION_NAME_LENGTH}`,
10562
);
10663
}
10764

108-
if (value < -Number.MAX_SAFE_INTEGER) {
109-
throw new InvalidMetricError(
110-
`Metric value ${value} must not be less than minimum value ${-Number.MAX_SAFE_INTEGER}`,
65+
if (value.length > Constants.MAX_DIMENSION_VALUE_LENGTH) {
66+
throw new InvalidDimensionError(
67+
`Dimension value ${value} must not exceed maximum length ${Constants.MAX_DIMENSION_VALUE_LENGTH}`,
11168
);
11269
}
11370

114-
if (
115-
unit !== undefined &&
116-
!Object.values(Unit)
117-
.map(u => String(u))
118-
.includes(unit)
119-
) {
120-
throw new InvalidMetricError(`Metric unit ${unit} is not valid`);
71+
if (key.startsWith(':')) {
72+
throw new InvalidDimensionError(`Dimension key ${key} cannot start with ':'`);
12173
}
122-
}
74+
});
75+
};
12376

124-
/**
125-
* Validates metric namespace.
126-
* @see [CloudWatch Namespace](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Namespace)
127-
*
128-
* @param namespace
129-
* @throws {InvalidNamespaceError} Namespace must be of valid length.
130-
*/
131-
public static validateNamespace(namespace: string): void {
132-
if (namespace.trim().length == 0) {
133-
throw new InvalidNamespaceError(`Namespace must include at least one non-whitespace character`);
134-
}
77+
/**
78+
* Validates metric.
79+
* @see [CloudWatch Metric](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html)
80+
*
81+
* @param key
82+
* @param value
83+
*
84+
* @throws {InvalidMetricError} Metric name must be valid.
85+
*/
86+
const validateMetric = (key: string, value: number, unit?: Unit | string): void => {
87+
if (key.trim().length == 0) {
88+
throw new InvalidMetricError(`Metric key ${key} must include at least one non-whitespace character`);
89+
}
13590

136-
if (namespace.length > Constants.MAX_NAMESPACE_LENGTH) {
137-
throw new InvalidNamespaceError(`Namespace must not exceed maximum length ${Constants.MAX_NAMESPACE_LENGTH}`);
138-
}
91+
if (key.length > Constants.MAX_METRIC_NAME_LENGTH) {
92+
throw new InvalidMetricError(
93+
`Metric key ${key} must not exceed maximum length ${Constants.MAX_METRIC_NAME_LENGTH}`,
94+
);
95+
}
13996

140-
if (!validator.matches(namespace, Constants.VALID_NAMESPACE_REGEX)) {
141-
throw new InvalidNamespaceError(`Namespace ${namespace} has invalid characters`);
142-
}
97+
if (!Number.isFinite(value)) {
98+
throw new InvalidMetricError(`Metric value ${value} is not a number`);
14399
}
144100

145-
/**
146-
* Validates timestamp.
147-
* @see [CloudWatch Timestamp](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#about_timestamp)
148-
*
149-
* @param timestamp
150-
*/
151-
public static validateTimestamp(timestamp: Date | number): void {
152-
timestamp = timestamp instanceof Date ? timestamp : new Date(timestamp);
153-
154-
let timestampStr;
155-
try {
156-
timestampStr = timestamp.toISOString();
157-
} catch (e) {
158-
throw new InvalidTimestampError(`Timestamp ${String(timestamp)} is invalid`);
159-
}
101+
if (value > Number.MAX_SAFE_INTEGER) {
102+
throw new InvalidMetricError(`Metric value ${value} must not exceed maximum value ${Number.MAX_SAFE_INTEGER}}`);
103+
}
160104

161-
const isTooOld = validator.isBefore(
162-
timestampStr,
163-
new Date(Date.now() - Constants.MAX_TIMESTAMP_PAST_AGE).toISOString(),
164-
);
165-
const isTooNew = validator.isAfter(
166-
timestampStr,
167-
new Date(Date.now() + Constants.MAX_TIMESTAMP_FUTURE_AGE).toISOString(),
105+
if (value < -Number.MAX_SAFE_INTEGER) {
106+
throw new InvalidMetricError(
107+
`Metric value ${value} must not be less than minimum value ${-Number.MAX_SAFE_INTEGER}`,
168108
);
109+
}
169110

170-
if (isTooOld) {
171-
throw new InvalidTimestampError(
172-
`Timestamp ${timestampStr} must not be older than ${Constants.MAX_TIMESTAMP_PAST_AGE} milliseconds`,
173-
);
174-
}
111+
if (
112+
unit !== undefined &&
113+
!Object.values(Unit)
114+
.map((u) => String(u))
115+
.includes(unit)
116+
) {
117+
throw new InvalidMetricError(`Metric unit ${unit} is not valid`);
118+
}
119+
};
175120

176-
if (isTooNew) {
177-
throw new InvalidTimestampError(
178-
`Timestamp ${timestampStr} must not be newer than ${Constants.MAX_TIMESTAMP_FUTURE_AGE} milliseconds`,
179-
);
180-
}
121+
/**
122+
* Validates metric namespace.
123+
* @see [CloudWatch Namespace](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Namespace)
124+
*
125+
* @param namespace
126+
* @throws {InvalidNamespaceError} Namespace must be of valid length.
127+
*/
128+
const validateNamespace = (namespace: string): void => {
129+
if (namespace.trim().length == 0) {
130+
throw new InvalidNamespaceError(`Namespace must include at least one non-whitespace character`);
131+
}
132+
133+
if (namespace.length > Constants.MAX_NAMESPACE_LENGTH) {
134+
throw new InvalidNamespaceError(`Namespace must not exceed maximum length ${Constants.MAX_NAMESPACE_LENGTH}`);
135+
}
136+
137+
if (!validator.matches(namespace, Constants.VALID_NAMESPACE_REGEX)) {
138+
throw new InvalidNamespaceError(`Namespace ${namespace} has invalid characters`);
181139
}
182-
}
140+
};
141+
142+
/**
143+
* Validates timestamp.
144+
* @see [CloudWatch Timestamp](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#about_timestamp)
145+
*
146+
* @param timestamp
147+
*/
148+
const validateTimestamp = (timestamp: Date | number): void => {
149+
timestamp = timestamp instanceof Date ? timestamp : new Date(timestamp);
150+
151+
let timestampStr;
152+
try {
153+
timestampStr = timestamp.toISOString();
154+
} catch (e) {
155+
throw new InvalidTimestampError(`Timestamp ${String(timestamp)} is invalid`);
156+
}
157+
158+
const isTooOld = validator.isBefore(
159+
timestampStr,
160+
new Date(Date.now() - Constants.MAX_TIMESTAMP_PAST_AGE).toISOString(),
161+
);
162+
const isTooNew = validator.isAfter(
163+
timestampStr,
164+
new Date(Date.now() + Constants.MAX_TIMESTAMP_FUTURE_AGE).toISOString(),
165+
);
166+
167+
if (isTooOld) {
168+
throw new InvalidTimestampError(
169+
`Timestamp ${timestampStr} must not be older than ${Constants.MAX_TIMESTAMP_PAST_AGE} milliseconds`,
170+
);
171+
}
172+
173+
if (isTooNew) {
174+
throw new InvalidTimestampError(
175+
`Timestamp ${timestampStr} must not be newer than ${Constants.MAX_TIMESTAMP_FUTURE_AGE} milliseconds`,
176+
);
177+
}
178+
};
179+
180+
export { validateDimensionSet, validateMetric, validateNamespace, validateTimestamp };

0 commit comments

Comments
 (0)