mushroom-cli 1.2.0-alpha.4 → 1.2.0-alpha.6

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/README.md CHANGED
@@ -88,6 +88,23 @@ Disable checking for update:
88
88
 
89
89
  ## Version
90
90
 
91
+ ### 1.2.0-alpha.6
92
+
93
+ New features:
94
+
95
+ * gen-ts-driver: Support offline mode
96
+
97
+ Changes:
98
+
99
+ * gen-api-docs: Improve generating api-docs
100
+ * gen-csharp: Generate resource classes with `partial`
101
+
102
+ ### 1.2.0-alpha.5
103
+
104
+ New features:
105
+
106
+ * Improve documentation generation: view, custom action.
107
+
91
108
  ### 1.2.0-alpha.4
92
109
 
93
110
  Fixed bugs:
package/docs/doc-mt.js CHANGED
@@ -279,6 +279,107 @@ function formatModal(obj, strIndent, options) {
279
279
  return result;
280
280
  }
281
281
 
282
+ function formatHintModal(obj, strIndent, options) {
283
+ if (!obj)
284
+ return "";
285
+
286
+ strIndent = strIndent || "";
287
+ options = options || {};
288
+
289
+ var result = "";
290
+ var nextIndent = strIndent + " ";
291
+ for (var m in obj) {
292
+ if (!obj.hasOwnProperty(m))
293
+ continue;
294
+
295
+ var child = obj[m];
296
+
297
+ var validation = !options.optionalToAll && child.required ? "required" : "optional";
298
+ if (child.type === "IdRef" && child.reference) {
299
+ validation += ", ref: <a href='#" + encodeHtml(child.reference) + "' onclick='setTimeout(gotoHash, 20)'>" + encodeHtml(child.reference) + "</a>";
300
+ }
301
+
302
+ if (child.validValues && Array.isArray(child.validValues)) {
303
+ validation += ", enum(" + encodeHtml(child.validValues.join(", ")) + ")";
304
+ }
305
+
306
+ if (child.type === "array" && child.items && child.items.type != "object") {
307
+ validation += ", array items: " + (!options.optionalToAll && child.items.required ? "required" : "optional");
308
+ if (child.items.validValues && Array.isArray(child.items.validValues))
309
+ validation += ", enum(" + encodeHtml(child.items.validValues.join(", ")) + ")";
310
+ }
311
+
312
+ var comment = `<span class="code-comment">// ${validation} ${typeof child.description === "string" && child.description !== "" ? "- " + encodeHtml(child.description) : ""}</span>`;
313
+
314
+ if (options.mode === "modal") {
315
+ if (child.type === "object")
316
+ result += "\r\n" + nextIndent + '"' + m + '": ' + comment + formatHintModal(child.fields, nextIndent, options) + ",";
317
+ else if (child.type === "array") {
318
+ result += `\r\n${nextIndent}"${m}": [`;
319
+ if (child.items.type === "object")
320
+ result += " " + comment + formatHintModal(child.items.fields, nextIndent, options);
321
+ else if (child.items.type === "datetime")
322
+ result += `\r\n${nextIndent} ` + JSON.stringify(child.items.defaultValue || "ISODate_ISO_8601") + " " + comment + `\r\n${nextIndent}`;
323
+ else if (child.items.type === "boolean")
324
+ result += `\r\n${nextIndent} ` + child.items.defaultValue || "false" + " " + comment + `\r\n${nextIndent}`;
325
+ else if (child.items.type === "integer" || child.items.type === "long"|| child.items.type === "double")
326
+ result += `\r\n${nextIndent} ` + child.items.defaultValue || "0" + " " + comment + `\r\n${nextIndent}`;
327
+ else
328
+ result += `\r\n${nextIndent} ` + JSON.stringify(child.defaultValue || child.type) + " " + comment + `\r\n${nextIndent}`;
329
+ result += `]`;
330
+ }
331
+ else if (child.type === "datetime")
332
+ result += `\r\n${nextIndent}"${m}": ` + JSON.stringify(child.defaultValue || "ISODate_ISO_8601") + ", " + comment;
333
+ else if (child.type === "boolean")
334
+ result += `\r\n${nextIndent}"${m}": ` + (child.defaultValue || "false") + ", " + comment;
335
+ else if (child.type === "integer" || child.type === "long"|| child.type === "double")
336
+ result += `\r\n${nextIndent}"${m}": ` + (child.defaultValue || "0") + ", " + comment;
337
+ else
338
+ result += `\r\n${nextIndent}"${m}": ` + JSON.stringify(child.defaultValue || child.type) + ", " + comment;
339
+ } else if (options.mode === "modal_null") {
340
+ if (child.type === "object")
341
+ result += "\r\n" + nextIndent + '"' + m + '": ' + comment + formatHintModal(child.fields, nextIndent, options);
342
+ else if (child.type === "array") {
343
+ result += `\r\n${nextIndent}"${m}": [`;
344
+ if (child.items.type === "object")
345
+ result += " " + comment + formatHintModal(child.items.fields, nextIndent, options) + "],";
346
+ else
347
+ result += "], " + comment;
348
+ }
349
+ else
350
+ result += `\r\n${nextIndent}"${m}": null, ${comment}`;
351
+ } else if (options.mode === "modal_undefined") {
352
+ if (child.type === "object")
353
+ result += "\r\n" + nextIndent + '"' + m + '": ' + comment + formatHintModal(child.fields, nextIndent, options);
354
+ else if (child.type === "array") {
355
+ result += `\r\n${nextIndent}"${m}": [`;
356
+ if (child.items.type === "object")
357
+ result += " " + comment + formatHintModal(child.items.fields, nextIndent, options) + "], ";
358
+ else
359
+ result += "], " + comment;
360
+ }
361
+ else
362
+ result += `\r\n${nextIndent}"${m}": undefined, ${comment}`;
363
+ } else {
364
+ result += "\r\n" + strIndent + encodeHtml(m) + ": " + encodeHtml(child.type);
365
+ if (child.type === "array")
366
+ result += child.items.type === "object" ? " of object" : " of " + child.items.type;
367
+ if (child.type === "object")
368
+ result += " " + comment + formatHintModal(child.fields, strIndent + " ", options);
369
+ else if (child.type === "array" && child.items.type === "object")
370
+ result += " " + comment + formatHintModal(child.items.fields, strIndent + " ", options);
371
+ else
372
+ result += ", " + comment;
373
+ }
374
+ }
375
+
376
+ if (options.mode === "modal" || options.mode === "modal_null" || options.mode === "modal_undefined") {
377
+ return (strIndent ? "\r\n" + strIndent : "") + "{" + result + "\r\n" + strIndent + "}";
378
+ }
379
+
380
+ return result;
381
+ }
382
+
282
383
  function explainRoles(strRoles) {
283
384
  if (!strRoles)
284
385
  return "";
package/docs/docs.html CHANGED
@@ -384,11 +384,17 @@
384
384
  <code data-mt-cond='{"action.pagingType": "Page"}'>Theo page number</code>
385
385
  </div>
386
386
  <div data-mt-cond='{"action.pagingType": {"$exists": true, "$ne": "None"}}'>
387
- Số lượng <span data-mt-attr='{"text": "$entityName"}'></span> mặc định trả về trong 1 trang:
388
- <code data-mt-cond='{"action.pageSize": {"$exists": true}}' data-mt-attr='{"text": "$action.pageSize"}'></code>
389
- <code data-mt-cond='{"action.pageSize": {"$exists": false}}'>25</code>
387
+ Số lượng <span data-mt-attr='{"text": "$entityName"}'></span> mặc định trả về trong 1 trang:
388
+ <code data-mt-cond='{"action.maxPageSize": {"$exists": false}, "action.pageSize": {"$exists": false}}'>25</code>
389
+ <code data-mt-cond='{"action.maxPageSize": {"$exists": false}, "action.pageSize": {"$exists": true}}' data-mt-attr='{"text": "$action.pageSize"}'></code>
390
+ <code data-mt-cond='{"action.maxPageSize": {"$exists": true}}'>
391
+ <span data-mt-cond='{"action.pageSize": {"$exists": false}, "action.maxPageSize": {"$lt": 25}}' data-mt-attr='{"text": "$action.maxPageSize"}'></span>
392
+ <span data-mt-cond='{"action.pageSize": {"$exists": false}, "action.maxPageSize": {"$gte": 25}}'>25</span>
393
+ <span data-mt-cond='{"action.pageSize": {"$exists": true}, "action.maxPageSize": {"$lt": "$action.pageSize"}}' data-mt-attr='{"text": "$action.maxPageSize"}'></span>
394
+ <span data-mt-cond='{"action.pageSize": {"$exists": true}, "action.maxPageSize": {"$gte": "$action.pageSize"}}' data-mt-attr='{"text": "$action.pageSize"}'></span>
395
+ </code>
390
396
  <div data-mt-cond='{"action.maxPageSize": {"$exists": true}}'>
391
- limit, pageSize có thể nhận giá trị tối đa: <code data-mt-attr='{"text": "$action.pageSize"}'></code>
397
+ <code>limit</code> có thể nhận giá trị tối đa: <code data-mt-attr='{"text": "$action.maxPageSize"}'></code>
392
398
  </div>
393
399
  </div>
394
400
  <div data-mt-cond='{"action.includeTotal": true}'>
@@ -438,30 +444,50 @@
438
444
  <div class="tab-page Javascript active" data-role="Javascript">
439
445
  <div class="js-driver-snippet">
440
446
  Đơn giản
441
- <pre data-language="javascript">try {
447
+ <pre data-language="javascript"><span class="code-comment">// Lấy về danh sách<span data-mt-cond='{"action.pagingType": {"$ne": "None"}}'> có phân trang</span></span>
448
+ try {
442
449
  const response = await mushroom.<span data-mt-attr='{"text": "$entityName"}'></span>.listAsync();
443
- console.log("Các <span data-mt-attr='{"text": "$entityName"}'></span> thỏa mãn: %o", response);
450
+ console.log("Các <span data-mt-attr='{"text": "$entityName"}'></span>: %o", response);
444
451
  }
445
452
  catch (e) {
446
453
  console.error("Có lỗi: %o", e);
447
- }</pre>
454
+ }
455
+
456
+ <span class="code-comment">// Lấy về tất cả danh sách</span>
457
+ try {
458
+ const response = await mushroom.<span data-mt-attr='{"text": "$entityName"}'></span>.getAllAsync();
459
+ console.log("Tất cả các <span data-mt-attr='{"text": "$entityName"}'></span>: %o", response);
460
+ }
461
+ catch (e) {
462
+ console.error("Có lỗi: %o", e);
463
+ }<div data-mt-cond='{"action.includeTotal": true}'>
464
+ <span class="code-comment">// Lấy về số lượng bản ghi</span>
465
+ try {
466
+ const response = await mushroom.<span data-mt-attr='{"text": "$entityName"}'></span>.countAsync();
467
+ console.log("Số lượng tất cả các <span data-mt-attr='{"text": "$entityName"}'></span>: %o", response);
468
+ }
469
+ catch (e) {
470
+ console.error("Có lỗi: %o", e);
471
+ }</div></pre>
448
472
  Tùy biến tham số
449
473
  <pre data-language="javascript">try {
450
474
  const response = await mushroom.<span data-mt-attr='{"text": "$entityName"}'></span>.listAsync({
451
475
  fields: "<span class="separated-items" data-mt-iterate='{"data": "$action.returnableFields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span>",
452
476
  filters: ["your filter 1", "your filter 2"], // <i>or</i> "your filters" ,<span data-mt-cond='{"action.allowSortings": {"$exists": true}}'>
453
477
  sort: "<span class="separated-items" data-mt-iterate='{"data": "$action.allowSortings"}'><span data-mt-cond='{"type": "Desc"}'>-</span><span data-mt-attr='{"text": "$field"}'></span><span class="separator">,</span></span>",</span>
454
- <span data-mt-cond='{"action.pagingType": "LimitOffset"}'> limit: 25,
455
- </span><span data-mt-cond='{"action.pagingType": "LimitOffset"}'> offset: 0,
456
- </span><span data-mt-cond='{"action.pagingType": "Page"}'> limit: 25,
457
- </span><span data-mt-cond='{"action.pagingType": "Page"}'> page: 1,
458
- </span><span data-mt-cond='{"entity.features.vn_text.fields.length": {"$gt": 0}}'> vn_text: "Chuỗi tìm kiếm", <span class="code-comment">// tìm kiếm tiếng Việt không dấu, không phân biệt hoa thường trên <span data-mt-cond='{"entity.features.vn_text.fields.length": {"$gt": 1}}'>các</span> trường: <span class="separated-items" data-mt-iterate='{"data": "$entity.features.vn_text.fields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span>
459
- </span> });
478
+ <span data-mt-cond='{"action.pagingType": {"$in": ["LimitOffset", "Page"]}}'> limit: 25,
479
+ </span> <span data-mt-cond='{"action.pagingType": "LimitOffset"}'> offset: 0,
480
+ </span> <span data-mt-cond='{"action.pagingType": "Page"}'> page: 1,
481
+ </span> <span data-mt-cond='{"entity.features.vn_text.fields.length": {"$gt": 0}}'> vn_text: "Chuỗi tìm kiếm", <span class="code-comment">// tìm kiếm tiếng Việt không dấu, không phân biệt hoa thường trên <span data-mt-cond='{"entity.features.vn_text.fields.length": {"$gt": 1}}'>các</span> trường: <span class="separated-items" data-mt-iterate='{"data": "$entity.features.vn_text.fields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span>
482
+ </span> });
460
483
  console.log("Các <span data-mt-attr='{"text": "$entityName"}'></span> thỏa mãn: %o", response);
461
484
  }
462
485
  catch (e) {
463
486
  console.error("Có lỗi: %o", e);
464
- }</pre>
487
+ }
488
+
489
+ <span class="code-comment">// Tham số cho getAllAsync tương tự listAsync</span><span data-mt-cond='{"action.includeTotal": true}' class="code-comment">
490
+ // Tham số cho countAsync chỉ hỗ trợ filters</span></pre>
465
491
  </div>
466
492
  </div>
467
493
  <div class="tab-page JavascriptModel" data-role="JavascriptModel">
@@ -530,7 +556,7 @@ Host: <span data-mt-attr='{"text": {"fn": "getApiDomain"}}'></span><span data-mt
530
556
  Token: your token
531
557
  </span></pre>
532
558
  Đầy đủ
533
- <pre data-language="http">GET <span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s?field1=value1&field2.subfield=value2<span class="separated-items">&$fields=<span data-mt-iterate='{"data": "$action.returnableFields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span><span class="separated-items" data-mt-cond='{"action.allowSortings": {"$exists": true}}'>&$sort=<span data-mt-iterate='{"data": "$action.allowSortings"}'><span data-mt-cond='{"type": "Desc"}'>-</span><span data-mt-attr='{"text": "$field"}'></span><span class="separator">,</span></span></span><span data-mt-cond='{"action.pagingType": "LimitOffset"}'>&$limit=limit&$offset=offset</span><span data-mt-cond='{"action.pagingType": "Page"}'>&$limit=limit&$page=page</span> HTTP/1.1
559
+ <pre data-language="http">GET <span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s?field1=value1&field2.subfield=value2<span class="separated-items">&$fields=<span data-mt-iterate='{"data": "$action.returnableFields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span><span class="separated-items" data-mt-cond='{"action.allowSortings": {"$exists": true}}'>&$sort=<span data-mt-iterate='{"data": "$action.allowSortings"}'><span data-mt-cond='{"type": "Desc"}'>-</span><span data-mt-attr='{"text": "$field"}'></span><span class="separator">,</span></span></span><span style="display: none"> </span><span data-mt-cond='{"action.pagingType": "LimitOffset"}'>&$limit=limit&$offset=offset</span><span style="display: none"> </span><span data-mt-cond='{"action.pagingType": "Page"}'>&$limit=limit&$page=page</span> HTTP/1.1
534
560
  Host: <span data-mt-attr='{"text": {"fn": "getApiDomain"}}'></span><span data-mt-cond='{"action.grant": {"$ne": "*"}}'>
