@develia/commons 0.4.2 → 0.4.3

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.
Files changed (61) hide show
  1. package/dist/cjs/browser/index.js +129 -0
  2. package/dist/cjs/browser/index.js.map +1 -0
  3. package/dist/cjs/index.js +4 -3
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/type-code.js +18 -0
  6. package/dist/cjs/type-code.js.map +1 -0
  7. package/dist/cjs/type.js +212 -12
  8. package/dist/cjs/type.js.map +1 -1
  9. package/dist/cjs/utilities.js +1 -127
  10. package/dist/cjs/utilities.js.map +1 -1
  11. package/dist/esm/browser/index.js +122 -0
  12. package/dist/esm/browser/index.js.map +1 -0
  13. package/dist/esm/index.js +2 -1
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/type-code.js +16 -0
  16. package/dist/esm/type-code.js.map +1 -0
  17. package/dist/esm/type.js +209 -12
  18. package/dist/esm/type.js.map +1 -1
  19. package/dist/esm/utilities.js +1 -122
  20. package/dist/esm/utilities.js.map +1 -1
  21. package/dist/types/browser/index.d.ts +7 -0
  22. package/dist/types/browser/index.d.ts.map +1 -0
  23. package/dist/types/index.d.ts +2 -1
  24. package/dist/types/index.d.ts.map +1 -1
  25. package/dist/types/patch.d.ts +3 -3
  26. package/dist/types/patch.d.ts.map +1 -1
  27. package/dist/types/type-code.d.ts +15 -0
  28. package/dist/types/type-code.d.ts.map +1 -0
  29. package/dist/types/type.d.ts +45 -11
  30. package/dist/types/type.d.ts.map +1 -1
  31. package/dist/types/types.d.ts +1 -2
  32. package/dist/types/types.d.ts.map +1 -1
  33. package/dist/types/utilities.d.ts +1 -6
  34. package/dist/types/utilities.d.ts.map +1 -1
  35. package/dist/web/browser/index.js +123 -0
  36. package/dist/web/browser/index.js.map +1 -0
  37. package/dist/web/index.js +2 -1
  38. package/dist/web/index.js.map +1 -1
  39. package/dist/web/type-code.js +16 -0
  40. package/dist/web/type-code.js.map +1 -0
  41. package/dist/web/type.js +210 -12
  42. package/dist/web/type.js.map +1 -1
  43. package/dist/web/utilities.js +1 -122
  44. package/dist/web/utilities.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/browser/index.ts +172 -0
  47. package/src/index.ts +15 -13
  48. package/src/patch.ts +3 -3
  49. package/src/type-code.ts +16 -0
  50. package/src/type.ts +370 -17
  51. package/src/types.ts +1 -5
  52. package/src/utilities.ts +2 -165
  53. package/dist/cjs/remote-data.js +0 -115
  54. package/dist/cjs/remote-data.js.map +0 -1
  55. package/dist/esm/remote-data.js +0 -112
  56. package/dist/esm/remote-data.js.map +0 -1
  57. package/dist/types/remote-data.d.ts +0 -32
  58. package/dist/types/remote-data.d.ts.map +0 -1
  59. package/dist/web/remote-data.js +0 -112
  60. package/dist/web/remote-data.js.map +0 -1
  61. package/src/remote-data.ts +0 -149
package/src/type.ts CHANGED
@@ -1,19 +1,372 @@
1
+ import TypeCode from "./type-code.js";
2
+ import {type Constructor} from "./types.js";
1
3
 
