@sinclair/typebox
Advanced tools
@@ -17,5 +17,2 @@ import { ValueError } from '../errors/index'; | ||
| } | ||
| export declare namespace Property { | ||
| function Check(propertyName: string): boolean; | ||
| } | ||
| export declare class TypeCompilerUnknownTypeError extends Error { | ||
@@ -22,0 +19,0 @@ readonly schema: Types.TSchema; |
+63
-64
@@ -30,3 +30,3 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.TypeCompiler = exports.TypeCompilerUnknownTypeError = exports.Property = exports.TypeCheck = void 0; | ||
| exports.TypeCompiler = exports.TypeCompilerUnknownTypeError = exports.TypeCheck = void 0; | ||
| const index_1 = require("../errors/index"); | ||
@@ -60,39 +60,31 @@ const index_2 = require("../guard/index"); | ||
| exports.TypeCheck = TypeCheck; | ||
| // ------------------------------------------------------------------ | ||
| // Guards | ||
| // ------------------------------------------------------------------ | ||
| function IsNumber(value) { | ||
| return value !== undefined && typeof value === 'number'; | ||
| } | ||
| function IsBoolean(value) { | ||
| return value !== undefined && typeof value === 'boolean'; | ||
| } | ||
| function IsString(value) { | ||
| return value !== undefined && typeof value === 'string'; | ||
| } | ||
| // ------------------------------------------------------------------ | ||
| // StringConstant | ||
| // ------------------------------------------------------------------ | ||
| function StringConstant(value) { | ||
| if (!IsString(value)) | ||
| throw Error('ConstantString: Not a String'); | ||
| const canonical = JSON.stringify(value).slice(1, -1); | ||
| const escaped = canonical.replace(/'/g, "\\'"); | ||
| return `'${escaped}'`; | ||
| } | ||
| // ------------------------------------------------------------------ | ||
| // MemberExpression | ||
| // ------------------------------------------------------------------ | ||
| function MemberExpression(value, key) { | ||
| return `${value}[${StringConstant(key)}]`; | ||
| } | ||
| // ------------------------------------------------------------------- | ||
| // Property | ||
| // ------------------------------------------------------------------- | ||
| var Property; | ||
| (function (Property) { | ||
| function DollarSign(code) { | ||
| return code === 36; | ||
| } | ||
| function Underscore(code) { | ||
| return code === 95; | ||
| } | ||
| function Numeric(code) { | ||
| return code >= 48 && code <= 57; | ||
| } | ||
| function Alpha(code) { | ||
| return (code >= 65 && code <= 90) || (code >= 97 && code <= 122); | ||
| } | ||
| function Check(propertyName) { | ||
| if (propertyName.length === 0) | ||
| return false; | ||
| { | ||
| const code = propertyName.charCodeAt(0); | ||
| if (!(DollarSign(code) || Underscore(code) || Alpha(code))) { | ||
| return false; | ||
| } | ||
| } | ||
| for (let i = 1; i < propertyName.length; i++) { | ||
| const code = propertyName.charCodeAt(i); | ||
| if (!(DollarSign(code) || Underscore(code) || Alpha(code) || Numeric(code))) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| Property.Check = Check; | ||
| })(Property = exports.Property || (exports.Property = {})); | ||
| // ------------------------------------------------------------------- | ||
| // TypeCompiler | ||
@@ -118,7 +110,7 @@ // ------------------------------------------------------------------- | ||
| const expression = CreateExpression(schema.items, 'value'); | ||
| if (schema.minItems !== undefined) | ||
| if (IsNumber(schema.minItems)) | ||
| yield `(${value}.length >= ${schema.minItems})`; | ||
| if (schema.maxItems !== undefined) | ||
| if (IsNumber(schema.maxItems)) | ||
| yield `(${value}.length <= ${schema.maxItems})`; | ||
| if (schema.uniqueItems !== undefined) | ||
| if (IsBoolean(schema.uniqueItems)) | ||
| yield `(new Set(${value}).size === ${value}.length)`; | ||
@@ -138,11 +130,11 @@ yield `(Array.isArray(${value}) && ${value}.every(value => ${expression}))`; | ||
| yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`; | ||
| if (schema.multipleOf !== undefined) | ||
| if (IsNumber(schema.multipleOf)) | ||
| yield `(${value} % ${schema.multipleOf} === 0)`; | ||
| if (schema.exclusiveMinimum !== undefined) | ||
| if (IsNumber(schema.exclusiveMinimum)) | ||
| yield `(${value} > ${schema.exclusiveMinimum})`; | ||
| if (schema.exclusiveMaximum !== undefined) | ||
| if (IsNumber(schema.exclusiveMaximum)) | ||
| yield `(${value} < ${schema.exclusiveMaximum})`; | ||
| if (schema.minimum !== undefined) | ||
| if (IsNumber(schema.minimum)) | ||
| yield `(${value} >= ${schema.minimum})`; | ||
| if (schema.maximum !== undefined) | ||
| if (IsNumber(schema.maximum)) | ||
| yield `(${value} <= ${schema.maximum})`; | ||
@@ -154,4 +146,7 @@ } | ||
| } | ||
| else if (typeof schema.const === 'string') { | ||
| yield `(${value} === ${StringConstant(schema.const)})`; | ||
| } | ||
| else { | ||
| yield `(${value} === '${schema.const}')`; | ||
| throw Error('Invalid Literal Value'); | ||
| } | ||
@@ -167,11 +162,11 @@ } | ||
| yield `(typeof ${value} === 'number')`; | ||
| if (schema.multipleOf !== undefined) | ||
| if (IsNumber(schema.multipleOf)) | ||
| yield `(${value} % ${schema.multipleOf} === 0)`; | ||
| if (schema.exclusiveMinimum !== undefined) | ||
| if (IsNumber(schema.exclusiveMinimum)) | ||
| yield `(${value} > ${schema.exclusiveMinimum})`; | ||
| if (schema.exclusiveMaximum !== undefined) | ||
| if (IsNumber(schema.exclusiveMaximum)) | ||
| yield `(${value} < ${schema.exclusiveMaximum})`; | ||
| if (schema.minimum !== undefined) | ||
| if (IsNumber(schema.minimum)) | ||
| yield `(${value} >= ${schema.minimum})`; | ||
| if (schema.maximum !== undefined) | ||
| if (IsNumber(schema.maximum)) | ||
| yield `(${value} <= ${schema.maximum})`; | ||
@@ -181,5 +176,5 @@ } | ||
| yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`; | ||
| if (schema.minProperties !== undefined) | ||
| if (IsNumber(schema.minProperties)) | ||
| yield `(Object.keys(${value}).length >= ${schema.minProperties})`; | ||
| if (schema.maxProperties !== undefined) | ||
| if (IsNumber(schema.maxProperties)) | ||
| yield `(Object.keys(${value}).length <= ${schema.maxProperties})`; | ||
@@ -196,3 +191,3 @@ const propertyKeys = globalThis.Object.keys(schema.properties); | ||
| else { | ||
| const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`; | ||
| const keys = `[${propertyKeys.map((key) => `${StringConstant(key)}`).join(', ')}]`; | ||
| yield `(Object.keys(${value}).every(key => ${keys}.includes(key)))`; | ||
@@ -203,7 +198,7 @@ } | ||
| const expression = CreateExpression(schema.additionalProperties, 'value[key]'); | ||
| const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`; | ||
| const keys = `[${propertyKeys.map((key) => `${StringConstant(key)}`).join(', ')}]`; | ||
| yield `(Object.keys(${value}).every(key => ${keys}.includes(key) || ${expression}))`; | ||
| } | ||
| for (const propertyKey of propertyKeys) { | ||
| const memberExpression = Property.Check(propertyKey) ? `${value}.${propertyKey}` : `${value}['${propertyKey}']`; | ||
| const memberExpression = MemberExpression(value, propertyKey); | ||
| const propertySchema = schema.properties[propertyKey]; | ||
@@ -225,3 +220,3 @@ if (schema.required && schema.required.includes(propertyKey)) { | ||
| const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0]; | ||
| const local = PushLocal(`new RegExp(/${keyPattern}/)`); | ||
| const local = PushLocal(`${new RegExp(keyPattern)}`); | ||
| yield `(Object.keys(${value}).every(key => ${local}.test(key)))`; | ||
@@ -248,14 +243,14 @@ const expression = CreateExpression(valueSchema, 'value'); | ||
| yield `(typeof ${value} === 'string')`; | ||
| if (schema.minLength !== undefined) { | ||
| if (IsNumber(schema.minLength)) { | ||
| yield `(${value}.length >= ${schema.minLength})`; | ||
| } | ||
| if (schema.maxLength !== undefined) { | ||
| if (IsNumber(schema.maxLength)) { | ||
| yield `(${value}.length <= ${schema.maxLength})`; | ||
| } | ||
| if (schema.pattern !== undefined) { | ||
| const local = PushLocal(`new RegExp(/${schema.pattern}/);`); | ||
| if (IsString(schema.pattern)) { | ||
| const local = PushLocal(`${new RegExp(schema.pattern)}`); | ||
| yield `(${local}.test(${value}))`; | ||
| } | ||
| if (schema.format !== undefined) { | ||
| yield `(format('${schema.format}', ${value}))`; | ||
| yield `(format(${StringConstant(schema.format)}, ${value}))`; | ||
| } | ||
@@ -267,2 +262,4 @@ } | ||
| return yield `(${value}.length === 0)`; | ||
| if (!IsNumber(schema.maxItems)) | ||
| throw Error('MaxItems: Not a Number'); | ||
| yield `(${value}.length === ${schema.maxItems})`; | ||
@@ -283,5 +280,5 @@ for (let i = 0; i < schema.items.length; i++) { | ||
| yield `(${value} instanceof Uint8Array)`; | ||
| if (schema.maxByteLength) | ||
| if (IsNumber(schema.maxByteLength)) | ||
| yield `(${value}.length <= ${schema.maxByteLength})`; | ||
| if (schema.minByteLength) | ||
| if (IsNumber(schema.minByteLength)) | ||
| yield `(${value}.length >= ${schema.minByteLength})`; | ||
@@ -381,2 +378,4 @@ } | ||
| function CreateFunctionName($id) { | ||
| if (!/^[a-zA-Z0-9_-]+$/.test($id)) | ||
| throw Error(`Invalid $id: '${$id}'`); | ||
| return `check_${$id.replace(/-/g, '_')}`; | ||
@@ -383,0 +382,0 @@ } |
+5
-2
| { | ||
| "name": "@sinclair/typebox", | ||
| "version": "0.24.51", | ||
| "version": "0.24.52", | ||
| "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript", | ||
@@ -17,3 +17,3 @@ "keywords": [ | ||
| "type": "git", | ||
| "url": "https://github.com/sinclairzx81/typebox" | ||
| "url": "https://github.com/sinclairzx81/sinclair-typebox" | ||
| }, | ||
@@ -40,3 +40,6 @@ "scripts": { | ||
| "typescript": "^4.8.2" | ||
| }, | ||
| "allowScripts": { | ||
| "esbuild@0.14.53": true | ||
| } | ||
| } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
300388
-1.99%4832
-0.08%