@axproo/core 1.0.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/README.md ADDED
@@ -0,0 +1,280 @@
1
+ # @axproo/core
2
+
3
+ **Librairie centralisée pour gérer la communication HTTP, la gestion des erreurs et l’authentification dans les projets Vue 3.**
4
+
5
+ Elle fournit un client HTTP basé sur **Axios**, normalisé avec des **interceptors** et un **adapter** pour simplifier l’accès aux APIs.
6
+
7
+ ---
8
+
9
+ ## Table des matières
10
+
11
+ - [Installation](#installation)
12
+ - [Configuration](#configuration)
13
+ - [Structure du projet](#structure-du-projet)
14
+ - [Utilisation](#utilisation)
15
+ - [Interceptors](#interceptors)
16
+ - [Adapter](#adapter)
17
+ - [Exemples](#exemples)
18
+ - [Utilisation dans Vue 3](#utilisation-dans-vue-3)
19
+ - [Cas avancés](#cas-avancés)
20
+ - [Upload de fichiers](#upload-de-fichiers)
21
+ - [Streaming de données](#streaming-de-données)
22
+ - [Requêtes simultanées](#requêtes-simultanées)
23
+ - [Timeouts et retries](#timeouts-et-retries)
24
+
25
+ ---
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install @axproo/core axios
31
+ ```
32
+
33
+ ⚠️ **Axios** doit être installé dans le projet qui utilise `@axproo/core`.
34
+
35
+ ---
36
+
37
+ ## Configuration
38
+
39
+ Le client HTTP se configure via `getHttpClient` avec les options suivantes :
40
+
41
+ ```typescript
42
+ import { getHttpClient } from '@axproo/core';
43
+
44
+ const client = getHttpClient({
45
+ baseURL: import.meta.env.VITE_API_URL || '',
46
+ getToken: () => localStorage.getItem('token'),
47
+ isInternal: true, // true pour les utilisateurs internes, false pour API externe
48
+ });
49
+ ```
50
+
51
+ - `**baseURL**` : URL de base de l’API.
52
+ - `**getToken**` : Fonction retournant le JWT (si utilisé).
53
+ - `**isInternal**` : Permet de différencier les utilisateurs internes (cookies httpOnly) et externes (JWT + cookies).
54
+
55
+ ---
56
+
57
+ ## Structure du projet
58
+
59
+ ```
60
+ @axproo/core/
61
+ ├─ src/
62
+ │ ├─ adapters/
63
+ │ │ └─ axios.ts # Adapter pour normaliser l’utilisation d’Axios
64
+ │ ├─ interceptors/
65
+ │ │ ├─ auth.ts # Gestion de l’authentification
66
+ │ │ ├─ error.ts # Gestion des erreurs API
67
+ │ │ └─ response.ts # Normalisation des réponses
68
+ │ ├─ types.ts # Types TypeScript (HttpClient, options, etc.)
69
+ │ └─ client.ts # Client centralisé
70
+ ├─ dist/
71
+ ├─ package.json
72
+ └─ README.md
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Utilisation
78
+
79
+ ### Créer un client
80
+
81
+ ```typescript
82
+ import { getHttpClient } from '@axproo/core';
83
+
84
+ const client = getHttpClient({
85
+ baseURL: 'https://api.monapp.com',
86
+ getToken: () => localStorage.getItem('token'),
87
+ isInternal: true,
88
+ });
89
+ ```
90
+
91
+ ### Requêtes HTTP
92
+
93
+ ```typescript
94
+ // GET
95
+ const form = await client.get('forms/show/auth_login');
96
+
97
+ // POST
98
+ const result = await client.post('forms/submit', { email, password });
99
+ ```
100
+
101
+ Les réponses sont normalisées via l’interceptor `response` pour retourner directement `data`.
102
+
103
+ ---
104
+
105
+ ## Interceptors
106
+
107
+ ### Auth Interceptor
108
+
109
+ Gère l’authentification pour les requêtes :
110
+
111
+ - **Internes** : cookies httpOnly.
112
+ - **Externes** : JWT + cookies.
113
+
114
+ ```typescript
115
+ import { createAuthInterceptor } from './interceptors/auth';
116
+
117
+ axios.interceptors.request.use(
118
+ createAuthInterceptor({
119
+ getToken: () => localStorage.getItem('token'),
120
+ isInternal: true,
121
+ })
122
+ );
123
+ ```
124
+
125
+ ### Response Interceptor
126
+
127
+ Normalise les réponses API pour toujours retourner le `data` principal.
128
+
129
+ ```typescript
130
+ import { createResponseInterceptor } from './interceptors/response';
131
+
132
+ axios.interceptors.response.use(createResponseInterceptor());
133
+ ```
134
+
135
+ ### Error Interceptor
136
+
137
+ Gère les erreurs HTTP globalement et permet de centraliser le traitement.
138
+
139
+ ```typescript
140
+ import { createErrorInterceptor } from './interceptors/error';
141
+
142
+ axios.interceptors.response.use(undefined, createErrorInterceptor());
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Adapter
148
+
149
+ L’adapter expose les méthodes classiques (`get`, `post`, `put`, `delete`) sur le client tout en utilisant les interceptors.
150
+
151
+ ```typescript
152
+ import { createAxiosAdapter } from './adapter';
153
+ import axios from 'axios';
154
+
155
+ const instance = axios.create({ baseURL: 'https://api.monapp.com' });
156
+ const client = createAxiosAdapter(instance);
157
+
158
+ // Utilisation
159
+ client.get('forms/show/auth_login');
160
+ client.post('forms/submit', { email, password });
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Exemples
166
+
167
+ ### Utilisation dans Vue 3
168
+
169
+ ```vue
170
+ <script setup lang="ts">
171
+ import { onMounted } from 'vue';
172
+ import { getHttpClient } from '@axproo/core';
173
+
174
+ const client = getHttpClient({
175
+ baseURL: import.meta.env.VITE_API_URL || '',
176
+ getToken: () => localStorage.getItem('token'),
177
+ isInternal: true,
178
+ });
179
+
180
+ onMounted(async () => {
181
+ try {
182
+ const form = await client.get('forms/show/auth_login');
183
+ console.log('Form data:', form);
184
+ } catch (error) {
185
+ console.error('API error:', error);
186
+ }
187
+ });
188
+ </script>
189
+ ```
190
+
191
+ Les réponses sont directement le contenu `data` de l’API, grâce au **response interceptor**.
192
+
193
+ ---
194
+
195
+ ### Cas avancés
196
+
197
+ #### Upload de fichiers
198
+
199
+ Pour uploader un fichier, utilisez `FormData` et la méthode `post` :
200
+
201
+ ```typescript
202
+ import { getHttpClient } from '@axproo/core'
203
+
204
+ const client = getHttpClient({
205
+ baseURL: import.meta.env.VITE_API_URL,
206
+ getToken: () => localStorage.getItem('jwt')
207
+ })
208
+
209
+ async function uploadFile(file: File) {
210
+ const formData = new FormData();
211
+ formData.append('file', file);
212
+
213
+ try {
214
+ const response = await client.post('upload', formData, {
215
+ headers: {
216
+ 'Content-Type': 'multipart/form-data',
217
+ },
218
+ });
219
+ console.log('Upload successful:', response);
220
+ } catch (error) {
221
+ console.error('Upload failed:', error);
222
+ }
223
+ }
224
+ ```
225
+
226
+ #### Streaming de données
227
+
228
+ Pour récupérer des données en streaming (ex: téléchargement d’un gros fichier) :
229
+
230
+ ```typescript
231
+ async function downloadFile(url: string, filename: string) {
232
+ try {
233
+ const response = await client.get(url, {
234
+ responseType: 'blob',
235
+ });
236
+
237
+ const blob = new Blob([response]);
238
+ const link = document.createElement('a');
239
+ link.href = URL.createObjectURL(blob);
240
+ link.download = filename;
241
+ link.click();
242
+ } catch (error) {
243
+ console.error('Download failed:', error);
244
+ }
245
+ }
246
+ ```
247
+
248
+ #### Requêtes simultanées
249
+
250
+ Pour exécuter plusieurs requêtes en parallèle :
251
+
252
+ ```typescript
253
+ async function fetchMultipleData() {
254
+ try {
255
+ const [users, posts] = await Promise.all([
256
+ client.get('users'),
257
+ client.get('posts'),
258
+ ]);
259
+ console.log('Users:', users);
260
+ console.log('Posts:', posts);
261
+ } catch (error) {
262
+ console.error('One or more requests failed:', error);
263
+ }
264
+ }
265
+ ```
266
+
267
+ #### Timeouts et retries
268
+
269
+ Pour configurer un timeout ou des retries, étendez la configuration Axios :
270
+
271
+ ```typescript
272
+ const client = getHttpClient({
273
+ baseURL: 'https://api.monapp.com',
274
+ getToken: () => localStorage.getItem('token'),
275
+ isInternal: true,
276
+ timeout: 10000, // 10 secondes
277
+ });
278
+
279
+ // Pour les retries, utilisez un interceptor personnalisé ou une librairie comme axios-retry
280
+ ```
@@ -0,0 +1,69 @@
1
+ import e from "axios";
2
+ //#region src/http/interceptors/auth.ts
3
+ function t(e = {}) {
4
+ let { getToken: t, isInternal: n = !1 } = e;
5
+ return (e) => {
6
+ if (e.withCredentials = !0, e.headers ||= {}, n && t) {
7
+ let n = t();
8
+ n && (e.headers.Authorization = `Bearer ${n}`);
9
+ }
10
+ return e;
11
+ };
12
+ }
13
+ //#endregion
14
+ //#region src/http/interceptors/response.ts
15
+ function n() {
16
+ return (e) => e.data && "success" in e.data ? e.data : {
17
+ success: !0,
18
+ message: "",
19
+ data: e.data
20
+ };
21
+ }
22
+ //#endregion
23
+ //#region src/http/interceptors/error.ts
24
+ function r() {
25
+ return (e) => {
26
+ if (e.message) {
27
+ let t = e.response?.data;
28
+ return console.error("[AXPROO API ERROR]", {
29
+ status: e.response?.status,
30
+ data: e.response?.data
31
+ }), Promise.reject({
32
+ message: t?.message || e.message,
33
+ status: t?.status,
34
+ data: t
35
+ });
36
+ } else if (e.request) return console.log("[AXPROO API NO RESPONSE]", e.request), Promise.reject({ message: "No response from server" });
37
+ else return console.error("[AXPROO ERROR]", e.message), Promise.reject({ message: e.message });
38
+ };
39
+ }
40
+ //#endregion
41
+ //#region src/http/adapter.ts
42
+ function i(e) {
43
+ return {
44
+ get: (t, n) => e.get(t, n),
45
+ post: (t, n, r) => e.post(t, n, r),
46
+ put: (t, n, r) => e.put(t, n, r),
47
+ delete: (t, n) => e.delete(t, n)
48
+ };
49
+ }
50
+ //#endregion
51
+ //#region src/http/client.ts
52
+ function a(e) {}
53
+ function o(a) {
54
+ let o = e.create({
55
+ baseURL: a.baseURL,
56
+ timeout: 3e4,
57
+ withCredentials: !0,
58
+ headers: {
59
+ "Content-Type": "application/json",
60
+ Accept: "application/json"
61
+ }
62
+ });
63
+ return o.interceptors.request.use(t({
64
+ getToken: a.getToken,
65
+ isInternal: a.isInternal
66
+ })), o.interceptors.response.use(n(), r()), i(o);
67
+ }
68
+ //#endregion
69
+ export { t as createAuthInterceptor, i as createAxiosAdapter, r as createErrorInterceptor, n as createResponseInterceptor, o as getHttpClient, a as setHttpClient };
@@ -0,0 +1 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`axios`)):typeof define==`function`&&define.amd?define([`exports`,`axios`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.Core={},e.Axios))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,c=(e,t,n,o)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=a(t),l=0,u=c.length,d;l<u;l++)d=c[l],!s.call(e,d)&&d!==n&&r(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(o=i(t,d))||o.enumerable});return e};t=((e,t,i)=>(i=e==null?{}:n(o(e)),c(t||!e||!e.__esModule?r(i,`default`,{value:e,enumerable:!0}):i,e)))(t);function l(e={}){let{getToken:t,isInternal:n=!1}=e;return e=>{if(e.withCredentials=!0,e.headers||={},n&&t){let n=t();n&&(e.headers.Authorization=`Bearer ${n}`)}return e}}function u(){return e=>e.data&&`success`in e.data?e.data:{success:!0,message:``,data:e.data}}function d(){return e=>{if(e.message){let t=e.response?.data;return console.error(`[AXPROO API ERROR]`,{status:e.response?.status,data:e.response?.data}),Promise.reject({message:t?.message||e.message,status:t?.status,data:t})}else if(e.request)return console.log(`[AXPROO API NO RESPONSE]`,e.request),Promise.reject({message:`No response from server`});else return console.error(`[AXPROO ERROR]`,e.message),Promise.reject({message:e.message})}}function f(e){return{get:(t,n)=>e.get(t,n),post:(t,n,r)=>e.post(t,n,r),put:(t,n,r)=>e.put(t,n,r),delete:(t,n)=>e.delete(t,n)}}function p(e){}function m(e){let n=t.default.create({baseURL:e.baseURL,timeout:3e4,withCredentials:!0,headers:{"Content-Type":`application/json`,Accept:`application/json`}});return n.interceptors.request.use(l({getToken:e.getToken,isInternal:e.isInternal})),n.interceptors.response.use(u(),d()),f(n)}e.createAuthInterceptor=l,e.createAxiosAdapter=f,e.createErrorInterceptor=d,e.createResponseInterceptor=u,e.getHttpClient=m,e.setHttpClient=p});
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="46" fill="none" viewBox="0 0 48 46"><path fill="#863bff" d="M25.946 44.938c-.664.845-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.287c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.497 0-3.578-1.842-3.578H1.237c-.92 0-1.456-1.04-.92-1.788L10.013.474c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.579 1.842 3.579h11.377c.943 0 1.473 1.088.89 1.83L25.947 44.94z" style="fill:#863bff;fill:color(display-p3 .5252 .23 1);fill-opacity:1"/><mask id="a" width="48" height="46" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M25.842 44.938c-.664.844-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.183c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.498 0-3.579-1.842-3.579H1.133c-.92 0-1.456-1.04-.92-1.787L9.91.473c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.578 1.842 3.578h11.377c.943 0 1.473 1.088.89 1.832L25.843 44.94z" style="fill:#000;fill-opacity:1"/></mask><g mask="url(#a)"><g filter="url(#b)"><ellipse cx="5.508" cy="14.704" fill="#ede6ff" rx="5.508" ry="14.704" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -4.47 31.516)"/></g><g filter="url(#c)"><ellipse cx="10.399" cy="29.851" fill="#ede6ff" rx="10.399" ry="29.851" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -39.328 7.883)"/></g><g filter="url(#d)"><ellipse cx="5.508" cy="30.487" fill="#7e14ff" rx="5.508" ry="30.487" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -25.913 -14.639)scale(1 -1)"/></g><g filter="url(#e)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -32.644 -3.334)scale(1 -1)"/></g><g filter="url(#f)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -34.34 30.47)"/></g><g filter="url(#g)"><ellipse cx="14.072" cy="22.078" fill="#ede6ff" rx="14.072" ry="22.078" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="rotate(93.35 24.506 48.493)scale(-1 1)"/></g><g filter="url(#h)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#i)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#j)"><ellipse cx=".387" cy="8.972" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(39.51 .387 8.972)"/></g><g filter="url(#k)"><ellipse cx="47.523" cy="-6.092" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 47.523 -6.092)"/></g><g filter="url(#l)"><ellipse cx="41.412" cy="6.333" fill="#47bfff" rx="5.971" ry="9.665" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 41.412 6.333)"/></g><g filter="url(#m)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#n)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#o)"><ellipse cx="35.651" cy="29.907" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 35.651 29.907)"/></g><g filter="url(#p)"><ellipse cx="38.418" cy="32.4" fill="#47bfff" rx="5.971" ry="15.297" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 38.418 32.4)"/></g></g><defs><filter id="b" width="60.045" height="41.654" x="-19.77" y="16.149" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="c" width="90.34" height="51.437" x="-54.613" y="-7.533" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="d" width="79.355" height="29.4" x="-49.64" y="2.03" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="e" width="79.579" height="29.4" x="-45.045" y="20.029" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="f" width="79.579" height="29.4" x="-43.513" y="21.178" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="g" width="74.749" height="58.852" x="15.756" y="-17.901" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="h" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="i" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="j" width="56.045" height="63.649" x="-27.636" y="-22.853" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="k" width="54.814" height="64.646" x="20.116" y="-38.415" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="l" width="33.541" height="35.313" x="24.641" y="-11.323" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="m" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="n" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="o" width="54.814" height="64.646" x="8.244" y="-2.416" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="p" width="39.409" height="43.623" x="18.713" y="10.588" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter></defs></svg>
@@ -0,0 +1,3 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { HttpClient } from './types';
3
+ export declare function createAxiosAdapter(instance: AxiosInstance): HttpClient;
@@ -0,0 +1,7 @@
1
+ import { HttpClient } from './types';
2
+ export declare function setHttpClient(client: HttpClient): void;
3
+ export declare function getHttpClient(options: {
4
+ baseURL: string;
5
+ getToken: () => string | null;
6
+ isInternal?: boolean;
7
+ }): HttpClient;
@@ -0,0 +1,6 @@
1
+ export * from './client';
2
+ export * from './types';
3
+ export * from './adapter';
4
+ export * from './interceptors/auth';
5
+ export * from './interceptors/error';
6
+ export * from './interceptors/response';
@@ -0,0 +1,3 @@
1
+ import { InternalAxiosRequestConfig } from 'axios';
2
+ import { AuthInterceptorOptions } from '../types';
3
+ export declare function createAuthInterceptor(options?: AuthInterceptorOptions): (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
@@ -0,0 +1,3 @@
1
+ import { AxiosError } from 'axios';
2
+ import { ApiError } from '../types';
3
+ export declare function createErrorInterceptor(): (error: AxiosError<ApiError>) => Promise<never>;
@@ -0,0 +1,2 @@
1
+ import { AxiosResponse } from 'axios';
2
+ export declare function createResponseInterceptor(): (response: AxiosResponse) => any;
@@ -0,0 +1,15 @@
1
+ export interface AuthInterceptorOptions {
2
+ getToken?: () => string | null;
3
+ isInternal?: boolean;
4
+ }
5
+ export interface HttpClient {
6
+ get<T = any>(url: string, config?: any): Promise<T>;
7
+ post<T = any>(url: string, data?: any, config?: any): Promise<T>;
8
+ put<T = any>(url: string, data?: any, config?: any): Promise<T>;
9
+ delete<T = any>(url: string, config?: any): Promise<T>;
10
+ }
11
+ export type ApiError = {
12
+ status?: boolean;
13
+ message?: string;
14
+ [key: string]: any;
15
+ };
package/dist/icons.svg ADDED
@@ -0,0 +1,24 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg">
2
+ <symbol id="bluesky-icon" viewBox="0 0 16 17">
3
+ <g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
4
+ <defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
5
+ </symbol>
6
+ <symbol id="discord-icon" viewBox="0 0 20 19">
7
+ <path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
8
+ </symbol>
9
+ <symbol id="documentation-icon" viewBox="0 0 21 20">
10
+ <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
11
+ <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
12
+ <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
13
+ </symbol>
14
+ <symbol id="github-icon" viewBox="0 0 19 19">
15
+ <path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
16
+ </symbol>
17
+ <symbol id="social-icon" viewBox="0 0 20 20">
18
+ <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
19
+ <path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
20
+ </symbol>
21
+ <symbol id="x-icon" viewBox="0 0 19 19">
22
+ <path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
23
+ </symbol>
24
+ </svg>
@@ -0,0 +1 @@
1
+ export * from './http';
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@axproo/core",
3
+ "version": "1.0.0",
4
+ "description": "Logique commune (store, composables, utils)",
5
+ "type": "module",
6
+ "main": "./dist/core.umd.js",
7
+ "module": "./dist/core.es.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/core.es.js",
12
+ "types": "./dist/index.d.ts",
13
+ "require": "./dist/core.umd.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "vite build"
21
+ },
22
+ "peerDependencies": {
23
+ "vue": "^3.5.30",
24
+ "axios": "^1.11.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^24.12.0",
28
+ "@vitejs/plugin-vue": "^6.0.5",
29
+ "@vue/tsconfig": "^0.9.0",
30
+ "typescript": "~5.9.3",
31
+ "vite": "^8.0.1",
32
+ "vite-plugin-dts": "^4.5.4",
33
+ "vue-tsc": "^3.2.5"
34
+ }
35
+ }