diff --git a/README.md b/README.md index cabe72e..b102744 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,4 @@ Visit: https://jsonmaster.github.io - [Newtonsoft](https://www.newtonsoft.com/json/help/html/SerializingJSON.htm) - C# Class +4. **[X++](https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-ref/xpp-language-reference)** \ No newline at end of file diff --git a/css/style.css b/css/style.css index dfbb73d..a4a5236 100644 --- a/css/style.css +++ b/css/style.css @@ -1,13 +1,28 @@ -.form-font { - font-size: small; -} - -.CodeMirror { - border: 0px solid #eee; - height: auto; - min-height: 400px; - font-size: small; - line-height: inherit; -} - +.form-font { + font-size: small; +} + +.CodeMirror { + border: 0px solid #eee; + height: auto; + min-height: 400px; + font-size: small; + line-height: inherit; +} + +.form-control[class = 'form-control mr-sm-2']{ + display: block; + width: 100%; + height: calc(2.25rem + 2px); + padding: .375rem .75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff0; + background-clip: padding-box; + border: 1px solid #ced4da00; + border-radius: .25rem; + transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; +} + pre {-moz-tab-size: 4; tab-size: 4; display: block; padding: 0.5em; color: #333; background: #f8f8ff; border: 1px solid #ccc; border-radius: 4px; } \ No newline at end of file diff --git a/index.html b/index.html index 18d5c2c..68b3e2c 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - JSON Master: Generate Swift, Kotlin, Java, C# from JSON + JSON Master: Generate Swift, Kotlin, Java, C#, X++ from JSON @@ -112,6 +112,10 @@
+
+
+
+
diff --git a/languages/KotlinGson.json b/languages/KotlinGson.json index 97cdee8..5acbc7a 100644 --- a/languages/KotlinGson.json +++ b/languages/KotlinGson.json @@ -115,7 +115,8 @@ "modelDefinition": "\ndata class (\n) ", "fileExtension": "kt", - "codeForEachProperty": "\n\t\t@SerializedName(\"\") val : ", + "codeForEachProperty": "\n\t\t@SerializedName(\"\")\n\t\t : ", + "codeForEachPropertyOptional": "\n\t\t@SerializedName(\"\")\n\t\t : ?", "modelEnd": "}", "staticImports": "\nimport com.google.gson.annotations.SerializedName\nimport com.google.gson.Gson\nimport com.google.gson.GsonBuilder", "supportsCamelcasing": true, diff --git a/languages/KotlinMoshi.json b/languages/KotlinMoshi.json index 35fd734..f1b8ebe 100644 --- a/languages/KotlinMoshi.json +++ b/languages/KotlinMoshi.json @@ -115,7 +115,8 @@ "modelDefinition": "\ndata class (\n) ", "fileExtension": "kt", - "codeForEachProperty": "\n\t\t@Json(\"\") val : ", + "codeForEachProperty": "\n\t\t@Json(\"\")\n\t\t : ", + "codeForEachPropertyOptional": "\n\t\t@Json(\"\")\n\t\t : ?", "modelEnd": "}", "staticImports": "\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.Moshi\nimport com.squareup.moshi.JsonAdapter\nimport com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory", "supportsCamelcasing": true, diff --git a/languages/SwiftCodable.json b/languages/SwiftCodable.json index 13d594e..e4bfef7 100644 --- a/languages/SwiftCodable.json +++ b/languages/SwiftCodable.json @@ -98,41 +98,44 @@ "getter": "", "setter": "", "fileExtension": "swift", - "instanceVarDefinition": "\tlet : ?\n", + "instanceVarDefinition": "\t : \n", + "instanceVarDefinitionOptional": "\t : ?\n", "modelEnd": "\n}", "staticImports": "import Foundation", "supportsCamelcasing": true, "methods": { - "constructorName": "Initializer", - "constructorChecked": "checked", - "constructors": [{ - "signature": "\tprivate enum CodingKeys: String, CodingKey ", - "bodyStart": "{\n", - "bodyEnd": "\t}\n", - "codeForEachProperty": "\t\tcase = \"\"\n", - "comment": "" - },{ - "signature": "\tinit(from decoder: Decoder) throws ", - "bodyStart": "{\n\t\tlet values = try decoder.container(keyedBy: CodingKeys.self)\n", - "bodyEnd": "\t}\n", - "codeForEachProperty": "\t\t = try values.decodeIfPresent(.self, forKey: .)\n", - "codeForUndefinedProperty": "\t\t = nil // TODO: Add code for decoding ``, It was null at the time of model creation.\n", - "codeForUndefinedArrayProperty": "\t\t = [] // TODO: Add code for decoding ``, It was empty at the time of model creation.\n", - "comment": "" - }], "others": { + "condingKeys": { + "name": "CodingKeys", + "signature": "\tprivate enum CodingKeys: String, CodingKey ", + "bodyStart": "{\n", + "bodyEnd": "\t}\n", + "codeForEachProperty": "\t\tcase = \"\"\n", + "comment": "" + }, + "initializer": { + "name": "Initializer", + "signature": "\tinit(from decoder: Decoder) throws ", + "bodyStart": "{\n\t\tlet values = try decoder.container(keyedBy: CodingKeys.self)\n", + "bodyEnd": "\t}\n", + "codeForEachProperty": "\t\t = try values.decode(.self, forKey: .)\n", + "codeForEachPropertyOptional": "\t\t = try values.decodeIfPresent(.self, forKey: .)\n", + "codeForUndefinedProperty": "\t\t? = nil // TODO: Add code for decoding ``, It was null at the time of model creation.\n", + "codeForUndefinedArrayProperty": "\t\t = [] // TODO: Add code for decoding ``, It was empty at the time of model creation.\n", + "comment": "" + }, "encoder": { "name": "Encoding", "signature": "\tfunc encode(to encoder: Encoder) throws ", "bodyStart": "{\n\t\tvar container = encoder.container(keyedBy: CodingKeys.self)\n", "bodyEnd": "\t}\n", - "codeForEachProperty": "\t\ttry container.encodeIfPresent(, forKey: .)\n", + "codeForEachProperty": "\t\ttry container.encode(, forKey: .)\n", + "codeForEachPropertyOptional": "\t\ttry container.encodeIfPresent(, forKey: .)\n", "codeForUndefinedProperty": "\t\t// TODO: Add code for encoding ``, It was null at the time of model creation.\n", "codeForUndefinedArrayProperty": "\t\t// TODO: Add code for encoding ``, It was empty at the time of model creation.\n", - "comment": "", - "checked": "checked" + "comment": "" } } }, "exampleCode": "## Example\n\n\n#### Decoding:\nThe example below shows how to decode an instance of `` type from JSON object.\n\n```swift\nlet json = \"\"\"\n\n\"\"\".data(using: .utf8)!\n\nlet decoder = JSONDecoder()\nlet model = try decoder.decode(.self, json)\n```\n\n\n#### Encoding: \nThe example below shows how to encode an instance of a simple `` type into a JSON object.\n\n```swift\nlet model = ()\n// Assign value to properties.\n\nlet encoder = JSONEncoder()\nencoder.outputFormatting = .prettyPrinted\n\nlet data = try encoder.encode(model)\nprint(String(data: data, encoding: .utf8)!)\n```" -} \ No newline at end of file +} diff --git a/languages/SwiftDictionary.json b/languages/SwiftDictionary.json index 62f174c..932c47e 100644 --- a/languages/SwiftDictionary.json +++ b/languages/SwiftDictionary.json @@ -114,7 +114,7 @@ "getter": "", "setter": "", "fileExtension": "swift", - "instanceVarDefinition": "\tlet : ?\n", + "instanceVarDefinition": "\t : ?\n", "modelEnd": "\n}", "staticImports": "import Foundation", "supportsCamelcasing": true, diff --git a/languages/SwiftyJSON.json b/languages/SwiftyJSON.json index d39af9f..3234598 100644 --- a/languages/SwiftyJSON.json +++ b/languages/SwiftyJSON.json @@ -114,7 +114,7 @@ "getter": "", "setter": "", "fileExtension": "swift", - "instanceVarDefinition": "\tlet : ?\n", + "instanceVarDefinition": "\t : ?\n", "modelEnd": "\n}", "staticImports": "import Foundation\nimport SwiftyJSON", "supportsCamelcasing": true, diff --git a/languages/xppJSON.json b/languages/xppJSON.json new file mode 100644 index 0000000..62000ef --- /dev/null +++ b/languages/xppJSON.json @@ -0,0 +1,115 @@ +{ + "modelStart": "\n{", + "reservedKeywords": [ + "abstract", + "as", + "base", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "checked", + "class", + "const", + "continue", + "real", + "default", + "delegate", + "do", + "double", + "else", + "enum", + "event", + "explicit", + "extern", + "false", + "finally", + "fixed", + "float", + "for", + "foreach", + "goto", + "if", + "implicit", + "in", + "int", + "interface", + "internal", + "is", + "lock", + "long", + "namespace", + "new", + "null", + "object", + "operator", + "out", + "override", + "params", + "private", + "protected", + "public", + "readonly", + "ref", + "return", + "sbyte", + "sealed", + "short", + "sizeof", + "stackalloc", + "static", + "str", + "struct", + "switch", + "this", + "throw", + "true", + "try", + "typeof", + "uint", + "ulong", + "unchecked", + "unsafe", + "ushort", + "using", + "virtual", + "void", + "volatile", + "while" + ], + + "dataTypes": { + "arrayType": "List", + "generic": "object", + "string": "str", + "boolean": "boolean", + "float": "real", + "doubleType": "real", + "characterType": "real", + "longType": "long", + "int": "int" + }, + + "modelDefinition": "\n[DataContract]\npublic class ", + "fileExtension": "cs", + "instanceVarDefinition": "\n\tprivate ;", + "modelEnd": "\n}", + "staticImports": "", + "supportsCamelcasing": false, + "methods": { + "others": { + "getterSetter": { + "name": "DataMembers", + "signature": "", + "bodyStart": "", + "bodyEnd": "", + "codeForEachProperty": "\n\t[DataMember]\n\tpublic ( _ = )\n\t{\n\t\t = _;\n\t\treturn ;\n\t}\n", + "codeForEachArrayProperty": "\n\t[DataMember,\n\t AifCollectionTypeAttribute(\"_\",Types::Class), classstr(putClassName),\n\t AifCollectionTypeAttribute(\"_return\",Types::Class), classstr(putClassName)]\n\tpublic ( _ = )\n\t{\n\t\t = _;\n\t\treturn ;\n\t}", + "checked": "checked" + } + } + }, + "exampleCode": "## Example\n\n\n#### Decoding:\nThe example below shows how to decode an instance of `` type from JSON object.\n\n```csharp\nstring json = \"...\"; // Your JSON String.\n\n model = JsonConvert.DeserializeObject<>(json);\n```\n\n\n#### Encoding: \nThe example below shows how to encode an instance of a simple `` type into a JSON object.\n\n```java\n model = new ();\n// Assign value to variables.\n\nstring json = JsonConvert.SerializeObject(model);\n```" +} \ No newline at end of file diff --git a/languages/xppParmJSON.json b/languages/xppParmJSON.json new file mode 100644 index 0000000..03f3f4c --- /dev/null +++ b/languages/xppParmJSON.json @@ -0,0 +1,115 @@ +{ + "modelStart": "\n{", + "reservedKeywords": [ + "abstract", + "as", + "base", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "checked", + "class", + "const", + "continue", + "real", + "default", + "delegate", + "do", + "double", + "else", + "enum", + "event", + "explicit", + "extern", + "false", + "finally", + "fixed", + "float", + "for", + "foreach", + "goto", + "if", + "implicit", + "in", + "int", + "interface", + "internal", + "is", + "lock", + "long", + "namespace", + "new", + "null", + "object", + "operator", + "out", + "override", + "params", + "private", + "protected", + "public", + "readonly", + "ref", + "return", + "sbyte", + "sealed", + "short", + "sizeof", + "stackalloc", + "static", + "str", + "struct", + "switch", + "this", + "throw", + "true", + "try", + "typeof", + "uint", + "ulong", + "unchecked", + "unsafe", + "ushort", + "using", + "virtual", + "void", + "volatile", + "while" + ], + + "dataTypes": { + "arrayType": "List", + "generic": "object", + "string": "str", + "boolean": "boolean", + "float": "real", + "doubleType": "real", + "characterType": "real", + "longType": "long", + "int": "int" + }, + + "modelDefinition": "\n[DataContract]\npublic class ", + "fileExtension": "cs", + "instanceVarDefinition": "\n\tprivate ;", + "modelEnd": "\n}", + "staticImports": "", + "supportsCamelcasing": false, + "methods": { + "others": { + "getterSetter": { + "name": "DataMembers", + "signature": "", + "bodyStart": "", + "bodyEnd": "", + "codeForEachProperty": "\n\t[DataMember('')]\n\tpublic parm( _ = )\n\t{\n\t\t = _;\n\t\treturn ;\n\t}\n", + "codeForEachArrayProperty": "\n\t[DataMember(''),\n\t AifCollectionTypeAttribute(\"_\",Types::Class), classstr(putClassName),\n\t AifCollectionTypeAttribute(\"_return\",Types::Class), classstr(putClassName)]\n\tpublic parm( _ = )\n\t{\n\t\t = _;\n\t\treturn ;\n\t}", + "checked": "checked" + } + } + }, + "exampleCode": "## Example\n\n\n#### Decoding:\nThe example below shows how to decode an instance of `` type from JSON object.\n\n```csharp\nstring json = \"...\"; // Your JSON String.\n\n model = JsonConvert.DeserializeObject<>(json);\n```\n\n\n#### Encoding: \nThe example below shows how to encode an instance of a simple `` type into a JSON object.\n\n```java\n model = new ();\n// Assign value to variables.\n\nstring json = JsonConvert.SerializeObject(model);\n```" +} \ No newline at end of file diff --git a/script/parser.js b/script/parser.js index 0b71011..40ce2ee 100644 --- a/script/parser.js +++ b/script/parser.js @@ -13,7 +13,7 @@ let constKeyName = "" let additionalCustomTypeProperty = "" let modelIdentifier = "" let modelDefinitionProperties = "" - +let varNameKey = "" // FileBuilder function FileBuilder(language) { @@ -59,7 +59,8 @@ FileBuilder.prototype.getFiles = function(fileName, object, language) { var _this = this; keys.forEach(function(key) { var value = obj[key]; - var property = getProperty(key, value, language); + var property = getProperty(key, value, language, _this.varTypes); + property.isOptional = _this.isOptional var prevIndex = properties.map(function(prop) { return prop.propertyName; @@ -82,12 +83,13 @@ FileBuilder.prototype.getFiles = function(fileName, object, language) { file.isInitializers = this.isInitializers; file.modelIdentifier = this.modelIdentifier; file.methods = this.methods; + file.varTypes = this.varTypes; files.splice(0, 0, file); return files; } -function getProperty(key, value, language) { +function getProperty(key, value, language, varTypes) { let propertyName = getLanguageName(key, language); let valueType = getPropertyTypeName(value, language); @@ -95,6 +97,7 @@ function getProperty(key, value, language) { property.jsonKeyName = key; property.propertyName = propertyName; property.sampleValue = value; + property.varTypes = varTypes if (value instanceof Array) { if (value[0] && (value[0] instanceof Object)) { @@ -224,7 +227,11 @@ Property.prototype = { constructor: Property, toString: function() { var content = this.language.instanceVarDefinition; + if (this.isOptional) { + content = this.language.instanceVarDefinitionOptional; + } + content = content.replaceAll(varNameKey, this.varTypes); content = content.replaceAll(varType, this.propertyType); content = content.replaceAll(varName, this.propertyName); content = content.replaceAll(jsonKeyName, this.jsonKeyName); @@ -320,6 +327,9 @@ FileRepresenter.prototype = { } var propertyString = method.codeForEachProperty; + if (property.isOptional && method.codeForEachPropertyOptional) { + propertyString = method.codeForEachPropertyOptional; + } if (property.isCustomClass) { if (method.codeForEachCustomProperty) { @@ -390,11 +400,19 @@ FileRepresenter.prototype = { var modelDefinition = this.language.modelDefinition.replaceAll(modelName, this.className).replaceAll(modelIdentifier, this.modelIdentifier); + var codeForEachProperty = this.language.codeForEachProperty + if (this.language.isOptional && this.language.codeForEachPropertyOptional) { + codeForEachProperty = this.language.codeForEachPropertyOptional + } - if (this.language.codeForEachProperty) { - var _language = this.language; + if (codeForEachProperty) { + var _this = this; let propertyList = this.properties.map(function (property) { - return _language.codeForEachProperty.replaceAll(varName, property.propertyName).replaceAll(jsonKeyName, property.jsonKeyName).replaceAll(varType, property.propertyType); + return codeForEachProperty + .replaceAll(varNameKey, _this.varTypes) + .replaceAll(varName, property.propertyName) + .replaceAll(jsonKeyName, property.jsonKeyName) + .replaceAll(varType, property.propertyType); }).join(","); modelDefinition = modelDefinition.replaceAll(modelDefinitionProperties, propertyList); @@ -427,8 +445,6 @@ FileRepresenter.prototype = { } } - - Date.prototype.dateString = function() { var monthNames = [ diff --git a/script/script.js b/script/script.js index 729e88e..a279203 100644 --- a/script/script.js +++ b/script/script.js @@ -16,6 +16,24 @@ let languages = { key: "class", value: "Class", checked: "" + }], + varTypes: [{ + key: "let", + value: "let", + checked: "checked" + },{ + key: "var", + value: "var", + checked: "" + }], + optionalTypes: [{ + key: "optional", + value: "Optional", + checked: "" + },{ + key: "non-optional", + value: "Non Optional", + checked: "checked" }] }, swiftyjson: { @@ -30,6 +48,15 @@ let languages = { key: "class", value: "Class", checked: "" + }], + varTypes: [{ + key: "let", + value: "let", + checked: "checked" + },{ + key: "var", + value: "var", + checked: "" }] }, dictionary: { @@ -44,6 +71,15 @@ let languages = { key: "class", value: "Class", checked: "" + }], + varTypes: [{ + key: "let", + value: "let", + checked: "checked" + },{ + key: "var", + value: "var", + checked: "" }] } } @@ -74,12 +110,48 @@ let languages = { gson: { mode: "text/x-kotlin", name: "Gson", - file: "KotlinGson.json" + file: "KotlinGson.json", + varTypes: [{ + key: "val", + value: "val", + checked: "checked" + },{ + key: "var", + value: "var", + checked: "" + }], + optionalTypes: [{ + key: "optional", + value: "Optional", + checked: "" + },{ + key: "non-optional", + value: "Non Optional", + checked: "checked" + }] }, moshi: { mode: "text/x-kotlin", name: "Moshi", - file: "KotlinMoshi.json" + file: "KotlinMoshi.json", + varTypes: [{ + key: "val", + value: "val", + checked: "checked" + },{ + key: "var", + value: "var", + checked: "" + }], + optionalTypes: [{ + key: "optional", + value: "Optional", + checked: "" + },{ + key: "non-optional", + value: "Non Optional", + checked: "checked" + }] } } }, @@ -95,9 +167,24 @@ let languages = { mode: "text/x-csharp", name: "C# Class", file: "CSharpClass.json" + } + } + }, + xpp: { + name: "X++", + frameworks: { + xppClass: { + mode: "text/x-csharp", + name: "X++ Contract Class", + file: "xppJSON.json" + }, + xppParmClass: { + mode: "text/x-csharp", + name: "X++ Parm Contract Class", + file: "xppParmJSON.json" + } } } - } }; var selectedLanguage = languages.swift; @@ -175,6 +262,8 @@ function getAllClasses(language) { builder.isInitializers = $('#initializerCheckbox').is(':checked'); builder.rootClassName = $('#rootClassName').val(); builder.modelIdentifier = $('[name="modelIdentifierRadios"]:checked').val(); + builder.varTypes = $('[name="modelVariableRadios"]:checked').val(); + builder.isOptional = $('[name="modelOptionalRadios"]:checked').val() == "optional"; var methods = new Array(); let checkedMethods = $('.method-checkbox:checked'); @@ -247,6 +336,24 @@ function updateSelectedFramework() { }); } + $("#modelVariableTypes").empty(); + if (selectedFramework.varTypes) { + $("#modelVariableTypes").append(''); + selectedFramework.varTypes.forEach(function(identifier){ + let element = '
'; + $("#modelVariableTypes").append(element); + }); + } + + $("#optionalTypes").empty(); + if (selectedFramework.optionalTypes) { + $("#optionalTypes").append(''); + selectedFramework.optionalTypes.forEach(function(identifier){ + let element = '
'; + $("#optionalTypes").append(element); + }); + } + $('.model-identifier-radio').click(function () { inputChanged(); });