mushroom-cli 1.1.0-alpha.9 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gen/gen-csharp.js CHANGED
@@ -1,8 +1,27 @@
1
1
  const fs = require("fs");
2
2
  const common = require("../common.js");
3
- const package = require("./../package.json");
3
+ const package_json = require("./../package.json");
4
4
 
5
5
  //#region shared function
6
+ const newLine = `
7
+ `;
8
+ const header = `// NOTE: Please do not modify this file
9
+ // NOTE: Version and compatibility information: please see in Info.cs file
10
+
11
+ // ReSharper disable CheckNamespace
12
+ // ReSharper disable CommentTypo
13
+ // ReSharper disable EmptyNamespace
14
+ // ReSharper disable IdentifierTypo
15
+ // ReSharper disable InconsistentNaming
16
+ // ReSharper disable PartialTypeWithSinglePart
17
+ // ReSharper disable RedundantUsingDirective
18
+ // ReSharper disable StringLiteralTypo
19
+ // ReSharper disable UnusedMember.Global
20
+ // ReSharper disable UnusedMember.Local
21
+ // ReSharper disable UnusedParameter.Local
22
+ // ReSharper disable UnusedTypeParameter
23
+ `;
24
+
6
25
  function singleLine(str) {
7
26
  if (!str)
8
27
  return "";
@@ -12,7 +31,7 @@ function singleLine(str) {
12
31
  function toVietnameseNonTongue(str) {
13
32
  const signText = "ăâđêôơưàảãạáằẳẵặắầẩẫậấèẻẽẹéềểễệếìỉĩịíòỏõọóồổỗộốờởỡợớùủũụúừửữựứỳỷỹỵýĂÂĐÐÊÔƠƯÀẢÃẠÁẰẲẴẶẮẦẨẪẬẤÈẺẼẸÉỀỂỄỆẾÌỈĨỊÍÒỎÕỌÓỒỔỖỘỐỜỞỠỢỚÙỦŨỤÚỪỬỮỰỨỲỶỸỴÝ";
14
33
  const unsignedText = "aadeoouaaaaaaaaaaaaaaaeeeeeeeeeeiiiiiooooooooooooooouuuuuuuuuuyyyyyAADDEOOUAAAAAAAAAAAAAAAEEEEEEEEEEIIIIIOOOOOOOOOOOOOOOUUUUUUUUUUYYYYY";
15
- var returnValue = "";
34
+ let returnValue = "";
16
35
  for (let i = 0; i < str.length; i++) {
17
36
  const index = signText.indexOf(str.charAt(i));
18
37
  returnValue += index !== -1 ? unsignedText.charAt(index) : str.charAt(i);
@@ -25,7 +44,7 @@ function toCSharpName(str) {
25
44
  return "_";
26
45
  const name = toVietnameseNonTongue(str).replace(/\W/g, "_");
27
46
  const c = name.charAt(0);
28
- return ('0' <= c && c <= '9' ? '_' : "") + c.toUpperCase() + name.substr(1);
47
+ return ('0' <= c && c <= '9' ? '_' : "") + c.toUpperCase() + name.substring(1);
29
48
  }
30
49
 
31
50
  function getCSharpTypeFromMushroomType(source, type, required) {
@@ -99,7 +118,7 @@ function generateEnumClass(source, out, field, defaultClassName) {
99
118
  return "";
100
119
  }
101
120
 
102
- var type = getCSharpTypeFromMushroomType(source, mrType, true);
121
+ const type = getCSharpTypeFromMushroomType(source, mrType, true);
103
122
 
104
123
  validation.codeHint = validation.codeHint || {};
105
124
  if (validation.validValues) {
@@ -115,8 +134,10 @@ function generateEnumClass(source, out, field, defaultClassName) {
115
134
  strEnumClasses += ` /// <summary>
116
135
  /// ${singleLine(validation.codeHint.validValues.description || field.description)}
117
136
  /// </summary>
118
- public static class ${enumClassName}
137
+ public class ${enumClassName}
119
138
  {
139
+ private ${enumClassName}() { }
140
+
120
141
  `;
121
142
  const enumProperties = validation.codeHint.validValues.nameMap || validation.validValues;
122
143
  for (let i = 0; i < enumProperties.length && i < validation.validValues.length; i++) {
@@ -136,16 +157,17 @@ function generateEnumClass(source, out, field, defaultClassName) {
136
157
 
137
158
  //#region CSharp MongoDb Classes
138
159
  function generateCSharpClassMongoDb(source, className, fields, isRoot, description, out) {
139
- var strClasses = "";
160
+ let strClasses = "";
140
161
  let strEnumClasses = "";
141
- var content = "";
162
+ let content = "";
142
163
  if (description) {
143
164
  content +=
144
165
  ` /// <summary>
145
166
  /// ${singleLine(description)}
146
- /// </summary>\r\n`;
167
+ /// </summary>
168
+ `;
147
169
  }
148
- var supperClass = "";
170
+ let supperClass = "";
149
171
  if (isRoot) {
150
172
  // thêm cho trường hợp không khai báo id hoặc id.type
151
173
  if (!fields.id) {
@@ -160,23 +182,23 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
160
182
  content += ` public class ${className}${supperClass}
161
183
  {
162
184
  `;
163
- for (var fieldName in fields) {
185
+ for (const fieldName in fields) {
164
186
  if (!fields.hasOwnProperty(fieldName))
165
187
  continue;
166
188
 
167
- var field = fields[fieldName];
168
- var type;
169
- var propertyName = toCSharpName(fieldName);
189
+ const field = fields[fieldName];
190
+ let type;
191
+ const propertyName = toCSharpName(fieldName);
170
192
  if (field.codeHint && field.codeHint.type && field.codeHint.type.csharp) {
171
193
  type = field.codeHint.type.csharp;
172
194
  }
173
195
  else if (field.type === "object") {
174
- strClasses += generateCSharpClassMongoDb(source, className + "_" + propertyName, field.fields, false, null, out) + "\r\n";
196
+ strClasses += generateCSharpClassMongoDb(source, className + "_" + propertyName, field.fields, false, null, out) + newLine;
175
197
  type = className + "_" + propertyName;
176
198
  }
177
199
  else if (field.type === "array") {
178
200
  if (field.items.type === "object") {
179
- strClasses += generateCSharpClassMongoDb(source, className + "_" + propertyName, field.items.fields, false, null, out) + "\r\n";
201
+ strClasses += generateCSharpClassMongoDb(source, className + "_" + propertyName, field.items.fields, false, null, out) + newLine;
180
202
  type = `System.Collections.Generic.List<${className}_${propertyName}>`;
181
203
  } else {
182
204
  type = `System.Collections.Generic.List<${getCSharpTypeFromMushroomType(source, field.items.type, field.items.validation && field.items.validation.required)}>`;
@@ -190,38 +212,38 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
190
212
  `;
191
213
 
192
214
  if (isRoot && fieldName === "id") {
193
- content += ` [BsonId${field.type === "AutoId" && source.idType === "GUID" ? "(IdGenerator = typeof(MongoDB.Bson.Serialization.IdGenerators.GuidGenerator))" : ""}]\r\n`;
215
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonId${field.type === "AutoId" && source.idType === "GUID" ? "(IdGenerator = typeof(MongoDB.Bson.Serialization.IdGenerators.GuidGenerator))" : ""}]${newLine}`;
194
216
  }
195
- content += ` [BsonElement("${isRoot && fieldName === "id" ? "_id" : fieldName}")]
196
- [BsonIgnoreIfNull]
197
- [JsonProperty(PropertyName = "${fieldName}", NullValueHandling = NullValueHandling.Ignore)]
217
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonElement("${isRoot && fieldName === "id" ? "_id" : fieldName}")]
218
+ [MongoDB.Bson.Serialization.Attributes.BsonIgnoreIfNull]
219
+ [Newtonsoft.Json.JsonProperty(PropertyName = "${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.DateTime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
198
220
  `;
199
221
  if ((field.type === "AutoId" || field.type === "IdRef") && source.idType === "ObjectId") {
200
- content += " [BsonRepresentation(BsonType.ObjectId)]\r\n";
222
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
201
223
  }
202
224
  if (field.type === "AutoId" && source.idType === "GUID") {
203
- content += " [BsonRepresentation(BsonType.String)]\r\n";
225
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]" + newLine;
204
226
  }
205
227
  if (field.type === "datetime") {
206
- content += " [BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]\r\n";
228
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]" + newLine;
207
229
  }
208
230
  if (field.type === "array") {
209
231
  if ((field.items.type === "AutoId" || field.items.type === "IdRef") && source.idType === "ObjectId") {
210
- content += " [BsonRepresentation(BsonType.ObjectId)]\r\n";
232
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
211
233
  }
212
234
  if (field.items.type === "AutoId" && source.idType === "GUID") {
213
- content += " [BsonRepresentation(BsonType.String)]\r\n";
235
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]" + newLine;
214
236
  }
215
237
  if (field.items.type === "datetime") {
216
- content += " [BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]\r\n";
238
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]" + newLine;
217
239
  }
218
240
  }
219
241
 
220
- content += ` public ${type} ${propertyName} { get; set; }\r\n\r\n`;
242
+ content += ` public ${type} ${propertyName} { get; set; }${newLine}${newLine}`;
221
243
 
222
244
  strEnumClasses += generateEnumClass(source, out, field, `${className.toUpperCase()}_${propertyName.toUpperCase()}_ENUM`);
223
245
  }
224
- content += ` [BsonExtraElements]
246
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonExtraElements]
225
247
  public System.Collections.Generic.Dictionary<string, object> Mushroom_ExtraProperties { get; set; }
226
248
 
227
249
  }
@@ -230,24 +252,28 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
230
252
  out.strEnumClasses = out.strEnumClasses || "";
231
253
 
232
254
  out.strEnumClasses += strEnumClasses;
233
- //console.log("strEnumClasses("+typeof(strEnumClasses)+"):" + strEnumClasses);
234
255
  }
235
256
 
236
- return strClasses + "\r\n" + content;
257
+ return strClasses + newLine + content;
237
258
  }
238
259
 
239
260
  function getCSharpFunc(methodName, methodType) {
240
261
  if (methodType === "static") return methodName;
241
262
  const idx = methodName.lastIndexOf('.');
242
263
  if (idx === -1) return methodName;
243
- return `new ${methodName.substr(0, idx)}()${methodName.substr(idx)}`;
264
+ return `new ${methodName.substring(0, idx)}()${methodName.substring(idx)}`;
244
265
  }
245
266
 
246
267
  function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
247
268
  const aliasProject = ((project.csharpMongo || {}).alias || {})[alias];
248
269
 
249
270
  if (!aliasProject) {
250
- throw new Error(`Not found gen c#-mongo configuration. Please run 'npx mr config ${projectName} gen c#-mongo OUTPUT_FILE.cs${alias === "default" ? "" : " alias " + alias}' first`);
271
+ throw new Error(`Not found gen c#-mongo configuration. Please run 'npx mushroom-cli config ${projectName} gen c#-mongo OUTPUT_FILE.cs${alias === "default" ? "" : " alias " + alias}' first`);
272
+ }
273
+
274
+ if (aliasProject.outputToFolder) {
275
+ genCSharpMongoDbClassesToFolder(projectName, alias, source, aliasProject);
276
+ return;
251
277
  }
252
278
 
253
279
  const entities = common.getEntities(source, aliasProject.allowRoles, true);
@@ -258,6 +284,17 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
258
284
  let strEnumClasses = "";
259
285
  let collectionNames = "";
260
286
  let resourceNames = "";
287
+ let roleNames = "";
288
+
289
+ source.roles?.forEach(role => {
290
+ if (!role.name) return;
291
+ roleNames += `
292
+ /// <summary>
293
+ /// ${role.description ?? ""}
294
+ /// </summary>
295
+ public static string ${toCSharpName(role.name)} => "${role.name}";
296
+ `;
297
+ });
261
298
 
262
299
  const out = {};
263
300
  for (let entityName in entities) {
@@ -268,7 +305,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
268
305
  collectionNames += ` public static string ${className}CollectionName => "${entities[entityName].storageName}";
269
306
  public static IMongoCollection<Resources.${className}> ${className}Collection => GetDatabase().GetCollection<Resources.${className}>(${className}CollectionName);
270
307
  `;
271
- resourceNames += ` public static string ${className} => "${entityName}";\r\n`;
308
+ resourceNames += ` public static string ${className} => "${entityName}";${newLine}`;
272
309
  strClasses += generateCSharpClassMongoDb(source, className, entities[entityName].fields, true, entities[entityName].description, out);
273
310
 
274
311
  const actions = entities[entityName].actions || {};
@@ -282,7 +319,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
282
319
  return;
283
320
  if (typeof a.delegator === "string" && a.delegator.indexOf("lib:") === 0) {
284
321
  out.delegators = out.delegators || [];
285
- const method = a.delegator.substr(4, a.delegator.length - 4);
322
+ const method = a.delegator.substring(4);
286
323
  let type = a.codeHint && a.codeHint.delegator && a.codeHint.delegator.csharp
287
324
  ? a.codeHint.delegator.csharp.methodType
288
325
  : null;
@@ -294,7 +331,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
294
331
  });
295
332
  }
296
333
 
297
- if (!a.events && !(typeof a.events === "object")) return;
334
+ if (!a.events && typeof a.events !== "object") return;
298
335
 
299
336
  for (let eventName in a.events) {
300
337
  if (!Array.isArray(a.events[eventName])) return;
@@ -302,7 +339,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
302
339
  out.eventHandlers = out.eventHandlers || [];
303
340
  a.events[eventName].forEach((ev, i) => {
304
341
  if (typeof ev !== "string" || ev.indexOf("lib:") !== 0) return;
305
- const method = ev.substr(4, ev.length - 4);
342
+ const method = ev.substring(4);
306
343
  let type = a.codeHint && a.codeHint.events
307
344
  && Array.isArray(a.codeHint.events[eventName])
308
345
  && a.codeHint.events[eventName][i]
@@ -331,7 +368,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
331
368
 
332
369
  if (typeof v.query === "string" && v.query.indexOf("lib:") === 0) {
333
370
  out.viewHandlers = out.viewHandlers || [];
334
- const method = v.query.substr(4, v.query.length - 4);
371
+ const method = v.query.substring(4);
335
372
  let type = v.codeHint && v.codeHint.query && v.codeHint.query.csharp
336
373
  ? v.codeHint.query.csharp.methodType
337
374
  : null;
@@ -344,6 +381,25 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
344
381
  }
345
382
  });
346
383
  }
384
+
385
+ const channels = entities[entityName].features?.vn_text?.channels;
386
+ if (channels != null) {
387
+ channels.forEach(channel => {
388
+ if (!channel.nativeBuilder || typeof channel.nativeBuilder !== "string" || channel.nativeBuilder.indexOf("lib:") !== 0) return;
389
+
390
+ out.vnTextChannels = out.vnTextChannels || [];
391
+ const method = channel.nativeBuilder.substring(4);
392
+ let type = channel.codeHint && channel.codeHint.nativeBuilder && channel.codeHint.nativeBuilder.csharp
393
+ ? channel.codeHint.nativeBuilder.csharp.methodType
394
+ : null;
395
+ if (type !== "non-static") type = "static";
396
+ out.vnTextChannels.push({
397
+ method: method,
398
+ source: `entity: ${entityName}, feature: vn_text, channel: ${channel.name}`,
399
+ type: type
400
+ });
401
+ });
402
+ }
347
403
  }
348
404
 
349
405
  if (out.strEnumClasses)
@@ -360,7 +416,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
360
416
  }
361
417
  return prev;
362
418
  }, {});
363
- const strDelegatorReferences = Object.keys(delegators).map(method => delegators[method].map(ev => ` // ${ev.source}`).join("\r\n") + "\r\n" + ` RegisterCustomMethod(${getCSharpFunc(method, delegators[method][0].type)});`).join("\r\n");
419
+ const strDelegatorReferences = Object.keys(delegators).map(method => delegators[method].map(ev => ` // ${ev.source}`).join(newLine) + newLine + ` RegisterCustomMethod(${getCSharpFunc(method, delegators[method][0].type)});`).join(newLine);
364
420
 
365
421
  const viewHandlers = (out.viewHandlers || []).reduce((prev, cur) => {
366
422
  if (cur.method in prev) {
@@ -373,7 +429,20 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
373
429
  }
374
430
  return prev;
375
431
  }, {});
376
- const strViewHandlerReferences = Object.keys(viewHandlers).map(method => viewHandlers[method].map(ev => ` // ${ev.source}`).join("\r\n") + "\r\n" + ` RegisterCustomViewMethod(${getCSharpFunc(method, viewHandlers[method][0].type)});`).join("\r\n");
432
+ const strViewHandlerReferences = Object.keys(viewHandlers).map(method => viewHandlers[method].map(ev => ` // ${ev.source}`).join(newLine) + newLine + ` RegisterCustomViewMethod(${getCSharpFunc(method, viewHandlers[method][0].type)});`).join(newLine);
433
+
434
+ const vnTextChannels = (out.vnTextChannels || []).reduce((prev, cur) => {
435
+ if (cur.method in prev) {
436
+ if (prev[cur.method].indexOf(cur.source) === -1) {
437
+ prev[cur.method].push(cur);
438
+ }
439
+ }
440
+ else {
441
+ prev[cur.method] = [cur];
442
+ }
443
+ return prev;
444
+ }, {});
445
+ const strVnTextChannels = Object.keys(vnTextChannels).map(method => vnTextChannels[method].map(channel => ` // ${channel.source}`).join(newLine) + newLine + ` RegisterCustomVnTextBuilderMethod(${getCSharpFunc(method, vnTextChannels[method][0].type)});`).join(newLine);
377
446
 
378
447
  const eventHandlers = (out.eventHandlers || []).reduce((prev, cur) => {
379
448
  if (cur.method in prev) {
@@ -386,18 +455,18 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
386
455
  }
387
456
  return prev;
388
457
  }, {});
389
- const strEventHandlerReferences = Object.keys(eventHandlers).map(method => eventHandlers[method].map(ev => ` // ${ev.source}`).join("\r\n") + "\r\n" + ` RegisterEvent(${getCSharpFunc(method, eventHandlers[method][0].type)});`).join("\r\n");
458
+ const strEventHandlerReferences = Object.keys(eventHandlers).map(method => eventHandlers[method].map(ev => ` // ${ev.source}`).join(newLine) + newLine + ` RegisterEvent(${getCSharpFunc(method, eventHandlers[method][0].type)});`).join(newLine);
390
459
 
391
460
  const strJobReferences = Array.isArray(source.jobs)
392
461
  ? source.jobs
393
462
  .filter(job => job !== null && typeof(job) === "object" && job.action && typeof (job.action) === "string" && job.action.indexOf("lib:") === 0)
394
- .map(job => ` RegisterJob<${job.action.substr(4).split(',')[0]}>();`)
395
- .join("\r\n")
463
+ .map(job => ` RegisterJob<${job.action.substring(4).split(',')[0]}>();`)
464
+ .join(newLine)
396
465
  : "";
397
466
 
398
- const code = `// This file was generated by Mushroom CLI ${package.version} (https://www.npmjs.com/package/mushroom-cli), please do not modify
467
+ const code = `// This file was generated by Mushroom CLI ${package_json.version} (https://www.npmjs.com/package/mushroom-cli), please do not modify
399
468
 
400
- // NOTE: Compatible with Mushroom Server version 0.2.18 or higher
469
+ // NOTE: Compatible with Mushroom Server version 0.2.18 or higher (https://www.nuget.org/packages/Mushroom/)
401
470
 
402
471
  // ReSharper disable RedundantUsingDirective
403
472
  // ReSharper disable InconsistentNaming
@@ -410,14 +479,10 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
410
479
  // ReSharper disable CommentTypo
411
480
  // ReSharper disable EmptyNamespace
412
481
 
413
- using MongoDB.Bson;
414
- using MongoDB.Bson.Serialization.Attributes;
415
- using MongoDB.Driver;
416
- using JsonPropertyAttribute = Newtonsoft.Json.JsonPropertyAttribute;
417
- using NullValueHandling = Newtonsoft.Json.NullValueHandling;
418
-
419
482
  namespace ${namespace}
420
483
  {
484
+ using MongoDB.Driver;
485
+
421
486
  public static class DbConnector
422
487
  {
423
488
  ${collectionNames}
@@ -439,10 +504,18 @@ ${collectionNames}
439
504
  }
440
505
  }
441
506
 
442
- public static class ResourceNames
507
+ public class ResourceNames
443
508
  {
509
+ private ResourceNames() { }
510
+
444
511
  ${resourceNames}
445
512
  }
513
+
514
+ public class RoleNames {
515
+ private RoleNames() { }
516
+
517
+ ${roleNames}
518
+ }
446
519
  }
447
520
 
448
521
  namespace ${namespace}.Resources
@@ -465,6 +538,7 @@ namespace ${namespace}.CodeHelper
465
538
  private void RegisterCustomMethod(System.Action<Mushroom.ActionArguments> fn) { }
466
539
  private void RegisterCustomViewMethod(System.Func<Mushroom.ViewArguments, System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<object>>> fn) { }
467
540
  private void RegisterCustomViewMethod(System.Action<Mushroom.ViewArguments> fn) { }
541
+ private void RegisterCustomVnTextBuilderMethod(System.Func<System.Collections.Generic.IEnumerable<string>, System.Collections.Generic.IEnumerable<string>> fn) { }
468
542
  private void RegisterEvent(System.Func<object, Mushroom.ActionArguments, System.Threading.Tasks.Task> fn) { }
469
543
  private void RegisterEvent(System.Action<object, Mushroom.ActionArguments> fn) { }
470
544
  private void RegisterJob<T>() where T : Mushroom.Job.JobBase { }
@@ -472,6 +546,7 @@ namespace ${namespace}.CodeHelper
472
546
  {
473
547
  ${strDelegatorReferences}
474
548
  ${strViewHandlerReferences}
549
+ ${strVnTextChannels}
475
550
  ${strEventHandlerReferences}
476
551
  ${strJobReferences}
477
552
  }
@@ -488,13 +563,427 @@ ${strJobReferences}
488
563
  console.log(`Generated CSharp MongoDb Classes for ${projectName}@${alias} to ${aliasProject.output}`);
489
564
  });
490
565
  }
