inputs-sanitize 1.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/LICENSE +21 -0
- package/README.md +423 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/sanitize.d.ts +7 -0
- package/dist/cjs/sanitize.d.ts.map +1 -0
- package/dist/cjs/sanitize.js +56 -0
- package/dist/cjs/sanitize.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/sanitize.d.ts +7 -0
- package/dist/esm/sanitize.d.ts.map +1 -0
- package/dist/esm/sanitize.js +53 -0
- package/dist/esm/sanitize.js.map +1 -0
- package/package.json +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joan Lozano
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
# inputs-sanitize 🛡️
|
|
2
|
+
|
|
3
|
+
A lightweight, zero-dependency utility to sanitize and filter input strings. Perfect for React, Vue, Angular, Svelte and other JavaScript/TypeScript frameworks.
|
|
4
|
+
|
|
5
|
+
**Supports both CommonJS and ES Modules (ESM)** for maximum compatibility with npm, yarn, and pnpm.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ **Multiple sanitization modes** (text, numbers, alphanumeric, safe)
|
|
10
|
+
- ✅ **TypeScript support** with full type definitions
|
|
11
|
+
- ✅ **Framework agnostic** - works with React, Vue, Angular, Svelte, etc.
|
|
12
|
+
- ✅ **Dual module support** - CommonJS & ESM
|
|
13
|
+
- ✅ **Zero dependencies**
|
|
14
|
+
- ✅ **Small bundle size** (~1KB minified)
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# using npm
|
|
20
|
+
npm install inputs-sanitize
|
|
21
|
+
|
|
22
|
+
# using yarn
|
|
23
|
+
yarn add inputs-sanitize
|
|
24
|
+
|
|
25
|
+
# using pnpm
|
|
26
|
+
pnpm add inputs-sanitize
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
### `sanitize(value: string, mode?: SanitizeMode, options?: NumberOptions): string`
|
|
32
|
+
|
|
33
|
+
Sanitizes input strings based on the specified mode.
|
|
34
|
+
|
|
35
|
+
#### SanitizeMode Types
|
|
36
|
+
|
|
37
|
+
**`"text"`** - Letras con acentos, espacios, puntos y comas
|
|
38
|
+
- ✓ Permite: `a-z`, `A-Z`, `áéíóúÁÉÍÓÚñÑ`, espacios, `.`, `,`
|
|
39
|
+
- ✗ Elimina: números, caracteres especiales
|
|
40
|
+
- **Uso:** Nombres, direcciones, descripciones
|
|
41
|
+
- **Ejemplo:** `"José María, México."` → `"José María, México."`
|
|
42
|
+
|
|
43
|
+
**`"numbers"`** - Solo números con soporte decimal y negativo opcional
|
|
44
|
+
- ✓ Permite: `0-9`, `.` (decimal si `allowDecimal=true`), `-` (negativo si `allowNegative=true`)
|
|
45
|
+
- ✗ Elimina: letras, caracteres especiales
|
|
46
|
+
- **Opciones:** `allowDecimal` (default: true), `allowNegative` (default: true)
|
|
47
|
+
- **Uso:** Precios, cantidades, edades, códigos numéricos
|
|
48
|
+
- **Ejemplo:**
|
|
49
|
+
- `"$99.99"` → `"99.99"`
|
|
50
|
+
- `"-42.5"` (con opciones) → `"-42.5"`
|
|
51
|
+
- `"-42.5"` (sin negativos) → `"42.5"`
|
|
52
|
+
|
|
53
|
+
**`"alphanumeric"`** - Combinación de TEXT + NUMBERS
|
|
54
|
+
- ✓ Permite: `a-z`, `A-Z`, `áéíóúÁÉÍÓÚñÑ`, `0-9`, espacios, `.`, `,`
|
|
55
|
+
- ✗ Elimina: caracteres especiales (@ ! # $ % etc.)
|
|
56
|
+
- **Uso:** Direcciones con números, nombres con códigos, descripciones con valores
|
|
57
|
+
- **Ejemplo:** `"Calle 123, Apto 45, México."` → `"Calle 123, Apto 45, México."`
|
|
58
|
+
|
|
59
|
+
**`"safe"`** - Solo letras, números y espacios (sin acentos)
|
|
60
|
+
- ✓ Permite: `a-z`, `A-Z`, `0-9`, espacios
|
|
61
|
+
- ✗ Elimina: acentos, puntos, comas, caracteres especiales
|
|
62
|
+
- **Uso:** Usernames, códigos, referencias
|
|
63
|
+
- **Ejemplo:** `"josé_user@123"` → `"jos user123"`
|
|
64
|
+
|
|
65
|
+
**`"all"`** - Sin cambios (valor por defecto)
|
|
66
|
+
- ✓ Permite: Todo
|
|
67
|
+
- **Uso:** Cuando no necesitas filtrado
|
|
68
|
+
- **Ejemplo:** `"José: $123.45!"` → `"José: $123.45!"`
|
|
69
|
+
|
|
70
|
+
#### NumberOptions
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
interface NumberOptions {
|
|
74
|
+
allowDecimal?: boolean; // default: true
|
|
75
|
+
allowNegative?: boolean; // default: true
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Estas opciones **solo aplican al modo `"numbers"`**:
|
|
80
|
+
|
|
81
|
+
- **`allowDecimal`**: Permite caracteres de punto (`.`) para números decimales
|
|
82
|
+
- `true` (default): `"99.99"` es válido
|
|
83
|
+
- `false`: `"99.99"` → `"9999"`
|
|
84
|
+
|
|
85
|
+
- **`allowNegative`**: Permite caracteres de guion (`-`) para números negativos
|
|
86
|
+
- `true` (default): `"-42"` es válido
|
|
87
|
+
- `false`: `"-42"` → `"42"`
|
|
88
|
+
|
|
89
|
+
### Input Type Handling
|
|
90
|
+
|
|
91
|
+
La función maneja automáticamente diferentes tipos de entrada:
|
|
92
|
+
|
|
93
|
+
| Input | Tipo | Comportamiento |
|
|
94
|
+
|-------|------|----------------|
|
|
95
|
+
| `"José María"` | string | ✅ Se sanitiza normalmente |
|
|
96
|
+
| `123` | number | ✅ Se convierte a string |
|
|
97
|
+
| `null` | null | ✅ Devuelve `""` (vacío) |
|
|
98
|
+
| `undefined` | undefined | ✅ Devuelve `""` (vacío) |
|
|
99
|
+
| `[1, 2, 3]` | array | ✅ Rechaza, devuelve `""` |
|
|
100
|
+
| `{name: 'José'}` | object | ✅ Rechaza, devuelve `""` |
|
|
101
|
+
| `() => {}` | function | ✅ Rechaza, devuelve `""` |
|
|
102
|
+
|
|
103
|
+
**Notas importantes:**
|
|
104
|
+
- ✅ Solo acepta `string` y `number` como valores válidos
|
|
105
|
+
- ✅ Automáticamente trimea espacios en blanco
|
|
106
|
+
- ✅ Rechaza objetos, arrays y funciones (devuelve vacío en lugar de error)
|
|
107
|
+
- ✅ Nunca lanza excepciones
|
|
108
|
+
|
|
109
|
+
## Usage Examples
|
|
110
|
+
|
|
111
|
+
### React
|
|
112
|
+
|
|
113
|
+
```jsx
|
|
114
|
+
import { sanitize } from 'inputs-sanitize';
|
|
115
|
+
import { useState } from 'react';
|
|
116
|
+
|
|
117
|
+
export default function MyComponent() {
|
|
118
|
+
const [email, setEmail] = useState('');
|
|
119
|
+
const [username, setUsername] = useState('');
|
|
120
|
+
|
|
121
|
+
const handleEmailChange = (e) => {
|
|
122
|
+
const sanitized = sanitize(e.target.value, 'safe');
|
|
123
|
+
setEmail(sanitized);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const handleUsernameChange = (e) => {
|
|
127
|
+
const sanitized = sanitize(e.target.value, 'alphanumeric');
|
|
128
|
+
setUsername(sanitized);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<div>
|
|
133
|
+
<input
|
|
134
|
+
type="email"
|
|
135
|
+
value={email}
|
|
136
|
+
onChange={handleEmailChange}
|
|
137
|
+
placeholder="Email"
|
|
138
|
+
/>
|
|
139
|
+
<input
|
|
140
|
+
type="text"
|
|
141
|
+
value={username}
|
|
142
|
+
onChange={handleUsernameChange}
|
|
143
|
+
placeholder="Username"
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Vue 3
|
|
151
|
+
|
|
152
|
+
```vue
|
|
153
|
+
<template>
|
|
154
|
+
<div>
|
|
155
|
+
<input
|
|
156
|
+
v-model="email"
|
|
157
|
+
@input="email = sanitize($event.target.value, 'safe')"
|
|
158
|
+
type="email"
|
|
159
|
+
placeholder="Email"
|
|
160
|
+
/>
|
|
161
|
+
<input
|
|
162
|
+
v-model="amount"
|
|
163
|
+
@input="amount = sanitize($event.target.value, 'numbers', { allowDecimal: true })"
|
|
164
|
+
type="number"
|
|
165
|
+
placeholder="Amount"
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
</template>
|
|
169
|
+
|
|
170
|
+
<script setup>
|
|
171
|
+
import { ref } from 'vue';
|
|
172
|
+
import { sanitize } from 'inputs-sanitize';
|
|
173
|
+
|
|
174
|
+
const email = ref('');
|
|
175
|
+
const amount = ref('');
|
|
176
|
+
</script>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Vue 2
|
|
180
|
+
|
|
181
|
+
```vue
|
|
182
|
+
<template>
|
|
183
|
+
<div>
|
|
184
|
+
<input
|
|
185
|
+
v-model="name"
|
|
186
|
+
@input="handleNameChange"
|
|
187
|
+
type="text"
|
|
188
|
+
placeholder="Full Name"
|
|
189
|
+
/>
|
|
190
|
+
<input
|
|
191
|
+
v-model="phone"
|
|
192
|
+
@input="handlePhoneChange"
|
|
193
|
+
type="tel"
|
|
194
|
+
placeholder="Phone (numbers only)"
|
|
195
|
+
/>
|
|
196
|
+
</div>
|
|
197
|
+
</template>
|
|
198
|
+
|
|
199
|
+
<script>
|
|
200
|
+
import { sanitize } from 'inputs-sanitize';
|
|
201
|
+
|
|
202
|
+
export default {
|
|
203
|
+
data() {
|
|
204
|
+
return {
|
|
205
|
+
name: '',
|
|
206
|
+
phone: ''
|
|
207
|
+
};
|
|
208
|
+
},
|
|
209
|
+
methods: {
|
|
210
|
+
handleNameChange() {
|
|
211
|
+
this.name = sanitize(this.name, 'text');
|
|
212
|
+
},
|
|
213
|
+
handlePhoneChange() {
|
|
214
|
+
this.phone = sanitize(this.phone, 'numbers', { allowNegative: false });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
</script>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Vanilla JavaScript
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
import { sanitize } from 'inputs-sanitize';
|
|
225
|
+
|
|
226
|
+
// CommonJS
|
|
227
|
+
// const { sanitize } = require('inputs-sanitize');
|
|
228
|
+
|
|
229
|
+
const input = document.getElementById('myInput');
|
|
230
|
+
input.addEventListener('input', (e) => {
|
|
231
|
+
e.target.value = sanitize(e.target.value, 'alphanumeric');
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Examples by Mode
|
|
236
|
+
|
|
237
|
+
### Text Mode
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { sanitize } from 'inputs-sanitize';
|
|
241
|
+
|
|
242
|
+
// Permitir: letras (acentos), espacios, puntos, comas
|
|
243
|
+
// Eliminar: números, caracteres especiales
|
|
244
|
+
|
|
245
|
+
sanitize('José María, México 123!', 'text');
|
|
246
|
+
// → "José María, México "
|
|
247
|
+
|
|
248
|
+
sanitize('Dr. Juan Pérez, Médico.', 'text');
|
|
249
|
+
// → "Dr. Juan Pérez, Médico."
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Numbers Mode
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
// Permitir: números, decimales (opcional), negativos (opcional)
|
|
256
|
+
// Eliminar: letras, caracteres especiales
|
|
257
|
+
|
|
258
|
+
// Con decimales y negativos (default)
|
|
259
|
+
sanitize('Price: $99.99', 'numbers');
|
|
260
|
+
// → "99.99"
|
|
261
|
+
|
|
262
|
+
sanitize('Temperature: -15.5°C', 'numbers');
|
|
263
|
+
// → "-15.5"
|
|
264
|
+
|
|
265
|
+
// Sin decimales
|
|
266
|
+
sanitize('$99.99', 'numbers', { allowDecimal: false });
|
|
267
|
+
// → "9999"
|
|
268
|
+
|
|
269
|
+
// Sin negativos
|
|
270
|
+
sanitize('-42.5', 'numbers', { allowNegative: false });
|
|
271
|
+
// → "42.5"
|
|
272
|
+
|
|
273
|
+
// Sin ambos
|
|
274
|
+
sanitize('-$99.99', 'numbers', { allowDecimal: false, allowNegative: false });
|
|
275
|
+
// → "9999"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Alphanumeric Mode
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// Permitir: letras (acentos), números, espacios, puntos, comas
|
|
282
|
+
// Eliminar: caracteres especiales (@!#$%^&*)
|
|
283
|
+
|
|
284
|
+
sanitize('Calle Principal 123, Apto 4A.', 'alphanumeric');
|
|
285
|
+
// → "Calle Principal 123, Apto 4A."
|
|
286
|
+
|
|
287
|
+
sanitize('José María: $123.45 @user!', 'alphanumeric');
|
|
288
|
+
// → "José María 123.45 user"
|
|
289
|
+
|
|
290
|
+
sanitize('Order #12345, Amount: $99.99, Client: María-José', 'alphanumeric');
|
|
291
|
+
// → "Order 12345, Amount 99.99, Client MaríaJosé"
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Safe Mode
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
// Permitir: letras (sin acentos), números, espacios
|
|
298
|
+
// Eliminar: acentos, puntos, comas, caracteres especiales
|
|
299
|
+
|
|
300
|
+
sanitize('<script>alert("xss")</script>', 'safe');
|
|
301
|
+
// → "scriptalertxssscript"
|
|
302
|
+
|
|
303
|
+
sanitize('user@email.com', 'safe');
|
|
304
|
+
// → "useremailcom"
|
|
305
|
+
|
|
306
|
+
sanitize('José_123@domain', 'safe');
|
|
307
|
+
// → "Jos 123domain"
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### All Mode
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
// Permitir: todo (sin cambios)
|
|
314
|
+
|
|
315
|
+
sanitize('José María: $123.45 @user!', 'all');
|
|
316
|
+
// → "José María: $123.45 @user!"
|
|
317
|
+
|
|
318
|
+
sanitize('<script>dangerous</script>', 'all');
|
|
319
|
+
// → "<script>dangerous</script>"
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Comparison Table
|
|
323
|
+
|
|
324
|
+
### Character Support by Mode
|
|
325
|
+
|
|
326
|
+
| Carácter | text | numbers | alphanumeric | safe | all |
|
|
327
|
+
|----------|------|---------|--------------|------|-----|
|
|
328
|
+
| **Letras** (a-z, A-Z) | ✓ | ✗ | ✓ | ✓ | ✓ |
|
|
329
|
+
| **Acentuadas** (á, é, í, ó, ú, ñ) | ✓ | ✗ | ✓ | ✗ | ✓ |
|
|
330
|
+
| **Números** (0-9) | ✗ | ✓ | ✓ | ✓ | ✓ |
|
|
331
|
+
| **Punto** (.) | ✓ | ✓* | ✓ | ✗ | ✓ |
|
|
332
|
+
| **Coma** (,) | ✓ | ✗ | ✓ | ✗ | ✓ |
|
|
333
|
+
| **Guion** (-) | ✗ | ✓* | ✗ | ✗ | ✓ |
|
|
334
|
+
| **Espacio** | ✓ | ✗ | ✓ | ✓ | ✓ |
|
|
335
|
+
| **Especiales** (@!#$%^&*) | ✗ | ✗ | ✗ | ✗ | ✓ |
|
|
336
|
+
|
|
337
|
+
*`numbers mode`: punto (.) = decimal si `allowDecimal=true`, guion (-) = negativo si `allowNegative=true`
|
|
338
|
+
|
|
339
|
+
## Framework Integration
|
|
340
|
+
|
|
341
|
+
### TypeScript with React
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import { sanitize, SanitizeMode } from 'inputs-sanitize';
|
|
345
|
+
import { ChangeEvent, useState } from 'react';
|
|
346
|
+
|
|
347
|
+
interface FormData {
|
|
348
|
+
username: string;
|
|
349
|
+
amount: string;
|
|
350
|
+
description: string;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export function MyForm() {
|
|
354
|
+
const [data, setData] = useState<FormData>({
|
|
355
|
+
username: '',
|
|
356
|
+
amount: '',
|
|
357
|
+
description: ''
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
const handleChange = (
|
|
361
|
+
e: ChangeEvent<HTMLInputElement>,
|
|
362
|
+
mode: SanitizeMode
|
|
363
|
+
) => {
|
|
364
|
+
const { name, value } = e.target;
|
|
365
|
+
setData(prev => ({
|
|
366
|
+
...prev,
|
|
367
|
+
[name]: sanitize(value, mode)
|
|
368
|
+
}));
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
<form>
|
|
373
|
+
<input
|
|
374
|
+
name="username"
|
|
375
|
+
value={data.username}
|
|
376
|
+
onChange={(e) => handleChange(e, 'alphanumeric')}
|
|
377
|
+
placeholder="Username"
|
|
378
|
+
/>
|
|
379
|
+
<input
|
|
380
|
+
name="amount"
|
|
381
|
+
value={data.amount}
|
|
382
|
+
onChange={(e) => handleChange(e, 'numbers')}
|
|
383
|
+
placeholder="Amount"
|
|
384
|
+
/>
|
|
385
|
+
<textarea
|
|
386
|
+
name="description"
|
|
387
|
+
value={data.description}
|
|
388
|
+
onChange={(e) =>
|
|
389
|
+
setData(prev => ({
|
|
390
|
+
...prev,
|
|
391
|
+
description: sanitize(e.target.value, 'safe')
|
|
392
|
+
}))
|
|
393
|
+
}
|
|
394
|
+
placeholder="Description"
|
|
395
|
+
/>
|
|
396
|
+
</form>
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Package Compatibility
|
|
402
|
+
|
|
403
|
+
| Package Manager | Support |
|
|
404
|
+
|-----------------|---------|
|
|
405
|
+
| npm | ✅ Yes |
|
|
406
|
+
| yarn | ✅ Yes |
|
|
407
|
+
| pnpm | ✅ Yes |
|
|
408
|
+
| Node.js | ✅ 14+ |
|
|
409
|
+
| Browser ES2020+ | ✅ Yes |
|
|
410
|
+
|
|
411
|
+
## Module Formats
|
|
412
|
+
|
|
413
|
+
This package supports both module formats:
|
|
414
|
+
|
|
415
|
+
- **CommonJS** (`dist/cjs/index.js`) - for Node.js and older build tools
|
|
416
|
+
- **ESM** (`dist/esm/index.js`) - for modern applications and bundlers
|
|
417
|
+
|
|
418
|
+
The correct format is automatically selected based on your environment.
|
|
419
|
+
|
|
420
|
+
## License
|
|
421
|
+
|
|
422
|
+
MIT
|
|
423
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitize = void 0;
|
|
4
|
+
var sanitize_1 = require("./sanitize");
|
|
5
|
+
Object.defineProperty(exports, "sanitize", { enumerable: true, get: function () { return sanitize_1.sanitize; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type SanitizeMode = "text" | "numbers" | "alphanumeric" | "safe" | "all";
|
|
2
|
+
export interface NumberOptions {
|
|
3
|
+
allowDecimal?: boolean;
|
|
4
|
+
allowNegative?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function sanitize(value: string | number | null | undefined | any, mode?: SanitizeMode, options?: NumberOptions): string;
|
|
7
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/sanitize.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAClB,MAAM,GACN,SAAS,GACT,cAAc,GACd,MAAM,GACN,KAAK,CAAC;AAEZ,MAAM,WAAW,aAAa;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,QAAQ,CACpB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,EAC/C,IAAI,GAAE,YAAoB,EAC1B,OAAO,GAAE,aAAkB,GAC5B,MAAM,CA8DR"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitize = sanitize;
|
|
4
|
+
function sanitize(value, mode = "all", options = {}) {
|
|
5
|
+
// Rechazar valores null y undefined
|
|
6
|
+
if (value === null || value === undefined) {
|
|
7
|
+
return "";
|
|
8
|
+
}
|
|
9
|
+
// Solo aceptar string y number
|
|
10
|
+
// Rechazar objetos, arrays, funciones, símbolos, etc.
|
|
11
|
+
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
// Convertir a string
|
|
15
|
+
let stringValue = String(value).trim();
|
|
16
|
+
if (!stringValue)
|
|
17
|
+
return "";
|
|
18
|
+
switch (mode) {
|
|
19
|
+
case "text":
|
|
20
|
+
return stringValue.replace(/[^a-zA-ZáéíóúÁÉÍÓÚñÑ\s.,]/g, "");
|
|
21
|
+
case "numbers": {
|
|
22
|
+
const { allowDecimal = true, allowNegative = true } = options;
|
|
23
|
+
let result = stringValue;
|
|
24
|
+
// quitar notación científica
|
|
25
|
+
result = result.replace(/[eE]/g, "");
|
|
26
|
+
// solo números básicos
|
|
27
|
+
result = result.replace(/[^0-9.\-]/g, "");
|
|
28
|
+
if (!allowDecimal) {
|
|
29
|
+
result = result.replace(/\./g, "");
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const parts = result.split(".");
|
|
33
|
+
if (parts.length > 2) {
|
|
34
|
+
result = parts[0] + "." + parts.slice(1).join("");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!allowNegative) {
|
|
38
|
+
result = result.replace(/-/g, "");
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
result = result.replace(/(?!^)-/g, "");
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
case "alphanumeric":
|
|
46
|
+
// Combina text + numbers: letras (con acentos), números, espacios, puntos, comas
|
|
47
|
+
return stringValue.replace(/[^a-zA-ZáéíóúÁÉÍÓÚñÑ0-9\s.,]/g, "");
|
|
48
|
+
case "safe":
|
|
49
|
+
// Solo letras, números y espacios
|
|
50
|
+
return stringValue.replace(/[^a-zA-Z0-9\s]/g, "");
|
|
51
|
+
case "all":
|
|
52
|
+
default:
|
|
53
|
+
return stringValue;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/sanitize.ts"],"names":[],"mappings":";;AAYA,4BAkEC;AAlED,SAAgB,QAAQ,CACpB,KAA+C,EAC/C,OAAqB,KAAK,EAC1B,UAAyB,EAAE;IAE3B,oCAAoC;IACpC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,sDAAsD;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzD,OAAO,EAAE,CAAC;IACd,CAAC;IAED,qBAAqB;IACrB,IAAI,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAEvC,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,MAAM;YACP,OAAO,WAAW,CAAC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC;QAEjE,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,aAAa,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;YAE9D,IAAI,MAAM,GAAG,WAAW,CAAC;YAEzB,6BAA6B;YAC7B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAErC,uBAAuB;YACvB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAE1C,IAAI,CAAC,YAAY,EAAE,CAAC;gBAChB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACJ,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACnB,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACtD,CAAC;YACL,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAC;gBACjB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC;YAED,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,KAAK,cAAc;YACf,iFAAiF;YACjF,OAAO,WAAW,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;QAEpE,KAAK,MAAM;YACP,kCAAkC;YAClC,OAAO,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAEtD,KAAK,KAAK,CAAC;QACX;YACI,OAAO,WAAW,CAAC;IAC3B,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type SanitizeMode = "text" | "numbers" | "alphanumeric" | "safe" | "all";
|
|
2
|
+
export interface NumberOptions {
|
|
3
|
+
allowDecimal?: boolean;
|
|
4
|
+
allowNegative?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function sanitize(value: string | number | null | undefined | any, mode?: SanitizeMode, options?: NumberOptions): string;
|
|
7
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/sanitize.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAClB,MAAM,GACN,SAAS,GACT,cAAc,GACd,MAAM,GACN,KAAK,CAAC;AAEZ,MAAM,WAAW,aAAa;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,QAAQ,CACpB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,EAC/C,IAAI,GAAE,YAAoB,EAC1B,OAAO,GAAE,aAAkB,GAC5B,MAAM,CA8DR"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function sanitize(value, mode = "all", options = {}) {
|
|
2
|
+
// Rechazar valores null y undefined
|
|
3
|
+
if (value === null || value === undefined) {
|
|
4
|
+
return "";
|
|
5
|
+
}
|
|
6
|
+
// Solo aceptar string y number
|
|
7
|
+
// Rechazar objetos, arrays, funciones, símbolos, etc.
|
|
8
|
+
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
9
|
+
return "";
|
|
10
|
+
}
|
|
11
|
+
// Convertir a string
|
|
12
|
+
let stringValue = String(value).trim();
|
|
13
|
+
if (!stringValue)
|
|
14
|
+
return "";
|
|
15
|
+
switch (mode) {
|
|
16
|
+
case "text":
|
|
17
|
+
return stringValue.replace(/[^a-zA-ZáéíóúÁÉÍÓÚñÑ\s.,]/g, "");
|
|
18
|
+
case "numbers": {
|
|
19
|
+
const { allowDecimal = true, allowNegative = true } = options;
|
|
20
|
+
let result = stringValue;
|
|
21
|
+
// quitar notación científica
|
|
22
|
+
result = result.replace(/[eE]/g, "");
|
|
23
|
+
// solo números básicos
|
|
24
|
+
result = result.replace(/[^0-9.\-]/g, "");
|
|
25
|
+
if (!allowDecimal) {
|
|
26
|
+
result = result.replace(/\./g, "");
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const parts = result.split(".");
|
|
30
|
+
if (parts.length > 2) {
|
|
31
|
+
result = parts[0] + "." + parts.slice(1).join("");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!allowNegative) {
|
|
35
|
+
result = result.replace(/-/g, "");
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
result = result.replace(/(?!^)-/g, "");
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
case "alphanumeric":
|
|
43
|
+
// Combina text + numbers: letras (con acentos), números, espacios, puntos, comas
|
|
44
|
+
return stringValue.replace(/[^a-zA-ZáéíóúÁÉÍÓÚñÑ0-9\s.,]/g, "");
|
|
45
|
+
case "safe":
|
|
46
|
+
// Solo letras, números y espacios
|
|
47
|
+
return stringValue.replace(/[^a-zA-Z0-9\s]/g, "");
|
|
48
|
+
case "all":
|
|
49
|
+
default:
|
|
50
|
+
return stringValue;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/sanitize.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,QAAQ,CACpB,KAA+C,EAC/C,OAAqB,KAAK,EAC1B,UAAyB,EAAE;IAE3B,oCAAoC;IACpC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,sDAAsD;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzD,OAAO,EAAE,CAAC;IACd,CAAC;IAED,qBAAqB;IACrB,IAAI,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAEvC,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,MAAM;YACP,OAAO,WAAW,CAAC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC;QAEjE,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,aAAa,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;YAE9D,IAAI,MAAM,GAAG,WAAW,CAAC;YAEzB,6BAA6B;YAC7B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAErC,uBAAuB;YACvB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAE1C,IAAI,CAAC,YAAY,EAAE,CAAC;gBAChB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACJ,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACnB,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACtD,CAAC;YACL,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAC;gBACjB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC;YAED,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,KAAK,cAAc;YACf,iFAAiF;YACjF,OAAO,WAAW,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;QAEpE,KAAK,MAAM;YACP,kCAAkC;YAClC,OAAO,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAEtD,KAAK,KAAK,CAAC;QACX;YACI,OAAO,WAAW,CAAC;IAC3B,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "inputs-sanitize",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lightweight utility to sanitize and filter input strings for React, Vue and other frameworks",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"require": "./dist/cjs/index.js",
|
|
12
|
+
"types": "./dist/esm/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "npm run build:cjs && npm run build:esm",
|
|
20
|
+
"build:cjs": "tsc --module commonjs --outDir dist/cjs",
|
|
21
|
+
"build:esm": "tsc --module esnext --outDir dist/esm",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"clean": "rm -rf dist"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"sanitize",
|
|
27
|
+
"input",
|
|
28
|
+
"validation",
|
|
29
|
+
"filter",
|
|
30
|
+
"react",
|
|
31
|
+
"vue",
|
|
32
|
+
"angular",
|
|
33
|
+
"svelte"
|
|
34
|
+
],
|
|
35
|
+
"author": "Joan Lozano",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"packageManager": "pnpm@10.15.0",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"typescript": "^5.5.0"
|
|
40
|
+
}
|
|
41
|
+
}
|