package js/d.ts
This commit is contained in:
parent
4afb0e8e27
commit
0c9b2778c5
32 changed files with 955 additions and 2 deletions
12
dist/case.d.ts
vendored
Normal file
12
dist/case.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export declare const CaseConvention: Readonly<{
|
||||||
|
readonly Lowercase: 0;
|
||||||
|
readonly Uppercase: 1;
|
||||||
|
readonly PascalCase: 2;
|
||||||
|
readonly CamelCase: 3;
|
||||||
|
readonly SnakeCase: 4;
|
||||||
|
readonly ScreamingSnakeCase: 5;
|
||||||
|
readonly KebabCase: 6;
|
||||||
|
readonly ScreamingKebabCase: 7;
|
||||||
|
}>;
|
||||||
|
export type CaseConvention = typeof CaseConvention[keyof typeof CaseConvention];
|
||||||
|
export declare function convertCase(value: string, convention: CaseConvention): string;
|
56
dist/case.js
vendored
Normal file
56
dist/case.js
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.CaseConvention = void 0;
|
||||||
|
exports.convertCase = convertCase;
|
||||||
|
exports.CaseConvention = Object.freeze({
|
||||||
|
Lowercase: 0,
|
||||||
|
Uppercase: 1,
|
||||||
|
PascalCase: 2,
|
||||||
|
CamelCase: 3,
|
||||||
|
SnakeCase: 4,
|
||||||
|
ScreamingSnakeCase: 5,
|
||||||
|
KebabCase: 6,
|
||||||
|
ScreamingKebabCase: 7
|
||||||
|
});
|
||||||
|
const wordBoundaryRegex = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g;
|
||||||
|
function identifyWords(value) {
|
||||||
|
return value && value.match(wordBoundaryRegex);
|
||||||
|
}
|
||||||
|
const lower = (ch) => ch.toLowerCase();
|
||||||
|
const upper = (ch) => ch.toUpperCase();
|
||||||
|
const first = (xs) => xs && xs[0];
|
||||||
|
const tail = (xs) => xs && xs.slice(1);
|
||||||
|
function upperFirst(xs) {
|
||||||
|
return upper(first(xs)) + tail(xs);
|
||||||
|
}
|
||||||
|
function toPascalCase(words) {
|
||||||
|
return words.map(lower).map(upperFirst).join('');
|
||||||
|
}
|
||||||
|
const joinMap = (fn, delim, xs) => {
|
||||||
|
return xs.map(fn).join(delim);
|
||||||
|
};
|
||||||
|
function convertCase(value, convention) {
|
||||||
|
const words = identifyWords(value);
|
||||||
|
if (!words || words.length <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
switch (convention) {
|
||||||
|
case exports.CaseConvention.Lowercase:
|
||||||
|
return words.join('').toLowerCase();
|
||||||
|
case exports.CaseConvention.Uppercase:
|
||||||
|
return words.join('').toUpperCase();
|
||||||
|
case exports.CaseConvention.PascalCase:
|
||||||
|
return toPascalCase(words);
|
||||||
|
case exports.CaseConvention.CamelCase:
|
||||||
|
const pascal = toPascalCase(words);
|
||||||
|
return first(pascal).toLowerCase() + tail(pascal);
|
||||||
|
case exports.CaseConvention.SnakeCase:
|
||||||
|
return joinMap(lower, '_', words);
|
||||||
|
case exports.CaseConvention.ScreamingSnakeCase:
|
||||||
|
return joinMap(upper, '_', words);
|
||||||
|
case exports.CaseConvention.KebabCase:
|
||||||
|
return joinMap(lower, '-', words);
|
||||||
|
case exports.CaseConvention.ScreamingKebabCase:
|
||||||
|
return joinMap(upper, '-', words);
|
||||||
|
}
|
||||||
|
}
|
15
dist/de/generic.d.ts
vendored
Normal file
15
dist/de/generic.d.ts
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Deserialize, Deserializer, IterableAccess, MapAccess, Visitor } from './interface';
|
||||||
|
export declare class GenericSeed<T> implements Deserialize<T> {
|
||||||
|
static deserialize<T, D extends Deserializer>(deserializer: D): T;
|
||||||
|
deserialize<D extends Deserializer>(deserializer: D): T;
|
||||||
|
}
|
||||||
|
export declare class GenericVisitor<T> implements Visitor<T> {
|
||||||
|
visitString(value: string): T;
|
||||||
|
visitNumber(value: number): T;
|
||||||
|
visitBigInt(value: bigint): T;
|
||||||
|
visitBoolean(value: boolean): T;
|
||||||
|
visitSymbol(value: symbol): T;
|
||||||
|
visitNull(): T;
|
||||||
|
visitObject(access: MapAccess): T;
|
||||||
|
visitIterable(access: IterableAccess): T;
|
||||||
|
}
|
60
dist/de/generic.js
vendored
Normal file
60
dist/de/generic.js
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
"use strict";
|
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||||
|
};
|
||||||
|
var GenericSeed_1;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.GenericVisitor = exports.GenericSeed = void 0;
|
||||||
|
const utils_1 = require("../utils");
|
||||||
|
let GenericSeed = GenericSeed_1 = class GenericSeed {
|
||||||
|
static deserialize(deserializer) {
|
||||||
|
return deserializer.deserializeAny(new GenericVisitor());
|
||||||
|
}
|
||||||
|
deserialize(deserializer) {
|
||||||
|
return GenericSeed_1.deserialize(deserializer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.GenericSeed = GenericSeed;
|
||||||
|
exports.GenericSeed = GenericSeed = GenericSeed_1 = __decorate([
|
||||||
|
(0, utils_1.staticImplements)()
|
||||||
|
], GenericSeed);
|
||||||
|
class GenericVisitor {
|
||||||
|
visitString(value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
visitNumber(value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
visitBigInt(value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
visitBoolean(value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
visitSymbol(value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
visitNull() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
visitObject(access) {
|
||||||
|
const result = {};
|
||||||
|
let entry;
|
||||||
|
while ((entry = access.nextEntry())) {
|
||||||
|
result[entry[0]] = entry[1];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
visitIterable(access) {
|
||||||
|
const result = new Array(access.sizeHint());
|
||||||
|
let element;
|
||||||
|
while ((element = access.nextElement())) {
|
||||||
|
result.push(element);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.GenericVisitor = GenericVisitor;
|
7
dist/de/impl.d.ts
vendored
Normal file
7
dist/de/impl.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { SerdeOptions } from '../options';
|
||||||
|
import { Deserialize, Deserializer } from './interface';
|
||||||
|
type DeserializeConstructor<T> = Deserialize<T> & {
|
||||||
|
new (): Deserialize<T>;
|
||||||
|
};
|
||||||
|
export declare function deserializeWith<T, D extends Deserializer, E extends DeserializeConstructor<T>>(deserializer: D, into: E, options: SerdeOptions): T;
|
||||||
|
export {};
|
21
dist/de/impl.js
vendored
Normal file
21
dist/de/impl.js
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.deserializeWith = deserializeWith;
|
||||||
|
const options_1 = require("../options");
|
||||||
|
const generic_1 = require("./generic");
|
||||||
|
function deserializeWith(deserializer, into, options) {
|
||||||
|
const visitor = new generic_1.GenericVisitor();
|
||||||
|
const obj = deserializer.deserializeObject(visitor);
|
||||||
|
const target = new into();
|
||||||
|
const newObject = {};
|
||||||
|
for (const property in target) {
|
||||||
|
const name = options.getPropertyName(property, options_1.Stage.Deserialize);
|
||||||
|
const value = obj[name] || options.getDefault(property);
|
||||||
|
newObject[property] = value;
|
||||||
|
delete obj[name];
|
||||||
|
}
|
||||||
|
if (options.options.denyUnknownFields && Object.keys(obj).length > 0) {
|
||||||
|
throw new TypeError(`Unexpected fields: ${Object.keys(obj).join(', ')}`);
|
||||||
|
}
|
||||||
|
return Object.assign(target, newObject);
|
||||||
|
}
|
3
dist/de/index.d.ts
vendored
Normal file
3
dist/de/index.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export * from './interface';
|
||||||
|
export * from './generic';
|
||||||
|
export * from './mixin';
|
19
dist/de/index.js
vendored
Normal file
19
dist/de/index.js
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
__exportStar(require("./interface"), exports);
|
||||||
|
__exportStar(require("./generic"), exports);
|
||||||
|
__exportStar(require("./mixin"), exports);
|
52
dist/de/interface.d.ts
vendored
Normal file
52
dist/de/interface.d.ts
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import { Nullable } from '../utils';
|
||||||
|
export interface MapAccess {
|
||||||
|
nextKeySeed<T, K extends Deserialize<T>>(seed: K): Nullable<T>;
|
||||||
|
nextValueSeed<T, V extends Deserialize<T>>(seed: V): Nullable<T>;
|
||||||
|
nextEntrySeed<TK, TV, K extends Deserialize<TK>, V extends Deserialize<TV>>(kseed: K, vseed: V): Nullable<[TK, TV]>;
|
||||||
|
nextKey<T>(): Nullable<T>;
|
||||||
|
nextValue<T>(): Nullable<T>;
|
||||||
|
nextEntry<K, V>(): Nullable<[K, V]>;
|
||||||
|
}
|
||||||
|
export declare abstract class DefaultMapAccessImpl implements MapAccess {
|
||||||
|
abstract nextKeySeed<T, K extends Deserialize<T>>(seed: K): Nullable<T>;
|
||||||
|
abstract nextValueSeed<T, V extends Deserialize<T>>(seed: V): Nullable<T>;
|
||||||
|
nextEntrySeed<TK, TV, K extends Deserialize<TK>, V extends Deserialize<TV>>(kseed: K, vseed: V): Nullable<[TK, TV]>;
|
||||||
|
nextKey<T>(): Nullable<T>;
|
||||||
|
nextValue<T>(): Nullable<T>;
|
||||||
|
nextEntry<K, V>(): Nullable<[K, V]>;
|
||||||
|
}
|
||||||
|
export interface IterableAccess {
|
||||||
|
nextElementSeed<T, I extends Deserialize<T>>(seed: I): Nullable<T>;
|
||||||
|
nextElement<T>(): Nullable<T>;
|
||||||
|
sizeHint(): number;
|
||||||
|
}
|
||||||
|
export declare abstract class DefaultIterableAccessImpl implements IterableAccess {
|
||||||
|
abstract nextElementSeed<T, I extends Deserialize<T>>(seed: I): Nullable<T>;
|
||||||
|
nextElement<T>(): Nullable<T>;
|
||||||
|
sizeHint(): number;
|
||||||
|
}
|
||||||
|
export interface Visitor<T> {
|
||||||
|
visitString(value: string): T;
|
||||||
|
visitNumber(value: number): T;
|
||||||
|
visitBigInt(value: bigint): T;
|
||||||
|
visitBoolean(value: boolean): T;
|
||||||
|
visitSymbol(value: symbol): T;
|
||||||
|
visitNull(): T;
|
||||||
|
visitObject(value: MapAccess): T;
|
||||||
|
visitIterable?(value: IterableAccess): T;
|
||||||
|
}
|
||||||
|
export interface Deserializer {
|
||||||
|
deserializeAny<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeString<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeNumber<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeBigInt<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeBoolean<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeNull<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeObject<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
deserializeClass<T, V extends Visitor<T>>(name: string, fields: string[], visitor: V): T;
|
||||||
|
deserializeIterable<T, V extends Visitor<T>>(visitor: V): T;
|
||||||
|
}
|
||||||
|
export interface Deserialize<T> {
|
||||||
|
deserialize<D extends Deserializer>(deserializer: D): T;
|
||||||
|
}
|
32
dist/de/interface.js
vendored
Normal file
32
dist/de/interface.js
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.DefaultIterableAccessImpl = exports.DefaultMapAccessImpl = void 0;
|
||||||
|
const generic_1 = require("./generic");
|
||||||
|
class DefaultMapAccessImpl {
|
||||||
|
nextEntrySeed(kseed, vseed) {
|
||||||
|
const key = this.nextKeySeed(kseed);
|
||||||
|
if (key !== undefined) {
|
||||||
|
const value = this.nextValueSeed(vseed);
|
||||||
|
if (value !== undefined) {
|
||||||
|
return [key, value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextKey() {
|
||||||
|
return this.nextValueSeed((generic_1.GenericSeed));
|
||||||
|
}
|
||||||
|
nextValue() {
|
||||||
|
return this.nextValueSeed((generic_1.GenericSeed));
|
||||||
|
}
|
||||||
|
nextEntry() {
|
||||||
|
return this.nextEntrySeed((generic_1.GenericSeed), (generic_1.GenericSeed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.DefaultMapAccessImpl = DefaultMapAccessImpl;
|
||||||
|
class DefaultIterableAccessImpl {
|
||||||
|
nextElement() {
|
||||||
|
return this.nextElementSeed((generic_1.GenericSeed));
|
||||||
|
}
|
||||||
|
sizeHint() { return 0; }
|
||||||
|
}
|
||||||
|
exports.DefaultIterableAccessImpl = DefaultIterableAccessImpl;
|
9
dist/de/mixin.d.ts
vendored
Normal file
9
dist/de/mixin.d.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { Constructor } from '../utils';
|
||||||
|
import { Deserializer } from './interface';
|
||||||
|
export declare function deserialize<T, C extends Constructor>(constructor: C): {
|
||||||
|
new (...args: any[]): {
|
||||||
|
[x: string]: any;
|
||||||
|
};
|
||||||
|
name: string;
|
||||||
|
deserialize<D extends Deserializer>(deserializer: D): T;
|
||||||
|
} & C;
|
31
dist/de/mixin.js
vendored
Normal file
31
dist/de/mixin.js
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
"use strict";
|
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.deserialize = deserialize;
|
||||||
|
const decorator_1 = require("../decorator");
|
||||||
|
const utils_1 = require("../utils");
|
||||||
|
const impl_1 = require("./impl");
|
||||||
|
function deserialize(constructor) {
|
||||||
|
let Deserializable = class Deserializable extends constructor {
|
||||||
|
static deserialize(deserializer) {
|
||||||
|
return (0, impl_1.deserializeWith)(deserializer, this, (0, decorator_1.getMetadata)(this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.defineProperty(Deserializable, "name", {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
value: constructor.name
|
||||||
|
});
|
||||||
|
Deserializable = __decorate([
|
||||||
|
(0, utils_1.staticImplements)()
|
||||||
|
], Deserializable);
|
||||||
|
// @ts-ignore
|
||||||
|
Deserializable[decorator_1.Serde] = constructor[decorator_1.Serde];
|
||||||
|
return Deserializable;
|
||||||
|
}
|
6
dist/decorator.d.ts
vendored
Normal file
6
dist/decorator.d.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { ContainerOptions, PropertyOptions } from './options';
|
||||||
|
import { Registry } from './registry';
|
||||||
|
export declare const Serde: unique symbol;
|
||||||
|
export declare function serde(options: ContainerOptions | PropertyOptions): (target: any, property?: PropertyKey) => any;
|
||||||
|
export declare function getMetadata(value: any): any;
|
||||||
|
export declare function register(registry?: Registry): (target: any) => any;
|
54
dist/decorator.js
vendored
Normal file
54
dist/decorator.js
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.Serde = void 0;
|
||||||
|
exports.serde = serde;
|
||||||
|
exports.getMetadata = getMetadata;
|
||||||
|
exports.register = register;
|
||||||
|
const options_1 = require("./options");
|
||||||
|
const registry_1 = require("./registry");
|
||||||
|
exports.Serde = Symbol('Serde');
|
||||||
|
function decorateContainer(options, constructor) {
|
||||||
|
if (constructor[exports.Serde] == null) {
|
||||||
|
constructor[exports.Serde] = new options_1.SerdeOptions(constructor, options);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
constructor[exports.Serde].options = options;
|
||||||
|
}
|
||||||
|
return constructor;
|
||||||
|
}
|
||||||
|
function decorateProperty(options, target, property) {
|
||||||
|
let constructor;
|
||||||
|
if (typeof target === 'function') {
|
||||||
|
constructor = target;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
constructor = target.constructor;
|
||||||
|
}
|
||||||
|
if (constructor[exports.Serde] == null) {
|
||||||
|
constructor[exports.Serde] = options_1.SerdeOptions.from(target);
|
||||||
|
}
|
||||||
|
constructor[exports.Serde].properties.set(property, options);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
function serde(options) {
|
||||||
|
return function (target, property) {
|
||||||
|
if (property != null) {
|
||||||
|
return decorateProperty(options, target, property);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return decorateContainer(options, target);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getMetadata(value) {
|
||||||
|
return value[exports.Serde];
|
||||||
|
}
|
||||||
|
function register(registry = registry_1.GlobalRegistry) {
|
||||||
|
return function (target) {
|
||||||
|
if (target[exports.Serde] == null) {
|
||||||
|
target[exports.Serde] = options_1.SerdeOptions.from(target);
|
||||||
|
}
|
||||||
|
registry.add(target);
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
}
|
6
dist/index.d.ts
vendored
Normal file
6
dist/index.d.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export * as ser from './ser/index';
|
||||||
|
export * as de from './de/index';
|
||||||
|
export * from './case';
|
||||||
|
export * from './registry';
|
||||||
|
export * from './decorator';
|
||||||
|
export * from './options';
|
45
dist/index.js
vendored
Normal file
45
dist/index.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || (function () {
|
||||||
|
var ownKeys = function(o) {
|
||||||
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||||
|
var ar = [];
|
||||||
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||||
|
return ar;
|
||||||
|
};
|
||||||
|
return ownKeys(o);
|
||||||
|
};
|
||||||
|
return function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.de = exports.ser = void 0;
|
||||||
|
exports.ser = __importStar(require("./ser/index"));
|
||||||
|
exports.de = __importStar(require("./de/index"));
|
||||||
|
__exportStar(require("./case"), exports);
|
||||||
|
__exportStar(require("./registry"), exports);
|
||||||
|
__exportStar(require("./decorator"), exports);
|
||||||
|
__exportStar(require("./options"), exports);
|
63
dist/options.d.ts
vendored
Normal file
63
dist/options.d.ts
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import { CaseConvention } from './case';
|
||||||
|
import { Deserializer } from './de';
|
||||||
|
import { Serializer } from './ser';
|
||||||
|
import { Registry } from './registry';
|
||||||
|
export interface RenameOptions {
|
||||||
|
serialize?: string;
|
||||||
|
deserialize?: string;
|
||||||
|
}
|
||||||
|
export interface RenameAllOptions {
|
||||||
|
serialize?: CaseConvention;
|
||||||
|
deserialize?: CaseConvention;
|
||||||
|
}
|
||||||
|
export interface ContainerOptions {
|
||||||
|
default?: () => any;
|
||||||
|
denyUnknownFields?: boolean;
|
||||||
|
expecting?: string;
|
||||||
|
rename?: RenameOptions | string;
|
||||||
|
renameAll?: RenameAllOptions | CaseConvention;
|
||||||
|
registry?: Registry;
|
||||||
|
tag?: string;
|
||||||
|
content?: string;
|
||||||
|
untagged?: boolean;
|
||||||
|
}
|
||||||
|
export interface ConditionalSkipOptions {
|
||||||
|
if: (value: any) => boolean;
|
||||||
|
}
|
||||||
|
export interface SkipOptions {
|
||||||
|
serializing?: ConditionalSkipOptions | boolean;
|
||||||
|
deserializing?: ConditionalSkipOptions | boolean;
|
||||||
|
}
|
||||||
|
export type CustomSerializer = <T, V, S extends Serializer<T>>(value: V, serializer: S) => T;
|
||||||
|
export type CustomDeserializer = <T, D extends Deserializer>(deserializer: D) => T;
|
||||||
|
export interface PropertyOptions {
|
||||||
|
alias?: string;
|
||||||
|
default?: () => any;
|
||||||
|
flatten?: boolean;
|
||||||
|
rename?: RenameOptions | string;
|
||||||
|
skip?: SkipOptions | ConditionalSkipOptions | boolean;
|
||||||
|
}
|
||||||
|
export declare const Stage: Readonly<{
|
||||||
|
readonly Serialize: 0;
|
||||||
|
readonly Deserialize: 1;
|
||||||
|
}>;
|
||||||
|
export type Stage = typeof Stage[keyof typeof Stage];
|
||||||
|
export declare class SerdeOptions {
|
||||||
|
private readonly target;
|
||||||
|
readonly options: ContainerOptions;
|
||||||
|
readonly properties: Map<string, PropertyOptions>;
|
||||||
|
get registry(): Registry;
|
||||||
|
constructor(target: any, options?: ContainerOptions, properties?: Map<string, PropertyOptions>);
|
||||||
|
static from(target: any): SerdeOptions;
|
||||||
|
getClassName(stage: Stage): any;
|
||||||
|
private getPropertyRename;
|
||||||
|
private getPropertyCase;
|
||||||
|
getPropertyName(property: string, stage: Stage): string;
|
||||||
|
getSerializationName(property: string): string;
|
||||||
|
getDeserializationName(property: string): string;
|
||||||
|
getDefault(property: string): any;
|
||||||
|
private isConditionalSkip;
|
||||||
|
shouldSkip(property: string, value: any, stage: Stage): boolean;
|
||||||
|
shouldSkipSerializing(property: string, value: any): boolean;
|
||||||
|
shouldSkipDeserializing(property: string, value: any): boolean;
|
||||||
|
}
|
156
dist/options.js
vendored
Normal file
156
dist/options.js
vendored
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.SerdeOptions = exports.Stage = void 0;
|
||||||
|
const case_1 = require("./case");
|
||||||
|
const utils_1 = require("./utils");
|
||||||
|
const registry_1 = require("./registry");
|
||||||
|
exports.Stage = Object.freeze({
|
||||||
|
Serialize: 0,
|
||||||
|
Deserialize: 1
|
||||||
|
});
|
||||||
|
class SerdeOptions {
|
||||||
|
get registry() {
|
||||||
|
return this.options.registry || registry_1.GlobalRegistry;
|
||||||
|
}
|
||||||
|
constructor(target, options = {}, properties = new Map()) {
|
||||||
|
Object.defineProperty(this, "target", {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
Object.defineProperty(this, "options", {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
Object.defineProperty(this, "properties", {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
this.target = target;
|
||||||
|
this.options = options;
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
static from(target) {
|
||||||
|
return new this(target);
|
||||||
|
}
|
||||||
|
getClassName(stage) {
|
||||||
|
var _a, _b;
|
||||||
|
if ((0, utils_1.isString)(this.options.rename)) {
|
||||||
|
return this.options.rename;
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Serialize && (0, utils_1.isString)((_a = this.options.rename) === null || _a === void 0 ? void 0 : _a.serialize)) {
|
||||||
|
return this.options.rename.serialize;
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Deserialize && (0, utils_1.isString)((_b = this.options.rename) === null || _b === void 0 ? void 0 : _b.deserialize)) {
|
||||||
|
return this.options.rename.deserialize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return this.target.constructor.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getPropertyRename(property, stage, options) {
|
||||||
|
var _a, _b;
|
||||||
|
if (options != null) {
|
||||||
|
if ((0, utils_1.isString)(options.rename)) {
|
||||||
|
return options.rename;
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Serialize && (0, utils_1.isString)((_a = options.rename) === null || _a === void 0 ? void 0 : _a.serialize)) {
|
||||||
|
return options.rename.serialize;
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Deserialize && (0, utils_1.isString)((_b = options.rename) === null || _b === void 0 ? void 0 : _b.deserialize)) {
|
||||||
|
return options.rename.deserialize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
getPropertyCase(name, stage) {
|
||||||
|
var _a, _b;
|
||||||
|
if ((0, utils_1.isNumber)(this.options.renameAll)) {
|
||||||
|
return (0, case_1.convertCase)(name, this.options.renameAll);
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Serialize && (0, utils_1.isNumber)((_a = this.options.renameAll) === null || _a === void 0 ? void 0 : _a.serialize)) {
|
||||||
|
return (0, case_1.convertCase)(name, this.options.renameAll.serialize);
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Deserialize && (0, utils_1.isNumber)((_b = this.options.renameAll) === null || _b === void 0 ? void 0 : _b.deserialize)) {
|
||||||
|
return (0, case_1.convertCase)(name, this.options.renameAll.deserialize);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getPropertyName(property, stage) {
|
||||||
|
const options = this.properties.get(property);
|
||||||
|
const name = options != null ? this.getPropertyRename(property, stage, options) : property;
|
||||||
|
return this.getPropertyCase(name, stage);
|
||||||
|
}
|
||||||
|
getSerializationName(property) {
|
||||||
|
return this.getPropertyName(property, exports.Stage.Serialize);
|
||||||
|
}
|
||||||
|
getDeserializationName(property) {
|
||||||
|
return this.getPropertyName(property, exports.Stage.Deserialize);
|
||||||
|
}
|
||||||
|
getDefault(property) {
|
||||||
|
const options = this.properties.get(property);
|
||||||
|
if (options && (0, utils_1.isFunction)(options.default)) {
|
||||||
|
return options.default();
|
||||||
|
}
|
||||||
|
else if ((0, utils_1.isFunction)(this.options.default)) {
|
||||||
|
return this.options.default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//getCustomImpl(property: string, stage: Stage) {
|
||||||
|
// const options = this.properties.get(property)
|
||||||
|
// if (options != null) {
|
||||||
|
// if (stage === Stage.Serialize && isFunction(options.serializeWith)) {
|
||||||
|
// return options.serializeWith
|
||||||
|
// } else if (stage === Stage.Deserialize && isFunction(options.deserializeWith)) {
|
||||||
|
// return options.deserializeWith
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//getSerializer(property: string): Nullable<CustomSerializer> {
|
||||||
|
// return this.getCustomImpl(property, Stage.Serialize) as CustomSerializer
|
||||||
|
//}
|
||||||
|
//getDeserializer(property: string): Nullable<CustomDeserializer> {
|
||||||
|
// return this.getCustomImpl(property, Stage.Deserialize) as CustomDeserializer
|
||||||
|
//}
|
||||||
|
isConditionalSkip(skip) {
|
||||||
|
return 'if' in skip && (0, utils_1.isFunction)(skip.if);
|
||||||
|
}
|
||||||
|
shouldSkip(property, value, stage) {
|
||||||
|
const options = this.properties.get(property);
|
||||||
|
if (options != null && options.skip != null) {
|
||||||
|
if (typeof options.skip === 'boolean') {
|
||||||
|
return options.skip;
|
||||||
|
}
|
||||||
|
else if (this.isConditionalSkip(options.skip)) {
|
||||||
|
return options.skip.if(value);
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Serialize && typeof options.skip.serializing === 'boolean') {
|
||||||
|
return options.skip.serializing;
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Serialize && this.isConditionalSkip(options.skip.serializing)) {
|
||||||
|
return options.skip.serializing.if(value);
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Deserialize && typeof options.skip.deserializing === 'boolean') {
|
||||||
|
return options.skip.deserializing;
|
||||||
|
}
|
||||||
|
else if (stage === exports.Stage.Deserialize && this.isConditionalSkip(options.skip.deserializing)) {
|
||||||
|
return options.skip.deserializing.if(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
shouldSkipSerializing(property, value) {
|
||||||
|
return this.shouldSkip(property, value, exports.Stage.Serialize);
|
||||||
|
}
|
||||||
|
shouldSkipDeserializing(property, value) {
|
||||||
|
return this.shouldSkip(property, value, exports.Stage.Deserialize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.SerdeOptions = SerdeOptions;
|
7
dist/registry.d.ts
vendored
Normal file
7
dist/registry.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { Constructor } from './utils';
|
||||||
|
export declare class Registry {
|
||||||
|
registeredClasses: Map<string, Constructor>;
|
||||||
|
add(ctor: Constructor, key?: string): void;
|
||||||
|
get(name: string): Constructor | undefined;
|
||||||
|
}
|
||||||
|
export declare const GlobalRegistry: Registry;
|
21
dist/registry.js
vendored
Normal file
21
dist/registry.js
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.GlobalRegistry = exports.Registry = void 0;
|
||||||
|
class Registry {
|
||||||
|
constructor() {
|
||||||
|
Object.defineProperty(this, "registeredClasses", {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
value: new Map()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
add(ctor, key = ctor.name) {
|
||||||
|
this.registeredClasses.set(key, ctor);
|
||||||
|
}
|
||||||
|
get(name) {
|
||||||
|
return this.registeredClasses.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Registry = Registry;
|
||||||
|
exports.GlobalRegistry = new Registry();
|
4
dist/ser/impl.d.ts
vendored
Normal file
4
dist/ser/impl.d.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { Serializable, Serializer } from './interface';
|
||||||
|
import { SerdeOptions } from '../options';
|
||||||
|
import { Nullable } from '../utils';
|
||||||
|
export declare function serializeWith<T>(serializer: Serializer<T>, value: Serializable, optionsGetter?: (value: any) => Nullable<SerdeOptions>): Nullable<T>;
|
64
dist/ser/impl.js
vendored
Normal file
64
dist/ser/impl.js
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.serializeWith = serializeWith;
|
||||||
|
const decorator_1 = require("../decorator");
|
||||||
|
const options_1 = require("../options");
|
||||||
|
const utils_1 = require("../utils");
|
||||||
|
const unhandledType = (serializer, value) => new TypeError(`'${serializer.constructor.name}' has no method for value type '${typeof value}'`);
|
||||||
|
function serializeEntries(serializer, value, options) {
|
||||||
|
var _a;
|
||||||
|
let state;
|
||||||
|
for (const [key, val] of value) {
|
||||||
|
if (options === null || options === void 0 ? void 0 : options.shouldSkipSerializing(key, val)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const name = (_a = options === null || options === void 0 ? void 0 : options.getPropertyName(key, options_1.Stage.Serialize)) !== null && _a !== void 0 ? _a : key;
|
||||||
|
console.log('prop name for', key, name);
|
||||||
|
state = serializer.serializeKey(name);
|
||||||
|
state = serializer.serializeValue(val);
|
||||||
|
}
|
||||||
|
return serializer.end();
|
||||||
|
}
|
||||||
|
function serializeClass(serializer, value, options) {
|
||||||
|
const classSerializer = serializer.serializeClass(value.constructor.name);
|
||||||
|
return serializeEntries(classSerializer, Object.entries(value), options);
|
||||||
|
}
|
||||||
|
function serializeObject(serializer, value, options) {
|
||||||
|
return serializeEntries(serializer.serializeObject(), Object.entries(value), options);
|
||||||
|
}
|
||||||
|
function serializeIter(serializer, value, options) {
|
||||||
|
let state;
|
||||||
|
for (const val of value) {
|
||||||
|
state = serializer.serializeElement(val);
|
||||||
|
}
|
||||||
|
return serializer.end();
|
||||||
|
}
|
||||||
|
function defaultOptions(value) {
|
||||||
|
return value.constructor[decorator_1.Serde];
|
||||||
|
}
|
||||||
|
// dispatches in the order of serializeType -> serializeAny -> throw TypeError
|
||||||
|
function serializeWith(serializer, value, optionsGetter = defaultOptions) {
|
||||||
|
// prepare fallback methods
|
||||||
|
const serializeAny = (0, utils_1.orElse)(serializer, serializer.serializeAny, (value) => unhandledType(serializer, value));
|
||||||
|
const serialize = (0, utils_1.ifNull)(serializer, serializeAny, value);
|
||||||
|
switch (typeof value) {
|
||||||
|
case 'string': return serialize(serializer.serializeString);
|
||||||
|
case 'number': return serialize(serializer.serializeNumber);
|
||||||
|
case 'bigint': return serialize(serializer.serializeBigInt);
|
||||||
|
case 'boolean': return serialize(serializer.serializeBoolean);
|
||||||
|
case 'symbol': return serialize(serializer.serializeSymbol);
|
||||||
|
case 'undefined': return serialize(serializer.serializeNull);
|
||||||
|
case 'object':
|
||||||
|
const options = optionsGetter(value);
|
||||||
|
if ((0, utils_1.isIterable)(value) && (0, utils_1.isFunction)(serializer.serializeIterable)) {
|
||||||
|
return serializeIter(serializer.serializeIterable(), value, options);
|
||||||
|
}
|
||||||
|
if (!(0, utils_1.isPlainObject)(value)) {
|
||||||
|
return serializeClass(serializer, value, options);
|
||||||
|
}
|
||||||
|
else if ((0, utils_1.isFunction)(serializer.serializeObject)) {
|
||||||
|
return serializeObject(serializer, value, options);
|
||||||
|
} // deliberate fallthrough when the above fail
|
||||||
|
default: return serializeAny(value);
|
||||||
|
}
|
||||||
|
}
|
3
dist/ser/index.d.ts
vendored
Normal file
3
dist/ser/index.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export * from './interface';
|
||||||
|
export * from './mixin';
|
||||||
|
export * from './impl';
|
19
dist/ser/index.js
vendored
Normal file
19
dist/ser/index.js
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
__exportStar(require("./interface"), exports);
|
||||||
|
__exportStar(require("./mixin"), exports);
|
||||||
|
__exportStar(require("./impl"), exports);
|
31
dist/ser/interface.d.ts
vendored
Normal file
31
dist/ser/interface.d.ts
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { Primitive, ToString } from "../utils";
|
||||||
|
export interface ObjectSerializer<T = void> {
|
||||||
|
serializeKey<U extends Serializable>(key: U): T;
|
||||||
|
serializeValue<U extends Serializable>(value: U): T;
|
||||||
|
end(): T;
|
||||||
|
}
|
||||||
|
export interface IterableSerializer<T = void> {
|
||||||
|
serializeElement<U extends Serializable>(element: U): T;
|
||||||
|
end(): T;
|
||||||
|
}
|
||||||
|
interface TypeSerializer<T> {
|
||||||
|
serializeString(value: string): T;
|
||||||
|
serializeNumber(value: number): T;
|
||||||
|
serializeBigInt(value: bigint): T;
|
||||||
|
serializeBoolean(value: boolean): T;
|
||||||
|
serializeSymbol(value: Symbol): T;
|
||||||
|
serializeNull(): T;
|
||||||
|
serializeObject(): ObjectSerializer<T>;
|
||||||
|
serializeIterable?(): IterableSerializer<T>;
|
||||||
|
serializeClass(name: PropertyKey): ObjectSerializer<T>;
|
||||||
|
}
|
||||||
|
interface AnySerializer<T> {
|
||||||
|
serializeAny?(value?: any): T;
|
||||||
|
}
|
||||||
|
export declare function isGenericSerializer(value: any): boolean;
|
||||||
|
export type Serializer<T> = Partial<TypeSerializer<T>> & Partial<AnySerializer<T>>;
|
||||||
|
export type Serializable = Primitive | ToString | Serialize;
|
||||||
|
export interface Serialize {
|
||||||
|
serialize<T, S extends Serializer<T>>(serializer: S): T;
|
||||||
|
}
|
||||||
|
export {};
|
21
dist/ser/interface.js
vendored
Normal file
21
dist/ser/interface.js
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.isGenericSerializer = isGenericSerializer;
|
||||||
|
const utils_1 = require("../utils");
|
||||||
|
const TypeSerializerMethods = [
|
||||||
|
'serializeString',
|
||||||
|
'serializeNumber',
|
||||||
|
'serializeBigInt',
|
||||||
|
'serializeBoolean',
|
||||||
|
'serializeSymbol',
|
||||||
|
//'serializeMap',
|
||||||
|
'serializeIterable',
|
||||||
|
'serializeNull',
|
||||||
|
'serializeObject',
|
||||||
|
'serializeClass',
|
||||||
|
];
|
||||||
|
const AnySerializerMethods = ['serializeAny'];
|
||||||
|
function isGenericSerializer(value) {
|
||||||
|
return AnySerializerMethods.every(k => (0, utils_1.isFunction)(value[k])) &&
|
||||||
|
TypeSerializerMethods.every(k => !(0, utils_1.isFunction)(value[k]));
|
||||||
|
}
|
9
dist/ser/mixin.d.ts
vendored
Normal file
9
dist/ser/mixin.d.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { Constructor } from '../utils';
|
||||||
|
import { Serializer } from './interface';
|
||||||
|
export declare function serialize<T extends Constructor>(constructor: T): {
|
||||||
|
new (...args: any[]): {
|
||||||
|
[x: string]: any;
|
||||||
|
serialize<U>(serializer: Serializer<U>): U;
|
||||||
|
};
|
||||||
|
name: string;
|
||||||
|
} & T;
|
27
dist/ser/mixin.js
vendored
Normal file
27
dist/ser/mixin.js
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.serialize = serialize;
|
||||||
|
const decorator_1 = require("../decorator");
|
||||||
|
const impl_1 = require("./impl");
|
||||||
|
const interface_1 = require("./interface");
|
||||||
|
function serialize(constructor) {
|
||||||
|
class Serializable extends constructor {
|
||||||
|
serialize(serializer) {
|
||||||
|
// shortcut for serializers with only the serializeAny method
|
||||||
|
if ((0, interface_1.isGenericSerializer)(serializer)) {
|
||||||
|
return serializer.serializeAny(this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (0, impl_1.serializeWith)(serializer, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object.defineProperty(Serializable, "name", {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
value: constructor.name
|
||||||
|
});
|
||||||
|
Serializable[decorator_1.Serde] = constructor[decorator_1.Serde];
|
||||||
|
return Serializable;
|
||||||
|
}
|
28
dist/utils.d.ts
vendored
Normal file
28
dist/utils.d.ts
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
export type Nullable<T> = T | undefined;
|
||||||
|
export interface Morphism<T = any, U = any> {
|
||||||
|
(value: T): U;
|
||||||
|
}
|
||||||
|
export type Primitive = string | number | boolean | symbol | bigint | null | undefined;
|
||||||
|
export interface ToString {
|
||||||
|
toString(): string;
|
||||||
|
}
|
||||||
|
export declare function staticImplements<T>(): <U extends T>(constructor: U) => void;
|
||||||
|
export declare function isPlainObject(value: any): boolean;
|
||||||
|
export declare function isFunction(value: any): value is Function;
|
||||||
|
export declare function isIterable(value: any): value is Iterable<any>;
|
||||||
|
export declare function isString(value: any): value is string;
|
||||||
|
export declare function isNumber(value: any): value is number;
|
||||||
|
export type Constructor<T = any> = new (...args: any[]) => T;
|
||||||
|
export declare function orElse(thisArg: any, a: Nullable<Function>, b: Function): (...args: any) => any;
|
||||||
|
export declare function ifNull(thisArg: any, b: Function, ...args: any): (a: Nullable<Function>) => any;
|
||||||
|
export declare function mixin<U = any>(impl: Function): <TBase extends Constructor<U>>(constructor: TBase) => TBase;
|
||||||
|
type AnyFunc = (...arg: any) => any;
|
||||||
|
type PipeArgs<F extends AnyFunc[], Acc extends AnyFunc[] = []> = F extends [
|
||||||
|
(...args: infer A) => infer B
|
||||||
|
] ? [...Acc, (...args: A) => B] : F extends [(...args: infer A) => any, ...infer Tail] ? Tail extends [(arg: infer B) => any, ...any[]] ? PipeArgs<Tail, [...Acc, (...args: A) => B]> : Acc : Acc;
|
||||||
|
type LastFnReturnType<F extends Array<AnyFunc>, Else = never> = F extends [
|
||||||
|
...any[],
|
||||||
|
(...arg: any) => infer R
|
||||||
|
] ? R : Else;
|
||||||
|
export declare function pipe<FirstFn extends AnyFunc, F extends AnyFunc[]>(arg: Parameters<FirstFn>[0], firstFn: FirstFn, ...fns: PipeArgs<F> extends F ? F : PipeArgs<F>): LastFnReturnType<F, ReturnType<FirstFn>>;
|
||||||
|
export {};
|
58
dist/utils.js
vendored
Normal file
58
dist/utils.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.staticImplements = staticImplements;
|
||||||
|
exports.isPlainObject = isPlainObject;
|
||||||
|
exports.isFunction = isFunction;
|
||||||
|
exports.isIterable = isIterable;
|
||||||
|
exports.isString = isString;
|
||||||
|
exports.isNumber = isNumber;
|
||||||
|
exports.orElse = orElse;
|
||||||
|
exports.ifNull = ifNull;
|
||||||
|
exports.mixin = mixin;
|
||||||
|
exports.pipe = pipe;
|
||||||
|
function staticImplements() {
|
||||||
|
return (constructor) => { constructor; };
|
||||||
|
}
|
||||||
|
function isPlainObject(value) {
|
||||||
|
return Object.getPrototypeOf(value) === Object.prototype;
|
||||||
|
}
|
||||||
|
function isFunction(value) {
|
||||||
|
return value != null && typeof value === 'function';
|
||||||
|
}
|
||||||
|
function isIterable(value) {
|
||||||
|
return isFunction(value[Symbol.iterator]);
|
||||||
|
}
|
||||||
|
function isString(value) {
|
||||||
|
return typeof value === 'string';
|
||||||
|
}
|
||||||
|
function isNumber(value) {
|
||||||
|
return !isNaN(value);
|
||||||
|
}
|
||||||
|
function orElse(thisArg, a, b) {
|
||||||
|
return function (...args) {
|
||||||
|
const fn = a != null ? a : b;
|
||||||
|
return fn.apply(thisArg, args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function ifNull(thisArg, b, ...args) {
|
||||||
|
return function (a) {
|
||||||
|
return orElse(thisArg, a, b).apply(thisArg, args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function applyMixins(derivedCtor, constructors) {
|
||||||
|
constructors.forEach((baseCtor) => {
|
||||||
|
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
|
||||||
|
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
|
||||||
|
Object.create(null));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function mixin(impl) {
|
||||||
|
return function (constructor) {
|
||||||
|
applyMixins(constructor, [impl]);
|
||||||
|
return constructor;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function pipe(arg, firstFn, ...fns) {
|
||||||
|
return fns.reduce((acc, fn) => fn(acc), firstFn(arg));
|
||||||
|
}
|
14
package.json
14
package.json
|
@ -3,6 +3,20 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"default": "src/index.ts"
|
||||||
|
},
|
||||||
|
"./ser": {
|
||||||
|
"types": "dist/ser/index.d.ts",
|
||||||
|
"default": "dist/ser/index.js"
|
||||||
|
},
|
||||||
|
"./de": {
|
||||||
|
"types": "dist/de/index.d.ts",
|
||||||
|
"default": "dist/de/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
|
|
@ -52,14 +52,14 @@
|
||||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||||
|
|
||||||
/* Emit */
|
/* Emit */
|
||||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
"outDir": "./dist/", /* Specify an output folder for all emitted files. */
|
||||||
// "removeComments": true, /* Disable emitting comments. */
|
// "removeComments": true, /* Disable emitting comments. */
|
||||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue