mm_api 1.1.0 → 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.
@@ -1,7 +1,8 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
- const Item = require("mm_corejs").Base;
4
- const { string, date } = require("mm_helper");
3
+ const Item = require('mm_machine').Mod;
4
+ const { string, date, object, file } = require("mm_helper");
5
+ const { getRet } = require('mm_ret');
5
6
  const Oauth = require("./oauth.js"); // 是MM自带的身份验证机制,基于Oauth2.0,可以不使用
6
7
 
7
8
  /**
@@ -17,79 +18,14 @@ function loadOptional(id) {
17
18
  }
18
19
  }
19
20
 
20
- const Param = loadOptional("mm_param/lib/drive.js"); // 是MM自带的参数机制,可以不使用
21
- const Sql = loadOptional("mm_sql/lib/drive.js"); // 是MM自带的sql机制,可以不使用
21
+ const Param = loadOptional("mm_param/lib/param.js"); // 是MM自带的参数机制,可以不使用
22
+ const Sql = loadOptional("mm_sql/lib/sql.js"); // 是MM自带的sql机制,可以不使用
22
23
 
23
24
  /** param 实例缓存(模块级,替代原全局 param 模块列表) */
24
25
  const PARAM_CACHE = new Map();
25
26
  /** sql 实例缓存(模块级,替代原全局 sql 模块列表) */
26
27
  const SQL_CACHE = new Map();
27
28
 
28
- /**
29
- * 补全文件路径(替代原全局路径补全能力,支持相对/绝对路径)
30
- * @param {string} file 文件路径
31
- * @param {string} dir 基准目录
32
- * @returns {string} 完整路径
33
- */
34
- function _resolvePath(file, dir) {
35
- if (!file) {
36
- return process.cwd();
37
- }
38
- if (path.isAbsolute(file)) {
39
- return file;
40
- }
41
- return path.resolve(dir || process.cwd(), file);
42
- }
43
-
44
- /**
45
- * 生成XML节点(_toXml 的内部递归辅助)
46
- * @param {string} name 节点名
47
- * @param {*} value 节点值
48
- * @returns {string} XML片段字符串
49
- */
50
- function _xmlNode(name, value) {
51
- if (value && typeof value === "object") {
52
- return "<" + name + ">" + _toXml(value) + "</" + name + ">";
53
- }
54
- var text = value === undefined || value === null ? "" : String(value);
55
- return "<" + name + ">" + text + "</" + name + ">";
56
- }
57
-
58
- /**
59
- * 对象转XML字符串(替代原全局 toXml 的精简等价实现)
60
- * @param {object} source 被转换的对象
61
- * @returns {string} xml格式字符串
62
- */
63
- function _toXml(source) {
64
- var parts = [];
65
- for (var key in source) {
66
- var val = source[key];
67
- if (Array.isArray(val)) {
68
- for (var i = 0; i < val.length; i++) {
69
- parts.push(_xmlNode(key, val[i]));
70
- }
71
- } else {
72
- parts.push(_xmlNode(key, val));
73
- }
74
- }
75
- return parts.join("");
76
- }
77
-
78
- /**
79
- * 构建错误响应体(替代原全局 ret.error,默认 json-rpc 形态)
80
- * @param {number} code 错误码
81
- * @param {string} message 错误信息
82
- * @returns {object} 形如 { error: { code, message } } 的响应体
83
- */
84
- function _retError(code, message) {
85
- return {
86
- error: {
87
- code,
88
- message,
89
- },
90
- };
91
- }
92
-
93
29
  /**
94
30
  * 去除 JSON 文本中的注释(支持 // 与整块注释,不处理字符串内部)
95
31
  * @param {string} text 原始文本
@@ -169,7 +105,7 @@ function _readJsonConfig(file) {
169
105
  * @augments {Item}
170
106
  * @class
171
107
  */
