@jvsoft/utils 1.0.0-alpha.4 → 1.0.0-alpha.5

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.
@@ -259,6 +259,30 @@ function eliminarElementos(origen, elementosAEliminar, claves) {
259
259
  return !clavesSet.has(key);
260
260
  });
261
261
  }
262
+ /**
263
+ * Filtra datos localmente según un valor de búsqueda
264
+ * @param data - Array de datos a filtrar
265
+ * @param value - Valor de búsqueda
266
+ * @param campoBuscar - Campo(s) por el cual buscar
267
+ * @returns Array filtrado
268
+ */
269
+ function filtrarDatosLocal(data, value, campoBuscar) {
270
+ if (!value)
271
+ return data;
272
+ const normalizar = (val) => val?.toString()?.toLowerCase() ?? '';
273
+ const esNum = !isNaN(Number(value));
274
+ return data.filter(item => {
275
+ const campos = Array.isArray(campoBuscar) ? campoBuscar : [campoBuscar];
276
+ return campos.some(campo => {
277
+ const campoVal = item[campo];
278
+ if (campoVal == null)
279
+ return false;
280
+ return esNum
281
+ ? campoVal.toString().includes(value.toString())
282
+ : normalizar(campoVal).includes(normalizar(value));
283
+ });
284
+ });
285
+ }
262
286
 
263
287
  function mostrarValorEnBusqueda(campos, idxSel) {
264
288
  const impDataMostrar = () => {
@@ -481,17 +505,192 @@ function changeSelectApi(control, queryService, formControl, tipo, dataExtra = {
481
505
  }
482
506
  });
483
507
  }
508
+ /**
509
+ * Comprueba si un valor es una Promesa
510
+ * @param valor - Valor a verificar
511
+ * @returns true si es una Promise
512
+ */
513
+ function esPromise(valor) {
514
+ return !!valor && typeof valor.then === 'function';
515
+ }
516
+ /**
517
+ * Selecciona todo el texto de un input
518
+ * @param event - Evento del input
519
+ */
520
+ function seleccionarTextoInput$1(event) {
521
+ event.target.select();
522
+ }
523
+ /**
524
+ * Función genérica para vincular un FormControl con datos desde API o Promise.
525
+ * Preparada para migrar a signals en el futuro.
526
+ */
527
+ function changeSelectReformateado(config) {
528
+ const { objThis, tipoReq, formControl, queryService, campoId, minLength = 3, dataExtra = {}, dataExtraVariable = [], anonimo = false, variableResultado = tipoReq, } = config;
529
+ formControl.valueChanges.pipe(debounceTime(500), tap(() => {
530
+ objThis.filtrados[variableResultado + 'tmp'] = isObservable(objThis.filtrados[variableResultado])
531
+ ? []
532
+ : objThis.filtrados[variableResultado] || [];
533
+ if (objThis.filtrados[variableResultado] !== objThis.filtrados[variableResultado + 'tmp']) {
534
+ objThis.filtrados[variableResultado] = [];
535
+ }
536
+ objThis.isLoading = true;
537
+ }), switchMap(value => {
538
+ if (campoId) {
539
+ const existe = objThis.filtrados[variableResultado + 'tmp']
540
+ .findIndex((item) => item[campoId] === value);
541
+ if (existe >= 0) {
542
+ return of({ [tipoReq]: objThis.filtrados[variableResultado + 'tmp'] });
543
+ }
544
+ }
545
+ if (!value || value.length < minLength) {
546
+ objThis.isLoading = false;
547
+ return of({ [tipoReq]: [] });
548
+ }
549
+ const extraVars = Object.fromEntries(dataExtraVariable.map((v) => [v.campo, v.ctrlValue.value]));
550
+ const query = queryService.getDataMethod('GET', tipoReq, { ...dataExtra, ...extraVars, txtBuscar: value }, anonimo);
551
+ if (esPromise(query)) {
552
+ return query
553
+ .then((data) => ({ [tipoReq]: data[tipoReq] ?? [] }))
554
+ .finally(() => { objThis.isLoading = false; });
555
+ }
556
+ return query.pipe(finalize(() => { objThis.isLoading = false; }));
557
+ })).subscribe((data) => {
558
+ objThis.filtrados[variableResultado] = data[tipoReq] ?? [];
559
+ });
560
+ }
484
561
 
485
562
  function seleccionarTextoInput(event) {
486
563
  event.target.select();
487
564
  }
488
565
 