535
561
  Token: your token
536
562
  </span></pre>
@@ -546,13 +572,13 @@ Token: your token
546
572
  </span></pre>
547
573
  Đầy đủ
548
574
  <pre data-language="cURL">curl -X GET \
549
- '<span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s?field1=value1&field2.subfield=value2<span class="separated-items">&$fields=<span data-mt-iterate='{"data": "$action.returnableFields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span><span class="separated-items" data-mt-cond='{"action.allowSortings": {"$exists": true}}'>&$sort=<span data-mt-iterate='{"data": "$action.allowSortings"}'><span data-mt-cond='{"type": "Desc"}'>-</span><span data-mt-attr='{"text": "$field"}'></span><span class="separator">,</span></span></span><span data-mt-cond='{"action.pagingType": "LimitOffset"}'>&$limit=limit&$offset=offset</span><span data-mt-cond='{"action.pagingType": "Page"}'>&$limit=limit&$page=page</span>' \
575
+ '<span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s?field1=value1&field2.subfield=value2<span class="separated-items">&$fields=<span data-mt-iterate='{"data": "$action.returnableFields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span><span class="separated-items" data-mt-cond='{"action.allowSortings": {"$exists": true}}'>&$sort=<span data-mt-iterate='{"data": "$action.allowSortings"}'><span data-mt-cond='{"type": "Desc"}'>-</span><span data-mt-attr='{"text": "$field"}'></span><span class="separator">,</span></span></span><span style="display: none"> </span><span data-mt-cond='{"action.pagingType": "LimitOffset"}'>&$limit=limit&$offset=offset</span><span style="display: none"> </span><span data-mt-cond='{"action.pagingType": "Page"}'>&$limit=limit&$page=page</span>' \
550
576
  -H 'Host: <span data-mt-attr='{"text": {"fn": "getApiDomain"}}'></span>'<span data-mt-cond='{"action.grant": {"$ne": "*"}}'> \
551
577
  -H 'Token: your token'
552
578
  </span></pre>
553
579
  Shell
554
580
  <pre data-language="cURL">curl --request GET \
555
- --url '<span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s?field1=value1&field2.subfield=value2<span class="separated-items">&$fields=<span data-mt-iterate='{"data": "$action.returnableFields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span><span class="separated-items" data-mt-cond='{"action.allowSortings": {"$exists": true}}'>&$sort=<span data-mt-iterate='{"data": "$action.allowSortings"}'><span data-mt-cond='{"type": "Desc"}'>-</span><span data-mt-attr='{"text": "$field"}'></span><span class="separator">,</span></span></span><span data-mt-cond='{"action.pagingType": "LimitOffset"}'>&$limit=limit&$offset=offset</span><span data-mt-cond='{"action.pagingType": "Page"}'>&$limit=limit&$page=page</span>' \
581
+ --url '<span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s?field1=value1&field2.subfield=value2<span class="separated-items">&$fields=<span data-mt-iterate='{"data": "$action.returnableFields"}'><span data-mt-attr='{"text": "$this"}'></span><span class="separator">,</span></span></span><span class="separated-items" data-mt-cond='{"action.allowSortings": {"$exists": true}}'>&$sort=<span data-mt-iterate='{"data": "$action.allowSortings"}'><span data-mt-cond='{"type": "Desc"}'>-</span><span data-mt-attr='{"text": "$field"}'></span><span class="separator">,</span></span></span><span style="display: none"> </span><span data-mt-cond='{"action.pagingType": "LimitOffset"}'>&$limit=limit&$offset=offset</span><span style="display: none"> </span><span data-mt-cond='{"action.pagingType": "Page"}'>&$limit=limit&$page=page</span>' \
556
582
  -header 'Host: <span data-mt-attr='{"text": {"fn": "getApiDomain"}}'></span>'<span data-mt-cond='{"action.grant": {"$ne": "*"}}'> \
557
583
  -header 'Token: your token'
558
584
  </span></pre>
@@ -2519,7 +2545,15 @@ API.get<span data-mt-attr='{"text": {"fn": "toCSharpName", "data": "$entityName"
2519
2545
  </ul>
2520
2546
  </div>
2521
2547
  <div data-mt-cond='{"action.description": {"$exists": true}}'>
2522
- <h4>Thông tin thêm</h4><p data-mt-attr='{"text": "$action.description"}'></p>
2548
+ <h4>Mô tả</h4><p data-mt-attr='{"text": "$action.description"}'></p>
2549
+ </div>
2550
+ <div data-mt-cond='{"action.codeHint.delegator.param.fields": {"$exists": true}}'>
2551
+ <h4>Query string</h4>
2552
+ <pre data-mt-attr='{"html": {"fn": "formatHintModal", "data": ["$action.codeHint.delegator.param.fields"]}}'></pre>
2553
+ </div>
2554
+ <div data-mt-cond='{"action.codeHint.delegator.requestBody.fields": {"$exists": true}}'>
2555
+ <h4>Request body</h4>
2556
+ <pre data-mt-attr='{"html": {"fn": "formatHintModal", "data": ["$action.codeHint.delegator.requestBody.fields"]}}'></pre>
2523
2557
  </div>
2524
2558
  <div class="driver-snippet">
2525
2559
  <h4>Code mẫu</h4>
@@ -2537,7 +2571,14 @@ API.get<span data-mt-attr='{"text": {"fn": "toCSharpName", "data": "$entityName"
2537
2571
  <div class="js-driver-snippet">
2538
2572
  Code tham khảo:
2539
2573
  <pre data-language="javascript">try {
2540
- const response = await mushroom.<span data-mt-attr='{"text": "$entityName"}'></span>.<span data-mt-attr='{"text": {"fn": "getHttpMethod", "data": "$actionName"}}'></span>Async(parameters)
2574
+ const response = await mushroom.<span data-mt-attr='{"text": "$entityName"}'></span>.<span data-mt-attr='{"text": {"fn": "getHttpMethod", "data": "$actionName"}}'></span>Async({<span data-mt-cond='{"action.codeHint.delegator.param.fields": {"$exists": true}}'>
2575
+ params: {
2576
+ <span class="code-comment">// parameters here</span>
2577
+ },</span><span data-mt-cond='{"action.codeHint.delegator.requestBody.fields": {"$exists": true}}'>
2578
+ body: {
2579
+ <span class="code-comment">// request body here</span>
2580
+ }</span>
2581
+ });
2541
2582
  console.log("Kết quả trả về, response: %o", response);
2542
2583
  } catch (error) {
2543
2584
  console.error("Có lỗi: %o", error);
@@ -2573,7 +2614,7 @@ Token: your token</span>
2573
2614
 
2574
2615
  <span class="place-holder">BODY DATA</span></pre>
2575
2616
  Nếu webserver chỉ hỗ trợ các http method thông dụng, không hỗ trợ http method <span data-mt-attr='{"text": {"fn": "getHttpMethod", "data": "$actionName"}}'></span> thì sử dụng Header theo cách sau:
2576
- <pre data-language="http">TRƯỜNG HỢP CÓ BODY DATA
2617
+ <pre data-language="http"><span data-mt-cond='{"action.codeHint.delegator.requestBody": {"$exists": false}}'>TRƯỜNG HỢP CÓ BODY DATA</span>
2577
2618
  POST <span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s/<span data-mt-attr='{"text": {"fn": "getHttpMethod", "data": "$actionName"}}'></span><span class="place-holder">?param1=value1&amp;param2=value2</span> HTTP/1.1
2578
2619
  Host: <span data-mt-attr='{"text": {"fn": "getApiDomain"}}'></span>
2579
2620
  Content-Type: application/json
@@ -2581,13 +2622,13 @@ X-HTTP-Method-Override: <span data-mt-attr='{"text": {"fn": "getHttpMethod", "da
2581
2622
  Token: your token</span>
2582
2623
 
2583
2624
  <span class="place-holder">BODY DATA</span>
2584
-
2625
+ <span data-mt-cond='{"action.codeHint.delegator.requestBody": {"$exists": false}}'>
2585
2626
  TRƯỜNG HỢP KHÔNG CÓ BODY DATA
2586
2627
  GET <span data-mt-attr='{"text": {"fn": "getApiPath"}}'></span><span data-mt-attr='{"text": "$entityName"}'></span>s/<span data-mt-attr='{"text": {"fn": "getHttpMethod", "data": "$actionName"}}'></span><span class="place-holder">?param1=value1&amp;param2=value2</span> HTTP/1.1
2587
2628
  Host: <span data-mt-attr='{"text": {"fn": "getApiDomain"}}'></span>
2588
2629
  Content-Type: application/json
2589
2630
  X-HTTP-Method-Override: <span data-mt-attr='{"text": {"fn": "getHttpMethod", "data": "$actionName"}}'></span><span data-mt-cond='{"action.grant": {"$ne": "*"}}'>
2590
- Token: your token</span>
2631
+ Token: your token</span></span>
2591
2632
  </pre>
2592
2633
  </div>
2593
2634
  </div>
@@ -2705,10 +2746,20 @@ API.get<span data-mt-attr='{"text": {"fn": "toCSharpName", "data": "$entityName"
2705
2746
  </li>
2706
2747
  </ul>
2707
2748
  </div>
2749
+ <div data-mt-cond='{"view.codeHint.output.fields": {"$exists": true}}'>
2750
+ <h4>Dữ liệu trả về</h4>
2751
+ Mảng các object:
2752
+ <pre data-mt-attr='{"html": {"fn": "formatHintModal", "data": ["$view.codeHint.output.fields"]}}'></pre>
2753
+ <div data-mt-cond='{"view.emptyResult": {"$exists": true}}'>
2754
+ Nếu không có phần tử nào, mảng giá trị sau sẽ được trả về:
2755
+ <pre data-mt-attr='{"text": {"fn": "JSON.stringify", "data": ["$view.emptyResult", null, 4]}}'></pre>
2756
+ </div>
2757
+ </div>
2708
2758
  <div class="driver-snippet">
2709
2759
  <h4>Code mẫu</h4>
2710
2760
  <ul class="nav nav-tabs">
2711
2761
  <li role="presentation" class="active"><a data-role="Javascript" data-mt-event='{"click": "activeRoleTab"}'>Javascript</a></li>
2762
+ <li role="presentation"><a data-role="JavascriptModel" data-mt-event='{"click": "activeRoleTab"}'>JavascriptModel</a></li>
2712
2763
  <li role="presentation"><a data-role="CSharp" data-mt-event='{"click": "activeRoleTab"}'>CSharp</a></li>
2713
2764
  <li role="presentation"><a data-role="HTTP" data-mt-event='{"click": "activeRoleTab"}'>HTTP</a></li>
2714
2765
  <li role="presentation"><a data-role="cURL" data-mt-event='{"click": "activeRoleTab"}'>cURL</a></li>
@@ -2729,6 +2780,16 @@ catch (e) {
2729
2780
  }</pre>
2730
2781
  </div>
2731
2782
  </div>
2783
+ <div class="tab-page JavascriptModel" data-role="JavascriptModel">
2784
+ <div class="js-modal-snippet">
2785
+ Javascript UNDEFINED model
2786
+ <pre data-language="json" data-mt-attr='{"html": {"fn": "formatHintModal", "data": ["$view.codeHint.output.fields", "", {"mode": "modal_undefined"}]}}'></pre>
2787
+ Javascript VALUE model
2788
+ <pre data-language="json" data-mt-attr='{"html": {"fn": "formatHintModal", "data": ["$view.codeHint.output.fields", "", {"mode": "modal"}]}}'></pre>
2789
+ Javascript NULL model
2790
+ <pre data-language="json" data-mt-attr='{"html": {"fn": "formatHintModal", "data": ["$view.codeHint.output.fields", "", {"mode": "modal_null"}]}}'></pre>
2791
+ </div>
2792
+ </div>
2732
2793
  <div class="tab-page CSharp" data-role="CSharp">
2733
2794
  <div class="csharp-driver-snippet">
2734
2795
  <p>Hỗ trợ: DotNet Framework 4.5+, DotNet Core 3.1+, Unity3D, Mono</p>
package/gen/gen-csharp.js CHANGED
@@ -134,7 +134,7 @@ function generateEnumClass(source, out, field, defaultClassName) {
134
134
  strEnumClasses += ` /// <summary>
135
135
  /// ${singleLine(validation.codeHint.validValues.description || field.description)}
136
136
  /// </summary>
137
- public class ${enumClassName}
137
+ public partial class ${enumClassName}
138
138
  {
139
139
  private ${enumClassName}() { }
140
140
 
@@ -179,7 +179,7 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
179
179
 
180
180
  supperClass = " : Mushroom.Models.IResource<" + getCSharpTypeFromMushroomType(source, fields.id.type, true) + ">";
181
181
  }
182
- content += ` public class ${className}${supperClass}
182
+ content += ` public partial class ${className}${supperClass}
183
183
  {
184
184
  `;
185
185
  for (var fieldName in fields) {
@@ -488,21 +488,6 @@ namespace ${namespace}
488
488
  {
489
489
  ${collectionNames}
490
490
  public static IMongoDatabase GetDatabase() => Mushroom.MushroomDaoFactory.GetDbAdapter() as IMongoDatabase;
491
-
492
- public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id) where T : Mushroom.Models.IResource<TId>
493
- {
494
- return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id))).FirstOrDefaultAsync();
495
- }
496
-
497
- 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>
498
- {
499
- return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), findOptions)).FirstOrDefaultAsync();
500
- }
501
-
502
- 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>
503
- {
504
- return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), new FindOptions<T> { Projection = projection })).FirstOrDefaultAsync();
505
- }
506
491
  }
