@fp-ts/schema
Advanced tools
Comparing version 0.2.0 to 0.2.1
@@ -7,2 +7,10 @@ /** | ||
*/ | ||
export type Brand = ReadonlyArray<string>; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export declare const BrandId = "@fp-ts/schema/annotation/BrandId"; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export type Custom = unknown; | ||
@@ -9,0 +17,0 @@ /** |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.TitleId = exports.MessageId = exports.JSONSchemaId = exports.IdentifierId = exports.ExamplesId = exports.DocumentationId = exports.DescriptionId = exports.CustomId = void 0; | ||
exports.TitleId = exports.MessageId = exports.JSONSchemaId = exports.IdentifierId = exports.ExamplesId = exports.DocumentationId = exports.DescriptionId = exports.CustomId = exports.BrandId = void 0; | ||
/** | ||
@@ -14,2 +14,7 @@ * @since 1.0.0 | ||
*/ | ||
const BrandId = "@fp-ts/schema/annotation/BrandId"; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
exports.BrandId = BrandId; | ||
const CustomId = "@fp-ts/schema/annotation/CustomId"; | ||
@@ -16,0 +21,0 @@ /** |
20
AST.d.ts
@@ -132,2 +132,7 @@ /** | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
export declare const isUnknownKeyword: (ast: AST) => ast is UnknownKeyword; | ||
/** | ||
* @category model | ||
@@ -145,2 +150,7 @@ * @since 1.0.0 | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
export declare const isAnyKeyword: (ast: AST) => ast is AnyKeyword; | ||
/** | ||
* @category model | ||
@@ -192,2 +202,7 @@ * @since 1.0.0 | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
export declare const isBooleanKeyword: (ast: AST) => ast is BooleanKeyword; | ||
/** | ||
* @category model | ||
@@ -205,2 +220,7 @@ * @since 1.0.0 | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
export declare const isBigIntKeyword: (ast: AST) => ast is BigIntKeyword; | ||
/** | ||
* @category model | ||
@@ -207,0 +227,0 @@ * @since 1.0.0 |
349
AST.js
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.voidKeyword = exports.unknownKeyword = exports.undefinedKeyword = exports.symbolKeyword = exports.stringKeyword = exports.setAnnotation = exports.pick = exports.partial = exports.omit = exports.objectKeyword = exports.numberKeyword = exports.neverKeyword = exports.mergeAnnotations = exports.keyof = exports.isUniqueSymbol = exports.isUnion = exports.isTypeLiteral = exports.isTypeAlias = exports.isTuple = exports.isTransform = exports.isTemplateLiteral = exports.isSymbolKeyword = exports.isStringKeyword = exports.isRefinement = exports.isNumberKeyword = exports.isLiteral = exports.isLazy = exports.getWeight = exports.getPropertySignatures = exports.getParameter = exports.getCompiler = exports.getCardinality = exports.getAnnotation = exports.createUniqueSymbol = exports.createUnion = exports.createTypeLiteral = exports.createTypeAlias = exports.createTuple = exports.createTransform = exports.createTemplateLiteral = exports.createRefinement = exports.createRecord = exports.createPropertySignature = exports.createLiteral = exports.createLazy = exports.createIndexSignature = exports.createEnums = exports.createElement = exports.booleanKeyword = exports.bigIntKeyword = exports.appendRestElement = exports.appendElement = exports.anyKeyword = void 0; | ||
exports.voidKeyword = exports.unknownKeyword = exports.undefinedKeyword = exports.symbolKeyword = exports.stringKeyword = exports.setAnnotation = exports.pick = exports.partial = exports.omit = exports.objectKeyword = exports.numberKeyword = exports.neverKeyword = exports.mergeAnnotations = exports.keyof = exports.isUnknownKeyword = exports.isUniqueSymbol = exports.isUnion = exports.isTypeLiteral = exports.isTypeAlias = exports.isTuple = exports.isTransform = exports.isTemplateLiteral = exports.isSymbolKeyword = exports.isStringKeyword = exports.isRefinement = exports.isNumberKeyword = exports.isLiteral = exports.isLazy = exports.isBooleanKeyword = exports.isBigIntKeyword = exports.isAnyKeyword = exports.getCompiler = exports.getAnnotation = exports.createUniqueSymbol = exports.createUnion = exports.createTypeLiteral = exports.createTypeAlias = exports.createTuple = exports.createTransform = exports.createTemplateLiteral = exports.createRefinement = exports.createRecord = exports.createPropertySignature = exports.createLiteral = exports.createLazy = exports.createIndexSignature = exports.createEnums = exports.createElement = exports.booleanKeyword = exports.bigIntKeyword = exports.appendRestElement = exports.appendElement = exports.anyKeyword = exports._getWeight = exports._getPropertySignatures = exports._getParameter = exports._getCardinality = void 0; | ||
var _Function = /*#__PURE__*/require("@fp-ts/core/Function"); | ||
@@ -119,6 +119,12 @@ var Number = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/core/Number")); | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
exports.unknownKeyword = unknownKeyword; | ||
const isUnknownKeyword = ast => ast._tag === "UnknownKeyword"; | ||
/** | ||
* @category constructors | ||
* @since 1.0.0 | ||
*/ | ||
exports.unknownKeyword = unknownKeyword; | ||
exports.isUnknownKeyword = isUnknownKeyword; | ||
const anyKeyword = { | ||
@@ -131,6 +137,12 @@ _tag: "AnyKeyword", | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
exports.anyKeyword = anyKeyword; | ||
const isAnyKeyword = ast => ast._tag === "AnyKeyword"; | ||
/** | ||
* @category constructors | ||
* @since 1.0.0 | ||
*/ | ||
exports.anyKeyword = anyKeyword; | ||
exports.isAnyKeyword = isAnyKeyword; | ||
const stringKeyword = { | ||
@@ -177,6 +189,12 @@ _tag: "StringKeyword", | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
exports.booleanKeyword = booleanKeyword; | ||
const isBooleanKeyword = ast => ast._tag === "BooleanKeyword"; | ||
/** | ||
* @category constructors | ||
* @since 1.0.0 | ||
*/ | ||
exports.booleanKeyword = booleanKeyword; | ||
exports.isBooleanKeyword = isBooleanKeyword; | ||
const bigIntKeyword = { | ||
@@ -189,6 +207,12 @@ _tag: "BigIntKeyword", | ||
/** | ||
* @category guards | ||
* @since 1.0.0 | ||
*/ | ||
exports.bigIntKeyword = bigIntKeyword; | ||
const isBigIntKeyword = ast => ast._tag === "BigIntKeyword"; | ||
/** | ||
* @category constructors | ||
* @since 1.0.0 | ||
*/ | ||
exports.bigIntKeyword = bigIntKeyword; | ||
exports.isBigIntKeyword = isBigIntKeyword; | ||
const symbolKeyword = { | ||
@@ -290,39 +314,2 @@ _tag: "SymbolKeyword", | ||
}); | ||
/** @internal */ | ||
exports.createIndexSignature = createIndexSignature; | ||
const getCardinality = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return getCardinality(ast.type); | ||
case "NeverKeyword": | ||
return 0; | ||
case "Literal": | ||
case "UndefinedKeyword": | ||
case "VoidKeyword": | ||
case "UniqueSymbol": | ||
return 1; | ||
case "BooleanKeyword": | ||
return 2; | ||
case "StringKeyword": | ||
case "NumberKeyword": | ||
case "BigIntKeyword": | ||
case "SymbolKeyword": | ||
return 3; | ||
case "ObjectKeyword": | ||
return 4; | ||
case "UnknownKeyword": | ||
case "AnyKeyword": | ||
return 6; | ||
case "Refinement": | ||
return getCardinality(ast.from); | ||
case "Transform": | ||
return getCardinality(ast.to); | ||
default: | ||
return 5; | ||
} | ||
}; | ||
exports.getCardinality = getCardinality; | ||
const sortByCardinalityAsc = /*#__PURE__*/RA.sort( /*#__PURE__*/(0, _Function.pipe)(Number.Order, /*#__PURE__*/Order.contramap(({ | ||
type | ||
}) => getCardinality(type)))); | ||
/** | ||
@@ -332,2 +319,3 @@ * @category constructors | ||
*/ | ||
exports.createIndexSignature = createIndexSignature; | ||
const createTypeLiteral = (propertySignatures, indexSignatures, annotations = {}) => ({ | ||
@@ -345,48 +333,2 @@ _tag: "TypeLiteral", | ||
const isTypeLiteral = ast => ast._tag === "TypeLiteral"; | ||
/** @internal */ | ||
exports.isTypeLiteral = isTypeLiteral; | ||
const getWeight = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return getWeight(ast.type); | ||
case "Tuple": | ||
return ast.elements.length + (O.isSome(ast.rest) ? ast.rest.value.length : 0); | ||
case "TypeLiteral": | ||
return ast.propertySignatures.length + ast.indexSignatures.length; | ||
case "Union": | ||
return ast.types.reduce((n, member) => n + getWeight(member), 0); | ||
case "Lazy": | ||
return 10; | ||
case "Refinement": | ||
return getWeight(ast.from); | ||
case "Transform": | ||
return getWeight(ast.to); | ||
default: | ||
return 0; | ||
} | ||
}; | ||
exports.getWeight = getWeight; | ||
const sortByWeightDesc = /*#__PURE__*/RA.sort( /*#__PURE__*/Order.reverse( /*#__PURE__*/(0, _Function.pipe)(Number.Order, /*#__PURE__*/Order.contramap(getWeight)))); | ||
const unify = candidates => { | ||
let out = (0, _Function.pipe)(candidates, RA.flatMap(ast => { | ||
switch (ast._tag) { | ||
case "NeverKeyword": | ||
return []; | ||
case "Union": | ||
return ast.types; | ||
default: | ||
return [ast]; | ||
} | ||
})); | ||
if (out.some(isStringKeyword)) { | ||
out = out.filter(m => !(isLiteral(m) && typeof m.literal === "string")); | ||
} | ||
if (out.some(isNumberKeyword)) { | ||
out = out.filter(m => !(isLiteral(m) && typeof m.literal === "number")); | ||
} | ||
if (out.some(isSymbolKeyword)) { | ||
out = out.filter(m => !isUniqueSymbol(m)); | ||
} | ||
return out; | ||
}; | ||
/** | ||
@@ -396,2 +338,3 @@ * @category constructors | ||
*/ | ||
exports.isTypeLiteral = isTypeLiteral; | ||
const createUnion = (candidates, annotations = {}) => { | ||
@@ -472,5 +415,5 @@ const types = unify(candidates); | ||
const isTransform = ast => ast._tag === "Transform"; | ||
// --------------------------------------------- | ||
// ------------------------------------------------------------------------------------- | ||
// API | ||
// --------------------------------------------- | ||
// ------------------------------------------------------------------------------------- | ||
/** | ||
@@ -534,31 +477,2 @@ * Adds a group of annotations, potentially overwriting existing annotations. | ||
}; | ||
/** @internal */ | ||
exports.appendElement = appendElement; | ||
const getParameter = x => isRefinement(x) ? getParameter(x.from) : x; | ||
exports.getParameter = getParameter; | ||
const _keyof = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return _keyof(ast.type); | ||
case "NeverKeyword": | ||
case "AnyKeyword": | ||
return [stringKeyword, numberKeyword, symbolKeyword]; | ||
case "StringKeyword": | ||
return [createLiteral("length")]; | ||
case "TypeLiteral": | ||
return ast.propertySignatures.map(p => typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)).concat(ast.indexSignatures.map(is => getParameter(is.parameter))); | ||
case "Union": | ||
{ | ||
return getPropertySignatures(ast).map(p => typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)); | ||
} | ||
case "Lazy": | ||
return _keyof(ast.f()); | ||
case "Refinement": | ||
return _keyof(ast.from); | ||
case "Transform": | ||
return _keyof(ast.to); | ||
default: | ||
return []; | ||
} | ||
}; | ||
/** | ||
@@ -569,2 +483,3 @@ * Equivalent at runtime to the TypeScript type-level `keyof` operator. | ||
*/ | ||
exports.appendElement = appendElement; | ||
const keyof = ast => createUnion(_keyof(ast)); | ||
@@ -618,3 +533,3 @@ /** | ||
const pick = (ast, keys) => { | ||
return createTypeLiteral(getPropertySignatures(ast).filter(ps => keys.includes(ps.name)), []); | ||
return createTypeLiteral(_getPropertySignatures(ast).filter(ps => keys.includes(ps.name)), []); | ||
}; | ||
@@ -628,37 +543,4 @@ /** | ||
const omit = (ast, keys) => { | ||
return createTypeLiteral(getPropertySignatures(ast).filter(ps => !keys.includes(ps.name)), []); | ||
return createTypeLiteral(_getPropertySignatures(ast).filter(ps => !keys.includes(ps.name)), []); | ||
}; | ||
/** @internal */ | ||
exports.omit = omit; | ||
const getPropertySignatures = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return getPropertySignatures(ast.type); | ||
case "Tuple": | ||
return ast.elements.map((element, i) => createPropertySignature(i, element.type, element.isOptional, ast.isReadonly)); | ||
case "TypeLiteral": | ||
return ast.propertySignatures; | ||
case "Union": | ||
{ | ||
const propertySignatures = ast.types.map(getPropertySignatures); | ||
return (0, _Function.pipe)(propertySignatures[0], RA.filterMap(({ | ||
name | ||
}) => { | ||
if (propertySignatures.every(ps => ps.some(p => p.name === name))) { | ||
const members = (0, _Function.pipe)(propertySignatures, RA.flatMap(ps => ps.filter(p => p.name === name))); | ||
return O.some(createPropertySignature(name, createUnion(members.map(p => p.type)), members.some(p => p.isOptional), members.some(p => p.isReadonly))); | ||
} | ||
return O.none(); | ||
})); | ||
} | ||
case "Lazy": | ||
return getPropertySignatures(ast.f()); | ||
case "Refinement": | ||
return getPropertySignatures(ast.from); | ||
case "Transform": | ||
return getPropertySignatures(ast.to); | ||
default: | ||
return []; | ||
} | ||
}; | ||
/** | ||
@@ -669,3 +551,3 @@ * Equivalent at runtime to the built-in TypeScript utility type `Partial`. | ||
*/ | ||
exports.getPropertySignatures = getPropertySignatures; | ||
exports.omit = omit; | ||
const partial = ast => { | ||
@@ -699,3 +581,160 @@ switch (ast._tag) { | ||
}; | ||
// ------------------------------------------------------------------------------------- | ||
// internal | ||
// ------------------------------------------------------------------------------------- | ||
/** @internal */ | ||
exports.getCompiler = getCompiler; | ||
const _getCardinality = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return _getCardinality(ast.type); | ||
case "NeverKeyword": | ||
return 0; | ||
case "Literal": | ||
case "UndefinedKeyword": | ||
case "VoidKeyword": | ||
case "UniqueSymbol": | ||
return 1; | ||
case "BooleanKeyword": | ||
return 2; | ||
case "StringKeyword": | ||
case "NumberKeyword": | ||
case "BigIntKeyword": | ||
case "SymbolKeyword": | ||
return 3; | ||
case "ObjectKeyword": | ||
return 4; | ||
case "UnknownKeyword": | ||
case "AnyKeyword": | ||
return 6; | ||
case "Refinement": | ||
return _getCardinality(ast.from); | ||
case "Transform": | ||
return _getCardinality(ast.to); | ||
default: | ||
return 5; | ||
} | ||
}; | ||
exports._getCardinality = _getCardinality; | ||
const sortByCardinalityAsc = /*#__PURE__*/RA.sort( /*#__PURE__*/(0, _Function.pipe)(Number.Order, /*#__PURE__*/Order.contramap(({ | ||
type | ||
}) => _getCardinality(type)))); | ||
/** @internal */ | ||
const _getWeight = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return _getWeight(ast.type); | ||
case "Tuple": | ||
return ast.elements.length + (O.isSome(ast.rest) ? ast.rest.value.length : 0); | ||
case "TypeLiteral": | ||
return ast.propertySignatures.length + ast.indexSignatures.length; | ||
case "Union": | ||
return ast.types.reduce((n, member) => n + _getWeight(member), 0); | ||
case "Lazy": | ||
return 10; | ||
case "Refinement": | ||
return _getWeight(ast.from); | ||
case "Transform": | ||
return _getWeight(ast.to); | ||
default: | ||
return 0; | ||
} | ||
}; | ||
exports._getWeight = _getWeight; | ||
const sortByWeightDesc = /*#__PURE__*/RA.sort( /*#__PURE__*/Order.reverse( /*#__PURE__*/(0, _Function.pipe)(Number.Order, /*#__PURE__*/Order.contramap(_getWeight)))); | ||
const unify = candidates => { | ||
let out = (0, _Function.pipe)(candidates, RA.flatMap(ast => { | ||
switch (ast._tag) { | ||
case "NeverKeyword": | ||
return []; | ||
case "Union": | ||
return ast.types; | ||
default: | ||
return [ast]; | ||
} | ||
})); | ||
if (out.some(isAnyKeyword)) { | ||
return [anyKeyword]; | ||
} | ||
if (out.some(isUnknownKeyword)) { | ||
return [unknownKeyword]; | ||
} | ||
if (out.some(isStringKeyword)) { | ||
out = out.filter(m => !(isLiteral(m) && typeof m.literal === "string")); | ||
} | ||
if (out.some(isNumberKeyword)) { | ||
out = out.filter(m => !(isLiteral(m) && typeof m.literal === "number")); | ||
} | ||
if (out.some(isBooleanKeyword)) { | ||
out = out.filter(m => !(isLiteral(m) && typeof m.literal === "boolean")); | ||
} | ||
if (out.some(isBigIntKeyword)) { | ||
out = out.filter(m => !(isLiteral(m) && typeof m.literal === "bigint")); | ||
} | ||
if (out.some(isSymbolKeyword)) { | ||
out = out.filter(m => !isUniqueSymbol(m)); | ||
} | ||
return out; | ||
}; | ||
/** @internal */ | ||
const _getParameter = x => isRefinement(x) ? _getParameter(x.from) : x; | ||
exports._getParameter = _getParameter; | ||
const _keyof = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return _keyof(ast.type); | ||
case "NeverKeyword": | ||
case "AnyKeyword": | ||
return [stringKeyword, numberKeyword, symbolKeyword]; | ||
case "StringKeyword": | ||
return [createLiteral("length")]; | ||
case "TypeLiteral": | ||
return ast.propertySignatures.map(p => typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)).concat(ast.indexSignatures.map(is => _getParameter(is.parameter))); | ||
case "Union": | ||
{ | ||
return _getPropertySignatures(ast).map(p => typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)); | ||
} | ||
case "Lazy": | ||
return _keyof(ast.f()); | ||
case "Refinement": | ||
return _keyof(ast.from); | ||
case "Transform": | ||
return _keyof(ast.to); | ||
default: | ||
return []; | ||
} | ||
}; | ||
/** @internal */ | ||
const _getPropertySignatures = ast => { | ||
switch (ast._tag) { | ||
case "TypeAlias": | ||
return _getPropertySignatures(ast.type); | ||
case "Tuple": | ||
return ast.elements.map((element, i) => createPropertySignature(i, element.type, element.isOptional, ast.isReadonly)); | ||
case "TypeLiteral": | ||
return ast.propertySignatures; | ||
case "Union": | ||
{ | ||
const propertySignatures = ast.types.map(_getPropertySignatures); | ||
return (0, _Function.pipe)(propertySignatures[0], RA.filterMap(({ | ||
name | ||
}) => { | ||
if (propertySignatures.every(ps => ps.some(p => p.name === name))) { | ||
const members = (0, _Function.pipe)(propertySignatures, RA.flatMap(ps => ps.filter(p => p.name === name))); | ||
return O.some(createPropertySignature(name, createUnion(members.map(p => p.type)), members.some(p => p.isOptional), members.some(p => p.isReadonly))); | ||
} | ||
return O.none(); | ||
})); | ||
} | ||
case "Lazy": | ||
return _getPropertySignatures(ast.f()); | ||
case "Refinement": | ||
return _getPropertySignatures(ast.from); | ||
case "Transform": | ||
return _getPropertySignatures(ast.to); | ||
default: | ||
return []; | ||
} | ||
}; | ||
exports._getPropertySignatures = _getPropertySignatures; | ||
//# sourceMappingURL=AST.js.map |
@@ -19,3 +19,3 @@ "use strict"; | ||
const greaterThan = (min, annotationOptions) => self => (0, _Function.pipe)(self, I.filter(a => a > min, { | ||
description: `a bigint greater than ${min}`, | ||
description: `a bigint greater than ${min}n`, | ||
jsonSchema: { | ||
@@ -31,3 +31,3 @@ exclusiveMinimum: min | ||
const greaterThanOrEqualTo = (min, annotationOptions) => self => (0, _Function.pipe)(self, I.filter(a => a >= min, { | ||
description: `a bigint greater than or equal to ${min}`, | ||
description: `a bigint greater than or equal to ${min}n`, | ||
jsonSchema: { | ||
@@ -43,3 +43,3 @@ minimum: min | ||
const lessThan = (max, annotationOptions) => self => (0, _Function.pipe)(self, I.filter(a => a < max, { | ||
description: `a bigint less than ${max}`, | ||
description: `a bigint less than ${max}n`, | ||
jsonSchema: { | ||
@@ -55,3 +55,3 @@ exclusiveMaximum: max | ||
const lessThanOrEqualTo = (max, annotationOptions) => self => (0, _Function.pipe)(self, I.filter(a => a <= max, { | ||
description: `a bigint less than or equal to ${max}`, | ||
description: `a bigint less than or equal to ${max}n`, | ||
jsonSchema: { | ||
@@ -67,3 +67,3 @@ maximum: max | ||
const between = (min, max, annotationOptions) => self => (0, _Function.pipe)(self, I.filter(a => a >= min && a <= max, { | ||
description: `a bigint between ${min} and ${max}`, | ||
description: `a bigint between ${min}n and ${max}n`, | ||
jsonSchema: { | ||
@@ -70,0 +70,0 @@ maximum: max, |
@@ -7,2 +7,3 @@ "use strict"; | ||
exports.date = void 0; | ||
var _Predicate = /*#__PURE__*/require("@fp-ts/core/Predicate"); | ||
var _AST = /*#__PURE__*/require("@fp-ts/schema/annotation/AST"); | ||
@@ -18,4 +19,3 @@ var H = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/schema/annotation/Hook")); | ||
const isDate = u => typeof u === "object" && typeof u !== null && u instanceof Date; | ||
const parser = () => I.makeParser(date, u => !isDate(u) ? PR.failure(PR.type(date.ast, u)) : PR.success(u)); | ||
const parser = () => I.makeParser(date, u => !(0, _Predicate.isDate)(u) ? PR.failure(PR.type(date.ast, u)) : PR.success(u)); | ||
const arbitrary = () => I.makeArbitrary(date, fc => fc.date()); | ||
@@ -22,0 +22,0 @@ const pretty = () => I.makePretty(date, date => `new Date(${JSON.stringify(date)})`); |
@@ -55,3 +55,3 @@ "use strict"; | ||
jsonSchema: { | ||
multipleOf: divisor < 0 ? -divisor : divisor | ||
multipleOf: Math.abs(divisor) | ||
}, | ||
@@ -58,0 +58,0 @@ ...annotationOptions |
@@ -19,3 +19,3 @@ "use strict"; | ||
const isMap = u => typeof u === "object" && typeof u !== null && u instanceof Map; | ||
const isMap = u => u instanceof Map; | ||
const parser = (key, value) => { | ||
@@ -22,0 +22,0 @@ const items = P.decode(I.array(I.tuple(key, value))); |
@@ -19,3 +19,3 @@ "use strict"; | ||
const isSet = u => typeof u === "object" && typeof u !== null && u instanceof Set; | ||
const isSet = u => u instanceof Set; | ||
const parser = item => { | ||
@@ -22,0 +22,0 @@ const items = P.decode(I.array(item)); |
@@ -50,2 +50,5 @@ "use strict"; | ||
} | ||
if (typeof actual === "bigint") { | ||
return String(actual) + "n"; | ||
} | ||
if (typeof actual === "symbol") { | ||
@@ -52,0 +55,0 @@ return String(actual); |
@@ -6,5 +6,5 @@ "use strict"; | ||
}); | ||
exports.boolean = exports.bigint = exports.array = exports.any = exports.annotations = exports._void = exports._undefined = exports._null = void 0; | ||
exports.brand = exports.boolean = exports.bigint = exports.array = exports.any = exports.annotations = exports._void = exports._undefined = exports._null = void 0; | ||
exports.filter = filter; | ||
exports.unknown = exports.uniqueSymbol = exports.union = exports.typeAlias = exports.tuple = exports.transformOrFail = exports.transform = exports.symbol = exports.struct = exports.string = exports.record = exports.ownKeys = exports.optional = exports.object = exports.number = exports.nullable = exports.never = exports.mutableAppend = exports.memoize = exports.map = exports.makeSchema = exports.makePretty = exports.makeParser = exports.makeArbitrary = exports.literal = exports.lazy = exports.isUnknownObject = exports.isUndefined = exports.isSymbol = exports.isObject = exports.isNotNull = exports.isNonEmpty = exports.isNever = exports.isJson = exports.isBigInt = exports.getTemplateLiteralRegex = exports.getKeysForIndexSignature = exports.fromRefinement = exports.flatMap = void 0; | ||
exports.unknown = exports.uniqueSymbol = exports.union = exports.typeAlias = exports.tuple = exports.transformOrFail = exports.transform = exports.symbol = exports.struct = exports.string = exports.record = exports.ownKeys = exports.optional = exports.object = exports.number = exports.nullable = exports.never = exports.mutableAppend = exports.memoize = exports.map = exports.makeSchema = exports.makePretty = exports.makeParser = exports.makeArbitrary = exports.literal = exports.lazy = exports.isNonEmpty = exports.getTemplateLiteralRegex = exports.getKeysForIndexSignature = exports.fromRefinement = exports.flatMap = void 0; | ||
var E = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/core/Either")); | ||
@@ -38,17 +38,6 @@ var _Function = /*#__PURE__*/require("@fp-ts/core/Function"); | ||
// --------------------------------------------- | ||
// Refinements | ||
// artifacts constructors | ||
// --------------------------------------------- | ||
/** @internal */ | ||
exports.isNonEmpty = isNonEmpty; | ||
const isUnknownObject = u => typeof u === "object" && u != null && !Array.isArray(u); | ||
exports.isUnknownObject = isUnknownObject; | ||
const isJsonArray = u => Array.isArray(u) && u.every(isJson); | ||
const isJsonObject = u => isUnknownObject(u) && Object.keys(u).every(key => isJson(u[key])); | ||
/** @internal */ | ||
const isJson = u => u === null || typeof u === "string" || typeof u === "number" && !isNaN(u) && isFinite(u) || typeof u === "boolean" || isJsonArray(u) || isJsonObject(u); | ||
// --------------------------------------------- | ||
// artifacts constructors | ||
// --------------------------------------------- | ||
/** @internal */ | ||
exports.isJson = isJson; | ||
const makeArbitrary = (schema, arbitrary) => ({ | ||
@@ -88,3 +77,3 @@ ast: schema.ast, | ||
exports.annotations = annotations; | ||
function filter(predicate, options) { | ||
const toAnnotations = options => { | ||
const annotations = {}; | ||
@@ -115,5 +104,17 @@ if (options?.message !== undefined) { | ||
} | ||
return from => makeSchema(AST.createRefinement(from.ast, predicate, annotations)); | ||
return annotations; | ||
}; | ||
function filter(predicate, options) { | ||
return from => makeSchema(AST.createRefinement(from.ast, predicate, toAnnotations(options))); | ||
} | ||
const getBrands = ast => ast.annotations[A.BrandId] || []; | ||
/** @internal */ | ||
const brand = (brand, options) => self => { | ||
const annotations = toAnnotations(options); | ||
annotations[A.BrandId] = [...getBrands(self.ast), brand]; | ||
const ast = AST.mergeAnnotations(self.ast, annotations); | ||
return makeSchema(ast); | ||
}; | ||
/** @internal */ | ||
exports.brand = brand; | ||
const transformOrFail = (to, decode, encode) => self => makeSchema(AST.createTransform(self.ast, to.ast, decode, encode)); | ||
@@ -141,5 +142,2 @@ /** @internal */ | ||
exports.any = any; | ||
const isUndefined = u => u === undefined; | ||
/** @internal */ | ||
exports.isUndefined = isUndefined; | ||
const _undefined = /*#__PURE__*/makeSchema(AST.undefinedKeyword); | ||
@@ -163,14 +161,5 @@ /** @internal */ | ||
exports.boolean = boolean; | ||
const isNever = u => false; | ||
/** @internal */ | ||
exports.isNever = isNever; | ||
const isBigInt = u => typeof u === "bigint"; | ||
/** @internal */ | ||
exports.isBigInt = isBigInt; | ||
const bigint = /*#__PURE__*/makeSchema(AST.bigIntKeyword); | ||
/** @internal */ | ||
exports.bigint = bigint; | ||
const isSymbol = u => typeof u === "symbol"; | ||
/** @internal */ | ||
exports.isSymbol = isSymbol; | ||
const symbol = /*#__PURE__*/makeSchema(AST.symbolKeyword); | ||
@@ -182,8 +171,2 @@ /** @internal */ | ||
exports.object = object; | ||
const isObject = u => typeof u === "object" && u !== null; | ||
/** @internal */ | ||
exports.isObject = isObject; | ||
const isNotNull = u => u !== null; | ||
/** @internal */ | ||
exports.isNotNull = isNotNull; | ||
const union = (...members) => makeSchema(AST.createUnion(members.map(m => m.ast))); | ||
@@ -190,0 +173,0 @@ /** @internal */ |
{ | ||
"name": "@fp-ts/schema", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"license": "MIT", | ||
@@ -10,3 +10,3 @@ "repository": { | ||
"dependencies": { | ||
"@effect/data": "~0.1.0", | ||
"@effect/data": "~0.1.2", | ||
"@fp-ts/core": "~0.2.1", | ||
@@ -13,0 +13,0 @@ "fast-check": "^3.6.3" |
@@ -11,4 +11,4 @@ "use strict"; | ||
var O = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/core/Option")); | ||
var _Predicate = /*#__PURE__*/require("@fp-ts/core/Predicate"); | ||
var RA = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/core/ReadonlyArray")); | ||
var _String = /*#__PURE__*/require("@fp-ts/core/String"); | ||
var H = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/schema/annotation/Hook")); | ||
@@ -97,7 +97,7 @@ var AST = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/schema/AST")); | ||
case "UndefinedKeyword": | ||
return I.fromRefinement(I.makeSchema(ast), I.isUndefined); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isUndefined); | ||
case "VoidKeyword": | ||
return I.fromRefinement(I.makeSchema(ast), I.isUndefined); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isUndefined); | ||
case "NeverKeyword": | ||
return I.fromRefinement(I.makeSchema(ast), I.isNever); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isNever); | ||
case "UnknownKeyword": | ||
@@ -107,3 +107,3 @@ case "AnyKeyword": | ||
case "StringKeyword": | ||
return I.fromRefinement(I.makeSchema(ast), _String.isString); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isString); | ||
case "NumberKeyword": | ||
@@ -114,7 +114,7 @@ return I.fromRefinement(I.makeSchema(ast), _Number.isNumber); | ||
case "BigIntKeyword": | ||
return I.fromRefinement(I.makeSchema(ast), I.isBigInt); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isBigint); | ||
case "SymbolKeyword": | ||
return I.fromRefinement(I.makeSchema(ast), I.isSymbol); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isSymbol); | ||
case "ObjectKeyword": | ||
return I.fromRefinement(I.makeSchema(ast), I.isObject); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isObject); | ||
case "Enums": | ||
@@ -125,3 +125,3 @@ return I.fromRefinement(I.makeSchema(ast), u => ast.enums.some(([_, value]) => value === u)); | ||
const regex = I.getTemplateLiteralRegex(ast); | ||
return I.fromRefinement(I.makeSchema(ast), u => (0, _String.isString)(u) && regex.test(u)); | ||
return I.fromRefinement(I.makeSchema(ast), u => (0, _Predicate.isString)(u) && regex.test(u)); | ||
} | ||
@@ -241,3 +241,3 @@ case "Tuple": | ||
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) { | ||
return I.fromRefinement(I.makeSchema(ast), I.isNotNull); | ||
return I.fromRefinement(I.makeSchema(ast), _Predicate.isNotNullable); | ||
} | ||
@@ -247,3 +247,3 @@ const propertySignaturesTypes = ast.propertySignatures.map(f => go(f.type)); | ||
return make(I.makeSchema(ast), (input, options) => { | ||
if (!I.isUnknownObject(input)) { | ||
if (!(0, _Predicate.isRecord)(input)) { | ||
return PR.failure(PR.type(unknownRecord, input)); | ||
@@ -250,0 +250,0 @@ } |
@@ -611,2 +611,21 @@ <h3 align="center"> | ||
### Access the schema for a particular key | ||
The `getPropertySignatures` function takes a `Schema<A>` and returns a new object of type `{ [K in keyof A]: Schema<A[K]> }`. The new object has properties that are the same keys as those in the original object, and each of these properties is a schema for the corresponding property in the original object. | ||
```ts | ||
import * as S from "@fp-ts/schema"; | ||
const Person = S.struct({ | ||
name: S.string, | ||
age: S.number, | ||
}); | ||
// get the schema for each property of `Person` | ||
const shape = S.getPropertySignatures(Person); | ||
shape.name; // S.string | ||
shape.age; // S.number | ||
``` | ||
## Pick | ||
@@ -613,0 +632,0 @@ |
/** | ||
* @since 1.0.0 | ||
*/ | ||
import type { Brand } from "@effect/data/Brand"; | ||
import type { Option } from "@fp-ts/core/Option"; | ||
@@ -289,5 +290,51 @@ import type { Predicate, Refinement } from "@fp-ts/core/Predicate"; | ||
/** | ||
* Returns an object containing all property signatures of a given schema. | ||
* | ||
* ``` | ||
* Schema<A> -> { [K in keyof A]: Schema<A[K]> } | ||
* ``` | ||
* | ||
* @param schema - The schema to extract property signatures from. | ||
* | ||
* @example | ||
* import * as S from "@fp-ts/schema" | ||
* | ||
* const Person = S.struct({ | ||
* name: S.string, | ||
* age: S.number | ||
* }) | ||
* | ||
* const shape = S.getPropertySignatures(Person) | ||
* | ||
* assert.deepStrictEqual(shape.name, S.string) | ||
* assert.deepStrictEqual(shape.age, S.number) | ||
* | ||
* @since 1.0.0 | ||
*/ | ||
export declare const getPropertySignatures: <A>(schema: Schema<A>) => { [K in keyof A]: Schema<A[K]>; }; | ||
/** | ||
* Returns a nominal branded schema by applying a brand to a given schema. | ||
* | ||
* ``` | ||
* Schema<A> + B -> Schema<A & Brand<B>> | ||
* ``` | ||
* | ||
* @param self - The input schema to be combined with the brand. | ||
* @param brand - The brand to apply. | ||
* | ||
* @example | ||
* import * as S from "@fp-ts/schema" | ||
* import { pipe } from "@fp-ts/core/Function" | ||
* | ||
* const Int = pipe(S.number, S.int(), S.brand("Int")) | ||
* type Int = S.Infer<typeof Int> // number & Brand<"Int"> | ||
* | ||
* @category combinators | ||
* @since 1.0.0 | ||
*/ | ||
export declare const brand: <B extends string, A>(brand: B, options?: AnnotationOptions<A>) => (self: Schema<A>) => Schema<A & Brand<B>>; | ||
/** | ||
* @category combinators | ||
* @since 1.0.0 | ||
*/ | ||
export declare const partial: <A>(self: Schema<A>) => Schema<Partial<A>>; | ||
@@ -294,0 +341,0 @@ /** |
@@ -6,5 +6,5 @@ "use strict"; | ||
}); | ||
exports.extend = exports.examples = exports.enums = exports.endsWith = exports.element = exports.documentation = exports.description = exports.date = exports.boolean = exports.bigint = exports.between = exports.array = exports.any = exports.annotations = exports.OptionalSchemaId = void 0; | ||
exports.extend = exports.examples = exports.enums = exports.endsWith = exports.element = exports.documentation = exports.description = exports.date = exports.brand = exports.boolean = exports.bigint = exports.between = exports.array = exports.any = exports.annotations = exports.OptionalSchemaId = void 0; | ||
exports.filter = filter; | ||
exports.void = exports.unknown = exports.uniqueSymbol = exports.union = exports.undefined = exports.typeAlias = exports.tuple = exports.trimmed = exports.trim = exports.transformOrFail = exports.transform = exports.title = exports.templateLiteral = exports.symbol = exports.struct = exports.string = exports.startsWith = exports.rest = exports.record = exports.positive = exports.pick = exports.pattern = exports.partial = exports.optionalElement = exports.optional = exports.option = exports.omit = exports.object = exports.number = exports.nullable = exports.null = exports.nonPositive = exports.nonNegative = exports.nonNaN = exports.nonEmptyArray = exports.nonEmpty = exports.never = exports.negative = exports.minLength = exports.minItems = exports.message = exports.maxLength = exports.maxItems = exports.make = exports.literal = exports.lessThanOrEqualTo = exports.lessThan = exports.length = exports.lazy = exports.keyof = exports.itemsCount = exports.int = exports.instanceOf = exports.includes = exports.identifier = exports.greaterThanOrEqualTo = exports.greaterThan = exports.finite = void 0; | ||
exports.void = exports.unknown = exports.uniqueSymbol = exports.union = exports.undefined = exports.typeAlias = exports.tuple = exports.trimmed = exports.trim = exports.transformOrFail = exports.transform = exports.title = exports.templateLiteral = exports.symbol = exports.struct = exports.string = exports.startsWith = exports.rest = exports.record = exports.positive = exports.pick = exports.pattern = exports.partial = exports.optionalElement = exports.optional = exports.option = exports.omit = exports.object = exports.number = exports.nullable = exports.null = exports.nonPositive = exports.nonNegative = exports.nonNaN = exports.nonEmptyArray = exports.nonEmpty = exports.never = exports.negative = exports.minLength = exports.minItems = exports.message = exports.maxLength = exports.maxItems = exports.make = exports.literal = exports.lessThanOrEqualTo = exports.lessThan = exports.length = exports.lazy = exports.keyof = exports.itemsCount = exports.int = exports.instanceOf = exports.includes = exports.identifier = exports.greaterThanOrEqualTo = exports.greaterThan = exports.getPropertySignatures = exports.finite = void 0; | ||
var _Function = /*#__PURE__*/require("@fp-ts/core/Function"); | ||
@@ -361,6 +361,61 @@ var RA = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@fp-ts/core/ReadonlyArray")); | ||
/** | ||
* Returns an object containing all property signatures of a given schema. | ||
* | ||
* ``` | ||
* Schema<A> -> { [K in keyof A]: Schema<A[K]> } | ||
* ``` | ||
* | ||
* @param schema - The schema to extract property signatures from. | ||
* | ||
* @example | ||
* import * as S from "@fp-ts/schema" | ||
* | ||
* const Person = S.struct({ | ||
* name: S.string, | ||
* age: S.number | ||
* }) | ||
* | ||
* const shape = S.getPropertySignatures(Person) | ||
* | ||
* assert.deepStrictEqual(shape.name, S.string) | ||
* assert.deepStrictEqual(shape.age, S.number) | ||
* | ||
* @since 1.0.0 | ||
*/ | ||
exports.omit = omit; | ||
const getPropertySignatures = schema => { | ||
const out = {}; | ||
const propertySignatures = AST._getPropertySignatures(schema.ast); | ||
for (const propertySignature of propertySignatures) { | ||
out[propertySignature.name] = make(propertySignature.type); | ||
} | ||
return out; | ||
}; | ||
/** | ||
* Returns a nominal branded schema by applying a brand to a given schema. | ||
* | ||
* ``` | ||
* Schema<A> + B -> Schema<A & Brand<B>> | ||
* ``` | ||
* | ||
* @param self - The input schema to be combined with the brand. | ||
* @param brand - The brand to apply. | ||
* | ||
* @example | ||
* import * as S from "@fp-ts/schema" | ||
* import { pipe } from "@fp-ts/core/Function" | ||
* | ||
* const Int = pipe(S.number, S.int(), S.brand("Int")) | ||
* type Int = S.Infer<typeof Int> // number & Brand<"Int"> | ||
* | ||
* @category combinators | ||
* @since 1.0.0 | ||
*/ | ||
exports.omit = omit; | ||
exports.getPropertySignatures = getPropertySignatures; | ||
const brand = I.brand; | ||
/** | ||
* @category combinators | ||
* @since 1.0.0 | ||
*/ | ||
exports.brand = brand; | ||
const partial = self => make(AST.partial(self.ast)); | ||
@@ -376,4 +431,4 @@ /** | ||
const isOverlappingIndexSignatures = (x, y) => x.indexSignatures.some(ix => y.indexSignatures.some(iy => { | ||
const bx = AST.getParameter(ix.parameter); | ||
const by = AST.getParameter(iy.parameter); | ||
const bx = AST._getParameter(ix.parameter); | ||
const by = AST._getParameter(iy.parameter); | ||
// there cannot be two string index signatures or two symbol index signatures at the same time | ||
@@ -380,0 +435,0 @@ return AST.isStringKeyword(bx) && AST.isStringKeyword(by) || AST.isSymbolKeyword(bx) && AST.isSymbolKeyword(by); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
588039
8843
1143
Updated@effect/data@~0.1.2