2
- /**
3
- * Represents different types in JavaScript.
4
- * @enum {string}
5
- */
6
- enum Type {
7
- Undefined = "undefined",
8
- Number = "number",
9
- String = "string",
10
- Boolean = "boolean",
11
- Object = "object",
12
- Function = "function",
13
- Symbol = "symbol",
14
- BigInt = "bigint",
15
- Null = "null"
16
- }
17
-
18
- export default Type;
4
+ export default class Type<T = unknown> {
19
5
 
6
+ // ──────────────────────────────────────────────
7
+ // Caché (Flyweight)
8
+ // ──────────────────────────────────────────────
9
+
10
+ private static readonly _cache = new Map<unknown, Type>();
11
+
12
+ // ──────────────────────────────────────────────
13
+ // Tipos predefinidos
14
+ // ──────────────────────────────────────────────
15
+
16
+ public static readonly String = Type._getOrCreate<string>('string', undefined, TypeCode.String, 'string');
17
+ public static readonly Number = Type._getOrCreate<number>('number', undefined, TypeCode.Number, 'number');
18
+ public static readonly Boolean = Type._getOrCreate<boolean>('boolean', undefined, TypeCode.Boolean, 'boolean');
19
+ public static readonly Symbol = Type._getOrCreate<symbol>('symbol', undefined, TypeCode.Symbol, 'symbol');
20
+ public static readonly BigInt = Type._getOrCreate<bigint>('bigint', undefined, TypeCode.BigInt, 'bigint');
21
+ public static readonly Null = Type._getOrCreate<null>('null', undefined, TypeCode.Null, 'null');
22
+ public static readonly Undefined = Type._getOrCreate<undefined>('undefined', undefined, TypeCode.Undefined, 'undefined');
23
+ public static readonly Object = Type._getOrCreate<object>(Object, Object, TypeCode.Object, 'Object');
24
+ public static readonly Function = Type._getOrCreate<Function>(Function, Function, TypeCode.Function, 'Function');
25
+ public static readonly Array = Type._getOrCreate<unknown[]>(Array, Array, TypeCode.Array, 'Array');
26
+
27
+ // ──────────────────────────────────────────────
28
+ // Propiedades inmutables
29
+ // ──────────────────────────────────────────────
30
+
31
+ public readonly name: string;
32
+ public readonly constructorRef:
33
+ Constructor<T> | undefined;
34
+ public readonly typeCode: TypeCode;
35
+
36
+ private constructor(
37
+ name: string,
38
+ constructorRef: Constructor<T> | undefined,
39
+ typeCode: TypeCode,
40
+ ) {
41
+ this.name = name;
42
+ this.constructorRef = constructorRef;
43
+ this.typeCode = typeCode;
44
+ }
45
+
46
+ // ══════════════════════════════════════════════
47
+ // ÚNICO PUNTO DE ENTRADA
48
+ // ══════════════════════════════════════════════
49
+
50
+ /**
51
+ * Obtiene el `Type` de cualquier valor, constructor o primitivo.
52
+ *
53
+ * Unifica `typeof()` y `.GetType()` de C# en un solo método.
54
+ *
55
+ * **Reglas de resolución:**
56
+ * 1. `null` / `undefined` → tipo nullish correspondiente
57
+ * 2. Primitivo (`number`, `string`, etc.) → tipo primitivo
58
+ * 3. Array → `Type.Array`
59
+ * 4. Función/Constructor → tipo del constructor (no "Function")
60
+ * 5. Objeto → tipo basado en su constructor
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * Type.of(42) // Type<number> — primitivo
65
+ * Type.of('hello') // Type<string> — primitivo
66
+ * Type.of(new Date()) // Type<Date> — desde instancia
67
+ * Type.of(Date) // Type<Date> — desde constructor
68
+ * Type.of(null) // Type<null>
69
+ * Type.of([1, 2, 3]) // Type<Array>
70
+ * ```
71
+ */
72
+ public static of<U>(target: U | Constructor<U>): Type<U> {
73
+ // ── Nullish ──
74
+ if (target === null) return Type.Null as Type<U>;
75
+ if (target === undefined) return Type.Undefined as Type<U>;
76
+
77
+ const jsType = typeof target;
78
+
79
+ // ── Primitivos ──
80
+ if (jsType !== 'object' && jsType !== 'function') {
81
+ return this._getOrCreate<U>(jsType, undefined, jsType as TypeCode);
82
+ }
83
+
84
+ // ── Funciones y Constructores ──
85
+ if (jsType === 'function') {
86
+ return this._resolveFunction<U>(target as Function & Constructor<U>);
87
+ }
88
+
89
+ // ── Arrays ──
90
+ if (Array.isArray(target)) {
91
+ return Type.Array as Type<U>;
92
+ }
93
+
94
+ // ── Objetos ──
95
+ return this._resolveObject<U>(target as object);
96
+ }
97
+
98
+ // ──────────────────────────────────────────────
99
+ // Resolvers privados (separan la lógica compleja)
100
+ // ──────────────────────────────────────────────
101
+
102
+ /**
103
+ * Resuelve funciones y constructores.
104
+ *
105
+ * Decisión clave: si la función tiene un `prototype` con
106
+ * miembros propios o empieza con `class`, es un constructor
107
+ * y devolvemos el tipo que construye. Si no, es una función.
108
+ */
109
+ private static _resolveFunction<U>(fn: Function & Constructor<U>): Type<U> {
110
+ const isConstructor = this._isConstructorLike(fn);
111
+
112
+ if (isConstructor) {
113
+ // Constructor → devuelve el tipo que construye
114
+ return this._getOrCreate<U>(
115
+ fn, // cacheamos por referencia al constructor
116
+ fn as Constructor<U>,
117
+ TypeCode.Object,
118
+ fn.name || 'AnonymousClass',
119
+ );
120
+ }
121
+
122
+ // Función pura → devuelve Type<Function>
123
+ return Type.Function as Type<U>;
124
+ }
125
+
126
+ /**
127
+ * Resuelve objetos por su cadena de prototipos.
128
+ */
129
+ private static _resolveObject<U>(obj: object): Type<U> {
130
+ const proto = Object.getPrototypeOf(obj) as { constructor?: Constructor<U> } | null;
131
+ const ctor = proto?.constructor as Constructor<U> | undefined;
132
+ const name = ctor?.name || 'Object';
133
+
134
+ if (!ctor || ctor === (Object as unknown)) {
135
+ return Type.Object as Type<U>;
136
+ }
137
+
138
+ return this._getOrCreate<U>(ctor, ctor, TypeCode.Object, name);
139
+ }
140
+
141
+ /**
142
+ * Heurística para distinguir constructores de funciones planas.
143
+ *
144
+ * Un "constructor" cumple al menos una de:
145
+ * - Su `toString()` empieza con "class "
146
+ * - Tiene propiedades propias en su prototype (más allá de constructor)
147
+ * - Es un built-in conocido (Date, Map, Set, etc.)
148
+ */
149
+ private static _isConstructorLike(fn: Function): boolean {
150
+ // 1. Clase ES6 explícita
151
+ try {
152
+ if (fn.toString().startsWith('class ')) return true;
153
+ } catch {
154
+ // toString puede fallar en Proxy, etc.
155
+ }
156
+
157
+ // 2. Built-ins conocidos con prototype significativo
158
+ if (fn === Object || fn === Function || fn === Array) return true;
159
+
160
+ const proto = fn.prototype;
161
+ if (!proto || typeof proto !== 'object') return false;
162
+
163
+ // 3. Prototype con miembros propios (señal de constructor)
164
+ const ownKeys = Object.getOwnPropertyNames(proto);
165
+ return ownKeys.length > 1 || (ownKeys.length === 1 && ownKeys[0] !== 'constructor');
166
+ }
167
+
168
+ // ══════════════════════════════════════════════
169
+ // PROPIEDADES COMPUTADAS
170
+ // ══════════════════════════════════════════════
171
+
172
+ public get isPrimitive(): boolean {
173
+ return (
174
+ this.typeCode === TypeCode.String ||
175
+ this.typeCode === TypeCode.Number ||
176
+ this.typeCode === TypeCode.Boolean ||
177
+ this.typeCode === TypeCode.Symbol ||
178
+ this.typeCode === TypeCode.BigInt
179
+ );
180
+ }
181
+
182
+ public get isNullish(): boolean {
183
+ return this.typeCode === TypeCode.Null || this.typeCode === TypeCode.Undefined;
184
+ }
185
+
186
+ public get isReferenceType(): boolean {
187
+ return !this.isPrimitive && !this.isNullish;
188
+ }
189
+
190
+ public get isArray(): boolean {
191
+ return this.typeCode === TypeCode.Array ||
192
+ this.constructorRef === (Array as unknown as Constructor<T>);
193
+ }
194
+
195
+ public get isFunction(): boolean {
196
+ return this.typeCode === TypeCode.Function;
197
+ }
198
+
199
+ public get isValueType(): boolean {
200
+ return this.isPrimitive;
201
+ }
202
+
203
+ public get isClass(): boolean {
204
+ if (!this.constructorRef) return false;
205
+ try {
206
+ return this.constructorRef.toString().startsWith('class ');
207
+ } catch {
208
+ return false;
209
+ }
210
+ }
211
+
212
+ public get fullName(): string {
213
+ if (this.isPrimitive || this.isNullish) {
214
+ return `System.${this.name.charAt(0).toUpperCase()}${this.name.slice(1)}`;
215
+ }
216
+ return this.name;
217
+ }
218
+
219
+ // ══════════════════════════════════════════════
220
+ // JERARQUÍA
221
+ // ══════════════════════════════════════════════
222
+
223
+ public get baseType(): Type | undefined {
224
+ if (!this.constructorRef) return undefined;
225
+
226
+ const parentProto = Object.getPrototypeOf(this.constructorRef.prototype);
227
+ if (!parentProto || parentProto === Object.prototype) {
228
+ return this === Type.Object ? undefined : Type.Object;
229
+ }
230
+
231
+ const parentCtor = parentProto.constructor as Constructor;
232
+ return Type.of(parentCtor);
233
+ }
234
+
235
+ public getInheritanceChain(): ReadonlyArray<Type> {
236
+ const chain: Type[] = [this];
237
+ let current: Type | undefined = this.baseType;
238
+
239
+ while (current && !chain.includes(current)) {
240
+ chain.push(current);
241
+ current = current.baseType;
242
+ }
243
+
244
+ return Object.freeze(chain);
245
+ }
246
+
247
+ public isAssignableTo(target: Type): boolean {
248
+ if (this === target) return true;
249
+ if (!this.constructorRef || !target.constructorRef) return false;
250
+
251
+ let proto: object | null = this.constructorRef.prototype;
252
+ while (proto) {
253
+ if (proto.constructor === target.constructorRef) return true;
254
+ proto = Object.getPrototypeOf(proto) as object | null;
255
+ }
256
+ return false;
257
+ }
258
+
259
+ public isAssignableFrom(source: Type): boolean {
260
+ return source.isAssignableTo(this);
261
+ }
262
+
263
+ public isSubclassOf(parent: Type): boolean {
264
+ if (this === parent) return false;
265
+ return this.isAssignableTo(parent);
266
+ }
267
+
268
+
269
+ // ══════════════════════════════════════════════
270
+ // REFLEXIÓN
271
+ // ══════════════════════════════════════════════
272
+
273
+ public getMethodNames(): ReadonlyArray<string> {
274
+ if (!this.constructorRef?.prototype) return Object.freeze([]);
275
+ return Object.freeze(
276
+ Object.getOwnPropertyNames(this.constructorRef.prototype)
277
+ .filter(n => n !== 'constructor' &&
278
+ typeof Object.getOwnPropertyDescriptor(
279
+ this.constructorRef!.prototype, n
280
+ )?.value === 'function'
281
+ )
282
+ );
283
+ }
284
+
285
+ public getPropertyNames(): ReadonlyArray<string> {
286
+ if (!this.constructorRef?.prototype) return Object.freeze([]);
287
+ return Object.freeze(
288
+ Object.getOwnPropertyNames(this.constructorRef.prototype)
289
+ .filter(n => n !== 'constructor' &&
290
+ typeof Object.getOwnPropertyDescriptor(
291
+ this.constructorRef!.prototype, n
292
+ )?.value !== 'function'
293
+ )
294
+ );
295
+ }
296
+
297
+ public getMemberNames(): ReadonlyArray<string> {
298
+ if (!this.constructorRef?.prototype) return Object.freeze([]);
299
+ return Object.freeze(
300
+ Object.getOwnPropertyNames(this.constructorRef.prototype)
301
+ .filter(n => n !== 'constructor')
302
+ );
303
+ }
304
+
305
+ public hasMethod(name: string): boolean {
306
+ if (!this.constructorRef?.prototype) return false;
307
+ return typeof this.constructorRef.prototype[name] === 'function';
308
+ }
309
+
310
+ public hasProperty(name: string): boolean {
311
+ if (!this.constructorRef?.prototype) return false;
312
+ return name in this.constructorRef.prototype && !this.hasMethod(name);
313
+ }
314
+
315
+ public getStaticMemberNames(): ReadonlyArray<string> {
316
+ if (!this.constructorRef) return Object.freeze([]);
317
+ const skip = new Set(['prototype', 'length', 'name', 'caller', 'arguments']);
318
+ return Object.freeze(
319
+ Object.getOwnPropertyNames(this.constructorRef)
320
+ .filter(n => !skip.has(n))
321
+ );
322
+ }
323
+
324
+
325
+ // ══════════════════════════════════════════════
326
+ // SERIALIZACIÓN
327
+ // ══════════════════════════════════════════════
328
+
329
+ public toString(): string {
330
+ return `Type [${this.name}]`;
331
+ }
332
+
333
+
334
+ public [Symbol.toPrimitive](hint: string): string | number {
335
+
336
+ let hash = 0;
337
+ for (let i = 0; i < this.name.length; i++) {
338
+ hash = ((hash << 5) - hash + this.name.charCodeAt(i)) | 0;
339
+ }
340
+
341
+ return hint === 'number' ? hash : this.toString();
342
+ }
343
+
344
+ public get [Symbol.toStringTag](): string {
345
+ return `Type<${this.name}>`;
346
+ }
347
+
348
+ // ──────────────────────────────────────────────
349
+ // FACTORY INTERNA
350
+ // ──────────────────────────────────────────────
351
+
352
+ private static _getOrCreate<V>(
353
+ key: unknown,
354
+ constructorRef: Constructor<V> | unknown,
355
+ typeCode: TypeCode,
356
+ customName?: string,
357
+ ): Type<V> {
358
+ const cached = this._cache.get(key);
359
+ if (cached) return cached as Type<V>;
360
+
361
+ const name = customName
362
+ ?? (typeof key === 'string' ? key : 'unknown');
363
+
364
+ const ref = typeof constructorRef === 'function'
365
+ ? constructorRef as Constructor<V>
366
+ : undefined;
367
+
368
+ const instance = new Type<V>(name, ref, typeCode);
369
+ this._cache.set(key, instance as Type);
370
+ return instance;
371
+ }
372
+ }
package/src/types.ts CHANGED
@@ -25,8 +25,4 @@ export type QuaternaryFunction<T1, T2, T3, T4, R> = (
25
25
  arg4: T4
26
26
  ) => R;
