@tstdl/base 0.93.47 → 0.93.49
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/ai/ai-file.service.d.ts +2 -2
- package/ai/ai-file.service.js +2 -1
- package/ai/ai.service.d.ts +2 -21
- package/ai/ai.service.js +12 -28
- package/ai/functions.js +1 -1
- package/ai/module.d.ts +20 -5
- package/ai/module.js +18 -2
- package/package.json +7 -4
- package/schema/converters/{openapi-converter.js → open-api-converter.js} +19 -12
- package/schema/converters/zod-converter.d.ts +3 -0
- package/schema/converters/zod-converter.js +172 -0
- package/schema/schemas/array.js +2 -2
- package/schema/schemas/date.d.ts +7 -4
- package/schema/schemas/date.js +11 -6
- package/schema/schemas/function.js +2 -2
- package/schema/schemas/instance.d.ts +1 -1
- package/schema/schemas/instance.js +1 -1
- package/schema/schemas/object.d.ts +5 -0
- package/schema/schemas/object.js +12 -0
- package/schema/schemas/regexp.d.ts +1 -1
- package/schema/schemas/regexp.js +2 -2
- package/schema/schemas/uint8-array.d.ts +4 -1
- package/schema/schemas/uint8-array.js +32 -3
- package/utils/encoding.js +1 -1
- package/utils/z-base32.d.ts +1 -1
- package/utils/z-base32.js +2 -1
- package/schema/converters/index.d.ts +0 -1
- package/schema/converters/index.js +0 -1
- /package/schema/converters/{openapi-converter.d.ts → open-api-converter.d.ts} +0 -0
package/ai/ai-file.service.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Resolvable, resolveArgumentType } from '../injector/interfaces.js';
|
|
2
|
-
import
|
|
2
|
+
import { AiModuleOptions } from './module.js';
|
|
3
3
|
import { type FileContentPart, type FileInput } from './types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Options for {@link AiFileService}.
|
|
6
6
|
*/
|
|
7
|
-
export type AiFileServiceOptions = Pick<
|
|
7
|
+
export type AiFileServiceOptions = Pick<AiModuleOptions, 'apiKey' | 'keyFile' | 'vertex'>;
|
|
8
8
|
export type AiFileServiceArgument = AiFileServiceOptions;
|
|
9
9
|
type File = {
|
|
10
10
|
id: string;
|
package/ai/ai-file.service.js
CHANGED
|
@@ -21,13 +21,14 @@ import { backoffGenerator } from '../utils/backoff.js';
|
|
|
21
21
|
import { formatBytes } from '../utils/format.js';
|
|
22
22
|
import { readBinaryStream } from '../utils/stream/stream-reader.js';
|
|
23
23
|
import { assertDefinedPass, isBlob, isDefined, isUndefined } from '../utils/type-guards.js';
|
|
24
|
+
import { AiModuleOptions } from './module.js';
|
|
24
25
|
import { isPathFileInput } from './types.js';
|
|
25
26
|
/**
|
|
26
27
|
* Manages file uploads and state for use with AI models.
|
|
27
28
|
* Handles both Google Generative AI File API and Google Cloud Storage for Vertex AI.
|
|
28
29
|
*/
|
|
29
30
|
let AiFileService = class AiFileService {
|
|
30
|
-
#options = injectArgument(this);
|
|
31
|
+
#options = injectArgument(this, { optional: true }) ?? inject(AiModuleOptions);
|
|
31
32
|
#genAI = new GoogleGenAI({
|
|
32
33
|
vertexai: isDefined(this.#options.vertex?.project),
|
|
33
34
|
project: this.#options.vertex?.project,
|
package/ai/ai.service.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Resolvable, resolveArgumentType } from '../injector/interfaces.js'
|
|
|
2
2
|
import { type SchemaTestable } from '../schema/index.js';
|
|
3
3
|
import type { Enumeration as EnumerationType, EnumerationValue } from '../types/index.js';
|
|
4
4
|
import { AiSession } from './ai-session.js';
|
|
5
|
+
import { AiModuleOptions } from './module.js';
|
|
5
6
|
import { type AiModel, type FileContentPart, type FileInput, type GenerationOptions, type GenerationRequest, type GenerationResult, type SchemaFunctionDeclarations, type SchemaFunctionDeclarationsResult } from './types.js';
|
|
6
7
|
/**
|
|
7
8
|
* A generation result that includes a specialized, typed result alongside the raw generation data.
|
|
@@ -20,27 +21,7 @@ export type SpecializedGenerationResult<T> = {
|
|
|
20
21
|
export type SpecializedGenerationResultGenerator<T> = AsyncGenerator<T> & {
|
|
21
22
|
raw: Promise<GenerationResult>;
|
|
22
23
|
};
|
|
23
|
-
|
|
24
|
-
* Options for configuring the {@link AiService}.
|
|
25
|
-
*/
|
|
26
|
-
export declare class AiServiceOptions {
|
|
27
|
-
/** Google AI API key. */
|
|
28
|
-
apiKey?: string;
|
|
29
|
-
/** Path to the Google Cloud credentials file. */
|
|
30
|
-
keyFile?: string;
|
|
31
|
-
/** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
|
|
32
|
-
vertex?: {
|
|
33
|
-
project: string;
|
|
34
|
-
location: string;
|
|
35
|
-
bucket?: string;
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* The default model to use for generation requests.
|
|
39
|
-
* @default 'small'
|
|
40
|
-
*/
|
|
41
|
-
defaultModel?: AiModel;
|
|
42
|
-
}
|
|
43
|
-
export type AiServiceArgument = AiServiceOptions;
|
|
24
|
+
export type AiServiceArgument = AiModuleOptions;
|
|
44
25
|
export type ClassificationResult<T extends EnumerationType> = {
|
|
45
26
|
types: {
|
|
46
27
|
type: EnumerationValue<T>;
|
package/ai/ai.service.js
CHANGED
|
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
var _a;
|
|
8
8
|
var AiService_1;
|
|
9
|
-
import { FinishReason, FunctionCallingConfigMode as GoogleFunctionCallingMode, GoogleGenAI } from '@google/genai';
|
|
9
|
+
import { ApiError, FinishReason, FunctionCallingConfigMode as GoogleFunctionCallingMode, GoogleGenAI } from '@google/genai';
|
|
10
10
|
import { match } from 'ts-pattern';
|
|
11
11
|
import { CancellationSignal } from '../cancellation/index.js';
|
|
12
12
|
import { NotSupportedError } from '../errors/not-supported.error.js';
|
|
@@ -15,7 +15,7 @@ import { inject, injectArgument } from '../injector/inject.js';
|
|
|
15
15
|
import { Logger } from '../logger/logger.js';
|
|
16
16
|
import { DeferredPromise } from '../promise/deferred-promise.js';
|
|
17
17
|
import { LazyPromise } from '../promise/lazy-promise.js';
|
|
18
|
-
import { convertToOpenApiSchema } from '../schema/converters/
|
|
18
|
+
import { convertToOpenApiSchema } from '../schema/converters/open-api-converter.js';
|
|
19
19
|
import { Schema } from '../schema/index.js';
|
|
20
20
|
import { toArray } from '../utils/array/array.js';
|
|
21
21
|
import { mapAsync } from '../utils/async-iterable-helpers/map.js';
|
|
@@ -23,28 +23,12 @@ import { toArrayAsync } from '../utils/async-iterable-helpers/to-array.js';
|
|
|
23
23
|
import { backoffGenerator } from '../utils/backoff.js';
|
|
24
24
|
import { lazyObject } from '../utils/object/lazy-property.js';
|
|
25
25
|
import { hasOwnProperty, objectEntries } from '../utils/object/object.js';
|
|
26
|
-
import { assertDefinedPass, isDefined, isError, isNotNull, isNull, isUndefined } from '../utils/type-guards.js';
|
|
26
|
+
import { assertDefinedPass, isDefined, isError, isInstanceOf, isNotNull, isNull, isUndefined } from '../utils/type-guards.js';
|
|
27
27
|
import { resolveValueOrAsyncProvider } from '../utils/value-or-provider.js';
|
|
28
28
|
import { AiFileService } from './ai-file.service.js';
|
|
29
29
|
import { AiSession } from './ai-session.js';
|
|
30
|
+
import { AiModuleOptions } from './module.js';
|
|
30
31
|
import { isSchemaFunctionDeclarationWithHandler } from './types.js';
|
|
31
|
-
/**
|
|
32
|
-
* Options for configuring the {@link AiService}.
|
|
33
|
-
*/
|
|
34
|
-
export class AiServiceOptions {
|
|
35
|
-
/** Google AI API key. */
|
|
36
|
-
apiKey;
|
|
37
|
-
/** Path to the Google Cloud credentials file. */
|
|
38
|
-
keyFile;
|
|
39
|
-
/** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
|
|
40
|
-
vertex;
|
|
41
|
-
/**
|
|
42
|
-
* The default model to use for generation requests.
|
|
43
|
-
* @default 'small'
|
|
44
|
-
*/
|
|
45
|
-
defaultModel;
|
|
46
|
-
}
|
|
47
|
-
;
|
|
48
32
|
const functionCallingModeMap = {
|
|
49
33
|
auto: GoogleFunctionCallingMode.AUTO,
|
|
50
34
|
force: GoogleFunctionCallingMode.ANY,
|
|
@@ -58,7 +42,7 @@ let generationCounter = 0;
|
|
|
58
42
|
* supporting both standard Google AI and Vertex AI endpoints.
|
|
59
43
|
*/
|
|
60
44
|
let AiService = AiService_1 = class AiService {
|
|
61
|
-
#options = injectArgument(this, { optional: true }) ?? inject(
|
|
45
|
+
#options = injectArgument(this, { optional: true }) ?? inject(AiModuleOptions);
|
|
62
46
|
#fileService = inject(AiFileService, this.#options);
|
|
63
47
|
#logger = inject(Logger, AiService_1.name);
|
|
64
48
|
#cancellationSignal = inject(CancellationSignal);
|
|
@@ -73,7 +57,7 @@ let AiService = AiService_1 = class AiService {
|
|
|
73
57
|
#backoffOptions = {
|
|
74
58
|
cancellationSignal: this.#cancellationSignal,
|
|
75
59
|
strategy: 'exponential',
|
|
76
|
-
initialDelay:
|
|
60
|
+
initialDelay: 5000,
|
|
77
61
|
increase: 1.5,
|
|
78
62
|
jitter: 0.2,
|
|
79
63
|
maximumDelay: 30000,
|
|
@@ -81,7 +65,7 @@ let AiService = AiService_1 = class AiService {
|
|
|
81
65
|
/**
|
|
82
66
|
* The default AI model to use for requests if not specified otherwise.
|
|
83
67
|
*/
|
|
84
|
-
defaultModel = this.#options.defaultModel ?? 'gemini-flash-lite
|
|
68
|
+
defaultModel = this.#options.defaultModel ?? 'gemini-2.5-flash-lite';
|
|
85
69
|
/**
|
|
86
70
|
* Creates a new {@link AiSession} for managing conversational history.
|
|
87
71
|
*/
|
|
@@ -231,7 +215,7 @@ let AiService = AiService_1 = class AiService {
|
|
|
231
215
|
}
|
|
232
216
|
catch (error) {
|
|
233
217
|
triesLeft -= 1;
|
|
234
|
-
if ((triesLeft > 0) &&
|
|
218
|
+
if ((triesLeft > 0) && isInstanceOf(error, ApiError) && ((error.status == 429) || (error.status == 503))) {
|
|
235
219
|
this.#logger.verbose(`Retrying after transient error: ${error.message}`);
|
|
236
220
|
backoff();
|
|
237
221
|
continue;
|
|
@@ -320,7 +304,7 @@ let AiService = AiService_1 = class AiService {
|
|
|
320
304
|
for (const call of generation.functionCalls) {
|
|
321
305
|
const fn = assertDefinedPass(options.functions[call.name], 'Function in response not declared.');
|
|
322
306
|
const parametersSchema = await resolveValueOrAsyncProvider(fn.parameters);
|
|
323
|
-
const parameters = isDefined(parametersSchema) ? parametersSchema.parse(call.parameters) : call.parameters;
|
|
307
|
+
const parameters = isDefined(parametersSchema) ? parametersSchema.parse(call.parameters, { coerce: true }) : call.parameters;
|
|
324
308
|
const handlerResult = isSchemaFunctionDeclarationWithHandler(fn) ? await fn.handler(parameters) : undefined;
|
|
325
309
|
yield {
|
|
326
310
|
functionName: call.name,
|
|
@@ -437,8 +421,8 @@ let AiService = AiService_1 = class AiService {
|
|
|
437
421
|
}
|
|
438
422
|
mapModel(model) {
|
|
439
423
|
return match(model)
|
|
440
|
-
.with('small', () => 'gemini-flash-lite
|
|
441
|
-
.with('medium', () => 'gemini-flash
|
|
424
|
+
.with('small', () => 'gemini-2.5-flash-lite')
|
|
425
|
+
.with('medium', () => 'gemini-2.5-flash')
|
|
442
426
|
.with('large', () => 'gemini-2.5-pro')
|
|
443
427
|
.otherwise(() => model ?? this.defaultModel);
|
|
444
428
|
}
|
|
@@ -486,7 +470,7 @@ export function mergeGenerationStreamItems(items, schema) {
|
|
|
486
470
|
catch (error) {
|
|
487
471
|
throw new Error(`Failed to parse model output as JSON. Raw text: "${this.text}"`, { cause: error });
|
|
488
472
|
}
|
|
489
|
-
return Schema.parse(schema, parsed);
|
|
473
|
+
return Schema.parse(schema, parsed, { coerce: true });
|
|
490
474
|
},
|
|
491
475
|
functionCalls() {
|
|
492
476
|
return parts.filter((part) => hasOwnProperty(part, 'functionCall')).map((part) => part.functionCall);
|
package/ai/functions.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { convertToOpenApiSchema } from '../schema/converters/
|
|
1
|
+
import { convertToOpenApiSchema } from '../schema/converters/open-api-converter.js';
|
|
2
2
|
import { FunctionSchema, getObjectSchema, object } from '../schema/index.js';
|
|
3
3
|
import { fromEntries, objectEntries } from '../utils/object/object.js';
|
|
4
4
|
import { isNotNull, isNull, isString } from '../utils/type-guards.js';
|
package/ai/module.d.ts
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AiModel } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Options for configuring the AI
|
|
4
|
-
* @see {@link AiServiceOptions}
|
|
3
|
+
* Options for configuring the AI Module.
|
|
5
4
|
*/
|
|
6
|
-
export
|
|
5
|
+
export declare class AiModuleOptions {
|
|
6
|
+
/** Google AI API key. */
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
/** Path to the Google Cloud credentials file. */
|
|
9
|
+
keyFile?: string;
|
|
10
|
+
/** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
|
|
11
|
+
vertex?: {
|
|
12
|
+
project: string;
|
|
13
|
+
location: string;
|
|
14
|
+
bucket?: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* The default model to use for generation requests.
|
|
18
|
+
* @default 'small'
|
|
19
|
+
*/
|
|
20
|
+
defaultModel?: AiModel;
|
|
21
|
+
}
|
|
7
22
|
/**
|
|
8
23
|
* Configures the {@link AiService}.
|
|
9
24
|
* @param options The configuration options for the AI services.
|
|
10
25
|
*/
|
|
11
|
-
export declare function configureAiService(options:
|
|
26
|
+
export declare function configureAiService(options: AiModuleOptions): void;
|
package/ai/module.js
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import { Injector } from '../injector/injector.js';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Options for configuring the AI Module.
|
|
4
|
+
*/
|
|
5
|
+
export class AiModuleOptions {
|
|
6
|
+
/** Google AI API key. */
|
|
7
|
+
apiKey;
|
|
8
|
+
/** Path to the Google Cloud credentials file. */
|
|
9
|
+
keyFile;
|
|
10
|
+
/** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
|
|
11
|
+
vertex;
|
|
12
|
+
/**
|
|
13
|
+
* The default model to use for generation requests.
|
|
14
|
+
* @default 'small'
|
|
15
|
+
*/
|
|
16
|
+
defaultModel;
|
|
17
|
+
}
|
|
18
|
+
;
|
|
3
19
|
/**
|
|
4
20
|
* Configures the {@link AiService}.
|
|
5
21
|
* @param options The configuration options for the AI services.
|
|
6
22
|
*/
|
|
7
23
|
export function configureAiService(options) {
|
|
8
|
-
Injector.register(
|
|
24
|
+
Injector.register(AiModuleOptions, { useValue: options });
|
|
9
25
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tstdl/base",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.49",
|
|
4
4
|
"author": "Patrick Hein",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -101,6 +101,8 @@
|
|
|
101
101
|
"./rxjs-utils": "./rxjs-utils/index.js",
|
|
102
102
|
"./schema": "./schema/index.js",
|
|
103
103
|
"./schema/converters": "./schema/converters/index.js",
|
|
104
|
+
"./schema/converters/open-api": "./schema/converters/open-api-converter.js",
|
|
105
|
+
"./schema/converters/zod": "./schema/converters/zod-converter.js",
|
|
104
106
|
"./serializer": "./serializer/index.js",
|
|
105
107
|
"./serializer/handlers": "./serializer/handlers/index.js",
|
|
106
108
|
"./signals": "./signals/index.js",
|
|
@@ -149,12 +151,13 @@
|
|
|
149
151
|
"mjml": "^4.17",
|
|
150
152
|
"nodemailer": "^7.0",
|
|
151
153
|
"pg": "^8.16",
|
|
152
|
-
"playwright": "^1.
|
|
154
|
+
"playwright": "^1.57",
|
|
153
155
|
"preact": "^10.27",
|
|
154
156
|
"preact-render-to-string": "^6.6",
|
|
155
157
|
"sharp": "^0.34",
|
|
156
158
|
"undici": "^7.16",
|
|
157
|
-
"urlpattern-polyfill": "^10.1"
|
|
159
|
+
"urlpattern-polyfill": "^10.1",
|
|
160
|
+
"zod": "^4.1"
|
|
158
161
|
},
|
|
159
162
|
"peerDependenciesMeta": {
|
|
160
163
|
"@tstdl/angular": {
|
|
@@ -178,7 +181,7 @@
|
|
|
178
181
|
"typedoc-plugin-markdown": "4.9",
|
|
179
182
|
"typedoc-plugin-missing-exports": "4.1",
|
|
180
183
|
"typescript": "5.9",
|
|
181
|
-
"typescript-eslint": "8.
|
|
184
|
+
"typescript-eslint": "8.48"
|
|
182
185
|
},
|
|
183
186
|
"overrides": {
|
|
184
187
|
"drizzle-kit": {
|
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
import { NotSupportedError } from '../../errors/not-supported.error.js';
|
|
2
2
|
import { filterUndefinedObjectProperties, fromEntries, hasOwnProperty, objectEntries } from '../../utils/object/object.js';
|
|
3
3
|
import { isDefined, isNotNull, isNumber, isString } from '../../utils/type-guards.js';
|
|
4
|
-
import { ArraySchema } from '../schemas/
|
|
5
|
-
import { BooleanSchema } from '../schemas/boolean.js';
|
|
6
|
-
import { DateSchema } from '../schemas/date.js';
|
|
7
|
-
import { EnumerationSchema } from '../schemas/enumeration.js';
|
|
8
|
-
import { LiteralSchema } from '../schemas/literal.js';
|
|
9
|
-
import { nullable, NullableSchema } from '../schemas/nullable.js';
|
|
10
|
-
import { NumberSchema } from '../schemas/number.js';
|
|
11
|
-
import { ObjectSchema } from '../schemas/object.js';
|
|
12
|
-
import { OptionalSchema } from '../schemas/optional.js';
|
|
13
|
-
import { StringSchema } from '../schemas/string.js';
|
|
14
|
-
import { UnionSchema } from '../schemas/union.js';
|
|
4
|
+
import { ArraySchema, BooleanSchema, DateSchema, DefaultSchema, EnumerationSchema, LiteralSchema, nullable, NullableSchema, NumberSchema, ObjectSchema, OptionalSchema, StringSchema, TransformSchema, Uint8ArraySchema, UnionSchema } from '../schemas/index.js';
|
|
15
5
|
import { schemaTestableToSchema } from '../testable.js';
|
|
16
6
|
export function convertToOpenApiSchema(testable) {
|
|
17
7
|
const schema = schemaTestableToSchema(testable);
|
|
@@ -39,12 +29,21 @@ function convertToOpenApiSchemaBase(schema) {
|
|
|
39
29
|
maxProperties: isNumber(schema.maximumPropertiesCount) ? schema.maximumPropertiesCount : undefined,
|
|
40
30
|
});
|
|
41
31
|
}
|
|
32
|
+
if (schema instanceof DefaultSchema) { // You'd need to import DefaultedSchema
|
|
33
|
+
return {
|
|
34
|
+
...convertToOpenApiSchema(schema.schema),
|
|
35
|
+
default: schema.defaultValue,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (schema instanceof TransformSchema) { // You'd need to import TransformSchema
|
|
39
|
+
return convertToOpenApiSchema(schema.schema);
|
|
40
|
+
}
|
|
42
41
|
if (schema instanceof StringSchema) {
|
|
43
42
|
return filterUndefinedObjectProperties({
|
|
44
43
|
type: 'string',
|
|
45
44
|
minLength: isNumber(schema.minimumLength) ? schema.minimumLength : undefined,
|
|
46
45
|
maxLength: isNumber(schema.maximumLength) ? schema.maximumLength : undefined,
|
|
47
|
-
pattern: isString(schema.pattern) ? schema.pattern :
|
|
46
|
+
pattern: isString(schema.pattern) ? schema.pattern : schema.pattern?.source,
|
|
48
47
|
});
|
|
49
48
|
}
|
|
50
49
|
if (schema instanceof DateSchema) {
|
|
@@ -79,6 +78,14 @@ function convertToOpenApiSchemaBase(schema) {
|
|
|
79
78
|
maxItems: isNumber(schema.maximum) ? schema.maximum : undefined,
|
|
80
79
|
});
|
|
81
80
|
}
|
|
81
|
+
if ((schema instanceof Uint8ArraySchema) && (schema.coerceType == 'base64')) {
|
|
82
|
+
return filterUndefinedObjectProperties({
|
|
83
|
+
type: 'string',
|
|
84
|
+
format: 'byte',
|
|
85
|
+
minLength: isNumber(schema.minimumLength) ? schema.minimumLength : undefined,
|
|
86
|
+
maxLength: isNumber(schema.maximumLength) ? schema.maximumLength : undefined,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
82
89
|
if (schema instanceof EnumerationSchema) {
|
|
83
90
|
const hasString = schema.allowedValues.some(isString);
|
|
84
91
|
const hasNumber = schema.allowedValues.some(isNumber);
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import * as z from 'zod/mini';
|
|
2
|
+
import { NotSupportedError } from '../../errors/not-supported.error.js';
|
|
3
|
+
import { objectEntries, objectKeys } from '../../utils/object/object.js';
|
|
4
|
+
import { isArray, isNotNull, isNumber, isString } from '../../utils/type-guards.js';
|
|
5
|
+
import { any, AnySchema, ArraySchema, BigIntSchema, BooleanSchema, DateSchema, DefaultSchema, DeferredSchema, EnumerationSchema, InstanceSchema, LiteralSchema, NeverSchema, NullableSchema, NumberSchema, ObjectSchema, OneOrManySchema, OptionalSchema, ReadableStreamSchema, RegExpSchema, StringSchema, SymbolSchema, TransformSchema, Uint8ArraySchema, UnionSchema, UnknownSchema } from '../schemas/index.js';
|
|
6
|
+
import { schemaTestableToSchema } from '../testable.js';
|
|
7
|
+
export function convertToZodSchema(testable) {
|
|
8
|
+
const schema = schemaTestableToSchema(testable);
|
|
9
|
+
return convertToZodSchemaBase(schema);
|
|
10
|
+
}
|
|
11
|
+
function convertToZodSchemaBase(schema) {
|
|
12
|
+
if (schema instanceof AnySchema) {
|
|
13
|
+
return z.any();
|
|
14
|
+
}
|
|
15
|
+
if (schema instanceof UnknownSchema) {
|
|
16
|
+
return z.unknown();
|
|
17
|
+
}
|
|
18
|
+
if (schema instanceof NeverSchema) {
|
|
19
|
+
return z.never();
|
|
20
|
+
}
|
|
21
|
+
if (schema instanceof NullableSchema) {
|
|
22
|
+
return z.nullable(convertToZodSchema(schema.schema));
|
|
23
|
+
}
|
|
24
|
+
if (schema instanceof OptionalSchema) {
|
|
25
|
+
return z.optional(convertToZodSchema(schema.schema));
|
|
26
|
+
}
|
|
27
|
+
if (schema instanceof OneOrManySchema) {
|
|
28
|
+
return convertToZodSchema(schema.schema);
|
|
29
|
+
}
|
|
30
|
+
if (schema instanceof StringSchema) {
|
|
31
|
+
const checks = [];
|
|
32
|
+
if (isNumber(schema.minimumLength)) {
|
|
33
|
+
checks.push(z.minLength(schema.minimumLength));
|
|
34
|
+
}
|
|
35
|
+
if (isNumber(schema.maximumLength)) {
|
|
36
|
+
checks.push(z.maxLength(schema.maximumLength));
|
|
37
|
+
}
|
|
38
|
+
if (isNotNull(schema.pattern)) {
|
|
39
|
+
checks.push(z.regex(isString(schema.pattern) ? new RegExp(schema.pattern) : schema.pattern));
|
|
40
|
+
}
|
|
41
|
+
if (schema.lowercase) {
|
|
42
|
+
checks.push(z.toLowerCase());
|
|
43
|
+
}
|
|
44
|
+
const zodSchema = z.string();
|
|
45
|
+
return (checks.length > 0) ? zodSchema.check(...checks) : zodSchema;
|
|
46
|
+
}
|
|
47
|
+
if (schema instanceof NumberSchema) {
|
|
48
|
+
const checks = [];
|
|
49
|
+
if (isNumber(schema.minimum)) {
|
|
50
|
+
checks.push(z.gte(schema.minimum));
|
|
51
|
+
}
|
|
52
|
+
if (isNumber(schema.maximum)) {
|
|
53
|
+
checks.push(z.lte(schema.maximum));
|
|
54
|
+
}
|
|
55
|
+
const zodSchema = (schema.integer) ? z.int() : z.number();
|
|
56
|
+
return (checks.length > 0) ? zodSchema.check(...checks) : zodSchema;
|
|
57
|
+
}
|
|
58
|
+
if (schema instanceof BooleanSchema) {
|
|
59
|
+
return z.boolean();
|
|
60
|
+
}
|
|
61
|
+
if (schema instanceof BigIntSchema) {
|
|
62
|
+
return z.bigint();
|
|
63
|
+
}
|
|
64
|
+
if (schema instanceof SymbolSchema) {
|
|
65
|
+
return z.symbol();
|
|
66
|
+
}
|
|
67
|
+
if (schema instanceof DateSchema) {
|
|
68
|
+
const checks = [];
|
|
69
|
+
if (isNotNull(schema.minimum)) {
|
|
70
|
+
checks.push(z.gte(schema.minimum));
|
|
71
|
+
}
|
|
72
|
+
if (isNotNull(schema.maximum)) {
|
|
73
|
+
checks.push(z.lte(schema.maximum));
|
|
74
|
+
}
|
|
75
|
+
const zodSchema = z.date();
|
|
76
|
+
return (checks.length > 0) ? zodSchema.check(...checks) : zodSchema;
|
|
77
|
+
}
|
|
78
|
+
if (schema instanceof LiteralSchema) {
|
|
79
|
+
return z.literal(schema.value);
|
|
80
|
+
}
|
|
81
|
+
if (schema instanceof ArraySchema) {
|
|
82
|
+
const itemSchema = convertToZodSchema(schema.itemSchema);
|
|
83
|
+
const checks = [];
|
|
84
|
+
if (isNumber(schema.minimum)) {
|
|
85
|
+
checks.push(z.minSize(schema.minimum));
|
|
86
|
+
}
|
|
87
|
+
if (isNumber(schema.maximum)) {
|
|
88
|
+
checks.push(z.maxSize(schema.maximum));
|
|
89
|
+
}
|
|
90
|
+
const zodSchema = z.array(itemSchema);
|
|
91
|
+
return (checks.length > 0) ? zodSchema.check(...checks) : zodSchema;
|
|
92
|
+
}
|
|
93
|
+
if (schema instanceof ObjectSchema) {
|
|
94
|
+
const propertyEntries = objectEntries(schema.properties);
|
|
95
|
+
if ((propertyEntries.length == 0) && (isNotNull(schema.unknownPropertiesKey) || isNotNull(schema.unknownProperties))) {
|
|
96
|
+
return z.record(convertToZodSchema(schema.unknownPropertiesKey ?? any()), convertToZodSchema(schema.unknownProperties ?? any()));
|
|
97
|
+
}
|
|
98
|
+
const shape = {};
|
|
99
|
+
for (const [key, propertySchema] of propertyEntries) {
|
|
100
|
+
shape[key] = convertToZodSchema(propertySchema);
|
|
101
|
+
}
|
|
102
|
+
const loose = isNotNull(schema.unknownPropertiesKey) || isNotNull(schema.unknownProperties);
|
|
103
|
+
const zodSchema = loose
|
|
104
|
+
? z.looseObject(shape)
|
|
105
|
+
: schema.mask
|
|
106
|
+
? z.object(shape)
|
|
107
|
+
: z.strictObject(shape);
|
|
108
|
+
if (loose) {
|
|
109
|
+
const propertiesSchema = convertToZodSchema(schema.unknownProperties ?? any());
|
|
110
|
+
const propertiesKeySchema = convertToZodSchema(schema.unknownPropertiesKey ?? any());
|
|
111
|
+
const knownPropertyKeys = new Set(objectKeys(shape));
|
|
112
|
+
return zodSchema.check(z.superRefine((record, context) => {
|
|
113
|
+
for (const [key, value] of objectEntries(record)) {
|
|
114
|
+
if (knownPropertyKeys.has(key)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const keyParseResult = propertiesKeySchema.safeParse(key);
|
|
118
|
+
const valueParseResult = propertiesSchema.safeParse(value);
|
|
119
|
+
if (!keyParseResult.success) {
|
|
120
|
+
context.addIssue({
|
|
121
|
+
code: 'invalid_key',
|
|
122
|
+
origin: 'record',
|
|
123
|
+
issues: keyParseResult.error.issues,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (!valueParseResult.success) {
|
|
127
|
+
context.addIssue({
|
|
128
|
+
code: 'custom',
|
|
129
|
+
input: value,
|
|
130
|
+
path: [key],
|
|
131
|
+
message: valueParseResult.error.message,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
return zodSchema;
|
|
138
|
+
}
|
|
139
|
+
if (schema instanceof UnionSchema) {
|
|
140
|
+
const schemas = schema.schemas.map((s) => convertToZodSchema(s));
|
|
141
|
+
return z.union(schemas);
|
|
142
|
+
}
|
|
143
|
+
if (schema instanceof EnumerationSchema) {
|
|
144
|
+
if (isArray(schema.enumeration) && schema.enumeration.some((v) => isNumber(v))) {
|
|
145
|
+
const types = schema.allowedValues.map((value) => z.literal(value));
|
|
146
|
+
return z.union(types);
|
|
147
|
+
}
|
|
148
|
+
return z.enum(schema.enumeration);
|
|
149
|
+
}
|
|
150
|
+
if (schema instanceof DefaultSchema) {
|
|
151
|
+
return z._default(convertToZodSchema(schema.schema), schema.defaultValue);
|
|
152
|
+
}
|
|
153
|
+
if (schema instanceof TransformSchema) {
|
|
154
|
+
return z.transform((input) => schema.transformFn(input));
|
|
155
|
+
}
|
|
156
|
+
if (schema instanceof DeferredSchema) {
|
|
157
|
+
return z.lazy(() => convertToZodSchema(schema.schema));
|
|
158
|
+
}
|
|
159
|
+
if (schema instanceof Uint8ArraySchema) {
|
|
160
|
+
return z.instanceof(Uint8Array);
|
|
161
|
+
}
|
|
162
|
+
if (schema instanceof ReadableStreamSchema) {
|
|
163
|
+
return z.instanceof(ReadableStream);
|
|
164
|
+
}
|
|
165
|
+
if (schema instanceof RegExpSchema) {
|
|
166
|
+
return z.instanceof(RegExp);
|
|
167
|
+
}
|
|
168
|
+
if (schema instanceof InstanceSchema) {
|
|
169
|
+
return z.instanceof(schema.type);
|
|
170
|
+
}
|
|
171
|
+
throw new NotSupportedError(`Schema "${schema.name}" cannot be converted to Zod schema.`);
|
|
172
|
+
}
|
package/schema/schemas/array.js
CHANGED
|
@@ -27,10 +27,10 @@ export class ArraySchema extends Schema {
|
|
|
27
27
|
return { valid: false, error: SchemaError.expectedButGot('array', typeOf(value), path) };
|
|
28
28
|
}
|
|
29
29
|
if (isNotNull(this.maximum) && (value.length > this.maximum)) {
|
|
30
|
-
|
|
30
|
+
return { valid: false, error: new SchemaError(`A maximum of ${this.maximum} items are allowed.`, { path, fast: options.fastErrors }) };
|
|
31
31
|
}
|
|
32
32
|
if (isNotNull(this.minimum) && (value.length < this.minimum)) {
|
|
33
|
-
|
|
33
|
+
return { valid: false, error: new SchemaError(`A minimum of ${this.minimum} items are required.`, { path, fast: options.fastErrors }) };
|
|
34
34
|
}
|
|
35
35
|
const values = [];
|
|
36
36
|
for (let i = 0; i < value.length; i++) {
|
package/schema/schemas/date.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type SchemaDecoratorOptions, type SchemaPropertyDecorator } from '../decorators/index.js';
|
|
2
2
|
import { SimpleSchema, type SimpleSchemaOptions } from './simple.js';
|
|
3
|
-
export type DateSchemaOptions = SimpleSchemaOptions<
|
|
4
|
-
|
|
3
|
+
export type DateSchemaOptions = SimpleSchemaOptions<Date> & {
|
|
4
|
+
minimum?: Date | number | null;
|
|
5
|
+
maximum?: Date | number | null;
|
|
5
6
|
};
|
|
6
|
-
export declare class DateSchema extends SimpleSchema<
|
|
7
|
+
export declare class DateSchema extends SimpleSchema<Date> {
|
|
7
8
|
readonly name = "date";
|
|
9
|
+
readonly minimum: Date | null;
|
|
10
|
+
readonly maximum: Date | null;
|
|
8
11
|
constructor(options?: DateSchemaOptions);
|
|
9
12
|
}
|
|
10
13
|
export declare function date(options?: DateSchemaOptions): DateSchema;
|
package/schema/schemas/date.js
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
|
-
import { isValidDate } from '../../utils/type-guards.js';
|
|
1
|
+
import { isNotNullOrUndefined, isValidDate } from '../../utils/type-guards.js';
|
|
2
2
|
import { PropertySchema } from '../decorators/index.js';
|
|
3
3
|
import { SchemaError } from '../schema.error.js';
|
|
4
4
|
import { SimpleSchema } from './simple.js';
|
|
5
5
|
export class DateSchema extends SimpleSchema {
|
|
6
6
|
name = 'date';
|
|
7
|
+
minimum;
|
|
8
|
+
maximum;
|
|
7
9
|
constructor(options) {
|
|
8
10
|
super('date', isValidDate, options, {
|
|
9
11
|
coercers: {
|
|
10
12
|
string: (value, path, options) => {
|
|
11
|
-
const result = new
|
|
12
|
-
return
|
|
13
|
+
const result = new Date(value);
|
|
14
|
+
return Number.isNaN(result.getTime())
|
|
13
15
|
? { success: false, error: SchemaError.couldNotCoerce('date', 'string', path, { fast: options.fastErrors }) }
|
|
14
16
|
: { success: true, value: result, valid: true };
|
|
15
17
|
},
|
|
16
|
-
number: (value) => ({ success: true, value: new
|
|
18
|
+
number: (value) => ({ success: true, value: new Date(value), valid: false }),
|
|
17
19
|
},
|
|
18
20
|
constraints: [
|
|
19
|
-
(options?.
|
|
20
|
-
|
|
21
|
+
isNotNullOrUndefined(options?.minimum) ? (value) => (value >= this.minimum) ? ({ success: true }) : ({ success: false, error: `Value ${value.toDateString()} is less than minimum ${this.minimum.toDateString()}` }) : null,
|
|
22
|
+
isNotNullOrUndefined(options?.maximum) ? (value) => (value <= this.maximum) ? ({ success: true }) : ({ success: false, error: `Value ${value.toDateString()} is greater than maximum ${this.maximum.toDateString()}` }) : null,
|
|
23
|
+
],
|
|
21
24
|
});
|
|
25
|
+
this.minimum = isNotNullOrUndefined(options?.minimum) ? new Date(options.minimum) : null;
|
|
26
|
+
this.maximum = isNotNullOrUndefined(options?.maximum) ? new Date(options.maximum) : null;
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
export function date(options) {
|
|
@@ -27,14 +27,14 @@ export function Method(parameterSchemasOrOptions, returnValueSchema, optionsOrNo
|
|
|
27
27
|
if (isArray(parameterSchemasOrOptions) || isNull(parameterSchemasOrOptions)) {
|
|
28
28
|
return Property({
|
|
29
29
|
...optionsOrNothing,
|
|
30
|
-
schema: (data) => func(parameterSchemasOrOptions, returnValueSchema, { description: data.description, example: data.example, ...optionsOrNothing })
|
|
30
|
+
schema: (data) => func(parameterSchemasOrOptions, returnValueSchema, { description: data.description, example: data.example, ...optionsOrNothing }),
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
return createMethodDecorator({
|
|
34
34
|
handler: (data, _metdata, originalArguments) => {
|
|
35
35
|
createSchemaDecorator(parameterSchemasOrOptions)(...originalArguments);
|
|
36
36
|
Property(getFunctionSchemaFromReflection(data.constructor, data.methodKey), parameterSchemasOrOptions);
|
|
37
|
-
}
|
|
37
|
+
},
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
export function getFunctionSchemaFromReflection(type, method) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JsonPath } from '../../json-path/json-path.js';
|
|
2
2
|
import type { AbstractConstructor } from '../../types/index.js';
|
|
3
|
-
import { type
|
|
3
|
+
import { type SchemaDecoratorOptions, type SchemaPropertyDecorator } from '../decorators/index.js';
|
|
4
4
|
import { Schema, type SchemaOptions, type SchemaTestOptions, type SchemaTestResult } from '../schema.js';
|
|
5
5
|
export type InstanceSchemaOptions<T extends AbstractConstructor> = SchemaOptions<InstanceType<T>>;
|
|
6
6
|
export declare class InstanceSchema<T extends AbstractConstructor> extends Schema<InstanceType<T>> {
|
|
@@ -17,7 +17,7 @@ export class InstanceSchema extends Schema {
|
|
|
17
17
|
}
|
|
18
18
|
return {
|
|
19
19
|
valid: false,
|
|
20
|
-
error: SchemaError.expectedButGot(typeOf(this.type), typeOf(value), path, { fast: options.fastErrors })
|
|
20
|
+
error: SchemaError.expectedButGot(typeOf(this.type), typeOf(value), path, { fast: options.fastErrors }),
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -47,6 +47,11 @@ export declare class ObjectSchema<T extends Record = Record> extends Schema<T> {
|
|
|
47
47
|
readonly factory: ObjectSchemaFactory<T> | null;
|
|
48
48
|
constructor(properties: ObjectSchemaProperties<T>, options?: ObjectSchemaOptions<T>);
|
|
49
49
|
_test(value: any, path: JsonPath, options: SchemaTestOptions): SchemaTestResult<T>;
|
|
50
|
+
pick<const K extends keyof T>(keys: OneOrMany<K>): ObjectSchema<SimplifyObject<Pick<T, K>>>;
|
|
51
|
+
omit<const K extends keyof T>(keys: OneOrMany<K>): ObjectSchema<SimplifyObject<Omit<T, K>>>;
|
|
52
|
+
partial(): ObjectSchema<Partial<T>>;
|
|
53
|
+
partial<const K extends keyof T>(keys: OneOrMany<K>): ObjectSchema<PartialProperty<T, K>>;
|
|
54
|
+
assign<T extends Record>(other: ObjectSchemaOrType<T>): ObjectSchema<Merge<T, T>>;
|
|
50
55
|
}
|
|
51
56
|
export declare function object<const K extends PropertyKey, const V>(properties: Record<never>, options: ObjectSchemaOptions<Record<K, V>> & {
|
|
52
57
|
unknownProperties: SchemaTestable<V>;
|
package/schema/schemas/object.js
CHANGED
|
@@ -81,6 +81,18 @@ export class ObjectSchema extends Schema {
|
|
|
81
81
|
const testResultValue = isFunction(this.factory) ? this.factory(resultValue) : resultValue;
|
|
82
82
|
return { valid: true, value: testResultValue };
|
|
83
83
|
}
|
|
84
|
+
pick(keys) {
|
|
85
|
+
return pick(this, keys);
|
|
86
|
+
}
|
|
87
|
+
omit(keys) {
|
|
88
|
+
return omit(this, keys);
|
|
89
|
+
}
|
|
90
|
+
partial(keys) {
|
|
91
|
+
return partial(this, keys);
|
|
92
|
+
}
|
|
93
|
+
assign(other) {
|
|
94
|
+
return assign(this, other);
|
|
95
|
+
}
|
|
84
96
|
}
|
|
85
97
|
export function object(properties, options) {
|
|
86
98
|
return new ObjectSchema(properties, options);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type SchemaDecoratorOptions, type SchemaPropertyDecorator } from '../decorators/index.js';
|
|
2
2
|
import { SimpleSchema, type SimpleSchemaOptions } from './simple.js';
|
|
3
3
|
export type RegExpSchemaOptions = SimpleSchemaOptions<RegExp>;
|
|
4
4
|
export declare class RegExpSchema extends SimpleSchema<RegExp> {
|
package/schema/schemas/regexp.js
CHANGED
|
@@ -15,8 +15,8 @@ export class RegExpSchema extends SimpleSchema {
|
|
|
15
15
|
catch (error) {
|
|
16
16
|
return { success: false, error: SchemaError.couldNotCoerce(globalThis.RegExp, 'string', path, { fast: options.fastErrors, customMessage: error.message }) };
|
|
17
17
|
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type SchemaDecoratorOptions, type SchemaPropertyDecorator } from '../decorators/index.js';
|
|
2
2
|
import { SimpleSchema, type SimpleSchemaOptions } from './simple.js';
|
|
3
3
|
export type Uint8ArraySchemaOptions = SimpleSchemaOptions<Uint8Array> & {
|
|
4
4
|
/** Minimum byte length */
|
|
5
5
|
minimumLength?: number;
|
|
6
6
|
/** Maximum byte length */
|
|
7
7
|
maximumLength?: number;
|
|
8
|
+
/** Type to coerce from string */
|
|
9
|
+
coerceType?: Uint8ArraySchema['coerceType'];
|
|
8
10
|
};
|
|
9
11
|
export declare class Uint8ArraySchema extends SimpleSchema<Uint8Array> {
|
|
10
12
|
readonly name = "Uint8Array";
|
|
11
13
|
readonly minimumLength: number | null;
|
|
12
14
|
readonly maximumLength: number | null;
|
|
15
|
+
readonly coerceType: 'base64' | 'base64url' | 'zbase32' | 'hex' | null;
|
|
13
16
|
constructor(options?: Uint8ArraySchemaOptions);
|
|
14
17
|
}
|
|
15
18
|
export declare function uint8Array(options?: Uint8ArraySchemaOptions): Uint8ArraySchema;
|
|
@@ -1,19 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { match } from 'ts-pattern';
|
|
2
|
+
import { AssertionError } from '../../errors/index.js';
|
|
3
|
+
import { decodeBase64, decodeBase64Url } from '../../utils/base64.js';
|
|
4
|
+
import { decodeHex } from '../../utils/encoding.js';
|
|
5
|
+
import { isDefined, isInstanceOf, isUint8Array } from '../../utils/type-guards.js';
|
|
6
|
+
import { zBase32Decode } from '../../utils/z-base32.js';
|
|
2
7
|
import { PropertySchema } from '../decorators/index.js';
|
|
8
|
+
import { SchemaError } from '../schema.error.js';
|
|
3
9
|
import { SimpleSchema } from './simple.js';
|
|
4
10
|
export class Uint8ArraySchema extends SimpleSchema {
|
|
5
11
|
name = 'Uint8Array';
|
|
6
12
|
minimumLength;
|
|
7
13
|
maximumLength;
|
|
14
|
+
coerceType;
|
|
8
15
|
constructor(options) {
|
|
9
16
|
super('Uint8Array', isUint8Array, options, {
|
|
17
|
+
coercers: {
|
|
18
|
+
string: isDefined(options?.coerceType)
|
|
19
|
+
? (value, path, options) => {
|
|
20
|
+
try {
|
|
21
|
+
const coerced = match(this.coerceType)
|
|
22
|
+
.with('base64', () => decodeBase64(value))
|
|
23
|
+
.with('base64url', () => decodeBase64Url(value))
|
|
24
|
+
.with('zbase32', () => zBase32Decode(value))
|
|
25
|
+
.with('hex', () => decodeHex(value))
|
|
26
|
+
.exhaustive();
|
|
27
|
+
return { success: true, valid: true, value: coerced };
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (isInstanceOf(error, AssertionError)) {
|
|
31
|
+
return { success: false, error: SchemaError.couldNotCoerce(`${this.coerceType} formatted string`, 'string', path, { fast: options.fastErrors, customMessage: error.message }) };
|
|
32
|
+
}
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
: undefined,
|
|
37
|
+
},
|
|
10
38
|
constraints: [
|
|
11
39
|
isDefined(options?.minimumLength) ? (value) => (value.byteLength >= this.minimumLength) ? ({ success: true }) : ({ success: false, error: `Size must be at least ${this.minimumLength} bytes.` }) : null,
|
|
12
|
-
isDefined(options?.maximumLength) ? (value) => (value.byteLength <= this.maximumLength) ? ({ success: true }) : ({ success: false, error: `Size must be at most ${this.maximumLength} bytes.` }) : null
|
|
13
|
-
]
|
|
40
|
+
isDefined(options?.maximumLength) ? (value) => (value.byteLength <= this.maximumLength) ? ({ success: true }) : ({ success: false, error: `Size must be at most ${this.maximumLength} bytes.` }) : null,
|
|
41
|
+
],
|
|
14
42
|
});
|
|
15
43
|
this.minimumLength = options?.minimumLength ?? null;
|
|
16
44
|
this.maximumLength = options?.maximumLength ?? null;
|
|
45
|
+
this.coerceType = options?.coerceType ?? null;
|
|
17
46
|
}
|
|
18
47
|
}
|
|
19
48
|
export function uint8Array(options) {
|
package/utils/encoding.js
CHANGED
|
@@ -62,7 +62,7 @@ export function decodeHex(hex) {
|
|
|
62
62
|
const hexPart = hex.substring(i, i + 2);
|
|
63
63
|
const byte = hexToByte.get(hexPart);
|
|
64
64
|
if (isUndefined(byte)) {
|
|
65
|
-
throw new AssertionError(`
|
|
65
|
+
throw new AssertionError(`Invalid hex string at position ${i}.`);
|
|
66
66
|
}
|
|
67
67
|
bytes[i / 2] = byte;
|
|
68
68
|
}
|
package/utils/z-base32.d.ts
CHANGED
package/utils/z-base32.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AssertionError } from '../errors/index.js';
|
|
1
2
|
import { Alphabet } from './alphabet.js';
|
|
2
3
|
import { toUint8Array } from './binary.js';
|
|
3
4
|
const alphabet = Alphabet.ZBase32;
|
|
@@ -30,7 +31,7 @@ export function zBase32Decode(input) {
|
|
|
30
31
|
const char = input[i];
|
|
31
32
|
const charValue = charValueMap.get(char);
|
|
32
33
|
if (charValue == undefined) {
|
|
33
|
-
throw new
|
|
34
|
+
throw new AssertionError(`Invalid character at index ${i}.`);
|
|
34
35
|
}
|
|
35
36
|
value = (value << 5) | charValue;
|
|
36
37
|
bits += 5;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './openapi-converter.js';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './openapi-converter.js';
|
|
File without changes
|