-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstatus-codes.js
More file actions
235 lines (205 loc) · 7.47 KB
/
Copy pathstatus-codes.js
File metadata and controls
235 lines (205 loc) · 7.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/**
* EPP Status Code Normalization
*
* Different registries use different status code formats and names.
* This module normalizes them to standard EPP status codes.
*
* @see https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en
*/
/**
* Standard EPP status codes
*/
export const EPP_STATUS_CODES = {
// OK statuses
ok: 'ok',
active: 'ok',
ACTIVE: 'ok',
Active: 'ok',
registered: 'ok',
REGISTERED: 'ok',
Registered: 'ok',
// Client-side restrictions
clientDeleteProhibited: 'clientDeleteProhibited',
clientHold: 'clientHold',
clientRenewProhibited: 'clientRenewProhibited',
clientTransferProhibited: 'clientTransferProhibited',
clientUpdateProhibited: 'clientUpdateProhibited',
// Server-side restrictions
serverDeleteProhibited: 'serverDeleteProhibited',
serverHold: 'serverHold',
serverRenewProhibited: 'serverRenewProhibited',
serverTransferProhibited: 'serverTransferProhibited',
serverUpdateProhibited: 'serverUpdateProhibited',
// Transfer states
pendingCreate: 'pendingCreate',
pendingDelete: 'pendingDelete',
pendingRenew: 'pendingRenew',
pendingRestore: 'pendingRestore',
pendingTransfer: 'pendingTransfer',
pendingUpdate: 'pendingUpdate',
// Redemption
redemptionPeriod: 'redemptionPeriod',
// Other
inactive: 'inactive',
addPeriod: 'addPeriod',
autoRenewPeriod: 'autoRenewPeriod',
renewPeriod: 'renewPeriod',
transferPeriod: 'transferPeriod',
};
/**
* Registry-specific status mappings
*/
const STATUS_MAPPINGS = {
// Common variations
'ok': 'ok',
'active': 'ok',
'Active': 'ok',
'ACTIVE': 'ok',
'registered': 'ok',
'Registered': 'ok',
'REGISTERED': 'ok',
// Russian format
'REGISTERED, DELEGATED': 'ok',
'REGISTERED, DELEGATED, VERIFIED': 'ok',
'REGISTERED, DELEGATED, UNVERIFIED': 'ok',
'REGISTERED, NOT DELEGATED': 'inactive',
// UK format
'Registered until expiry date.': 'ok',
'Registration request being processed.': 'pendingCreate',
// Guernsey/Jersey format
'Registered until cancelled': 'ok',
// German format
'connect': 'ok',
'free': 'inactive',
// Estonian format
'ok (paid and in zone)': 'ok',
'expired': 'inactive',
// Dutch format
'in quarantine': 'redemptionPeriod',
// Delete/inactive variations
'inactive': 'inactive',
'Inactive': 'inactive',
'INACTIVE': 'inactive',
'pendingDelete': 'pendingDelete',
'PendingDelete': 'pendingDelete',
'PENDING DELETE': 'pendingDelete',
// Transfer variations
'pendingTransfer': 'pendingTransfer',
'PendingTransfer': 'pendingTransfer',
'PENDING TRANSFER': 'pendingTransfer',
// Lock variations (map to clientTransferProhibited)
'locked': 'clientTransferProhibited',
'Locked': 'clientTransferProhibited',
'LOCKED': 'clientTransferProhibited',
'DomainTransferLocked': 'clientTransferProhibited',
'AgentChangeLocked': 'clientUpdateProhibited',
};
/**
* Normalize a single status code
* @param {string} status - The raw status code
* @returns {string} Normalized EPP status code
*/
export function normalizeStatus(status) {
if (!status) return null;
// Trim whitespace
const trimmed = status.trim();
// Check direct mapping first
if (STATUS_MAPPINGS[trimmed]) {
return STATUS_MAPPINGS[trimmed];
}
// Check if it's an EPP status code with URL, with or without parentheses:
// "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited"
// "clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)"
const eppMatch = trimmed.match(/^(\w+)\s*\(?\s*https?:\/\//i);
if (eppMatch) {
const code = eppMatch[1];
// Check if it's a known EPP code
if (EPP_STATUS_CODES[code]) {
return EPP_STATUS_CODES[code];
}
// Return as-is if it looks like a valid EPP code
if (/^(client|server)[A-Z]/.test(code)) {
return code;
}
}
// Check for case/separator-insensitive match in EPP codes:
// "CLIENT TRANSFER PROHIBITED", "client-transfer-prohibited", "clienttransferprohibited"
const compact = trimmed.toLowerCase().replace(/[\s_-]+/g, '');
for (const [key, value] of Object.entries(EPP_STATUS_CODES)) {
if (key.toLowerCase() === compact) {
return value;
}
}
// Return original if no mapping found
return trimmed;
}
/**
* Normalize an array of status codes
* @param {string[]} statuses - Array of raw status codes
* @returns {string[]} Array of normalized EPP status codes
*/
export function normalizeStatuses(statuses) {
if (!Array.isArray(statuses)) return [];
return statuses.map(normalizeStatus).filter(Boolean);
}
/**
* Check if a status indicates the domain is active/registered
* @param {string|string[]} status - Status code(s) to check
* @returns {boolean} True if domain is active
*/
export function isActive(status) {
const statuses = Array.isArray(status) ? status : [status];
const normalized = normalizeStatuses(statuses);
// Domain is active if it has 'ok' status or no hold/delete statuses
if (normalized.includes('ok')) return true;
const inactiveStatuses = ['inactive', 'pendingDelete', 'serverHold', 'clientHold'];
return !normalized.some(s => inactiveStatuses.includes(s));
}
/**
* Check if a domain has transfer restrictions
* @param {string|string[]} status - Status code(s) to check
* @returns {boolean} True if domain has transfer restrictions
*/
export function hasTransferLock(status) {
const statuses = Array.isArray(status) ? status : [status];
const normalized = normalizeStatuses(statuses);
const transferLocks = [
'clientTransferProhibited',
'serverTransferProhibited',
'pendingTransfer',
];
return normalized.some(s => transferLocks.includes(s));
}
/**
* Get a human-readable description for a status code
* @param {string} status - EPP status code
* @returns {string} Human-readable description
*/
export function getStatusDescription(status) {
const descriptions = {
ok: 'Domain is registered and active',
inactive: 'Domain is not active',
clientDeleteProhibited: 'Client has requested delete protection',
clientHold: 'Domain is on hold by client request',
clientRenewProhibited: 'Client has requested renewal protection',
clientTransferProhibited: 'Client has requested transfer protection',
clientUpdateProhibited: 'Client has requested update protection',
serverDeleteProhibited: 'Server has set delete protection',
serverHold: 'Domain is on hold by server',
serverRenewProhibited: 'Server has set renewal protection',
serverTransferProhibited: 'Server has set transfer protection',
serverUpdateProhibited: 'Server has set update protection',
pendingCreate: 'Domain registration is pending',
pendingDelete: 'Domain deletion is pending',
pendingRenew: 'Domain renewal is pending',
pendingRestore: 'Domain restore is pending',
pendingTransfer: 'Domain transfer is pending',
pendingUpdate: 'Domain update is pending',
redemptionPeriod: 'Domain is in redemption period',
addPeriod: 'Domain is in add grace period',
autoRenewPeriod: 'Domain is in auto-renew period',
renewPeriod: 'Domain is in renewal period',
transferPeriod: 'Domain is in transfer period',
};
return descriptions[status] || status;
}