@arc-js/pajo 0.0.1

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.d.ts ADDED
@@ -0,0 +1,90 @@
1
+ declare global {
2
+ interface Window {
3
+ Pajo: typeof Pajo;
4
+ }
5
+ }
6
+ declare class Pajo {
7
+ private static readonly PROTOCOL_REGEX;
8
+ private static readonly DOUBLE_SLASH_REGEX;
9
+ private static readonly DOUBLE_BACKSLASH_REGEX;
10
+ private static readonly TRAILING_SLASH_REGEX;
11
+ private static readonly TRAILING_BACKSLASH_REGEX;
12
+ private static readonly LEADING_SLASH_REGEX;
13
+ private static readonly WINDOWS_DRIVE_REGEX;
14
+ private static readonly MIXED_SEPARATORS_REGEX;
15
+ /**
16
+ * Joint plusieurs segments de chemin en normalisant les séparateurs
17
+ * @param paths Segments de chemin à joindre
18
+ * @returns Le chemin normalisé ou undefined si aucun chemin valide
19
+ */
20
+ static join(...paths: string[]): string | undefined;
21
+ /**
22
+ * Joint un hôte avec des segments de chemin
23
+ * @param host Hôte (peut inclure le protocole)
24
+ * @param paths Segments de chemin à joindre
25
+ * @returns L'URL complète normalisée ou undefined si invalide
26
+ */
27
+ static joinWithHost(host: string, ...paths: string[]): string | undefined;
28
+ /**
29
+ * Normalise un segment de chemin individuel
30
+ * @param path Segment de chemin à normaliser
31
+ * @param isWindowsStyle Si on doit utiliser le style Windows
32
+ * @returns Le segment normalisé
33
+ */
34
+ private static normalizePathSegment;
35
+ /**
36
+ * Vérifie si le chemin est un chemin Windows
37
+ * @param path Chemin à vérifier
38
+ * @returns True si c'est un chemin Windows
39
+ */
40
+ private static isWindowsPath;
41
+ /**
42
+ * Résout les chemins avec . et .. (simplifié)
43
+ * @param paths Segments de chemin à résoudre
44
+ * @returns Chemin résolu
45
+ */
46
+ static resolve(...paths: string[]): string | undefined;
47
+ /**
48
+ * Vérifie si un chemin est absolu
49
+ * @param path Chemin à vérifier
50
+ * @returns True si le chemin est absolu
51
+ */
52
+ static isAbsolute(path: string): boolean;
53
+ /**
54
+ * Extrait le répertoire parent d'un chemin
55
+ * @param path Chemin source
56
+ * @returns Le répertoire parent ou undefined
57
+ */
58
+ static dirname(path: string): string | undefined;
59
+ /**
60
+ * Extrait le nom de fichier d'un chemin
61
+ * @param path Chemin source
62
+ * @param ext Extension optionnelle à retirer
63
+ * @returns Le nom de fichier ou undefined
64
+ */
65
+ static basename(path: string, ext?: string): string | undefined;
66
+ /**
67
+ * Extrait l'extension d'un fichier
68
+ * @param path Chemin source
69
+ * @returns L'extension ou undefined
70
+ */
71
+ static extname(path: string): string | undefined;
72
+ /**
73
+ * Convertit un chemin Windows en chemin Unix
74
+ * @param path Chemin Windows
75
+ * @returns Chemin Unix
76
+ */
77
+ static toUnixPath(path: string): string;
78
+ /**
79
+ * Convertit un chemin Unix en chemin Windows
80
+ * @param path Chemin Unix
81
+ * @returns Chemin Windows
82
+ */
83
+ static toWindowsPath(path: string): string;
84
+ /**
85
+ * Exposition globale de la classe
86
+ */
87
+ static exposeToGlobal(): void;
88
+ }
89
+
90
+ export { Pajo, Pajo as default };
package/index.js ADDED
@@ -0,0 +1,150 @@
1
+ class Pajo {
2
+ static PROTOCOL_REGEX = /^[a-zA-Z]+:\/\//;
3
+ static DOUBLE_SLASH_REGEX = /\/+/g;
4
+ static DOUBLE_BACKSLASH_REGEX = /\\+/g;
5
+ static TRAILING_SLASH_REGEX = /\/+$/;
6
+ static TRAILING_BACKSLASH_REGEX = /\\+$/;
7
+ static LEADING_SLASH_REGEX = /^\/+/;
8
+ static WINDOWS_DRIVE_REGEX = /^[a-zA-Z]:\\/;
9
+ static MIXED_SEPARATORS_REGEX = /[\\/]+/g;
10
+ static join(...paths) {
11
+ if (paths.length === 0)
12
+ return undefined;
13
+ const isWindowsPath = paths.some(path => this.isWindowsPath(path));
14
+ const cleanPaths = paths
15
+ .filter(path => path != null && path.trim().length > 0)
16
+ .map(path => this.normalizePathSegment(path, isWindowsPath));
17
+ if (cleanPaths.length === 0)
18
+ return undefined;
19
+ const separator = isWindowsPath ? '\\' : '/';
20
+ let result = cleanPaths.join(separator);
21
+ if (isWindowsPath) {
22
+ result = result.replace(this.DOUBLE_BACKSLASH_REGEX, '\\');
23
+ }
24
+ else {
25
+ result = result.replace(this.DOUBLE_SLASH_REGEX, '/');
26
+ const hasLeadingSlash = paths[0]?.startsWith('/') || false;
27
+ if (hasLeadingSlash && !result.startsWith('/')) {
28
+ result = '/' + result;
29
+ }
30
+ }
31
+ return result || undefined;
32
+ }
33
+ static joinWithHost(host, ...paths) {
34
+ if (!host || host.trim().length === 0) {
35
+ return this.join(...paths);
36
+ }
37
+ const cleanHost = host.trim().replace(this.TRAILING_SLASH_REGEX, '');
38
+ const hasProtocol = this.PROTOCOL_REGEX.test(cleanHost);
39
+ const normalizedHost = hasProtocol ? cleanHost : `https://${cleanHost}`;
40
+ const joinedPath = this.join(...paths);
41
+ if (!joinedPath) {
42
+ return normalizedHost;
43
+ }
44
+ const cleanPath = joinedPath.replace(/\\/g, '/').replace(this.LEADING_SLASH_REGEX, '');
45
+ return `${normalizedHost}/${cleanPath}`;
46
+ }
47
+ static normalizePathSegment(path, isWindowsStyle) {
48
+ if (!path || path.trim().length === 0)
49
+ return '';
50
+ const trimmed = path.trim();
51
+ if (isWindowsStyle) {
52
+ return trimmed
53
+ .replace(this.DOUBLE_BACKSLASH_REGEX, '\\')
54
+ .replace(this.TRAILING_BACKSLASH_REGEX, '');
55
+ }
56
+ else {
57
+ return trimmed
58
+ .replace(this.DOUBLE_SLASH_REGEX, '/')
59
+ .replace(this.TRAILING_SLASH_REGEX, '');
60
+ }
61
+ }
62
+ static isWindowsPath(path) {
63
+ return this.WINDOWS_DRIVE_REGEX.test(path) || path.includes('\\');
64
+ }
65
+ static resolve(...paths) {
66
+ const joined = this.join(...paths);
67
+ if (!joined)
68
+ return undefined;
69
+ const isWindows = this.isWindowsPath(joined);
70
+ const separator = isWindows ? '\\' : '/';
71
+ const parts = joined.split(separator);
72
+ const resolved = [];
73
+ for (const part of parts) {
74
+ if (part === '..') {
75
+ if (resolved.length > 0 && resolved[resolved.length - 1] !== '..') {
76
+ resolved.pop();
77
+ }
78
+ else {
79
+ resolved.push(part);
80
+ }
81
+ }
82
+ else if (part !== '.' && part !== '') {
83
+ resolved.push(part);
84
+ }
85
+ }
86
+ let result = resolved.join(separator);
87
+ if (isWindows && this.WINDOWS_DRIVE_REGEX.test(parts[0])) {
88
+ result = parts[0] + separator + result;
89
+ }
90
+ return result;
91
+ }
92
+ static isAbsolute(path) {
93
+ if (!path)
94
+ return false;
95
+ return path.startsWith('/') ||
96
+ this.WINDOWS_DRIVE_REGEX.test(path) ||
97
+ this.PROTOCOL_REGEX.test(path);
98
+ }
99
+ static dirname(path) {
100
+ if (!path)
101
+ return undefined;
102
+ const isWindows = this.isWindowsPath(path);
103
+ const separator = isWindows ? '\\' : '/';
104
+ const normalized = this.normalizePathSegment(path, isWindows);
105
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
106
+ if (lastSeparatorIndex === -1)
107
+ return isWindows ? '.' : '.';
108
+ if (lastSeparatorIndex === 0)
109
+ return isWindows ? normalized.substring(0, 2) : '/';
110
+ return normalized.substring(0, lastSeparatorIndex) || (isWindows ? '.' : '/');
111
+ }
112
+ static basename(path, ext) {
113
+ if (!path)
114
+ return undefined;
115
+ const isWindows = this.isWindowsPath(path);
116
+ const separator = isWindows ? '\\' : '/';
117
+ const normalized = this.normalizePathSegment(path, isWindows);
118
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
119
+ let basename = lastSeparatorIndex === -1 ? normalized : normalized.substring(lastSeparatorIndex + 1);
120
+ if (ext && basename.endsWith(ext)) {
121
+ basename = basename.substring(0, basename.length - ext.length);
122
+ }
123
+ return basename || undefined;
124
+ }
125
+ static extname(path) {
126
+ if (!path)
127
+ return undefined;
128
+ const basename = this.basename(path);
129
+ if (!basename)
130
+ return undefined;
131
+ const lastDotIndex = basename.lastIndexOf('.');
132
+ return lastDotIndex > 0 ? basename.substring(lastDotIndex) : undefined;
133
+ }
134
+ static toUnixPath(path) {
135
+ return path.replace(/\\/g, '/');
136
+ }
137
+ static toWindowsPath(path) {
138
+ return path.replace(/\//g, '\\');
139
+ }
140
+ static exposeToGlobal() {
141
+ if (typeof window !== "undefined") {
142
+ window.Pajo = Pajo;
143
+ }
144
+ }
145
+ }
146
+ if (typeof window !== "undefined") {
147
+ Pajo.exposeToGlobal();
148
+ }
149
+
150
+ export { Pajo, Pajo as default };
package/index.min.d.ts ADDED
@@ -0,0 +1,90 @@
1
+ declare global {
2
+ interface Window {
3
+ Pajo: typeof Pajo;
4
+ }
5
+ }
6
+ declare class Pajo {
7
+ private static readonly PROTOCOL_REGEX;
8
+ private static readonly DOUBLE_SLASH_REGEX;
9
+ private static readonly DOUBLE_BACKSLASH_REGEX;
10
+ private static readonly TRAILING_SLASH_REGEX;
11
+ private static readonly TRAILING_BACKSLASH_REGEX;
12
+ private static readonly LEADING_SLASH_REGEX;
13
+ private static readonly WINDOWS_DRIVE_REGEX;
14
+ private static readonly MIXED_SEPARATORS_REGEX;
15
+ /**
16
+ * Joint plusieurs segments de chemin en normalisant les séparateurs
17
+ * @param paths Segments de chemin à joindre
18
+ * @returns Le chemin normalisé ou undefined si aucun chemin valide
19
+ */
20
+ static join(...paths: string[]): string | undefined;
21
+ /**
22
+ * Joint un hôte avec des segments de chemin
23
+ * @param host Hôte (peut inclure le protocole)
24
+ * @param paths Segments de chemin à joindre
25
+ * @returns L'URL complète normalisée ou undefined si invalide
26
+ */
27
+ static joinWithHost(host: string, ...paths: string[]): string | undefined;
28
+ /**
29
+ * Normalise un segment de chemin individuel
30
+ * @param path Segment de chemin à normaliser
31
+ * @param isWindowsStyle Si on doit utiliser le style Windows
32
+ * @returns Le segment normalisé
33
+ */
34
+ private static normalizePathSegment;
35
+ /**
36
+ * Vérifie si le chemin est un chemin Windows
37
+ * @param path Chemin à vérifier
38
+ * @returns True si c'est un chemin Windows
39
+ */
40
+ private static isWindowsPath;
41
+ /**
42
+ * Résout les chemins avec . et .. (simplifié)
43
+ * @param paths Segments de chemin à résoudre
44
+ * @returns Chemin résolu
45
+ */
46
+ static resolve(...paths: string[]): string | undefined;
47
+ /**
48
+ * Vérifie si un chemin est absolu
49
+ * @param path Chemin à vérifier
50
+ * @returns True si le chemin est absolu
51
+ */
52
+ static isAbsolute(path: string): boolean;
53
+ /**
54
+ * Extrait le répertoire parent d'un chemin
55
+ * @param path Chemin source
56
+ * @returns Le répertoire parent ou undefined
57
+ */
58
+ static dirname(path: string): string | undefined;
59
+ /**
60
+ * Extrait le nom de fichier d'un chemin
61
+ * @param path Chemin source
62
+ * @param ext Extension optionnelle à retirer
63
+ * @returns Le nom de fichier ou undefined
64
+ */
65
+ static basename(path: string, ext?: string): string | undefined;
66
+ /**
67
+ * Extrait l'extension d'un fichier
68
+ * @param path Chemin source
69
+ * @returns L'extension ou undefined
70
+ */
71
+ static extname(path: string): string | undefined;
72
+ /**
73
+ * Convertit un chemin Windows en chemin Unix
74
+ * @param path Chemin Windows
75
+ * @returns Chemin Unix
76
+ */
77
+ static toUnixPath(path: string): string;
78
+ /**
79
+ * Convertit un chemin Unix en chemin Windows
80
+ * @param path Chemin Unix
81
+ * @returns Chemin Windows
82
+ */
83
+ static toWindowsPath(path: string): string;
84
+ /**
85
+ * Exposition globale de la classe
86
+ */
87
+ static exposeToGlobal(): void;
88
+ }
89
+
90
+ export { Pajo, Pajo as default };
package/index.min.js ADDED
@@ -0,0 +1 @@
1
+ class Pajo{static PROTOCOL_REGEX=/^[a-zA-Z]+:\/\//;static DOUBLE_SLASH_REGEX=/\/+/g;static DOUBLE_BACKSLASH_REGEX=/\\+/g;static TRAILING_SLASH_REGEX=/\/+$/;static TRAILING_BACKSLASH_REGEX=/\\+$/;static LEADING_SLASH_REGEX=/^\/+/;static WINDOWS_DRIVE_REGEX=/^[a-zA-Z]:\\/;static MIXED_SEPARATORS_REGEX=/[\\/]+/g;static join(...s){if(0!==s.length){let i=s.some(t=>this.isWindowsPath(t));var e=s.filter(t=>null!=t&&0<t.trim().length).map(t=>this.normalizePathSegment(t,i));if(0!==e.length){var a=i?"\\":"/";let t=e.join(a);return i?t=t.replace(this.DOUBLE_BACKSLASH_REGEX,"\\"):(t=t.replace(this.DOUBLE_SLASH_REGEX,"/"),s[0]?.startsWith("/")&&!t.startsWith("/")&&(t="/"+t)),t||void 0}}}static joinWithHost(t,...i){var s;return t&&0!==t.trim().length?(t=t.trim().replace(this.TRAILING_SLASH_REGEX,""),t=this.PROTOCOL_REGEX.test(t)?t:"https://"+t,(s=this.join(...i))?t+"/"+s.replace(/\\/g,"/").replace(this.LEADING_SLASH_REGEX,""):t):this.join(...i)}static normalizePathSegment(t,i){return t&&0!==t.trim().length?(t=t.trim(),i?t.replace(this.DOUBLE_BACKSLASH_REGEX,"\\").replace(this.TRAILING_BACKSLASH_REGEX,""):t.replace(this.DOUBLE_SLASH_REGEX,"/").replace(this.TRAILING_SLASH_REGEX,"")):""}static isWindowsPath(t){return this.WINDOWS_DRIVE_REGEX.test(t)||t.includes("\\")}static resolve(...i){i=this.join(...i);if(i){var s,e=this.isWindowsPath(i),a=e?"\\":"/",i=i.split(a),n=[];for(s of i)".."===s?0<n.length&&".."!==n[n.length-1]?n.pop():n.push(s):"."!==s&&""!==s&&n.push(s);let t=n.join(a);return t=e&&this.WINDOWS_DRIVE_REGEX.test(i[0])?i[0]+a+t:t}}static isAbsolute(t){return!!t&&(t.startsWith("/")||this.WINDOWS_DRIVE_REGEX.test(t)||this.PROTOCOL_REGEX.test(t))}static dirname(t){var i,s;if(t)return s=(i=this.isWindowsPath(t))?"\\":"/",-1===(s=(t=this.normalizePathSegment(t,i)).lastIndexOf(s))?".":0===s?i?t.substring(0,2):"/":t.substring(0,s)||(i?".":"/")}static basename(i,s){if(i){var e=this.isWindowsPath(i),a=e?"\\":"/",i=this.normalizePathSegment(i,e),e=i.lastIndexOf(a);let t=-1===e?i:i.substring(e+1);return(t=s&&t.endsWith(s)?t.substring(0,t.length-s.length):t)||void 0}}static extname(t){var i;return(t=t&&this.basename(t))&&0<(i=t.lastIndexOf("."))?t.substring(i):void 0}static toUnixPath(t){return t.replace(/\\/g,"/")}static toWindowsPath(t){return t.replace(/\//g,"\\")}static exposeToGlobal(){"undefined"!=typeof window&&(window.Pajo=Pajo)}}"undefined"!=typeof window&&Pajo.exposeToGlobal();export{Pajo,Pajo as default};
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@arc-js/pajo",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "0.0.1",
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/pajo.all.js ADDED
@@ -0,0 +1,222 @@
1
+ class Pajo {
2
+ static PROTOCOL_REGEX = /^[a-zA-Z]+:\/\//;
3
+ static DOUBLE_SLASH_REGEX = /\/+/g;
4
+ static DOUBLE_BACKSLASH_REGEX = /\\+/g;
5
+ static TRAILING_SLASH_REGEX = /\/+$/;
6
+ static TRAILING_BACKSLASH_REGEX = /\\+$/;
7
+ static LEADING_SLASH_REGEX = /^\/+/;
8
+ static WINDOWS_DRIVE_REGEX = /^[a-zA-Z]:\\/;
9
+ static MIXED_SEPARATORS_REGEX = /[\\/]+/g;
10
+ /**
11
+ * Joint plusieurs segments de chemin en normalisant les séparateurs
12
+ * @param paths Segments de chemin à joindre
13
+ * @returns Le chemin normalisé ou undefined si aucun chemin valide
14
+ */
15
+ static join(...paths) {
16
+ if (paths.length === 0)
17
+ return undefined;
18
+ // Détection du style de chemin (Windows ou Unix)
19
+ const isWindowsPath = paths.some(path => this.isWindowsPath(path));
20
+ // Filtre les chemins vides et nettoie chaque segment
21
+ const cleanPaths = paths
22
+ .filter(path => path != null && path.trim().length > 0)
23
+ .map(path => this.normalizePathSegment(path, isWindowsPath));
24
+ if (cleanPaths.length === 0)
25
+ return undefined;
26
+ // Reconstruction du chemin final avec le séparateur approprié
27
+ const separator = isWindowsPath ? '\\' : '/';
28
+ let result = cleanPaths.join(separator);
29
+ // Normalisation des séparateurs multiples
30
+ if (isWindowsPath) {
31
+ result = result.replace(this.DOUBLE_BACKSLASH_REGEX, '\\');
32
+ }
33
+ else {
34
+ result = result.replace(this.DOUBLE_SLASH_REGEX, '/');
35
+ // Préservation du slash initial pour les chemins absolus Linux
36
+ const hasLeadingSlash = paths[0]?.startsWith('/') || false;
37
+ if (hasLeadingSlash && !result.startsWith('/')) {
38
+ result = '/' + result;
39
+ }
40
+ }
41
+ return result || undefined;
42
+ }
43
+ /**
44
+ * Joint un hôte avec des segments de chemin
45
+ * @param host Hôte (peut inclure le protocole)
46
+ * @param paths Segments de chemin à joindre
47
+ * @returns L'URL complète normalisée ou undefined si invalide
48
+ */
49
+ static joinWithHost(host, ...paths) {
50
+ if (!host || host.trim().length === 0) {
51
+ return this.join(...paths);
52
+ }
53
+ const cleanHost = host.trim().replace(this.TRAILING_SLASH_REGEX, '');
54
+ // Vérification du protocole
55
+ const hasProtocol = this.PROTOCOL_REGEX.test(cleanHost);
56
+ const normalizedHost = hasProtocol ? cleanHost : `https://${cleanHost}`;
57
+ // Traitement des chemins
58
+ const joinedPath = this.join(...paths);
59
+ if (!joinedPath) {
60
+ return normalizedHost;
61
+ }
62
+ // Pour les URLs, on utilise toujours des slashs
63
+ const cleanPath = joinedPath.replace(/\\/g, '/').replace(this.LEADING_SLASH_REGEX, '');
64
+ return `${normalizedHost}/${cleanPath}`;
65
+ }
66
+ /**
67
+ * Normalise un segment de chemin individuel
68
+ * @param path Segment de chemin à normaliser
69
+ * @param isWindowsStyle Si on doit utiliser le style Windows
70
+ * @returns Le segment normalisé
71
+ */
72
+ static normalizePathSegment(path, isWindowsStyle) {
73
+ if (!path || path.trim().length === 0)
74
+ return '';
75
+ const trimmed = path.trim();
76
+ if (isWindowsStyle) {
77
+ return trimmed
78
+ .replace(this.DOUBLE_BACKSLASH_REGEX, '\\')
79
+ .replace(this.TRAILING_BACKSLASH_REGEX, '');
80
+ }
81
+ else {
82
+ return trimmed
83
+ .replace(this.DOUBLE_SLASH_REGEX, '/')
84
+ .replace(this.TRAILING_SLASH_REGEX, '');
85
+ }
86
+ }
87
+ /**
88
+ * Vérifie si le chemin est un chemin Windows
89
+ * @param path Chemin à vérifier
90
+ * @returns True si c'est un chemin Windows
91
+ */
92
+ static isWindowsPath(path) {
93
+ return this.WINDOWS_DRIVE_REGEX.test(path) || path.includes('\\');
94
+ }
95
+ /**
96
+ * Résout les chemins avec . et .. (simplifié)
97
+ * @param paths Segments de chemin à résoudre
98
+ * @returns Chemin résolu
99
+ */
100
+ static resolve(...paths) {
101
+ const joined = this.join(...paths);
102
+ if (!joined)
103
+ return undefined;
104
+ const isWindows = this.isWindowsPath(joined);
105
+ const separator = isWindows ? '\\' : '/';
106
+ const parts = joined.split(separator);
107
+ const resolved = [];
108
+ for (const part of parts) {
109
+ if (part === '..') {
110
+ if (resolved.length > 0 && resolved[resolved.length - 1] !== '..') {
111
+ resolved.pop();
112
+ }
113
+ else {
114
+ resolved.push(part);
115
+ }
116
+ }
117
+ else if (part !== '.' && part !== '') {
118
+ resolved.push(part);
119
+ }
120
+ }
121
+ let result = resolved.join(separator);
122
+ // Restauration du préfixe Windows si nécessaire
123
+ if (isWindows && this.WINDOWS_DRIVE_REGEX.test(parts[0])) {
124
+ result = parts[0] + separator + result;
125
+ }
126
+ return result;
127
+ }
128
+ /**
129
+ * Vérifie si un chemin est absolu
130
+ * @param path Chemin à vérifier
131
+ * @returns True si le chemin est absolu
132
+ */
133
+ static isAbsolute(path) {
134
+ if (!path)
135
+ return false;
136
+ return path.startsWith('/') ||
137
+ this.WINDOWS_DRIVE_REGEX.test(path) ||
138
+ this.PROTOCOL_REGEX.test(path);
139
+ }
140
+ /**
141
+ * Extrait le répertoire parent d'un chemin
142
+ * @param path Chemin source
143
+ * @returns Le répertoire parent ou undefined
144
+ */
145
+ static dirname(path) {
146
+ if (!path)
147
+ return undefined;
148
+ const isWindows = this.isWindowsPath(path);
149
+ const separator = isWindows ? '\\' : '/';
150
+ const normalized = this.normalizePathSegment(path, isWindows);
151
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
152
+ if (lastSeparatorIndex === -1)
153
+ return isWindows ? '.' : '.';
154
+ if (lastSeparatorIndex === 0)
155
+ return isWindows ? normalized.substring(0, 2) : '/';
156
+ return normalized.substring(0, lastSeparatorIndex) || (isWindows ? '.' : '/');
157
+ }
158
+ /**
159
+ * Extrait le nom de fichier d'un chemin
160
+ * @param path Chemin source
161
+ * @param ext Extension optionnelle à retirer
162
+ * @returns Le nom de fichier ou undefined
163
+ */
164
+ static basename(path, ext) {
165
+ if (!path)
166
+ return undefined;
167
+ const isWindows = this.isWindowsPath(path);
168
+ const separator = isWindows ? '\\' : '/';
169
+ const normalized = this.normalizePathSegment(path, isWindows);
170
+ const lastSeparatorIndex = normalized.lastIndexOf(separator);
171
+ let basename = lastSeparatorIndex === -1 ? normalized : normalized.substring(lastSeparatorIndex + 1);
172
+ // Gestion de l'extension optionnelle
173
+ if (ext && basename.endsWith(ext)) {
174
+ basename = basename.substring(0, basename.length - ext.length);
175
+ }
176
+ return basename || undefined;
177
+ }
178
+ /**
179
+ * Extrait l'extension d'un fichier
180
+ * @param path Chemin source
181
+ * @returns L'extension ou undefined
182
+ */
183
+ static extname(path) {
184
+ if (!path)
185
+ return undefined;
186
+ const basename = this.basename(path);
187
+ if (!basename)
188
+ return undefined;
189
+ const lastDotIndex = basename.lastIndexOf('.');
190
+ return lastDotIndex > 0 ? basename.substring(lastDotIndex) : undefined;
191
+ }
192
+ /**
193
+ * Convertit un chemin Windows en chemin Unix
194
+ * @param path Chemin Windows
195
+ * @returns Chemin Unix
196
+ */
197
+ static toUnixPath(path) {
198
+ return path.replace(/\\/g, '/');
199
+ }
200
+ /**
201
+ * Convertit un chemin Unix en chemin Windows
202
+ * @param path Chemin Unix
203
+ * @returns Chemin Windows
204
+ */
205
+ static toWindowsPath(path) {
206
+ return path.replace(/\//g, '\\');
207
+ }
208
+ /**
209
+ * Exposition globale de la classe
210
+ */
211
+ static exposeToGlobal() {
212
+ if (typeof window !== "undefined") {
213
+ window.Pajo = Pajo;
214
+ }
215
+ }
216
+ }
217
+ // Exposition automatique en environnement browser
218
+ if (typeof window !== "undefined") {
219
+ Pajo.exposeToGlobal();
220
+ }
221
+
222
+
@@ -0,0 +1 @@
1
+ class Pajo{static PROTOCOL_REGEX=/^[a-zA-Z]+:\/\//;static DOUBLE_SLASH_REGEX=/\/+/g;static DOUBLE_BACKSLASH_REGEX=/\\+/g;static TRAILING_SLASH_REGEX=/\/+$/;static TRAILING_BACKSLASH_REGEX=/\\+$/;static LEADING_SLASH_REGEX=/^\/+/;static WINDOWS_DRIVE_REGEX=/^[a-zA-Z]:\\/;static MIXED_SEPARATORS_REGEX=/[\\/]+/g;static join(...s){if(0!==s.length){let i=s.some(t=>this.isWindowsPath(t));var e=s.filter(t=>null!=t&&0<t.trim().length).map(t=>this.normalizePathSegment(t,i));if(0!==e.length){var a=i?"\\":"/";let t=e.join(a);return i?t=t.replace(this.DOUBLE_BACKSLASH_REGEX,"\\"):(t=t.replace(this.DOUBLE_SLASH_REGEX,"/"),s[0]?.startsWith("/")&&!t.startsWith("/")&&(t="/"+t)),t||void 0}}}static joinWithHost(t,...i){var s;return t&&0!==t.trim().length?(t=t.trim().replace(this.TRAILING_SLASH_REGEX,""),t=this.PROTOCOL_REGEX.test(t)?t:"https://"+t,(s=this.join(...i))?t+"/"+s.replace(/\\/g,"/").replace(this.LEADING_SLASH_REGEX,""):t):this.join(...i)}static normalizePathSegment(t,i){return t&&0!==t.trim().length?(t=t.trim(),i?t.replace(this.DOUBLE_BACKSLASH_REGEX,"\\").replace(this.TRAILING_BACKSLASH_REGEX,""):t.replace(this.DOUBLE_SLASH_REGEX,"/").replace(this.TRAILING_SLASH_REGEX,"")):""}static isWindowsPath(t){return this.WINDOWS_DRIVE_REGEX.test(t)||t.includes("\\")}static resolve(...i){i=this.join(...i);if(i){var s,e=this.isWindowsPath(i),a=e?"\\":"/",i=i.split(a),n=[];for(s of i)".."===s?0<n.length&&".."!==n[n.length-1]?n.pop():n.push(s):"."!==s&&""!==s&&n.push(s);let t=n.join(a);return t=e&&this.WINDOWS_DRIVE_REGEX.test(i[0])?i[0]+a+t:t}}static isAbsolute(t){return!!t&&(t.startsWith("/")||this.WINDOWS_DRIVE_REGEX.test(t)||this.PROTOCOL_REGEX.test(t))}static dirname(t){var i,s;if(t)return s=(i=this.isWindowsPath(t))?"\\":"/",-1===(s=(t=this.normalizePathSegment(t,i)).lastIndexOf(s))?".":0===s?i?t.substring(0,2):"/":t.substring(0,s)||(i?".":"/")}static basename(i,s){if(i){var e=this.isWindowsPath(i),a=e?"\\":"/",i=this.normalizePathSegment(i,e),e=i.lastIndexOf(a);let t=-1===e?i:i.substring(e+1);return(t=s&&t.endsWith(s)?t.substring(0,t.length-s.length):t)||void 0}}static extname(t){var i;return(t=t&&this.basename(t))&&0<(i=t.lastIndexOf("."))?t.substring(i):void 0}static toUnixPath(t){return t.replace(/\\/g,"/")}static toWindowsPath(t){return t.replace(/\//g,"\\")}static exposeToGlobal(){"undefined"!=typeof window&&(window.Pajo=Pajo)}}"undefined"!=typeof window&&Pajo.exposeToGlobal();
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES6",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable", "ESNext"],
6
+ "strict": false,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "declaration": false,
10
+ "sourceMap": false,
11
+ "allowSyntheticDefaultImports": true,
12
+ "noEmit": false
13
+ },
14
+ "include": [],
15
+ "exclude": [
16
+ "node_modules",
17
+ "**/*.d.ts"
18
+ ]
19
+ }