566
+ /**
567
+ * Codifica un string a base64 (método legacy)
568
+ * @param val - String a codificar
569
+ * @returns String codificado en base64
570
+ * @deprecated Use encodeBase64String() en su lugar
571
+ */
489
572
  function b64Encode(val) {
490
573
  return Buffer.from(val, 'binary').toString('base64');
491
574
  }
575
+ /**
576
+ * Decodifica un string desde base64 (método legacy)
577
+ * @param val - String en base64 a decodificar
578
+ * @returns String decodificado
579
+ * @deprecated Use decodeBase64String() en su lugar
580
+ */
492
581
  function b64Decode(val) {
493
582
  return Buffer.from(val, 'base64').toString('binary');
494
583
  }
584
+ /**
585
+ * Codificar string a Base64 (UTF-8 seguro)
586
+ * @param str - String a codificar
587
+ * @returns String codificado en base64
588
+ *
589
+ * @example
590
+ * ```typescript
591
+ * const encoded = encodeBase64String('Hola Mundo ñ');
592
+ * // encoded: "SG9sYSBNdW5kbyDDsQ=="
593
+ * ```
594
+ */
595
+ function encodeBase64String(str) {
596
+ const encoder = new TextEncoder();
597
+ const bytes = encoder.encode(str);
598
+ let binary = '';
599
+ bytes.forEach(b => binary += String.fromCharCode(b));
600
+ return btoa(binary);
601
+ }
602
+ /**
603
+ * Decodificar Base64 a string (UTF-8 seguro)
604
+ * @param b64 - String en base64 a decodificar
605
+ * @returns String decodificado
606
+ *
607
+ * @example
608
+ * ```typescript
609
+ * const decoded = decodeBase64String('SG9sYSBNdW5kbyDDsQ==');
610
+ * // decoded: "Hola Mundo ñ"
611
+ * ```
612
+ */
613
+ function decodeBase64String(b64) {
614
+ const binary = atob(b64);
615
+ const bytes = new Uint8Array(binary.length);
616
+ for (let i = 0; i < binary.length; i++) {
617
+ bytes[i] = binary.charCodeAt(i);
618
+ }
619
+ const decoder = new TextDecoder();
620
+ return decoder.decode(bytes);
621
+ }
622
+ /**
623
+ * Codificar un objeto a base64 (UTF-8 seguro)
624
+ * @param obj - Objeto a codificar
625
+ * @returns String codificado en base64
626
+ *
627
+ * @example
628
+ * ```typescript
629
+ * const obj = { nombre: 'Juan', edad: 25 };
630
+ * const encoded = encodeBase64Object(obj);
631
+ * ```
632
+ */
633
+ function encodeBase64Object(obj) {
634
+ return encodeBase64String(JSON.stringify(obj));
635
+ }
636
+ /**
637
+ * Decodificar un base64 y obtener el objeto original
638
+ * @param b64 - String en base64 a decodificar
639
+ * @returns Objeto decodificado
640
+ *
641
+ * @example
642
+ * ```typescript
643
+ * const obj = decodeBase64Object<{ nombre: string, edad: number }>(encoded);
644
+ * // obj: { nombre: 'Juan', edad: 25 }
645
+ * ```
646
+ */
647
+ function decodeBase64Object(b64) {
648
+ return JSON.parse(decodeBase64String(b64));
649
+ }
650
+ /**
651
+ * Codificar archivo a Base64 (retorna solo el contenido, sin "data:...")
652
+ * @param file - Archivo o Blob a codificar
653
+ * @returns Promise con el string en base64
654
+ *
655
+ * @example
656
+ * ```typescript
657
+ * const file = event.target.files[0];
658
+ * const base64 = await encodeBase64File(file);
659
+ * // base64: "iVBORw0KGgoAAAANSUhEUgAA..."
660
+ * ```
661
+ */
662
+ function encodeBase64File(file) {
663
+ return new Promise((resolve, reject) => {
664
+ const reader = new FileReader();
665
+ reader.onload = () => {
666
+ const result = reader.result;
667
+ resolve(result.split(',')[1]); // quita el prefijo "data:...;base64,"
668
+ };
669
+ reader.onerror = reject;
670
+ reader.readAsDataURL(file);
671
+ });
672
+ }
673
+ /**
674
+ * Decodificar Base64 a Blob (para reconstruir archivos en Angular)
675
+ * @param b64 - String en base64
676
+ * @param mimeType - Tipo MIME del archivo (opcional)
677
+ * @returns Blob con el contenido decodificado
678
+ *
679
+ * @example
680
+ * ```typescript
681
+ * const blob = decodeBase64ToBlob(base64String, 'image/png');
682
+ * const url = URL.createObjectURL(blob);
683
+ * // Usar url para mostrar imagen o descargar
684
+ * ```
685
+ */
686
+ function decodeBase64ToBlob(b64, mimeType = 'application/octet-stream') {
687
+ const byteChars = atob(b64);
688
+ const byteNumbers = new Array(byteChars.length);
689
+ for (let i = 0; i < byteChars.length; i++) {
690
+ byteNumbers[i] = byteChars.charCodeAt(i);
691
+ }
692
+ return new Blob([new Uint8Array(byteNumbers)], { type: mimeType });
693
+ }
495
694
 
