Upload via GUI (7543 Dateien)

This commit is contained in:
2026-10-22 07:01:41 +00:00
parent 8d29040b57
commit 54baf9b874
50 changed files with 2264 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+158
View File
@@ -0,0 +1,158 @@
# JSON-SCHEMA
[![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/PeculiarVentures/json-schema/master/LICENSE.md)
[![CircleCI](https://circleci.com/gh/PeculiarVentures/json-schema.svg?style=svg)](https://circleci.com/gh/PeculiarVentures/json-schema)
[![Coverage Status](https://coveralls.io/repos/github/PeculiarVentures/json-schema/badge.svg?branch=master&t=ddJivl)](https://coveralls.io/github/PeculiarVentures/json-schema?branch=master)
[![npm version](https://badge.fury.io/js/%40peculiar%2Fjson-schema.svg)](https://badge.fury.io/js/%40peculiar%2Fjson-schema)
[![NPM](https://nodei.co/npm/@peculiar/json-schema.png)](https://nodei.co/npm/@peculiar/json-schema/)
This package uses ES2015 [decorators](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841) to simplify JSON [schema creation and use](https://json-schema.org/understanding-json-schema/index.html).
## Introduction
JSON (JavaScript Object Notation) is a lightweight data-interchange format that was designed to be easy for humans to read and write but in practice, it is [minefield](http://seriot.ch/parsing_json.html) when it machines need to parse it.
While the use of schemas can help with this problem their use can be complicated. When using `json-schema` this is addressed by using decorators to make both serialization and parsing of XML possible via a simple class that handles the schemas for you.
This is important because validating input data before its use is important to do because all input data is evil. Using a schema helps you handle this data [safely](https://www.whitehatsec.com/blog/handling-untrusted-json-safely/).
## Installation
Installation is handled via `npm`:
```
$ npm install @peculiar/json-schema
```
## Examples
### Node.js
Creating a schema:
```js
import { JsonParser, JsonSerializer, JsonProp, JsonPropTypes, IJsonConverter } from "@peculiar/json-schema";
// custom data converter
const JsonBase64UrlConverter: IJsonConverter<Uint8Array, string> = {
fromJSON: (value: string) => base64UrlToBuffer(value),
toJSON: (value: Uint8Array) => bufferToBase64Url(value),
};
class EcPublicKey {
@JsonProp({ name: "kty" })
keyType = "EC";
@JsonProp({ name: "crv" })
namedCurve = "";
@JsonProp({ converter: JsonBase64UrlConverter })
x = new Uint8Array(0);
@JsonProp({ converter: JsonBase64UrlConverter })
y = new Uint8Array(0);
@JsonProp({ name: "ext", type: JsonPropTypes.Boolean, optional: true })
extractable = false;
@JsonProp({ name: "key_ops", type: JsonPropTypes.String, repeated: true, optional: true })
usages: string[] = [];
}
const json = `{
"kty": "EC",
"crv": "P-256",
"x": "zCQ5BPHPCLZYgdpo1n-x_90P2Ij52d53YVwTh3ZdiMo",
"y": "pDfQTUx0-OiZc5ZuKMcA7v2Q7ZPKsQwzB58bft0JTko",
"ext": true
}`;
const ecPubKey = JsonParser.parse(json, { targetSchema: EcPublicKey });
console.log(ecPubKey);
ecPubKey.usages.push("verify");
const jsonText = JsonSerializer.serialize(ecPubKey, undefined, undefined, 2);
console.log(jsonText);
// Output
//
// EcPublicKey {keyType: "EC", namedCurve: "P-256", x: Uint8Array(32), y: Uint8Array(32), extractable: true, …}
//
// {
// "kty": "EC",
// "crv": "P-256",
// "x": "zCQ5BPHPCLZYgdpo1n+x/90P2Ij52d53YVwTh3ZdiMo=",
// "y": "pDfQTUx0+OiZc5ZuKMcA7v2Q7ZPKsQwzB58bft0JTko=",
// "ext": true,
// "key_ops": [
// "verify"
// ]
// }
```
Extending a Schema:
```js
class BaseObject {
@JsonProp({ name: "i" })
public id = 0;
}
class Word extends BaseObject {
@JsonProp({ name: "t" })
public text = "";
}
class Person extends BaseObject {
@JsonProp({ name: "n" })
public name = 0;
@JsonProp({ name: "w", repeated: true, type: Word })
public words = [];
}
const json = `{
"i":1,
"n":"Bob",
"w":[
{"i":2,"t":"hello"},
{"i":3,"t":"world"}
]
}`;
const person = JsonParser.parse(json, { targetSchema: Person });
console.log(person);
const word = new Word();
word.id = 4;
word.text = "!!!";
const jsonText = JsonSerializer.serialize(person, undefined, undefined, 2);
console.log(jsonText);
// Output
//
// Person {id: 1, name: "Bob", words: [Word {id: 2, text: "hello"}, Word {id: 3, text: "world"}]}
// {
// "i": 1,
// "n": "Bob",
// "w": [
// {
// "i": 2,
// "t": "hello"
// },
// {
// "i": 3,
// "t": "world"
// },
// {
// "i": 4,
// "t": "!!!"
// }
// ]
// }
```
## API
Use [index.d.ts](index.d.ts) file
+495
View File
@@ -0,0 +1,495 @@
/**
* Copyright (c) 2020, Peculiar Ventures, All rights reserved.
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
class JsonError extends Error {
constructor(message, innerError) {
super(innerError
? `${message}. See the inner exception for more details.`
: message);
this.message = message;
this.innerError = innerError;
}
}
class TransformError extends JsonError {
constructor(schema, message, innerError) {
super(message, innerError);
this.schema = schema;
}
}
class ParserError extends TransformError {
constructor(schema, message, innerError) {
super(schema, `JSON doesn't match to '${schema.target.name}' schema. ${message}`, innerError);
}
}
class ValidationError extends JsonError {
}
class SerializerError extends JsonError {
constructor(schemaName, message, innerError) {
super(`Cannot serialize by '${schemaName}' schema. ${message}`, innerError);
this.schemaName = schemaName;
}
}
class KeyError extends ParserError {
constructor(schema, keys, errors = {}) {
super(schema, "Some keys doesn't match to schema");
this.keys = keys;
this.errors = errors;
}
}
(function (JsonPropTypes) {
JsonPropTypes[JsonPropTypes["Any"] = 0] = "Any";
JsonPropTypes[JsonPropTypes["Boolean"] = 1] = "Boolean";
JsonPropTypes[JsonPropTypes["Number"] = 2] = "Number";
JsonPropTypes[JsonPropTypes["String"] = 3] = "String";
})(exports.JsonPropTypes || (exports.JsonPropTypes = {}));
function checkType(value, type) {
switch (type) {
case exports.JsonPropTypes.Boolean:
return typeof value === "boolean";
case exports.JsonPropTypes.Number:
return typeof value === "number";
case exports.JsonPropTypes.String:
return typeof value === "string";
}
return true;
}
function throwIfTypeIsWrong(value, type) {
if (!checkType(value, type)) {
throw new TypeError(`Value must be ${exports.JsonPropTypes[type]}`);
}
}
function isConvertible(target) {
if (target && target.prototype) {
if (target.prototype.toJSON && target.prototype.fromJSON) {
return true;
}
else {
return isConvertible(target.prototype);
}
}
else {
return !!(target && target.toJSON && target.fromJSON);
}
}
class JsonSchemaStorage {
constructor() {
this.items = new Map();
}
has(target) {
return this.items.has(target) || !!this.findParentSchema(target);
}
get(target) {
const schema = this.items.get(target) || this.findParentSchema(target);
if (!schema) {
throw new Error("Cannot get schema for current target");
}
return schema;
}
create(target) {
const schema = { names: {} };
const parentSchema = this.findParentSchema(target);
if (parentSchema) {
Object.assign(schema, parentSchema);
schema.names = {};
for (const name in parentSchema.names) {
schema.names[name] = Object.assign({}, parentSchema.names[name]);
}
}
schema.target = target;
return schema;
}
set(target, schema) {
this.items.set(target, schema);
return this;
}
findParentSchema(target) {
const parent = target.__proto__;
if (parent) {
const schema = this.items.get(parent);
return schema || this.findParentSchema(parent);
}
return null;
}
}
const DEFAULT_SCHEMA = "default";
const schemaStorage = new JsonSchemaStorage();
class PatternValidation {
constructor(pattern) {
this.pattern = new RegExp(pattern);
}
validate(value) {
const pattern = new RegExp(this.pattern.source, this.pattern.flags);
if (typeof value !== "string") {
throw new ValidationError("Incoming value must be string");
}
if (!pattern.exec(value)) {
throw new ValidationError(`Value doesn't match to pattern '${pattern.toString()}'`);
}
}
}
class InclusiveValidation {
constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) {
this.min = min;
this.max = max;
}
validate(value) {
throwIfTypeIsWrong(value, exports.JsonPropTypes.Number);
if (!(this.min <= value && value <= this.max)) {
const min = this.min === Number.MIN_VALUE ? "MIN" : this.min;
const max = this.max === Number.MAX_VALUE ? "MAX" : this.max;
throw new ValidationError(`Value doesn't match to diapason [${min},${max}]`);
}
}
}
class ExclusiveValidation {
constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) {
this.min = min;
this.max = max;
}
validate(value) {
throwIfTypeIsWrong(value, exports.JsonPropTypes.Number);
if (!(this.min < value && value < this.max)) {
const min = this.min === Number.MIN_VALUE ? "MIN" : this.min;
const max = this.max === Number.MAX_VALUE ? "MAX" : this.max;
throw new ValidationError(`Value doesn't match to diapason (${min},${max})`);
}
}
}
class LengthValidation {
constructor(length, minLength, maxLength) {
this.length = length;
this.minLength = minLength;
this.maxLength = maxLength;
}
validate(value) {
if (this.length !== undefined) {
if (value.length !== this.length) {
throw new ValidationError(`Value length must be exactly ${this.length}.`);
}
return;
}
if (this.minLength !== undefined) {
if (value.length < this.minLength) {
throw new ValidationError(`Value length must be more than ${this.minLength}.`);
}
}
if (this.maxLength !== undefined) {
if (value.length > this.maxLength) {
throw new ValidationError(`Value length must be less than ${this.maxLength}.`);
}
}
}
}
class EnumerationValidation {
constructor(enumeration) {
this.enumeration = enumeration;
}
validate(value) {
throwIfTypeIsWrong(value, exports.JsonPropTypes.String);
if (!this.enumeration.includes(value)) {
throw new ValidationError(`Value must be one of ${this.enumeration.map((v) => `'${v}'`).join(", ")}`);
}
}
}
class JsonTransform {
static checkValues(data, schemaItem) {
const values = Array.isArray(data) ? data : [data];
for (const value of values) {
for (const validation of schemaItem.validations) {
if (validation instanceof LengthValidation && schemaItem.repeated) {
validation.validate(data);
}
else {
validation.validate(value);
}
}
}
}
static checkTypes(value, schemaItem) {
if (schemaItem.repeated && !Array.isArray(value)) {
throw new TypeError("Value must be Array");
}
if (typeof schemaItem.type === "number") {
const values = Array.isArray(value) ? value : [value];
for (const v of values) {
throwIfTypeIsWrong(v, schemaItem.type);
}
}
}
static getSchemaByName(schema, name = DEFAULT_SCHEMA) {
return { ...schema.names[DEFAULT_SCHEMA], ...schema.names[name] };
}
}
class JsonSerializer extends JsonTransform {
static serialize(obj, options, replacer, space) {
const json = this.toJSON(obj, options);
return JSON.stringify(json, replacer, space);
}
static toJSON(obj, options = {}) {
let res;
let targetSchema = options.targetSchema;
const schemaName = options.schemaName || DEFAULT_SCHEMA;
if (isConvertible(obj)) {
return obj.toJSON();
}
if (Array.isArray(obj)) {
res = [];
for (const item of obj) {
res.push(this.toJSON(item, options));
}
}
else if (typeof obj === "object") {
if (targetSchema && !schemaStorage.has(targetSchema)) {
throw new JsonError("Cannot get schema for `targetSchema` param");
}
targetSchema = (targetSchema || obj.constructor);
if (schemaStorage.has(targetSchema)) {
const schema = schemaStorage.get(targetSchema);
res = {};
const namedSchema = this.getSchemaByName(schema, schemaName);
for (const key in namedSchema) {
try {
const item = namedSchema[key];
const objItem = obj[key];
let value;
if ((item.optional && objItem === undefined)
|| (item.defaultValue !== undefined && objItem === item.defaultValue)) {
continue;
}
if (!item.optional && objItem === undefined) {
throw new SerializerError(targetSchema.name, `Property '${key}' is required.`);
}
if (typeof item.type === "number") {
if (item.converter) {
if (item.repeated) {
value = objItem.map((el) => item.converter.toJSON(el, obj));
}
else {
value = item.converter.toJSON(objItem, obj);
}
}
else {
value = objItem;
}
}
else {
if (item.repeated) {
value = objItem.map((el) => this.toJSON(el, { schemaName }));
}
else {
value = this.toJSON(objItem, { schemaName });
}
}
this.checkTypes(value, item);
this.checkValues(value, item);
res[item.name || key] = value;
}
catch (e) {
if (e instanceof SerializerError) {
throw e;
}
else {
throw new SerializerError(schema.target.name, `Property '${key}' is wrong. ${e.message}`, e);
}
}
}
}
else {
res = {};
for (const key in obj) {
res[key] = this.toJSON(obj[key], { schemaName });
}
}
}
else {
res = obj;
}
return res;
}
}
class JsonParser extends JsonTransform {
static parse(data, options) {
const obj = JSON.parse(data);
return this.fromJSON(obj, options);
}
static fromJSON(target, options) {
const targetSchema = options.targetSchema;
const schemaName = options.schemaName || DEFAULT_SCHEMA;
const obj = new targetSchema();
if (isConvertible(obj)) {
return obj.fromJSON(target);
}
const schema = schemaStorage.get(targetSchema);
const namedSchema = this.getSchemaByName(schema, schemaName);
const keyErrors = {};
if (options.strictProperty && !Array.isArray(target)) {
JsonParser.checkStrictProperty(target, namedSchema, schema);
}
for (const key in namedSchema) {
try {
const item = namedSchema[key];
const name = item.name || key;
const value = target[name];
if (value === undefined && (item.optional || item.defaultValue !== undefined)) {
continue;
}
if (!item.optional && value === undefined) {
throw new ParserError(schema, `Property '${name}' is required.`);
}
this.checkTypes(value, item);
this.checkValues(value, item);
if (typeof (item.type) === "number") {
if (item.converter) {
if (item.repeated) {
obj[key] = value.map((el) => item.converter.fromJSON(el, obj));
}
else {
obj[key] = item.converter.fromJSON(value, obj);
}
}
else {
obj[key] = value;
}
}
else {
const newOptions = {
...options,
targetSchema: item.type,
schemaName,
};
if (item.repeated) {
obj[key] = value.map((el) => this.fromJSON(el, newOptions));
}
else {
obj[key] = this.fromJSON(value, newOptions);
}
}
}
catch (e) {
if (!(e instanceof ParserError)) {
e = new ParserError(schema, `Property '${key}' is wrong. ${e.message}`, e);
}
if (options.strictAllKeys) {
keyErrors[key] = e;
}
else {
throw e;
}
}
}
const keys = Object.keys(keyErrors);
if (keys.length) {
throw new KeyError(schema, keys, keyErrors);
}
return obj;
}
static checkStrictProperty(target, namedSchema, schema) {
const jsonProps = Object.keys(target);
const schemaProps = Object.keys(namedSchema);
const keys = [];
for (const key of jsonProps) {
if (schemaProps.indexOf(key) === -1) {
keys.push(key);
}
}
if (keys.length) {
throw new KeyError(schema, keys);
}
}
}
function getValidations(item) {
const validations = [];
if (item.pattern) {
validations.push(new PatternValidation(item.pattern));
}
if (item.type === exports.JsonPropTypes.Number || item.type === exports.JsonPropTypes.Any) {
if (item.minInclusive !== undefined || item.maxInclusive !== undefined) {
validations.push(new InclusiveValidation(item.minInclusive, item.maxInclusive));
}
if (item.minExclusive !== undefined || item.maxExclusive !== undefined) {
validations.push(new ExclusiveValidation(item.minExclusive, item.maxExclusive));
}
if (item.enumeration !== undefined) {
validations.push(new EnumerationValidation(item.enumeration));
}
}
if (item.type === exports.JsonPropTypes.String || item.repeated || item.type === exports.JsonPropTypes.Any) {
if (item.length !== undefined || item.minLength !== undefined || item.maxLength !== undefined) {
validations.push(new LengthValidation(item.length, item.minLength, item.maxLength));
}
}
return validations;
}
const JsonProp = (options = {}) => (target, propertyKey) => {
const errorMessage = `Cannot set type for ${propertyKey} property of ${target.constructor.name} schema`;
let schema;
if (!schemaStorage.has(target.constructor)) {
schema = schemaStorage.create(target.constructor);
schemaStorage.set(target.constructor, schema);
}
else {
schema = schemaStorage.get(target.constructor);
if (schema.target !== target.constructor) {
schema = schemaStorage.create(target.constructor);
schemaStorage.set(target.constructor, schema);
}
}
const defaultSchema = {
type: exports.JsonPropTypes.Any,
validations: [],
};
const copyOptions = Object.assign(defaultSchema, options);
copyOptions.validations = getValidations(copyOptions);
if (typeof copyOptions.type !== "number") {
if (!schemaStorage.has(copyOptions.type) && !isConvertible(copyOptions.type)) {
throw new Error(`${errorMessage}. Assigning type doesn't have schema.`);
}
}
let schemaNames;
if (Array.isArray(options.schema)) {
schemaNames = options.schema;
}
else {
schemaNames = [options.schema || DEFAULT_SCHEMA];
}
for (const schemaName of schemaNames) {
if (!schema.names[schemaName]) {
schema.names[schemaName] = {};
}
const namedSchema = schema.names[schemaName];
namedSchema[propertyKey] = copyOptions;
}
};
exports.JsonError = JsonError;
exports.JsonParser = JsonParser;
exports.JsonProp = JsonProp;
exports.JsonSerializer = JsonSerializer;
exports.KeyError = KeyError;
exports.ParserError = ParserError;
exports.SerializerError = SerializerError;
exports.TransformError = TransformError;
exports.ValidationError = ValidationError;
+51
View File
@@ -0,0 +1,51 @@
import { JsonPropTypes } from "./prop_types";
import { IEmptyConstructor, IJsonConverter } from "./types";
export interface IJsonPropOptions {
type?: JsonPropTypes | IEmptyConstructor<any>;
optional?: boolean;
defaultValue?: any;
converter?: IJsonConverter<any, any>;
repeated?: boolean;
name?: string;
/**
* Defines name of schema
*/
schema?: string | string[];
/**
* Defines regular expression for text
*/
pattern?: string | RegExp;
/**
* Defines a list of acceptable values
*/
enumeration?: string[];
/**
* Specifies the exact number of characters or list items allowed. Must be equal to or greater than zero
*/
length?: number;
/**
* Specifies the minimum number of characters or list items allowed. Must be equal to or greater than zero
*/
minLength?: number;
/**
* Specifies the maximum number of characters or list items allowed. Must be equal to or greater than zero
*/
maxLength?: number;
/**
* Specifies the lower bounds for numeric values (the value must be greater than or equal to this value)
*/
minInclusive?: number;
/**
* Specifies the upper bounds for numeric values (the value must be less than or equal to this value)
*/
maxInclusive?: number;
/**
* Specifies the lower bounds for numeric values (the value must be greater than this value)
*/
minExclusive?: number;
/**
* Specifies the upper bounds for numeric values (the value must be less than this value)
*/
maxExclusive?: number;
}
export declare const JsonProp: (options?: IJsonPropOptions) => (target: object, propertyKey: string) => void;
+6
View File
@@ -0,0 +1,6 @@
export * from "./json_error";
export * from "./parser_error";
export * from "./validation_error";
export * from "./serializer_error";
export * from "./transform_error";
export * from "./key_error";
@@ -0,0 +1,5 @@
export declare class JsonError extends Error {
message: string;
innerError?: Error | undefined;
constructor(message: string, innerError?: Error | undefined);
}
+10
View File
@@ -0,0 +1,10 @@
import { IJsonSchema } from "../schema";
import { ParserError } from "./parser_error";
export interface IKeyErrors {
[key: string]: Error;
}
export declare class KeyError extends ParserError {
keys: string[];
errors: IKeyErrors;
constructor(schema: IJsonSchema, keys: string[], errors?: IKeyErrors);
}
@@ -0,0 +1,5 @@
import { IJsonSchema } from "../schema";
import { TransformError } from "./transform_error";
export declare class ParserError extends TransformError {
constructor(schema: IJsonSchema, message: string, innerError?: Error);
}
@@ -0,0 +1,5 @@
import { JsonError } from "./json_error";
export declare class SerializerError extends JsonError {
schemaName: string;
constructor(schemaName: string, message: string, innerError?: Error);
}
@@ -0,0 +1,6 @@
import { IJsonSchema } from "../schema";
import { JsonError } from "./json_error";
export declare class TransformError extends JsonError {
schema: IJsonSchema;
constructor(schema: IJsonSchema, message: string, innerError?: Error);
}
@@ -0,0 +1,3 @@
import { JsonError } from "./json_error";
export declare class ValidationError extends JsonError {
}
+5
View File
@@ -0,0 +1,5 @@
import { JsonPropTypes } from "./prop_types";
import { IJsonConvertible } from "./types";
export declare function checkType(value: any, type: JsonPropTypes): boolean;
export declare function throwIfTypeIsWrong(value: any, type: JsonPropTypes): void;
export declare function isConvertible(target: any): target is IJsonConvertible;
+6
View File
@@ -0,0 +1,6 @@
export * from "./serializer";
export * from "./parser";
export * from "./decorators";
export { JsonPropTypes } from "./prop_types";
export * from "./types";
export * from "./errors";
+26
View File
@@ -0,0 +1,26 @@
import { JsonTransform } from "./transform";
import { IEmptyConstructor } from "./types";
export interface IJsonParserOptions<T> {
targetSchema: IEmptyConstructor<T>;
schemaName?: string;
/**
* Enable strict checking of properties. Throw exception if incoming JSON has odd fields
*/
strictProperty?: boolean;
/**
* Checks all properties for object and throws KeyError with list of wrong keys
*/
strictAllKeys?: boolean;
}
export declare class JsonParser extends JsonTransform {
static parse<T>(data: string, options: IJsonParserOptions<T>): T;
static fromJSON<T>(target: any, options: IJsonParserOptions<T>): T;
/**
* Checks for odd properties in target object.
* @param target Target object
* @param namedSchema Named schema with a list of properties
* @param schema
* @throws Throws ParserError exception whenever target object has odd property
*/
private static checkStrictProperty;
}
+6
View File
@@ -0,0 +1,6 @@
export declare enum JsonPropTypes {
Any = 0,
Boolean = 1,
Number = 2,
String = 3
}
+35
View File
@@ -0,0 +1,35 @@
import { JsonPropTypes } from "./prop_types";
import { IEmptyConstructor, IJsonConverter, IValidation } from "./types";
export interface IValidationEvent {
propName: string;
value: any;
}
export interface IJsonSchemaItem {
type: JsonPropTypes | IEmptyConstructor<any>;
optional?: boolean;
defaultValue?: any;
converter?: IJsonConverter<any, any>;
repeated?: boolean;
name?: string;
validations: IValidation[];
}
export interface IJsonSchema {
target: IEmptyConstructor<any>;
names: {
[key: string]: {
[key: string]: IJsonSchemaItem;
};
};
}
export declare class JsonSchemaStorage {
protected items: Map<object, IJsonSchema>;
has(target: object): boolean;
get(target: object): IJsonSchema;
/**
* Creates new schema
* @param target Target object
*/
create(target: object): IJsonSchema;
set(target: object, schema: IJsonSchema): this;
protected findParentSchema(target: object): IJsonSchema | null;
}
+10
View File
@@ -0,0 +1,10 @@
import { JsonTransform } from "./transform";
import { IEmptyConstructor } from "./types";
export interface IJsonSerializerOptions {
targetSchema?: IEmptyConstructor<any>;
schemaName?: string;
}
export declare class JsonSerializer extends JsonTransform {
static serialize(obj: any, options?: IJsonSerializerOptions, replacer?: (key: string, value: any) => any, space?: string | number): string;
static toJSON(obj: any, options?: IJsonSerializerOptions): any;
}
+6
View File
@@ -0,0 +1,6 @@
import { JsonSchemaStorage } from "./schema";
/**
* Name of default schema
*/
export declare const DEFAULT_SCHEMA = "default";
export declare const schemaStorage: JsonSchemaStorage;
+9
View File
@@ -0,0 +1,9 @@
import { IJsonSchema, IJsonSchemaItem } from "./schema";
export interface IJsonNamedSchema {
[key: string]: IJsonSchemaItem;
}
export declare class JsonTransform {
protected static checkValues(data: any, schemaItem: IJsonSchemaItem): void;
protected static checkTypes(value: any, schemaItem: IJsonSchemaItem): void;
protected static getSchemaByName(schema: IJsonSchema, name?: string): IJsonNamedSchema;
}
+12
View File
@@ -0,0 +1,12 @@
export declare type IEmptyConstructor<T> = new () => T;
export interface IJsonConverter<T, S> {
fromJSON(value: S, target: any): T;
toJSON(value: T, target: any): S;
}
export interface IJsonConvertible<T = any> {
fromJSON(json: T): this;
toJSON(): T;
}
export interface IValidation {
validate(value: any): void;
}
@@ -0,0 +1,6 @@
import { IValidation } from "../types";
export declare class EnumerationValidation implements IValidation {
private enumeration;
constructor(enumeration: string[]);
validate(value: any): void;
}
@@ -0,0 +1,7 @@
import { IValidation } from "../types";
export declare class ExclusiveValidation implements IValidation {
private min;
private max;
constructor(min?: number, max?: number);
validate(value: any): void;
}
@@ -0,0 +1,7 @@
import { IValidation } from "../types";
export declare class InclusiveValidation implements IValidation {
private min;
private max;
constructor(min?: number, max?: number);
validate(value: any): void;
}
@@ -0,0 +1,5 @@
export * from "./pattern";
export * from "./inclusive";
export * from "./exclusive";
export * from "./length";
export * from "./enumeration";
@@ -0,0 +1,8 @@
import { IValidation } from "../types";
export declare class LengthValidation implements IValidation {
private length?;
private minLength?;
private maxLength?;
constructor(length?: number | undefined, minLength?: number | undefined, maxLength?: number | undefined);
validate(value: any): void;
}
@@ -0,0 +1,6 @@
import { IValidation } from "../types";
export declare class PatternValidation implements IValidation {
private pattern;
constructor(pattern: string | RegExp);
validate(value: any): void;
}
+95
View File
@@ -0,0 +1,95 @@
{
"name": "@peculiar/json-schema",
"version": "1.1.12",
"description": "This package uses ES2015 decorators to simplify JSON schema creation and use",
"main": "build/index.js",
"module": "build/index.es.js",
"types": "build/types/index.d.ts",
"scripts": {
"test": "mocha",
"prepare": "npm run build",
"lint": "tslint -p .",
"lint:fix": "tslint --fix -p .",
"build": "npm run build:module && npm run build:types",
"build:module": "rollup -c",
"build:types": "tsc -p tsconfig.types.json",
"clear": "rimraf build/*",
"rebuild": "npm run clear && npm run build",
"prepub": "npm run lint && npm run build",
"pub": "npm version patch && npm publish",
"postpub": "git push && git push --tags origin master",
"prepub:next": "npm run lint && npm run build",
"pub:next": "npm version prerelease --preid=next && npm publish --tag next",
"postpub:next": "git push",
"coverage": "nyc npm test",
"coveralls": "nyc report --reporter=text-lcov | coveralls"
},
"repository": {
"type": "git",
"url": "git+https://github.com/PeculiarVentures/json-schema.git"
},
"keywords": [
"json",
"stringify",
"serialize",
"parse",
"convert",
"decorator"
],
"author": "PeculiarVentures, Inc",
"contributors": [
{
"email": "rmh@unmitigatedrisk.com",
"name": "Ryan Hurst"
},
{
"email": "microshine@mail.ru",
"name": "Miroshin Stepan"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/PeculiarVentures/json-schema/issues"
},
"homepage": "https://github.com/PeculiarVentures/json-schema#readme",
"engines": {
"node": ">=8.0.0"
},
"devDependencies": {
"@types/mocha": "^8.0.0",
"@types/node": "^12.12.51",
"mocha": "^8.0.1",
"rimraf": "^3.0.2",
"rollup": "^2.22.2",
"rollup-plugin-typescript2": "^0.27.1",
"ts-node": "^8.10.2",
"tslint": "^6.1.2",
"typescript": "^3.9.7"
},
"dependencies": {
"tslib": "^2.0.0"
},
"nyc": {
"extension": [
".ts",
".tsx"
],
"include": [
"src/**/*.ts"
],
"exclude": [
"**/*.d.ts"
],
"reporter": [
"text-summary",
"html"
]
},
"mocha": {
"require": "ts-node/register",
"extension": [
"ts"
],
"watch-files": "test/**/*.ts"
}
}
+115
View File
@@ -0,0 +1,115 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isArrayBuffer = isArrayBuffer;
exports.isSharedArrayBuffer = isSharedArrayBuffer;
exports.isArrayBufferLike = isArrayBufferLike;
exports.isArrayBufferView = isArrayBufferView;
exports.isBufferSource = isBufferSource;
exports.assertBufferSource = assertBufferSource;
exports.toUint8Array = toUint8Array;
exports.toUint8ArrayCopy = toUint8ArrayCopy;
exports.toArrayBuffer = toArrayBuffer;
exports.toArrayBufferLike = toArrayBufferLike;
exports.toView = toView;
exports.toViewCopy = toViewCopy;
const ARRAY_BUFFER_TAG = "[object ArrayBuffer]";
const SHARED_ARRAY_BUFFER_TAG = "[object SharedArrayBuffer]";
function tagOf(value) {
return Object.prototype.toString.call(value);
}
function isDataViewConstructor(type) {
return type === DataView || type.prototype instanceof DataView;
}
function bytesPerElement(type) {
if (isDataViewConstructor(type)) {
return 1;
}
const value = type.BYTES_PER_ELEMENT;
return value ?? 1;
}
function isArrayBufferViewLike(value) {
if (ArrayBuffer.isView(value)) {
return true;
}
if (!value || typeof value !== "object") {
return false;
}
const view = value;
return typeof view.byteOffset === "number"
&& typeof view.byteLength === "number"
&& isArrayBufferLike(view.buffer);
}
function copyBytes(data) {
const view = toUint8Array(data);
const copy = new Uint8Array(view.byteLength);
copy.set(view);
return copy;
}
function isArrayBuffer(value) {
return tagOf(value) === ARRAY_BUFFER_TAG;
}
function isSharedArrayBuffer(value) {
return typeof SharedArrayBuffer !== "undefined" && tagOf(value) === SHARED_ARRAY_BUFFER_TAG;
}
function isArrayBufferLike(value) {
return isArrayBuffer(value) || isSharedArrayBuffer(value);
}
function isArrayBufferView(value) {
return isArrayBufferViewLike(value);
}
function isBufferSource(value) {
return isArrayBufferLike(value) || isArrayBufferView(value);
}
function assertBufferSource(value) {
if (!isBufferSource(value)) {
throw new TypeError("Expected ArrayBuffer, SharedArrayBuffer, or ArrayBufferView");
}
}
function toUint8Array(data) {
assertBufferSource(data);
if (isArrayBufferLike(data)) {
return new Uint8Array(data);
}
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
}
function toUint8ArrayCopy(data) {
return copyBytes(data);
}
function toArrayBuffer(data) {
assertBufferSource(data);
if (isArrayBuffer(data)) {
return data;
}
const buffer = new ArrayBuffer(data.byteLength);
new Uint8Array(buffer).set(toUint8Array(data));
return buffer;
}
function toArrayBufferLike(data) {
assertBufferSource(data);
if (isArrayBufferLike(data)) {
return data;
}
if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
return data.buffer;
}
return copyBytes(data).buffer;
}
function toView(data, type) {
assertBufferSource(data);
if (ArrayBuffer.isView(data) && data.constructor === type) {
return data;
}
const view = toUint8Array(data);
const elementSize = bytesPerElement(type);
if (view.byteOffset % elementSize !== 0 || view.byteLength % elementSize !== 0) {
throw new RangeError(`Cannot create ${type.name} over unaligned byte range`);
}
if (isDataViewConstructor(type)) {
return new type(view.buffer, view.byteOffset, view.byteLength);
}
return new type(view.buffer, view.byteOffset, view.byteLength / elementSize);
}
function toViewCopy(data, type) {
const copy = toUint8ArrayCopy(data);
return toView(copy, type);
}
+41
View File
@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.concatToUint8Array = concatToUint8Array;
exports.concat = concat;
const buffer_source_js_1 = require("./buffer-source.js");
function concatToUint8Array(buffers) {
const views = [];
let length = 0;
for (const buffer of buffers) {
const view = (0, buffer_source_js_1.toUint8Array)(buffer);
views.push(view);
length += view.byteLength;
}
const result = new Uint8Array(length);
let offset = 0;
for (const view of views) {
result.set(view, offset);
offset += view.byteLength;
}
return result;
}
function concat(first, second, ...rest) {
let buffers;
let type;
if (typeof second === "function") {
buffers = Array.from(first);
type = second;
}
else if ((0, buffer_source_js_1.isBufferSource)(first)) {
buffers = [first, second, ...rest].filter(buffer_source_js_1.isBufferSource);
}
else {
buffers = Array.from(first);
if (second) {
buffers.push(second);
}
buffers.push(...rest);
}
const bytes = concatToUint8Array(buffers);
return type ? (0, buffer_source_js_1.toView)(bytes, type) : bytes.buffer;
}
+17
View File
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.equal = equal;
const buffer_source_js_1 = require("./buffer-source.js");
function equal(a, b, options = {}) {
const left = (0, buffer_source_js_1.toUint8Array)(a);
const right = (0, buffer_source_js_1.toUint8Array)(b);
if (!options.constantTime && left.byteLength !== right.byteLength) {
return false;
}
const length = Math.max(left.byteLength, right.byteLength);
let diff = left.byteLength ^ right.byteLength;
for (let i = 0; i < length; i++) {
diff |= (left[i] ?? 0) ^ (right[i] ?? 0);
}
return diff === 0;
}
+31
View File
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.tail = exports.startsWith = exports.slice = exports.lastIndexOf = exports.indexOf = exports.includes = exports.endsWith = exports.copy = exports.compare = exports.equal = exports.concatToUint8Array = exports.concat = exports.toViewCopy = exports.toView = exports.toUint8ArrayCopy = exports.toUint8Array = exports.toArrayBufferLike = exports.toArrayBuffer = exports.isSharedArrayBuffer = exports.isBufferSource = exports.isArrayBufferView = exports.isArrayBufferLike = exports.isArrayBuffer = exports.assertBufferSource = void 0;
var buffer_source_js_1 = require("./buffer-source.js");
Object.defineProperty(exports, "assertBufferSource", { enumerable: true, get: function () { return buffer_source_js_1.assertBufferSource; } });
Object.defineProperty(exports, "isArrayBuffer", { enumerable: true, get: function () { return buffer_source_js_1.isArrayBuffer; } });
Object.defineProperty(exports, "isArrayBufferLike", { enumerable: true, get: function () { return buffer_source_js_1.isArrayBufferLike; } });
Object.defineProperty(exports, "isArrayBufferView", { enumerable: true, get: function () { return buffer_source_js_1.isArrayBufferView; } });
Object.defineProperty(exports, "isBufferSource", { enumerable: true, get: function () { return buffer_source_js_1.isBufferSource; } });
Object.defineProperty(exports, "isSharedArrayBuffer", { enumerable: true, get: function () { return buffer_source_js_1.isSharedArrayBuffer; } });
Object.defineProperty(exports, "toArrayBuffer", { enumerable: true, get: function () { return buffer_source_js_1.toArrayBuffer; } });
Object.defineProperty(exports, "toArrayBufferLike", { enumerable: true, get: function () { return buffer_source_js_1.toArrayBufferLike; } });
Object.defineProperty(exports, "toUint8Array", { enumerable: true, get: function () { return buffer_source_js_1.toUint8Array; } });
Object.defineProperty(exports, "toUint8ArrayCopy", { enumerable: true, get: function () { return buffer_source_js_1.toUint8ArrayCopy; } });
Object.defineProperty(exports, "toView", { enumerable: true, get: function () { return buffer_source_js_1.toView; } });
Object.defineProperty(exports, "toViewCopy", { enumerable: true, get: function () { return buffer_source_js_1.toViewCopy; } });
var concat_js_1 = require("./concat.js");
Object.defineProperty(exports, "concat", { enumerable: true, get: function () { return concat_js_1.concat; } });
Object.defineProperty(exports, "concatToUint8Array", { enumerable: true, get: function () { return concat_js_1.concatToUint8Array; } });
var equal_js_1 = require("./equal.js");
Object.defineProperty(exports, "equal", { enumerable: true, get: function () { return equal_js_1.equal; } });
var sequence_js_1 = require("./sequence.js");
Object.defineProperty(exports, "compare", { enumerable: true, get: function () { return sequence_js_1.compare; } });
Object.defineProperty(exports, "copy", { enumerable: true, get: function () { return sequence_js_1.copy; } });
Object.defineProperty(exports, "endsWith", { enumerable: true, get: function () { return sequence_js_1.endsWith; } });
Object.defineProperty(exports, "includes", { enumerable: true, get: function () { return sequence_js_1.includes; } });
Object.defineProperty(exports, "indexOf", { enumerable: true, get: function () { return sequence_js_1.indexOf; } });
Object.defineProperty(exports, "lastIndexOf", { enumerable: true, get: function () { return sequence_js_1.lastIndexOf; } });
Object.defineProperty(exports, "slice", { enumerable: true, get: function () { return sequence_js_1.slice; } });
Object.defineProperty(exports, "startsWith", { enumerable: true, get: function () { return sequence_js_1.startsWith; } });
Object.defineProperty(exports, "tail", { enumerable: true, get: function () { return sequence_js_1.tail; } });
+161
View File
@@ -0,0 +1,161 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.indexOf = indexOf;
exports.lastIndexOf = lastIndexOf;
exports.includes = includes;
exports.startsWith = startsWith;
exports.endsWith = endsWith;
exports.slice = slice;
exports.tail = tail;
exports.copy = copy;
exports.compare = compare;
const buffer_source_js_1 = require("./buffer-source.js");
function clampIndex(value, fallback, length) {
const normalized = Number.isFinite(value) ? Math.trunc(value) : fallback;
if (normalized <= 0) {
return 0;
}
if (normalized >= length) {
return length;
}
return normalized;
}
function normalizeForwardRange(length, options) {
const start = clampIndex(options?.start, 0, length);
const end = clampIndex(options?.end, length, length);
return end >= start ? [start, end] : [start, start];
}
function normalizeReverseRange(length, options) {
const start = clampIndex(options?.start, length, length);
const end = clampIndex(options?.end, 0, length);
return start >= end ? [end, start] : [start, start];
}
function normalizeSliceIndex(value, fallback, length) {
const normalized = Number.isFinite(value) ? Math.trunc(value) : fallback;
if (normalized < 0) {
return Math.max(length + normalized, 0);
}
if (normalized > length) {
return length;
}
return normalized;
}
function encodeAscii(text) {
const bytes = new Uint8Array(text.length);
for (let i = 0; i < text.length; i++) {
bytes[i] = text.charCodeAt(i) & 0xff;
}
return bytes;
}
function encodeUtf8(text) {
return new TextEncoder().encode(text);
}
function toPatternBytes(pattern, options) {
if (typeof pattern === "string") {
return options?.encoding === "utf8" ? encodeUtf8(pattern) : encodeAscii(pattern);
}
return (0, buffer_source_js_1.toUint8Array)(pattern);
}
function bytesEqualAt(data, pattern, offset) {
for (let index = 0; index < pattern.byteLength; index++) {
if (data[offset + index] !== pattern[index]) {
return false;
}
}
return true;
}
function indexOf(data, pattern, options) {
const bytes = (0, buffer_source_js_1.toUint8Array)(data);
const needle = toPatternBytes(pattern, options);
const [start, end] = normalizeForwardRange(bytes.byteLength, options);
if (needle.byteLength === 0) {
return start;
}
const lastOffset = end - needle.byteLength;
if (lastOffset < start) {
return -1;
}
for (let offset = start; offset <= lastOffset; offset++) {
if (bytesEqualAt(bytes, needle, offset)) {
return offset;
}
}
return -1;
}
function lastIndexOf(data, pattern, options) {
const bytes = (0, buffer_source_js_1.toUint8Array)(data);
const needle = toPatternBytes(pattern, options);
const [end, start] = normalizeReverseRange(bytes.byteLength, options);
if (needle.byteLength === 0) {
return start;
}
const firstOffset = start - needle.byteLength;
if (firstOffset < end) {
return -1;
}
for (let offset = firstOffset; offset >= end; offset--) {
if (bytesEqualAt(bytes, needle, offset)) {
return offset;
}
}
return -1;
}
function includes(data, pattern, options) {
return indexOf(data, pattern, options) !== -1;
}
function startsWith(data, pattern, options) {
const bytes = (0, buffer_source_js_1.toUint8Array)(data);
const needle = toPatternBytes(pattern, options);
if (needle.byteLength > bytes.byteLength) {
return false;
}
return bytesEqualAt(bytes, needle, 0);
}
function endsWith(data, pattern, options) {
const bytes = (0, buffer_source_js_1.toUint8Array)(data);
const needle = toPatternBytes(pattern, options);
if (needle.byteLength > bytes.byteLength) {
return false;
}
return bytesEqualAt(bytes, needle, bytes.byteLength - needle.byteLength);
}
function slice(data, start, end) {
const bytes = (0, buffer_source_js_1.toUint8Array)(data);
const normalizedStart = normalizeSliceIndex(start, 0, bytes.byteLength);
const normalizedEnd = normalizeSliceIndex(end, bytes.byteLength, bytes.byteLength);
if (normalizedEnd <= normalizedStart) {
return bytes.subarray(normalizedStart, normalizedStart);
}
return bytes.subarray(normalizedStart, normalizedEnd);
}
function tail(data, length) {
const bytes = (0, buffer_source_js_1.toUint8Array)(data);
const normalizedLength = Number.isFinite(length) ? Math.max(0, Math.trunc(length)) : 0;
if (normalizedLength >= bytes.byteLength) {
return bytes;
}
return bytes.subarray(bytes.byteLength - normalizedLength);
}
function copy(data) {
return (0, buffer_source_js_1.toUint8ArrayCopy)(data);
}
function compare(a, b) {
const left = (0, buffer_source_js_1.toUint8Array)(a);
const right = (0, buffer_source_js_1.toUint8Array)(b);
const limit = Math.min(left.byteLength, right.byteLength);
for (let index = 0; index < limit; index++) {
if (left[index] < right[index]) {
return -1;
}
if (left[index] > right[index]) {
return 1;
}
}
if (left.byteLength < right.byteLength) {
return -1;
}
if (left.byteLength > right.byteLength) {
return 1;
}
return 0;
}
+2
View File
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
+74
View File
@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convert = void 0;
const index_js_1 = require("../bytes/index.js");
const index_js_2 = require("../encoding/index.js");
const defaults_js_1 = require("./defaults.js");
function encode(name, data, ...args) {
return defaults_js_1.defaultConverterRegistry.encode(name, data, ...args);
}
function decode(name, text, ...args) {
return defaults_js_1.defaultConverterRegistry.decode(name, text, ...args);
}
function tryDecode(name, text, ...args) {
return defaults_js_1.defaultConverterRegistry.tryDecode(name, text, ...args);
}
function normalize(name, text, ...args) {
return defaults_js_1.defaultConverterRegistry.normalize(name, text, ...args);
}
function parse(name, text, ...args) {
return defaults_js_1.defaultConverterRegistry.parse(name, text, ...args);
}
function format(name, data, value) {
return defaults_js_1.defaultConverterRegistry.format(name, data, value);
}
function transcode(text, options) {
return defaults_js_1.defaultConverterRegistry.transcode(text, options);
}
function detect(text, options) {
return defaults_js_1.defaultConverterRegistry.detect(text, options);
}
function normalizeEncodingName(encoding) {
return encoding.toLowerCase();
}
exports.convert = {
encode,
decode,
tryDecode,
normalize,
parse,
format,
transcode,
detect,
to(format, data, ...args) {
return encode(format, data, ...args);
},
from(format, text, ...args) {
return decode(format, text, ...args);
},
toString(data, encoding = "utf8") {
return encode(encoding, data);
},
fromString(text, encoding = "utf8") {
if (normalizeEncodingName(encoding) === "hex") {
return (0, index_js_1.toArrayBuffer)(index_js_2.hex.decode(text, { allowOddLength: true }));
}
return (0, index_js_1.toArrayBuffer)(decode(encoding, text));
},
toBase64: index_js_2.base64.encode,
fromBase64: (text) => (0, index_js_1.toArrayBuffer)(index_js_2.base64.decode(text)),
toBase64Url: index_js_2.base64url.encode,
fromBase64Url: (text) => (0, index_js_1.toArrayBuffer)(index_js_2.base64url.decode(text)),
toHex: index_js_2.hex.encode,
fromHex: (text) => (0, index_js_1.toArrayBuffer)(index_js_2.hex.decode(text, { allowOddLength: true })),
toBinary: index_js_2.binary.encode,
fromBinary: (text) => (0, index_js_1.toArrayBuffer)(index_js_2.binary.decode(text)),
toUtf8String: index_js_2.utf8.decode,
fromUtf8String: (text) => (0, index_js_1.toArrayBuffer)(index_js_2.utf8.encode(text)),
toUtf16String: (data, littleEndian = false) => index_js_2.utf16.decode(data, { littleEndian }),
fromUtf16String: (text, littleEndian = false) => (0, index_js_1.toArrayBuffer)(index_js_2.utf16.encode(text, { littleEndian })),
isHex: index_js_2.hex.is,
isBase64: index_js_2.base64.is,
isBase64Url: index_js_2.base64url.is,
formatString: index_js_2.base64.normalize,
};
+72
View File
@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultConverterRegistry = exports.defaultConverters = exports.utf16leConverter = exports.utf16beConverter = exports.utf8Converter = exports.base64urlConverter = exports.base64Converter = exports.hexConverter = exports.binaryConverter = exports.pemConverter = void 0;
const index_js_1 = require("../encoding/index.js");
const index_js_2 = require("../pem/index.js");
var index_js_3 = require("../pem/index.js");
Object.defineProperty(exports, "pemConverter", { enumerable: true, get: function () { return index_js_3.pemConverter; } });
const registry_js_1 = require("./registry.js");
exports.binaryConverter = {
name: "binary",
aliases: ["latin1"],
encode: index_js_1.binary.encode,
decode: index_js_1.binary.decode,
is: index_js_1.binary.is,
};
exports.hexConverter = {
name: "hex",
encode: index_js_1.hex.encode,
decode: index_js_1.hex.decode,
format: index_js_1.hex.format,
is: index_js_1.hex.is,
normalize: index_js_1.hex.normalize,
parse: index_js_1.hex.parse,
};
exports.base64Converter = {
name: "base64",
aliases: ["b64"],
encode: index_js_1.base64.encode,
decode: index_js_1.base64.decode,
is: index_js_1.base64.is,
normalize: index_js_1.base64.normalize,
};
exports.base64urlConverter = {
name: "base64url",
aliases: ["base64-url", "b64url"],
encode: index_js_1.base64url.encode,
decode: index_js_1.base64url.decode,
is: index_js_1.base64url.is,
normalize: index_js_1.base64url.normalize,
};
exports.utf8Converter = {
name: "utf8",
aliases: ["utf-8"],
encode: (data) => index_js_1.utf8.decode(data),
decode: (text) => index_js_1.utf8.encode(text),
is: (text) => typeof text === "string",
};
exports.utf16beConverter = {
name: "utf16be",
aliases: ["utf16", "utf-16", "utf-16be"],
encode: (data) => index_js_1.utf16.decode(data),
decode: (text) => index_js_1.utf16.encode(text),
is: (text) => typeof text === "string",
};
exports.utf16leConverter = {
name: "utf16le",
aliases: ["utf-16le", "ucs2", "usc2"],
encode: (data) => index_js_1.utf16.decode(data, { littleEndian: true }),
decode: (text) => index_js_1.utf16.encode(text, { littleEndian: true }),
is: (text) => typeof text === "string",
};
exports.defaultConverters = [
exports.binaryConverter,
exports.hexConverter,
exports.base64Converter,
exports.base64urlConverter,
exports.utf8Converter,
exports.utf16beConverter,
exports.utf16leConverter,
index_js_2.pemConverter,
];
exports.defaultConverterRegistry = (0, registry_js_1.createConverterRegistry)(exports.defaultConverters);
+18
View File
@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convert = exports.utf8Converter = exports.utf16leConverter = exports.utf16beConverter = exports.pemConverter = exports.hexConverter = exports.defaultConverters = exports.defaultConverterRegistry = exports.binaryConverter = exports.base64urlConverter = exports.base64Converter = exports.createConverterRegistry = void 0;
var registry_js_1 = require("./registry.js");
Object.defineProperty(exports, "createConverterRegistry", { enumerable: true, get: function () { return registry_js_1.createConverterRegistry; } });
var defaults_js_1 = require("./defaults.js");
Object.defineProperty(exports, "base64Converter", { enumerable: true, get: function () { return defaults_js_1.base64Converter; } });
Object.defineProperty(exports, "base64urlConverter", { enumerable: true, get: function () { return defaults_js_1.base64urlConverter; } });
Object.defineProperty(exports, "binaryConverter", { enumerable: true, get: function () { return defaults_js_1.binaryConverter; } });
Object.defineProperty(exports, "defaultConverterRegistry", { enumerable: true, get: function () { return defaults_js_1.defaultConverterRegistry; } });
Object.defineProperty(exports, "defaultConverters", { enumerable: true, get: function () { return defaults_js_1.defaultConverters; } });
Object.defineProperty(exports, "hexConverter", { enumerable: true, get: function () { return defaults_js_1.hexConverter; } });
Object.defineProperty(exports, "pemConverter", { enumerable: true, get: function () { return defaults_js_1.pemConverter; } });
Object.defineProperty(exports, "utf16beConverter", { enumerable: true, get: function () { return defaults_js_1.utf16beConverter; } });
Object.defineProperty(exports, "utf16leConverter", { enumerable: true, get: function () { return defaults_js_1.utf16leConverter; } });
Object.defineProperty(exports, "utf8Converter", { enumerable: true, get: function () { return defaults_js_1.utf8Converter; } });
var convert_js_1 = require("./convert.js");
Object.defineProperty(exports, "convert", { enumerable: true, get: function () { return convert_js_1.convert; } });
+188
View File
@@ -0,0 +1,188 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createConverterRegistry = createConverterRegistry;
function keyOf(name) {
return name.trim().toLowerCase();
}
function toError(error) {
return error instanceof Error ? error : new Error(String(error));
}
function removeConverter(converters, primaryNames, converter) {
for (const alias of [converter.name, ...(converter.aliases ?? [])]) {
converters.delete(keyOf(alias));
}
primaryNames.delete(keyOf(converter.name));
}
function requireCapability(converter, name, capability) {
const method = converter[capability];
if (typeof method !== "function") {
throw new Error(`Converter '${name}' does not support ${capability}()`);
}
return method;
}
function detectConfidence(name, text, converter) {
const normalizedName = keyOf(converter.name || name);
const trimmed = text.trim();
if (!trimmed) {
return 0;
}
let accepted = false;
if (converter.is) {
accepted = converter.is(text);
}
let decodable = false;
try {
converter.decode(text);
decodable = true;
}
catch {
decodable = false;
}
if (!accepted && !decodable) {
return 0;
}
switch (normalizedName) {
case "pem":
return /-----BEGIN [^-]+-----/.test(text) ? 1 : 0;
case "hex": {
const compact = trimmed.replace(/^0x/i, "").replace(/[\s:.-]/g, "");
if (!compact || /[^0-9a-f]/i.test(compact) || compact.length % 2 !== 0) {
return 0;
}
if (/^0x/i.test(trimmed) || /[:\s.-]/.test(trimmed)) {
return 0.95;
}
if (/[a-f]/.test(trimmed) || /[A-F]/.test(trimmed)) {
return 0.8;
}
return 0.45;
}
case "base64url":
if (/[-_]/.test(trimmed)) {
return 0.95;
}
if (/=/.test(trimmed)) {
return 0.1;
}
return 0.6;
case "base64":
if (/[+/=]/.test(trimmed)) {
return 0.9;
}
return 0.55;
case "binary":
case "utf8":
case "utf16be":
case "utf16le":
return 0;
default:
return accepted && decodable ? 0.75 : 0.5;
}
}
function createConverterRegistry(initialConverters = []) {
const converters = new Map();
const primaryNames = new Set();
const api = {
register(converter, options = {}) {
if (!converter.name || !keyOf(converter.name)) {
throw new TypeError("Converter name is required");
}
const names = [...new Set([converter.name, ...(converter.aliases ?? [])].map(keyOf))];
const conflicts = new Set();
for (const name of names) {
const existing = converters.get(name);
if (!existing) {
continue;
}
if (!options.override) {
throw new Error(`Converter '${name}' is already registered`);
}
conflicts.add(existing);
}
for (const conflicting of conflicts) {
removeConverter(converters, primaryNames, conflicting);
}
for (const name of names) {
converters.set(name, converter);
}
primaryNames.add(keyOf(converter.name));
return this;
},
unregister(name) {
const converter = converters.get(keyOf(name));
if (!converter) {
return false;
}
removeConverter(converters, primaryNames, converter);
return true;
},
has(name) {
return converters.has(keyOf(name));
},
get(name) {
const converter = converters.get(keyOf(name));
if (!converter) {
throw new Error(`Converter '${name}' is not registered`);
}
return converter;
},
list() {
return [...primaryNames].map((name) => this.get(name));
},
encode(name, data, options) {
return this.get(name).encode(data, options);
},
decode(name, text, options) {
return this.get(name).decode(text, options);
},
tryDecode(name, text, options) {
try {
return { ok: true, bytes: this.decode(name, text, options) };
}
catch (error) {
return { ok: false, error: toError(error) };
}
},
normalize(name, text, options) {
const converter = this.get(name);
return requireCapability(converter, name, "normalize").call(converter, text, options);
},
parse(name, text, options) {
const converter = this.get(name);
return requireCapability(converter, name, "parse").call(converter, text, options);
},
format(name, data, format) {
const converter = this.get(name);
return requireCapability(converter, name, "format").call(converter, data, format);
},
transcode(text, options) {
const bytes = this.decode(options.from, text, options.fromOptions);
return this.encode(options.to, bytes, options.toOptions);
},
detect(text, options = {}) {
const formatNames = options.formats?.length
? options.formats.map((name) => String(name))
: this.list()
.map((converter) => converter.name)
.filter((name) => !["binary", "utf8", "utf16be", "utf16le"].includes(keyOf(name)));
const detections = new Map();
for (const requestedName of formatNames) {
const converter = this.get(requestedName);
const confidence = detectConfidence(requestedName, text, converter);
if (confidence <= 0) {
continue;
}
const format = converter.name;
const current = detections.get(format);
if (!current || confidence > current.confidence) {
detections.set(format, { format, confidence });
}
}
return [...detections.values()].sort((left, right) => right.confidence - left.confidence);
},
};
for (const converter of initialConverters) {
api.register(converter);
}
return api;
}
+2
View File
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
+48
View File
@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.base64 = void 0;
exports.normalize = normalize;
exports.pad = pad;
exports.is = is;
exports.encode = encode;
exports.decode = decode;
const index_js_1 = require("../bytes/index.js");
const binary_js_1 = require("./binary.js");
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
function nodeBuffer() {
return globalThis.Buffer;
}
function normalize(text) {
return text.replace(/[\n\r\t ]/g, "");
}
function pad(text) {
const remainder = text.length % 4;
return remainder ? text + "=".repeat(4 - remainder) : text;
}
function is(text) {
if (typeof text !== "string") {
return false;
}
const normalized = normalize(text);
return normalized === "" || BASE64_REGEX.test(normalized);
}
function encode(data, _options) {
const bytes = (0, index_js_1.toUint8Array)(data);
const buffer = nodeBuffer();
if (buffer) {
return buffer.from(bytes).toString("base64");
}
return btoa((0, binary_js_1.encode)(bytes));
}
function decode(text, _options) {
const normalized = normalize(text);
if (!is(normalized)) {
throw new TypeError("Input is not valid Base64 text");
}
const buffer = nodeBuffer();
if (buffer) {
return new Uint8Array(buffer.from(normalized, "base64"));
}
return (0, binary_js_1.decode)(atob(normalized));
}
exports.base64 = { encode, decode, is, normalize, pad };
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.base64url = void 0;
exports.normalize = normalize;
exports.is = is;
exports.encode = encode;
exports.decode = decode;
const base64_js_1 = require("./base64.js");
const BASE64URL_REGEX = /^[A-Za-z0-9_-]*$/;
function normalize(text) {
return text.replace(/[\n\r\t ]/g, "");
}
function is(text) {
return typeof text === "string" && BASE64URL_REGEX.test(normalize(text));
}
function encode(data, _options) {
return base64_js_1.base64.encode(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
}
function decode(text, _options) {
const normalized = normalize(text);
if (!is(normalized)) {
throw new TypeError("Input is not valid Base64Url text");
}
return base64_js_1.base64.decode(base64_js_1.base64.pad(normalized.replace(/-/g, "+").replace(/_/g, "/")));
}
exports.base64url = { encode, decode, is, normalize };
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.binary = void 0;
exports.encode = encode;
exports.decode = decode;
exports.is = is;
const index_js_1 = require("../bytes/index.js");
function encode(data) {
const bytes = (0, index_js_1.toUint8Array)(data);
let result = "";
for (const byte of bytes) {
result += String.fromCharCode(byte);
}
return result;
}
function decode(text) {
const result = new Uint8Array(text.length);
for (let i = 0; i < text.length; i++) {
result[i] = text.charCodeAt(i) & 0xff;
}
return result;
}
function is(text) {
return typeof text === "string";
}
exports.binary = { encode, decode, is };
+229
View File
@@ -0,0 +1,229 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hex = exports.formats = void 0;
exports.normalize = normalize;
exports.is = is;
exports.encode = encode;
exports.decode = decode;
exports.parse = parse;
exports.format = format;
const index_js_1 = require("../bytes/index.js");
const HEX_CHARACTER_REGEX = /^[0-9a-f]$/i;
const COMMON_SEPARATORS = [" ", "\t", "\n", "\r", ":", "-", "."];
function resolveSeparators(options) {
if (options.separators === "none") {
return [];
}
if (!options.separators || options.separators === "common") {
return COMMON_SEPARATORS;
}
return options.separators;
}
function validateSeparator(separator) {
if (!separator) {
throw new TypeError("Hex separators must be non-empty strings");
}
}
function matchSeparator(text, index, separators) {
for (const separator of separators) {
if (text.startsWith(separator, index)) {
return separator;
}
}
return undefined;
}
function detectCase(text) {
const hasUpper = /[A-F]/.test(text);
const hasLower = /[a-f]/.test(text);
return hasUpper && !hasLower ? "upper" : "lower";
}
function detectLineSeparator(text) {
const match = /\r\n|\n/.exec(text);
if (!match) {
return undefined;
}
return match[0] === "\r\n" ? "\r\n" : "\n";
}
function compactForDetection(text) {
return text.replace(/[^0-9a-f]/gi, "");
}
function detectGroup(text) {
const segments = text.match(/[0-9A-Fa-f]+|[^0-9A-Fa-f]+/g) ?? [];
if (segments.length < 3) {
return undefined;
}
const hexSegments = segments.filter((_, index) => index % 2 === 0);
const separators = segments.filter((_, index) => index % 2 === 1);
const separator = separators[0];
if (!separator || separators.some((item) => item !== separator)) {
return undefined;
}
if (hexSegments.some((segment) => segment.length === 0 || segment.length % 2 !== 0)) {
return undefined;
}
const firstLength = hexSegments[0]?.length ?? 0;
if (!firstLength) {
return undefined;
}
if (hexSegments.slice(0, -1).some((segment) => segment.length !== firstLength)) {
return undefined;
}
if ((hexSegments[hexSegments.length - 1]?.length ?? 0) > firstLength) {
return undefined;
}
return {
size: firstLength / 2,
separator,
};
}
function detectFormat(text) {
const trimmed = text.trim();
const prefix = /^0x/i.test(trimmed) ? "0x" : "";
const body = prefix ? trimmed.slice(2) : trimmed;
const lineSeparator = detectLineSeparator(body);
const lines = body.split(/\r\n|\n/).filter((line) => line.length > 0);
const sampleLine = lines[0]?.trim() ?? "";
const group = detectGroup(sampleLine);
const format = {
case: detectCase(trimmed),
prefix,
};
if (group) {
format.group = group;
}
if (lineSeparator && lines.length > 1) {
const firstLineBytes = compactForDetection(lines[0] ?? "").length / 2;
if (firstLineBytes > 0 && lines.slice(0, -1).every((line) => compactForDetection(line).length / 2 === firstLineBytes)) {
format.line = {
bytesPerLine: firstLineBytes,
separator: lineSeparator,
};
}
}
return format;
}
function normalizeText(text, options) {
const allowPrefix = options.allowPrefix ?? true;
const separators = [...resolveSeparators(options)].sort((left, right) => right.length - left.length);
for (const separator of separators) {
validateSeparator(separator);
}
let working = text.trim();
if (/^0x/i.test(working)) {
if (!allowPrefix) {
throw new TypeError("Hexadecimal text must not include a 0x prefix");
}
working = working.slice(2);
}
let normalized = "";
let lastTokenWasSeparator = false;
for (let index = 0; index < working.length;) {
const character = working[index] ?? "";
if (HEX_CHARACTER_REGEX.test(character)) {
normalized += character;
lastTokenWasSeparator = false;
index += 1;
continue;
}
const separator = matchSeparator(working, index, separators);
if (!separator) {
throw new TypeError("Input is not valid hexadecimal text");
}
if (options.strict && (lastTokenWasSeparator || normalized.length === 0)) {
throw new TypeError("Hexadecimal text contains misplaced separators");
}
lastTokenWasSeparator = true;
index += separator.length;
}
if (options.strict && lastTokenWasSeparator && normalized.length > 0) {
throw new TypeError("Hexadecimal text must not end with a separator");
}
if (normalized.length % 2 !== 0) {
if (!options.allowOddLength) {
throw new TypeError("Hexadecimal text must contain an even number of characters");
}
normalized = `0${normalized}`;
}
return normalized.toLowerCase();
}
function groupPairs(pairs, group) {
if (!group) {
return pairs.join("");
}
if (!Number.isInteger(group.size) || group.size < 1) {
throw new RangeError("Hex group size must be a positive integer");
}
const chunks = [];
for (let index = 0; index < pairs.length; index += group.size) {
chunks.push(pairs.slice(index, index + group.size).join(""));
}
return chunks.join(group.separator);
}
function normalize(text, options = {}) {
return normalizeText(text, options);
}
function is(text, options = {}) {
if (typeof text !== "string") {
return false;
}
try {
normalize(text, options);
return true;
}
catch {
return false;
}
}
function encode(data, options = {}) {
const bytes = (0, index_js_1.toUint8Array)(data);
const casing = options.case ?? "lower";
const pairs = Array.from(bytes, (byte) => {
const text = byte.toString(16).padStart(2, "0");
return casing === "upper" ? text.toUpperCase() : text;
});
let body = "";
if (options.line) {
const bytesPerLine = options.line.bytesPerLine;
if (!Number.isInteger(bytesPerLine) || bytesPerLine < 1) {
throw new RangeError("Hex bytesPerLine must be a positive integer");
}
const separator = options.line.separator ?? "\n";
const lines = [];
for (let index = 0; index < pairs.length; index += bytesPerLine) {
lines.push(groupPairs(pairs.slice(index, index + bytesPerLine), options.group));
}
body = lines.join(separator);
}
else {
body = groupPairs(pairs, options.group);
}
return `${options.prefix ?? ""}${body}`;
}
function decode(text, options = {}) {
const normalized = normalize(text, options);
const result = new Uint8Array(normalized.length / 2);
for (let i = 0; i < normalized.length; i += 2) {
result[i / 2] = Number.parseInt(normalized.slice(i, i + 2), 16);
}
return result;
}
function parse(text, options = {}) {
const normalized = normalize(text, options);
return {
bytes: decode(normalized),
format: detectFormat(text),
normalized,
};
}
function format(data, value) {
return encode(data, value);
}
exports.formats = {
compact: Object.freeze({}),
upper: Object.freeze({ case: "upper" }),
colon: Object.freeze({ group: { size: 1, separator: ":" } }),
colonUpper: Object.freeze({ case: "upper", group: { size: 1, separator: ":" } }),
groupsOf4: Object.freeze({ group: { size: 4, separator: " " } }),
prefixed: Object.freeze({ prefix: "0x" }),
};
exports.hex = { encode, decode, format, formats: exports.formats, is, normalize, parse };
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.base64url = exports.base64 = exports.utf16 = exports.utf8 = exports.hex = exports.binary = void 0;
const tslib_1 = require("tslib");
exports.binary = tslib_1.__importStar(require("./binary.js"));
exports.hex = tslib_1.__importStar(require("./hex.js"));
exports.utf8 = tslib_1.__importStar(require("./utf8.js"));
exports.utf16 = tslib_1.__importStar(require("./utf16.js"));
exports.base64 = tslib_1.__importStar(require("./base64.js"));
exports.base64url = tslib_1.__importStar(require("./base64url.js"));
+24
View File
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.utf16 = void 0;
exports.encode = encode;
exports.decode = decode;
const index_js_1 = require("../bytes/index.js");
function encode(text, options = {}) {
const result = new ArrayBuffer(text.length * 2);
const view = new DataView(result);
for (let i = 0; i < text.length; i++) {
view.setUint16(i * 2, text.charCodeAt(i), options.littleEndian ?? false);
}
return new Uint8Array(result);
}
function decode(data, options = {}) {
const buffer = (0, index_js_1.toArrayBuffer)(data);
const view = new DataView(buffer);
let result = "";
for (let i = 0; i < buffer.byteLength; i += 2) {
result += String.fromCharCode(view.getUint16(i, options.littleEndian ?? false));
}
return result;
}
exports.utf16 = { encode, decode };
+13
View File
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.utf8 = void 0;
exports.encode = encode;
exports.decode = decode;
const index_js_1 = require("../bytes/index.js");
function encode(text) {
return new TextEncoder().encode(text);
}
function decode(data) {
return new TextDecoder("utf-8", { fatal: false }).decode((0, index_js_1.toUint8Array)(data));
}
exports.utf8 = { encode, decode };
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bytes = void 0;
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./bytes/index.js"), exports);
exports.bytes = tslib_1.__importStar(require("./bytes/index.js"));
tslib_1.__exportStar(require("./encoding/index.js"), exports);
tslib_1.__exportStar(require("./pem/index.js"), exports);
tslib_1.__exportStar(require("./converters/index.js"), exports);
tslib_1.__exportStar(require("./legacy/index.js"), exports);
@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BufferSourceConverter = void 0;
const index_js_1 = require("../bytes/index.js");
class BufferSourceConverter {
static isArrayBuffer(data) {
return (0, index_js_1.isArrayBuffer)(data);
}
static toArrayBuffer(data) {
return (0, index_js_1.toArrayBuffer)(data);
}
static toUint8Array(data) {
return (0, index_js_1.toUint8Array)(data);
}
static toView(data, type) {
return (0, index_js_1.toView)(data, type);
}
static isBufferSource(data) {
return (0, index_js_1.isBufferSource)(data);
}
static isArrayBufferView(data) {
return (0, index_js_1.isArrayBufferView)(data);
}
static isEqual(a, b) {
return (0, index_js_1.equal)(a, b);
}
static concat(first, second, ...rest) {
if (Array.isArray(first)) {
return typeof second === "function"
? (0, index_js_1.concat)(first, second)
: (0, index_js_1.concat)(first);
}
const buffers = [first, second, ...rest].filter(Boolean);
return (0, index_js_1.concat)(buffers);
}
}
exports.BufferSourceConverter = BufferSourceConverter;
+72
View File
@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Convert = void 0;
const index_js_1 = require("../converters/index.js");
function normalizeTextEncoding(encoding) {
return encoding === "ascii" ? "binary" : encoding;
}
class Convert {
static DEFAULT_UTF8_ENCODING = "utf8";
static isHex(data) {
return index_js_1.convert.isHex(data);
}
static isBase64(data) {
return index_js_1.convert.isBase64(data);
}
static isBase64Url(data) {
return index_js_1.convert.isBase64Url(data);
}
static ToString(buffer, enc = "utf8") {
return index_js_1.convert.toString(buffer, enc);
}
static FromString(str, enc = "utf8") {
if (!str) {
return new ArrayBuffer(0);
}
return index_js_1.convert.fromString(str, enc);
}
static ToBase64(buffer) {
return index_js_1.convert.toBase64(buffer);
}
static FromBase64(base64) {
return index_js_1.convert.fromBase64(base64);
}
static FromBase64Url(base64url) {
return index_js_1.convert.fromBase64Url(base64url);
}
static ToBase64Url(data) {
return index_js_1.convert.toBase64Url(data);
}
static FromUtf8String(text, encoding = Convert.DEFAULT_UTF8_ENCODING) {
return index_js_1.convert.fromString(text, normalizeTextEncoding(encoding));
}
static ToUtf8String(buffer, encoding = Convert.DEFAULT_UTF8_ENCODING) {
return index_js_1.convert.toString(buffer, normalizeTextEncoding(encoding));
}
static FromBinary(text) {
return index_js_1.convert.fromBinary(text);
}
static ToBinary(buffer) {
return index_js_1.convert.toBinary(buffer);
}
static ToHex(buffer) {
return index_js_1.convert.toHex(buffer);
}
static FromHex(hexString) {
return index_js_1.convert.fromHex(hexString);
}
static ToUtf16String(buffer, littleEndian = false) {
return index_js_1.convert.toUtf16String(buffer, littleEndian);
}
static FromUtf16String(text, littleEndian = false) {
return index_js_1.convert.fromUtf16String(text, littleEndian);
}
static Base64Padding(base64) {
const padCount = 4 - (base64.length % 4);
return padCount < 4 ? base64 + "=".repeat(padCount) : base64;
}
static formatString(data) {
return index_js_1.convert.formatString(data);
}
}
exports.Convert = Convert;
+23
View File
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.assign = assign;
exports.combine = combine;
exports.isEqual = isEqual;
const index_js_1 = require("../bytes/index.js");
function assign(target, ...sources) {
for (const source of sources) {
if (!source) {
continue;
}
for (const prop in source) {
target[prop] = source[prop];
}
}
return target;
}
function combine(...buf) {
return (0, index_js_1.concat)(buf);
}
function isEqual(bytes1, bytes2) {
return (0, index_js_1.equal)(bytes1, bytes2);
}
+11
View File
@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isEqual = exports.combine = exports.assign = exports.Convert = exports.BufferSourceConverter = void 0;
var buffer_source_converter_js_1 = require("./buffer-source-converter.js");
Object.defineProperty(exports, "BufferSourceConverter", { enumerable: true, get: function () { return buffer_source_converter_js_1.BufferSourceConverter; } });
var convert_js_1 = require("./convert.js");
Object.defineProperty(exports, "Convert", { enumerable: true, get: function () { return convert_js_1.Convert; } });
var functions_js_1 = require("./functions.js");
Object.defineProperty(exports, "assign", { enumerable: true, get: function () { return functions_js_1.assign; } });
Object.defineProperty(exports, "combine", { enumerable: true, get: function () { return functions_js_1.combine; } });
Object.defineProperty(exports, "isEqual", { enumerable: true, get: function () { return functions_js_1.isEqual; } });