566
+
567
+ function generateCSharpClassMongoDbToFolder(source, className, fields, isRoot, description, out, aliasProject) {
568
+ let content = "";
569
+ const namespace = toCSharpName(source.name);
570
+ if (description) {
571
+ content +=
572
+ ` /// <summary>
573
+ /// ${singleLine(description)}
574
+ /// </summary>
575
+ `;
576
+ }
577
+ let supperClass = "";
578
+ if (isRoot) {
579
+ // thêm cho trường hợp không khai báo id hoặc id.type
580
+ if (!fields.id) {
581
+ fields.id = {
582
+ type: "AutoId"
583
+ };
584
+ }
585
+ if (!fields.id.type) fields.id.type = "AutoId";
586
+
587
+ supperClass = " : Mushroom.Models.IResource<" + getCSharpTypeFromMushroomType(source, fields.id.type, true) + ">";
588
+ }
589
+ content += ` public class ${className}${supperClass}
590
+ {
591
+ `;
592
+ for (const fieldName in fields) {
593
+ if (!fields.hasOwnProperty(fieldName))
594
+ continue;
595
+
596
+ const field = fields[fieldName];
597
+ let type;
598
+ const propertyName = toCSharpName(fieldName);
599
+ if (field.codeHint && field.codeHint.type && field.codeHint.type.csharp) {
600
+ type = field.codeHint.type.csharp;
601
+ }
602
+ else if (field.type === "object") {
603
+ generateCSharpClassMongoDbToFolder(source, className + "_" + propertyName, field.fields, false, null, out, aliasProject);
604
+ type = className + "_" + propertyName;
605
+ }
606
+ else if (field.type === "array") {
607
+ if (field.items.type === "object") {
608
+ generateCSharpClassMongoDbToFolder(source, className + "_" + propertyName, field.items.fields, false, null, out, aliasProject);
609
+ type = `System.Collections.Generic.List<${className}_${propertyName}>`;
610
+ } else {
611
+ type = `System.Collections.Generic.List<${getCSharpTypeFromMushroomType(source, field.items.type, field.items.validation && field.items.validation.required)}>`;
612
+ }
613
+ } else
614
+ type = getCSharpTypeFromMushroomType(source, field.type, field.validation && field.validation.required);
615
+ content +=
616
+ ` /// <summary>
617
+ /// ${singleLine(field.description)}
618
+ /// </summary>
619
+ `;
620
+
621
+ if (isRoot && fieldName === "id") {
622
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonId${field.type === "AutoId" && source.idType === "GUID" ? "(IdGenerator = typeof(MongoDB.Bson.Serialization.IdGenerators.GuidGenerator))" : ""}]${newLine}`;
623
+ }
624
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonElement("${isRoot && fieldName === "id" ? "_id" : fieldName}")]
625
+ [MongoDB.Bson.Serialization.Attributes.BsonIgnoreIfNull]
626
+ [Newtonsoft.Json.JsonProperty(PropertyName = "${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.DateTime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
627
+ `;
628
+ if ((field.type === "AutoId" || field.type === "IdRef") && source.idType === "ObjectId") {
629
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
630
+ }
631
+ if (field.type === "AutoId" && source.idType === "GUID") {
632
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]" + newLine;
633
+ }
634
+ if (field.type === "datetime") {
635
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]" + newLine;
636
+ }
637
+ if (field.type === "array") {
638
+ if ((field.items.type === "AutoId" || field.items.type === "IdRef") && source.idType === "ObjectId") {
639
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
640
+ }
641
+ if (field.items.type === "AutoId" && source.idType === "GUID") {
642
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]" + newLine;
643
+ }
644
+ if (field.items.type === "datetime") {
645
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]" + newLine;
646
+ }
647
+ }
648
+
649
+ content += ` public ${type} ${propertyName} { get; set; }
650
+
651
+ `;
652
+
653
+ let strEnumClasses = generateEnumClass(source, {}, field, `${className.toUpperCase()}_${propertyName.toUpperCase()}_ENUM`);
654
+
655
+ const match = strEnumClasses.match(/public class\s+(\w+)/);
656
+ if (!match) continue;
657
+ common.ensureFolder(aliasProject.output + "/Enums", true);
658
+ strEnumClasses = `${header}
659
+
660
+ namespace ${namespace}.Enums
661
+ {
662
+ ${strEnumClasses}
663
+ }
664
+ `;
665
+
666
+ fs.writeFileSync(aliasProject.output + "/Enums/" + match[1] + ".cs", strEnumClasses);
667
+ }
668
+
669
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonExtraElements]
670
+ [Newtonsoft.Json.JsonIgnore]
671
+ public System.Collections.Generic.Dictionary<string, object> Mushroom_ExtraProperties { get; set; }
672
+
673
+ }
674
+ `;
675
+
676
+ common.ensureFolder(aliasProject.output + "/Resources", true);
677
+
678
+ content = `${header}
679
+
680
+ namespace ${namespace}.Resources
681
+ {
682
+ ${content}
683
+ }
684
+ `;
685
+
686
+ out.allClasses = out.allClasses || [];
687
+
688
+ const normalizedName = className.toLowerCase();
689
+ const duplicate = out.allClasses.find(c => c.normalizedName == normalizedName);
690
+ if (duplicate) {
691
+ fs.appendFileSync(aliasProject.output + "/Resources/" + duplicate.className + ".cs", content);
692
+ }
693
+ else {
694
+ out.allClasses.push({
695
+ className,
696
+ normalizedName
697
+ });
698
+ fs.writeFileSync(aliasProject.output + "/Resources/" + className + ".cs", content);
699
+ }
700
+ }
701
+
702
+ function genCSharpMongoDbClassesToFolder(projectName, alias, source, aliasProject) {
703
+
704
+ if (fs.existsSync(aliasProject.output)) {
705
+ try {
706
+ fs.unlinkSync(aliasProject.output); // xóa file nếu có
707
+ } catch(e) {}
708
+ try {
709
+ fs.rmSync(aliasProject.output, { recursive: true, force: true }); // xóa thư mục nếu có
710
+ } catch(e) {}
711
+ }
712
+ fs.mkdirSync(aliasProject.output, { recursive: true, mode: 493 }); // 493 = 755 in octa
713
+
714
+ const entities = common.getEntities(source, aliasProject.allowRoles, true);
715
+
716
+ const namespace = toCSharpName(source.name);
717
+
718
+ let collectionNames = "";
719
+ let resourceNames = "";
720
+ let roleNames = "";
721
+
722
+ source.roles?.forEach(role => {
723
+ if (!role.name) return;
724
+ roleNames += `
725
+ /// <summary>
726
+ /// ${role.description ?? ""}
727
+ /// </summary>
728
+ public static string ${toCSharpName(role.name)} => "${role.name}";
729
+ `;
730
+ });
731
+
732
+ const out = {};
733
+ for (let entityName in entities) {
734
+ if (!entities.hasOwnProperty(entityName))
735
+ continue;
736
+
737
+ const className = toCSharpName(entityName);
738
+ collectionNames += ` public static string ${className}CollectionName => "${entities[entityName].storageName}";
739
+ public static IMongoCollection<Resources.${className}> ${className}Collection => GetDatabase().GetCollection<Resources.${className}>(${className}CollectionName);
740
+ `;
741
+ resourceNames += ` public static string ${className} => "${entityName}";
742
+ `;
743
+
744
+ generateCSharpClassMongoDbToFolder(source, className, entities[entityName].fields, true, entities[entityName].description, out, aliasProject);
745
+
746
+ const actions = entities[entityName].actions || {};
747
+ for (let actionName in actions) {
748
+ const action = actions[actionName];
749
+ if (!Array.isArray(action))
750
+ continue;
751
+
752
+ action.forEach(a => {
753
+ if (!a)
754
+ return;
755
+ if (typeof a.delegator === "string" && a.delegator.indexOf("lib:") === 0) {
756
+ out.delegators = out.delegators || [];
757
+ const method = a.delegator.substring(4);
758
+ let type = a.codeHint && a.codeHint.delegator && a.codeHint.delegator.csharp
759
+ ? a.codeHint.delegator.csharp.methodType
760
+ : null;
761
+ if (type !== "non-static") type = "static";
762
+ out.delegators.push({
763
+ method: method,
764
+ source: `entity: ${entityName}, action: ${actionName}, grant: ${a.grant}`,
765
+ type: type
766
+ });
767
+ }
768
+
769
+ if (!a.events && typeof a.events !== "object") return;
770
+
771
+ for (let eventName in a.events) {
772
+ if (!Array.isArray(a.events[eventName])) return;
773
+
774
+ out.eventHandlers = out.eventHandlers || [];
775
+ a.events[eventName].forEach((ev, i) => {
776
+ if (typeof ev !== "string" || ev.indexOf("lib:") !== 0) return;
777
+ const method = ev.substring(4);
778
+ let type = a.codeHint && a.codeHint.events
779
+ && Array.isArray(a.codeHint.events[eventName])
780
+ && a.codeHint.events[eventName][i]
781
+ && a.codeHint.events[eventName][i].csharp
782
+ ? a.codeHint.events[eventName][i].csharp.methodType
783
+ : null;
784
+ if (type !== "non-static") type = "static";
785
+ out.eventHandlers.push({
786
+ method: method,
787
+ source: `entity: ${entityName}, action: ${actionName}, grant: ${a.grant}, event: ${eventName}`,
788
+ type: type
789
+ });
790
+ });
791
+ }
792
+ });
793
+ }
794
+
795
+ const views = entities[entityName].views || {};
796
+ for (let viewName in views) {
797
+ const view = views[viewName];
798
+ if (!Array.isArray(view))
799
+ continue;
800
+
801
+ view.forEach(v => {
802
+ if (!v) return;
803
+
804
+ if (typeof v.query === "string" && v.query.indexOf("lib:") === 0) {
805
+ out.viewHandlers = out.viewHandlers || [];
806
+ const method = v.query.substring(4);
807
+ let type = v.codeHint && v.codeHint.query && v.codeHint.query.csharp
808
+ ? v.codeHint.query.csharp.methodType
809
+ : null;
810
+ if (type !== "non-static") type = "static";
811
+ out.viewHandlers.push({
812
+ method: method,
813
+ source: `entity: ${entityName}, view: ${viewName}, grant: ${v.grant}`,
814
+ type: type
815
+ });
816
+ }
817
+ });
818
+ }
819
+
820
+ const channels = entities[entityName].features?.vn_text?.channels;
821
+ if (channels != null) {
822
+ channels.forEach(channel => {
823
+ if (!channel.nativeBuilder || typeof channel.nativeBuilder !== "string" || channel.nativeBuilder.indexOf("lib:") !== 0) return;
824
+
825
+ out.vnTextChannels = out.vnTextChannels || [];
826
+ const method = channel.nativeBuilder.substring(4);
827
+ let type = channel.codeHint && channel.codeHint.nativeBuilder && channel.codeHint.nativeBuilder.csharp
828
+ ? channel.codeHint.nativeBuilder.csharp.methodType
829
+ : null;
830
+ if (type !== "non-static") type = "static";
831
+ out.vnTextChannels.push({
832
+ method: method,
833
+ source: `entity: ${entityName}, feature: vn_text, channel: ${channel.name}`,
834
+ type: type
835
+ });
836
+ });
837
+ }
838
+ }
839
+
840
+
841
+ const delegators = (out.delegators || []).reduce((prev, cur) => {
842
+ if (cur.method in prev) {
843
+ if (prev[cur.method].indexOf(cur.source) === -1) {
844
+ prev[cur.method].push(cur);
845
+ }
846
+ }
847
+ else {
848
+ prev[cur.method] = [cur];
849
+ }
850
+ return prev;
851
+ }, {});
852
+ const strDelegatorReferences = Object.keys(delegators).map(method => delegators[method].map(ev => ` // ${ev.source}`).join(newLine) + newLine + ` RegisterCustomMethod(${getCSharpFunc(method, delegators[method][0].type)});`).join(newLine);
853
+
854
+ const viewHandlers = (out.viewHandlers || []).reduce((prev, cur) => {
855
+ if (cur.method in prev) {
856
+ if (prev[cur.method].indexOf(cur.source) === -1) {
857
+ prev[cur.method].push(cur);
858
+ }
859
+ }
860
+ else {
861
+ prev[cur.method] = [cur];
862
+ }
863
+ return prev;
864
+ }, {});
865
+ const strViewHandlerReferences = Object.keys(viewHandlers).map(method => viewHandlers[method].map(ev => ` // ${ev.source}`).join(newLine) + newLine + ` RegisterCustomViewMethod(${getCSharpFunc(method, viewHandlers[method][0].type)});`).join(newLine);
866
+
867
+ const vnTextChannels = (out.vnTextChannels || []).reduce((prev, cur) => {
868
+ if (cur.method in prev) {
869
+ if (prev[cur.method].indexOf(cur.source) === -1) {
870
+ prev[cur.method].push(cur);
871
+ }
872
+ }
873
+ else {
874
+ prev[cur.method] = [cur];
875
+ }
876
+ return prev;
877
+ }, {});
878
+ const strVnTextChannels = Object.keys(vnTextChannels).map(method => vnTextChannels[method].map(channel => ` // ${channel.source}`).join(newLine) + newLine + ` RegisterCustomVnTextBuilderMethod(${getCSharpFunc(method, vnTextChannels[method][0].type)});`).join(newLine);
879
+
880
+ const eventHandlers = (out.eventHandlers || []).reduce((prev, cur) => {
881
+ if (cur.method in prev) {
882
+ if (prev[cur.method].indexOf(cur.source) === -1) {
883
+ prev[cur.method].push(cur);
884
+ }
885
+ }
886
+ else {
887
+ prev[cur.method] = [cur];
888
+ }
889
+ return prev;
890
+ }, {});
891
+ const strEventHandlerReferences = Object.keys(eventHandlers).map(method => eventHandlers[method].map(ev => ` // ${ev.source}`).join(newLine) + newLine + ` RegisterEvent(${getCSharpFunc(method, eventHandlers[method][0].type)});`).join(newLine);
892
+
893
+ const strJobReferences = Array.isArray(source.jobs)
894
+ ? source.jobs
895
+ .filter(job => job !== null && typeof(job) === "object" && job.action && typeof (job.action) === "string" && job.action.indexOf("lib:") === 0)
896
+ .map(job => ` RegisterJob<${job.action.substring(4).split(',')[0]}>();`)
897
+ .join(newLine)
898
+ : "";
899
+
900
+ const dbConnectorFileContent = `${header}
901
+ using MongoDB.Driver;
902
+
903
+ namespace ${namespace}
904
+ {
905
+ public static class DbConnector
906
+ {
907
+ ${collectionNames}
908
+ public static IMongoDatabase GetDatabase() => Mushroom.MushroomDaoFactory.GetDbAdapter() as IMongoDatabase;
909
+ }
910
+ }
911
+ `;
912
+
913
+ const resourceNamesFileContent = `${header}
914
+
915
+ namespace ${namespace}
916
+ {
917
+ public class ResourceNames
918
+ {
919
+ private ResourceNames() { }
920
+
921
+ ${resourceNames}
922
+ }
923
+ }
924
+ `;
925
+
926
+ const roleNamesFileContent = `${header}
927
+
928
+ namespace ${namespace}
929
+ {
930
+ public class RoleNames
931
+ {
932
+ private RoleNames() { }
933
+
934
+ ${roleNames}
935
+ }
936
+ }
937
+ `;
938
+
939
+
940
+ const refactorHelperFileContent = `${header}
941
+
942
+ #if DEBUG
943
+ namespace ${namespace}
944
+ {
945
+ class RefactorHelper
946
+ {
947
+ private RefactorHelper() { }
948
+ private void RegisterCustomMethod(System.Func<Mushroom.ActionArguments, System.Threading.Tasks.Task> fn) { }
949
+ private void RegisterCustomMethod(System.Action<Mushroom.ActionArguments> fn) { }
950
+ private void RegisterCustomViewMethod(System.Func<Mushroom.ViewArguments, System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<object>>> fn) { }
951
+ private void RegisterCustomViewMethod(System.Action<Mushroom.ViewArguments> fn) { }
952
+ private void RegisterCustomVnTextBuilderMethod(System.Func<System.Collections.Generic.IEnumerable<string>, System.Collections.Generic.IEnumerable<string>> fn) { }
953
+ private void RegisterEvent(System.Func<object, Mushroom.ActionArguments, System.Threading.Tasks.Task> fn) { }
954
+ private void RegisterEvent(System.Action<object, Mushroom.ActionArguments> fn) { }
955
+ private void RegisterJob<T>() where T : Mushroom.Job.JobBase { }
956
+ private void Help()
957
+ {
958
+ ${strDelegatorReferences}
959
+ ${strViewHandlerReferences}
960
+ ${strVnTextChannels}
961
+ ${strEventHandlerReferences}
962
+ ${strJobReferences}
963
+ }
964
+ }
965
+ }
966
+ #endif
967
+ `;
968
+
969
+ const infoFileContent = `// Mushroom CLI version: ${package_json.version}${newLine}// Compatible with Mushroom Server version: 0.2.25.4 or higher (https://www.nuget.org/packages/Mushroom/)
970
+ // For Mushroom Server 0.2.18 to 0.2.25.4: Please remove all FindById methods in DbConnector.cs`
971
+
972
+ fs.writeFileSync(aliasProject.output + "/DbConnector.cs", dbConnectorFileContent);
973
+ fs.writeFileSync(aliasProject.output + "/ResourceNames.cs", resourceNamesFileContent);
974
+ fs.writeFileSync(aliasProject.output + "/RoleNames.cs", roleNamesFileContent);
975
+ fs.writeFileSync(aliasProject.output + "/RefactorHelper.cs", refactorHelperFileContent);
976
+ fs.writeFileSync(aliasProject.output + "/Info.cs", infoFileContent);
977
+
978
+ console.log(`Generated CSharp MongoDb Classes for ${projectName}@${alias} to folder ${aliasProject.output}`);
979
+ }
491
980
  //#endregion