496
695
  function getBrowserName() {
497
696
  const agent = window.navigator.userAgent.toLowerCase();
@@ -1504,5 +1703,5 @@ function verificarRUC(ruc) {
1504
1703
  * Generated bundle index. Do not edit.
1505
1704
  */
1506
1705
 
1507
- export { b64Decode, b64Encode, buscarPorCampo, changeSelect, changeSelectApi, changeSelectData, changeSelectDataApi, convertirBytes, deepClone, deepMerge, delLocalStorage, desencriptar, devError, devGroup, devGroupEnd, devLog, devTable, devTime, devTimeEnd, devWarn, downLoadFileStream, eliminarColumnaPorIndex, eliminarDuplicados, eliminarElementos, encriptar, esNumero, establecerQuitarRequired, extraerDominio, formatearFecha, formatearFechaCadena, formatearFechaFormato, generateRandomString, getBrowserName, getCambiarPwd, getDataArchivoFromPath, getFormValidationErrors, getLocalStorage, getUniqueValues, getUniqueValuesByProperty, groupBy, inicializarVariablesSessionStorage, isEmail, isProduction, jwtToken, jwtTokenData, jwtTokenExpiracion, jwtTokenExpiracionFaltante, localStorageKeys, markAsTouchedWithoutEmitEvent, maskEmail, mensajeAlerta, mensajeConfirmacion, mensajeTimer, mensajeToast, mensajesDeError, mensajesErrorFormControl, mostrarValorEnBusqueda, nestGroupsBy, numberToWords, objectPropertiesBoolean, objectPropertiesToType, obtenerHostDesdeUrl, obtenerMimeType, obtenerUltimoOrden, ordenarArray, ordenarPorPropiedad, ordenarPorPropiedades, roundToDecimal, sanitizarNombreArchivo, seleccionarTextoInput, setCambiarPwd, setControlDesdeLista, setJwtTokenData, setLocalStorage, setProductionMode, sumarObjetos, sumarPropiedades, toFormData, transformarFechasPorNombreDeCampo, verificarRUC };
1706
+ export { b64Decode, b64Encode, buscarPorCampo, changeSelect, changeSelectApi, changeSelectData, changeSelectDataApi, changeSelectReformateado, convertirBytes, decodeBase64Object, decodeBase64String, decodeBase64ToBlob, deepClone, deepMerge, delLocalStorage, desencriptar, devError, devGroup, devGroupEnd, devLog, devTable, devTime, devTimeEnd, devWarn, downLoadFileStream, eliminarColumnaPorIndex, eliminarDuplicados, eliminarElementos, encodeBase64File, encodeBase64Object, encodeBase64String, encriptar, esNumero, esPromise, establecerQuitarRequired, extraerDominio, filtrarDatosLocal, formatearFecha, formatearFechaCadena, formatearFechaFormato, generateRandomString, getBrowserName, getCambiarPwd, getDataArchivoFromPath, getFormValidationErrors, getLocalStorage, getUniqueValues, getUniqueValuesByProperty, getValueByPath, groupBy, inicializarVariablesSessionStorage, isEmail, isProduction, jwtToken, jwtTokenData, jwtTokenExpiracion, jwtTokenExpiracionFaltante, localStorageKeys, markAsTouchedWithoutEmitEvent, maskEmail, mensajeAlerta, mensajeConfirmacion, mensajeTimer, mensajeToast, mensajesDeError, mensajesErrorFormControl, mostrarValorEnBusqueda, nestGroupsBy, numberToWords, objectPropertiesBoolean, objectPropertiesToType, obtenerHostDesdeUrl, obtenerMimeType, obtenerUltimoOrden, ordenarArray, ordenarPorPropiedad, ordenarPorPropiedades, roundToDecimal, sanitizarNombreArchivo, seleccionarTextoInput, setCambiarPwd, setControlDesdeLista, setJwtTokenData, setLocalStorage, setProductionMode, sumarObjetos, sumarPropiedades, toFormData, transformarFechasPorNombreDeCampo, verificarRUC };
1508
1707
  //# sourceMappingURL=jvsoft-utils-src-functions.mjs.map