172
- class Drive extends Item {
108
+ class Api extends Item {
173
109
  static config = {
174
110
  // 应用名称 例如:demo_app
175
111
  app: "server",
@@ -223,7 +159,7 @@ class Drive extends Item {
223
159
  * @class
224
160
  */
225
161
  constructor(config, parent) {
226
- super({ ...Drive.config, ...config });
162
+ super({ ...Api.config, ...config });
227
163
 
228
164
  // 父级管理器引用(用于缓存、插件与默认配置回退)
229
165
  this.parent = parent || null;
@@ -239,7 +175,7 @@ class Drive extends Item {
239
175
  /**
240
176
  * 预设配置
241
177
  */
242
- Drive.prototype._preset = function () {
178
+ Api.prototype._preset = function () {
243
179
  this.save_dir = "./static/file/";
244
180
  this.url_path = "/file/";
245
181
 
@@ -260,7 +196,7 @@ Drive.prototype._preset = function () {
260
196
  * 获取驱动目录(方案B:来自手动配置的 dir,替代旧基类 getDir)
261
197
  * @returns {string} 驱动目录
262
198
  */
263
- Drive.prototype.getDir = function () {
199
+ Api.prototype.getDir = function () {
264
200
  return this.config.dir || __dirname;
265
201
  };
266
202
 
@@ -270,7 +206,7 @@ Drive.prototype.getDir = function () {
270
206
  * @returns {object|null} 配置对象,文件不存在或解析失败返回 null
271
207
  * @private
272
208
  */
273
- Drive.prototype._loadJsonConfig = function (file) {
209
+ Api.prototype._loadJsonConfig = function (file) {
274
210
  if (!fs.existsSync(file)) {
275
211
  this.log("warn", "配置文件不存在", file);
276
212
  return null;
@@ -288,7 +224,7 @@ Drive.prototype._loadJsonConfig = function (file) {
288
224
  * @returns {object|null} 缓存实例;未配置返回 null
289
225
  * @private
290
226
  */
291
- Drive.prototype._getCache = function () {
227
+ Api.prototype._getCache = function () {
292
228
  var fn = this.config.get_cache;
293
229
  if (typeof fn !== "function" && this.parent) {
294
230
  fn = this.parent.config.get_cache;
@@ -300,7 +236,7 @@ Drive.prototype._getCache = function () {
300
236
  * 设置参数对象(写入模块级缓存,替代原全局 param 模块列表)
301
237
  * @param {object} param 参数对象
302
238
  */
303
- Drive.prototype.updateParam = function (param) {
239
+ Api.prototype.updateParam = function (param) {
304
240
  PARAM_CACHE.set(param.config_file, param);
305
241
  };
306
242
 
@@ -309,7 +245,7 @@ Drive.prototype.updateParam = function (param) {
309
245
  * @param {string} file 文件名
310
246
  * @returns {object} 获取的对象
311
247
  */
312
- Drive.prototype.getParam = function (file) {
248
+ Api.prototype.getParam = function (file) {
313
249
  return PARAM_CACHE.get(file) || null;
314
250
  };
315
251
 
@@ -318,11 +254,11 @@ Drive.prototype.getParam = function (file) {
318
254
  * @param {string} file_path 参数文件路径
319
255
  * @returns {object|null} 参数驱动实例,未配置或加载失败返回 null
320
256
  */
321
- Drive.prototype._loadParam = function (file_path) {
257
+ Api.prototype._loadParam = function (file_path) {
322
258
  if (!file_path || !Param) {
323
259
  return null;
324
260
  }
325
- var p = _resolvePath(file_path, this.getDir());
261
+ var p = file.fullname(file_path, this.getDir());
326
262
  var param = this.getParam(p);
327
263
  if (param) {
328
264
  this.param = param;
@@ -345,7 +281,7 @@ Drive.prototype._loadParam = function (file_path) {
345
281
  * @param {string} sql.config_file 文件名
346
282
  * @param {object} sql.sql sql语句
347
283
  */
348
- Drive.prototype.updateSql = function (sql) {
284
+ Api.prototype.updateSql = function (sql) {
349
285
  SQL_CACHE.set(sql.config_file, sql);
350
286
  };
351
287
 
@@ -354,7 +290,7 @@ Drive.prototype.updateSql = function (sql) {
354
290
  * @param {string} file 文件名
355
291
  * @returns {object} 获取的对象
356
292
  */
357
- Drive.prototype.getSql = function (file) {
293
+ Api.prototype.getSql = function (file) {
358
294
  return SQL_CACHE.get(file) || null;
359
295
  };
360
296
 
@@ -363,11 +299,11 @@ Drive.prototype.getSql = function (file) {
363
299
  * @param {string} file_path sql模板文件路径
364
300
  * @returns {object|null} sql驱动实例,未配置或加载失败返回 null
365
301
  */
366
- Drive.prototype._loadSql = function (file_path) {
302
+ Api.prototype._loadSql = function (file_path) {
367
303
  if (!file_path || !Sql) {
368
304
  return null;
369
305
  }
370
- var p = _resolvePath(file_path, this.getDir());
306
+ var p = file.fullname(file_path, this.getDir());
371
307
  var sql = this.getSql(p);
372
308
  if (sql) {
373
309
  this.sql = sql;
@@ -388,7 +324,7 @@ Drive.prototype._loadSql = function (file_path) {
388
324
  /**
389
325
  * 加载身份验证配置
390
326
  */
391
- Drive.prototype._loadOauth = function () {
327
+ Api.prototype._loadOauth = function () {
392
328
  var cg = this.config.oauth;
393
329
  if (cg) {
394
330
  this.oauth = new Oauth({
@@ -406,19 +342,19 @@ Drive.prototype._loadOauth = function () {
406
342
  * @returns {string|null} 脚本文件路径,未配置返回null
407
343
  * @private
408
344
  */
409
- Drive.prototype._getScriptFile = function () {
345
+ Api.prototype._getScriptFile = function () {
410
346
  var main = this.config.main || "";
411
347
  if (!main) {
412
348
  return null;
413
349
  }
414
- return _resolvePath(main, this.getDir());
350
+ return file.fullname(main, this.getDir());
415
351
  };
416
352
 
417
353
  /**
418
354
  * 脚本是否已加载(方案B:替代旧基类 isLoaded 机制)
419
355
  * @returns {boolean} 是否已加载
420
356
  */
421
- Drive.prototype.isLoaded = function () {
357
+ Api.prototype.isLoaded = function () {
422
358
  return this._loaded;
423
359
  };
424
360
 
@@ -426,7 +362,7 @@ Drive.prototype.isLoaded = function () {
426
362
  * 加载主脚本文件(方案B:标准 require,替代旧基类 do("load") 与热重载模式)
427
363
  * @returns {object|null} 加载的模块对象
428
364
  */
429
- Drive.prototype.load = function () {
365
+ Api.prototype.load = function () {
430
366
  var file = this._getScriptFile();
431
367
  if (!file || !fs.existsSync(file)) {
432
368
  return null;
@@ -446,7 +382,7 @@ Drive.prototype.load = function () {
446
382
  * @param {object} mod 模块对象
447
383
  * @private
448
384
  */
449
- Drive.prototype._setMainMethod = function (mod) {
385
+ Api.prototype._setMainMethod = function (mod) {
450
386
  if (!mod) {
451
387
  return;
452
388
  }
@@ -469,7 +405,7 @@ Drive.prototype._setMainMethod = function (mod) {
469
405
  * @param {string} files.file 上传的文件对象
470
406
  * @returns {object} 返回文件路径和URL
471
407
  */
472
- Drive.prototype.saveFile = function (files) {
408
+ Api.prototype.saveFile = function (files) {
473
409
  var file;
474
410
  var url;
475
411
  if (files.file) {
@@ -477,7 +413,7 @@ Drive.prototype.saveFile = function (files) {
477
413
  // 安全处理文件名: 移除路径穿越字符和特殊字符
478
414
  var name = f.name || f.originalFilename;
479
415
  name = name.replace(/[\\/]|\.\./g, "_");
480
- file = _resolvePath("./" + name, this.save_dir);
416
+ file = file.fullname("./" + name, this.save_dir);
481
417
  fs.mkdirSync(path.dirname(file), { recursive: true });
482
418
  // 创建写入流
483
419
  var read_stream = fs.createReadStream(f.filepath);
@@ -513,7 +449,7 @@ Drive.prototype.saveFile = function (files) {
513
449
  * @returns {object|null} 登录态与用户信息
514
450
  * @private
515
451
  */
516
- Drive.prototype._getState = async function (db, token) {
452
+ Api.prototype._getState = async function (db, token) {
517
453
  var db1 = db.new("user_state", "user_id");
518
454
  var state = await db1.getObj(
519
455
  {
@@ -552,10 +488,10 @@ Drive.prototype._getState = async function (db, token) {
552
488
  * @param {object} db 数据管理器
553
489
  * @returns {object} 执行结果
554
490
  */
555
- Drive.prototype.getLoginState = async function (ctx, options) {
491
+ Api.prototype.getLoginState = async function (params, ctx, options) {
556
492
  var o = await this._getUserFromSession(ctx);
557
493
  if (!o) {
558
- o = await this._getUserFromToken(ctx, options);
494
+ o = await this._getUserFromToken(params, ctx, options);
559
495
  }
560
496
  return this._processUserInfo(o);
561
497
  };
@@ -566,7 +502,7 @@ Drive.prototype.getLoginState = async function (ctx, options) {
566
502
  * @returns {object|null} 用户信息
567
503
  * @private
568
504
  */
569
- Drive.prototype._getUserFromSession = function (ctx) {
505
+ Api.prototype._getUserFromSession = function (ctx) {
570
506
  var u = ctx.session?.user;
571
507
  if (u) {
572
508
  var o = { ...u };
@@ -583,7 +519,7 @@ Drive.prototype._getUserFromSession = function (ctx) {
583
519
  * @returns {object|null} 用户信息
584
520
  * @private
585
521
  */
586
- Drive.prototype._getUserFromToken = async function (ctx, options) {
522
+ Api.prototype._getUserFromToken = async function (params, ctx, options) {
587
523
  var token = ctx.headers[this.config.token_key];
588
524
  if (!token) {
589
525
  return null;
@@ -607,7 +543,7 @@ Drive.prototype._getUserFromToken = async function (ctx, options) {
607
543
  * @returns {object|null} 用户信息
608
544
  * @private
609
545
  */
610
- Drive.prototype._processUserFromCache = async function (u, ctx, options, token) {
546
+ Api.prototype._processUserFromCache = async function (u, ctx, options, token) {
611
547
  var o;
612
548
  if (typeof u === "string") {
613
549
  o = { ...string.toJson(u) };
@@ -628,12 +564,12 @@ Drive.prototype._processUserFromCache = async function (u, ctx, options, token)
628
564
  * 从数据库中获取用户信息
629
565
  * @param {string} token token
630
566
  * @param {object} ctx 请求上下文
631
- * @param {object} db 数据管理器
567
+ * @param {object} options 数据管理器
632
568
  * @returns {object|null} 用户信息
633
569
  * @private
634
570
  */
635
- Drive.prototype._getUserFromDb = async function (token, ctx, options) {
636
- var obj = await this._getState(db, token);
571
+ Api.prototype._getUserFromDb = async function (token, ctx, options) {
572
+ var obj = await this._getState(options, token);
637
573
  if (obj) {
638
574
  var o = { ...obj.user };
639
575
  ctx.session.user = obj.user;
@@ -650,7 +586,7 @@ Drive.prototype._getUserFromDb = async function (token, ctx, options) {
650
586
  * @returns {object|null} 处理后的用户信息
651
587
  * @private
652
588
  */
653
- Drive.prototype._processUserInfo = function (o) {
589
+ Api.prototype._processUserInfo = function (o) {
654
590
  if (o) {
655
591
  o.password_pay = o.password_pay ? "******" : "";
656
592
  o.password = o.password ? "******" : "";
@@ -663,22 +599,22 @@ Drive.prototype._processUserInfo = function (o) {
663
599
  /**
664
600
  * 获取登录态
665
601
  * @param {object} ctx 请求上下文
666
- * @param {object} db 数据管理器
602
+ * @param {object} options 数据管理器
667
603
  * @returns {object} 执行结果
668
604
  */
669
- Drive.prototype.before = async function (ctx, options) {
605
+ Api.prototype.before = async function (params, ctx, options) {
670
606
  if (this.config.oauth && this.config.oauth.sign_in) {
671
- db.user = await this.getLoginState(ctx, options);
607
+ options.user = await this.getLoginState(params, ctx, options);
672
608
  }
673
609
  };
674
610
 
675
611
  /**
676
612
  * 主要函数
677
613
  * @param {object} ctx 请求上下文
678
- * @param {object} db 数据管理器
614
+ * @param {object} options 数据管理器
679
615
  * @returns {object} 执行结果
680
616
  */
681
- Drive.prototype.main = async function (ctx, options) {
617
+ Api.prototype.main = async function (params, ctx, options) {
682
618
  if (this.sql) {
683
619
  var req = ctx.request;
684
620
  // 获取文件
@@ -687,10 +623,10 @@ Drive.prototype.main = async function (ctx, options) {
687
623
  req.body.file = fobj.file;
688
624
  req.body.url = fobj.url;
689
625
  }
690
- var ret = await this.sql.run(req.query, req.body, db);
626
+ var ret = await this.sql.run(req.query, req.body, options);
691
627
  return ret;
692
628
  } else {
693
- return _retError(10000, "接口函数未定义");
629
+ return getRet().error(10000, "接口函数未定义");
694
630
  }
695
631
  };
696
632
 
@@ -700,7 +636,7 @@ Drive.prototype.main = async function (ctx, options) {
700
636
  * @param {object} db 数据管理器
701
637
  * @returns {object} 执行结果
702
638
  */
703
- Drive.prototype.run = async function (ctx, options) {
639
+ Api.prototype.run = async function (params, ctx, options) {
704
640
  try {
705
641
  var body = await this.getCache(ctx);
706
642
  if (!body) {
@@ -709,14 +645,14 @@ Drive.prototype.run = async function (ctx, options) {
709
645
  if (md !== req.method && md !== "ALL") {
710
646
  return null;
711
647
  }
712
- await this.before(ctx, options);
713
- var ret = await this.check(ctx, options);
648
+ await this.before(params, ctx, options);
649
+ var ret = await this.check(params, ctx, options);
714
650
  if (!ret) {
715
651
  try {
716
- ret = await this.main(ctx, options);
652
+ ret = await this.main(params, ctx, options);
717
653
  } catch (err) {
718
654
  this.log("error", "脚本文件错误", req.path, err);
719
- ret = _retError(10000, "脚本文件错误:" + err.toString());
655
+ ret = getRet().error(10000, "脚本文件错误:" + err.toString());
720
656
  }
721
657
  }
722
658
  var res = ctx.response;
@@ -734,7 +670,7 @@ Drive.prototype.run = async function (ctx, options) {
734
670
  * @param {object} ctx 请求上下文
735
671
  * @returns {string} 响应内容
736
672
  */
737
- Drive.prototype.getCache = async function (ctx) {
673
+ Api.prototype.getCache = async function (ctx) {
738
674
  var cg = this.config;
739
675
  if (cg.cache) {
740
676
  var req = ctx.request;
@@ -769,7 +705,7 @@ Drive.prototype.getCache = async function (ctx) {
769
705
  * @param {object} body 正文参数
770
706
  * @param {string} type 响应类型
771
707
  */
772
- Drive.prototype.setCache = async function (ctx, body, type = null) {
708
+ Api.prototype.setCache = async function (ctx, body, type = null) {
773
709
  var cg = this.config;
774
710
  if (cg.cache && ctx.method === "GET") {
775
711
  if (cg.client_cache) {
@@ -796,7 +732,7 @@ Drive.prototype.setCache = async function (ctx, body, type = null) {
796
732
  * @param {string} t 请求类型
797
733
  * @returns {string} 处理后的响应结果
798
734
  */
799
- Drive.prototype.body = function (result, res, t) {
735
+ Api.prototype.body = function (result, res, t) {
800
736
  var ret = result;
801
737
  var type = res.type;
802
738
  if (!ret) {
@@ -821,7 +757,7 @@ Drive.prototype.body = function (result, res, t) {
821
757
  * @returns {string} 处理后的类型
822
758
  * @private
823
759
  */
824
- Drive.prototype._handleObjectType = function (res, type, t) {
760
+ Api.prototype._handleObjectType = function (res, type, t) {
825
761
  var new_type = type;
826
762
  if (!new_type) {
827
763
  new_type = t.indexOf("xml") !== -1 ? t : "application/json; charset=utf-8";
@@ -839,7 +775,7 @@ Drive.prototype._handleObjectType = function (res, type, t) {
839
775
  * @returns {string} 标准化后的类型
840
776
  * @private
841
777
  */
842
- Drive.prototype._normType = function (type) {
778
+ Api.prototype._normType = function (type) {
843
779
  if (type.indexOf("json") !== -1) {
844
780
  return "application/json; charset=utf-8";
845
781
  } else if (type.indexOf("html") !== -1) {
@@ -857,8 +793,8 @@ Drive.prototype._normType = function (type) {
857
793
  * @returns {string} 转换后的字符串
858
794
  * @private
859
795
  */
860
- Drive.prototype._convertObject = function (obj, type) {
861
- return type.indexOf("/xml") !== -1 ? _toXml(obj) : JSON.stringify(obj);
796
+ Api.prototype._convertObject = function (obj, type) {
797
+ return type.indexOf("/xml") !== -1 ? object.toXml(obj) : JSON.stringify(obj);
862
798
  };
863
799
 
864
800
  /**
@@ -868,7 +804,7 @@ Drive.prototype._convertObject = function (obj, type) {
868
804
  * @param {string} str 字符串
869
805
  * @private
870
806
  */
871
- Drive.prototype._handleStringType = function (res, type, str) {
807
+ Api.prototype._handleStringType = function (res, type, str) {
872
808
  if (!type) {
873
809
  if (
874
810
  (str.startsWith("{") && str.endsWith("}")) ||
@@ -892,17 +828,21 @@ Drive.prototype._handleStringType = function (res, type, str) {
892
828
  * @param {string} method 方法
893
829
  * @returns {object} 验证结果
894
830
  */
895
- Drive.prototype.checkParam = function (query, body, method) {
831
+ Api.prototype.checkParam = function (query, body, method) {
896
832
  if (this.param) {
897
833
  var msg = this.param.check(query, body, method);
898
834
  if (msg) {
899
835
  var code;
900
- if (msg.indexOf("必须") !== -1 || msg.indexOf("为空") !== -1) {
836
+ if (
837
+ msg.indexOf("必须") !== -1 ||
838
+ msg.indexOf("必填") !== -1 ||
839
+ msg.indexOf("为空") !== -1
840
+ ) {
901
841
  code = 30001;
902
842
  } else {
903
843
  code = 30002;
904
844
  }
905
- return _retError(code, msg);
845
+ return getRet().error(code, msg);
906
846
  }
907
847
  }
908
848
  return null;
@@ -910,10 +850,12 @@ Drive.prototype.checkParam = function (query, body, method) {
910
850
 
911
851
  /**
912
852
  * 验证参数
853
+ * @param {object} params 请求参数
913
854
  * @param {object} ctx 内容上下文
855
+ * @param {object} options 事件运行选项
914
856
  * @returns {object} 验证结果
915
857
  */
916
- Drive.prototype.check = async function (ctx) {
858
+ Api.prototype.check = async function (params, ctx, options) {
917
859
  var error;
918
860
  if (this.config.check_param) {
919
861
  var req = ctx.request;
@@ -935,7 +877,7 @@ Drive.prototype.check = async function (ctx) {
935
877
  * @param {object} ctx 内容上下文
936
878
  * @returns {object} 验证结果
937
879
  */
938
- Drive.prototype.checkOauth = async function (ctx) {
880
+ Api.prototype.checkOauth = async function (ctx) {
939
881
  var aouth = this.oauth;
940
882
  if (aouth) {
941
883
  return await aouth.check(ctx);
@@ -950,7 +892,7 @@ Drive.prototype.checkOauth = async function (ctx) {
950
892
  * @param {string} name 插件名称
951
893
  * @returns {object} 返回获取到的插件
952
894
  */
953
- Drive.prototype.plugin = function (app, name) {
895
+ Api.prototype.plugin = function (app, name) {
954
896
  var l = path.sep;
955
897
  var dir = this.config.dir || "";
956
898
  var app_name = app || string.between(dir, "app" + l, l);
@@ -968,7 +910,7 @@ Drive.prototype.plugin = function (app, name) {
968
910
  * @param {string} type 模型类型
969
911
  * @returns {object} 返回获取到的模型
970
912
  */
971
- Drive.prototype.getModel = function (type) {
913
+ Api.prototype.getModel = function (type) {
972
914
  let model = { ...this.config };
973
915
  let dir = this.getDir();
974
916
  let l = path.sep;
@@ -982,4 +924,4 @@ Drive.prototype.getModel = function (type) {
982
924
  return model;
983
925
  };
984
926
 
985
- module.exports = Drive;
927
+ module.exports = Api;