@arc-js/pajo 0.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,568 @@
1
+ # @arc-js/pajo
2
+
3
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+ ![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-007ACC)
5
+ ![Browser](https://img.shields.io/badge/browser-compatible-green)
6
+ ![Node.js](https://img.shields.io/badge/Node.js-18+-339933)
7
+ ![Deno](https://img.shields.io/badge/Deno-1.30+-000000)
8
+ ![Bun](https://img.shields.io/badge/Bun-1.0+-FBF0DF)
9
+
10
+ **@arc-js/pajo** est une bibliothèque TypeScript légère et robuste pour la manipulation de chemins de fichiers et d'URLs. Elle offre une API unifiée et type-safe pour travailler avec des chemins de fichiers sur différentes plateformes (Windows, Linux, macOS) et pour construire des URLs de manière cohérente.
11
+
12
+ ## ✨ Fonctionnalités Principales
13
+
14
+ ### 📁 Manipulation de Chemins
15
+ - **Style multi-plateforme** : Support natif des chemins Windows (\) et Unix (/)
16
+ - **Joindre des chemins** : Méthode intelligente pour joindre plusieurs segments de chemin
17
+ - **Chemins absolus/relatifs** : Détection automatique du type de chemin
18
+ - **Normalisation** : Élimination des séparateurs redondants et des points (., ..)
19
+ - **Extraction** : Récupération du nom de fichier, extension et répertoire parent
20
+
21
+ ### 🌐 Manipulation d'URLs
22
+ - **Construction d'URLs** : Joindre des segments avec un hôte (avec ou sans protocole)
23
+ - **Normalisation automatique** : Ajout de protocole si absent, gestion des slashs
24
+ - **Support des protocoles** : Reconnaissance automatique des schémas (http://, https://, etc.)
25
+
26
+ ### 🔄 Conversion
27
+ - **Conversion de style** : Convertir entre chemins Windows et Unix
28
+ - **Adaptation automatique** : Détection du style basée sur le contenu du chemin
29
+
30
+ ### 🛡️ Robustesse
31
+ - **Gestion des cas limites** : Chemins vides, séparateurs multiples, points spéciaux
32
+ - **Type-safe** : Entièrement écrit en TypeScript avec des types stricts
33
+ - **Pas de dépendances** : Bibliothèque autonome, zéro dépendance
34
+
35
+ ## 📦 Installation
36
+
37
+ ### Via npm/yarn/pnpm
38
+
39
+ ```bash
40
+ npm install @arc-js/pajo
41
+ # ou
42
+ yarn add @arc-js/pajo
43
+ # ou
44
+ pnpm add @arc-js/pajo
45
+ ```
46
+
47
+ ### Importation directe (CDN)
48
+
49
+ ```html
50
+ <script src="@arc-js/pajo/pajo.all.js"></script>
51
+ ```
52
+
53
+ ## 🚀 Démarrage Rapide
54
+
55
+ ### TypeScript/ES Modules
56
+
57
+ ```typescript
58
+ import Pajo from '@arc-js/pajo';
59
+ // ou
60
+ import { Pajo } from '@arc-js/pajo';
61
+ ```
62
+
63
+ ### CommonJS
64
+
65
+ ```javascript
66
+ const Pajo = require('@arc-js/pajo').default;
67
+ // ou
68
+ const { Pajo } = require('@arc-js/pajo');
69
+ ```
70
+
71
+ ### Navigateur (global)
72
+
73
+ ```html
74
+ <script src="@arc-js/pajo/pajo.all.js"></script>
75
+ <script>
76
+ // Disponible globalement via window.Pajo
77
+ console.log(Pajo.join('path', 'to', 'file.txt'));
78
+ </script>
79
+ ```
80
+
81
+ ### Deno
82
+
83
+ ```typescript
84
+ import Pajo from '@arc-js/pajo';
85
+ ```
86
+
87
+ ## 📚 Documentation API
88
+
89
+ ### Méthodes Statiques
90
+
91
+ #### `Pajo.join(...paths: string[]): string | undefined`
92
+ Joint plusieurs segments de chemin en normalisant les séparateurs.
93
+
94
+ **Paramètres:**
95
+ - `paths`: Segments de chemin à joindre (peut être vide)
96
+
97
+ **Retourne:** Le chemin normalisé ou `undefined` si aucun chemin valide
98
+
99
+ **Exemples:**
100
+ ```typescript
101
+ // Chemins Unix
102
+ Pajo.join('/var', 'www', 'html'); // "/var/www/html"
103
+ Pajo.join('/usr/', '/local/', '/bin'); // "/usr/local/bin"
104
+ Pajo.join('./src', './utils', '../components'); // "src/components"
105
+
106
+ // Chemins Windows
107
+ Pajo.join('C:\\Users', 'Documents', 'file.txt'); // "C:\\Users\\Documents\\file.txt"
108
+ Pajo.join('D:\\Projects\\', '\\src\\', '\\app.js'); // "D:\\Projects\\src\\app.js"
109
+
110
+ // Chemins mixtes
111
+ Pajo.join('path', 'to', 'file.txt'); // "path/to/file.txt"
112
+ Pajo.join('path/', '//to/', 'file.txt'); // "path/to/file.txt"
113
+ ```
114
+
115
+ #### `Pajo.joinWithHost(host: string, ...paths: string[]): string | undefined`
116
+ Joint un hôte avec des segments de chemin pour former une URL.
117
+
118
+ **Paramètres:**
119
+ - `host`: Hôte (peut inclure le protocole)
120
+ - `paths`: Segments de chemin à joindre
121
+
122
+ **Retourne:** L'URL complète normalisée ou `undefined` si invalide
123
+
124
+ **Exemples:**
125
+ ```typescript
126
+ Pajo.joinWithHost('example.com', 'api', 'v1', 'users');
127
+ // "https://example.com/api/v1/users"
128
+
129
+ Pajo.joinWithHost('https://example.com', 'api', 'v1');
130
+ // "https://example.com/api/v1"
131
+
132
+ Pajo.joinWithHost('myserver.com', '/var', 'log', 'app.log');
133
+ // "https://myserver.com/var/log/app.log"
134
+ ```
135
+
136
+ #### `Pajo.resolve(...paths: string[]): string | undefined`
137
+ Résout les chemins avec . et .. pour obtenir un chemin normalisé.
138
+
139
+ **Paramètres:**
140
+ - `paths`: Segments de chemin à résoudre
141
+
142
+ **Retourne:** Chemin résolu ou `undefined` si invalide
143
+
144
+ **Exemples:**
145
+ ```typescript
146
+ Pajo.resolve('/foo/bar', './baz'); // "/foo/bar/baz"
147
+ Pajo.resolve('/foo/bar', '../baz'); // "/foo/baz"
148
+ Pajo.resolve('C:\\foo\\bar', '..\\baz'); // "C:\\foo\\baz"
149
+ ```
150
+
151
+ #### `Pajo.isAbsolute(path: string): boolean`
152
+ Vérifie si un chemin est absolu.
153
+
154
+ **Paramètres:**
155
+ - `path`: Chemin à vérifier
156
+
157
+ **Retourne:** `true` si le chemin est absolu
158
+
159
+ **Exemples:**
160
+ ```typescript
161
+ Pajo.isAbsolute('/path/to/file'); // true
162
+ Pajo.isAbsolute('C:\\Windows\\System32'); // true
163
+ Pajo.isAbsolute('https://example.com'); // true
164
+ Pajo.isAbsolute('relative/path'); // false
165
+ Pajo.isAbsolute('./file.txt'); // false
166
+ ```
167
+
168
+ #### `Pajo.dirname(path: string): string | undefined`
169
+ Extrait le répertoire parent d'un chemin.
170
+
171
+ **Paramètres:**
172
+ - `path`: Chemin source
173
+
174
+ **Retourne:** Le répertoire parent ou `undefined`
175
+
176
+ **Exemples:**
177
+ ```typescript
178
+ Pajo.dirname('/path/to/file.txt'); // "/path/to"
179
+ Pajo.dirname('C:\\Users\\file.txt'); // "C:\\Users"
180
+ Pajo.dirname('file.txt'); // "."
181
+ ```
182
+
183
+ #### `Pajo.basename(path: string, ext?: string): string | undefined`
184
+ Extrait le nom de fichier d'un chemin.
185
+
186
+ **Paramètres:**
187
+ - `path`: Chemin source
188
+ - `ext` (optionnel): Extension à retirer
189
+
190
+ **Retourne:** Le nom de fichier ou `undefined`
191
+
192
+ **Exemples:**
193
+ ```typescript
194
+ Pajo.basename('/path/to/file.txt'); // "file.txt"
195
+ Pajo.basename('/path/to/file.txt', '.txt'); // "file"
196
+ Pajo.basename('C:\\Users\\document.pdf'); // "document.pdf"
197
+ ```
198
+
199
+ #### `Pajo.extname(path: string): string | undefined`
200
+ Extrait l'extension d'un fichier.
201
+
202
+ **Paramètres:**
203
+ - `path`: Chemin source
204
+
205
+ **Retourne:** L'extension (incluant le point) ou `undefined`
206
+
207
+ **Exemples:**
208
+ ```typescript
209
+ Pajo.extname('/path/to/file.txt'); // ".txt"
210
+ Pajo.extname('document.pdf'); // ".pdf"
211
+ Pajo.extname('file.with.many.dots.tar.gz'); // ".gz"
212
+ Pajo.extname('noextension'); // undefined
213
+ ```
214
+
215
+ #### `Pajo.toUnixPath(path: string): string`
216
+ Convertit un chemin Windows en chemin Unix.
217
+
218
+ **Paramètres:**
219
+ - `path`: Chemin Windows
220
+
221
+ **Retourne:** Chemin Unix
222
+
223
+ **Exemples:**
224
+ ```typescript
225
+ Pajo.toUnixPath('C:\\Users\\file.txt'); // "C:/Users/file.txt"
226
+ Pajo.toUnixPath('D:\\Projects\\src'); // "D:/Projects/src"
227
+ ```
228
+
229
+ #### `Pajo.toWindowsPath(path: string): string`
230
+ Convertit un chemin Unix en chemin Windows.
231
+
232
+ **Paramètres:**
233
+ - `path`: Chemin Unix
234
+
235
+ **Retourne:** Chemin Windows
236
+
237
+ **Exemples:**
238
+ ```typescript
239
+ Pajo.toWindowsPath('/home/user/file.txt'); // "\\home\\user\\file.txt"
240
+ Pajo.toWindowsPath('C:/Users/document'); // "C:\\Users\\document"
241
+ ```
242
+
243
+ #### `Pajo.exposeToGlobal(): void`
244
+ Expose la classe Pajo à l'objet global (window) pour une utilisation dans les navigateurs.
245
+
246
+ **Exemple:**
247
+ ```javascript
248
+ // Dans un navigateur, après avoir chargé le script
249
+ Pajo.exposeToGlobal();
250
+ console.log(window.Pajo); // La classe Pajo est disponible
251
+ ```
252
+
253
+ ## 🔧 Utilisation Détaillée
254
+
255
+ ### Gestion Multi-Plateforme
256
+
257
+ Pajo détecte automatiquement le style de chemin basé sur le contenu :
258
+
259
+ ```typescript
260
+ // Détection automatique du style
261
+ Pajo.join('C:\\Users', 'Documents'); // Style Windows
262
+ Pajo.join('/home', 'user'); // Style Unix
263
+ Pajo.join('relative', 'path'); // Style Unix par défaut
264
+ ```
265
+
266
+ ### Construction d'URLs
267
+
268
+ ```typescript
269
+ // Construction d'URLs avec protocole automatique
270
+ Pajo.joinWithHost('api.example.com', 'v1', 'users');
271
+ // → "https://api.example.com/v1/users"
272
+
273
+ // Avec protocole explicite
274
+ Pajo.joinWithHost('http://localhost:3000', 'api', 'data');
275
+ // → "http://localhost:3000/api/data"
276
+
277
+ // Avec chemin absolu sur l'hôte
278
+ Pajo.joinWithHost('example.com', '/absolute/path');
279
+ // → "https://example.com/absolute/path"
280
+ ```
281
+
282
+ ### Résolution de Chemins Relatifs
283
+
284
+ ```typescript
285
+ // Résolution des chemins avec .. et .
286
+ Pajo.resolve('/usr/local/bin', '..', 'share');
287
+ // → "/usr/local/share"
288
+
289
+ Pajo.resolve('C:\\Program Files\\App', '..', 'Common Files');
290
+ // → "C:\\Program Files\\Common Files"
291
+
292
+ Pajo.resolve('./src', '../lib', './utils');
293
+ // → "lib/utils"
294
+ ```
295
+
296
+ ### Extraction d'Informations
297
+
298
+ ```typescript
299
+ const path = '/var/www/html/index.html';
300
+
301
+ Pajo.dirname(path); // "/var/www/html"
302
+ Pajo.basename(path); // "index.html"
303
+ Pajo.extname(path); // ".html"
304
+ Pajo.isAbsolute(path); // true
305
+ ```
306
+
307
+ ## 🎯 Exemples Complets
308
+
309
+ ### Exemple 1 : Gestion de Chemins dans une Application
310
+
311
+ ```typescript
312
+ import Pajo from '@arc-js/pajo';
313
+
314
+ class FileManager {
315
+ private baseDir: string;
316
+
317
+ constructor(baseDir: string) {
318
+ this.baseDir = baseDir;
319
+ }
320
+
321
+ getFilePath(...segments: string[]): string {
322
+ const fullPath = Pajo.join(this.baseDir, ...segments);
323
+ return Pajo.resolve(fullPath) || fullPath;
324
+ }
325
+
326
+ getFileInfo(path: string) {
327
+ return {
328
+ directory: Pajo.dirname(path),
329
+ filename: Pajo.basename(path),
330
+ extension: Pajo.extname(path),
331
+ isAbsolute: Pajo.isAbsolute(path),
332
+ unixPath: Pajo.toUnixPath(path)
333
+ };
334
+ }
335
+ }
336
+
337
+ // Utilisation
338
+ const manager = new FileManager('/var/www');
339
+ const filePath = manager.getFilePath('uploads', '..', 'images', 'photo.jpg');
340
+ console.log(filePath); // "/var/images/photo.jpg"
341
+
342
+ const info = manager.getFileInfo(filePath);
343
+ console.log(info);
344
+ // {
345
+ // directory: "/var/images",
346
+ // filename: "photo.jpg",
347
+ // extension: ".jpg",
348
+ // isAbsolute: true,
349
+ // unixPath: "/var/images/photo.jpg"
350
+ // }
351
+ ```
352
+
353
+ ### Exemple 2 : Construction d'APIs REST
354
+
355
+ ```typescript
356
+ import Pajo from '@arc-js/pajo';
357
+
358
+ class ApiClient {
359
+ private baseUrl: string;
360
+
361
+ constructor(baseUrl: string) {
362
+ this.baseUrl = baseUrl;
363
+ }
364
+
365
+ buildUrl(endpoint: string, ...params: string[]): string {
366
+ return Pajo.joinWithHost(this.baseUrl, endpoint, ...params) || '';
367
+ }
368
+
369
+ async getResource(endpoint: string, id?: string) {
370
+ const url = id
371
+ ? this.buildUrl(endpoint, id)
372
+ : this.buildUrl(endpoint);
373
+
374
+ const response = await fetch(url);
375
+ return response.json();
376
+ }
377
+ }
378
+
379
+ // Utilisation
380
+ const api = new ApiClient('https://api.example.com');
381
+
382
+ // Construire des URLs
383
+ const usersUrl = api.buildUrl('users');
384
+ // → "https://api.example.com/users"
385
+
386
+ const userUrl = api.buildUrl('users', '123');
387
+ // → "https://api.example.com/users/123"
388
+
389
+ // Récupérer des données
390
+ const users = await api.getResource('users');
391
+ const user = await api.getResource('users', '123');
392
+ ```
393
+
394
+ ### Exemple 3 : Migration Multi-Plateforme
395
+
396
+ ```typescript
397
+ import Pajo from '@arc-js/pajo';
398
+
399
+ function migratePath(oldPath: string, newBase: string): string {
400
+ // Normaliser le chemin d'entrée
401
+ const normalized = Pajo.resolve(oldPath);
402
+ if (!normalized) return newBase;
403
+
404
+ // Extraire le nom de fichier
405
+ const filename = Pajo.basename(normalized);
406
+
407
+ // Construire le nouveau chemin
408
+ return Pajo.join(newBase, filename);
409
+ }
410
+
411
+ // Migration depuis Windows vers Unix
412
+ const windowsPath = 'C:\\Users\\John\\Documents\\file.txt';
413
+ const unixBase = '/home/john/files';
414
+
415
+ const migrated = migratePath(windowsPath, unixBase);
416
+ console.log(migrated); // "/home/john/files/file.txt"
417
+
418
+ // Conversion explicite si nécessaire
419
+ console.log(Pajo.toUnixPath(windowsPath)); // "C:/Users/John/Documents/file.txt"
420
+ ```
421
+
422
+ ## 🔧 Configuration Avancée
423
+
424
+ ### Personnalisation du Style de Chemin
425
+
426
+ Bien que Pajo détecte automatiquement le style, vous pouvez forcer un style spécifique :
427
+
428
+ ```typescript
429
+ function forceWindowsPath(...segments: string[]): string {
430
+ // Ajouter un préfixe Windows pour forcer le style
431
+ return Pajo.join('C:\\forced', ...segments).replace('C:\\forced\\', '');
432
+ }
433
+
434
+ function forceUnixPath(...segments: string[]): string {
435
+ // Ajouter un slash initial pour forcer le style Unix
436
+ return Pajo.join('/forced', ...segments).replace('/forced/', '');
437
+ }
438
+ ```
439
+
440
+ ### Extension pour les Chemins d'URL
441
+
442
+ ```typescript
443
+ class UrlPath extends Pajo {
444
+ static normalizeUrlPath(path: string): string {
445
+ // Pour les URLs, on utilise toujours des slashs
446
+ return path.replace(/\\/g, '/').replace(/\/+/g, '/');
447
+ }
448
+
449
+ static buildQueryString(params: Record<string, any>): string {
450
+ const query = new URLSearchParams();
451
+ Object.entries(params).forEach(([key, value]) => {
452
+ if (value !== undefined && value !== null) {
453
+ query.append(key, String(value));
454
+ }
455
+ });
456
+ const queryString = query.toString();
457
+ return queryString ? `?\${queryString}` : '';
458
+ }
459
+
460
+ static joinWithQuery(host: string, path: string, queryParams?: Record<string, any>): string {
461
+ const url = this.joinWithHost(host, path);
462
+ if (!url || !queryParams) return url || '';
463
+
464
+ const query = this.buildQueryString(queryParams);
465
+ return `\${url}\${query}`;
466
+ }
467
+ }
468
+
469
+ // Utilisation
470
+ const url = UrlPath.joinWithQuery(
471
+ 'example.com',
472
+ 'api/search',
473
+ { q: 'test', page: 1 }
474
+ );
475
+ console.log(url); // "https://example.com/api/search?q=test&page=1"
476
+ ```
477
+
478
+ ## 📋 Table de Compatibilité
479
+
480
+ ### Caractères Spéciaux Supportés
481
+
482
+ | Caractère | Description | Exemple |
483
+ |-----------|-------------|---------|
484
+ | . | Répertoire courant | `./file.txt` |
485
+ | .. | Répertoire parent | `../parent/file.txt` |
486
+ | ~ | Répertoire home (Unix) | `~/.config/app` |
487
+ | \\ | Séparateur Windows | `C:\\Users\\file.txt` |
488
+ | / | Séparateur Unix | `/home/user/file.txt` |
489
+
490
+ ### Plates-formes Supportées
491
+
492
+ | Plate-forme | Support | Notes |
493
+ |-------------|---------|-------|
494
+ | Windows | ✅ Complet | Détection automatique des chemins Windows |
495
+ | Linux | ✅ Complet | Détection automatique des chemins Unix |
496
+ | macOS | ✅ Complet | Identique à Linux |
497
+ | Navigateurs | ✅ Complet | Via CDN ou module ES |
498
+ | Node.js | ✅ Complet | v18+ recommandé |
499
+ | Deno | ✅ Complet | Via esm.sh ou npm: |
500
+ | Bun | ✅ Complet | Support natif des modules ES |
501
+
502
+ ## 🚨 Gestion des Cas Limites
503
+
504
+ ### Chemins Vides ou Nuls
505
+
506
+ ```typescript
507
+ Pajo.join(); // undefined
508
+ Pajo.join(''); // undefined
509
+ Pajo.join('', 'path'); // "path"
510
+ Pajo.join('path', '', 'file'); // "path/file"
511
+ ```
512
+
513
+ ### Séparateurs Multiples
514
+
515
+ ```typescript
516
+ Pajo.join('path///', '//to/', 'file.txt'); // "path/to/file.txt"
517
+ Pajo.join('C:\\\\Windows', '\\\\System32'); // "C:\\\\Windows\\\\System32"
518
+ ```
519
+
520
+ ### Chemins avec Points
521
+
522
+ ```typescript
523
+ Pajo.join('..', 'parent', 'file.txt'); // "../parent/file.txt"
524
+ Pajo.join('.', 'current', 'file.txt'); // "current/file.txt"
525
+ Pajo.join('path..', 'file.txt'); // "path../file.txt"
526
+ ```
527
+
528
+ ### URLs et Protocoles
529
+
530
+ ```typescript
531
+ Pajo.joinWithHost('https://example.com'); // "https://example.com"
532
+ Pajo.joinWithHost('ftp://server.com', 'files'); // "ftp://server.com/files"
533
+ Pajo.joinWithHost('file:///C:/Users', 'doc.txt'); // "file:///C:/Users/doc.txt"
534
+ ```
535
+
536
+ ## 🔧 Build et Développement
537
+
538
+ ### Structure du Projet
539
+
540
+ ```
541
+ @arc-js/pajo/
542
+ ├── pajo.all.js
543
+ ├── pajo.all.min.js
544
+ ├── index.d.ts
545
+ ├── index.js
546
+ ├── index.min.d.ts
547
+ ├── index.min.js
548
+ ├── package.json
549
+ ├── tsconfig.json
550
+ └── README.md
551
+ ```
552
+
553
+ ## 📄 Licence
554
+
555
+ MIT License - Voir le fichier [LICENSE](LICENSE) pour plus de détails.
556
+
557
+ ## 🐛 Signaler un Bug
558
+
559
+ Envoyez nous un mail à l'adresse `contact.inicode@gmail.com` pour :
560
+ - Signaler un bug
561
+ - Proposer une amélioration
562
+ - Poser une question
563
+
564
+ ---
565
+
566
+ **@arc-js/pajo** - Manipulation de chemins multi-plateforme, simple et robuste.
567
+
568
+ *Développé par l'équipe INICODE*
package/index.ts ADDED
@@ -0,0 +1,294 @@
1
+ // @ts-nocheck
2
+
3
+ interface Window {
4
+ default: typeof defaultElementGF;
5
+ Pajo: any;
6
+ __bundledModules: any;
7
+ }
8
+
9
+ const globalFunct = (function(global: any) {
10
+ 'use strict';
11
+
12
+
13
+
14
+
15
+ class Pajo {
16
+ private static readonly PROTOCOL_REGEX = new RegExp('^[a-zA-Z]+://');
17
+ private static readonly DOUBLE_SLASH_REGEX = new RegExp('/+', 'g');
18
+ private static readonly DOUBLE_BACKSLASH_REGEX = new RegExp('\\\\+', 'g');
19
+ private static readonly TRAILING_SLASH_REGEX = new RegExp('/+$');
20
+ private static readonly TRAILING_BACKSLASH_REGEX = new RegExp('\\\\+$');
21
+ private static readonly LEADING_SLASH_REGEX = new RegExp('^/+');
22
+ private static readonly WINDOWS_DRIVE_REGEX = new RegExp('^[a-zA-Z]:\\\\');
23
+ private static readonly MIXED_SEPARATORS_REGEX = new RegExp('[\\\\/]+', 'g');
24
+
25
+ /**
26
+ * Joint plusieurs segments de chemin en normalisant les séparateurs
27
+ * @param paths Segments de chemin à joindre
28
+ * @returns Le chemin normalisé ou undefined si aucun chemin valide
29
+ */
30
+ static join(...paths: string[]): string | undefined {
31
+ if (paths.length === 0) return undefined;
32
+
33
+ // Détection du style de chemin (Windows ou Unix)
34
+ const isWindowsPath = paths.some(path => this.isWindowsPath(path));
35
+
36
+ // Filtre les chemins vides et nettoie chaque segment
37
+ const cleanPaths = paths
38
+ .filter(path => path != null && path.trim().length > 0)
39
+ .map(path => this.normalizePathSegment(path, isWindowsPath));
40
+
41
+ if (cleanPaths.length === 0) return undefined;
42
+
43
+ // Reconstruction du chemin final avec le séparateur approprié
44
+ const separator = isWindowsPath ? '\\' : '/';
45
+ let result = cleanPaths.join(separator);
46
+
47
+ if (isWindowsPath) {
48
+ result = result.replace(this.DOUBLE_BACKSLASH_REGEX, '\\');
49
+ } else {
50
+ result = result.replace(this.DOUBLE_SLASH_REGEX, '/');
51
+
52
+ // Préservation du slash initial pour les chemins absolus Linux
53
+ const hasLeadingSlash = paths[0]?.startsWith('/') || false;
54
+ if (hasLeadingSlash && !result.startsWith('/')) {
55
+ result = '/' + result;
56
+ }
57
+ }
58
+
59
+ return result || undefined;
60
+ }
61
+
62
+ /**
63
+ * Joint un hôte avec des segments de chemin
64
+ * @param host Hôte (peut inclure le protocole)
65
+ * @param paths Segments de chemin à joindre
66
+ * @returns L'URL complète normalisée ou undefined si invalide
67
+ */
68
+ static joinWithHost(host: string, ...paths: string[]): string | undefined {
69
+ if (!host || host.trim().length === 0) {
70
+ return this.join(...paths);
71
+ }
72
+
73
+ const cleanHost = host.trim().replace(this.TRAILING_SLASH_REGEX, '');
74
+
75
+ const hasProtocol = this.PROTOCOL_REGEX.test(cleanHost);
76
+ const normalizedHost = hasProtocol ? cleanHost : `https://${cleanHost}`;
77
+
78
+ const joinedPath = this.join(...paths);
79
+ if (!joinedPath) {
80
+ return normalizedHost;
81
+ }
82
+
83
+ const cleanPath = joinedPath.replace(new RegExp('\\\\', 'g'), '/').replace(this.LEADING_SLASH_REGEX, '');
84
+ return `${normalizedHost}/${cleanPath}`;
85
+ }
86
+
87
+ /**
88
+ * Normalise un segment de chemin individuel
89
+ * @param path Segment de chemin à normaliser
90
+ * @param isWindowsStyle Si on doit utiliser le style Windows
91
+ * @returns Le segment normalisé
92
+ */
93
+ private static normalizePathSegment(path: string, isWindowsStyle: boolean): string {
94
+ if (!path || path.trim().length === 0) return '';
95
+
96
+ const trimmed = path.trim();
97
+
98
+ if (isWindowsStyle) {
99
+ return trimmed
100
+ .replace(this.DOUBLE_BACKSLASH_REGEX, '\\')
101
+ .replace(this.TRAILING_BACKSLASH_REGEX, '');
102
+ } else {
103
+ return trimmed
104
+ .replace(this.DOUBLE_SLASH_REGEX, '/')
105
+ .replace(this.TRAILING_SLASH_REGEX, '');
106
+ }
107
+ }
108
+
109
+ private static isWindowsPath(path: string): boolean {
110
+ return this.WINDOWS_DRIVE_REGEX.test(path) || path.includes('\\');
111
+ }
112
+
113
+ /**
114
+ * Résout les chemins avec . et .. (simplifié)
115
+ * @param paths Segments de chemin à résoudre
116
+ * @returns Chemin résolu
117
+ */
118
+ static resolve(...paths: string[]): string | undefined {
119
+ const joined = this.join(...paths);
120
+ if (!joined) return undefined;
121
+
122
+ const isWindows = this.isWindowsPath(joined);
123
+ const separator = isWindows ? '\\' : '/';
124
+ const parts = joined.split(separator);
125
+ const resolved: string[] = [];
126
+
127
+ for (const part of parts) {
128
+ if (part === '..') {
129
+ if (resolved.length > 0 && resolved[resolved.length - 1] !== '..') {
130
+ resolved.pop();
131
+ } else {
132
+ resolved.push(part);
133
+ }
134
+ } else if (part !== '.' && part !== '') {
135
+ resolved.push(part);
136
+ }
137
+ }
138
+
139
+ let result = resolved.join(separator);
140
+
141
+ if (isWindows && this.WINDOWS_DRIVE_REGEX.test(parts[0])) {
142
+ result = parts[0] + separator + result;
143
+ }
144
+
145
+ return result;
146
+ }
147
+
148
+ static isAbsolute(path: string): boolean {
149
+ if (!path) return false;
150
+
151
+ return path.startsWith('/') ||
152
+ this.WINDOWS_DRIVE_REGEX.test(path) ||
153
+ this.PROTOCOL_REGEX.test(path);
154
+ }
155
+
156
+ static dirname(path: string): string | undefined {
157
+ if (!path) return undefined;
158
+
159
+ const isWindows = this.isWindowsPath(path);
160
+ const separator = isWindows ? '\\' : '/';
161
+ const normalized = this.normalizePathSegment(path, isWindows);
162
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
163
+
164
+ if (lastSeparatorIndex === -1) return isWindows ? '.' : '.';
165
+ if (lastSeparatorIndex === 0) return isWindows ? normalized.substring(0, 2) : '/';
166
+
167
+ return normalized.substring(0, lastSeparatorIndex) || (isWindows ? '.' : '/');
168
+ }
169
+
170
+ /**
171
+ * Extrait le nom de fichier d'un chemin
172
+ * @param path Chemin source
173
+ * @param ext Extension optionnelle à retirer
174
+ * @returns Le nom de fichier ou undefined
175
+ */
176
+ static basename(path: string, ext?: string): string | undefined {
177
+ if (!path) return undefined;
178
+
179
+ const isWindows = this.isWindowsPath(path);
180
+ const separator = isWindows ? '\\' : '/';
181
+ const normalized = this.normalizePathSegment(path, isWindows);
182
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
183
+ let basename = lastSeparatorIndex === -1 ? normalized : normalized.substring(lastSeparatorIndex + 1);
184
+
185
+ // Gestion de l'extension optionnelle
186
+ if (ext && basename.endsWith(ext)) {
187
+ basename = basename.substring(0, basename.length - ext.length);
188
+ }
189
+
190
+ return basename || undefined;
191
+ }
192
+
193
+ static extname(path: string): string | undefined {
194
+ if (!path) return undefined;
195
+
196
+ const basename = this.basename(path);
197
+ if (!basename) return undefined;
198
+
199
+ const lastDotIndex = basename.lastIndexOf('.');
200
+ return lastDotIndex > 0 ? basename.substring(lastDotIndex) : undefined;
201
+ }
202
+
203
+ static toUnixPath(path: string): string {
204
+ return path.replace(new RegExp('\\\\', 'g'), '/');
205
+ }
206
+
207
+ /**
208
+ * Convertit un chemin Unix en chemin Windows
209
+ * @param path Chemin Unix
210
+ * @returns Chemin Windows
211
+ */
212
+ static toWindowsPath(path: string): string {
213
+ return path.replace(new RegExp('/', 'g'), '\\\\');
214
+ }
215
+
216
+ static exposeToGlobal(): void {
217
+ if (typeof window !== "undefined") {
218
+ window.Pajo = Pajo;
219
+ }
220
+ }
221
+ }
222
+
223
+ if (typeof window !== "undefined") {
224
+ Pajo.exposeToGlobal();
225
+ }
226
+
227
+
228
+
229
+
230
+ const globalFunctModule = {
231
+ default: Pajo,
232
+ Pajo: Pajo,
233
+ };
234
+
235
+ globalFunctModule.default = {...(globalFunctModule?.default || {}), Pajo: Pajo};
236
+
237
+ const __bundledModules = globalFunctModule;
238
+
239
+ if (typeof global !== 'undefined') {
240
+ (global as any).default = Pajo;
241
+ (global as any).Pajo = Pajo;
242
+ (global as any).__bundledModules = __bundledModules;
243
+ }
244
+
245
+ if (typeof window !== "undefined") {
246
+ (window as any).default = Pajo;
247
+ (window as any).Pajo = Pajo;
248
+ (window as any).__bundledModules = __bundledModules;
249
+ }
250
+
251
+ if (typeof module !== 'undefined' && module.exports) {
252
+ module.exports = __bundledModules;
253
+ module.exports.default = Pajo;
254
+ module.exports.Pajo = Pajo;
255
+ }
256
+
257
+ if (typeof exports !== 'undefined') {
258
+ exports.default = Pajo;
259
+ exports.Pajo = Pajo;
260
+ }
261
+ return __bundledModules;
262
+
263
+ })(typeof global !== 'undefined' ? global :
264
+ typeof window !== 'undefined' ? window :
265
+ typeof self !== 'undefined' ? self :
266
+ typeof globalThis !== 'undefined' ? globalThis :
267
+ {});
268
+
269
+ type PajoElementTypeGF = typeof globalFunct.Pajo;
270
+
271
+ type DefaultElementTypeGF = typeof globalFunct.default;
272
+
273
+ const PajoElementGF: PajoElementTypeGF = globalFunct.Pajo;
274
+
275
+ const defaultElementGF: DefaultElementTypeGF = globalFunct.default;
276
+
277
+ export {
278
+ PajoElementGF as Pajo,
279
+ };
280
+
281
+ export default defaultElementGF;
282
+ if (typeof module !== 'undefined' && module.exports) {
283
+ module.exports = {
284
+ Pajo: PajoElementGF,
285
+ };
286
+ }
287
+
288
+ if (typeof module !== 'undefined' && module.exports) {
289
+ module.exports.default = globalFunct?.default;
290
+ }
291
+
292
+ export type { PajoElementTypeGF };
293
+
294
+ export type { DefaultElementTypeGF };
package/js/index.js ADDED
@@ -0,0 +1,231 @@
1
+ const globalFunct = (function (global) {
2
+ 'use strict';
3
+ class Pajo {
4
+ static PROTOCOL_REGEX = new RegExp('^[a-zA-Z]+://');
5
+ static DOUBLE_SLASH_REGEX = new RegExp('/+', 'g');
6
+ static DOUBLE_BACKSLASH_REGEX = new RegExp('\\\\+', 'g');
7
+ static TRAILING_SLASH_REGEX = new RegExp('/+$');
8
+ static TRAILING_BACKSLASH_REGEX = new RegExp('\\\\+$');
9
+ static LEADING_SLASH_REGEX = new RegExp('^/+');
10
+ static WINDOWS_DRIVE_REGEX = new RegExp('^[a-zA-Z]:\\\\');
11
+ static MIXED_SEPARATORS_REGEX = new RegExp('[\\\\/]+', 'g');
12
+ /**
13
+ * Joint plusieurs segments de chemin en normalisant les séparateurs
14
+ * @param paths Segments de chemin à joindre
15
+ * @returns Le chemin normalisé ou undefined si aucun chemin valide
16
+ */
17
+ static join(...paths) {
18
+ if (paths.length === 0)
19
+ return undefined;
20
+ // Détection du style de chemin (Windows ou Unix)
21
+ const isWindowsPath = paths.some(path => this.isWindowsPath(path));
22
+ // Filtre les chemins vides et nettoie chaque segment
23
+ const cleanPaths = paths
24
+ .filter(path => path != null && path.trim().length > 0)
25
+ .map(path => this.normalizePathSegment(path, isWindowsPath));
26
+ if (cleanPaths.length === 0)
27
+ return undefined;
28
+ // Reconstruction du chemin final avec le séparateur approprié
29
+ const separator = isWindowsPath ? '\\' : '/';
30
+ let result = cleanPaths.join(separator);
31
+ if (isWindowsPath) {
32
+ result = result.replace(this.DOUBLE_BACKSLASH_REGEX, '\\');
33
+ }
34
+ else {
35
+ result = result.replace(this.DOUBLE_SLASH_REGEX, '/');
36
+ // Préservation du slash initial pour les chemins absolus Linux
37
+ const hasLeadingSlash = paths[0]?.startsWith('/') || false;
38
+ if (hasLeadingSlash && !result.startsWith('/')) {
39
+ result = '/' + result;
40
+ }
41
+ }
42
+ return result || undefined;
43
+ }
44
+ /**
45
+ * Joint un hôte avec des segments de chemin
46
+ * @param host Hôte (peut inclure le protocole)
47
+ * @param paths Segments de chemin à joindre
48
+ * @returns L'URL complète normalisée ou undefined si invalide
49
+ */
50
+ static joinWithHost(host, ...paths) {
51
+ if (!host || host.trim().length === 0) {
52
+ return this.join(...paths);
53
+ }
54
+ const cleanHost = host.trim().replace(this.TRAILING_SLASH_REGEX, '');
55
+ const hasProtocol = this.PROTOCOL_REGEX.test(cleanHost);
56
+ const normalizedHost = hasProtocol ? cleanHost : `https://${cleanHost}`;
57
+ const joinedPath = this.join(...paths);
58
+ if (!joinedPath) {
59
+ return normalizedHost;
60
+ }
61
+ const cleanPath = joinedPath.replace(new RegExp('\\\\', 'g'), '/').replace(this.LEADING_SLASH_REGEX, '');
62
+ return `${normalizedHost}/${cleanPath}`;
63
+ }
64
+ /**
65
+ * Normalise un segment de chemin individuel
66
+ * @param path Segment de chemin à normaliser
67
+ * @param isWindowsStyle Si on doit utiliser le style Windows
68
+ * @returns Le segment normalisé
69
+ */
70
+ static normalizePathSegment(path, isWindowsStyle) {
71
+ if (!path || path.trim().length === 0)
72
+ return '';
73
+ const trimmed = path.trim();
74
+ if (isWindowsStyle) {
75
+ return trimmed
76
+ .replace(this.DOUBLE_BACKSLASH_REGEX, '\\')
77
+ .replace(this.TRAILING_BACKSLASH_REGEX, '');
78
+ }
79
+ else {
80
+ return trimmed
81
+ .replace(this.DOUBLE_SLASH_REGEX, '/')
82
+ .replace(this.TRAILING_SLASH_REGEX, '');
83
+ }
84
+ }
85
+ static isWindowsPath(path) {
86
+ return this.WINDOWS_DRIVE_REGEX.test(path) || path.includes('\\');
87
+ }
88
+ /**
89
+ * Résout les chemins avec . et .. (simplifié)
90
+ * @param paths Segments de chemin à résoudre
91
+ * @returns Chemin résolu
92
+ */
93
+ static resolve(...paths) {
94
+ const joined = this.join(...paths);
95
+ if (!joined)
96
+ return undefined;
97
+ const isWindows = this.isWindowsPath(joined);
98
+ const separator = isWindows ? '\\' : '/';
99
+ const parts = joined.split(separator);
100
+ const resolved = [];
101
+ for (const part of parts) {
102
+ if (part === '..') {
103
+ if (resolved.length > 0 && resolved[resolved.length - 1] !== '..') {
104
+ resolved.pop();
105
+ }
106
+ else {
107
+ resolved.push(part);
108
+ }
109
+ }
110
+ else if (part !== '.' && part !== '') {
111
+ resolved.push(part);
112
+ }
113
+ }
114
+ let result = resolved.join(separator);
115
+ if (isWindows && this.WINDOWS_DRIVE_REGEX.test(parts[0])) {
116
+ result = parts[0] + separator + result;
117
+ }
118
+ return result;
119
+ }
120
+ static isAbsolute(path) {
121
+ if (!path)
122
+ return false;
123
+ return path.startsWith('/') ||
124
+ this.WINDOWS_DRIVE_REGEX.test(path) ||
125
+ this.PROTOCOL_REGEX.test(path);
126
+ }
127
+ static dirname(path) {
128
+ if (!path)
129
+ return undefined;
130
+ const isWindows = this.isWindowsPath(path);
131
+ const separator = isWindows ? '\\' : '/';
132
+ const normalized = this.normalizePathSegment(path, isWindows);
133
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
134
+ if (lastSeparatorIndex === -1)
135
+ return isWindows ? '.' : '.';
136
+ if (lastSeparatorIndex === 0)
137
+ return isWindows ? normalized.substring(0, 2) : '/';
138
+ return normalized.substring(0, lastSeparatorIndex) || (isWindows ? '.' : '/');
139
+ }
140
+ /**
141
+ * Extrait le nom de fichier d'un chemin
142
+ * @param path Chemin source
143
+ * @param ext Extension optionnelle à retirer
144
+ * @returns Le nom de fichier ou undefined
145
+ */
146
+ static basename(path, ext) {
147
+ if (!path)
148
+ return undefined;
149
+ const isWindows = this.isWindowsPath(path);
150
+ const separator = isWindows ? '\\' : '/';
151
+ const normalized = this.normalizePathSegment(path, isWindows);
152
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
153
+ let basename = lastSeparatorIndex === -1 ? normalized : normalized.substring(lastSeparatorIndex + 1);
154
+ // Gestion de l'extension optionnelle
155
+ if (ext && basename.endsWith(ext)) {
156
+ basename = basename.substring(0, basename.length - ext.length);
157
+ }
158
+ return basename || undefined;
159
+ }
160
+ static extname(path) {
161
+ if (!path)
162
+ return undefined;
163
+ const basename = this.basename(path);
164
+ if (!basename)
165
+ return undefined;
166
+ const lastDotIndex = basename.lastIndexOf('.');
167
+ return lastDotIndex > 0 ? basename.substring(lastDotIndex) : undefined;
168
+ }
169
+ static toUnixPath(path) {
170
+ return path.replace(new RegExp('\\\\', 'g'), '/');
171
+ }
172
+ /**
173
+ * Convertit un chemin Unix en chemin Windows
174
+ * @param path Chemin Unix
175
+ * @returns Chemin Windows
176
+ */
177
+ static toWindowsPath(path) {
178
+ return path.replace(new RegExp('/', 'g'), '\\\\');
179
+ }
180
+ static exposeToGlobal() {
181
+ if (typeof window !== "undefined") {
182
+ window.Pajo = Pajo;
183
+ }
184
+ }
185
+ }
186
+ if (typeof window !== "undefined") {
187
+ Pajo.exposeToGlobal();
188
+ }
189
+ const globalFunctModule = {
190
+ default: Pajo,
191
+ Pajo: Pajo,
192
+ };
193
+ globalFunctModule.default = { ...(globalFunctModule?.default || {}), Pajo: Pajo };
194
+ const __bundledModules = globalFunctModule;
195
+ if (typeof global !== 'undefined') {
196
+ global.default = Pajo;
197
+ global.Pajo = Pajo;
198
+ global.__bundledModules = __bundledModules;
199
+ }
200
+ if (typeof window !== "undefined") {
201
+ window.default = Pajo;
202
+ window.Pajo = Pajo;
203
+ window.__bundledModules = __bundledModules;
204
+ }
205
+ if (typeof module !== 'undefined' && module.exports) {
206
+ module.exports = __bundledModules;
207
+ module.exports.default = Pajo;
208
+ module.exports.Pajo = Pajo;
209
+ }
210
+ if (typeof exports !== 'undefined') {
211
+ exports.default = Pajo;
212
+ exports.Pajo = Pajo;
213
+ }
214
+ return __bundledModules;
215
+ })(typeof global !== 'undefined' ? global :
216
+ typeof window !== 'undefined' ? window :
217
+ typeof self !== 'undefined' ? self :
218
+ typeof globalThis !== 'undefined' ? globalThis :
219
+ {});
220
+ const PajoElementGF = globalFunct.Pajo;
221
+ const defaultElementGF = globalFunct.default;
222
+ export { PajoElementGF as Pajo, };
223
+ export default defaultElementGF;
224
+ if (typeof module !== 'undefined' && module.exports) {
225
+ module.exports = {
226
+ Pajo: PajoElementGF,
227
+ };
228
+ }
229
+ if (typeof module !== 'undefined' && module.exports) {
230
+ module.exports.default = globalFunct?.default;
231
+ }
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@arc-js/pajo",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "0.0.0",
7
+ "description": "Pajo est une bibliothèque TypeScript légère et robuste pour la manipulation de chemins de fichiers et d'URLs. Elle offre une API unifiée et type-safe pour travailler avec des chemins de fichiers sur différentes plateformes (Windows, Linux, macOS) et pour construire des URLs de manière cohérente.",
8
+ "main": "index.js",
9
+ "keywords": [],
10
+ "author": "INICODE <contact.inicode@gmail.com>",
11
+ "license": "MIT",
12
+ "scripts": {
13
+ "init": "npm init --scope=@arc-js/pajo",
14
+ "login": "npm login"
15
+ },
16
+ "devDependencies": {},
17
+ "dependencies": {}
18
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES6",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable", "ESNext"],
6
+ "esModuleInterop": true,
7
+ "skipLibCheck": true,
8
+ "declaration": false,
9
+ "sourceMap": false,
10
+ "allowSyntheticDefaultImports": true,
11
+ "noEmit": false,
12
+
13
+ "strict": false,
14
+ "noImplicitAny": false,
15
+ "strictNullChecks": false,
16
+ "strictFunctionTypes": false,
17
+ "strictBindCallApply": false,
18
+ "strictPropertyInitialization": false,
19
+ "noImplicitThis": false,
20
+ "alwaysStrict": false
21
+ },
22
+ "include": [],
23
+ "exclude": [
24
+ "node_modules",
25
+ "**/*.d.ts"
26
+ ]
27
+ }
package/web/pajo.js ADDED
@@ -0,0 +1,229 @@
1
+ const globalFunct = (function (global) {
2
+ 'use strict';
3
+ class Pajo {
4
+ static PROTOCOL_REGEX = new RegExp('^[a-zA-Z]+://');
5
+ static DOUBLE_SLASH_REGEX = new RegExp('/+', 'g');
6
+ static DOUBLE_BACKSLASH_REGEX = new RegExp('\\\\+', 'g');
7
+ static TRAILING_SLASH_REGEX = new RegExp('/+$');
8
+ static TRAILING_BACKSLASH_REGEX = new RegExp('\\\\+$');
9
+ static LEADING_SLASH_REGEX = new RegExp('^/+');
10
+ static WINDOWS_DRIVE_REGEX = new RegExp('^[a-zA-Z]:\\\\');
11
+ static MIXED_SEPARATORS_REGEX = new RegExp('[\\\\/]+', 'g');
12
+ /**
13
+ * Joint plusieurs segments de chemin en normalisant les séparateurs
14
+ * @param paths Segments de chemin à joindre
15
+ * @returns Le chemin normalisé ou undefined si aucun chemin valide
16
+ */
17
+ static join(...paths) {
18
+ if (paths.length === 0)
19
+ return undefined;
20
+ // Détection du style de chemin (Windows ou Unix)
21
+ const isWindowsPath = paths.some(path => this.isWindowsPath(path));
22
+ // Filtre les chemins vides et nettoie chaque segment
23
+ const cleanPaths = paths
24
+ .filter(path => path != null && path.trim().length > 0)
25
+ .map(path => this.normalizePathSegment(path, isWindowsPath));
26
+ if (cleanPaths.length === 0)
27
+ return undefined;
28
+ // Reconstruction du chemin final avec le séparateur approprié
29
+ const separator = isWindowsPath ? '\\' : '/';
30
+ let result = cleanPaths.join(separator);
31
+ if (isWindowsPath) {
32
+ result = result.replace(this.DOUBLE_BACKSLASH_REGEX, '\\');
33
+ }
34
+ else {
35
+ result = result.replace(this.DOUBLE_SLASH_REGEX, '/');
36
+ // Préservation du slash initial pour les chemins absolus Linux
37
+ const hasLeadingSlash = paths[0]?.startsWith('/') || false;
38
+ if (hasLeadingSlash && !result.startsWith('/')) {
39
+ result = '/' + result;
40
+ }
41
+ }
42
+ return result || undefined;
43
+ }
44
+ /**
45
+ * Joint un hôte avec des segments de chemin
46
+ * @param host Hôte (peut inclure le protocole)
47
+ * @param paths Segments de chemin à joindre
48
+ * @returns L'URL complète normalisée ou undefined si invalide
49
+ */
50
+ static joinWithHost(host, ...paths) {
51
+ if (!host || host.trim().length === 0) {
52
+ return this.join(...paths);
53
+ }
54
+ const cleanHost = host.trim().replace(this.TRAILING_SLASH_REGEX, '');
55
+ const hasProtocol = this.PROTOCOL_REGEX.test(cleanHost);
56
+ const normalizedHost = hasProtocol ? cleanHost : `https://${cleanHost}`;
57
+ const joinedPath = this.join(...paths);
58
+ if (!joinedPath) {
59
+ return normalizedHost;
60
+ }
61
+ const cleanPath = joinedPath.replace(new RegExp('\\\\', 'g'), '/').replace(this.LEADING_SLASH_REGEX, '');
62
+ return `${normalizedHost}/${cleanPath}`;
63
+ }
64
+ /**
65
+ * Normalise un segment de chemin individuel
66
+ * @param path Segment de chemin à normaliser
67
+ * @param isWindowsStyle Si on doit utiliser le style Windows
68
+ * @returns Le segment normalisé
69
+ */
70
+ static normalizePathSegment(path, isWindowsStyle) {
71
+ if (!path || path.trim().length === 0)
72
+ return '';
73
+ const trimmed = path.trim();
74
+ if (isWindowsStyle) {
75
+ return trimmed
76
+ .replace(this.DOUBLE_BACKSLASH_REGEX, '\\')
77
+ .replace(this.TRAILING_BACKSLASH_REGEX, '');
78
+ }
79
+ else {
80
+ return trimmed
81
+ .replace(this.DOUBLE_SLASH_REGEX, '/')
82
+ .replace(this.TRAILING_SLASH_REGEX, '');
83
+ }
84
+ }
85
+ static isWindowsPath(path) {
86
+ return this.WINDOWS_DRIVE_REGEX.test(path) || path.includes('\\');
87
+ }
88
+ /**
89
+ * Résout les chemins avec . et .. (simplifié)
90
+ * @param paths Segments de chemin à résoudre
91
+ * @returns Chemin résolu
92
+ */
93
+ static resolve(...paths) {
94
+ const joined = this.join(...paths);
95
+ if (!joined)
96
+ return undefined;
97
+ const isWindows = this.isWindowsPath(joined);
98
+ const separator = isWindows ? '\\' : '/';
99
+ const parts = joined.split(separator);
100
+ const resolved = [];
101
+ for (const part of parts) {
102
+ if (part === '..') {
103
+ if (resolved.length > 0 && resolved[resolved.length - 1] !== '..') {
104
+ resolved.pop();
105
+ }
106
+ else {
107
+ resolved.push(part);
108
+ }
109
+ }
110
+ else if (part !== '.' && part !== '') {
111
+ resolved.push(part);
112
+ }
113
+ }
114
+ let result = resolved.join(separator);
115
+ if (isWindows && this.WINDOWS_DRIVE_REGEX.test(parts[0])) {
116
+ result = parts[0] + separator + result;
117
+ }
118
+ return result;
119
+ }
120
+ static isAbsolute(path) {
121
+ if (!path)
122
+ return false;
123
+ return path.startsWith('/') ||
124
+ this.WINDOWS_DRIVE_REGEX.test(path) ||
125
+ this.PROTOCOL_REGEX.test(path);
126
+ }
127
+ static dirname(path) {
128
+ if (!path)
129
+ return undefined;
130
+ const isWindows = this.isWindowsPath(path);
131
+ const separator = isWindows ? '\\' : '/';
132
+ const normalized = this.normalizePathSegment(path, isWindows);
133
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
134
+ if (lastSeparatorIndex === -1)
135
+ return isWindows ? '.' : '.';
136
+ if (lastSeparatorIndex === 0)
137
+ return isWindows ? normalized.substring(0, 2) : '/';
138
+ return normalized.substring(0, lastSeparatorIndex) || (isWindows ? '.' : '/');
139
+ }
140
+ /**
141
+ * Extrait le nom de fichier d'un chemin
142
+ * @param path Chemin source
143
+ * @param ext Extension optionnelle à retirer
144
+ * @returns Le nom de fichier ou undefined
145
+ */
146
+ static basename(path, ext) {
147
+ if (!path)
148
+ return undefined;
149
+ const isWindows = this.isWindowsPath(path);
150
+ const separator = isWindows ? '\\' : '/';
151
+ const normalized = this.normalizePathSegment(path, isWindows);
152
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
153
+ let basename = lastSeparatorIndex === -1 ? normalized : normalized.substring(lastSeparatorIndex + 1);
154
+ // Gestion de l'extension optionnelle
155
+ if (ext && basename.endsWith(ext)) {
156
+ basename = basename.substring(0, basename.length - ext.length);
157
+ }
158
+ return basename || undefined;
159
+ }
160
+ static extname(path) {
161
+ if (!path)
162
+ return undefined;
163
+ const basename = this.basename(path);
164
+ if (!basename)
165
+ return undefined;
166
+ const lastDotIndex = basename.lastIndexOf('.');
167
+ return lastDotIndex > 0 ? basename.substring(lastDotIndex) : undefined;
168
+ }
169
+ static toUnixPath(path) {
170
+ return path.replace(new RegExp('\\\\', 'g'), '/');
171
+ }
172
+ /**
173
+ * Convertit un chemin Unix en chemin Windows
174
+ * @param path Chemin Unix
175
+ * @returns Chemin Windows
176
+ */
177
+ static toWindowsPath(path) {
178
+ return path.replace(new RegExp('/', 'g'), '\\\\');
179
+ }
180
+ static exposeToGlobal() {
181
+ if (typeof window !== "undefined") {
182
+ window.Pajo = Pajo;
183
+ }
184
+ }
185
+ }
186
+ if (typeof window !== "undefined") {
187
+ Pajo.exposeToGlobal();
188
+ }
189
+ const globalFunctModule = {
190
+ default: Pajo,
191
+ Pajo: Pajo,
192
+ };
193
+ globalFunctModule.default = { ...(globalFunctModule?.default || {}), Pajo: Pajo };
194
+ const __bundledModules = globalFunctModule;
195
+ if (typeof global !== 'undefined') {
196
+ global.default = Pajo;
197
+ global.Pajo = Pajo;
198
+ global.__bundledModules = __bundledModules;
199
+ }
200
+ if (typeof window !== "undefined") {
201
+ window.default = Pajo;
202
+ window.Pajo = Pajo;
203
+ window.__bundledModules = __bundledModules;
204
+ }
205
+ if (typeof module !== 'undefined' && module.exports) {
206
+ module.exports = __bundledModules;
207
+ module.exports.default = Pajo;
208
+ module.exports.Pajo = Pajo;
209
+ }
210
+ if (typeof exports !== 'undefined') {
211
+ exports.default = Pajo;
212
+ exports.Pajo = Pajo;
213
+ }
214
+ return __bundledModules;
215
+ })(typeof global !== 'undefined' ? global :
216
+ typeof window !== 'undefined' ? window :
217
+ typeof self !== 'undefined' ? self :
218
+ typeof globalThis !== 'undefined' ? globalThis :
219
+ {});
220
+ const PajoElementGF = globalFunct.Pajo;
221
+ const defaultElementGF = globalFunct.default;
222
+ if (typeof module !== 'undefined' && module.exports) {
223
+ module.exports = {
224
+ Pajo: PajoElementGF,
225
+ };
226
+ }
227
+ if (typeof module !== 'undefined' && module.exports) {
228
+ module.exports.default = globalFunct?.default;
229
+ }
@@ -0,0 +1 @@
1
+ let globalFunct=(t=>{class e{static PROTOCOL_REGEX=new RegExp("^[a-zA-Z]+://");static DOUBLE_SLASH_REGEX=new RegExp("/+","g");static DOUBLE_BACKSLASH_REGEX=new RegExp("\\\\+","g");static TRAILING_SLASH_REGEX=new RegExp("/+$");static TRAILING_BACKSLASH_REGEX=new RegExp("\\\\+$");static LEADING_SLASH_REGEX=new RegExp("^/+");static WINDOWS_DRIVE_REGEX=new RegExp("^[a-zA-Z]:\\\\");static MIXED_SEPARATORS_REGEX=new RegExp("[\\\\/]+","g");static join(...i){if(0!==i.length){let e=i.some(t=>this.isWindowsPath(t));var s=i.filter(t=>null!=t&&0<t.trim().length).map(t=>this.normalizePathSegment(t,e));if(0!==s.length){var n=e?"\\":"/";let t=s.join(n);return e?t=t.replace(this.DOUBLE_BACKSLASH_REGEX,"\\"):(t=t.replace(this.DOUBLE_SLASH_REGEX,"/"),i[0]?.startsWith("/")&&!t.startsWith("/")&&(t="/"+t)),t||void 0}}}static joinWithHost(t,...e){var i;return t&&0!==t.trim().length?(t=t.trim().replace(this.TRAILING_SLASH_REGEX,""),t=this.PROTOCOL_REGEX.test(t)?t:"https: