@arc-js/qust 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 +630 -0
- package/index.ts +456 -0
- package/js/index.js +328 -0
- package/package.json +18 -0
- package/tsconfig.json +27 -0
- package/web/qust.js +326 -0
- package/web/qust.min.js +1 -0
package/index.ts
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
|
|
3
|
+
interface Window {
|
|
4
|
+
default: typeof defaultElementGF;
|
|
5
|
+
Qust: any;
|
|
6
|
+
qust: any;
|
|
7
|
+
__bundledModules: any;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface QustOptions {
|
|
11
|
+
arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'none';
|
|
12
|
+
arraySeparator?: string;
|
|
13
|
+
skipNull?: boolean;
|
|
14
|
+
skipEmptyString?: boolean;
|
|
15
|
+
encode?: boolean;
|
|
16
|
+
decode?: boolean;
|
|
17
|
+
depth?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
type Primitive = string | number | boolean | null | undefined;
|
|
22
|
+
|
|
23
|
+
type QueryValue = Primitive | Primitive[] | { [key: string]: QueryValue };
|
|
24
|
+
|
|
25
|
+
type QueryObject = { [key: string]: QueryValue };
|
|
26
|
+
|
|
27
|
+
const globalFunct = (function(global: any) {
|
|
28
|
+
'use strict';
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
const DEFAULT_OPTIONS: Required<QustOptions> = {
|
|
39
|
+
arrayFormat: 'bracket',
|
|
40
|
+
arraySeparator: ',',
|
|
41
|
+
skipNull: true,
|
|
42
|
+
skipEmptyString: false,
|
|
43
|
+
encode: true,
|
|
44
|
+
decode: true,
|
|
45
|
+
depth: 10
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
class Qust {
|
|
49
|
+
private options: Required<QustOptions>;
|
|
50
|
+
|
|
51
|
+
constructor(options: QustOptions = {}) {
|
|
52
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
stringify(obj: QueryObject): string {
|
|
56
|
+
if (!obj || typeof obj !== 'object') {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const parts: string[] = [];
|
|
61
|
+
this.processObject('', obj, parts, 0);
|
|
62
|
+
|
|
63
|
+
return parts.length > 0 ? `?${parts.join('&')}` : '';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
parse<T = QueryObject>(queryString: string): T {
|
|
67
|
+
if (!queryString || typeof queryString !== 'string') {
|
|
68
|
+
return {} as T;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const cleanString = queryString.startsWith('?')
|
|
72
|
+
? queryString.slice(1)
|
|
73
|
+
: queryString;
|
|
74
|
+
|
|
75
|
+
if (!cleanString) {
|
|
76
|
+
return {} as T;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const result: QueryObject = {};
|
|
80
|
+
const pairs = cleanString.split('&');
|
|
81
|
+
|
|
82
|
+
for (const pair of pairs) {
|
|
83
|
+
if (!pair) continue;
|
|
84
|
+
|
|
85
|
+
const [encodedKey, encodedValue] = pair.split('=');
|
|
86
|
+
|
|
87
|
+
if (!encodedKey) continue;
|
|
88
|
+
|
|
89
|
+
const key = this.options.decode
|
|
90
|
+
? decodeURIComponent(encodedKey)
|
|
91
|
+
: encodedKey;
|
|
92
|
+
|
|
93
|
+
const value = this.options.decode && encodedValue !== undefined
|
|
94
|
+
? decodeURIComponent(encodedValue)
|
|
95
|
+
: encodedValue;
|
|
96
|
+
|
|
97
|
+
this.setValue(result, key, value);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return this.transformArrays(result) as T;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private processObject(
|
|
104
|
+
prefix: string,
|
|
105
|
+
value: QueryValue,
|
|
106
|
+
parts: string[],
|
|
107
|
+
depth: number
|
|
108
|
+
): void {
|
|
109
|
+
if (depth > this.options.depth) {
|
|
110
|
+
console.warn('Qust: Profondeur maximale atteinte, arrêt de la récursion');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (value === null || value === undefined) {
|
|
115
|
+
if (!this.options.skipNull) {
|
|
116
|
+
parts.push(this.encodeKey(prefix));
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (typeof value === 'string' && value === '' && this.options.skipEmptyString) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (Array.isArray(value)) {
|
|
126
|
+
this.processArray(prefix, value, parts, depth + 1);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (typeof value === 'object' && !this.isPrimitive(value)) {
|
|
131
|
+
for (const [key, val] of Object.entries(value)) {
|
|
132
|
+
const newPrefix = prefix ? `${prefix}[${key}]` : key;
|
|
133
|
+
this.processObject(newPrefix, val, parts, depth + 1);
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const encodedKey = this.encodeKey(prefix);
|
|
139
|
+
const encodedValue = this.options.encode && typeof value === 'string'
|
|
140
|
+
? encodeURIComponent(value)
|
|
141
|
+
: String(value);
|
|
142
|
+
|
|
143
|
+
parts.push(`${encodedKey}=${encodedValue}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private processArray(
|
|
147
|
+
prefix: string,
|
|
148
|
+
array: Primitive[],
|
|
149
|
+
parts: string[],
|
|
150
|
+
depth: number
|
|
151
|
+
): void {
|
|
152
|
+
if (array.length === 0) return;
|
|
153
|
+
|
|
154
|
+
const encodedKey = this.encodeKey(prefix);
|
|
155
|
+
|
|
156
|
+
switch (this.options.arrayFormat) {
|
|
157
|
+
case 'comma':
|
|
158
|
+
const values = array
|
|
159
|
+
.map(item => this.options.encode && typeof item === 'string'
|
|
160
|
+
? encodeURIComponent(item)
|
|
161
|
+
: String(item)
|
|
162
|
+
)
|
|
163
|
+
.join(this.options.arraySeparator);
|
|
164
|
+
parts.push(`${encodedKey}=${values}`);
|
|
165
|
+
break;
|
|
166
|
+
|
|
167
|
+
case 'index':
|
|
168
|
+
array.forEach((item, index) => {
|
|
169
|
+
const arrayPrefix = `${prefix}[${index}]`;
|
|
170
|
+
this.processObject(arrayPrefix, item, parts, depth);
|
|
171
|
+
});
|
|
172
|
+
break;
|
|
173
|
+
|
|
174
|
+
case 'separator':
|
|
175
|
+
array.forEach(item => {
|
|
176
|
+
const encodedValue = this.options.encode && typeof item === 'string'
|
|
177
|
+
? encodeURIComponent(item)
|
|
178
|
+
: String(item);
|
|
179
|
+
parts.push(`${encodedKey}=${encodedValue}`);
|
|
180
|
+
});
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
case 'none':
|
|
184
|
+
array.forEach(item => {
|
|
185
|
+
this.processObject(prefix, item, parts, depth);
|
|
186
|
+
});
|
|
187
|
+
break;
|
|
188
|
+
|
|
189
|
+
case 'bracket':
|
|
190
|
+
default:
|
|
191
|
+
array.forEach(item => {
|
|
192
|
+
const arrayPrefix = `${prefix}[]`;
|
|
193
|
+
this.processObject(arrayPrefix, item, parts, depth);
|
|
194
|
+
});
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private encodeKey(key: string): string {
|
|
200
|
+
if (!this.options.encode) {
|
|
201
|
+
return key;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const parts: string[] = [];
|
|
205
|
+
let currentPart = '';
|
|
206
|
+
|
|
207
|
+
for (let i = 0; i < key.length; i++) {
|
|
208
|
+
const char = key[i];
|
|
209
|
+
|
|
210
|
+
if (char === '[' || char === ']') {
|
|
211
|
+
|
|
212
|
+
if (currentPart) {
|
|
213
|
+
parts.push(encodeURIComponent(currentPart));
|
|
214
|
+
currentPart = '';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
parts.push(char);
|
|
218
|
+
} else {
|
|
219
|
+
currentPart += char;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (currentPart) {
|
|
224
|
+
parts.push(encodeURIComponent(currentPart));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return parts.join('');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private setValue(obj: QueryObject, key: string, value: string | undefined): void {
|
|
231
|
+
const matches = key.match(/([^\[\]]+)|(\[\])/g);
|
|
232
|
+
|
|
233
|
+
if (!matches) {
|
|
234
|
+
if (value !== undefined) {
|
|
235
|
+
obj[key] = this.parseValue(value);
|
|
236
|
+
}
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
let current: any = obj;
|
|
241
|
+
|
|
242
|
+
for (let i = 0; i < matches.length; i++) {
|
|
243
|
+
const match = matches[i];
|
|
244
|
+
const isLast = i === matches.length - 1;
|
|
245
|
+
|
|
246
|
+
if (match === '[]') {
|
|
247
|
+
if (!Array.isArray(current)) {
|
|
248
|
+
current = [];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (isLast) {
|
|
252
|
+
if (!!value) {
|
|
253
|
+
current.push(this.parseValue(value));
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
const nextMatch = matches[i + 1];
|
|
257
|
+
const nextIndex = parseInt(nextMatch, 10);
|
|
258
|
+
|
|
259
|
+
if (!isNaN(nextIndex)) {
|
|
260
|
+
if (current[nextIndex] === undefined) {
|
|
261
|
+
current[nextIndex] = {};
|
|
262
|
+
}
|
|
263
|
+
current = current[nextIndex];
|
|
264
|
+
i++;
|
|
265
|
+
} else {
|
|
266
|
+
const newObj = {};
|
|
267
|
+
current.push(newObj);
|
|
268
|
+
current = newObj;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
if (isLast) {
|
|
273
|
+
if (value !== undefined) {
|
|
274
|
+
current[match] = this.parseValue(value);
|
|
275
|
+
}
|
|
276
|
+
} else {
|
|
277
|
+
if (current[match] === undefined || typeof current[match] !== 'object') {
|
|
278
|
+
const nextMatch = matches[i + 1];
|
|
279
|
+
current[match] = nextMatch === '[]' ? [] : {};
|
|
280
|
+
}
|
|
281
|
+
current = current[match];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private transformArrays(obj: any): any {
|
|
288
|
+
if (Array.isArray(obj)) {
|
|
289
|
+
return obj.map(item =>
|
|
290
|
+
typeof item === 'object' && item !== null
|
|
291
|
+
? this.transformArrays(item)
|
|
292
|
+
: item
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
297
|
+
return obj;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const result: any = {};
|
|
301
|
+
const keys = Object.keys(obj);
|
|
302
|
+
|
|
303
|
+
const isArrayLike = keys.every(key => {
|
|
304
|
+
const num = parseInt(key, 10);
|
|
305
|
+
return !isNaN(num) && num >= 0 && num.toString() === key;
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
if (isArrayLike && keys.length > 0) {
|
|
309
|
+
const array: any[] = [];
|
|
310
|
+
keys.forEach(key => {
|
|
311
|
+
const index = parseInt(key, 10);
|
|
312
|
+
array[index] = this.transformArrays(obj[key]);
|
|
313
|
+
});
|
|
314
|
+
return array;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
keys.forEach(key => {
|
|
318
|
+
const value = obj[key];
|
|
319
|
+
result[key] =
|
|
320
|
+
typeof value === 'object' && value !== null
|
|
321
|
+
? this.transformArrays(value)
|
|
322
|
+
: value;
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private parseValue(value: string): Primitive {
|
|
329
|
+
if (value === 'true') return true;
|
|
330
|
+
if (value === 'false') return false;
|
|
331
|
+
if (value === 'null') return null;
|
|
332
|
+
if (value === 'undefined') return undefined;
|
|
333
|
+
|
|
334
|
+
const num = Number(value);
|
|
335
|
+
if (!isNaN(num) && value.trim() !== '') return num;
|
|
336
|
+
|
|
337
|
+
return value;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private isPrimitive(value: any): boolean {
|
|
341
|
+
return value === null ||
|
|
342
|
+
typeof value !== 'object' &&
|
|
343
|
+
typeof value !== 'function';
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
setOptions(newOptions: Partial<QustOptions>): void {
|
|
347
|
+
this.options = { ...this.options, ...newOptions };
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
getOptions(): Required<QustOptions> {
|
|
351
|
+
return { ...this.options };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
static exposeToGlobal(): void {
|
|
355
|
+
if (typeof window !== "undefined") {
|
|
356
|
+
window.Qust = Qust;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const qust = {
|
|
362
|
+
|
|
363
|
+
stringify(obj: QueryObject, options?: QustOptions): string {
|
|
364
|
+
return new Qust(options).stringify(obj);
|
|
365
|
+
},
|
|
366
|
+
|
|
367
|
+
parse<T = QueryObject>(queryString: string, options?: QustOptions): T {
|
|
368
|
+
return new Qust(options).parse<T>(queryString);
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
if (typeof window !== "undefined") {
|
|
373
|
+
window.Qust = Qust;
|
|
374
|
+
window.qust = qust;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
const globalFunctModule = {
|
|
381
|
+
default: qust,
|
|
382
|
+
Qust: Qust,
|
|
383
|
+
qust: qust,
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
globalFunctModule.default = {...(globalFunctModule?.default || {}), Qust: Qust};
|
|
387
|
+
globalFunctModule.default = {...(globalFunctModule?.default || {}), qust: qust};
|
|
388
|
+
|
|
389
|
+
const __bundledModules = globalFunctModule;
|
|
390
|
+
|
|
391
|
+
if (typeof global !== 'undefined') {
|
|
392
|
+
(global as any).default = qust;
|
|
393
|
+
(global as any).Qust = Qust;
|
|
394
|
+
(global as any).qust = qust;
|
|
395
|
+
(global as any).__bundledModules = __bundledModules;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (typeof window !== "undefined") {
|
|
399
|
+
(window as any).default = qust;
|
|
400
|
+
(window as any).Qust = Qust;
|
|
401
|
+
(window as any).qust = qust;
|
|
402
|
+
(window as any).__bundledModules = __bundledModules;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
406
|
+
module.exports = __bundledModules;
|
|
407
|
+
module.exports.default = qust;
|
|
408
|
+
module.exports.Qust = Qust;
|
|
409
|
+
module.exports.qust = qust;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (typeof exports !== 'undefined') {
|
|
413
|
+
exports.default = qust;
|
|
414
|
+
exports.Qust = Qust;
|
|
415
|
+
exports.qust = qust;
|
|
416
|
+
}
|
|
417
|
+
return __bundledModules;
|
|
418
|
+
|
|
419
|
+
})(typeof global !== 'undefined' ? global :
|
|
420
|
+
typeof window !== 'undefined' ? window :
|
|
421
|
+
typeof self !== 'undefined' ? self :
|
|
422
|
+
typeof globalThis !== 'undefined' ? globalThis :
|
|
423
|
+
{});
|
|
424
|
+
|
|
425
|
+
type QustElementTypeGF = typeof globalFunct.Qust;
|
|
426
|
+
|
|
427
|
+
type qustElementTypeGF = typeof globalFunct.qust;
|
|
428
|
+
|
|
429
|
+
type DefaultElementTypeGF = typeof globalFunct.default;
|
|
430
|
+
|
|
431
|
+
const QustElementGF: QustElementTypeGF = globalFunct.Qust;
|
|
432
|
+
|
|
433
|
+
const qustElementGF: qustElementTypeGF = globalFunct.qust;
|
|
434
|
+
|
|
435
|
+
const defaultElementGF: DefaultElementTypeGF = globalFunct.default;
|
|
436
|
+
|
|
437
|
+
export {
|
|
438
|
+
QustElementGF as Qust,
|
|
439
|
+
qustElementGF as qust,
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
export default defaultElementGF;
|
|
443
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
444
|
+
module.exports = {
|
|
445
|
+
Qust: QustElementGF,
|
|
446
|
+
qust: qustElementGF,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
451
|
+
module.exports.default = globalFunct?.default;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export type { QustElementTypeGF, qustElementTypeGF };
|
|
455
|
+
|
|
456
|
+
export type { DefaultElementTypeGF };
|