@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 +568 -0
- package/index.ts +294 -0
- package/js/index.js +231 -0
- package/package.json +18 -0
- package/tsconfig.json +27 -0
- package/web/pajo.js +229 -0
- package/web/pajo.min.js +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
# @arc-js/pajo
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
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
|
+
}
|
package/web/pajo.min.js
ADDED
|
@@ -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:
|