507
492
 
508
493
  public class ResourceNames
@@ -587,7 +572,7 @@ function generateCSharpClassMongoDbToFolder(source, className, fields, isRoot, d
587
572
 
588
573
  supperClass = " : Mushroom.Models.IResource<" + getCSharpTypeFromMushroomType(source, fields.id.type, true) + ">";
589
574
  }
590
- content += ` public class ${className}${supperClass}
575
+ content += ` public partial class ${className}${supperClass}
591
576
  {
592
577
  `;
593
578
  for (var fieldName in fields) {
@@ -125,7 +125,7 @@ function genTypescriptDriverString(aliasProject, source) {
125
125
  }
126
126
  }
127
127
 
128
- let code = `import mushroom, { defineAsyncResource, defineAsyncView, fireEvent, createRestfulAsyncFunction, IdType, IMushroom, Mushroom, MushroomRequest, MushroomRequestSetting, MushroomRestfulRequest, MushroomResponse, MushroomResourceBase, MushroomListResource, MushroomFindByIdResource, MushroomCreateResource, MushroomBatchCreateResource, MushroomUpdateResource, MushroomBatchUpdateResource, MushroomPartialUpdateResource, MushroomDeleteResource, MushroomBatchDeleteResource, MushroomExtensibleResource, MushroomViewFunction, MushroomError } from "mushroomjs";
128
+ let code = `import mushroom, { defineAsyncResource, defineAsyncView, fireEvent, createRestfulAsyncFunction, IdType, IMushroom, Mushroom, MushroomRequest, MushroomRequestSetting, MushroomRestfulRequest, MushroomResponse, MushroomResponseDataType, MushroomResourceBase, MushroomListResource, MushroomFindByIdResource, MushroomCreateResource, MushroomBatchCreateResource, MushroomUpdateResource, MushroomBatchUpdateResource, MushroomPartialUpdateResource, MushroomDeleteResource, MushroomBatchDeleteResource, MushroomExtensibleResource, MushroomViewFunction, MushroomError, IMushroomOfflineResponse, MushroomOfflineResponse, MushroomOfflineResponseState } from "mushroomjs";
129
129
  ${extensionsImportLines.join("\n")}
130
130
  export * from "mushroomjs";
131
131
  export const extensions = {
@@ -156,7 +156,12 @@ export type IdValue = ${source.idType == "AutoIncInt" || source.idType == "AutoI
156
156
 
157
157
  actions[actionName] = {
158
158
  clientCache: (actionName === "findById" || actionName === "findMany") && isAllowCache(entity.actions[actionName], true) ? true : undefined,
159
- includeTotal: actionName === "findMany" && entity.actions[actionName].some(a => a.includeTotal) ? true: undefined
159
+ includeTotal: actionName === "findMany" && entity.actions[actionName].some(a => a.includeTotal) ? true: undefined,
160
+ offlineMode: entity.actions[actionName].some(a => a.offlineMode === "disallow")
161
+ ? "disallow"
162
+ : !entity.actions[actionName].length || entity.actions[actionName].some(a => a.offlineMode === "allow")
163
+ ? "allow"
164
+ : undefined
160
165
  };
161
166
 
162
167
  switch (actionName) {
@@ -299,7 +304,7 @@ function genDtsString(aliasProject, source) {
299
304
  }
300
305
  }
301
306
 
302
- let code = `import { IdType, IMushroom, Mushroom, MushroomRequest, MushroomRequestSetting, MushroomRestfulRequest, MushroomResponse, MushroomResourceBase, MushroomListResource, MushroomFindByIdResource, MushroomCreateResource, MushroomBatchCreateResource, MushroomUpdateResource, MushroomBatchUpdateResource, MushroomPartialUpdateResource, MushroomDeleteResource, MushroomBatchDeleteResource, MushroomExtensibleResource, MushroomViewFunction, MushroomError } from "mushroomjs";
307
+ let code = `import { IdType, IMushroom, Mushroom, MushroomRequest, MushroomRequestSetting, MushroomRestfulRequest, MushroomResponse, MushroomResponseDataType, MushroomResourceBase, MushroomListResource, MushroomFindByIdResource, MushroomCreateResource, MushroomBatchCreateResource, MushroomUpdateResource, MushroomBatchUpdateResource, MushroomPartialUpdateResource, MushroomDeleteResource, MushroomBatchDeleteResource, MushroomExtensibleResource, MushroomViewFunction, MushroomError, IMushroomOfflineResponse, MushroomOfflineResponse, MushroomOfflineResponseState } from "mushroomjs";
303
308
  ${extensionsImportLines.join("\n")}
304
309
  export * from "mushroomjs";
305
310
  export declare const extensions = {
@@ -329,7 +334,13 @@ export declare type IdValue = ${source.idType == "AutoIncInt" || source.idType =
329
334
  continue;
330
335
 
331
336
  actions[actionName] = {
332
- clientCache: (actionName === "findById" || actionName === "findMany") && isAllowCache(entity.actions[actionName], true) ? true : undefined
337
+ clientCache: (actionName === "findById" || actionName === "findMany") && isAllowCache(entity.actions[actionName], true) ? true : undefined,
338
+ includeTotal: actionName === "findMany" && entity.actions[actionName].some(a => a.includeTotal) ? true: undefined,
339
+ offlineMode: entity.actions[actionName].some(a => a.offlineMode === "disallow")
340
+ ? "disallow"
341
+ : !entity.actions[actionName].length || entity.actions[actionName].some(a => a.offlineMode === "allow")
342
+ ? "allow"
343
+ : undefined
333
344
  };
334
345
 
335
346
  switch (actionName) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mushroom-cli",
3
- "version": "1.2.0-alpha.4",
3
+ "version": "1.2.0-alpha.6",
4
4
  "description": "Mushroom CLI",
5
5
  "main": "mr.js",
6
6
  "scripts": {