0.0.4 • Published 3 years ago

cold-cli v0.0.4

Weekly downloads
46
License
MIT
Repository
github
Last release
3 years ago

npm dependents Downloads

JSON defines ALL @.@

COLD-CLI is a Javascript tool for CrOss Language Domain Generation from a single JSON file. The lib help simplify the process when creating entity classes for different language. The single JSON file definition also help make the domain definition more consistent.

Currently supports: Java, JavaScript, Mongoose(Js)

Note: the project is still under constant development!

Table of content

Installation

  • Install the CLI tool globally
npm i -g cold-cli

Start CLI

  • Type coldx in the command line after installation of the cli package
coldx

Sample Project Structure

Here is a sample project structure for using the CLI tool. (ref: https://github.com/hongckh/cold-cli/tree/main/example)

.
+-- coldConfig.json
+-- definition
|   +-- config
    |   +-- java.json
    |   +-- javascript.json
    |   +-- typescript.json
|   +-- entities
    |   +-- domain.json

coldConfig.json

The CLI will look for a config file coldConfig.json upon initialization. You have to input the config file location. You may leave it blank if the coldConfig.json is your current directory.

# ? COLD-CLI config [coldConfig.json] directory (blank for current directory): <input the coldConfig.json path>

Config variables

variabledescriptionexample
libVergenerated lib version. Linked to pom and package.json0.0.1
target.baseDirthe base directory of the generated domain files./
target.javaDiroutput directory of Java domain filescold-common-lib-java
target.jsDiroutput directory of Javascript domain filescold-common-lib-js
target.mongooseDiroutput directory of Mongoose domain filescold-common-lib-mongoose
target.javaRefreshDirJava directory to be cleared per code generationsrc/main
target.jsRefreshDirJavascript directory to be cleared per code generationsrc/domain
target.mongooseRefreshDirMongoose directory to be cleared per code generationsrc/domain
definition.baseDirthe directory containing the config files./example/definition
definition.domainthe config file defining the domain entities./example/definition
definition.javathe Java config fileconfig/java.json
definition.javascriptthe Javascript config fileconfig/javascript.json
definition.typescriptthe Mongoose config fileconfig/typescript.json
commentBlockMaxCharPerLinethe max. character per line of comment80
indentationthe number of space as indentation4
logEnabledindicate if log is enabledtrue/false
logDirindicate log directory, enables log automatically if logEnabled is not set./

Sample coldConfig.json

{
    "libVer": "0.0.1",
    "target": {
        "baseDir": "../",
        "javaDir": "cold-common-lib",
        "javaRefreshDir": "src/main/java/com/cold/common/coldcommonlib/domain",
        "mongooseDir": "cold-common-lib-mongoose",
        "mongooseRefreshDir": "src/domain",
        "jsDir": "cold-common-lib-js",
        "jsRefreshDir": "src/domain"
    },
    "definition": {
        "baseDir": "./example/definition",
        "domain": "entities/domain.json",
        "java": "config/java.json",
        "javascript": "config/javascript.json",
        "typescript": "config/typescript.json"
    },
    "commentBlockMaxCharPerLine": 80,
    "indentation": 4,
    "logEnabled": true,
    "logDir": "logs"
}

Language based config

The CLI requires 3 language based config: java, javascript, and typescript.

Java config

The java config is mapped in coldConfig.json.definition.java.

Here are the key components of the java config.

keydesc
maventhe definition for generating pom.xml
dependencyMapdependency mapping for java import
annotateDefaultValdefault values of annotations

Java config - maven

  • Defines how the pom.xml will be generated.

  • Definition:

{
    "maven": {
        "project": {
            "@attribute": {
                "xmlns": "http://maven.apache.org/POM/4.0.0",
                "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
                "xsi:schemaLocation": "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
            },
            "modelVersion": "4.0.0",
            "parent": {
                "groupId": "org.springframework.boot",
                "artifactId": "spring-boot-starter-parent",
                "version": "2.3.0.RELEASE"
            },
            "groupId": "com.cold.common",
            "artifactId": "cold-common-lib",
            "version": "${libVer}",
            "name": "cold-common-lib",
            "description": "Cold Common Domain Java Lib Example"
        }
    }
}
  • Generated:
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.0.RELEASE</version>
  </parent>
  <groupId>com.cold.common</groupId>
  <artifactId>cold-common-lib</artifactId>
  <version>0.0.1</version>
  <name>cold-common-lib</name>
  <description>Cold Common Domain Java Lib Example</description>
</project>
  • The xml generation is based on the xmlbuilder package.
  • Any ${} (e.g. ${libVer}) in the json template will be replaced by the same config in coldConfig.json.

Java config - dependencyMap

  • Stores the dependency mapping for generated the required import ... string in java class.
  • For any annotation dependency @ will be the key-prefix. E.g. @Data
  • Example:
{
    "dependencyMap": {
        "@Data": "lombok.Data",
        "Set": "java.util.Set"
    }
}
  • Generated:
import lombok.Data;
import java.util.Set;
...
@Data
public class ... {
    ...
    private Set<String> ...
}

Java config - annotateDefaultVal

  • Defines the default value for each annotation if any.
  • Example:
{
    "annotateDefaultVal": {
        "EqualsAndHashCode": { "callSuper": true },
        "ToString": { "callSuper": true, "includeFieldNames": true },
        "JsonInclude": "JsonInclude.Include.NON_NULL"
    }
}
  • Generated:
...
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true, includeFieldNames = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ...

Javascript config

The javascript config is mapped in coldConfig.json.definition.javascript.

Here are the key components of the javascript config.

keydesc
packageJavascriptthe definition for generating javascript package.json
packageMongoosethe definition for generating mongoose package.json
javascriptTypeMapmapping for javascript type conversion
mongooseTypeMapmapping for mongoose type conversion
dependencyMapdefine dependency needed for specific type

Javascript config - packageJavascript / packageMongoose

  • Same as package.json

Javascript config - javascriptTypeMap / mongooseTypeMap

  • Type conversion mapping
  • Mapping example:
{
    "javascriptTypeMap": {
        "string": ["String", "ObjectId"]
    },
    "mongooseTypeMap": {
        "Schema.Types.ObjectId": "ObjectId"
    }
}
  • Generated
// javascript
...
export interface ... {
    id?: string;
    ...
}

// mongoose
... new Schema ({
    id: Schema.Types.ObjectId,
    ...
})

Javascript config - dependencyMap

  • Defines the import dependency for specific type
  • Example:
{
    "dependencyMap": {
        "Moment": "moment"
    }
}
  • Generated:
import { Moment } from 'moment';
...
export interface ... {
    lastUpdatedDate?: Moment;
}

Typescript config

The typescript config is mapped in coldConfig.json.definition.typescript.

Here are the key components of the typescript config.

keydesc
tsconfigthe definition for generating javascript tsconfig.json

Typescript config - tsconfig

  • Same as the tsconfig.json generated

Domain Definition

  • The domain definition is mapped in coldConfig.json.definition.domain.
  • The definition object types are mainly based on Java.

Class Definition

  • A class is defined as an object with "type": "obj". Object without this property will be treated as a directory / package.
  • Here are the 3 main components of a class:
keydesc
typeindicate the object is a class by "type": "obj"
attributesdefines the attributes of the class
propertiesdefines the class properties e.g. annotations and extension
  • Example:
{
    "packageA" : {
        "ClassA": {
            "type": "obj",
            "attributes": {
                "classAField": { "type": "boolean" }
            },
            "properties": {
                "annotate" : "Data"
            }
        }
    }

}
  • Generated java:
package com.cold.common.coldcommonlib.domain.packagea;

import lombok.Data;

@Data
public class ClassA {

    private boolean classAField;

    public ClassA classAField(boolean classAField) {
        this.classAField = classAField;
        return this;
    }

}
  • Generated javascript:
export interface IClassA {
    classAField?: boolean;
}

export class ClassA implements IClassA {
    constructor(
        public classAField?: boolean,
    ){}
}
  • Generated Mongoose:
import { Schema } from "mongoose";

const ClassASchema = new Schema ({
    classAField: Boolean,
});

export { ClassASchema };

Class Definition - attributes

  • The attributes key indicates the object storing the class attributes.
  • Here are the main components of an attribute object:
keydescexample
typetype of attribute"type": "String"
injectiontype of class for injecting into the attribute type"injection": "String"
annotateannotation of the attribute"annotate": "NotNull"
descdescription of the attribute"desc": "A short desc."

attributes obj - type
  • Java: directly write the same value
  • Javascript: base on the javascriptTypeMap
  • Mongoose: base on the mongooseTypeMap

attributes obj - injection
  • Inject the defined class into the attribute type.
  • Can be a string or an array
  • Example:
"ClassA": {
    "type": "obj",
    "attributes": {
        "classAField1": { "type": "List", "injection" : "String" },
        "classAField2": { "type": "Map", "injection" : [ "String", "String"] }
    },
    "properties": { "annotate" : "Data" }
}
  • Java:
...
@Data
public class ClassA {
    private List<String> classAField1;
    private Map<String,String> classAField2;
...
}
  • Javascript:
export interface IClassA {
    classAField1?: string[];
    classAField2?: Map<string,string>;
}

export class ClassA implements IClassA {
    constructor(
        public classAField1?: string[],
        public classAField2?: Map<string,string>,
    ){}
}
  • Mongoose:
const ClassASchema = new Schema ({
    classAField1: [ String ],
    classAField2: Map,
});

attributes obj - annotate
  • Annotation is mainly for java code generation.
  • It can be a string / an object / a array.
  • Example:
"attributes": {
    "classAField1": { "type": "String", "annotate" : "NotNull" },
    "classAField2": { "type": "String", "annotate": [
        { "NotNull" : { "message" : "custAcctId cannot be null" }},
        { "Length" : { "min" : 15, "max" : 15, "message" : "Invalid custAcctId" } }
    ]}
},
  • Generated Java:
@NotNull
private String classAField1;

@NotNull(message = "custAcctId cannot be null")
@Length(min = 15, max = 15, message = "Invalid custAcctId")
private String classAField2;

attributes obj - desc
  • Defines the comment of the attribute
  • Can be a string or an array of string
"classAField1": { "type": "String", "desc" : "a desc" },
"classAField2": { "type": "String", "desc": [ "desc line 1", "desc line 2" ]}
  • Generated desc:
/** a desc */
private String classAField1;

/**
 * desc line 1
 * desc line 2
*/
private String classAField2;

Class Definition - properties

  • The properties key indicates the object storing the class properties.
  • Here are the main components of an properties object:
keydescexample
classTypespecific type of class"classType": "ABSTRACT_CLASS"
extendsclass extended"extends": "ClassB"
injectiontype of class for injecting into the class"injection": "String"
annotateannotation of the attribute"annotate": "Data"
dependenciesspecific dependencies for import (java)"dependencies": "ToStringSerializer"
descdescription of the attribute"desc": "A short desc."

properties obj - classType
  • The classType is mainly for defining special class e.g. enumeration / java abstract class
classTypeclass
ABSTRACT_CLASSpublic abstract class
ENUMpublic enum

properties obj - extends
  • Defines the class to be extended
  • Example:
"extends" : "ClassB",
  • Generated java:
public class ClassA extends ClassB {...}
  • Generated javascript:
export interface IClassA extends IClassB {...}
  • Generated mongoose:
const ClassASchema = new Schema ({})

properties obj - injection
  • Defines the class to be injected
  • Example
"properties" : { "injection": "T" }
  • Generated java:
public class ClassA<T>
  • Generated javascript
export interface IClassA<T> {...}
  • Generated mongoose
const ClassASchema = new Schema ({...})

properties obj - annotate
  • Annotation is mainly for java code generation
  • Example:
"annotate" : [
    "Data",
    "EqualsAndHashCode",
    "ToString",
    "JsonInclude",
    { "Sharded" : "shardKey = { \"classAId\" }" },
    { "Document" : { "collection" : "collection_a" } },
    { "TypeName" : "\"ClassA\"" }
]
  • Generated Java:
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true, includeFieldNames = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Sharded(shardKey = { "classAId" })
@Document(collection = "collection_a")
@TypeName("ClassA")
public class ClassA extends ClassB {...}

properties obj - dependencies
  • Add specific import dependencies needed for the class
    • Will search the dependencyMap for the predefined import
  • Mainly for java code generation
  • Example:
"dependencies" : [ "ToStringSerializer" ]
  • Generated Java:
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

properties obj - desc
  • Same as the desc in the class attributes