mushroom-cli 1.1.0-alpha.2 → 1.1.0-alpha.20

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
@@ -3,6 +3,25 @@ const common = require("../common.js");
3
3
  const package = 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 "";
@@ -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) {
@@ -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++) {
@@ -143,7 +164,8 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
143
164
  content +=
144
165
  ` /// <summary>
145
166
  /// ${singleLine(description)}
146
- /// </summary>\r\n`;
167
+ /// </summary>
168
+ `;
147
169
  }
148
170
  var supperClass = "";
149
171
  if (isRoot) {
@@ -171,12 +193,12 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
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
  }
@@ -233,14 +255,14 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
233
255
  //console.log("strEnumClasses("+typeof(strEnumClasses)+"):" + strEnumClasses);
234
256
  }
235
257
 
236
- return strClasses + "\r\n" + content;
258
+ return strClasses + newLine + content;
237
259
  }
238
260
 
239
261
  function getCSharpFunc(methodName, methodType) {
240
262
  if (methodType === "static") return methodName;
241
263
  const idx = methodName.lastIndexOf('.');
242
264
  if (idx === -1) return methodName;
243
- return `new ${methodName.substr(0, idx)}()${methodName.substr(idx)}`;
265
+ return `new ${methodName.substring(0, idx)}()${methodName.substring(idx)}`;
244
266
  }
245
267
 
246
268
  function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
@@ -250,6 +272,11 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
250
272
  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`);
251
273
  }
252
274
 
275
+ if (aliasProject.outputToFolder) {
276
+ genCSharpMongoDbClassesToFolder(projectName, alias, source, aliasProject);
277
+ return;
278
+ }
279
+
253
280
  const entities = common.getEntities(source, aliasProject.allowRoles, true);
254
281
 
255
282
  const namespace = toCSharpName(source.name);
@@ -258,6 +285,17 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
258
285
  let strEnumClasses = "";
259
286
  let collectionNames = "";
260
287
  let resourceNames = "";
288
+ let roleNames = "";
289
+
290
+ source.roles?.forEach(role => {
291
+ if (!role.name) return;
292
+ roleNames += `
293
+ /// <summary>
294
+ /// ${role.description ?? ""}
295
+ /// </summary>
296
+ public static string ${toCSharpName(role.name)} => "${role.name}";
297
+ `;
298
+ });
261
299
 
262
300
  const out = {};
263
301
  for (let entityName in entities) {
@@ -268,7 +306,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
268
306
  collectionNames += ` public static string ${className}CollectionName => "${entities[entityName].storageName}";
269
307
  public static IMongoCollection<Resources.${className}> ${className}Collection => GetDatabase().GetCollection<Resources.${className}>(${className}CollectionName);
270
308
  `;
271
- resourceNames += ` public static string ${className} => "${entityName}";\r\n`;
309
+ resourceNames += ` public static string ${className} => "${entityName}";${newLine}`;
272
310
  strClasses += generateCSharpClassMongoDb(source, className, entities[entityName].fields, true, entities[entityName].description, out);
273
311
 
274
312
  const actions = entities[entityName].actions || {};
@@ -360,7 +398,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
360
398
  }
361
399
  return prev;
362
400
  }, {});
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");
401
+ 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
402
 
365
403
  const viewHandlers = (out.viewHandlers || []).reduce((prev, cur) => {
366
404
  if (cur.method in prev) {
@@ -373,7 +411,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
373
411
  }
374
412
  return prev;
375
413
  }, {});
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");
414
+ 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);
377
415
 
378
416
  const eventHandlers = (out.eventHandlers || []).reduce((prev, cur) => {
379
417
  if (cur.method in prev) {
@@ -386,18 +424,18 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
386
424
  }
387
425
  return prev;
388
426
  }, {});
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");
427
+ 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
428
 
391
429
  const strJobReferences = Array.isArray(source.jobs)
392
430
  ? source.jobs
393
431
  .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")
432
+ .map(job => ` RegisterJob<${job.action.substring(4).split(',')[0]}>();`)
433
+ .join(newLine)
396
434
  : "";
397
435
 
398
436
  const code = `// This file was generated by Mushroom CLI ${package.version} (https://www.npmjs.com/package/mushroom-cli), please do not modify
399
437
 
400
- // NOTE: Compatible with Mushroom Server version 0.2.18 or higher
438
+ // NOTE: Compatible with Mushroom Server version 0.2.18 or higher (https://www.nuget.org/packages/Mushroom/)
401
439
 
402
440
  // ReSharper disable RedundantUsingDirective
403
441
  // ReSharper disable InconsistentNaming
@@ -410,14 +448,10 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
410
448
  // ReSharper disable CommentTypo
411
449
  // ReSharper disable EmptyNamespace
412
450
 
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
451
  namespace ${namespace}
420
452
  {
453
+ using MongoDB.Driver;
454
+
421
455
  public static class DbConnector
422
456
  {
423
457
  ${collectionNames}
@@ -439,10 +473,18 @@ ${collectionNames}
439
473
  }
440
474
  }
441
475
 
442
- public static class ResourceNames
476
+ public class ResourceNames
443
477
  {
478
+ private ResourceNames() { }
479
+
444
480
  ${resourceNames}
445
481
  }
482
+
483
+ public class RoleNames {
484
+ private RoleNames() { }
485
+
486
+ ${roleNames}
487
+ }
446
488
  }
447
489
 
448
490
  namespace ${namespace}.Resources
@@ -488,6 +530,402 @@ ${strJobReferences}
488
530
  console.log(`Generated CSharp MongoDb Classes for ${projectName}@${alias} to ${aliasProject.output}`);
489
531
  });
490
532
  }
533
+
534
+ function generateCSharpClassMongoDbToFolder(source, className, fields, isRoot, description, out, aliasProject) {
535
+ var content = "";
536
+ const namespace = toCSharpName(source.name);
537
+ if (description) {
538
+ content +=
539
+ ` /// <summary>
540
+ /// ${singleLine(description)}
541
+ /// </summary>
542
+ `;
543
+ }
544
+ var supperClass = "";
545
+ if (isRoot) {
546
+ // thêm cho trường hợp không khai báo id hoặc id.type
547
+ if (!fields.id) {
548
+ fields.id = {
549
+ type: "AutoId"
550
+ };
551
+ }
552
+ if (!fields.id.type) fields.id.type = "AutoId";
553
+
554
+ supperClass = " : Mushroom.Models.IResource<" + getCSharpTypeFromMushroomType(source, fields.id.type, true) + ">";
555
+ }
556
+ content += ` public class ${className}${supperClass}
557
+ {
558
+ `;
559
+ for (var fieldName in fields) {
560
+ if (!fields.hasOwnProperty(fieldName))
561
+ continue;
562
+
563
+ var field = fields[fieldName];
564
+ var type;
565
+ var propertyName = toCSharpName(fieldName);
566
+ if (field.codeHint && field.codeHint.type && field.codeHint.type.csharp) {
567
+ type = field.codeHint.type.csharp;
568
+ }
569
+ else if (field.type === "object") {
570
+ generateCSharpClassMongoDbToFolder(source, className + "_" + propertyName, field.fields, false, null, out, aliasProject) + newLine;
571
+ type = className + "_" + propertyName;
572
+ }
573
+ else if (field.type === "array") {
574
+ if (field.items.type === "object") {
575
+ generateCSharpClassMongoDbToFolder(source, className + "_" + propertyName, field.items.fields, false, null, out, aliasProject) + newLine;
576
+ type = `System.Collections.Generic.List<${className}_${propertyName}>`;
577
+ } else {
578
+ type = `System.Collections.Generic.List<${getCSharpTypeFromMushroomType(source, field.items.type, field.items.validation && field.items.validation.required)}>`;
579
+ }
580
+ } else
581
+ type = getCSharpTypeFromMushroomType(source, field.type, field.validation && field.validation.required);
582
+ content +=
583
+ ` /// <summary>
584
+ /// ${singleLine(field.description)}
585
+ /// </summary>
586
+ `;
587
+
588
+ if (isRoot && fieldName === "id") {
589
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonId${field.type === "AutoId" && source.idType === "GUID" ? "(IdGenerator = typeof(MongoDB.Bson.Serialization.IdGenerators.GuidGenerator))" : ""}]${newLine}`;
590
+ }
591
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonElement("${isRoot && fieldName === "id" ? "_id" : fieldName}")]
592
+ [MongoDB.Bson.Serialization.Attributes.BsonIgnoreIfNull]
593
+ [Newtonsoft.Json.JsonProperty(PropertyName = "${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.DateTime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
594
+ `;
595
+ if ((field.type === "AutoId" || field.type === "IdRef") && source.idType === "ObjectId") {
596
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
597
+ }
598
+ if (field.type === "AutoId" && source.idType === "GUID") {
599
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]" + newLine;
600
+ }
601
+ if (field.type === "datetime") {
602
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]" + newLine;
603
+ }
604
+ if (field.type === "array") {
605
+ if ((field.items.type === "AutoId" || field.items.type === "IdRef") && source.idType === "ObjectId") {
606
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
607
+ }
608
+ if (field.items.type === "AutoId" && source.idType === "GUID") {
609
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]" + newLine;
610
+ }
611
+ if (field.items.type === "datetime") {
612
+ content += " [MongoDB.Bson.Serialization.Attributes.BsonDateTimeOptions(Kind = System.DateTimeKind.Local)]" + newLine;
613
+ }
614
+ }
615
+
616
+ content += ` public ${type} ${propertyName} { get; set; }
617
+
618
+ `;
619
+
620
+ let strEnumClasses = generateEnumClass(source, {}, field, `${className.toUpperCase()}_${propertyName.toUpperCase()}_ENUM`);
621
+
622
+ const match = strEnumClasses.match(/public class\s+(\w+)/);
623
+ if (!match) continue;
624
+ common.ensureFolder(aliasProject.output + "/Enums", true);
625
+ strEnumClasses = `${header}
626
+
627
+ namespace ${namespace}.Enums
628
+ {
629
+ ${strEnumClasses}
630
+ }
631
+ `;
632
+
633
+ fs.writeFileSync(aliasProject.output + "/Enums/" + match[1] + ".cs", strEnumClasses);
634
+ }
635
+
636
+ content += ` [MongoDB.Bson.Serialization.Attributes.BsonExtraElements]
637
+ [Newtonsoft.Json.JsonIgnore]
638
+ public System.Collections.Generic.Dictionary<string, object> Mushroom_ExtraProperties { get; set; }
639
+
640
+ }
641
+ `;
642
+
643
+ //return strClasses + newLine + content;
644
+ common.ensureFolder(aliasProject.output + "/Resources", true);
645
+
646
+ content = `${header}
647
+
648
+ namespace ${namespace}.Resources
649
+ {
650
+ ${content}
651
+ }
652
+ `;
653
+
654
+ out.allClasses = out.allClasses || [];
655
+
656
+ const normalizedName = className.toLowerCase();
657
+ const duplicate = out.allClasses.find(c => c.normalizedName == normalizedName);
658
+ if (duplicate) {
659
+ fs.appendFileSync(aliasProject.output + "/Resources/" + duplicate.className + ".cs", content);
660
+ }
661
+ else {
662
+ out.allClasses.push({
663
+ className,
664
+ normalizedName
665
+ });
666
+ fs.writeFileSync(aliasProject.output + "/Resources/" + className + ".cs", content);
667
+ }
668
+ }
669
+
670
+ function genCSharpMongoDbClassesToFolder(projectName, alias, source, aliasProject) {
671
+
672
+ if (fs.existsSync(aliasProject.output)) {
673
+ try {
674
+ fs.unlinkSync(aliasProject.output); // xóa file nếu có
675
+ } catch(e) {}
676
+ try {
677
+ fs.rmdirSync(aliasProject.output, { recursive: true, force: true }); // xóa thư mục nếu có
678
+ } catch(e) {}
679
+ }
680
+ fs.mkdirSync(aliasProject.output, { recursive: true, mode: 0755 });
681
+
682
+ const entities = common.getEntities(source, aliasProject.allowRoles, true);
683
+
684
+ const namespace = toCSharpName(source.name);
685
+
686
+ let collectionNames = "";
687
+ let resourceNames = "";
688
+ let roleNames = "";
689
+
690
+ source.roles?.forEach(role => {
691
+ if (!role.name) return;
692
+ roleNames += `
693
+ /// <summary>
694
+ /// ${role.description ?? ""}
695
+ /// </summary>
696
+ public static string ${toCSharpName(role.name)} => "${role.name}";
697
+ `;
698
+ });
699
+
700
+ const out = {};
701
+ for (let entityName in entities) {
702
+ if (!entities.hasOwnProperty(entityName))
703
+ continue;
704
+
705
+ const className = toCSharpName(entityName);
706
+ collectionNames += ` public static string ${className}CollectionName => "${entities[entityName].storageName}";
707
+ public static IMongoCollection<Resources.${className}> ${className}Collection => GetDatabase().GetCollection<Resources.${className}>(${className}CollectionName);
708
+ `;
709
+ resourceNames += ` public static string ${className} => "${entityName}";
710
+ `;
711
+ //strClasses += generateCSharpClassMongoDbToFolder(source, className, entities[entityName].fields, true, entities[entityName].description, out);
712
+
713
+ generateCSharpClassMongoDbToFolder(source, className, entities[entityName].fields, true, entities[entityName].description, out, aliasProject);
714
+
715
+ const actions = entities[entityName].actions || {};
716
+ for (let actionName in actions) {
717
+ const action = actions[actionName];
718
+ if (!Array.isArray(action))
719
+ continue;
720
+
721
+ action.forEach(a => {
722
+ if (!a)
723
+ return;
724
+ if (typeof a.delegator === "string" && a.delegator.indexOf("lib:") === 0) {
725
+ out.delegators = out.delegators || [];
726
+ const method = a.delegator.substr(4, a.delegator.length - 4);
727
+ let type = a.codeHint && a.codeHint.delegator && a.codeHint.delegator.csharp
728
+ ? a.codeHint.delegator.csharp.methodType
729
+ : null;
730
+ if (type !== "non-static") type = "static";
731
+ out.delegators.push({
732
+ method: method,
733
+ source: `entity: ${entityName}, action: ${actionName}, grant: ${a.grant}`,
734
+ type: type
735
+ });
736
+ }
737
+
738
+ if (!a.events && !(typeof a.events === "object")) return;
739
+
740
+ for (let eventName in a.events) {
741
+ if (!Array.isArray(a.events[eventName])) return;
742
+
743
+ out.eventHandlers = out.eventHandlers || [];
744
+ a.events[eventName].forEach((ev, i) => {
745
+ if (typeof ev !== "string" || ev.indexOf("lib:") !== 0) return;
746
+ const method = ev.substr(4, ev.length - 4);
747
+ let type = a.codeHint && a.codeHint.events
748
+ && Array.isArray(a.codeHint.events[eventName])
749
+ && a.codeHint.events[eventName][i]
750
+ && a.codeHint.events[eventName][i].csharp
751
+ ? a.codeHint.events[eventName][i].csharp.methodType
752
+ : null;
753
+ if (type !== "non-static") type = "static";
754
+ out.eventHandlers.push({
755
+ method: method,
756
+ source: `entity: ${entityName}, action: ${actionName}, grant: ${a.grant}, event: ${eventName}`,
757
+ type: type
758
+ });
759
+ });
760
+ }
761
+ });
762
+ }
763
+
764
+ const views = entities[entityName].views || {};
765
+ for (let viewName in views) {
766
+ const view = views[viewName];
767
+ if (!Array.isArray(view))
768
+ continue;
769
+
770
+ view.forEach(v => {
771
+ if (!v) return;
772
+
773
+ if (typeof v.query === "string" && v.query.indexOf("lib:") === 0) {
774
+ out.viewHandlers = out.viewHandlers || [];
775
+ const method = v.query.substr(4, v.query.length - 4);
776
+ let type = v.codeHint && v.codeHint.query && v.codeHint.query.csharp
777
+ ? v.codeHint.query.csharp.methodType
778
+ : null;
779
+ if (type !== "non-static") type = "static";
780
+ out.viewHandlers.push({
781
+ method: method,
782
+ source: `entity: ${entityName}, view: ${viewName}, grant: ${v.grant}`,
783
+ type: type
784
+ });
785
+ }
786
+ });
787
+ }
788
+ }
789
+
790
+
791
+ const delegators = (out.delegators || []).reduce((prev, cur) => {
792
+ if (cur.method in prev) {
793
+ if (prev[cur.method].indexOf(cur.source) === -1) {
794
+ prev[cur.method].push(cur);
795
+ }
796
+ }
797
+ else {
798
+ prev[cur.method] = [cur];
799
+ }
800
+ return prev;
801
+ }, {});
802
+ 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);
803
+
804
+ const viewHandlers = (out.viewHandlers || []).reduce((prev, cur) => {
805
+ if (cur.method in prev) {
806
+ if (prev[cur.method].indexOf(cur.source) === -1) {
807
+ prev[cur.method].push(cur);
808
+ }
809
+ }
810
+ else {
811
+ prev[cur.method] = [cur];
812
+ }
813
+ return prev;
814
+ }, {});
815
+ 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);
816
+
817
+ const eventHandlers = (out.eventHandlers || []).reduce((prev, cur) => {
818
+ if (cur.method in prev) {
819
+ if (prev[cur.method].indexOf(cur.source) === -1) {
820
+ prev[cur.method].push(cur);
821
+ }
822
+ }
823
+ else {
824
+ prev[cur.method] = [cur];
825
+ }
826
+ return prev;
827
+ }, {});
828
+ 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);
829
+
830
+ const strJobReferences = Array.isArray(source.jobs)
831
+ ? source.jobs
832
+ .filter(job => job !== null && typeof(job) === "object" && job.action && typeof (job.action) === "string" && job.action.indexOf("lib:") === 0)
833
+ .map(job => ` RegisterJob<${job.action.substring(4).split(',')[0]}>();`)
834
+ .join(newLine)
835
+ : "";
836
+
837
+ const dbConnectorFileContent = `${header}
838
+ using MongoDB.Driver;
839
+
840
+ namespace ${namespace}
841
+ {
842
+ public static class DbConnector
843
+ {
844
+ ${collectionNames}
845
+ public static IMongoDatabase GetDatabase() => Mushroom.MushroomDaoFactory.GetDbAdapter() as IMongoDatabase;
846
+
847
+ public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id) where T : Mushroom.Models.IResource<TId>
848
+ {
849
+ return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id))).FirstOrDefaultAsync();
850
+ }
851
+
852
+ public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id, FindOptions<T> findOptions) where T : Mushroom.Models.IResource<TId>
853
+ {
854
+ return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), findOptions)).FirstOrDefaultAsync();
855
+ }
856
+
857
+ public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id, ProjectionDefinition<T> projection) where T : Mushroom.Models.IResource<TId>
858
+ {
859
+ return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), new FindOptions<T> { Projection = projection })).FirstOrDefaultAsync();
860
+ }
861
+ }
862
+ }
863
+ `;
864
+
865
+ const resourceNamesFileContent = `${header}
866
+
867
+ namespace ${namespace}
868
+ {
869
+ public class ResourceNames
870
+ {
871
+ private ResourceNames() { }
872
+
873
+ ${resourceNames}
874
+ }
875
+ }
876
+ `;
877
+
878
+ const roleNamesFileContent = `${header}
879
+
880
+ namespace ${namespace}
881
+ {
882
+ public class RoleNames
883
+ {
884
+ private RoleNames() { }
885
+
886
+ ${roleNames}
887
+ }
888
+ }
889
+ `;
890
+
891
+
892
+ const refactorHelperFileContent = `${header}
893
+
894
+ #if DEBUG
895
+ namespace ${namespace}
896
+ {
897
+ class RefactorHelper
898
+ {
899
+ private RefactorHelper() { }
900
+ private void RegisterCustomMethod(System.Func<Mushroom.ActionArguments, System.Threading.Tasks.Task> fn) { }
901
+ private void RegisterCustomMethod(System.Action<Mushroom.ActionArguments> fn) { }
902
+ private void RegisterCustomViewMethod(System.Func<Mushroom.ViewArguments, System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<object>>> fn) { }
903
+ private void RegisterCustomViewMethod(System.Action<Mushroom.ViewArguments> fn) { }
904
+ private void RegisterEvent(System.Func<object, Mushroom.ActionArguments, System.Threading.Tasks.Task> fn) { }
905
+ private void RegisterEvent(System.Action<object, Mushroom.ActionArguments> fn) { }
906
+ private void RegisterJob<T>() where T : Mushroom.Job.JobBase { }
907
+ private void Help()
908
+ {
909
+ ${strDelegatorReferences}
910
+ ${strViewHandlerReferences}
911
+ ${strEventHandlerReferences}
912
+ ${strJobReferences}
913
+ }
914
+ }
915
+ }
916
+ #endif
917
+ `;
918
+
919
+ const infoFileContent = `// Mushroom CLI version: ${package.version}${newLine}// Compatible with Mushroom Server version: 0.2.18 or higher (https://www.nuget.org/packages/Mushroom/)`
920
+
921
+ fs.writeFileSync(aliasProject.output + "/DbConnector.cs", dbConnectorFileContent);
922
+ fs.writeFileSync(aliasProject.output + "/ResourceNames.cs", resourceNamesFileContent);
923
+ fs.writeFileSync(aliasProject.output + "/RoleNames.cs", roleNamesFileContent);
924
+ fs.writeFileSync(aliasProject.output + "/RefactorHelper.cs", refactorHelperFileContent);
925
+ fs.writeFileSync(aliasProject.output + "/Info.cs", infoFileContent);
926
+
927
+ console.log(`Generated CSharp MongoDb Classes for ${projectName}@${alias} to folder ${aliasProject.output}`);
928
+ }
491
929
  //#endregion
492
930
 
493
931
  //#region CSharp Driver
@@ -515,12 +953,12 @@ function generateCSharpClassDriver(source, className, fields, description, out)
515
953
  const propertyName = toCSharpName(fieldName);
516
954
  let type;
517
955
  if (field.type === "object") {
518
- strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.fields, null, out) + "\r\n";
956
+ strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.fields, null, out) + newLine;
519
957
  type = className + "_" + propertyName;
520
958
  }
521
959
  else if (field.type === "array") {
522
960
  if (field.items.type === "object") {
523
- strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.items.fields, null, out) + "\r\n";
961
+ strClasses += generateCSharpClassDriver(source, className + "_" + propertyName, field.items.fields, null, out) + newLine;
524
962
  type = `System.Collections.Generic.List<${className}_${propertyName}>`;
525
963
  } else {
526
964
  type = `System.Collections.Generic.List<${getCSharpTypeFromMushroomType(source, field.items.type, field.items.validation && field.items.validation.required)}>`;
@@ -531,7 +969,7 @@ function generateCSharpClassDriver(source, className, fields, description, out)
531
969
  ` /// <summary>
532
970
  /// ${singleLine(field.description)}
533
971
  /// </summary>
534
- [JsonProperty(PropertyName ="${fieldName}", NullValueHandling = NullValueHandling.Ignore)]
972
+ [Newtonsoft.Json.JsonProperty(PropertyName ="${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.Datetime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
535
973
  public ${type} ${propertyName} { get; set; }
536
974
 
537
975
  `;
@@ -545,8 +983,8 @@ function generateCSharpClassDriver(source, className, fields, description, out)
545
983
  }
