q-type 0.1.2
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 +312 -0
- package/dist/index.cjs +602 -0
- package/dist/index.d.cts +612 -0
- package/dist/index.d.ts +612 -0
- package/dist/index.js +559 -0
- package/package.json +26 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clase base abstracta para todo esquema de Qtype.
|
|
3
|
+
*
|
|
4
|
+
* Cada esquema concreto (QString, QNumber, QSchema, etc.) extiende esta clase
|
|
5
|
+
* e implementa {@link decode} y {@link encode}.
|
|
6
|
+
*
|
|
7
|
+
* @typeParam T - El tipo TypeScript que representa este esquema.
|
|
8
|
+
*/
|
|
9
|
+
declare abstract class QType<T> {
|
|
10
|
+
/** Discriminante de runtime que identifica el tipo de esquema. */
|
|
11
|
+
abstract readonly kind: string;
|
|
12
|
+
/**
|
|
13
|
+
* Decodifica un string crudo en el valor tipado {@link T}.
|
|
14
|
+
*
|
|
15
|
+
* @throws {QtypeParseError} si el string no es válido.
|
|
16
|
+
*/
|
|
17
|
+
abstract decode(raw: string, ctx: DecodeContext): T;
|
|
18
|
+
/**
|
|
19
|
+
* Codifica un valor tipado {@link T} de vuelta a su representación en string.
|
|
20
|
+
*/
|
|
21
|
+
abstract encode(value: T, opts?: EncodeOptions): string;
|
|
22
|
+
}
|
|
23
|
+
/** Contexto que se propaga durante la decodificación para generar mensajes de error precisos. */
|
|
24
|
+
interface DecodeContext {
|
|
25
|
+
readonly key: string;
|
|
26
|
+
readonly path: string;
|
|
27
|
+
readonly raw: string;
|
|
28
|
+
}
|
|
29
|
+
/** Opciones de codificación compartidas por todos los esquemas. */
|
|
30
|
+
interface EncodeOptions {
|
|
31
|
+
/** Extiende la salida a al menos N segmentos (solo aplica en {@link QSchema}). */
|
|
32
|
+
length?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extrae el tipo TypeScript a partir de una instancia de esquema.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const Name = q.String();
|
|
40
|
+
* type Name = Static<typeof Name>; // string
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
type Static<T extends QType<any>> = T extends QType<infer U> ? U : never;
|
|
44
|
+
/** Mapa de propiedades que define la forma de un {@link QObject} o {@link QSchema}. */
|
|
45
|
+
type SchemaProps = Record<string, QType<any>>;
|
|
46
|
+
/**
|
|
47
|
+
* Desenvuelve {@link QPositioned}`<T>` → `T`.
|
|
48
|
+
*
|
|
49
|
+
* Para cualquier otro esquema se comporta como {@link Static}.
|
|
50
|
+
*
|
|
51
|
+
* @internal — Usado por {@link FilterAt}.
|
|
52
|
+
*/
|
|
53
|
+
type UnwrapAt<T extends QType<any>> = T extends {
|
|
54
|
+
kind: "positioned";
|
|
55
|
+
decode(raw: string, ctx: DecodeContext): infer U;
|
|
56
|
+
} ? U : Static<T>;
|
|
57
|
+
/**
|
|
58
|
+
* Tipo resultante de un {@link QSchema}: un objeto cuyas claves son las
|
|
59
|
+
* propiedades declaradas y cuyos valores son los tipos decodificados.
|
|
60
|
+
*/
|
|
61
|
+
type FilterAt<T extends SchemaProps> = { [K in keyof T] : UnwrapAt<T[K]> };
|
|
62
|
+
/**
|
|
63
|
+
* Error lanzado cuando el parseo de un segmento falla.
|
|
64
|
+
*
|
|
65
|
+
* Incluye el contexto completo (key, path, rawValue) para facilitar el debug.
|
|
66
|
+
*/
|
|
67
|
+
declare class QtypeParseError extends Error {
|
|
68
|
+
readonly key: string;
|
|
69
|
+
readonly path: string;
|
|
70
|
+
readonly rawValue: string;
|
|
71
|
+
constructor(message: string, ctx: DecodeContext);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Resultado de {@link QSchema.safeParse} y {@link QUnion.safeParse}.
|
|
75
|
+
*
|
|
76
|
+
* `success: true` con `data`, o `success: false` con `error`.
|
|
77
|
+
*/
|
|
78
|
+
type SafeResult<T> = {
|
|
79
|
+
success: true;
|
|
80
|
+
data: T;
|
|
81
|
+
} | {
|
|
82
|
+
success: false;
|
|
83
|
+
error: QtypeParseError;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Esquema para strings.
|
|
87
|
+
*
|
|
88
|
+
* Lanza {@link QtypeParseError} si el segmento está vacío.
|
|
89
|
+
* Para permitir strings vacíos usa {@link QOptional} o {@link QDefault}.
|
|
90
|
+
*/
|
|
91
|
+
declare class QString extends QType<string> {
|
|
92
|
+
readonly kind = "string";
|
|
93
|
+
decode(raw: string, ctx: DecodeContext): string;
|
|
94
|
+
encode(value: string, _opts?: EncodeOptions): string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Esquema para números de punto flotante.
|
|
98
|
+
*
|
|
99
|
+
* Acepta cualquier string que `Number()` pueda parsear.
|
|
100
|
+
* Lanza {@link QtypeParseError} si está vacío o no es un número válido.
|
|
101
|
+
*/
|
|
102
|
+
declare class QNumber extends QType<number> {
|
|
103
|
+
readonly kind = "number";
|
|
104
|
+
decode(raw: string, ctx: DecodeContext): number;
|
|
105
|
+
encode(value: number, _opts?: EncodeOptions): string;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Esquema para números enteros.
|
|
109
|
+
*
|
|
110
|
+
* Usa {@link parseInt} con la base especificada (por defecto 10).
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* q.Integer() // base 10, decimal
|
|
115
|
+
* q.Integer(16) // base 16, hexadecimal
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
declare class QInteger extends QType<number> {
|
|
119
|
+
readonly kind = "integer";
|
|
120
|
+
private readonly radix;
|
|
121
|
+
constructor(radix?: number);
|
|
122
|
+
decode(raw: string, ctx: DecodeContext): number;
|
|
123
|
+
encode(value: number, _opts?: EncodeOptions): string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Esquema para valores booleanos.
|
|
127
|
+
*
|
|
128
|
+
* Por defecto reconoce `"1"`, `"true"`, `"Y"`, `"y"` como `true`.
|
|
129
|
+
* Cualquier otro valor (incluyendo vacío) es `false`.
|
|
130
|
+
* La lista de valores truthy es configurable.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* q.Boolean() // truthy: ["1", "true", "Y", "y"]
|
|
135
|
+
* q.Boolean(["S", "s", "SI", "si"]) // truthy personalizado
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
declare class QBoolean extends QType<boolean> {
|
|
139
|
+
readonly kind = "boolean";
|
|
140
|
+
private readonly truthy;
|
|
141
|
+
constructor(truthy?: readonly string[]);
|
|
142
|
+
decode(raw: string, ctx: DecodeContext): boolean;
|
|
143
|
+
encode(value: boolean, _opts?: EncodeOptions): string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Esquema para fechas.
|
|
147
|
+
*
|
|
148
|
+
* Soporta dos formatos:
|
|
149
|
+
* - `"iso"` (por defecto): usa `new Date(str)` y serializa con `toISOString()`.
|
|
150
|
+
* - `"yyyyMMdd"`: parsea y serializa manualmente en zona horaria local.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* q.Date() // formato ISO
|
|
155
|
+
* q.Date("yyyyMMdd") // formato compacto de 8 dígitos
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
declare class QDate extends QType<Date> {
|
|
159
|
+
readonly kind = "date";
|
|
160
|
+
private readonly format;
|
|
161
|
+
constructor(format?: "iso" | "yyyyMMdd");
|
|
162
|
+
decode(raw: string, ctx: DecodeContext): Date;
|
|
163
|
+
encode(value: Date, _opts?: EncodeOptions): string;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Esquema que solo acepta un valor literal exacto.
|
|
167
|
+
*
|
|
168
|
+
* Útil como discriminador en uniones (ver {@link QUnion.match}).
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* q.Literal("00") // solo acepta el string "00"
|
|
173
|
+
* q.Literal(42) // solo acepta el número 42
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
declare class QLiteral<T extends string | number> extends QType<T> {
|
|
177
|
+
readonly kind = "literal";
|
|
178
|
+
readonly value: T;
|
|
179
|
+
constructor(value: T);
|
|
180
|
+
decode(raw: string, ctx: DecodeContext): T;
|
|
181
|
+
encode(value: T, _opts?: EncodeOptions): string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Esquema que restringe el valor a un conjunto finito de strings.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```ts
|
|
188
|
+
* q.Enum(["pendiente", "procesado", "rechazado"])
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
declare class QEnum<T extends readonly string[]> extends QType<T[number]> {
|
|
192
|
+
readonly kind = "enum";
|
|
193
|
+
readonly values: T;
|
|
194
|
+
constructor(values: T);
|
|
195
|
+
decode(raw: string, ctx: DecodeContext): T[number];
|
|
196
|
+
encode(value: T[number], _opts?: EncodeOptions): string;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Convierte un esquema en opcional.
|
|
200
|
+
*
|
|
201
|
+
* Un segmento vacío (`""`) se decodifica como `undefined`.
|
|
202
|
+
* Al codificar, `undefined` se serializa como `""`.
|
|
203
|
+
*/
|
|
204
|
+
declare class QOptional<T extends QType<any>> extends QType<Static<T> | undefined> {
|
|
205
|
+
readonly kind = "optional";
|
|
206
|
+
readonly inner: T;
|
|
207
|
+
constructor(schema: T);
|
|
208
|
+
decode(raw: string, ctx: DecodeContext): Static<T> | undefined;
|
|
209
|
+
encode(value: Static<T> | undefined, _opts?: EncodeOptions): string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Convierte un esquema en nullable.
|
|
213
|
+
*
|
|
214
|
+
* Un segmento vacío (`""`) se decodifica como `null`.
|
|
215
|
+
* Al codificar, `null` se serializa como `""`.
|
|
216
|
+
*/
|
|
217
|
+
declare class QNullable<T extends QType<any>> extends QType<Static<T> | null> {
|
|
218
|
+
readonly kind = "nullable";
|
|
219
|
+
readonly inner: T;
|
|
220
|
+
constructor(schema: T);
|
|
221
|
+
decode(raw: string, ctx: DecodeContext): Static<T> | null;
|
|
222
|
+
encode(value: Static<T> | null, _opts?: EncodeOptions): string;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Asigna un valor por defecto cuando el segmento está vacío.
|
|
226
|
+
*
|
|
227
|
+
* A diferencia de {@link QOptional}, el tipo de salida **no** incluye `undefined`.
|
|
228
|
+
* Si el segmento no está vacío, se decodifica normalmente con el esquema interno.
|
|
229
|
+
*/
|
|
230
|
+
declare class QDefault<T extends QType<any>> extends QType<Static<T>> {
|
|
231
|
+
readonly kind = "default";
|
|
232
|
+
readonly inner: T;
|
|
233
|
+
readonly defaultValue: Static<T>;
|
|
234
|
+
constructor(schema: T, defaultValue: Static<T>);
|
|
235
|
+
decode(raw: string, ctx: DecodeContext): Static<T>;
|
|
236
|
+
encode(value: Static<T>, _opts?: EncodeOptions): string;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Aplica una transformación bidireccional sobre otro esquema.
|
|
240
|
+
*
|
|
241
|
+
* Permite convertir entre la representación en el wire y el tipo en la app.
|
|
242
|
+
*
|
|
243
|
+
* @typeParam A - Esquema de entrada (tipo wire).
|
|
244
|
+
* @typeParam B - Tipo de salida en la app.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* // wire: centavos (entero), app: dólares (flotante)
|
|
249
|
+
* q.Transform(q.Number(), cents => cents / 100, dollars => dollars * 100)
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
declare class QTransform<
|
|
253
|
+
A extends QType<any>,
|
|
254
|
+
B
|
|
255
|
+
> extends QType<B> {
|
|
256
|
+
readonly kind = "transform";
|
|
257
|
+
readonly inner: A;
|
|
258
|
+
private readonly decodeFn;
|
|
259
|
+
private readonly encodeFn;
|
|
260
|
+
constructor(schema: A, decodeFn: (a: Static<A>) => B, encodeFn: (b: B) => Static<A>);
|
|
261
|
+
decode(raw: string, ctx: DecodeContext): B;
|
|
262
|
+
encode(value: B, opts?: EncodeOptions): string;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Asigna una posición explícita a un campo dentro de un {@link QSchema}.
|
|
266
|
+
*
|
|
267
|
+
* Se crea mediante {@link q.at}.
|
|
268
|
+
* A nivel de tipos es transparente: el tipo de salida es el del esquema interno.
|
|
269
|
+
*/
|
|
270
|
+
declare class QPositioned<T extends QType<any>> extends QType<Static<T>> {
|
|
271
|
+
readonly kind = "positioned";
|
|
272
|
+
readonly index: number;
|
|
273
|
+
readonly inner: T;
|
|
274
|
+
constructor(index: number, schema: T);
|
|
275
|
+
decode(raw: string, ctx: DecodeContext): Static<T>;
|
|
276
|
+
encode(value: Static<T>, opts?: EncodeOptions): string;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Verifica en runtime si un esquema es una instancia de {@link QPositioned}.
|
|
280
|
+
*/
|
|
281
|
+
declare function isPositioned(schema: QType<any>): schema is QPositioned<any>;
|
|
282
|
+
/**
|
|
283
|
+
* Lista delimitada de elementos homogéneos dentro de un mismo segmento.
|
|
284
|
+
*
|
|
285
|
+
* El separador por defecto es `";"`.
|
|
286
|
+
* Un segmento vacío (`""`) produce un arreglo vacío `[]`.
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* ```ts
|
|
290
|
+
* q.Array(q.String(), { sep: ";" })
|
|
291
|
+
* // "a;b;c" → ["a", "b", "c"]
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
declare class QArray<T extends QType<any>> extends QType<Static<T>[]> {
|
|
295
|
+
readonly kind = "array";
|
|
296
|
+
readonly element: T;
|
|
297
|
+
private readonly sep;
|
|
298
|
+
constructor(schema: T, opts?: {
|
|
299
|
+
sep?: string;
|
|
300
|
+
});
|
|
301
|
+
decode(raw: string, ctx: DecodeContext): Static<T>[];
|
|
302
|
+
encode(value: Static<T>[], _opts?: EncodeOptions): string;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Pares clave:valor delimitados dentro de un mismo segmento.
|
|
306
|
+
*
|
|
307
|
+
* Los separadores por defecto son:
|
|
308
|
+
* - Entre pares: `";"`
|
|
309
|
+
* - Entre clave y valor: `":"`
|
|
310
|
+
*
|
|
311
|
+
* Las claves no declaradas en el esquema producen error.
|
|
312
|
+
* Las claves declaradas pero ausentes se decodifican con string vacío
|
|
313
|
+
* (permitiendo que {@link QOptional}, {@link QNullable} y {@link QDefault}
|
|
314
|
+
* manejen el caso).
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```ts
|
|
318
|
+
* q.Object({ name: q.String(), age: q.Integer() }, { sep: ";", kvSep: ":" })
|
|
319
|
+
* // "name:John;age:30" → { name: "John", age: 30 }
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
declare class QObject<T extends SchemaProps> extends QType<{ [K in keyof T] : Static<T[K]> }> {
|
|
323
|
+
readonly kind = "object";
|
|
324
|
+
readonly properties: T;
|
|
325
|
+
private readonly sep;
|
|
326
|
+
private readonly kvSep;
|
|
327
|
+
constructor(properties: T, opts?: {
|
|
328
|
+
sep?: string;
|
|
329
|
+
kvSep?: string;
|
|
330
|
+
});
|
|
331
|
+
decode(raw: string, ctx: DecodeContext): { [K in keyof T] : Static<T[K]> };
|
|
332
|
+
encode(value: { [K in keyof T] : Static<T[K]> }, _opts?: EncodeOptions): string;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Lista posicional de largo fijo con esquemas heterogéneos.
|
|
336
|
+
*
|
|
337
|
+
* Cada posición tiene su propio esquema. El número de elementos en el wire
|
|
338
|
+
* debe ser al menos igual al número de esquemas declarados.
|
|
339
|
+
* El separador por defecto es `";"`.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```ts
|
|
343
|
+
* q.Tuple([q.String(), q.Integer(), q.String()], { sep: ";" })
|
|
344
|
+
* // "John;30;NYC" → ["John", 30, "NYC"]
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
declare class QTuple<T extends QType<any>[]> extends QType<{ [K in keyof T] : Static<T[K]> }> {
|
|
348
|
+
readonly kind = "tuple";
|
|
349
|
+
readonly items: T;
|
|
350
|
+
private readonly sep;
|
|
351
|
+
constructor(items: [...T], opts?: {
|
|
352
|
+
sep?: string;
|
|
353
|
+
});
|
|
354
|
+
decode(raw: string, ctx: DecodeContext): { [K in keyof T] : Static<T[K]> };
|
|
355
|
+
encode(value: { [K in keyof T] : Static<T[K]> }, _opts?: EncodeOptions): string;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Esquema principal: protocolo delimitado por pipes de nivel superior.
|
|
359
|
+
*
|
|
360
|
+
* Es el tipo de esquema más común. Define un mensaje completo donde cada
|
|
361
|
+
* campo ocupa una posición fija separada por `delimiter` (por defecto `"|"`).
|
|
362
|
+
*
|
|
363
|
+
* ### Posiciones
|
|
364
|
+
*
|
|
365
|
+
* Por defecto, las posiciones se asignan secuencialmente según el orden de
|
|
366
|
+
* las claves. Usa {@link q.at} para asignar posiciones explícitas y crear
|
|
367
|
+
* layouts sparse (ej. declarar 7 campos de 200 posiciones).
|
|
368
|
+
*
|
|
369
|
+
* ### Métodos de conveniencia
|
|
370
|
+
*
|
|
371
|
+
* - {@link parse}: decodifica un string crudo, lanza {@link QtypeParseError} si falla.
|
|
372
|
+
* - {@link safeParse}: igual que `parse` pero retorna `{ success, data/error }` sin lanzar.
|
|
373
|
+
* - {@link serialize}: codifica un objeto de vuelta a string.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```ts
|
|
377
|
+
* const Msg = q.Schema({
|
|
378
|
+
* tipo: q.String(),
|
|
379
|
+
* monto: q.Number(),
|
|
380
|
+
* });
|
|
381
|
+
*
|
|
382
|
+
* Msg.parse("105|150.00"); // { tipo: "105", monto: 150 }
|
|
383
|
+
* Msg.serialize({ tipo: "105", monto: 150 }); // "105|150"
|
|
384
|
+
* ```
|
|
385
|
+
*/
|
|
386
|
+
declare class QSchema<T extends SchemaProps> extends QType<FilterAt<T>> {
|
|
387
|
+
readonly kind = "schema";
|
|
388
|
+
readonly properties: T;
|
|
389
|
+
private readonly delimiter;
|
|
390
|
+
private readonly positions;
|
|
391
|
+
constructor(properties: T, opts?: {
|
|
392
|
+
delimiter?: string;
|
|
393
|
+
strictLength?: boolean;
|
|
394
|
+
});
|
|
395
|
+
/**
|
|
396
|
+
* Decodifica un mensaje completo.
|
|
397
|
+
*
|
|
398
|
+
* @throws {QtypeParseError} si el mensaje no es válido.
|
|
399
|
+
*/
|
|
400
|
+
parse(raw: string): FilterAt<T>;
|
|
401
|
+
/**
|
|
402
|
+
* Decodifica un mensaje completo sin lanzar excepciones.
|
|
403
|
+
*
|
|
404
|
+
* Retorna `{ success: true, data }` o `{ success: false, error }`.
|
|
405
|
+
*/
|
|
406
|
+
safeParse(raw: string): SafeResult<FilterAt<T>>;
|
|
407
|
+
decode(raw: string, ctx: DecodeContext): FilterAt<T>;
|
|
408
|
+
encode(value: FilterAt<T>, opts?: EncodeOptions): string;
|
|
409
|
+
/**
|
|
410
|
+
* Alias de {@link encode} para mayor claridad semántica.
|
|
411
|
+
*/
|
|
412
|
+
serialize(value: FilterAt<T>, opts?: EncodeOptions): string;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Unión de esquemas: prueba cada variante en orden y retorna la primera
|
|
416
|
+
* que decodifique correctamente.
|
|
417
|
+
*
|
|
418
|
+
* ### Modo no discriminado (por defecto)
|
|
419
|
+
*
|
|
420
|
+
* Prueba cada variante secuencialmente al decodificar. La primera que no
|
|
421
|
+
* lance error gana.
|
|
422
|
+
*
|
|
423
|
+
* ### Modo discriminado
|
|
424
|
+
*
|
|
425
|
+
* Cuando se provee `discriminator`, {@link match} permite seleccionar la
|
|
426
|
+
* variante correcta antes de decodificar, según el valor de un campo
|
|
427
|
+
* {@link QLiteral} o {@link QEnum} en el {@link QSchema}.
|
|
428
|
+
*
|
|
429
|
+
* @example
|
|
430
|
+
* ```ts
|
|
431
|
+
* const Msg = q.Union([
|
|
432
|
+
* q.Schema({ tipo: q.Literal("00"), id: q.String() }),
|
|
433
|
+
* q.Schema({ tipo: q.Literal("01"), id: q.String(), status: q.String() }),
|
|
434
|
+
* ]);
|
|
435
|
+
*
|
|
436
|
+
* Msg.parse("00|CPN-1"); // variante 00
|
|
437
|
+
* Msg.parse("01|CPN-2|ok"); // variante 01
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
440
|
+
declare class QUnion<T extends QType<any>[]> extends QType<Static<T[number]>> {
|
|
441
|
+
readonly kind = "union";
|
|
442
|
+
readonly variants: [...T];
|
|
443
|
+
private readonly discriminator?;
|
|
444
|
+
constructor(variants: [...T], opts?: {
|
|
445
|
+
discriminator?: string;
|
|
446
|
+
});
|
|
447
|
+
/**
|
|
448
|
+
* Decodifica un mensaje probando cada variante en orden.
|
|
449
|
+
*
|
|
450
|
+
* @throws {QtypeParseError} si ninguna variante coincide.
|
|
451
|
+
*/
|
|
452
|
+
parse(raw: string): Static<T[number]>;
|
|
453
|
+
/**
|
|
454
|
+
* Versión segura de {@link parse} que no lanza excepciones.
|
|
455
|
+
*/
|
|
456
|
+
safeParse(raw: string): {
|
|
457
|
+
success: true;
|
|
458
|
+
data: Static<T[number]>;
|
|
459
|
+
} | {
|
|
460
|
+
success: false;
|
|
461
|
+
error: QtypeParseError;
|
|
462
|
+
};
|
|
463
|
+
decode(raw: string, ctx: DecodeContext): Static<T[number]>;
|
|
464
|
+
encode(value: Static<T[number]>, opts?: EncodeOptions): string;
|
|
465
|
+
/**
|
|
466
|
+
* Alias de {@link encode} para mayor claridad semántica.
|
|
467
|
+
*/
|
|
468
|
+
serialize(value: Static<T[number]>, opts?: EncodeOptions): string;
|
|
469
|
+
/**
|
|
470
|
+
* Para uniones discriminadas, retorna la variante cuyo campo discriminador
|
|
471
|
+
* coincide con `value`.
|
|
472
|
+
*
|
|
473
|
+
* El discriminador debe ser un {@link QLiteral} o {@link QEnum} dentro de
|
|
474
|
+
* un {@link QSchema}.
|
|
475
|
+
*
|
|
476
|
+
* @returns La variante coincidente, o `undefined` si no hay coincidencia.
|
|
477
|
+
*/
|
|
478
|
+
match(value: string): QType<any> | undefined;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Namespace `q` — fábrica de esquemas.
|
|
482
|
+
*
|
|
483
|
+
* Cada método retorna una instancia de esquema lista para usar en
|
|
484
|
+
* {@link QSchema.parse}, {@link QSchema.serialize}, etc.
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* ```ts
|
|
488
|
+
* import { q, type Static } from "qtype";
|
|
489
|
+
*
|
|
490
|
+
* const Msg = q.Schema({
|
|
491
|
+
* tipo: q.String(),
|
|
492
|
+
* monto: q.Number(),
|
|
493
|
+
* activo: q.Boolean(),
|
|
494
|
+
* });
|
|
495
|
+
*
|
|
496
|
+
* type Msg = Static<typeof Msg>;
|
|
497
|
+
* // { tipo: string; monto: number; activo: boolean }
|
|
498
|
+
* ```
|
|
499
|
+
*/
|
|
500
|
+
declare const q: {
|
|
501
|
+
/** Esquema para strings. El segmento vacío lanza error. */
|
|
502
|
+
String: () => QString;
|
|
503
|
+
/** Esquema para números de punto flotante. */
|
|
504
|
+
Number: () => QNumber;
|
|
505
|
+
/**
|
|
506
|
+
* Esquema para números enteros.
|
|
507
|
+
*
|
|
508
|
+
* @param radix - Base numérica (por defecto 10).
|
|
509
|
+
*/
|
|
510
|
+
Integer: (radix?: number) => QInteger;
|
|
511
|
+
/**
|
|
512
|
+
* Esquema para booleanos.
|
|
513
|
+
*
|
|
514
|
+
* @param truthy - Lista de strings que se interpretan como `true`.
|
|
515
|
+
* Por defecto `["1", "true", "Y", "y"]`.
|
|
516
|
+
*/
|
|
517
|
+
Boolean: (truthy?: readonly string[]) => QBoolean;
|
|
518
|
+
/**
|
|
519
|
+
* Esquema para fechas.
|
|
520
|
+
*
|
|
521
|
+
* @param format - `"iso"` (por defecto) o `"yyyyMMdd"`.
|
|
522
|
+
*/
|
|
523
|
+
Date: (format?: "iso" | "yyyyMMdd") => QDate;
|
|
524
|
+
/** Esquema que solo acepta un valor literal exacto. */
|
|
525
|
+
Literal: <T extends string | number>(value: T) => QLiteral<T>;
|
|
526
|
+
/** Esquema que restringe el valor a un conjunto de strings. */
|
|
527
|
+
Enum: <T extends readonly string[]>(values: T) => QEnum<T>;
|
|
528
|
+
/**
|
|
529
|
+
* Lista delimitada de elementos homogéneos.
|
|
530
|
+
*
|
|
531
|
+
* @param schema - Esquema de cada elemento.
|
|
532
|
+
* @param opts.sep - Separador entre elementos (por defecto `";"`).
|
|
533
|
+
*/
|
|
534
|
+
Array: <T extends QType<any>>(schema: T, opts?: {
|
|
535
|
+
sep?: string;
|
|
536
|
+
}) => QArray<T>;
|
|
537
|
+
/**
|
|
538
|
+
* Pares clave:valor delimitados.
|
|
539
|
+
*
|
|
540
|
+
* @param props - Definición de las propiedades.
|
|
541
|
+
* @param opts.sep - Separador entre pares (por defecto `";"`).
|
|
542
|
+
* @param opts.kvSep - Separador clave-valor (por defecto `":"`).
|
|
543
|
+
*/
|
|
544
|
+
Object: <T extends SchemaProps>(props: T, opts?: {
|
|
545
|
+
sep?: string;
|
|
546
|
+
kvSep?: string;
|
|
547
|
+
}) => QObject<T>;
|
|
548
|
+
/**
|
|
549
|
+
* Tupla posicional de largo fijo con esquemas heterogéneos.
|
|
550
|
+
*
|
|
551
|
+
* @param items - Arreglo de esquemas, uno por posición.
|
|
552
|
+
* @param opts.sep - Separador entre elementos (por defecto `";"`).
|
|
553
|
+
*/
|
|
554
|
+
Tuple: <T extends QType<any>[]>(items: [...T], opts?: {
|
|
555
|
+
sep?: string;
|
|
556
|
+
}) => QTuple<T>;
|
|
557
|
+
/**
|
|
558
|
+
* Esquema principal: mensaje delimitado por pipes.
|
|
559
|
+
*
|
|
560
|
+
* @param props - Definición de los campos del mensaje.
|
|
561
|
+
* @param opts.delimiter - Separador entre campos (por defecto `"|"`).
|
|
562
|
+
*/
|
|
563
|
+
Schema: <T extends SchemaProps>(props: T, opts?: {
|
|
564
|
+
delimiter?: string;
|
|
565
|
+
strictLength?: boolean;
|
|
566
|
+
}) => QSchema<T>;
|
|
567
|
+
/** Convierte un esquema en opcional. Vacío → `undefined`. */
|
|
568
|
+
Optional: <T extends QType<any>>(schema: T) => QOptional<T>;
|
|
569
|
+
/** Convierte un esquema en nullable. Vacío → `null`. */
|
|
570
|
+
Nullable: <T extends QType<any>>(schema: T) => QNullable<T>;
|
|
571
|
+
/**
|
|
572
|
+
* Asigna un valor por defecto cuando el segmento está vacío.
|
|
573
|
+
*
|
|
574
|
+
* A diferencia de {@link Optional}, el tipo de salida no incluye `undefined`.
|
|
575
|
+
*/
|
|
576
|
+
Default: <T extends QType<any>>(schema: T, defaultValue: Static<T>) => QDefault<T>;
|
|
577
|
+
/**
|
|
578
|
+
* Aplica una transformación bidireccional sobre otro esquema.
|
|
579
|
+
*
|
|
580
|
+
* @param schema - Esquema base (tipo wire).
|
|
581
|
+
* @param decode - Función de decodificación (wire → app).
|
|
582
|
+
* @param encode - Función de codificación (app → wire).
|
|
583
|
+
*
|
|
584
|
+
* @example
|
|
585
|
+
* ```ts
|
|
586
|
+
* // wire: centavos (entero), app: dólares (flotante)
|
|
587
|
+
* q.Transform(q.Number(), cents => cents / 100, dollars => dollars * 100)
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
590
|
+
Transform: <
|
|
591
|
+
A extends QType<any>,
|
|
592
|
+
B
|
|
593
|
+
>(schema: A, decode: (a: Static<A>) => B, encode: (b: B) => Static<A>) => QTransform<A, B>;
|
|
594
|
+
/**
|
|
595
|
+
* Asigna una posición explícita a un campo dentro de un {@link QSchema}.
|
|
596
|
+
*
|
|
597
|
+
* Los campos sin `q.at` reciben posiciones secuenciales automáticamente,
|
|
598
|
+
* saltando las posiciones ya ocupadas por campos explícitos.
|
|
599
|
+
*/
|
|
600
|
+
at: <T extends QType<any>>(index: number, schema: T) => QPositioned<T>;
|
|
601
|
+
/**
|
|
602
|
+
* Unión de esquemas. Prueba cada variante en orden.
|
|
603
|
+
*
|
|
604
|
+
* @param variants - Lista de esquemas variantes.
|
|
605
|
+
* @param opts.discriminator - Campo {@link QLiteral} o {@link QEnum} usado
|
|
606
|
+
* para seleccionar la variante correcta con {@link QUnion.match}.
|
|
607
|
+
*/
|
|
608
|
+
Union: <T extends QType<any>[]>(variants: [...T], opts?: {
|
|
609
|
+
discriminator?: string;
|
|
610
|
+
}) => QUnion<T>;
|
|
611
|
+
};
|
|
612
|
+
export { q, isPositioned, Static, SchemaProps, SafeResult, QtypeParseError, QUnion, QType, QTuple, QTransform, QString, QSchema, QPositioned, QOptional, QObject, QNumber, QNullable, QLiteral, QInteger, QEnum, QDefault, QDate, QBoolean, QArray, FilterAt, EncodeOptions, DecodeContext };
|