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.
Files changed (208) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +22 -0
  3. package/README.md +300 -0
  4. package/dist/config.d.ts +35 -0
  5. package/dist/config.js +4 -0
  6. package/dist/error-handler.d.ts +7 -0
  7. package/dist/error-handler.js +52 -0
  8. package/dist/errors.d.ts +25 -0
  9. package/dist/errors.js +40 -0
  10. package/dist/examples.d.ts +8 -0
  11. package/dist/examples.js +91 -0
  12. package/dist/generated/core/ApiError.d.ts +10 -0
  13. package/dist/generated/core/ApiError.js +11 -0
  14. package/dist/generated/core/ApiRequestOptions.d.ts +13 -0
  15. package/dist/generated/core/ApiRequestOptions.js +1 -0
  16. package/dist/generated/core/ApiResult.d.ts +7 -0
  17. package/dist/generated/core/ApiResult.js +1 -0
  18. package/dist/generated/core/CancelablePromise.d.ts +20 -0
  19. package/dist/generated/core/CancelablePromise.js +111 -0
  20. package/dist/generated/core/OpenAPI.d.ts +16 -0
  21. package/dist/generated/core/OpenAPI.js +11 -0
  22. package/dist/generated/core/request.d.ts +34 -0
  23. package/dist/generated/core/request.js +269 -0
  24. package/dist/generated/index.d.ts +78 -0
  25. package/dist/generated/index.js +43 -0
  26. package/dist/generated/models/AliasCreationReponse.d.ts +22 -0
  27. package/dist/generated/models/AliasCreationReponse.js +1 -0
  28. package/dist/generated/models/AliasCreationRequest.d.ts +11 -0
  29. package/dist/generated/models/AliasCreationRequest.js +1 -0
  30. package/dist/generated/models/AliasReponseListe.d.ts +26 -0
  31. package/dist/generated/models/AliasReponseListe.js +1 -0
  32. package/dist/generated/models/AnnulationStatut.d.ts +13 -0
  33. package/dist/generated/models/AnnulationStatut.js +18 -0
  34. package/dist/generated/models/Champs.d.ts +1 -0
  35. package/dist/generated/models/Champs.js +1 -0
  36. package/dist/generated/models/CompteOperation.d.ts +72 -0
  37. package/dist/generated/models/CompteOperation.js +24 -0
  38. package/dist/generated/models/CompteOperationListe.d.ts +18 -0
  39. package/dist/generated/models/CompteOperationListe.js +1 -0
  40. package/dist/generated/models/CompteSolde.d.ts +129 -0
  41. package/dist/generated/models/CompteSolde.js +71 -0
  42. package/dist/generated/models/CompteTransfertIntraReponse.d.ts +33 -0
  43. package/dist/generated/models/CompteTransfertIntraReponse.js +12 -0
  44. package/dist/generated/models/CompteTransfertIntraRequest.d.ts +9 -0
  45. package/dist/generated/models/CompteTransfertIntraRequest.js +1 -0
  46. package/dist/generated/models/DemandePaiementConfirmationAnnulationRaison.d.ts +14 -0
  47. package/dist/generated/models/DemandePaiementConfirmationAnnulationRaison.js +19 -0
  48. package/dist/generated/models/DemandePaiementConfirmationReponse.d.ts +41 -0
  49. package/dist/generated/models/DemandePaiementConfirmationReponse.js +13 -0
  50. package/dist/generated/models/DemandePaiementConfirmationRequest.d.ts +3 -0
  51. package/dist/generated/models/DemandePaiementConfirmationRequest.js +1 -0
  52. package/dist/generated/models/DemandePaiementConfirmationRequestAccepter.d.ts +9 -0
  53. package/dist/generated/models/DemandePaiementConfirmationRequestAccepter.js +1 -0
  54. package/dist/generated/models/DemandePaiementConfirmationRequestRejeter.d.ts +9 -0
  55. package/dist/generated/models/DemandePaiementConfirmationRequestRejeter.js +1 -0
  56. package/dist/generated/models/DemandePaiementConsultationReponse.d.ts +151 -0
  57. package/dist/generated/models/DemandePaiementConsultationReponse.js +27 -0
  58. package/dist/generated/models/DemandePaiementEnMasseConfirmationRequest.d.ts +3 -0
  59. package/dist/generated/models/DemandePaiementEnMasseConfirmationRequest.js +1 -0
  60. package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestAccepter.d.ts +9 -0
  61. package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestAccepter.js +1 -0
  62. package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestRejeter.d.ts +9 -0
  63. package/dist/generated/models/DemandePaiementEnMasseConfirmationRequestRejeter.js +1 -0
  64. package/dist/generated/models/DemandePaiementEnMasseRequest.d.ts +74 -0
  65. package/dist/generated/models/DemandePaiementEnMasseRequest.js +1 -0
  66. package/dist/generated/models/DemandePaiementEnMasseStatutReponse.d.ts +98 -0
  67. package/dist/generated/models/DemandePaiementEnMasseStatutReponse.js +20 -0
  68. package/dist/generated/models/DemandePaiementListe.d.ts +26 -0
  69. package/dist/generated/models/DemandePaiementListe.js +1 -0
  70. package/dist/generated/models/DemandePaiementListeItem.d.ts +163 -0
  71. package/dist/generated/models/DemandePaiementListeItem.js +27 -0
  72. package/dist/generated/models/DemandePaiementReponse.d.ts +129 -0
  73. package/dist/generated/models/DemandePaiementReponse.js +1 -0
  74. package/dist/generated/models/DemandePaiementReponseRequest.d.ts +21 -0
  75. package/dist/generated/models/DemandePaiementReponseRequest.js +11 -0
  76. package/dist/generated/models/DemandePaiementRequest.d.ts +98 -0
  77. package/dist/generated/models/DemandePaiementRequest.js +7 -0
  78. package/dist/generated/models/DemandePaiementRequestBase.d.ts +42 -0
  79. package/dist/generated/models/DemandePaiementRequestBase.js +1 -0
  80. package/dist/generated/models/DemandePaiementRequestCategorie.d.ts +12 -0
  81. package/dist/generated/models/DemandePaiementRequestCategorie.js +17 -0
  82. package/dist/generated/models/DemandePaiementStatut.d.ts +13 -0
  83. package/dist/generated/models/DemandePaiementStatut.js +18 -0
  84. package/dist/generated/models/DemandePaiementStatutRaison.d.ts +46 -0
  85. package/dist/generated/models/DemandePaiementStatutRaison.js +51 -0
  86. package/dist/generated/models/ListeMeta.d.ts +14 -0
  87. package/dist/generated/models/ListeMeta.js +1 -0
  88. package/dist/generated/models/Paiement.d.ts +156 -0
  89. package/dist/generated/models/Paiement.js +28 -0
  90. package/dist/generated/models/PaiementAnnulationMotif.d.ts +17 -0
  91. package/dist/generated/models/PaiementAnnulationMotif.js +22 -0
  92. package/dist/generated/models/PaiementAnnulationReponseRequest.d.ts +11 -0
  93. package/dist/generated/models/PaiementAnnulationReponseRequest.js +1 -0
  94. package/dist/generated/models/PaiementAnnulationReponseRequestAccepter.d.ts +9 -0
  95. package/dist/generated/models/PaiementAnnulationReponseRequestAccepter.js +1 -0
  96. package/dist/generated/models/PaiementAnnulationReponseRequestRejeter.d.ts +9 -0
  97. package/dist/generated/models/PaiementAnnulationReponseRequestRejeter.js +1 -0
  98. package/dist/generated/models/PaiementAnnulationRequest.d.ts +4 -0
  99. package/dist/generated/models/PaiementAnnulationRequest.js +1 -0
  100. package/dist/generated/models/PaiementAnnulationStatutRaison.d.ts +21 -0
  101. package/dist/generated/models/PaiementAnnulationStatutRaison.js +26 -0
  102. package/dist/generated/models/PaiementEnMasseConfirmationRequest.d.ts +3 -0
  103. package/dist/generated/models/PaiementEnMasseConfirmationRequest.js +1 -0
  104. package/dist/generated/models/PaiementEnMasseConfirmationRequestAccepter.d.ts +9 -0
  105. package/dist/generated/models/PaiementEnMasseConfirmationRequestAccepter.js +1 -0
  106. package/dist/generated/models/PaiementEnMasseConfirmationRequestRejeter.d.ts +9 -0
  107. package/dist/generated/models/PaiementEnMasseConfirmationRequestRejeter.js +1 -0
  108. package/dist/generated/models/PaiementEnMasseReponseStatut.d.ts +97 -0
  109. package/dist/generated/models/PaiementEnMasseReponseStatut.js +20 -0
  110. package/dist/generated/models/PaiementEnMasseRequest.d.ts +54 -0
  111. package/dist/generated/models/PaiementEnMasseRequest.js +1 -0
  112. package/dist/generated/models/PaiementImmediatConfirmationReponse.d.ts +31 -0
  113. package/dist/generated/models/PaiementImmediatConfirmationReponse.js +7 -0
  114. package/dist/generated/models/PaiementImmediatConfirmationRequest.d.ts +3 -0
  115. package/dist/generated/models/PaiementImmediatConfirmationRequest.js +1 -0
  116. package/dist/generated/models/PaiementImmediatConfirmationRequestAccepter.d.ts +9 -0
  117. package/dist/generated/models/PaiementImmediatConfirmationRequestAccepter.js +1 -0
  118. package/dist/generated/models/PaiementImmediatConfirmationRequestRejeter.d.ts +9 -0
  119. package/dist/generated/models/PaiementImmediatConfirmationRequestRejeter.js +1 -0
  120. package/dist/generated/models/PaiementImmediatReponse.d.ts +98 -0
  121. package/dist/generated/models/PaiementImmediatReponse.js +7 -0
  122. package/dist/generated/models/PaiementImmediatRequest.d.ts +13 -0
  123. package/dist/generated/models/PaiementImmediatRequest.js +1 -0
  124. package/dist/generated/models/PaiementListe.d.ts +6 -0
  125. package/dist/generated/models/PaiementListe.js +1 -0
  126. package/dist/generated/models/PaiementRequest.d.ts +33 -0
  127. package/dist/generated/models/PaiementRequest.js +1 -0
  128. package/dist/generated/models/PaiementStatut.d.ts +13 -0
  129. package/dist/generated/models/PaiementStatut.js +18 -0
  130. package/dist/generated/models/PaiementStatutRaison.d.ts +56 -0
  131. package/dist/generated/models/PaiementStatutRaison.js +61 -0
  132. package/dist/generated/models/Problem7807.d.ts +31 -0
  133. package/dist/generated/models/Problem7807.js +1 -0
  134. package/dist/generated/models/RefDocType.d.ts +38 -0
  135. package/dist/generated/models/RefDocType.js +43 -0
  136. package/dist/generated/models/RetourStatut.d.ts +13 -0
  137. package/dist/generated/models/RetourStatut.js +18 -0
  138. package/dist/generated/models/RetourStatutRaison.d.ts +25 -0
  139. package/dist/generated/models/RetourStatutRaison.js +30 -0
  140. package/dist/generated/models/WebhookCreationRequest.d.ts +14 -0
  141. package/dist/generated/models/WebhookCreationRequest.js +1 -0
  142. package/dist/generated/models/WebhookCreationResponse.d.ts +12 -0
  143. package/dist/generated/models/WebhookCreationResponse.js +1 -0
  144. package/dist/generated/models/WebhookData.d.ts +8 -0
  145. package/dist/generated/models/WebhookData.js +1 -0
  146. package/dist/generated/models/WebhookEvent.d.ts +191 -0
  147. package/dist/generated/models/WebhookEvent.js +42 -0
  148. package/dist/generated/models/WebhookEventsList.d.ts +13 -0
  149. package/dist/generated/models/WebhookEventsList.js +1 -0
  150. package/dist/generated/models/WebhookList.d.ts +13 -0
  151. package/dist/generated/models/WebhookList.js +1 -0
  152. package/dist/generated/models/WebhookModificationRequest.d.ts +4 -0
  153. package/dist/generated/models/WebhookModificationRequest.js +1 -0
  154. package/dist/generated/models/WebhooksEvents.d.ts +12 -0
  155. package/dist/generated/models/WebhooksEvents.js +17 -0
  156. package/dist/generated/services/AliasService.d.ts +63 -0
  157. package/dist/generated/services/AliasService.js +84 -0
  158. package/dist/generated/services/ComptesService.d.ts +64 -0
  159. package/dist/generated/services/ComptesService.js +86 -0
  160. package/dist/generated/services/DemandeAnnulationService.d.ts +84 -0
  161. package/dist/generated/services/DemandeAnnulationService.js +99 -0
  162. package/dist/generated/services/DemandesDePaiementEnMasseService.d.ts +161 -0
  163. package/dist/generated/services/DemandesDePaiementEnMasseService.js +189 -0
  164. package/dist/generated/services/DemandesDePaiementService.d.ts +123 -0
  165. package/dist/generated/services/DemandesDePaiementService.js +161 -0
  166. package/dist/generated/services/NotificationService.d.ts +80 -0
  167. package/dist/generated/services/NotificationService.js +132 -0
  168. package/dist/generated/services/PaiementEnMasseService.d.ts +159 -0
  169. package/dist/generated/services/PaiementEnMasseService.js +187 -0
  170. package/dist/generated/services/PaiementImmediatService.d.ts +135 -0
  171. package/dist/generated/services/PaiementImmediatService.js +176 -0
  172. package/dist/generated/services/RetoursdeFondsService.d.ts +28 -0
  173. package/dist/generated/services/RetoursdeFondsService.js +37 -0
  174. package/dist/index.d.ts +14 -0
  175. package/dist/index.js +23 -0
  176. package/dist/query-builder.d.ts +91 -0
  177. package/dist/query-builder.js +187 -0
  178. package/dist/sdk.d.ts +88 -0
  179. package/dist/sdk.js +107 -0
  180. package/dist/services/alias.d.ts +72 -0
  181. package/dist/services/alias.js +82 -0
  182. package/dist/services/base.d.ts +9 -0
  183. package/dist/services/base.js +17 -0
  184. package/dist/services/comptes.d.ts +149 -0
  185. package/dist/services/comptes.js +158 -0
  186. package/dist/services/demandes-annulation.d.ts +97 -0
  187. package/dist/services/demandes-annulation.js +104 -0
  188. package/dist/services/demandes-paiement-en-masse.d.ts +139 -0
  189. package/dist/services/demandes-paiement-en-masse.js +139 -0
  190. package/dist/services/demandes-paiement.d.ts +144 -0
  191. package/dist/services/demandes-paiement.js +151 -0
  192. package/dist/services/paiements-en-masse.d.ts +152 -0
  193. package/dist/services/paiements-en-masse.js +153 -0
  194. package/dist/services/paiements.d.ts +135 -0
  195. package/dist/services/paiements.js +135 -0
  196. package/dist/services/retours-fonds.d.ts +94 -0
  197. package/dist/services/retours-fonds.js +100 -0
  198. package/dist/services/webhooks.d.ts +131 -0
  199. package/dist/services/webhooks.js +142 -0
  200. package/dist/types/alias.d.ts +64 -0
  201. package/dist/types/alias.js +73 -0
  202. package/dist/utils/constants.d.ts +93 -0
  203. package/dist/utils/constants.js +93 -0
  204. package/dist/utils/index.d.ts +60 -0
  205. package/dist/utils/index.js +115 -0
  206. package/package.json +81 -0
  207. package/scripts/post-generate.js +129 -0
  208. 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
+ }