@atproto/lexicon
Advanced tools
Comparing version 0.4.2 to 0.4.3
# @atproto/lexicon | ||
## 0.4.3 | ||
### Patch Changes | ||
- [#2911](https://github.com/bluesky-social/atproto/pull/2911) [`bac9be2d3`](https://github.com/bluesky-social/atproto/commit/bac9be2d3ec904d1f984a871f43cf89aca17289d) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Improve validation performances by using discriminated unions where possible | ||
- Updated dependencies [[`bac9be2d3`](https://github.com/bluesky-social/atproto/commit/bac9be2d3ec904d1f984a871f43cf89aca17289d)]: | ||
- @atproto/syntax@0.3.1 | ||
## 0.4.2 | ||
@@ -4,0 +13,0 @@ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LexiconDefNotFoundError = exports.InvalidLexiconError = exports.ValidationError = exports.parseLexiconDoc = exports.isDiscriminatedObject = exports.discriminatedObject = exports.hasProp = exports.isObj = exports.isValidLexiconDoc = exports.lexiconDoc = exports.lexUserType = exports.lexRecord = exports.lexXrpcSubscription = exports.lexXrpcProcedure = exports.lexXrpcQuery = exports.lexXrpcError = exports.lexXrpcSubscriptionMessage = exports.lexXrpcBody = exports.lexXrpcParameters = exports.lexObject = exports.lexToken = exports.lexPrimitiveArray = exports.lexArray = exports.lexBlob = exports.lexRefVariant = exports.lexRefUnion = exports.lexRef = exports.lexIpldType = exports.lexCidLink = exports.lexBytes = exports.lexPrimitive = exports.lexUnknown = exports.lexString = exports.lexStringFormat = exports.lexInteger = exports.lexBoolean = void 0; | ||
exports.LexiconDefNotFoundError = exports.InvalidLexiconError = exports.ValidationError = exports.discriminatedObject = exports.lexiconDoc = exports.lexUserType = exports.lexRecord = exports.lexXrpcSubscription = exports.lexXrpcProcedure = exports.lexXrpcQuery = exports.lexXrpcError = exports.lexXrpcSubscriptionMessage = exports.lexXrpcBody = exports.lexXrpcParameters = exports.lexObject = exports.lexToken = exports.lexPrimitiveArray = exports.lexArray = exports.lexBlob = exports.lexRefVariant = exports.lexRefUnion = exports.lexRef = exports.lexIpldType = exports.lexCidLink = exports.lexBytes = exports.lexPrimitive = exports.lexUnknown = exports.lexString = exports.lexStringFormat = exports.lexInteger = exports.lexBoolean = void 0; | ||
exports.isValidLexiconDoc = isValidLexiconDoc; | ||
exports.isObj = isObj; | ||
exports.hasProp = hasProp; | ||
exports.isDiscriminatedObject = isDiscriminatedObject; | ||
exports.parseLexiconDoc = parseLexiconDoc; | ||
const zod_1 = require("zod"); | ||
@@ -119,3 +124,17 @@ const syntax_1 = require("@atproto/syntax"); | ||
description: zod_1.z.string().optional(), | ||
items: zod_1.z.union([exports.lexPrimitive, exports.lexIpldType, exports.lexBlob, exports.lexRefVariant]), | ||
items: zod_1.z.discriminatedUnion('type', [ | ||
// lexPrimitive | ||
exports.lexBoolean, | ||
exports.lexInteger, | ||
exports.lexString, | ||
exports.lexUnknown, | ||
// lexIpldType | ||
exports.lexBytes, | ||
exports.lexCidLink, | ||
// lexRefVariant | ||
exports.lexRef, | ||
exports.lexRefUnion, | ||
// other | ||
exports.lexBlob, | ||
]), | ||
minLength: zod_1.z.number().int().optional(), | ||
@@ -142,3 +161,18 @@ maxLength: zod_1.z.number().int().optional(), | ||
nullable: zod_1.z.string().array().optional(), | ||
properties: zod_1.z.record(zod_1.z.union([exports.lexRefVariant, exports.lexIpldType, exports.lexArray, exports.lexBlob, exports.lexPrimitive])), | ||
properties: zod_1.z.record(zod_1.z.discriminatedUnion('type', [ | ||
exports.lexArray, | ||
// lexPrimitive | ||
exports.lexBoolean, | ||
exports.lexInteger, | ||
exports.lexString, | ||
exports.lexUnknown, | ||
// lexIpldType | ||
exports.lexBytes, | ||
exports.lexCidLink, | ||
// lexRefVariant | ||
exports.lexRef, | ||
exports.lexRefUnion, | ||
// other | ||
exports.lexBlob, | ||
])), | ||
}) | ||
@@ -154,3 +188,10 @@ .strict() | ||
required: zod_1.z.string().array().optional(), | ||
properties: zod_1.z.record(zod_1.z.union([exports.lexPrimitive, exports.lexPrimitiveArray])), | ||
properties: zod_1.z.record(zod_1.z.discriminatedUnion('type', [ | ||
exports.lexPrimitiveArray, | ||
// lexPrimitive | ||
exports.lexBoolean, | ||
exports.lexInteger, | ||
exports.lexString, | ||
exports.lexUnknown, | ||
])), | ||
}) | ||
@@ -163,2 +204,3 @@ .strict() | ||
encoding: zod_1.z.string(), | ||
// @NOTE using discriminatedUnion with a refined schema requires zod >= 4 | ||
schema: zod_1.z.union([exports.lexRefVariant, exports.lexObject]).optional(), | ||
@@ -170,2 +212,3 @@ }) | ||
description: zod_1.z.string().optional(), | ||
// @NOTE using discriminatedUnion with a refined schema requires zod >= 4 | ||
schema: zod_1.z.union([exports.lexRefVariant, exports.lexObject]).optional(), | ||
@@ -274,2 +317,8 @@ }) | ||
} | ||
if (typeof val['type'] !== 'string') { | ||
return { | ||
message: 'Type property must be a string', | ||
fatal: true, | ||
}; | ||
} | ||
return { | ||
@@ -311,11 +360,8 @@ message: `Invalid type: ${val['type']} must be one of: record, query, procedure, subscription, blob, array, token, object, boolean, integer, string, bytes, cid-link, unknown`, | ||
} | ||
exports.isValidLexiconDoc = isValidLexiconDoc; | ||
function isObj(obj) { | ||
return obj !== null && typeof obj === 'object'; | ||
} | ||
exports.isObj = isObj; | ||
function hasProp(data, prop) { | ||
return prop in data; | ||
} | ||
exports.hasProp = hasProp; | ||
exports.discriminatedObject = zod_1.z.object({ $type: zod_1.z.string() }); | ||
@@ -325,3 +371,2 @@ function isDiscriminatedObject(value) { | ||
} | ||
exports.isDiscriminatedObject = isDiscriminatedObject; | ||
function parseLexiconDoc(v) { | ||
@@ -331,3 +376,2 @@ exports.lexiconDoc.parse(v); | ||
} | ||
exports.parseLexiconDoc = parseLexiconDoc; | ||
class ValidationError extends Error { | ||
@@ -334,0 +378,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.requiredPropertiesRefinement = exports.toConcreteTypes = exports.toLexUri = void 0; | ||
exports.toLexUri = toLexUri; | ||
exports.toConcreteTypes = toConcreteTypes; | ||
exports.requiredPropertiesRefinement = requiredPropertiesRefinement; | ||
const zod_1 = require("zod"); | ||
@@ -20,3 +22,2 @@ function toLexUri(str, baseUri) { | ||
} | ||
exports.toLexUri = toLexUri; | ||
function toConcreteTypes(lexicons, def) { | ||
@@ -33,3 +34,2 @@ if (def.type === 'ref') { | ||
} | ||
exports.toConcreteTypes = toConcreteTypes; | ||
function requiredPropertiesRefinement(object, ctx) { | ||
@@ -66,3 +66,2 @@ // Required fields check | ||
} | ||
exports.requiredPropertiesRefinement = requiredPropertiesRefinement; | ||
//# sourceMappingURL=util.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.assertValidXrpcMessage = exports.assertValidXrpcOutput = exports.assertValidXrpcInput = exports.assertValidXrpcParams = exports.assertValidRecord = void 0; | ||
exports.assertValidRecord = assertValidRecord; | ||
exports.assertValidXrpcParams = assertValidXrpcParams; | ||
exports.assertValidXrpcInput = assertValidXrpcInput; | ||
exports.assertValidXrpcOutput = assertValidXrpcOutput; | ||
exports.assertValidXrpcMessage = assertValidXrpcMessage; | ||
const complex_1 = require("./validators/complex"); | ||
@@ -12,3 +16,2 @@ const xrpc_1 = require("./validators/xrpc"); | ||
} | ||
exports.assertValidRecord = assertValidRecord; | ||
function assertValidXrpcParams(lexicons, def, value) { | ||
@@ -22,3 +25,2 @@ if (def.parameters) { | ||
} | ||
exports.assertValidXrpcParams = assertValidXrpcParams; | ||
function assertValidXrpcInput(lexicons, def, value) { | ||
@@ -30,3 +32,2 @@ if (def.input?.schema) { | ||
} | ||
exports.assertValidXrpcInput = assertValidXrpcInput; | ||
function assertValidXrpcOutput(lexicons, def, value) { | ||
@@ -38,3 +39,2 @@ if (def.output?.schema) { | ||
} | ||
exports.assertValidXrpcOutput = assertValidXrpcOutput; | ||
function assertValidXrpcMessage(lexicons, def, value) { | ||
@@ -46,3 +46,2 @@ if (def.message?.schema) { | ||
} | ||
exports.assertValidXrpcMessage = assertValidXrpcMessage; | ||
function assertValidOneOf(lexicons, path, def, value, mustBeObj = false) { | ||
@@ -49,0 +48,0 @@ const res = (0, complex_1.validateOneOf)(lexicons, path, def, value, mustBeObj); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.blob = void 0; | ||
exports.blob = blob; | ||
const blob_refs_1 = require("../blob-refs"); | ||
@@ -16,3 +16,2 @@ const types_1 = require("../types"); | ||
} | ||
exports.blob = blob; | ||
//# sourceMappingURL=blob.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validateOneOf = exports.object = exports.array = exports.validate = void 0; | ||
exports.validate = validate; | ||
exports.array = array; | ||
exports.object = object; | ||
exports.validateOneOf = validateOneOf; | ||
const types_1 = require("../types"); | ||
@@ -35,3 +38,2 @@ const util_1 = require("../util"); | ||
} | ||
exports.validate = validate; | ||
function array(lexicons, path, def, value) { | ||
@@ -75,3 +77,2 @@ // type | ||
} | ||
exports.array = array; | ||
function object(lexicons, path, def, value) { | ||
@@ -136,3 +137,2 @@ def = def; | ||
} | ||
exports.object = object; | ||
function validateOneOf(lexicons, path, def, value, mustBeObj = false) { | ||
@@ -184,3 +184,2 @@ let error; | ||
} | ||
exports.validateOneOf = validateOneOf; | ||
// to avoid bugs like #0189 this needs to handle both | ||
@@ -187,0 +186,0 @@ // explicit and implicit #main |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.recordKey = exports.tid = exports.language = exports.cid = exports.nsid = exports.atIdentifier = exports.handle = exports.did = exports.atUri = exports.uri = exports.datetime = void 0; | ||
exports.datetime = datetime; | ||
exports.uri = uri; | ||
exports.atUri = atUri; | ||
exports.did = did; | ||
exports.handle = handle; | ||
exports.atIdentifier = atIdentifier; | ||
exports.nsid = nsid; | ||
exports.cid = cid; | ||
exports.language = language; | ||
exports.tid = tid; | ||
exports.recordKey = recordKey; | ||
const iso_datestring_validator_1 = require("iso-datestring-validator"); | ||
@@ -23,3 +33,2 @@ const cid_1 = require("multiformats/cid"); | ||
} | ||
exports.datetime = datetime; | ||
function uri(path, value) { | ||
@@ -35,3 +44,2 @@ const isUri = value.match(/^\w+:(?:\/\/)?[^\s/][^\s]*$/) !== null; | ||
} | ||
exports.uri = uri; | ||
function atUri(path, value) { | ||
@@ -49,3 +57,2 @@ try { | ||
} | ||
exports.atUri = atUri; | ||
function did(path, value) { | ||
@@ -63,3 +70,2 @@ try { | ||
} | ||
exports.did = did; | ||
function handle(path, value) { | ||
@@ -77,17 +83,19 @@ try { | ||
} | ||
exports.handle = handle; | ||
function atIdentifier(path, value) { | ||
const isDid = did(path, value); | ||
if (!isDid.success) { | ||
const isHandle = handle(path, value); | ||
if (!isHandle.success) { | ||
return { | ||
success: false, | ||
error: new types_1.ValidationError(`${path} must be a valid did or a handle`), | ||
}; | ||
} | ||
// We can discriminate based on the "did:" prefix | ||
if (value.startsWith('did:')) { | ||
const didResult = did(path, value); | ||
if (didResult.success) | ||
return didResult; | ||
} | ||
return { success: true, value }; | ||
else { | ||
const handleResult = handle(path, value); | ||
if (handleResult.success) | ||
return handleResult; | ||
} | ||
return { | ||
success: false, | ||
error: new types_1.ValidationError(`${path} must be a valid did or a handle`), | ||
}; | ||
} | ||
exports.atIdentifier = atIdentifier; | ||
function nsid(path, value) { | ||
@@ -105,3 +113,2 @@ try { | ||
} | ||
exports.nsid = nsid; | ||
function cid(path, value) { | ||
@@ -119,3 +126,2 @@ try { | ||
} | ||
exports.cid = cid; | ||
// The language format validates well-formed BCP 47 language tags: https://www.rfc-editor.org/info/bcp47 | ||
@@ -131,3 +137,2 @@ function language(path, value) { | ||
} | ||
exports.language = language; | ||
function tid(path, value) { | ||
@@ -145,3 +150,2 @@ try { | ||
} | ||
exports.tid = tid; | ||
function recordKey(path, value) { | ||
@@ -159,3 +163,2 @@ try { | ||
} | ||
exports.recordKey = recordKey; | ||
//# sourceMappingURL=formats.js.map |
@@ -26,3 +26,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.unknown = exports.cidLink = exports.bytes = exports.string = exports.integer = exports.boolean = exports.validate = void 0; | ||
exports.validate = validate; | ||
exports.boolean = boolean; | ||
exports.integer = integer; | ||
exports.string = string; | ||
exports.bytes = bytes; | ||
exports.cidLink = cidLink; | ||
exports.unknown = unknown; | ||
const common_web_1 = require("@atproto/common-web"); | ||
@@ -53,3 +59,2 @@ const cid_1 = require("multiformats/cid"); | ||
} | ||
exports.validate = validate; | ||
function boolean(lexicons, path, def, value) { | ||
@@ -85,3 +90,2 @@ def = def; | ||
} | ||
exports.boolean = boolean; | ||
function integer(lexicons, path, def, value) { | ||
@@ -144,3 +148,2 @@ def = def; | ||
} | ||
exports.integer = integer; | ||
function string(lexicons, path, def, value) { | ||
@@ -279,3 +282,2 @@ def = def; | ||
} | ||
exports.string = string; | ||
function bytes(lexicons, path, def, value) { | ||
@@ -309,3 +311,2 @@ def = def; | ||
} | ||
exports.bytes = bytes; | ||
function cidLink(lexicons, path, def, value) { | ||
@@ -320,3 +321,2 @@ if (cid_1.CID.asCID(value) === null) { | ||
} | ||
exports.cidLink = cidLink; | ||
function unknown(lexicons, path, def, value) { | ||
@@ -332,3 +332,2 @@ // type | ||
} | ||
exports.unknown = unknown; | ||
//# sourceMappingURL=primitives.js.map |
@@ -26,3 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.params = void 0; | ||
exports.params = params; | ||
const types_1 = require("../types"); | ||
@@ -67,3 +67,2 @@ const PrimitiveValidators = __importStar(require("./primitives")); | ||
} | ||
exports.params = params; | ||
//# sourceMappingURL=xrpc.js.map |
/** @type {import('jest').Config} */ | ||
module.exports = { | ||
displayName: 'Lexicon', | ||
transform: { '^.+\\.(t|j)s$': '@swc/jest' }, | ||
transformIgnorePatterns: [`<rootDir>/node_modules/(?!get-port)`], | ||
transform: { '^.+\\.ts$': '@swc/jest' }, | ||
setupFiles: ['<rootDir>/../../jest.setup.ts'], | ||
} |
{ | ||
"name": "@atproto/lexicon", | ||
"version": "0.4.2", | ||
"version": "0.4.3", | ||
"license": "MIT", | ||
@@ -23,6 +23,7 @@ "description": "atproto Lexicon schema language library", | ||
"@atproto/common-web": "^0.3.1", | ||
"@atproto/syntax": "^0.3.0" | ||
"@atproto/syntax": "^0.3.1" | ||
}, | ||
"devDependencies": { | ||
"jest": "^28.1.2" | ||
"jest": "^28.1.2", | ||
"typescript": "^5.6.3" | ||
}, | ||
@@ -29,0 +30,0 @@ "scripts": { |
@@ -148,3 +148,17 @@ import { z } from 'zod' | ||
description: z.string().optional(), | ||
items: z.union([lexPrimitive, lexIpldType, lexBlob, lexRefVariant]), | ||
items: z.discriminatedUnion('type', [ | ||
// lexPrimitive | ||
lexBoolean, | ||
lexInteger, | ||
lexString, | ||
lexUnknown, | ||
// lexIpldType | ||
lexBytes, | ||
lexCidLink, | ||
// lexRefVariant | ||
lexRef, | ||
lexRefUnion, | ||
// other | ||
lexBlob, | ||
]), | ||
minLength: z.number().int().optional(), | ||
@@ -180,3 +194,19 @@ maxLength: z.number().int().optional(), | ||
properties: z.record( | ||
z.union([lexRefVariant, lexIpldType, lexArray, lexBlob, lexPrimitive]), | ||
z.discriminatedUnion('type', [ | ||
lexArray, | ||
// lexPrimitive | ||
lexBoolean, | ||
lexInteger, | ||
lexString, | ||
lexUnknown, | ||
// lexIpldType | ||
lexBytes, | ||
lexCidLink, | ||
// lexRefVariant | ||
lexRef, | ||
lexRefUnion, | ||
// other | ||
lexBlob, | ||
]), | ||
), | ||
@@ -196,3 +226,13 @@ }) | ||
required: z.string().array().optional(), | ||
properties: z.record(z.union([lexPrimitive, lexPrimitiveArray])), | ||
properties: z.record( | ||
z.discriminatedUnion('type', [ | ||
lexPrimitiveArray, | ||
// lexPrimitive | ||
lexBoolean, | ||
lexInteger, | ||
lexString, | ||
lexUnknown, | ||
]), | ||
), | ||
}) | ||
@@ -207,2 +247,3 @@ .strict() | ||
encoding: z.string(), | ||
// @NOTE using discriminatedUnion with a refined schema requires zod >= 4 | ||
schema: z.union([lexRefVariant, lexObject]).optional(), | ||
@@ -216,2 +257,3 @@ }) | ||
description: z.string().optional(), | ||
// @NOTE using discriminatedUnion with a refined schema requires zod >= 4 | ||
schema: z.union([lexRefVariant, lexObject]).optional(), | ||
@@ -361,2 +403,9 @@ }) | ||
if (typeof val['type'] !== 'string') { | ||
return { | ||
message: 'Type property must be a string', | ||
fatal: true, | ||
} | ||
} | ||
return { | ||
@@ -363,0 +412,0 @@ message: `Invalid type: ${val['type']} must be one of: record, query, procedure, subscription, blob, array, token, object, boolean, integer, string, bytes, cid-link, unknown`, |
@@ -50,2 +50,3 @@ import { isValidISODateString } from 'iso-datestring-validator' | ||
} | ||
return { success: true, value } | ||
@@ -63,2 +64,3 @@ } | ||
} | ||
return { success: true, value } | ||
@@ -76,2 +78,3 @@ } | ||
} | ||
return { success: true, value } | ||
@@ -81,13 +84,15 @@ } | ||
export function atIdentifier(path: string, value: string): ValidationResult { | ||
const isDid = did(path, value) | ||
if (!isDid.success) { | ||
const isHandle = handle(path, value) | ||
if (!isHandle.success) { | ||
return { | ||
success: false, | ||
error: new ValidationError(`${path} must be a valid did or a handle`), | ||
} | ||
} | ||
// We can discriminate based on the "did:" prefix | ||
if (value.startsWith('did:')) { | ||
const didResult = did(path, value) | ||
if (didResult.success) return didResult | ||
} else { | ||
const handleResult = handle(path, value) | ||
if (handleResult.success) return handleResult | ||
} | ||
return { success: true, value } | ||
return { | ||
success: false, | ||
error: new ValidationError(`${path} must be a valid did or a handle`), | ||
} | ||
} | ||
@@ -94,0 +99,0 @@ |
Sorry, the diff of this file is too big to display
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
1175637
72
27669
2
Updated@atproto/syntax@^0.3.1