27
27
 
28
- export type Constructor<T = object, A extends any[] = any[]> =
29
- new (...args: A) => T;
30
-
31
- export type AbstractConstructor<T = object, A extends any[] = any[]> =
32
- abstract new (...args: A) => T;
28
+ export type Constructor<T = unknown> = abstract new (...args: any[]) => T;
package/src/utilities.ts CHANGED
@@ -134,56 +134,7 @@ export function deepEqual(a: any, b: any): boolean {
134
134
  * @param method - HTTP method to use: 'POST' or 'GET' (default: 'POST').
135
135
  * @param target - Optional parameter specifying the target for the form submission (e.g., '_blank', '_self', '_parent', '_top').
136
136
  */
137
- export function submitForm(
138
- url: string,
139
- data: Record<string, any>,
140
- method: 'POST' | 'GET' = 'POST',
141
- target?: '_blank' | '_self' | '_parent' | '_top'
142
- ): void {
143
-
144
- const form = document.createElement('form');
145
- form.method = method.toUpperCase();
146
- form.action = url;
147
- form.style.display = 'none';
148
-
149
- if (target) {
150
- form.target = target;
151
- }
152
-
153
- /**
154
- * Recursively appends inputs to the form, supporting nested keys and arrays.
155
- * @param keyPrefix - Key path, e.g., 'user[name]' or 'tags[]'
156
- * @param value - The value to append (can be nested)
157
- */
158
- const appendInputs = (keyPrefix: string, value: any) => {
159
- if (Array.isArray(value)) {
160
- value.forEach(val => {
161
- appendInputs(`${keyPrefix}[]`, val);
162
- });
163
- } else if (typeof value === 'object' && value !== null) {
164
- for (const subKey in value) {
165
- if (value.hasOwnProperty(subKey)) {
166
- appendInputs(`${keyPrefix}[${subKey}]`, value[subKey]);
167
- }
168
- }
169
- } else {
170
- const input = document.createElement('input');
171
- input.type = 'hidden';
172
- input.name = keyPrefix;
173
- input.value = String(value);
174
- form.appendChild(input);
175
- }
176
- };
177
137
 
178
- for (const key in data) {
179
- if (data.hasOwnProperty(key)) {
180
- appendInputs(key, data[key]);
181
- }
182
- }
183
-
184
- document.body.appendChild(form);
185
- form.submit();
186
- }
187
138
 
188
139
  /**
189
140
  * Compares two objects or arrays to check if they have the same immediate fields and values,
@@ -319,29 +270,7 @@ export function isEmptyOrWhitespace(value: any): boolean {
319
270
  }
320
271
 
321
272
 
322
- /**
323
- * Submits a form via AJAX and returns a Promise that resolves to the Response object.
324
- *
325
- * @param {HTMLFormElement | string} selectorOrElement - The form element or selector.
326
- * @return {Promise<Response>} A Promise that resolves to the Response object.
327
- * @throws {Error} If the element is invalid.
328
- */
329
- export async function ajaxSubmit(selectorOrElement: HTMLFormElement | string): Promise<Response> {
330
273
 
331
- const form = typeof selectorOrElement === 'string'
332
- ? document.querySelector(selectorOrElement)
333
- : selectorOrElement;
334
-
335
- if (!(form instanceof HTMLFormElement)) {
336
- throw new Error("Invalid element.");
337
- }
338
-
339
- // Crear un objeto FormData a partir del formulario
340
- return await fetch(form.action, {
341
- method: form.method,
342
- body: new FormData(form),
343
- });
344
- }
345
274
 
346
275
  /**
347
276
  * Converts an object into an array of key-value pairs.
@@ -386,33 +315,6 @@ export function promisify<T>(thing: Resolvable<T>): Promise<T> {
386
315
  }
387
316
 
388
317
 
389
- export function ajaxSubmission(selectorOrElement: HTMLFormElement | string,
390
- onSuccess: Optional<Supplier<any>> = undefined,
391
- onFailure: Optional<Supplier<any>> = undefined): void {
392
-
393
- const form = typeof selectorOrElement === 'string'
394
- ? document.querySelector(selectorOrElement)
395
- : selectorOrElement;
396
-
397
- if (!(form instanceof HTMLFormElement)) {
398
- return;
399
- }
400
-
401
- form.addEventListener('submit', async (event) => {
402
- event.preventDefault();
403
- let promise = ajaxSubmit(form);
404
- if (promise) {
405
- if (onSuccess)
406
- promise = promise.then(onSuccess);
407
- if (onFailure)
408
- promise.catch(onFailure);
409
- }
410
-
411
- });
412
-
413
-
414
- }
415
-
416
318
 
417
319
  /**
418
320
  * Creates a deep clone of the given object.
@@ -447,77 +349,12 @@ export function deepClone<T>(obj: T): T {
447
349
  *
448
350
  * @param {any} value - The value to determine the type of.
449
351
  * @return {Type} - The type of the given value.
352
+ * @deprecated use Type.of(...)
450
353
  */
451
354
  export function getType(value: any): Type {
452
355
 
453
- return value === null ? Type.Null : Type[typeof value as keyof typeof Type];
454
- }
455
-
456
- export function formToObject(form: HTMLFormElement): Record<string, FormDataEntryValue | FormDataEntryValue[]> {
457
- const fd = new FormData(form);
458
- const out: Record<string, FormDataEntryValue | FormDataEntryValue[]> = {};
459
-
460
- for (const [key, value] of fd.entries()) {
461
- if (key in out) {
462
- const current = out[key];
463
- if (Array.isArray(current)) {
464
- current.push(value);
465
- } else {
466
- out[key] = [current, value];
467
- }
468
- } else {
469
- out[key] = value;
470
- }
471
- }
472
-
473
- return out;
356
+ return Type.of(value);
474
357
  }
475
358
 
476
- /**
477
- * Converts an object to `FormData` format recursively.
478
- *
479
- * @param {Record<string, any>} data - The object data to convert.
480
- * @param {FormData} formData - The `FormData` instance to append data to.
481
- * @param {string} parentKey - The parent key to append to child keys in the `FormData`.
482
- * @returns {FormData} - The `FormData` instance with the converted data.
483
- */
484
- function _objectToFormData(data: Record<string, any>, formData: FormData, parentKey: string = ''): FormData {
485
-
486
- for (const key in data) {
487
- if (data.hasOwnProperty(key)) {
488
- const value = data[key];
489
-
490
- if (value instanceof Date) {
491
- formData.append(parentKey ? `${parentKey}[${key}]` : key, value.toISOString());
492
- } else if (value instanceof File) {
493
- formData.append(parentKey ? `${parentKey}[${key}]` : key, value);
494
- } else if (typeof value === 'object' && !Array.isArray(value)) {
495
- _objectToFormData(value, formData, parentKey ? `${parentKey}[${key}]` : key);
496
- } else if (Array.isArray(value)) {
497
- value.forEach((item, index) => {
498
- const arrayKey = `${parentKey ? `${parentKey}[${key}]` : key}[${index}]`;
499
- if (typeof item === 'object' && !Array.isArray(item)) {
500
- _objectToFormData(item, formData, arrayKey);
501
- } else {
502
- formData.append(arrayKey, item);
503
- }
504
- });
505
- } else {
506
- formData.append(parentKey ? `${parentKey}[${key}]` : key, value);
507
- }
508
- }
509
- }
510
359
 
511
- return formData;
512
- }
513
360
 
514
- /**
515
- * Converts an object into FormData.
516
- *
517
- * @param {Record<string, any>} data - The object to be converted into FormData.
518
- * @return {FormData} - The FormData object representing the converted data.
519
- */
520
- export function objectToFormData(data: Record<string, any>): FormData {
521
- let formData = new FormData();
522
- return _objectToFormData(data, formData);
523
- }