@jsonjoy.com/json-type
Version:
High-performance JSON Pointer implementation
243 lines (242 loc) • 9.26 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractType = void 0;
const json_random_1 = require("@jsonjoy.com/util/lib/json-random");
const ValidatorCodegenContext_1 = require("../../codegen/validator/ValidatorCodegenContext");
const JsonTextEncoderCodegenContext_1 = require("../../codegen/json/JsonTextEncoderCodegenContext");
const CborEncoderCodegenContext_1 = require("../../codegen/binary/CborEncoderCodegenContext");
const JsonEncoderCodegenContext_1 = require("../../codegen/binary/JsonEncoderCodegenContext");
const CborEncoder_1 = require("@jsonjoy.com/json-pack/lib/cbor/CborEncoder");
const JsExpression_1 = require("@jsonjoy.com/util/lib/codegen/util/JsExpression");
const MessagePackEncoderCodegenContext_1 = require("../../codegen/binary/MessagePackEncoderCodegenContext");
const msgpack_1 = require("@jsonjoy.com/json-pack/lib/msgpack");
const lazyFunction_1 = require("@jsonjoy.com/util/lib/lazyFunction");
const JsonEncoder_1 = require("@jsonjoy.com/json-pack/lib/json/JsonEncoder");
const Writer_1 = require("@jsonjoy.com/util/lib/buffers/Writer");
const CapacityEstimatorCodegenContext_1 = require("../../codegen/capacity/CapacityEstimatorCodegenContext");
class AbstractType {
constructor() {
this.validators = {};
this.encoders = new Map();
}
getSystem() {
const system = this.system;
if (!system)
throw new Error('NO_SYSTEM');
return system;
}
getTypeName() {
return this.schema.kind;
}
/**
* @todo Add ability to export the whole schema, including aliases.
*/
getSchema() {
return this.schema;
}
getValidatorNames() {
const { validator } = this.schema;
if (!validator)
return [];
return Array.isArray(validator) ? validator : [validator];
}
toJsonSchema(ctx) {
const schema = this.getSchema();
const jsonSchema = {};
if (schema.title)
jsonSchema.title = schema.title;
if (schema.description)
jsonSchema.description = schema.description;
if (schema.examples)
jsonSchema.examples = schema.examples.map((example) => example.value);
return jsonSchema;
}
options(options) {
Object.assign(this.schema, options);
return this;
}
getOptions() {
const { kind, ...options } = this.schema;
return options;
}
validate(value) {
const validator = this.validator('string');
const err = validator(value);
if (err)
throw new Error(JSON.parse(err)[0]);
}
compileValidator(options) {
const ctx = new ValidatorCodegenContext_1.ValidatorCodegenContext({
system: this.system,
errors: 'object',
...options,
type: this,
});
this.codegenValidator(ctx, [], ctx.codegen.options.args[0]);
return ctx.compile();
}
__compileValidator(kind) {
return (this.validators[kind] = this.compileValidator({
errors: kind,
system: this.system,
skipObjectExtraFieldsCheck: kind === 'boolean',
unsafeMode: kind === 'boolean',
}));
}
validator(kind) {
return this.validators[kind] || (0, lazyFunction_1.lazy)(() => this.__compileValidator(kind));
}
compileJsonTextEncoder(options) {
const ctx = new JsonTextEncoderCodegenContext_1.JsonTextEncoderCodegenContext({
...options,
system: this.system,
type: this,
});
const r = ctx.codegen.options.args[0];
const value = new JsExpression_1.JsExpression(() => r);
this.codegenJsonTextEncoder(ctx, value);
return ctx.compile();
}
codegenJsonTextEncoder(ctx, value) {
throw new Error(`${this.toStringName()}.codegenJsonTextEncoder() not implemented`);
}
jsonTextEncoder() {
return (this.__jsonEncoder || (this.__jsonEncoder = (0, lazyFunction_1.lazy)(() => (this.__jsonEncoder = this.compileJsonTextEncoder({})))));
}
compileEncoder(format, name) {
switch (format) {
case 0 /* EncodingFormat.Cbor */: {
const encoder = this.compileCborEncoder({ name });
this.encoders.set(0 /* EncodingFormat.Cbor */, encoder);
return encoder;
}
case 1 /* EncodingFormat.MsgPack */: {
const encoder = this.compileMessagePackEncoder({ name });
this.encoders.set(1 /* EncodingFormat.MsgPack */, encoder);
return encoder;
}
case 2 /* EncodingFormat.Json */: {
const encoder = this.compileJsonEncoder({ name });
this.encoders.set(2 /* EncodingFormat.Json */, encoder);
return encoder;
}
default:
throw new Error(`Unsupported encoding format: ${format}`);
}
}
encoder(kind) {
const encoders = this.encoders;
const cachedEncoder = encoders.get(kind);
if (cachedEncoder)
return cachedEncoder;
const temporaryWrappedEncoder = (0, lazyFunction_1.lazy)(() => this.compileEncoder(kind));
encoders.set(kind, temporaryWrappedEncoder);
return temporaryWrappedEncoder;
}
encode(codec, value) {
const encoder = this.encoder(codec.format);
const writer = codec.encoder.writer;
writer.reset();
encoder(value, codec.encoder);
return writer.flush();
}
codegenValidator(ctx, path, r) {
throw new Error(`${this.toStringName()}.codegenValidator() not implemented`);
}
compileCborEncoder(options) {
const ctx = new CborEncoderCodegenContext_1.CborEncoderCodegenContext({
system: this.system,
encoder: new CborEncoder_1.CborEncoder(),
...options,
type: this,
});
const r = ctx.codegen.options.args[0];
const value = new JsExpression_1.JsExpression(() => r);
this.codegenCborEncoder(ctx, value);
return ctx.compile();
}
codegenCborEncoder(ctx, value) {
throw new Error(`${this.toStringName()}.codegenCborEncoder() not implemented`);
}
compileMessagePackEncoder(options) {
const ctx = new MessagePackEncoderCodegenContext_1.MessagePackEncoderCodegenContext({
system: this.system,
encoder: new msgpack_1.MsgPackEncoder(),
...options,
type: this,
});
const r = ctx.codegen.options.args[0];
const value = new JsExpression_1.JsExpression(() => r);
this.codegenMessagePackEncoder(ctx, value);
return ctx.compile();
}
codegenMessagePackEncoder(ctx, value) {
throw new Error(`${this.toStringName()}.codegenMessagePackEncoder() not implemented`);
}
compileJsonEncoder(options) {
const writer = new Writer_1.Writer();
const ctx = new JsonEncoderCodegenContext_1.JsonEncoderCodegenContext({
system: this.system,
encoder: new JsonEncoder_1.JsonEncoder(writer),
...options,
type: this,
});
const r = ctx.codegen.options.args[0];
const value = new JsExpression_1.JsExpression(() => r);
this.codegenJsonEncoder(ctx, value);
return ctx.compile();
}
codegenJsonEncoder(ctx, value) {
throw new Error(`${this.toStringName()}.codegenJsonEncoder() not implemented`);
}
compileCapacityEstimator(options) {
const ctx = new CapacityEstimatorCodegenContext_1.CapacityEstimatorCodegenContext({
system: this.system,
...options,
type: this,
});
const r = ctx.codegen.options.args[0];
const value = new JsExpression_1.JsExpression(() => r);
this.codegenCapacityEstimator(ctx, value);
return ctx.compile();
}
codegenCapacityEstimator(ctx, value) {
throw new Error(`${this.toStringName()}.codegenCapacityEstimator() not implemented`);
}
capacityEstimator() {
return (this.__capacityEstimator ||
(this.__capacityEstimator = (0, lazyFunction_1.lazy)(() => (this.__capacityEstimator = this.compileCapacityEstimator({})))));
}
random() {
return json_random_1.RandomJson.generate({ nodeCount: 5 });
}
toTypeScriptAst() {
const node = { node: 'UnknownKeyword' };
return node;
}
toJson(value, system = this.system) {
return JSON.stringify(value);
}
toStringTitle() {
return this.getTypeName();
}
toStringOptions() {
const options = this.getOptions();
const title = options.title || options.intro || options.description;
if (!title)
return '';
return JSON.stringify(title);
}
toStringName() {
return 'AbstractType';
}
toString(tab = '') {
const options = this.toStringOptions();
return this.toStringTitle() + (options ? ` ${options}` : '');
}
toJtdForm() {
const form = { nullable: false };
return form;
}
}
exports.AbstractType = AbstractType;