diff options
Diffstat (limited to 'packages/taler-util/src/codec.ts')
-rw-r--r-- | packages/taler-util/src/codec.ts | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/packages/taler-util/src/codec.ts b/packages/taler-util/src/codec.ts index 701fc8835..54d450d82 100644 --- a/packages/taler-util/src/codec.ts +++ b/packages/taler-util/src/codec.ts @@ -361,6 +361,40 @@ export function codecForStringURL(shouldEndWithSlash?: boolean): Codec<string> { } /** + * Return a codec for a value that must be a string. + */ +export function codecForURL(shouldEndWithSlash?: boolean): Codec<URL> { + return { + decode(x: any, c?: Context): URL { + if (typeof x !== "string") { + throw new DecodingError( + `expected string at ${renderContext(c)} but got ${typeof x}`, + ); + } + if (shouldEndWithSlash && !x.endsWith("/")) { + throw new DecodingError( + `expected URL string that ends with slash at ${renderContext( + c, + )} but got ${x}`, + ); + } + try { + const url = new URL(x); + return url; + } catch (e) { + if (e instanceof Error) { + throw new DecodingError(e.message); + } else { + throw new DecodingError( + `expected an URL string at ${renderContext(c)} but got "${x}"`, + ); + } + } + }, + }; +} + +/** * Codec that allows any value. */ export function codecForAny(): Codec<any> { @@ -457,6 +491,19 @@ export function codecOptional<V>(innerCodec: Codec<V>): Codec<V | undefined> { }; } +export function codecForLazy<V>(innerCodec: () => Codec<V>): Codec<V> { + let instance: Codec<V> | undefined = undefined + return { + decode(x: any, c?: Context): V { + if (instance === undefined) { + instance = innerCodec() + } + return instance.decode(x, c); + }, + }; +} + + export type CodecType<T> = T extends Codec<infer X> ? X : any; export function codecForEither<T extends Array<Codec<unknown>>>( @@ -480,5 +527,3 @@ export function codecForEither<T extends Array<Codec<unknown>>>( }, }; } - -const x = codecForEither(codecForString(), codecForNumber()); |