492
981
 
493
982
  //#region CSharp Driver
494
983
  function generateCSharpClassDriver(source, className, fields, description, out) {
495
- var strClasses = "";
496
- var strEnumClasses = "";
497
- var content = "";
984
+ let strClasses = "";
985
+ let strEnumClasses = "";
986
+ let content = "";
498
987
  if (description) {
499
988
  content +=
500
989
  ` /// <summary>
@@ -515,12 +1004,12 @@ function generateCSharpClassDriver(source, className, fields, description, out)
515
1004
  const propertyName = toCSharpName(fieldName);
516
1005
  let type;
517
1006
  if (field.type === "object") {
518
- strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.fields, null, out) + "\r\n";
1007
+ strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.fields, null, out) + newLine;
519
1008
  type = className + "_" + propertyName;
520
1009
  }
521
1010
  else if (field.type === "array") {
522
1011
  if (field.items.type === "object") {
523
- strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.items.fields, null, out) + "\r\n";
1012
+ strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.items.fields, null, out) + newLine;
524
1013
  type = `System.Collections.Generic.List<${className}_${propertyName}>`;
525
1014
  } else {
526
1015
  type = `System.Collections.Generic.List<${getCSharpTypeFromMushroomType(source, field.items.type, field.items.validation && field.items.validation.required)}>`;
@@ -531,7 +1020,7 @@ function generateCSharpClassDriver(source, className, fields, description, out)
531
1020
  ` /// <summary>
532
1021
  /// ${singleLine(field.description)}
533
1022
  /// </summary>
534
- [JsonProperty(PropertyName ="${fieldName}", NullValueHandling = NullValueHandling.Ignore)]
1023
+ [Newtonsoft.Json.JsonProperty(PropertyName ="${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.Datetime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
535
1024
  public ${type} ${propertyName} { get; set; }
536
1025
 
537
1026
  `;
@@ -545,43 +1034,43 @@ function generateCSharpClassDriver(source, className, fields, description, out)
545
1034
  }
546
1035
 
547
1036
 
548
- content += " }\r\n";
549
- return strClasses + "\r\n" + content;
1037
+ content += " }" + newLine;
1038
+ return strClasses + newLine + content;
550
1039
  }
551
1040
 
552
1041
  function genCSharpDriver(args, projectName, project, alias, source) {
553
1042
  const aliasProject = ((project.csharpDriver || {}).alias || {})[alias];
554
1043
 
555
1044
  if (!aliasProject) {
556
- throw new Error(`Not found gen c#-driver configuration. Please run 'npx mr config ${projectName} gen c#-driver OUTPUT_FILE.cs${alias === "default" ? "" : " alias " + alias}' first`);
1045
+ throw new Error(`Not found gen c#-driver configuration. Please run 'npx mushroom-cli config ${projectName} gen c#-driver OUTPUT_FILE.cs${alias === "default" ? "" : " alias " + alias}' first`);
557
1046
  }
558
1047
 
559
1048
  const entities = common.getEntities(source, aliasProject.allowRoles);
560
1049
 
561
- var namespace = toCSharpName(source.name);
1050
+ const namespace = toCSharpName(source.name);
562
1051
 
563
- var strClasses = "";
564
- var strEnumClasses = "";
565
- var codeStaticCtor = "";
566
- var codeStaticProperties = "";
567
- var codeConnectors = "";
568
- var codeExtraClasses = "";
1052
+ let strClasses = "";
1053
+ let strEnumClasses = "";
1054
+ let codeStaticCtor = "";
1055
+ let codeStaticProperties = "";
1056
+ let codeConnectors = "";
1057
+ let codeExtraClasses = "";
569
1058
 
570
- var out = {};
1059
+ const out = {};
571
1060
 
572
1061
  let accessModifier = aliasProject.accessModifier || "internal";
573
1062
 
574
- for (var entityName in entities) {
1063
+ for (const entityName in entities) {
575
1064
  if (!entities.hasOwnProperty(entityName))
576
1065
  continue;
577
1066
 
578
- var className = toCSharpName(entityName);
1067
+ const className = toCSharpName(entityName);
579
1068
 
580
1069
  strClasses += generateCSharpClassDriver(source, className, entities[entityName].fields, entities[entityName].description, out);
581
- codeStaticCtor += ` ${className} = new ${className}Connector(client);\r\n`;
582
- codeStaticProperties += ` public static ${className}Connector ${className} { get; }\r\n\r\n`;
1070
+ codeStaticCtor += ` ${className} = new ${className}Connector(client);${newLine}`;
1071
+ codeStaticProperties += ` public static ${className}Connector ${className} { get; }${newLine}${newLine}`;
583
1072
 
584
- var entity = entities[entityName];
1073
+ const entity = entities[entityName];
585
1074
 
586
1075
  codeConnectors += ` ${accessModifier} partial class ${className}Connector : MushroomDriver.MushroomResourceConnector<${className}>
587
1076
  {
@@ -602,7 +1091,7 @@ function genCSharpDriver(args, projectName, project, alias, source) {
602
1091
  `;
603
1092
  }
604
1093
 
605
- for (var actionName in entity.actions) {
1094
+ for (const actionName in entity.actions) {
606
1095
  if (!entity.actions.hasOwnProperty(actionName))
607
1096
  continue;
608
1097
 
@@ -689,7 +1178,7 @@ function genCSharpDriver(args, projectName, project, alias, source) {
689
1178
  if (actionName.indexOf("_raw_http_method_"))
690
1179
  break;
691
1180
 
692
- var customMethod = toCSharpName(actionName.substr("_raw_http_method_".length));
1181
+ const customMethod = toCSharpName(actionName.substring("_raw_http_method_".length));
693
1182
 
694
1183
  codeConnectors += ` public async System.Threading.Tasks.Task<${className}${customMethod}Result> ${customMethod}(${className}${customMethod}Arg arg)
695
1184
  {
@@ -738,11 +1227,11 @@ function genCSharpDriver(args, projectName, project, alias, source) {
738
1227
 
739
1228
  partial void BuildCustomUrl();
740
1229
 
741
- private string OriginUrl => "${entityName}s/${actionName.substr("_raw_http_method_".length)}";
1230
+ private string OriginUrl => "${entityName}s/${actionName.substring("_raw_http_method_".length)}";
742
1231
 
743
- private string CustomUrl { get; set; } = "${entityName}s/${actionName.substr("_raw_http_method_".length)}";
1232
+ private string CustomUrl { get; set; } = "${entityName}s/${actionName.substring("_raw_http_method_".length)}";
744
1233
 
745
- public override string Method { get; } = "${actionName.substr("_raw_http_method_".length)}";
1234
+ public override string Method { get; } = "${actionName.substring("_raw_http_method_".length)}";
746
1235
 
747
1236
  public ${className}${customMethod}Body Data { get; set; }
748
1237
 
@@ -794,10 +1283,10 @@ function genCSharpDriver(args, projectName, project, alias, source) {
794
1283
  {
795
1284
  `;
796
1285
  view.parameters.forEach(p => {
797
- var type = getCSharpTypeFromMushroomType(source, p.type, p.validation && p.validation.required);
1286
+ let type = getCSharpTypeFromMushroomType(source, p.type, p.validation && p.validation.required);
798
1287
  if (p.isArray)
799
1288
  type = `System.Collections.Generic.List<${type}>`;
800
- viewExtraClass += ` [JsonProperty(PropertyName = "${p.field}")]
1289
+ viewExtraClass += ` [Newtonsoft.Json.JsonProperty(PropertyName = "${p.field}")]
801
1290
  public ${type} ${toCSharpName(p.field)} { get; set; }
802
1291
 
803
1292
  `;
@@ -833,15 +1322,15 @@ function genCSharpDriver(args, projectName, project, alias, source) {
833
1322
  ${viewExtraClass}`;
834
1323
  }
835
1324
 
836
- codeConnectors += " }\r\n\r\n";
1325
+ codeConnectors += " }" + newLine + newLine;
837
1326
  }
838
1327
 
839
1328
  if (out.strEnumClasses)
840
1329
  strEnumClasses += out.strEnumClasses;
841
1330
 
842
- const code = `// This file was generated by Mushroom CLI (https://www.npmjs.com/package/mushroom-cli), please do not modify
1331
+ const code = `// This file was generated by Mushroom CLI ${package_json.version} (https://www.npmjs.com/package/mushroom-cli), please do not modify
843
1332
 
844
- // Require package: Mushroom.Driver version 1.4.0 or later https://www.nuget.org/packages/Mushroom.Driver/
1333
+ // Require package: Mushroom.Driver version 1.4.0 or later (https://www.nuget.org/packages/Mushroom.Driver/)
845
1334
 
846
1335
  // ReSharper disable InconsistentNaming
847
1336
  // ReSharper disable PartialTypeWithSinglePart