pi-spi-sdk 0.1.0
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/CHANGELOG.md +33 -0
- package/LICENSE +22 -0
- package/README.md +300 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.js +4 -0
- package/dist/error-handler.d.ts +7 -0
- package/dist/error-handler.js +52 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.js +40 -0
- package/dist/examples.d.ts +8 -0
- package/dist/examples.js +91 -0
- package/dist/generated/core/ApiError.d.ts +10 -0
- package/dist/generated/core/ApiError.js +11 -0
- package/dist/generated/core/ApiRequestOptions.d.ts +13 -0
- package/dist/generated/core/ApiRequestOptions.js +1 -0
- package/dist/generated/core/ApiResult.d.ts +7 -0
- package/dist/generated/core/ApiResult.js +1 -0
- package/dist/generated/core/CancelablePromise.d.ts +20 -0
- package/dist/generated/core/CancelablePromise.js +111 -0
- package/dist/generated/core/OpenAPI.d.ts +16 -0
- package/dist/generated/core/OpenAPI.js +11 -0
- package/dist/generated/core/request.d.ts +34 -0
- package/dist/generated/core/request.js +269 -0
- package/dist/generated/index.d.ts +78 -0
- package/dist/generated/index.js +43 -0
- package/dist/generated/models/AliasCreationReponse.d.ts +22 -0
- package/dist/generated/models/AliasCreationReponse.js +1 -0
- package/dist/generated/models/AliasCreationRequest.d.ts +11 -0
- package/dist/generated/models/AliasCreationRequest.js +1 -0
- package/dist/generated/models/AliasReponseListe.d.ts +26 -0
- package/dist/generated/models/AliasReponseListe.js +1 -0
- package/dist/generated/models/AnnulationStatut.d.ts +13 -0
- package/dist/generated/models/AnnulationStatut.js +18 -0
- package/dist/generated/models/Champs.d.ts +1 -0
- package/dist/generated/models/Champs.js +1 -0
- package/dist/generated/models/CompteOperation.d.ts +72 -0
- package/dist/generated/models/CompteOperation.js +24 -0
- package/dist/generated/models/CompteOperationListe.d.ts +18 -0
- package/dist/generated/models/CompteOperationListe.js +1 -0
- package/dist/generated/models/CompteSolde.d.ts +129 -0
- package/dist/generated/models/CompteSolde.js +71 -0
- package/dist/generated/models/CompteTransfertIntraReponse.d.ts +33 -0
- package/dist/generated/models/CompteTransfertIntraReponse.js +12 -0
- package/dist/generated/models/CompteTransfertIntraRequest.d.ts +9 -0
- package/dist/generated/models/CompteTransfertIntraRequest.js +1 -0
- package/dist/generated/models/DemandePaiementConfirmationAnnulationRaison.d.ts +14 -0
- package/dist/generated/models/DemandePaiementConfirmationAnnulationRaison.js +19 -0
- package/dist/generated/models/DemandePaiementConfirmationReponse.d.ts +41 -0
- package/dist/generated/models/DemandePaiementConfirmationReponse.js +13 -0
- package/dist/generated/models/DemandePaiementConfirmationRequest.d.ts +3 -0
- package/dist/generated/models/DemandePaiementConfirmationRequest.js +1 -0
- package/dist/generated/models/DemandePaiementConfirmationRequestAccepter.d.ts +9 -0
- package/dist/generated/models/DemandePaiementConfirmationRequestAccepter.js +1 -0
- package/dist/generated/models/DemandePaiementConfirmationRequestRejeter.d.ts +9 -0
- package/dist/generated/models/DemandePaiementConfirmationRequestRejeter.js +1 -0
- package/dist/generated/models/DemandePaiementConsultationReponse.d.ts +151 -0
- package/dist/generated/models/DemandePaiementConsultationReponse.js +27 -0
- package/dist/generated/models/DemandePaiementEnMasseConfirmationRequest.d.ts +3 -0
- package/dist/generated/models/DemandePaiementEnMasseConfirmationRequest.js +1 -0
- package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestAccepter.d.ts +9 -0
- package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestAccepter.js +1 -0
- package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestRejeter.d.ts +9 -0
- package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestRejeter.js +1 -0
- package/dist/generated/models/DemandePaiementEnMasseRequest.d.ts +74 -0
- package/dist/generated/models/DemandePaiementEnMasseRequest.js +1 -0
- package/dist/generated/models/DemandePaiementEnMasseStatutReponse.d.ts +98 -0
- package/dist/generated/models/DemandePaiementEnMasseStatutReponse.js +20 -0
- package/dist/generated/models/DemandePaiementListe.d.ts +26 -0
- package/dist/generated/models/DemandePaiementListe.js +1 -0
- package/dist/generated/models/DemandePaiementListeItem.d.ts +163 -0
- package/dist/generated/models/DemandePaiementListeItem.js +27 -0
- package/dist/generated/models/DemandePaiementReponse.d.ts +129 -0
- package/dist/generated/models/DemandePaiementReponse.js +1 -0
- package/dist/generated/models/DemandePaiementReponseRequest.d.ts +21 -0
- package/dist/generated/models/DemandePaiementReponseRequest.js +11 -0
- package/dist/generated/models/DemandePaiementRequest.d.ts +98 -0
- package/dist/generated/models/DemandePaiementRequest.js +7 -0
- package/dist/generated/models/DemandePaiementRequestBase.d.ts +42 -0
- package/dist/generated/models/DemandePaiementRequestBase.js +1 -0
- package/dist/generated/models/DemandePaiementRequestCategorie.d.ts +12 -0
- package/dist/generated/models/DemandePaiementRequestCategorie.js +17 -0
- package/dist/generated/models/DemandePaiementStatut.d.ts +13 -0
- package/dist/generated/models/DemandePaiementStatut.js +18 -0
- package/dist/generated/models/DemandePaiementStatutRaison.d.ts +46 -0
- package/dist/generated/models/DemandePaiementStatutRaison.js +51 -0
- package/dist/generated/models/ListeMeta.d.ts +14 -0
- package/dist/generated/models/ListeMeta.js +1 -0
- package/dist/generated/models/Paiement.d.ts +156 -0
- package/dist/generated/models/Paiement.js +28 -0
- package/dist/generated/models/PaiementAnnulationMotif.d.ts +17 -0
- package/dist/generated/models/PaiementAnnulationMotif.js +22 -0
- package/dist/generated/models/PaiementAnnulationReponseRequest.d.ts +11 -0
- package/dist/generated/models/PaiementAnnulationReponseRequest.js +1 -0
- package/dist/generated/models/PaiementAnnulationReponseRequestAccepter.d.ts +9 -0
- package/dist/generated/models/PaiementAnnulationReponseRequestAccepter.js +1 -0
- package/dist/generated/models/PaiementAnnulationReponseRequestRejeter.d.ts +9 -0
- package/dist/generated/models/PaiementAnnulationReponseRequestRejeter.js +1 -0
- package/dist/generated/models/PaiementAnnulationRequest.d.ts +4 -0
- package/dist/generated/models/PaiementAnnulationRequest.js +1 -0
- package/dist/generated/models/PaiementAnnulationStatutRaison.d.ts +21 -0
- package/dist/generated/models/PaiementAnnulationStatutRaison.js +26 -0
- package/dist/generated/models/PaiementEnMasseConfirmationRequest.d.ts +3 -0
- package/dist/generated/models/PaiementEnMasseConfirmationRequest.js +1 -0
- package/dist/generated/models/PaiementEnMasseConfirmationRequestAccepter.d.ts +9 -0
- package/dist/generated/models/PaiementEnMasseConfirmationRequestAccepter.js +1 -0
- package/dist/generated/models/PaiementEnMasseConfirmationRequestRejeter.d.ts +9 -0
- package/dist/generated/models/PaiementEnMasseConfirmationRequestRejeter.js +1 -0
- package/dist/generated/models/PaiementEnMasseReponseStatut.d.ts +97 -0
- package/dist/generated/models/PaiementEnMasseReponseStatut.js +20 -0
- package/dist/generated/models/PaiementEnMasseRequest.d.ts +54 -0
- package/dist/generated/models/PaiementEnMasseRequest.js +1 -0
- package/dist/generated/models/PaiementImmediatConfirmationReponse.d.ts +31 -0
- package/dist/generated/models/PaiementImmediatConfirmationReponse.js +7 -0
- package/dist/generated/models/PaiementImmediatConfirmationRequest.d.ts +3 -0
- package/dist/generated/models/PaiementImmediatConfirmationRequest.js +1 -0
- package/dist/generated/models/PaiementImmediatConfirmationRequestAccepter.d.ts +9 -0
- package/dist/generated/models/PaiementImmediatConfirmationRequestAccepter.js +1 -0
- package/dist/generated/models/PaiementImmediatConfirmationRequestRejeter.d.ts +9 -0
- package/dist/generated/models/PaiementImmediatConfirmationRequestRejeter.js +1 -0
- package/dist/generated/models/PaiementImmediatReponse.d.ts +98 -0
- package/dist/generated/models/PaiementImmediatReponse.js +7 -0
- package/dist/generated/models/PaiementImmediatRequest.d.ts +13 -0
- package/dist/generated/models/PaiementImmediatRequest.js +1 -0
- package/dist/generated/models/PaiementListe.d.ts +6 -0
- package/dist/generated/models/PaiementListe.js +1 -0
- package/dist/generated/models/PaiementRequest.d.ts +33 -0
- package/dist/generated/models/PaiementRequest.js +1 -0
- package/dist/generated/models/PaiementStatut.d.ts +13 -0
- package/dist/generated/models/PaiementStatut.js +18 -0
- package/dist/generated/models/PaiementStatutRaison.d.ts +56 -0
- package/dist/generated/models/PaiementStatutRaison.js +61 -0
- package/dist/generated/models/Problem7807.d.ts +31 -0
- package/dist/generated/models/Problem7807.js +1 -0
- package/dist/generated/models/RefDocType.d.ts +38 -0
- package/dist/generated/models/RefDocType.js +43 -0
- package/dist/generated/models/RetourStatut.d.ts +13 -0
- package/dist/generated/models/RetourStatut.js +18 -0
- package/dist/generated/models/RetourStatutRaison.d.ts +25 -0
- package/dist/generated/models/RetourStatutRaison.js +30 -0
- package/dist/generated/models/WebhookCreationRequest.d.ts +14 -0
- package/dist/generated/models/WebhookCreationRequest.js +1 -0
- package/dist/generated/models/WebhookCreationResponse.d.ts +12 -0
- package/dist/generated/models/WebhookCreationResponse.js +1 -0
- package/dist/generated/models/WebhookData.d.ts +8 -0
- package/dist/generated/models/WebhookData.js +1 -0
- package/dist/generated/models/WebhookEvent.d.ts +191 -0
- package/dist/generated/models/WebhookEvent.js +42 -0
- package/dist/generated/models/WebhookEventsList.d.ts +13 -0
- package/dist/generated/models/WebhookEventsList.js +1 -0
- package/dist/generated/models/WebhookList.d.ts +13 -0
- package/dist/generated/models/WebhookList.js +1 -0
- package/dist/generated/models/WebhookModificationRequest.d.ts +4 -0
- package/dist/generated/models/WebhookModificationRequest.js +1 -0
- package/dist/generated/models/WebhooksEvents.d.ts +12 -0
- package/dist/generated/models/WebhooksEvents.js +17 -0
- package/dist/generated/services/AliasService.d.ts +63 -0
- package/dist/generated/services/AliasService.js +84 -0
- package/dist/generated/services/ComptesService.d.ts +64 -0
- package/dist/generated/services/ComptesService.js +86 -0
- package/dist/generated/services/DemandeAnnulationService.d.ts +84 -0
- package/dist/generated/services/DemandeAnnulationService.js +99 -0
- package/dist/generated/services/DemandesDePaiementEnMasseService.d.ts +161 -0
- package/dist/generated/services/DemandesDePaiementEnMasseService.js +189 -0
- package/dist/generated/services/DemandesDePaiementService.d.ts +123 -0
- package/dist/generated/services/DemandesDePaiementService.js +161 -0
- package/dist/generated/services/NotificationService.d.ts +80 -0
- package/dist/generated/services/NotificationService.js +132 -0
- package/dist/generated/services/PaiementEnMasseService.d.ts +159 -0
- package/dist/generated/services/PaiementEnMasseService.js +187 -0
- package/dist/generated/services/PaiementImmediatService.d.ts +135 -0
- package/dist/generated/services/PaiementImmediatService.js +176 -0
- package/dist/generated/services/RetoursdeFondsService.d.ts +28 -0
- package/dist/generated/services/RetoursdeFondsService.js +37 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +23 -0
- package/dist/query-builder.d.ts +91 -0
- package/dist/query-builder.js +187 -0
- package/dist/sdk.d.ts +88 -0
- package/dist/sdk.js +107 -0
- package/dist/services/alias.d.ts +72 -0
- package/dist/services/alias.js +82 -0
- package/dist/services/base.d.ts +9 -0
- package/dist/services/base.js +17 -0
- package/dist/services/comptes.d.ts +149 -0
- package/dist/services/comptes.js +158 -0
- package/dist/services/demandes-annulation.d.ts +97 -0
- package/dist/services/demandes-annulation.js +104 -0
- package/dist/services/demandes-paiement-en-masse.d.ts +139 -0
- package/dist/services/demandes-paiement-en-masse.js +139 -0
- package/dist/services/demandes-paiement.d.ts +144 -0
- package/dist/services/demandes-paiement.js +151 -0
- package/dist/services/paiements-en-masse.d.ts +152 -0
- package/dist/services/paiements-en-masse.js +153 -0
- package/dist/services/paiements.d.ts +135 -0
- package/dist/services/paiements.js +135 -0
- package/dist/services/retours-fonds.d.ts +94 -0
- package/dist/services/retours-fonds.js +100 -0
- package/dist/services/webhooks.d.ts +131 -0
- package/dist/services/webhooks.js +142 -0
- package/dist/types/alias.d.ts +64 -0
- package/dist/types/alias.js +73 -0
- package/dist/utils/constants.d.ts +93 -0
- package/dist/utils/constants.js +93 -0
- package/dist/utils/index.d.ts +60 -0
- package/dist/utils/index.js +115 -0
- package/package.json +81 -0
- package/scripts/post-generate.js +129 -0
- package/scripts/pre-generate.js +106 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for PI-SPI operations
|
|
3
|
+
*
|
|
4
|
+
* Common helper functions for formatting amounts, validating inputs,
|
|
5
|
+
* and other utility operations.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Format amount from centimes to XOF
|
|
9
|
+
* @param centimes - Amount in centimes
|
|
10
|
+
* @returns Formatted amount string (e.g., "1 500 XOF")
|
|
11
|
+
*/
|
|
12
|
+
export function formatAmount(centimes) {
|
|
13
|
+
const xof = centimes / 100;
|
|
14
|
+
return new Intl.NumberFormat('fr-FR', {
|
|
15
|
+
style: 'currency',
|
|
16
|
+
currency: 'XOF',
|
|
17
|
+
minimumFractionDigits: 0,
|
|
18
|
+
maximumFractionDigits: 0,
|
|
19
|
+
}).format(xof);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Convert XOF to centimes
|
|
23
|
+
* @param xof - Amount in XOF
|
|
24
|
+
* @returns Amount in centimes
|
|
25
|
+
*/
|
|
26
|
+
export function xofToCentimes(xof) {
|
|
27
|
+
return Math.round(xof * 100);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Convert centimes to XOF
|
|
31
|
+
* @param centimes - Amount in centimes
|
|
32
|
+
* @returns Amount in XOF
|
|
33
|
+
*/
|
|
34
|
+
export function centimesToXof(centimes) {
|
|
35
|
+
return centimes / 100;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validate account number format
|
|
39
|
+
* @param accountNumber - Account number to validate
|
|
40
|
+
* @returns True if valid format
|
|
41
|
+
*/
|
|
42
|
+
export function isValidAccountNumber(accountNumber) {
|
|
43
|
+
// PI-SPI account numbers are typically 22 characters
|
|
44
|
+
// Format: [Country Code][Bank Code][Account Number]
|
|
45
|
+
// Example: CIC2344256727788288822 (Côte d'Ivoire)
|
|
46
|
+
return /^[A-Z]{2,3}\d{19,22}$/.test(accountNumber);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Validate SHID alias format (UUID)
|
|
50
|
+
* @param alias - Alias to validate
|
|
51
|
+
* @returns True if valid UUID format
|
|
52
|
+
*/
|
|
53
|
+
export function isValidShidAlias(alias) {
|
|
54
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
55
|
+
return uuidRegex.test(alias);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Validate phone number format (for MBNO alias)
|
|
59
|
+
* @param phoneNumber - Phone number to validate
|
|
60
|
+
* @returns True if valid format
|
|
61
|
+
*/
|
|
62
|
+
export function isValidPhoneNumber(phoneNumber) {
|
|
63
|
+
// Basic validation for West African phone numbers
|
|
64
|
+
// Format: +[country code][number] or [country code][number]
|
|
65
|
+
const phoneRegex = /^\+?[1-9]\d{8,12}$/;
|
|
66
|
+
return phoneRegex.test(phoneNumber.replace(/[\s-]/g, ''));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Extract country code from account number
|
|
70
|
+
* @param accountNumber - Account number
|
|
71
|
+
* @returns Country code or null
|
|
72
|
+
*/
|
|
73
|
+
export function getCountryFromAccount(accountNumber) {
|
|
74
|
+
const countryMap = {
|
|
75
|
+
CI: "Côte d'Ivoire",
|
|
76
|
+
SN: 'Senegal',
|
|
77
|
+
BJ: 'Benin',
|
|
78
|
+
BF: 'Burkina Faso',
|
|
79
|
+
ML: 'Mali',
|
|
80
|
+
NE: 'Niger',
|
|
81
|
+
TG: 'Togo',
|
|
82
|
+
GW: 'Guinea-Bissau',
|
|
83
|
+
};
|
|
84
|
+
const countryCode = accountNumber.substring(0, 2);
|
|
85
|
+
return countryMap[countryCode] || null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Sleep/delay utility
|
|
89
|
+
* @param ms - Milliseconds to wait
|
|
90
|
+
*/
|
|
91
|
+
export function sleep(ms) {
|
|
92
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Retry a function with exponential backoff
|
|
96
|
+
* @param fn - Function to retry
|
|
97
|
+
* @param maxRetries - Maximum number of retries
|
|
98
|
+
* @param initialDelay - Initial delay in milliseconds
|
|
99
|
+
*/
|
|
100
|
+
export async function retryWithBackoff(fn, maxRetries = 3, initialDelay = 1000) {
|
|
101
|
+
let lastError;
|
|
102
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
103
|
+
try {
|
|
104
|
+
return await fn();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
108
|
+
if (i < maxRetries - 1) {
|
|
109
|
+
const delay = initialDelay * Math.pow(2, i);
|
|
110
|
+
await sleep(delay);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
throw lastError ?? new Error('Retry failed with unknown error');
|
|
115
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-spi-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official TypeScript SDK for PI-SPI Business API - Built by lomi. for the West African fintech community",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"scripts",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE",
|
|
19
|
+
"CHANGELOG.md"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"pi-spi",
|
|
23
|
+
"spi",
|
|
24
|
+
"bceao",
|
|
25
|
+
"west-africa",
|
|
26
|
+
"uemoa",
|
|
27
|
+
"payment",
|
|
28
|
+
"interoperability",
|
|
29
|
+
"mobile-money",
|
|
30
|
+
"xof",
|
|
31
|
+
"fcfa",
|
|
32
|
+
"cfa-franc",
|
|
33
|
+
"fintech",
|
|
34
|
+
"sdk",
|
|
35
|
+
"typescript",
|
|
36
|
+
"api-client",
|
|
37
|
+
"benin",
|
|
38
|
+
"burkina-faso",
|
|
39
|
+
"ivory-coast",
|
|
40
|
+
"mali",
|
|
41
|
+
"niger",
|
|
42
|
+
"senegal",
|
|
43
|
+
"togo",
|
|
44
|
+
"guinea-bissau"
|
|
45
|
+
],
|
|
46
|
+
"author": "lomi. <hello@lomi.africa> (https://lomi.africa)",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"homepage": "https://github.com/lomiafrica/pi-spi-sdk",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/lomiafrica/pi-spi-sdk/issues"
|
|
51
|
+
},
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+https://github.com/lomiafrica/pi-spi-sdk.git"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=18.0.0"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"axios": "^1.8.4",
|
|
64
|
+
"dotenv": "^16.4.5",
|
|
65
|
+
"form-data": "^4.0.2"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/form-data": "^2.5.2",
|
|
69
|
+
"@types/node": "^20.10.6",
|
|
70
|
+
"openapi-typescript-codegen": "^0.29.0",
|
|
71
|
+
"prettier": "^3.2.5",
|
|
72
|
+
"typescript": "^5.3.3"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "tsc",
|
|
76
|
+
"dev": "tsc --watch",
|
|
77
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,json,md}\" \"*.{json,md}\" \"scripts/**/*.{js,ts}\"",
|
|
78
|
+
"prepublish": "pnpm run generate && pnpm run build",
|
|
79
|
+
"generate": "node scripts/pre-generate.js && openapi --input ./openapi.json --output ./src/generated --client axios --useOptions && node scripts/post-generate.js"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Post-generation script
|
|
4
|
+
*
|
|
5
|
+
* This script runs after OpenAPI code generation to set up the SDK properly.
|
|
6
|
+
* It updates the OpenAPI base URL, fixes empty types, and ensures proper exports.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFileSync, writeFileSync, readdirSync, statSync } from 'fs';
|
|
10
|
+
import { join, dirname } from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
|
|
16
|
+
const rootDir = join(__dirname, '..');
|
|
17
|
+
const generatedOpenAPIPath = join(rootDir, 'src/generated/core/OpenAPI.ts');
|
|
18
|
+
const modelsDir = join(rootDir, 'src/generated/models');
|
|
19
|
+
|
|
20
|
+
// Known empty types and their proper definitions
|
|
21
|
+
const emptyTypeFixes = {
|
|
22
|
+
CompteTransfertIntraRequest: `{
|
|
23
|
+
txId: string;
|
|
24
|
+
montant: number;
|
|
25
|
+
motif?: string;
|
|
26
|
+
payeurNumero?: string;
|
|
27
|
+
payeNumero?: string;
|
|
28
|
+
payeurAlias?: string;
|
|
29
|
+
payeAlias?: string;
|
|
30
|
+
}`,
|
|
31
|
+
WebhookModificationRequest: `{
|
|
32
|
+
callbackUrl?: string;
|
|
33
|
+
alias?: string;
|
|
34
|
+
}`,
|
|
35
|
+
remise: `{
|
|
36
|
+
montant?: number;
|
|
37
|
+
taux?: number;
|
|
38
|
+
}`,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Fix empty type definitions in generated files
|
|
43
|
+
*/
|
|
44
|
+
function fixEmptyTypes() {
|
|
45
|
+
try {
|
|
46
|
+
const files = readdirSync(modelsDir);
|
|
47
|
+
let fixedCount = 0;
|
|
48
|
+
|
|
49
|
+
for (const file of files) {
|
|
50
|
+
if (!file.endsWith('.ts')) continue;
|
|
51
|
+
|
|
52
|
+
const filePath = join(modelsDir, file);
|
|
53
|
+
let content = readFileSync(filePath, 'utf-8');
|
|
54
|
+
|
|
55
|
+
// Fix empty type definitions
|
|
56
|
+
// Pattern: export type TypeName = ;
|
|
57
|
+
const emptyTypePattern = /export type (\w+) = \s*;/g;
|
|
58
|
+
let match;
|
|
59
|
+
let modified = false;
|
|
60
|
+
|
|
61
|
+
while ((match = emptyTypePattern.exec(content)) !== null) {
|
|
62
|
+
const typeName = match[1];
|
|
63
|
+
|
|
64
|
+
// Check if we have a fix for this type
|
|
65
|
+
if (emptyTypeFixes[typeName]) {
|
|
66
|
+
content = content.replace(
|
|
67
|
+
`export type ${typeName} = ;`,
|
|
68
|
+
`export type ${typeName} = ${emptyTypeFixes[typeName]};`
|
|
69
|
+
);
|
|
70
|
+
fixedCount++;
|
|
71
|
+
modified = true;
|
|
72
|
+
console.log(` ✅ Fixed empty type: ${typeName}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Fix inline empty remise types
|
|
77
|
+
// Pattern: remise?: ; or remise: ;
|
|
78
|
+
const remisePattern = /(\s+)(remise)\??:\s*;/g;
|
|
79
|
+
if (remisePattern.test(content)) {
|
|
80
|
+
content = content.replace(remisePattern, `$1$2?: ${emptyTypeFixes['remise']}`);
|
|
81
|
+
fixedCount++;
|
|
82
|
+
modified = true;
|
|
83
|
+
console.log(` ✅ Fixed remise type in: ${file}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Fix standalone remise type definitions
|
|
87
|
+
if (content.includes('remise: ;')) {
|
|
88
|
+
content = content.replace(/remise:\s*;/g, `remise: ${emptyTypeFixes['remise']}`);
|
|
89
|
+
fixedCount++;
|
|
90
|
+
modified = true;
|
|
91
|
+
console.log(` ✅ Fixed remise type definition in: ${file}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (modified) {
|
|
95
|
+
writeFileSync(filePath, content, 'utf-8');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (fixedCount > 0) {
|
|
100
|
+
console.log(`✅ Fixed ${fixedCount} empty type definition(s)`);
|
|
101
|
+
} else {
|
|
102
|
+
console.log('✅ No empty types found to fix');
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.warn('⚠️ Could not fix empty types:', error.message);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
let content = readFileSync(generatedOpenAPIPath, 'utf-8');
|
|
111
|
+
|
|
112
|
+
// Update the default BASE URL to match PI-SPI sandbox
|
|
113
|
+
content = content.replace(/BASE: '.*'/, "BASE: 'https://sandbox.api.pi-bceao.com/piz/v1'");
|
|
114
|
+
|
|
115
|
+
// Update VERSION if needed
|
|
116
|
+
content = content.replace(/VERSION: '.*'/, "VERSION: '1.0.0'");
|
|
117
|
+
|
|
118
|
+
writeFileSync(generatedOpenAPIPath, content, 'utf-8');
|
|
119
|
+
console.log('✅ Updated OpenAPI configuration');
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.warn('⚠️ Could not update OpenAPI.ts:', error.message);
|
|
122
|
+
console.log(" This is okay if the file doesn't exist yet.");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Fix empty types
|
|
126
|
+
console.log('🔧 Fixing empty type definitions...');
|
|
127
|
+
fixEmptyTypes();
|
|
128
|
+
|
|
129
|
+
console.log('✅ Post-generation setup complete');
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Pre-generation validation and fix script
|
|
4
|
+
*
|
|
5
|
+
* This script validates the OpenAPI spec and fixes common issues
|
|
6
|
+
* before running the code generator.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
10
|
+
import { join, dirname } from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
|
|
16
|
+
const specPath = join(__dirname, '../openapi.json');
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
console.log('📋 Validating OpenAPI specification...');
|
|
20
|
+
|
|
21
|
+
const specContent = readFileSync(specPath, 'utf-8');
|
|
22
|
+
const spec = JSON.parse(specContent);
|
|
23
|
+
|
|
24
|
+
if (!spec.openapi) {
|
|
25
|
+
throw new Error('Missing "openapi" field');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!spec.info) {
|
|
29
|
+
throw new Error('Missing "info" field');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!spec.paths || typeof spec.paths !== 'object') {
|
|
33
|
+
throw new Error('Missing or invalid "paths" field');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!spec.components || typeof spec.components !== 'object') {
|
|
37
|
+
throw new Error('Missing or invalid "components" field');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Ensure tags array exists (even if empty)
|
|
41
|
+
if (!spec.tags || !Array.isArray(spec.tags)) {
|
|
42
|
+
console.log('⚠️ Tags array missing or invalid, creating empty array...');
|
|
43
|
+
spec.tags = [];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Ensure each path operation has tags and remove null operations
|
|
47
|
+
let fixedPaths = 0;
|
|
48
|
+
let removedNullOps = 0;
|
|
49
|
+
const httpMethods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];
|
|
50
|
+
|
|
51
|
+
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
52
|
+
if (pathItem && typeof pathItem === 'object') {
|
|
53
|
+
for (const [key, value] of Object.entries(pathItem)) {
|
|
54
|
+
// Check if this is an HTTP method
|
|
55
|
+
if (httpMethods.includes(key.toLowerCase())) {
|
|
56
|
+
// Remove null operations (sometimes used to indicate method not available)
|
|
57
|
+
if (value === null || value === undefined) {
|
|
58
|
+
console.log(`⚠️ Removing null operation ${key.toUpperCase()} ${path}`);
|
|
59
|
+
delete pathItem[key];
|
|
60
|
+
removedNullOps++;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Ensure the operation object exists and has tags
|
|
65
|
+
if (typeof value !== 'object') {
|
|
66
|
+
console.log(`⚠️ Skipping invalid operation ${key.toUpperCase()} ${path}`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Ensure tags array exists
|
|
71
|
+
if (!value.tags || !Array.isArray(value.tags) || value.tags.length === 0) {
|
|
72
|
+
console.log(`⚠️ Adding default tag to ${key.toUpperCase()} ${path}`);
|
|
73
|
+
value.tags = ['Default'];
|
|
74
|
+
fixedPaths++;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Ensure operationId exists (required by some generators)
|
|
78
|
+
if (!value.operationId) {
|
|
79
|
+
// Generate a default operationId from method and path
|
|
80
|
+
const pathParts = path.split('/').filter((p) => p && !p.startsWith('{'));
|
|
81
|
+
const operationId =
|
|
82
|
+
key.toLowerCase() +
|
|
83
|
+
pathParts.map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join('');
|
|
84
|
+
value.operationId = operationId;
|
|
85
|
+
console.log(`⚠️ Added operationId "${operationId}" to ${key.toUpperCase()} ${path}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (removedNullOps > 0) {
|
|
93
|
+
console.log(`✅ Removed ${removedNullOps} null operations`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (fixedPaths > 0) {
|
|
97
|
+
console.log(`✅ Fixed ${fixedPaths} path operations`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Write back the fixed spec
|
|
101
|
+
writeFileSync(specPath, JSON.stringify(spec, null, 2), 'utf-8');
|
|
102
|
+
console.log('✅ OpenAPI specification validated and fixed');
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('❌ Error validating OpenAPI spec:', error);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|