@temboplus/afloat 0.1.63 → 0.1.64

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.
@@ -125,7 +125,7 @@ declare abstract class BaseContactInfo {
125
125
  * - Comprehensive error handling with structured context
126
126
  *
127
127
  * **MNP Handling:**
128
- * - **Tanzania (no MNP)**: MNO can be auto-detected from phone number prefix
128
+ * - **Tanzania (no MNP)**: MNO is always auto-detected from phone number prefix, ignoring any provided MNO
129
129
  * - **Kenya (has MNP)**: MNO must be explicitly provided as numbers can be ported
130
130
  *
131
131
  * @extends BaseContactInfo
@@ -137,12 +137,13 @@ declare abstract class BaseContactInfo {
137
137
  *
138
138
  * @example
139
139
  * ```typescript
140
- * // Tanzania - MNO auto-detected from prefix
140
+ * // Tanzania - MNO auto-detected from prefix (ignores provided MNO)
141
141
  * const tzContact = new MobileContactInfo("John Doe", tzPhoneNumber);
142
142
  * console.log(tzContact.channel); // "VODACOM" (auto-detected)
143
143
  *
144
- * // Tanzania - Explicit MNO (validated against prefix)
145
- * const tzExplicit = new MobileContactInfo("John Doe", tzPhoneNumber, TZMNOId.VODACOM);
144
+ * // Tanzania - Even with explicit MNO, it's auto-detected from prefix
145
+ * const tzExplicit = new MobileContactInfo("John Doe", tzPhoneNumber, TZMNOId.AIRTEL);
146
+ * console.log(tzExplicit.channel); // "VODACOM" (auto-detected, not AIRTEL)
146
147
  *
147
148
  * // Kenya - MNO must be explicit due to MNP
148
149
  * const keContact = new MobileContactInfo("Jane Smith", kePhoneNumber, KEMNOId.SAFARICOM);
@@ -165,26 +166,27 @@ export declare class MobileContactInfo extends BaseContactInfo {
165
166
  * 2. Validates phone number structure
166
167
  * 3. Handles MNO validation based on country MNP status:
167
168
  * - **Countries with MNP (KE)**: Requires explicit MNO, validates it's valid for country
168
- * - **Countries without MNP (TZ)**: Can auto-detect or validate explicit MNO against prefix
169
+ * - **Countries without MNP (TZ)**: Always auto-detects MNO from phone number prefix (ignores provided MNO)
169
170
  *
170
171
  * @param {string} name - The contact's personal name (required, non-empty)
171
172
  * @param {PhoneNumber} phoneNumber - The validated phone number object
172
- * @param {MNOId} [mnoId] - Optional MNO ID. Required for MNP countries (KE), optional for non-MNP (TZ)
173
+ * @param {MNOId} [mnoId] - MNO ID. Required for MNP countries (KE), ignored for non-MNP countries (TZ)
173
174
  *
174
175
  * @throws {ContactInfoError} When any validation fails:
175
176
  * - Empty or invalid name
176
177
  * - Invalid phone number structure
177
- * - Invalid MNO for the country
178
- * - MNO-phone number mismatch (for non-MNP countries)
178
+ * - Invalid MNO for the country (MNP countries only)
179
179
  * - Missing MNO for MNP countries
180
180
  * - Unable to auto-detect MNO for non-MNP countries
181
181
  *
182
182
  * @example
183
183
  * ```typescript
184
184
  * try {
185
- * // All these are valid
185
+ * // Tanzania - MNO always auto-detected
186
186
  * const tzAuto = new MobileContactInfo("John", tzPhone);
187
- * const tzExplicit = new MobileContactInfo("John", tzPhone, TZMNOId.VODACOM);
187
+ * const tzIgnored = new MobileContactInfo("John", tzPhone, TZMNOId.AIRTEL); // AIRTEL ignored, auto-detected from prefix
188
+ *
189
+ * // Kenya - MNO must be explicit
188
190
  * const keExplicit = new MobileContactInfo("Jane", kePhone, KEMNOId.SAFARICOM);
189
191
  * } catch (error) {
190
192
  * if (error instanceof ContactInfoError) {
@@ -202,7 +204,9 @@ export declare class MobileContactInfo extends BaseContactInfo {
202
204
  * 1. Validates DTO type is "Mobile"
203
205
  * 2. Validates country code format
204
206
  * 3. Parses phone number with country context
205
- * 4. Extracts and validates MNO from channel field (if provided)
207
+ * 4. Handles MNO based on country MNP status:
208
+ * - **MNP countries**: Uses channel field (required)
209
+ * - **Non-MNP countries**: Auto-detects from phone number (ignores channel field)
206
210
  * 5. Delegates to constructor for final validation
207
211
  *
208
212
  * @static
@@ -211,24 +215,35 @@ export declare class MobileContactInfo extends BaseContactInfo {
211
215
  * @param {string} info.accountNo - The phone number string to parse
212
216
  * @param {string} info.countryCode - ISO2 country code
213
217
  * @param {string} info.displayName - The contact's name
214
- * @param {string} [info.channel] - Optional MNO ID (required for MNP countries)
218
+ * @param {string} [info.channel] - MNO ID (required for MNP countries, ignored for non-MNP countries)
215
219
  *
216
220
  * @returns {MobileContactInfo | undefined} New instance if successful, undefined if validation fails
217
221
  *
218
222
  * @example
219
223
  * ```typescript
220
- * const contactDTO = {
224
+ * // Tanzania DTO - channel ignored, auto-detected from phone number
225
+ * const tzContactDTO = {
221
226
  * type: "Mobile",
222
- * accountNo: "+255712345678",
227
+ * accountNo: "+255712345678", // Vodacom prefix
223
228
  * countryCode: "TZ",
224
229
  * displayName: "John Doe",
225
- * channel: "VODACOM" // Optional for TZ, required for KE
230
+ * channel: "AIRTEL" // This will be ignored, Vodacom will be auto-detected
226
231
  * };
227
232
  *
228
- * const contact = MobileContactInfo.fromContactDTO(contactDTO);
229
- * if (contact) {
230
- * console.log(`Created contact: ${contact.displayName}`);
231
- * }
233
+ * // Kenya DTO - channel required
234
+ * const keContactDTO = {
235
+ * type: "Mobile",
236
+ * accountNo: "+254712345678",
237
+ * countryCode: "KE",
238
+ * displayName: "Jane Smith",
239
+ * channel: "SAFARICOM" // Required for Kenya
240
+ * };
241
+ *
242
+ * const tzContact = MobileContactInfo.fromContactDTO(tzContactDTO);
243
+ * console.log(tzContact?.channelId); // "VODACOM" (not "AIRTEL")
244
+ *
245
+ * const keContact = MobileContactInfo.fromContactDTO(keContactDTO);
246
+ * console.log(keContact?.channelId); // "SAFARICOM"
232
247
  * ```
233
248
  */
234
249
  static fromContactDTO(info: ContactDTO): MobileContactInfo | undefined;
@@ -239,7 +254,9 @@ export declare class MobileContactInfo extends BaseContactInfo {
239
254
  * **Process:**
240
255
  * 1. Validates country code format
241
256
  * 2. Parses phone number from msisdn field
242
- * 3. Extracts MNO from channel field (if available)
257
+ * 3. Handles MNO based on country MNP status:
258
+ * - **MNP countries**: Uses channel field (required)
259
+ * - **Non-MNP countries**: Auto-detects from phone number (ignores channel field)
243
260
  * 4. Uses payeeName as the contact name
244
261
  * 5. Delegates to constructor for validation
245
262
  *
@@ -248,23 +265,30 @@ export declare class MobileContactInfo extends BaseContactInfo {
248
265
  * @param {string} info.msisdn - The phone number in various formats
249
266
  * @param {string} info.countryCode - ISO2 country code
250
267
  * @param {string} info.payeeName - The recipient's name
251
- * @param {string} [info.channel] - Optional MNO ID
268
+ * @param {string} [info.channel] - MNO ID (required for MNP countries, ignored for non-MNP countries)
252
269
  *
253
270
  * @returns {MobileContactInfo | undefined} New instance if successful, undefined if parsing fails
254
271
  *
255
272
  * @example
256
273
  * ```typescript
257
- * const payoutDTO = {
274
+ * // Tanzania payout - channel ignored
275
+ * const tzPayoutDTO = {
276
+ * msisdn: "+255712345678", // Vodacom prefix
277
+ * countryCode: "TZ",
278
+ * payeeName: "John Doe",
279
+ * channel: "AIRTEL" // Ignored, Vodacom auto-detected
280
+ * };
281
+ *
282
+ * // Kenya payout - channel required
283
+ * const kePayoutDTO = {
258
284
  * msisdn: "+254712345678",
259
285
  * countryCode: "KE",
260
286
  * payeeName: "Jane Smith",
261
- * channel: "SAFARICOM"
287
+ * channel: "SAFARICOM" // Required
262
288
  * };
263
289
  *
264
- * const contact = MobileContactInfo.fromPayoutDTO(payoutDTO);
265
- * if (contact) {
266
- * console.log(`Payout contact: ${contact.displayName} via ${contact.channelDisplayName}`);
267
- * }
290
+ * const tzContact = MobileContactInfo.fromPayoutDTO(tzPayoutDTO);
291
+ * console.log(tzContact?.channelName); // "M-Pesa" (Vodacom's service)
268
292
  * ```
269
293
  */
270
294
  static fromPayoutDTO(info: PayoutDTO): MobileContactInfo | undefined;
@@ -278,7 +302,7 @@ export declare class MobileContactInfo extends BaseContactInfo {
278
302
  * 3. **Phone validation**: Validates phone number can be parsed and is valid
279
303
  * 4. **MNO validation**: Country-specific validation:
280
304
  * - **MNP countries (KE)**: Validates MNO ID is valid for country
281
- * - **Non-MNP countries (TZ)**: Validates MNO matches phone number prefix
305
+ * - **Non-MNP countries (TZ)**: Validates MNO matches phone number prefix (auto-detected)
282
306
  *
283
307
  * @static
284
308
  * @param {unknown} obj - The object to validate
@@ -307,6 +331,7 @@ export declare class MobileContactInfo extends BaseContactInfo {
307
331
  * - Phone numbers can be provided as strings or PhoneNumber objects
308
332
  * - Uses country-specific MNO validation through MNOUtils
309
333
  * - Returns false for any validation failure (fail-fast approach)
334
+ * - For non-MNP countries, validates that the MNO matches what would be auto-detected
310
335
  */
311
336
  static is(obj: unknown): obj is MobileContactInfo;
312
337
  /**
@@ -317,7 +342,7 @@ export declare class MobileContactInfo extends BaseContactInfo {
317
342
  * 1. **Name validation**: Non-empty string
318
343
  * 2. **Phone validation**: Valid phone number structure
319
344
  * 3. **MNO validation**: Valid MNO for the country
320
- * 4. **Consistency check**: For non-MNP countries, validates MNO matches phone prefix
345
+ * 4. **Consistency check**: For non-MNP countries, validates MNO matches auto-detected value from phone prefix
321
346
  *
322
347
  * @returns {boolean} True if all validations pass, false otherwise
323
348
  *
@@ -335,32 +360,6 @@ export declare class MobileContactInfo extends BaseContactInfo {
335
360
  *
336
361
  * @see {@link getValidationDetails} For detailed validation results with specific errors
337
362
  */
338
- /**
339
- * Validates that all bank contact information meets banking industry standards.
340
- * Uses comprehensive validation rules for account names, numbers, and bank data.
341
- *
342
- * **Validation Checks:**
343
- * 1. **Account name**: Format, length, and character requirements
344
- * 2. **Account number**: Country-specific format validation
345
- * 3. **Bank data**: SWIFT code validity and institution data integrity
346
- *
347
- * @returns {boolean} True if all validations pass, false otherwise
348
- *
349
- * @example
350
- * ```typescript
351
- * const contact = new BankContactInfo("John Doe", bank, "0150123456789");
352
- *
353
- * if (contact.validate()) {
354
- * console.log("Bank contact is ready for transactions");
355
- * } else {
356
- * console.log("Bank contact has validation issues");
357
- * }
358
- * ```
359
- *
360
- * @remarks
361
- * Uses BankValidation utility methods for industry-standard validation rules.
362
- * All validation must pass for the contact to be considered valid.
363
- */
364
363
  validate(): boolean;
365
364
  /**
366
365
  * Provides detailed validation results with specific error and warning information.
@@ -377,7 +376,7 @@ export declare class MobileContactInfo extends BaseContactInfo {
377
376
  *
378
377
  * @example
379
378
  * ```typescript
380
- * const contact = new MobileContactInfo("John", phoneNumber, TZMNOId.AIRTEL);
379
+ * const contact = new MobileContactInfo("John", phoneNumber);
381
380
  * const validation = contact.getValidationDetails();
382
381
  *
383
382
  * console.log(`Valid: ${validation.isValid}`);
@@ -392,18 +391,14 @@ export declare class MobileContactInfo extends BaseContactInfo {
392
391
  * validation.warnings.forEach(warning => console.log(`- ${warning}`));
393
392
  * }
394
393
  *
395
- * // Example output for TZ number with wrong MNO:
396
- * // Valid: false
397
- * // Errors:
398
- * // - Invalid MNO AIRTEL for country TZ
399
- * // Warnings:
400
- * // - MNO doesn't match phone number prefix - possible data inconsistency
394
+ * // For non-MNP countries, the MNO is always consistent as it's auto-detected
395
+ * // Warnings would only appear if there were other potential issues
401
396
  * ```
402
397
  *
403
398
  * @remarks
404
399
  * Uses MNOUtils for country-specific validation logic:
405
- * - **Tanzania**: Validates MNO against phone number prefix
406
- * - **Kenya**: Acknowledges MNP limitations, focuses on MNO validity
400
+ * - **Tanzania**: Validates MNO matches auto-detected value from phone number prefix
401
+ * - **Kenya**: Acknowledges MNP limitations, focuses on MNO validity for country
407
402
  */
408
403
  getValidationDetails(): {
409
404
  isValid: boolean;
@@ -461,12 +456,11 @@ export declare class MobileContactInfo extends BaseContactInfo {
461
456
  * @example
462
457
  * ```typescript
463
458
  * const contact = new MobileContactInfo("John", tzPhone, TZMNOId.VODACOM);
464
- * console.log(contact.channel); // "VODACOM"
459
+ * console.log(contact.channel); // "VODACOM" (for MNP countries)
465
460
  *
466
- * // Type-safe usage
467
- * if (contact.channel === TZMNOId.VODACOM) {
468
- * console.log("This is a Vodacom number");
469
- * }
461
+ * // For non-MNP countries, always returns auto-detected value
462
+ * const contact2 = new MobileContactInfo("John", tzPhone, TZMNOId.AIRTEL); // AIRTEL ignored
463
+ * console.log(contact2.channel); // "VODACOM" (auto-detected from phone prefix)
470
464
  * ```
471
465
  */
472
466
  get channelId(): MNOId;
@@ -478,6 +472,7 @@ export declare class MobileContactInfo extends BaseContactInfo {
478
472
  * - Returns the mobile money service name (e.g., "M-Pesa", "Airtel Money")
479
473
  * - Falls back to MNO display name if service name unavailable
480
474
  * - Falls back to MNO ID if no display information available
475
+ * - For non-MNP countries, always reflects the auto-detected MNO service
481
476
  *
482
477
  * @returns {string} The mobile money service name for display
483
478
  *
@@ -489,8 +484,9 @@ export declare class MobileContactInfo extends BaseContactInfo {
489
484
  * const safaricomContact = new MobileContactInfo("Jane", kePhone, KEMNOId.SAFARICOM);
490
485
  * console.log(safaricomContact.channelDisplayName); // "M-Pesa"
491
486
  *
492
- * const airtelContact = new MobileContactInfo("Bob", tzPhone, TZMNOId.AIRTEL);
493
- * console.log(airtelContact.channelDisplayName); // "Airtel Money"
487
+ * // For non-MNP countries, shows auto-detected service regardless of provided MNO
488
+ * const tzContact = new MobileContactInfo("Bob", tzVodacomPhone, TZMNOId.AIRTEL); // AIRTEL ignored
489
+ * console.log(tzContact.channelDisplayName); // "M-Pesa" (Vodacom's service, auto-detected)
494
490
  * ```
495
491
  *
496
492
  * @remarks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temboplus/afloat",
3
- "version": "0.1.63",
3
+ "version": "0.1.64",
4
4
  "description": "A foundational library for Temboplus-Afloat projects.",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "module": "./dist/index.esm.js",