@wuapi/essential
Version:
Essential definition of WU-API
664 lines (663 loc) • 20.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.$Project = exports.$Module = exports.$Entity = exports.$EntityType = exports.$Field = exports.$TSSMap = exports.$TString = exports.$TBoolean = exports.$TDateTime = exports.$TURL = exports.$TID = exports.$TDouble = exports.$TLong = exports.$TInteger = exports.$TUnknown = exports.$TList = exports.$TEnum = exports.$TObject = exports.$FieldType = exports.$Enum = exports.$EnumItem = exports.$ElementPath = exports.$ReqMethod = exports.$Commentable = void 0;
const util_1 = require("./util");
/**
* Parent of classes that have comment.
*/
class $Commentable {
constructor() {
/**
* The comment
*/
this.comment = "";
/**
* The configuration map of this field.
*/
this.config = null;
}
}
exports.$Commentable = $Commentable;
var $ReqMethod;
(function ($ReqMethod) {
// HTTP
$ReqMethod[$ReqMethod["GET"] = 0] = "GET";
$ReqMethod[$ReqMethod["HEAD"] = 1] = "HEAD";
$ReqMethod[$ReqMethod["POST"] = 2] = "POST";
$ReqMethod[$ReqMethod["PUT"] = 3] = "PUT";
$ReqMethod[$ReqMethod["DELETE"] = 4] = "DELETE";
$ReqMethod[$ReqMethod["CONNECT"] = 5] = "CONNECT";
$ReqMethod[$ReqMethod["OPTIONS"] = 6] = "OPTIONS";
$ReqMethod[$ReqMethod["TRACE"] = 7] = "TRACE";
$ReqMethod[$ReqMethod["PATCH"] = 8] = "PATCH";
// SOCKET or MQTT
$ReqMethod[$ReqMethod["SOCKET"] = 9] = "SOCKET";
$ReqMethod[$ReqMethod["MQTT"] = 10] = "MQTT";
})($ReqMethod = exports.$ReqMethod || (exports.$ReqMethod = {}));
/**
* A class to represent an element (entity or enumeration) path
* inside a project.
*/
class $ElementPath {
/**
* Constructor of ElementPath
* @param module The module name
* @param name The element name
*/
constructor(module, name) {
this.module = module;
this.name = name;
}
/**
* Compare with another ElementPath object
* @param another Another ElementPath object.
* @returns true if the other is identitcal to this ElementPath, false otherwise.
*/
equals(another) {
if (!another)
return false;
return another.module == this.module && another.name == this.name;
}
/**
* Returns the entity in the project, designated by the path.
* @param project The project where to find the Entity.
* @returns The entity found.
*/
asEntityOf(project) {
if (!project)
return null;
if (this.module == null || this.name == null)
return null;
return project.modules[this.module]?.entities[this.name] ?? null;
}
/**
* Returns the enumeration in the project, designated by the path.
* @param project The project where to find the Entity.
* @returns The enumeration found.
*/
asEnumOf(project) {
if (!project)
return null;
if (this.module == null || this.name == null)
return null;
return project.modules[this.module]?.enums[this.name] ?? null;
}
/**
* Create $ElementPath instance from json data.
* @param data Json data
* @returns The $ElementPath instance
*/
static load(data) {
return new $ElementPath(data.module ?? null, data.name ?? null);
}
}
exports.$ElementPath = $ElementPath;
/**
* Item of enumeration entity.
*/
class $EnumItem extends $Commentable {
/**
* The constructor of enumeration item.
* @param value The number id of the item.
*/
constructor(value) {
super();
this.value = value;
/**
* The real (json) name may differ from the display name.
* For example, the json name may violet forbidden key rules.
*/
this.realname = null;
}
/**
* Create $EnumItem instance from json data.
* @param data Json data
* @returns The $EnumItem instance
*/
static load(data) {
if (!(0, util_1.notNU)(data.value))
return null;
const item = new $EnumItem(data.value);
item.comment = data.comment ?? "";
item.config = data.config;
item.realname = data.realname ?? null;
return item;
}
}
exports.$EnumItem = $EnumItem;
/**
* Enumeration entity.
*/
class $Enum extends $Commentable {
constructor() {
super(...arguments);
/**
* Map of string names to enum items.
*/
this.enumMap = {};
}
/**
* Get the first item.
* @returns The first item (by number value) of this Enumeration
*/
first() {
const k = this.firstName();
return null == k ? null : this.enumMap[k];
}
/**
* Get the name of the first item.
* @returns The name of the first (by number value) item of this Enumeration.
*/
firstName() {
var i = null;
var k = null;
for (const key in this.enumMap) {
const item = this.enumMap[key];
if (i == null || item.value < i) {
i = item.value;
k = key;
}
}
// return k == null ? null : this.enumMap[k]
return k;
}
/**
* Flat an enumeration's items.
* @returns List of name, item. Order is not defined.
*/
flat() {
let result = [];
(0, util_1.forIn)(this.enumMap, (item, name) => {
result.push({
name,
item,
});
});
return result;
}
/**
* Create $Enum instance from json data.
* @param data Json data
* @returns The $Enum instance
*/
static load(data) {
if (!(0, util_1.notNU)(data.enumMap))
return null;
const enu = new $Enum();
enu.comment = data.comment ?? "";
enu.config = data.config;
for (let i in data.enumMap) {
const item = $EnumItem.load(data.enumMap[i]);
if ((0, util_1.notNU)(item)) {
enu.enumMap[i] = item;
}
}
return enu;
}
}
exports.$Enum = $Enum;
/**
* The entity field type.
*/
class $FieldType {
/**
* Constructor of FieldType
* @param type The name of this type
*/
constructor(type) {
this.type = type;
}
/**
* Check if this type equals with another.
* @param another Another type, or null
* @returns true if this type is the same with another type
*/
equals(another) {
if (!another)
return false;
if (another.type != this.type)
return false;
switch (this.type) {
case 'TObject': {
const _self = this;
const _other = another;
return _self?.entity?.equals(_other?.entity) == true;
}
case 'TEnum': {
const _self = this;
const _other = another;
return _self?.enu?.equals(_other?.enu) == true;
}
case 'TUnknown': {
const _self = this;
const _other = another;
return _self?.unknown == _other?.unknown;
}
case 'TList': {
const _self = this;
const _other = another;
return _self?.member?.equals(_other?.member);
}
default: {
return true;
}
}
}
/**
* Check if this type equals with another.
* If the other field type is list, check it's member.
*
* @param another Another type, or null
* @returns true if this type is the same with another type
*/
equalsEvenInList(another) {
if (this.type == 'TList')
throw "List field shall not use quealsInList!";
if (!(0, util_1.notNU)(another))
return false;
if (another?.type == 'TList') {
return this.equalsEvenInList(another.member);
}
else {
return this.equals(another);
}
}
/**
* Create $FieldType instance from json data.
* @param data Json data
* @returns The $FieldType instance
*/
static load(data) {
if (!(0, util_1.notNU)(data.type))
return null;
switch (data.type) {
case 'TInteger': return new $TInteger();
case 'TLong': return new $TLong();
case 'TDouble': return new $TDouble();
case 'TID': return new $TID();
case 'TURL': return new $TURL();
case 'TDateTime': return new $TDateTime();
case 'TBoolean': return new $TBoolean();
case 'TString': return new $TString();
case 'TSSMap': return new $TSSMap();
case 'TObject': {
if (!(0, util_1.notNU)(data.entity))
return null;
const path = $ElementPath.load(data.entity);
if (!(0, util_1.notNU)(path))
return null;
return new $TObject(path);
}
case 'TEnum': {
if (!(0, util_1.notNU)(data.enu))
return null;
const path = $ElementPath.load(data.enu);
if (!(0, util_1.notNU)(path))
return null;
return new $TEnum(path);
}
case 'TList': {
if (!(0, util_1.notNU)(data.member))
return null;
const member = $FieldType.load(data.member);
if (!(0, util_1.notNU)(member))
return null;
return new $TList(member);
}
case 'TUnknown': {
if (!(0, util_1.notNU)(data.unknown))
return null;
return new $TUnknown(data.unknown);
}
default: return null;
}
}
}
exports.$FieldType = $FieldType;
class $TObject extends $FieldType {
constructor(entity) {
super('TObject');
this.entity = entity;
}
}
exports.$TObject = $TObject;
class $TEnum extends $FieldType {
constructor(enu) {
super('TEnum');
this.enu = enu;
}
}
exports.$TEnum = $TEnum;
class $TList extends $FieldType {
constructor(member) {
super('TList');
this.member = member;
}
}
exports.$TList = $TList;
class $TUnknown extends $FieldType {
constructor(unknown) {
super('TUnknown');
this.unknown = unknown;
}
}
exports.$TUnknown = $TUnknown;
class $TInteger extends $FieldType {
constructor() { super('TInteger'); }
}
exports.$TInteger = $TInteger;
class $TLong extends $FieldType {
constructor() { super('TLong'); }
}
exports.$TLong = $TLong;
class $TDouble extends $FieldType {
constructor() { super('TDouble'); }
}
exports.$TDouble = $TDouble;
class $TID extends $FieldType {
constructor() { super('TID'); }
}
exports.$TID = $TID;
class $TURL extends $FieldType {
constructor() { super('TURL'); }
}
exports.$TURL = $TURL;
class $TDateTime extends $FieldType {
constructor() { super('TDateTime'); }
}
exports.$TDateTime = $TDateTime;
class $TBoolean extends $FieldType {
constructor() { super('TBoolean'); }
}
exports.$TBoolean = $TBoolean;
class $TString extends $FieldType {
constructor() { super('TString'); }
}
exports.$TString = $TString;
class $TSSMap extends $FieldType {
constructor() { super('TSSMap'); }
}
exports.$TSSMap = $TSSMap;
/**
* The entity field.
*/
class $Field extends $Commentable {
/**
* Constructor of Entity Field.
* @param type The type of this field
*/
constructor(type) {
super();
this.type = type;
/**
* The real (json) name may differ from the display name.
* For example, the json name may violet forbidden key rules.
*/
this.realname = null;
/**
* True if this field is optional
*/
this.isOptional = false;
/**
* True if this field would appear inside path.
*/
this.isPathParameter = false;
/**
* The optional fixed value of this field.
*/
this.fixedValue = null;
}
/**
* Create $Field instance from json data.
* @param data Json data
* @returns The $Field instance
*/
static load(data) {
if (!(0, util_1.notNU)(data.type, data.isOptional, data.isPathParameter))
return null;
const filedType = $FieldType.load(data.type);
if (!(0, util_1.notNU)(filedType))
return null;
const field = new $Field(filedType);
field.comment = data.comment ?? "";
field.config = data.config;
field.realname = data.realname ?? null;
field.isOptional = data.isOptional;
field.isPathParameter = data.isPathParameter;
field.fixedValue = data.fixedValue;
field.config = data.config;
return field;
}
}
exports.$Field = $Field;
/**
* Type of entities.
*/
var $EntityType;
(function ($EntityType) {
$EntityType[$EntityType["OBJECT"] = 0] = "OBJECT";
$EntityType[$EntityType["REQUEST"] = 1] = "REQUEST";
$EntityType[$EntityType["RESPONSE"] = 2] = "RESPONSE";
})($EntityType = exports.$EntityType || (exports.$EntityType = {}));
/**
* Entity
*/
class $Entity extends $Commentable {
/**
* List of generic parameters defined inside current entity.
* (no generic from parent)
*/
getGenericLocal() {
let result = [];
for (let k in this.fieldsLocal) {
const field = this.fieldsLocal[k];
if (field.type.type == 'TUnknown') {
result.push(field.type.unknown);
}
}
return result;
}
/**
* Return a list of names of generics that are unsolved until this entity.
* @param project The project, from where to get generic unsolved.
* @returns A list of names of unsolved generics.
*/
getGenericUnsolved(project) {
if (!project)
return [];
let pg = this.parent?.asEntityOf(project)?.getGenericUnsolved(project) ?? [];
pg = pg.concat(this.getGenericLocal());
return pg.filter((o) => !this.genericMap[o]);
}
/**
* Traverse from the eldest ancestor all down to this entity.
* @param project The project from where to traverse.
* @param block The callback function
*/
fromAncestorToMe(project, block) {
this.parent?.asEntityOf(project)?.fromAncestorToMe(project, block);
block(this);
}
/**
* Constructor of Entity class.
* @param type The type of this entity
*/
constructor(type = $EntityType.OBJECT) {
super();
this.type = type;
/**
* True if this entity is abstract (shall not instantiate)
*/
this.isAbstract = false;
/**
* The path of the parent entity, optional.
*/
this.parent = null;
/**
* The path of corresponding response entity, if this entity is a request.
*/
this.response = null;
/**
* The URL path, if this entity is a request.
*/
this.path = null;
/**
* The Request method, if this entity is a request.
*/
this.method = null;
/**
* List of fields defined inside current entity.
* (no field from parent)
*/
this.fieldsLocal = {};
/**
* The map of definitions of generic parameters, till this entity.
*/
this.genericMap = {};
}
/**
* Create $Entity instance from json data.
* @param data Json data
* @returns The $Entity instance
*/
static load(data) {
if (!(0, util_1.notNU)(data.type, data.isAbstract, data.fieldsLocal, data.genericMap))
return null;
const entity = new $Entity(data.type); // enum as number
entity.comment = data.comment ?? "";
entity.config = data.config;
entity.isAbstract = data.isAbstract;
entity.path = data.path ?? null;
entity.method = data.method ?? null; // enum as number
if ((0, util_1.notNU)(data.parent)) {
entity.parent = $ElementPath.load(data.parent);
}
if ((0, util_1.notNU)(data.response)) {
entity.response = $ElementPath.load(data.response);
}
for (let i in data.fieldsLocal) {
const field = $Field.load(data.fieldsLocal[i]);
if ((0, util_1.notNU)(field)) {
entity.fieldsLocal[i] = field;
}
}
for (let i in data.genericMap) {
const field = $Field.load(data.genericMap[i]);
if ((0, util_1.notNU)(field)) {
entity.genericMap[i] = field;
}
}
return entity;
}
}
exports.$Entity = $Entity;
/**
* The module object
*/
class $Module {
constructor() {
/**
* The map of entities inside this module.
*/
this.entities = {};
/**
* The map of enumerations inside this module.
*/
this.enums = {};
}
/**
* Create $Module instance from json data.
* @param data Json data
* @returns The $Module instance
*/
static load(data) {
if (!(0, util_1.notNU)(data.entities, data.enums))
return null;
const module = new $Module();
for (let i in data.entities) {
const entity = $Entity.load(data.entities[i]);
if ((0, util_1.notNU)(entity)) {
module.entities[i] = entity;
}
}
for (let i in data.enums) {
const enu = $Enum.load(data.enums[i]);
if ((0, util_1.notNU)(enu)) {
module.enums[i] = enu;
}
}
return module;
}
}
exports.$Module = $Module;
/**
* The project object
*/
class $Project {
/**
* The constructor of entity project.
* @param name The name of the project
* @param version The version of the project
* @param targetPackage The package (for Java & Kotlin) into which the entities
* will be generated
*/
constructor(name, version, targetPackage) {
this.name = name;
this.version = version;
this.targetPackage = targetPackage;
/**
* The map of modules.
*/
this.modules = {};
}
/**
* Flat the project into list of entities.
* @returns list of path, entity. Order is not defined!
*/
flatEntities() {
let result = [];
(0, util_1.forIn)(this.modules, (moduleInstance, module) => {
(0, util_1.forIn)(moduleInstance.entities, (entityInstance, name) => {
result.push({
path: new $ElementPath(module, name),
entity: entityInstance
});
});
});
return result;
}
/**
* Flat the project into list of enumerations.
* @returns list of path, enumerations. Order is not defined!
*/
flatEnums() {
let result = [];
(0, util_1.forIn)(this.modules, (moduleInstance, module) => {
(0, util_1.forIn)(moduleInstance.enums, (enumInstance, name) => {
result.push({
path: new $ElementPath(module, name),
enu: enumInstance
});
});
});
return result;
}
/**
* Create $Project instance from json data.
* @param data Json object
* @returns Generated $Project instance.
*/
static load(data) {
if (!(0, util_1.notNU)(data.name, data.version, data.targetPackage, data.modules))
return null;
const project = new $Project(data.name, data.version, data.targetPackage);
for (let i in data.modules) {
const module = $Module.load(data.modules[i]);
if ((0, util_1.notNU)(module)) {
project.modules[i] = module;
}
}
return project;
}
}
exports.$Project = $Project;