Skip to content

Commit 81dfaec

Browse files
Create dataNormalizer.js
1 parent ef9fc6d commit 81dfaec

File tree

1 file changed

+231
-0
lines changed

1 file changed

+231
-0
lines changed
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/**
2+
* DataNormalizer Script Include
3+
* ----------------------------------------------------------------
4+
* Provides reusable utility functions to standardize and sanitize
5+
* common data fields such as names, emails, phone numbers, addresses,
6+
* and dates. Supports both server-side and client-side (GlideAjax)
7+
* for flexible integration across multiple modules.
8+
* ----------------------------------------------------------------
9+
*/
10+
11+
var DataNormalizer = Class.create();
12+
DataNormalizer.prototype = Object.extendsObject(AbstractAjaxProcessor, {
13+
14+
initialize: function() {
15+
this.debug = true; // Toggle debug logging
16+
},
17+
18+
/**
19+
* Logs structured error messages to system logs.
20+
* @param {String} method - Method name where the error occurred.
21+
* @param {Object} error - JavaScript error object.
22+
* @param {Object} [context] - Optional additional context data.
23+
*/
24+
logError: function(method, error, context) {
25+
gs.error('[DataNormalizer] Error in {0}: {1} | Context: {2}',
26+
method, error.message, JSON.stringify(context || {}));
27+
},
28+
29+
/**
30+
* Logs informational messages when debug mode is enabled.
31+
* @param {String} message - The message to log.
32+
*/
33+
logInfo: function(message) {
34+
if (this.debug)
35+
gs.info('[DataNormalizer] {0}', message);
36+
},
37+
38+
/**
39+
* Normalizes personal names by removing special characters
40+
* and applying proper case formatting.
41+
* Example: "JOHN DOE" → "John Doe"
42+
*
43+
* @param {String} name - Input name value.
44+
* @returns {String} - Normalized name.
45+
*/
46+
normalizeName: function(name) {
47+
try {
48+
if (!name) return '';
49+
name = name.trim().replace(/[^a-zA-Z\s]/g, '');
50+
var formatted = name.split(/\s+/)
51+
.map(function(w) {
52+
return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();
53+
})
54+
.join(' ');
55+
this.logInfo('normalizeName: "' + name + '" → "' + formatted + '"');
56+
return formatted;
57+
} catch (e) {
58+
this.logError('normalizeName', e, { name: name });
59+
return name;
60+
}
61+
},
62+
63+
/**
64+
* Normalizes email addresses by trimming whitespace,
65+
* converting to lowercase, and removing invalid characters.
66+
*
67+
* @param {String} email - Input email value.
68+
* @returns {String} - Normalized email.
69+
*/
70+
normalizeEmail: function(email) {
71+
try {
72+
if (!email) return '';
73+
var clean = email.trim().toLowerCase().replace(/[,;]+/g, '');
74+
this.logInfo('normalizeEmail: "' + email + '" → "' + clean + '"');
75+
return clean;
76+
} catch (e) {
77+
this.logError('normalizeEmail', e, { email: email });
78+
return email;
79+
}
80+
},
81+
82+
/**
83+
* Standardizes phone numbers by removing non-numeric characters
84+
* and adding country codes where applicable.
85+
*
86+
* @param {String} phone - Input phone number.
87+
* @param {String} [defaultCountryCode] - Optional default country code (e.g., "91").
88+
* @returns {String} - Normalized phone number.
89+
*/
90+
normalizePhone: function(phone, defaultCountryCode) {
91+
try {
92+
if (!phone) return '';
93+
var digits = phone.replace(/\D/g, '');
94+
var result;
95+
96+
if (digits.length == 10 && defaultCountryCode)
97+
result = '+' + defaultCountryCode + ' ' + digits;
98+
else if (digits.length > 10 && digits.startsWith('91'))
99+
result = '+' + digits.slice(0, 2) + ' ' + digits.slice(2);
100+
else
101+
result = '+' + digits;
102+
103+
this.logInfo('normalizePhone: "' + phone + '" → "' + result + '"');
104+
return result;
105+
} catch (e) {
106+
this.logError('normalizePhone', e, { phone: phone });
107+
return phone;
108+
}
109+
},
110+
111+
/**
112+
* Cleans and formats postal addresses by removing excess spaces
113+
* and applying title case to each word.
114+
*
115+
* @param {String} address - Input address text.
116+
* @returns {String} - Normalized address.
117+
*/
118+
normalizeAddress: function(address) {
119+
try {
120+
if (!address) return '';
121+
address = address.trim().replace(/\s{2,}/g, ' ');
122+
var result = address.split(' ')
123+
.map(function(w) {
124+
return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();
125+
})
126+
.join(' ');
127+
this.logInfo('normalizeAddress: "' + address + '" → "' + result + '"');
128+
return result;
129+
} catch (e) {
130+
this.logError('normalizeAddress', e, { address: address });
131+
return address;
132+
}
133+
},
134+
135+
/**
136+
* Converts date strings into system-standard display format
137+
* using GlideDateTime APIs.
138+
*
139+
* @param {String} dateStr - Input date string.
140+
* @returns {String} - Normalized date in display format.
141+
*/
142+
normalizeDate: function(dateStr) {
143+
try {
144+
if (!dateStr) return '';
145+
var gdt = new GlideDateTime(dateStr);
146+
var formatted = gdt.getDate().getDisplayValue();
147+
this.logInfo('normalizeDate: "' + dateStr + '" → "' + formatted + '"');
148+
return formatted;
149+
} catch (e) {
150+
this.logError('normalizeDate', e, { date: dateStr });
151+
return dateStr;
152+
}
153+
},
154+
155+
/**
156+
* Generic text cleanup. Removes invalid placeholders such as
157+
* 'N/A', '--', or empty values.
158+
*
159+
* @param {String} value - Input text value.
160+
* @returns {String} - Cleaned text.
161+
*/
162+
cleanValue: function(value) {
163+
try {
164+
if (!value) return '';
165+
var cleaned = value.trim();
166+
var invalid = ['n/a', 'none', 'na', '-', '--'];
167+
if (invalid.indexOf(cleaned.toLowerCase()) > -1) return '';
168+
this.logInfo('cleanValue: "' + value + '" → "' + cleaned + '"');
169+
return cleaned;
170+
} catch (e) {
171+
this.logError('cleanValue', e, { value: value });
172+
return value;
173+
}
174+
},
175+
176+
/**
177+
* Dynamically detects field type and applies the corresponding
178+
* normalization method.
179+
*
180+
* @param {String} fieldName - The field name or label.
181+
* @param {String} value - The value to normalize.
182+
* @returns {String} - Normalized value.
183+
*/
184+
smartNormalize: function(fieldName, value) {
185+
try {
186+
if (!value) return '';
187+
var field = fieldName.toLowerCase();
188+
var result;
189+
190+
if (field.indexOf('email') >= 0)
191+
result = this.normalizeEmail(value);
192+
else if (field.indexOf('phone') >= 0 || field.indexOf('mobile') >= 0)
193+
result = this.normalizePhone(value, '91');
194+
else if (field.indexOf('name') >= 0)
195+
result = this.normalizeName(value);
196+
else if (field.indexOf('address') >= 0)
197+
result = this.normalizeAddress(value);
198+
else if (field.indexOf('date') >= 0)
199+
result = this.normalizeDate(value);
200+
else
201+
result = this.cleanValue(value);
202+
203+
this.logInfo('smartNormalize: Field=' + fieldName + ', Result=' + result);
204+
return result;
205+
} catch (e) {
206+
this.logError('smartNormalize', e, { fieldName: fieldName, value: value });
207+
return value;
208+
}
209+
},
210+
211+
/**
212+
* Client-callable method exposed via GlideAjax.
213+
* Accepts parameters from client scripts and returns
214+
* normalized values synchronously.
215+
*
216+
* @returns {String} - Normalized value for client-side use.
217+
*/
218+
normalizeFromClient: function() {
219+
try {
220+
var field = this.getParameter('sysparm_fieldName');
221+
var value = this.getParameter('sysparm_value');
222+
var normalized = this.smartNormalize(field, value);
223+
return normalized;
224+
} catch (e) {
225+
this.logError('normalizeFromClient', e, { field: field, value: value });
226+
return value;
227+
}
228+
},
229+
230+
type: 'DataNormalizer'
231+
});

0 commit comments

Comments
 (0)