546
984
 
547
985
 
548
- content += " }\r\n";
549
- return strClasses + "\r\n" + content;
986
+ content += " }" + newLine;
987
+ return strClasses + newLine + content;
550
988
  }
551
989
 
552
990
  function genCSharpDriver(args, projectName, project, alias, source) {
@@ -578,8 +1016,8 @@ function genCSharpDriver(args, projectName, project, alias, source) {
578
1016
  var className = toCSharpName(entityName);
579
1017
 
580
1018
  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`;
1019
+ codeStaticCtor += ` ${className} = new ${className}Connector(client);${newLine}`;
1020
+ codeStaticProperties += ` public static ${className}Connector ${className} { get; }${newLine}${newLine}`;
583
1021
 
584
1022
  var entity = entities[entityName];
585
1023
 
@@ -689,7 +1127,7 @@ function genCSharpDriver(args, projectName, project, alias, source) {
689
1127
  if (actionName.indexOf("_raw_http_method_"))
690
1128
  break;
691
1129
 
692
- var customMethod = toCSharpName(actionName.substr("_raw_http_method_".length));
1130
+ var customMethod = toCSharpName(actionName.substring("_raw_http_method_".length));
693
1131
 
694
1132
  codeConnectors += ` public async System.Threading.Tasks.Task<${className}${customMethod}Result> ${customMethod}(${className}${customMethod}Arg arg)
695
1133
  {
@@ -738,11 +1176,11 @@ function genCSharpDriver(args, projectName, project, alias, source) {
738
1176
 
739
1177
  partial void BuildCustomUrl();
740
1178
 
741
- private string OriginUrl => "${entityName}s/${actionName.substr("_raw_http_method_".length)}";
1179
+ private string OriginUrl => "${entityName}s/${actionName.substring("_raw_http_method_".length)}";
742
1180
 
743
- private string CustomUrl { get; set; } = "${entityName}s/${actionName.substr("_raw_http_method_".length)}";
1181
+ private string CustomUrl { get; set; } = "${entityName}s/${actionName.substring("_raw_http_method_".length)}";
744
1182
 
745
- public override string Method { get; } = "${actionName.substr("_raw_http_method_".length)}";
1183
+ public override string Method { get; } = "${actionName.substring("_raw_http_method_".length)}";
746
1184
 
747
1185
  public ${className}${customMethod}Body Data { get; set; }
748
1186
 
@@ -797,7 +1235,7 @@ function genCSharpDriver(args, projectName, project, alias, source) {
797
1235
  var type = getCSharpTypeFromMushroomType(source, p.type, p.validation && p.validation.required);
798
1236
  if (p.isArray)
799
1237
  type = `System.Collections.Generic.List<${type}>`;
800
- viewExtraClass += ` [JsonProperty(PropertyName = "${p.field}")]
1238
+ viewExtraClass += ` [Newtonsoft.Json.JsonProperty(PropertyName = "${p.field}")]
801
1239
  public ${type} ${toCSharpName(p.field)} { get; set; }
802
1240
 
803
1241
  `;
@@ -833,15 +1271,15 @@ function genCSharpDriver(args, projectName, project, alias, source) {
833
1271
  ${viewExtraClass}`;
834
1272
  }
835
1273
 
836
- codeConnectors += " }\r\n\r\n";
1274
+ codeConnectors += " }" + newLine + newLine;
837
1275
  }
838
1276
 
839
1277
  if (out.strEnumClasses)
840
1278
  strEnumClasses += out.strEnumClasses;
841
1279
 
842
- const code = `// This file was generated by Mushroom CLI (https://www.npmjs.com/package/mushroom-cli), please do not modify
1280
+ const code = `// This file was generated by Mushroom CLI ${package.version} (https://www.npmjs.com/package/mushroom-cli), please do not modify
843
1281
 
844
- // Require package: Mushroom.Driver version 1.4.0 or later https://www.nuget.org/packages/Mushroom.Driver/
1282
+ // Require package: Mushroom.Driver version 1.4.0 or later (https://www.nuget.org/packages/Mushroom.Driver/)
845
1283
 
846
1284
  // ReSharper disable InconsistentNaming
847
1285
  // ReSharper disable PartialTypeWithSinglePart