@ruiapp/rapid-core 0.1.3 → 0.1.4

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.
@@ -0,0 +1,22 @@
1
+ export type BodyData = Record<string, string | File | (string | File)[]>;
2
+ export type ParseBodyOptions = {
3
+ /**
4
+ * Parse all fields with multiple values should be parsed as an array.
5
+ * @default false
6
+ * @example
7
+ * ```ts
8
+ * const data = new FormData()
9
+ * data.append('file', 'aaa')
10
+ * data.append('file', 'bbb')
11
+ * data.append('message', 'hello')
12
+ * ```
13
+ *
14
+ * If `all` is `false`:
15
+ * parseBody should return `{ file: 'bbb', message: 'hello' }`
16
+ *
17
+ * If `all` is `true`:
18
+ * parseBody should return `{ file: ['aaa', 'bbb'], message: 'hello' }`
19
+ */
20
+ all?: boolean;
21
+ };
22
+ export declare const parseFormDataBody: <T extends BodyData = BodyData>(request: Request, options?: ParseBodyOptions) => Promise<T>;
@@ -0,0 +1,4 @@
1
+ export interface IRuntimeProvider {
2
+ copyFile(fromPath: string, toPath: string): Promise<void>;
3
+ removeFile(path: string): Promise<void>;
4
+ }
@@ -8,7 +8,6 @@ export declare class RouteContext {
8
8
  readonly state: Record<string, any>;
9
9
  method: string;
10
10
  path: string;
11
- status: HttpStatus;
12
11
  params: Record<string, string>;
13
12
  constructor(request: RapidRequest);
14
13
  set(headerName: string, headerValue: string): void;
package/dist/index.js CHANGED
@@ -3,6 +3,9 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _ = require('lodash');
6
+ var path = require('path');
7
+ var fs = require('fs');
8
+ var uuid = require('uuid');
6
9
  var Router = require('koa-tree-router');
7
10
  var qs = require('qs');
8
11
  var jsonwebtoken = require('jsonwebtoken');
@@ -30,6 +33,8 @@ function _interopNamespace(e) {
30
33
  }
31
34
 
32
35
  var ___namespace = /*#__PURE__*/_interopNamespace(_);
36
+ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
37
+ var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
33
38
  var Router__default = /*#__PURE__*/_interopDefaultLegacy(Router);
34
39
  var qs__default = /*#__PURE__*/_interopDefaultLegacy(qs);
35
40
  var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);
@@ -1034,20 +1039,20 @@ async function updateEntityById(server, dataAccessor, options) {
1034
1039
  return updatedEntity;
1035
1040
  }
1036
1041
 
1037
- const code$l = "listMetaModels";
1038
- async function handler$g(plugin, ctx, options) {
1042
+ const code$p = "listMetaModels";
1043
+ async function handler$j(plugin, ctx, options) {
1039
1044
  const { applicationConfig } = ctx;
1040
1045
  ctx.output = { list: applicationConfig.models };
1041
1046
  }
1042
1047
 
1043
1048
  var listMetaModels = /*#__PURE__*/Object.freeze({
1044
1049
  __proto__: null,
1045
- code: code$l,
1046
- handler: handler$g
1050
+ code: code$p,
1051
+ handler: handler$j
1047
1052
  });
1048
1053
 
1049
- const code$k = "getMetaModelDetail";
1050
- async function handler$f(plugin, ctx, options) {
1054
+ const code$o = "getMetaModelDetail";
1055
+ async function handler$i(plugin, ctx, options) {
1051
1056
  const { server, input } = ctx;
1052
1057
  const model = server.getModel(input);
1053
1058
  ctx.output = model;
@@ -1055,33 +1060,33 @@ async function handler$f(plugin, ctx, options) {
1055
1060
 
1056
1061
  var getMetaModelDetail = /*#__PURE__*/Object.freeze({
1057
1062
  __proto__: null,
1058
- code: code$k,
1059
- handler: handler$f
1063
+ code: code$o,
1064
+ handler: handler$i
1060
1065
  });
1061
1066
 
1062
1067
  /**
1063
1068
  * Meta manager plugin
1064
1069
  */
1065
- const code$j = "metaManager";
1066
- const description$4 = "metaManager";
1067
- const extendingAbilities$4 = [];
1068
- const configurableTargets$4 = [];
1069
- const configurations$4 = [];
1070
- let _plugin$4;
1071
- async function initPlugin$4(plugin, server) {
1072
- _plugin$4 = plugin;
1073
- }
1074
- async function registerHttpHandlers$4(server) {
1075
- server.registerHttpHandler(_plugin$4, listMetaModels);
1076
- server.registerHttpHandler(_plugin$4, getMetaModelDetail);
1077
- }
1078
- async function registerEventHandlers$3(server) {
1070
+ const code$n = "metaManager";
1071
+ const description$5 = "metaManager";
1072
+ const extendingAbilities$5 = [];
1073
+ const configurableTargets$5 = [];
1074
+ const configurations$5 = [];
1075
+ let _plugin$5;
1076
+ async function initPlugin$5(plugin, server) {
1077
+ _plugin$5 = plugin;
1078
+ }
1079
+ async function registerHttpHandlers$5(server) {
1080
+ server.registerHttpHandler(_plugin$5, listMetaModels);
1081
+ server.registerHttpHandler(_plugin$5, getMetaModelDetail);
1082
+ }
1083
+ async function registerEventHandlers$4(server) {
1079
1084
  server.registerEventHandler("entity.create", handleEntityCreateEvent.bind(null, server));
1080
1085
  server.registerEventHandler("entity.update", handleEntityUpdateEvent.bind(null, server));
1081
1086
  server.registerEventHandler("entity.delete", handleEntityDeleteEvent.bind(null, server));
1082
1087
  }
1083
1088
  async function handleEntityCreateEvent(server, sender, payload) {
1084
- if (sender === _plugin$4) {
1089
+ if (sender === _plugin$5) {
1085
1090
  return;
1086
1091
  }
1087
1092
  if (payload.namespace === "meta" && payload.modelSingularCode === "model") {
@@ -1089,7 +1094,7 @@ async function handleEntityCreateEvent(server, sender, payload) {
1089
1094
  }
1090
1095
  }
1091
1096
  async function handleEntityUpdateEvent(server, sender, payload) {
1092
- if (sender === _plugin$4) {
1097
+ if (sender === _plugin$5) {
1093
1098
  return;
1094
1099
  }
1095
1100
  if (payload.namespace === "meta" && payload.modelSingularCode === "model") {
@@ -1097,7 +1102,7 @@ async function handleEntityUpdateEvent(server, sender, payload) {
1097
1102
  }
1098
1103
  }
1099
1104
  async function handleEntityDeleteEvent(server, sender, payload) {
1100
- if (sender === _plugin$4) {
1105
+ if (sender === _plugin$5) {
1101
1106
  return;
1102
1107
  }
1103
1108
  if (payload.namespace !== "meta") {
@@ -1130,7 +1135,7 @@ async function handleEntityDeleteEvent(server, sender, payload) {
1130
1135
  }
1131
1136
  }
1132
1137
  }
1133
- async function configureModels$3(server, applicationConfig) {
1138
+ async function configureModels$4(server, applicationConfig) {
1134
1139
  try {
1135
1140
  const models = await listCollections(server, applicationConfig);
1136
1141
  server.appendApplicationConfig({ models });
@@ -1149,7 +1154,7 @@ function listCollections(server, applicationConfig) {
1149
1154
  properties: model.properties.map((item) => item.code),
1150
1155
  });
1151
1156
  }
1152
- async function onApplicationLoaded$5(server, applicationConfig) {
1157
+ async function onApplicationLoaded$6(server, applicationConfig) {
1153
1158
  console.log("metaManager.onApplicationLoaded");
1154
1159
  await syncDatabaseSchema(server, applicationConfig);
1155
1160
  }
@@ -1341,16 +1346,16 @@ const pgPropertyTypeColumnMap = {
1341
1346
 
1342
1347
  var metaManager = /*#__PURE__*/Object.freeze({
1343
1348
  __proto__: null,
1344
- code: code$j,
1345
- description: description$4,
1346
- extendingAbilities: extendingAbilities$4,
1347
- configurableTargets: configurableTargets$4,
1348
- configurations: configurations$4,
1349
- initPlugin: initPlugin$4,
1350
- registerHttpHandlers: registerHttpHandlers$4,
1351
- registerEventHandlers: registerEventHandlers$3,
1352
- configureModels: configureModels$3,
1353
- onApplicationLoaded: onApplicationLoaded$5
1349
+ code: code$n,
1350
+ description: description$5,
1351
+ extendingAbilities: extendingAbilities$5,
1352
+ configurableTargets: configurableTargets$5,
1353
+ configurations: configurations$5,
1354
+ initPlugin: initPlugin$5,
1355
+ registerHttpHandlers: registerHttpHandlers$5,
1356
+ registerEventHandlers: registerEventHandlers$4,
1357
+ configureModels: configureModels$4,
1358
+ onApplicationLoaded: onApplicationLoaded$6
1354
1359
  });
1355
1360
 
1356
1361
  function mergeInput(defaultInput, input, fixedInput) {
@@ -1418,9 +1423,9 @@ function transformFilterWithSubFilters(filter) {
1418
1423
  return filter;
1419
1424
  }
1420
1425
 
1421
- const code$i = "findCollectionEntities";
1422
- async function handler$e(plugin, ctx, options) {
1423
- await runCollectionEntityHttpHandler(ctx, options, code$i, async (dataAccessor, input) => {
1426
+ const code$m = "findCollectionEntities";
1427
+ async function handler$h(plugin, ctx, options) {
1428
+ await runCollectionEntityHttpHandler(ctx, options, code$m, async (dataAccessor, input) => {
1424
1429
  input.filters = removeFiltersWithNullValue(input.filters);
1425
1430
  const entities = await findEntities(ctx.server, dataAccessor, input);
1426
1431
  const result = { list: entities };
@@ -1435,13 +1440,13 @@ async function handler$e(plugin, ctx, options) {
1435
1440
 
1436
1441
  var findCollectionEntitiesHttpHandler = /*#__PURE__*/Object.freeze({
1437
1442
  __proto__: null,
1438
- code: code$i,
1439
- handler: handler$e
1443
+ code: code$m,
1444
+ handler: handler$h
1440
1445
  });
1441
1446
 
1442
- const code$h = "findCollectionEntityById";
1443
- async function handler$d(plugin, ctx, options) {
1444
- console.debug(`Running ${code$h} handler...`);
1447
+ const code$l = "findCollectionEntityById";
1448
+ async function handler$g(plugin, ctx, options) {
1449
+ console.debug(`Running ${code$l} handler...`);
1445
1450
  const { server, input } = ctx;
1446
1451
  const { id } = input;
1447
1452
  const dataAccessor = server.getDataAccessor(options);
@@ -1462,13 +1467,13 @@ async function handler$d(plugin, ctx, options) {
1462
1467
 
1463
1468
  var findCollectionEntityById = /*#__PURE__*/Object.freeze({
1464
1469
  __proto__: null,
1465
- code: code$h,
1466
- handler: handler$d
1470
+ code: code$l,
1471
+ handler: handler$g
1467
1472
  });
1468
1473
 
1469
- const code$g = "countCollectionEntities";
1470
- async function handler$c(plugin, ctx, options) {
1471
- await runCollectionEntityHttpHandler(ctx, options, code$g, (dataAccessor, input) => {
1474
+ const code$k = "countCollectionEntities";
1475
+ async function handler$f(plugin, ctx, options) {
1476
+ await runCollectionEntityHttpHandler(ctx, options, code$k, (dataAccessor, input) => {
1472
1477
  input.filters = removeFiltersWithNullValue(input.filters);
1473
1478
  return dataAccessor.count(input);
1474
1479
  });
@@ -1476,15 +1481,15 @@ async function handler$c(plugin, ctx, options) {
1476
1481
 
1477
1482
  var countCollectionEntities = /*#__PURE__*/Object.freeze({
1478
1483
  __proto__: null,
1479
- code: code$g,
1480
- handler: handler$c
1484
+ code: code$k,
1485
+ handler: handler$f
1481
1486
  });
1482
1487
 
1483
- const code$f = "createCollectionEntity";
1484
- async function handler$b(plugin, ctx, options) {
1488
+ const code$j = "createCollectionEntity";
1489
+ async function handler$e(plugin, ctx, options) {
1485
1490
  const { server, input } = ctx;
1486
1491
  const { defaultInput, fixedInput } = options;
1487
- console.debug(`Running ${code$f} handler...`);
1492
+ console.debug(`Running ${code$j} handler...`);
1488
1493
  console.debug(`defaultInput: ${JSON.stringify(defaultInput)}`);
1489
1494
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
1490
1495
  console.debug(`fixedInput: ${JSON.stringify(fixedInput)}`);
@@ -1507,15 +1512,15 @@ async function handler$b(plugin, ctx, options) {
1507
1512
 
1508
1513
  var createCollectionEntity = /*#__PURE__*/Object.freeze({
1509
1514
  __proto__: null,
1510
- code: code$f,
1511
- handler: handler$b
1515
+ code: code$j,
1516
+ handler: handler$e
1512
1517
  });
1513
1518
 
1514
- const code$e = "createCollectionEntitiesBatch";
1515
- async function handler$a(plugin, ctx, options) {
1519
+ const code$i = "createCollectionEntitiesBatch";
1520
+ async function handler$d(plugin, ctx, options) {
1516
1521
  const { server, input } = ctx;
1517
1522
  const { defaultInput, fixedInput } = options;
1518
- console.debug(`Running ${code$e} handler...`);
1523
+ console.debug(`Running ${code$i} handler...`);
1519
1524
  const { entities } = input;
1520
1525
  if (!_.isArray(entities)) {
1521
1526
  throw new Error("input.entities should be an array.");
@@ -1546,8 +1551,8 @@ async function handler$a(plugin, ctx, options) {
1546
1551
 
1547
1552
  var createCollectionEntitiesBatch = /*#__PURE__*/Object.freeze({
1548
1553
  __proto__: null,
1549
- code: code$e,
1550
- handler: handler$a
1554
+ code: code$i,
1555
+ handler: handler$d
1551
1556
  });
1552
1557
 
1553
1558
  function getEntityPartChanges(before, after) {
@@ -1571,11 +1576,11 @@ function getEntityPartChanges(before, after) {
1571
1576
  return changed;
1572
1577
  }
1573
1578
 
1574
- const code$d = "updateCollectionEntityById";
1575
- async function handler$9(plugin, ctx, options) {
1579
+ const code$h = "updateCollectionEntityById";
1580
+ async function handler$c(plugin, ctx, options) {
1576
1581
  const { server, input } = ctx;
1577
1582
  const { defaultInput, fixedInput } = options;
1578
- console.debug(`Running ${code$d} handler...`);
1583
+ console.debug(`Running ${code$h} handler...`);
1579
1584
  console.debug(`defaultInput: ${JSON.stringify(defaultInput)}`);
1580
1585
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
1581
1586
  console.debug(`fixedInput: ${JSON.stringify(fixedInput)}`);
@@ -1605,13 +1610,13 @@ async function handler$9(plugin, ctx, options) {
1605
1610
 
1606
1611
  var updateCollectionEntityById = /*#__PURE__*/Object.freeze({
1607
1612
  __proto__: null,
1608
- code: code$d,
1609
- handler: handler$9
1613
+ code: code$h,
1614
+ handler: handler$c
1610
1615
  });
1611
1616
 
1612
- const code$c = "deleteCollectionEntityById";
1613
- async function handler$8(plugin, ctx, options) {
1614
- console.debug(`Running ${code$c} handler...`);
1617
+ const code$g = "deleteCollectionEntityById";
1618
+ async function handler$b(plugin, ctx, options) {
1619
+ console.debug(`Running ${code$g} handler...`);
1615
1620
  const { server, input } = ctx;
1616
1621
  const dataAccessor = server.getDataAccessor(options);
1617
1622
  const id = input.id;
@@ -1632,16 +1637,16 @@ async function handler$8(plugin, ctx, options) {
1632
1637
 
1633
1638
  var deleteCollectionEntityById = /*#__PURE__*/Object.freeze({
1634
1639
  __proto__: null,
1635
- code: code$c,
1636
- handler: handler$8
1640
+ code: code$g,
1641
+ handler: handler$b
1637
1642
  });
1638
1643
 
1639
- const code$b = "addEntityRelations";
1640
- async function handler$7(plugin, ctx, options) {
1644
+ const code$f = "addEntityRelations";
1645
+ async function handler$a(plugin, ctx, options) {
1641
1646
  const { server, input } = ctx;
1642
1647
  const { queryBuilder } = server;
1643
1648
  const { defaultInput, fixedInput } = options;
1644
- console.debug(`Running ${code$b} handler...`);
1649
+ console.debug(`Running ${code$f} handler...`);
1645
1650
  console.debug(`defaultInput: ${JSON.stringify(defaultInput)}`);
1646
1651
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
1647
1652
  console.debug(`fixedInput: ${JSON.stringify(fixedInput)}`);
@@ -1684,16 +1689,16 @@ async function handler$7(plugin, ctx, options) {
1684
1689
 
1685
1690
  var addEntityRelations = /*#__PURE__*/Object.freeze({
1686
1691
  __proto__: null,
1687
- code: code$b,
1688
- handler: handler$7
1692
+ code: code$f,
1693
+ handler: handler$a
1689
1694
  });
1690
1695
 
1691
- const code$a = "removeEntityRelations";
1692
- async function handler$6(plugin, ctx, options) {
1696
+ const code$e = "removeEntityRelations";
1697
+ async function handler$9(plugin, ctx, options) {
1693
1698
  const { server, input } = ctx;
1694
1699
  const { queryBuilder } = server;
1695
1700
  const { defaultInput, fixedInput } = options;
1696
- console.debug(`Running ${code$a} handler...`);
1701
+ console.debug(`Running ${code$e} handler...`);
1697
1702
  console.debug(`defaultInput: ${JSON.stringify(defaultInput)}`);
1698
1703
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
1699
1704
  console.debug(`fixedInput: ${JSON.stringify(fixedInput)}`);
@@ -1733,15 +1738,15 @@ async function handler$6(plugin, ctx, options) {
1733
1738
 
1734
1739
  var removeEntityRelations = /*#__PURE__*/Object.freeze({
1735
1740
  __proto__: null,
1736
- code: code$a,
1737
- handler: handler$6
1741
+ code: code$e,
1742
+ handler: handler$9
1738
1743
  });
1739
1744
 
1740
- const code$9 = "queryDatabase";
1741
- async function handler$5(plugin, ctx, options) {
1745
+ const code$d = "queryDatabase";
1746
+ async function handler$8(plugin, ctx, options) {
1742
1747
  const { server, input } = ctx;
1743
1748
  const { sql, querySingle, defaultInput, fixedInput } = options;
1744
- console.debug(`Running ${code$9} handler...`);
1749
+ console.debug(`Running ${code$d} handler...`);
1745
1750
  console.debug(`defaultInput: ${JSON.stringify(defaultInput)}`);
1746
1751
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
1747
1752
  console.debug(`fixedInput: ${JSON.stringify(fixedInput)}`);
@@ -1757,8 +1762,8 @@ async function handler$5(plugin, ctx, options) {
1757
1762
 
1758
1763
  var queryDatabase = /*#__PURE__*/Object.freeze({
1759
1764
  __proto__: null,
1760
- code: code$9,
1761
- handler: handler$5
1765
+ code: code$d,
1766
+ handler: handler$8
1762
1767
  });
1763
1768
 
1764
1769
  /**
@@ -1766,11 +1771,11 @@ var queryDatabase = /*#__PURE__*/Object.freeze({
1766
1771
  * This plugin provide:
1767
1772
  * - routes for manage data in database.
1768
1773
  */
1769
- const code$8 = "dataManager";
1770
- const description$3 = "对数据进行管理,提供增删改查等接口。";
1771
- const extendingAbilities$3 = [];
1772
- const configurableTargets$3 = [];
1773
- const configurations$3 = [];
1774
+ const code$c = "dataManager";
1775
+ const description$4 = "对数据进行管理,提供增删改查等接口。";
1776
+ const extendingAbilities$4 = [];
1777
+ const configurableTargets$4 = [];
1778
+ const configurations$4 = [];
1774
1779
  const routeConfigs = [
1775
1780
  {
1776
1781
  code: "createBatch",
@@ -1827,21 +1832,21 @@ const routeConfigs = [
1827
1832
  handlerCode: "deleteCollectionEntityById",
1828
1833
  },
1829
1834
  ];
1830
- let _plugin$3;
1831
- async function initPlugin$3(plugin, server) {
1832
- _plugin$3 = plugin;
1835
+ let _plugin$4;
1836
+ async function initPlugin$4(plugin, server) {
1837
+ _plugin$4 = plugin;
1833
1838
  }
1834
- async function registerHttpHandlers$3(server) {
1835
- server.registerHttpHandler(_plugin$3, findCollectionEntitiesHttpHandler);
1836
- server.registerHttpHandler(_plugin$3, findCollectionEntityById);
1837
- server.registerHttpHandler(_plugin$3, countCollectionEntities);
1838
- server.registerHttpHandler(_plugin$3, createCollectionEntity);
1839
- server.registerHttpHandler(_plugin$3, createCollectionEntitiesBatch);
1840
- server.registerHttpHandler(_plugin$3, updateCollectionEntityById);
1841
- server.registerHttpHandler(_plugin$3, addEntityRelations);
1842
- server.registerHttpHandler(_plugin$3, removeEntityRelations);
1843
- server.registerHttpHandler(_plugin$3, deleteCollectionEntityById);
1844
- server.registerHttpHandler(_plugin$3, queryDatabase);
1839
+ async function registerHttpHandlers$4(server) {
1840
+ server.registerHttpHandler(_plugin$4, findCollectionEntitiesHttpHandler);
1841
+ server.registerHttpHandler(_plugin$4, findCollectionEntityById);
1842
+ server.registerHttpHandler(_plugin$4, countCollectionEntities);
1843
+ server.registerHttpHandler(_plugin$4, createCollectionEntity);
1844
+ server.registerHttpHandler(_plugin$4, createCollectionEntitiesBatch);
1845
+ server.registerHttpHandler(_plugin$4, updateCollectionEntityById);
1846
+ server.registerHttpHandler(_plugin$4, addEntityRelations);
1847
+ server.registerHttpHandler(_plugin$4, removeEntityRelations);
1848
+ server.registerHttpHandler(_plugin$4, deleteCollectionEntityById);
1849
+ server.registerHttpHandler(_plugin$4, queryDatabase);
1845
1850
  }
1846
1851
  async function configureRoutes$3(server, applicationConfig) {
1847
1852
  const { models } = applicationConfig;
@@ -1870,11 +1875,158 @@ async function configureRoutes$3(server, applicationConfig) {
1870
1875
  });
1871
1876
  server.appendApplicationConfig({ routes });
1872
1877
  }
1873
- async function onApplicationLoaded$4(server, application) {
1878
+ async function onApplicationLoaded$5(server, application) {
1874
1879
  console.log("[dataManager.onApplicationLoaded]");
1875
1880
  }
1876
1881
 
1877
1882
  var dataManager = /*#__PURE__*/Object.freeze({
1883
+ __proto__: null,
1884
+ code: code$c,
1885
+ description: description$4,
1886
+ extendingAbilities: extendingAbilities$4,
1887
+ configurableTargets: configurableTargets$4,
1888
+ configurations: configurations$4,
1889
+ initPlugin: initPlugin$4,
1890
+ registerHttpHandlers: registerHttpHandlers$4,
1891
+ configureRoutes: configureRoutes$3,
1892
+ onApplicationLoaded: onApplicationLoaded$5
1893
+ });
1894
+
1895
+ async function readFile(path) {
1896
+ return new Promise((resolve, reject) => {
1897
+ fs__default["default"].readFile(path, null, (err, data) => {
1898
+ if (err) {
1899
+ reject(err);
1900
+ }
1901
+ else {
1902
+ resolve(data);
1903
+ }
1904
+ });
1905
+ });
1906
+ }
1907
+ async function appendFile(path, data) {
1908
+ return new Promise((resolve, reject) => {
1909
+ fs__default["default"].appendFile(path, Buffer.from(data), (err) => {
1910
+ if (err) {
1911
+ reject(err);
1912
+ }
1913
+ else {
1914
+ resolve();
1915
+ }
1916
+ });
1917
+ });
1918
+ }
1919
+
1920
+ const code$b = "downloadDocument";
1921
+ async function handler$7(plugin, ctx, options) {
1922
+ const { server, applicationConfig, routerContext, input } = ctx;
1923
+ const { request, response } = routerContext;
1924
+ const documentDataAccessor = ctx.server.getDataAccessor({
1925
+ singularCode: "ecm_document",
1926
+ });
1927
+ const storageDataAccessor = ctx.server.getDataAccessor({
1928
+ singularCode: "ecm_storage_object",
1929
+ });
1930
+ const document = await documentDataAccessor.findById(input.documentId);
1931
+ if (!document) {
1932
+ ctx.output = { error: new Error("Document not found.") };
1933
+ return;
1934
+ }
1935
+ const storageObject = await storageDataAccessor.findById(document.storage_object_id);
1936
+ if (!storageObject) {
1937
+ ctx.output = { error: new Error("Storage object not found.") };
1938
+ return;
1939
+ }
1940
+ const fileKey = storageObject.key;
1941
+ const filePathName = path__default["default"].join(server.config.localFileStoragePath, fileKey);
1942
+ const attachmentFileName = document.name;
1943
+ response.body = await readFile(filePathName);
1944
+ response.headers.set("Content-Disposition", `attachment; filename="${encodeURIComponent(attachmentFileName)}"`);
1945
+ }
1946
+
1947
+ var downloadDocumentHttpHandler = /*#__PURE__*/Object.freeze({
1948
+ __proto__: null,
1949
+ code: code$b,
1950
+ handler: handler$7
1951
+ });
1952
+
1953
+ const code$a = "downloadFile";
1954
+ async function handler$6(plugin, ctx, options) {
1955
+ const { server, applicationConfig, routerContext, input } = ctx;
1956
+ const { request, response } = routerContext;
1957
+ const dataAccessor = ctx.server.getDataAccessor({
1958
+ singularCode: "ecm_storage_object",
1959
+ });
1960
+ const storageObject = await dataAccessor.findById(input.fileId);
1961
+ if (!storageObject) {
1962
+ ctx.output = { error: new Error("Storage object not found.") };
1963
+ return;
1964
+ }
1965
+ const fileKey = storageObject.key;
1966
+ const filePathName = path__default["default"].join(server.config.localFileStoragePath, fileKey);
1967
+ const attachmentFileName = input.fileName || path__default["default"].basename(fileKey);
1968
+ response.body = await readFile(filePathName);
1969
+ response.headers.set("Content-Disposition", `attachment; filename="${encodeURIComponent(attachmentFileName)}"`);
1970
+ }
1971
+
1972
+ var downloadFileHttpHandler = /*#__PURE__*/Object.freeze({
1973
+ __proto__: null,
1974
+ code: code$a,
1975
+ handler: handler$6
1976
+ });
1977
+
1978
+ const code$9 = "uploadFile";
1979
+ async function handler$5(plugin, ctx, options) {
1980
+ const { server, applicationConfig, routerContext, input } = ctx;
1981
+ let file = input.files;
1982
+ if (_.isArray(file)) {
1983
+ file = file[0];
1984
+ }
1985
+ if (!file) {
1986
+ ctx.status = 400;
1987
+ ctx.output = { error: "File not found in request body." };
1988
+ return;
1989
+ }
1990
+ const extName = path__default["default"].extname(file.name);
1991
+ const fileKey = `${uuid.v1()}${extName}`;
1992
+ const filePathName = path__default["default"].join(server.config.localFileStoragePath, fileKey);
1993
+ const fileBuffer = await file.arrayBuffer();
1994
+ await appendFile(filePathName, fileBuffer);
1995
+ ctx.output = { ok: true, fileKey };
1996
+ }
1997
+
1998
+ var uploadFileHttpHandler = /*#__PURE__*/Object.freeze({
1999
+ __proto__: null,
2000
+ code: code$9,
2001
+ handler: handler$5
2002
+ });
2003
+
2004
+ /**
2005
+ * File manager plugin
2006
+ */
2007
+ const code$8 = "fileManager";
2008
+ const description$3 = "fileManager";
2009
+ const extendingAbilities$3 = [];
2010
+ const configurableTargets$3 = [];
2011
+ const configurations$3 = [];
2012
+ let _plugin$3;
2013
+ async function initPlugin$3(plugin, server) {
2014
+ _plugin$3 = plugin;
2015
+ }
2016
+ async function registerHttpHandlers$3(server) {
2017
+ server.registerHttpHandler(_plugin$3, downloadDocumentHttpHandler);
2018
+ server.registerHttpHandler(_plugin$3, downloadFileHttpHandler);
2019
+ server.registerHttpHandler(_plugin$3, uploadFileHttpHandler);
2020
+ }
2021
+ async function registerEventHandlers$3(server) {
2022
+ }
2023
+ async function configureModels$3(server, applicationConfig) {
2024
+ }
2025
+ async function onApplicationLoaded$4(server, applicationConfig) {
2026
+ console.log("fileManager.onApplicationLoaded");
2027
+ }
2028
+
2029
+ var fileManager = /*#__PURE__*/Object.freeze({
1878
2030
  __proto__: null,
1879
2031
  code: code$8,
1880
2032
  description: description$3,
@@ -1883,7 +2035,8 @@ var dataManager = /*#__PURE__*/Object.freeze({
1883
2035
  configurations: configurations$3,
1884
2036
  initPlugin: initPlugin$3,
1885
2037
  registerHttpHandlers: registerHttpHandlers$3,
1886
- configureRoutes: configureRoutes$3,
2038
+ registerEventHandlers: registerEventHandlers$3,
2039
+ configureModels: configureModels$3,
1887
2040
  onApplicationLoaded: onApplicationLoaded$4
1888
2041
  });
1889
2042
 
@@ -1990,16 +2143,7 @@ async function buildRoutes(server, applicationConfig) {
1990
2143
  requestMethod === "PATCH")) {
1991
2144
  const body = request.body;
1992
2145
  if (body) {
1993
- if (body.type === "form-data") {
1994
- const formDataReader = body.value;
1995
- const formDataBody = await formDataReader.read({ maxFileSize: 1073741824 /* 1GB */ });
1996
- Object.assign(input, {
1997
- formData: formDataBody
1998
- });
1999
- }
2000
- else {
2001
- Object.assign(input, body.value);
2002
- }
2146
+ Object.assign(input, body.value);
2003
2147
  }
2004
2148
  }
2005
2149
  // Normalize input value
@@ -2022,11 +2166,8 @@ async function buildRoutes(server, applicationConfig) {
2022
2166
  await result;
2023
2167
  }
2024
2168
  }
2025
- if (handlerContext.status) {
2026
- routerContext.status = handlerContext.status;
2027
- }
2028
2169
  if (!isNullOrUndefined(handlerContext.output)) {
2029
- routerContext.json(handlerContext.output);
2170
+ routerContext.json(handlerContext.output, handlerContext.status);
2030
2171
  }
2031
2172
  });
2032
2173
  });
@@ -2887,6 +3028,7 @@ const plugins = [];
2887
3028
  async function loadPlugins() {
2888
3029
  plugins.push(metaManager);
2889
3030
  plugins.push(dataManager);
3031
+ plugins.push(fileManager);
2890
3032
  plugins.push(routeManager);
2891
3033
  plugins.push(webhooks$1);
2892
3034
  plugins.push(authManager);
@@ -3064,7 +3206,6 @@ class RouteContext {
3064
3206
  state;
3065
3207
  method;
3066
3208
  path;
3067
- status;
3068
3209
  params;
3069
3210
  constructor(request) {
3070
3211
  this.request = request;
@@ -3086,6 +3227,61 @@ class RouteContext {
3086
3227
  }
3087
3228
  }
3088
3229
 
3230
+ const parseFormDataBody = async (request, options = { all: false }) => {
3231
+ const contentType = request.headers.get('Content-Type');
3232
+ if (isFormDataContent(contentType)) {
3233
+ return parseFormData(request, options);
3234
+ }
3235
+ return {};
3236
+ };
3237
+ function isFormDataContent(contentType) {
3238
+ if (contentType === null) {
3239
+ return false;
3240
+ }
3241
+ return (contentType.startsWith('multipart/form-data') ||
3242
+ contentType.startsWith('application/x-www-form-urlencoded'));
3243
+ }
3244
+ async function parseFormData(request, options) {
3245
+ const formData = await request.formData();
3246
+ if (formData) {
3247
+ return convertFormDataToBodyData(formData, options);
3248
+ }
3249
+ return {};
3250
+ }
3251
+ function convertFormDataToBodyData(formData, options) {
3252
+ const form = {};
3253
+ formData.forEach((value, key) => {
3254
+ const shouldParseAllValues = options.all || key.endsWith('[]');
3255
+ if (!shouldParseAllValues) {
3256
+ form[key] = value;
3257
+ }
3258
+ else {
3259
+ handleParsingAllValues(form, key, value);
3260
+ }
3261
+ });
3262
+ return form;
3263
+ }
3264
+ const handleParsingAllValues = (form, key, value) => {
3265
+ if (form[key] && isArrayField(form[key])) {
3266
+ appendToExistingArray(form[key], value);
3267
+ }
3268
+ else if (form[key]) {
3269
+ convertToNewArray(form, key, value);
3270
+ }
3271
+ else {
3272
+ form[key] = value;
3273
+ }
3274
+ };
3275
+ function isArrayField(field) {
3276
+ return Array.isArray(field);
3277
+ }
3278
+ const appendToExistingArray = (arr, value) => {
3279
+ arr.push(value);
3280
+ };
3281
+ const convertToNewArray = (form, key, value) => {
3282
+ form[key] = [form[key], value];
3283
+ };
3284
+
3089
3285
  const GlobalRequest = global.Request;
3090
3286
  class RapidRequest {
3091
3287
  #raw;
@@ -3125,7 +3321,7 @@ class RapidRequest {
3125
3321
  else if (contentType.startsWith("multipart/form-data")) {
3126
3322
  this.#body = {
3127
3323
  type: "form-data",
3128
- value: await req.formData(),
3324
+ value: await parseFormDataBody(req),
3129
3325
  };
3130
3326
  }
3131
3327
  }
@@ -0,0 +1,4 @@
1
+ import { IPluginInstance } from "~/types";
2
+ import { HttpHandlerContext } from "~/core/httpHandler";
3
+ export declare const code = "downloadDocument";
4
+ export declare function handler(plugin: IPluginInstance, ctx: HttpHandlerContext, options: any): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import { IPluginInstance } from "~/types";
2
+ import { HttpHandlerContext } from "~/core/httpHandler";
3
+ export declare const code = "downloadFile";
4
+ export declare function handler(plugin: IPluginInstance, ctx: HttpHandlerContext, options: any): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import { IPluginInstance } from "~/types";
2
+ import { HttpHandlerContext } from "~/core/httpHandler";
3
+ export declare const code = "uploadFile";
4
+ export declare function handler(plugin: IPluginInstance, ctx: HttpHandlerContext, options: any): Promise<void>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * File manager plugin
3
+ */
4
+ import { IPluginInstance, RpdApplicationConfig } from "~/types";
5
+ import { IRpdServer, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "~/core/server";
6
+ export declare const code = "fileManager";
7
+ export declare const description = "fileManager";
8
+ export declare const extendingAbilities: RpdServerPluginExtendingAbilities[];
9
+ export declare const configurableTargets: RpdServerPluginConfigurableTargetOptions[];
10
+ export declare const configurations: RpdConfigurationItemOptions[];
11
+ export declare function initPlugin(plugin: IPluginInstance, server: IRpdServer): Promise<void>;
12
+ export declare function registerHttpHandlers(server: IRpdServer): Promise<void>;
13
+ export declare function registerEventHandlers(server: IRpdServer): Promise<void>;
14
+ export declare function configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<void>;
15
+ export declare function onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<void>;
@@ -0,0 +1,6 @@
1
+ /// <reference types="node" />
2
+ export declare function readFile(path: string): Promise<Buffer>;
3
+ export declare function copyFile(fromPath: string, toPath: string): Promise<void>;
4
+ export declare function removeFile(path: string): Promise<void>;
5
+ export declare function moveFile(fromPath: string, toPath: string): Promise<void>;
6
+ export declare function appendFile(path: string, data: ArrayBuffer): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [],
@@ -20,7 +20,8 @@
20
20
  "jsonwebtoken": "^9.0.2",
21
21
  "koa-tree-router": "^0.12.1",
22
22
  "lodash": "^4.17.21",
23
- "qs": "^6.11.0"
23
+ "qs": "^6.11.0",
24
+ "uuid": "^9.0.1"
24
25
  },
25
26
  "scripts": {
26
27
  "build": "rimraf dist && rollup --config",
@@ -0,0 +1,101 @@
1
+ import type { RapidRequest } from '../request'
2
+
3
+ export type BodyData = Record<string, string | File | (string | File)[]>
4
+ export type ParseBodyOptions = {
5
+ /**
6
+ * Parse all fields with multiple values should be parsed as an array.
7
+ * @default false
8
+ * @example
9
+ * ```ts
10
+ * const data = new FormData()
11
+ * data.append('file', 'aaa')
12
+ * data.append('file', 'bbb')
13
+ * data.append('message', 'hello')
14
+ * ```
15
+ *
16
+ * If `all` is `false`:
17
+ * parseBody should return `{ file: 'bbb', message: 'hello' }`
18
+ *
19
+ * If `all` is `true`:
20
+ * parseBody should return `{ file: ['aaa', 'bbb'], message: 'hello' }`
21
+ */
22
+ all?: boolean
23
+ }
24
+
25
+ export const parseFormDataBody = async <T extends BodyData = BodyData>(
26
+ request: Request,
27
+ options: ParseBodyOptions = { all: false }
28
+ ): Promise<T> => {
29
+ const contentType = request.headers.get('Content-Type')
30
+
31
+ if (isFormDataContent(contentType)) {
32
+ return parseFormData<T>(request, options)
33
+ }
34
+
35
+ return {} as T
36
+ }
37
+
38
+ function isFormDataContent(contentType: string | null): boolean {
39
+ if (contentType === null) {
40
+ return false
41
+ }
42
+
43
+ return (
44
+ contentType.startsWith('multipart/form-data') ||
45
+ contentType.startsWith('application/x-www-form-urlencoded')
46
+ )
47
+ }
48
+
49
+ async function parseFormData<T extends BodyData = BodyData>(
50
+ request: Request,
51
+ options: ParseBodyOptions
52
+ ): Promise<T> {
53
+ const formData = await (request as Request).formData()
54
+
55
+ if (formData) {
56
+ return convertFormDataToBodyData<T>(formData, options)
57
+ }
58
+
59
+ return {} as T
60
+ }
61
+
62
+ function convertFormDataToBodyData<T extends BodyData = BodyData>(
63
+ formData: FormData,
64
+ options: ParseBodyOptions
65
+ ): T {
66
+ const form: BodyData = {}
67
+
68
+ formData.forEach((value, key) => {
69
+ const shouldParseAllValues = options.all || key.endsWith('[]')
70
+
71
+ if (!shouldParseAllValues) {
72
+ form[key] = value
73
+ } else {
74
+ handleParsingAllValues(form, key, value)
75
+ }
76
+ })
77
+
78
+ return form as T
79
+ }
80
+
81
+ const handleParsingAllValues = (form: BodyData, key: string, value: FormDataEntryValue): void => {
82
+ if (form[key] && isArrayField(form[key])) {
83
+ appendToExistingArray(form[key] as (string | File)[], value)
84
+ } else if (form[key]) {
85
+ convertToNewArray(form, key, value)
86
+ } else {
87
+ form[key] = value
88
+ }
89
+ }
90
+
91
+ function isArrayField(field: unknown): field is (string | File)[] {
92
+ return Array.isArray(field)
93
+ }
94
+
95
+ const appendToExistingArray = (arr: (string | File)[], value: FormDataEntryValue): void => {
96
+ arr.push(value)
97
+ }
98
+
99
+ const convertToNewArray = (form: BodyData, key: string, value: FormDataEntryValue): void => {
100
+ form[key] = [form[key] as string | File, value]
101
+ }
@@ -2,6 +2,7 @@ import { RpdApplicationConfig } from "~/types";
2
2
  import Plugin from "./plugin";
3
3
  import * as metaManager from "~/plugins/metaManager/mod";
4
4
  import * as dataManager from "~/plugins/dataManager/mod";
5
+ import * as fileManager from "~/plugins/fileManager/mod";
5
6
  import * as routeManager from "~/plugins/routeManager/mod";
6
7
  import * as webhooks from "~/plugins/webhooks/mod";
7
8
  import * as authManager from "~/plugins/authManager/mod";
@@ -12,6 +13,7 @@ const plugins: IRpdServerPlugin[] = [];
12
13
  export async function loadPlugins() {
13
14
  plugins.push(metaManager);
14
15
  plugins.push(dataManager);
16
+ plugins.push(fileManager);
15
17
  plugins.push(routeManager);
16
18
  plugins.push(webhooks);
17
19
  plugins.push(authManager);
@@ -0,0 +1,5 @@
1
+ export interface IRuntimeProvider {
2
+ copyFile(fromPath: string, toPath: string): Promise<void>;
3
+
4
+ removeFile(path: string): Promise<void>;
5
+ }
@@ -1,4 +1,5 @@
1
1
  import qs from "qs";
2
+ import { parseFormDataBody } from "./http/formDataParser";
2
3
 
3
4
  export const GlobalRequest = global.Request;
4
5
 
@@ -46,7 +47,7 @@ export class RapidRequest {
46
47
  } else if (contentType.startsWith("multipart/form-data")) {
47
48
  this.#body = {
48
49
  type: "form-data",
49
- value: await req.formData(),
50
+ value: await parseFormDataBody(req),
50
51
  }
51
52
  }
52
53
  } else {
@@ -11,7 +11,6 @@ export class RouteContext {
11
11
  readonly state: Record<string, any>;
12
12
  method: string;
13
13
  path: string;
14
- status: HttpStatus;
15
14
  params: Record<string, string>;
16
15
 
17
16
  constructor(request: RapidRequest) {
@@ -47,15 +47,7 @@ export async function buildRoutes(
47
47
  ) {
48
48
  const body = request.body;
49
49
  if (body) {
50
- if (body.type === "form-data") {
51
- const formDataReader = body.value;
52
- const formDataBody = await formDataReader.read({ maxFileSize: 1073741824 /* 1GB */});
53
- Object.assign(input, {
54
- formData: formDataBody
55
- });
56
- } else {
57
- Object.assign(input, body.value);
58
- }
50
+ Object.assign(input, body.value);
59
51
  }
60
52
  }
61
53
 
@@ -84,12 +76,8 @@ export async function buildRoutes(
84
76
  }
85
77
  }
86
78
 
87
- if (handlerContext.status) {
88
- routerContext.status = handlerContext.status;
89
- }
90
-
91
79
  if (!isNullOrUndefined(handlerContext.output)) {
92
- routerContext.json(handlerContext.output);
80
+ routerContext.json(handlerContext.output, handlerContext.status);
93
81
  }
94
82
  },
95
83
  );
@@ -0,0 +1,40 @@
1
+ import path from "path";
2
+ import { IPluginInstance } from "~/types";
3
+ import { HttpHandlerContext } from "~/core/httpHandler";
4
+ import { readFile } from "~/utilities/fsUtility";
5
+
6
+ export const code = "downloadDocument";
7
+
8
+ export async function handler(
9
+ plugin: IPluginInstance,
10
+ ctx: HttpHandlerContext,
11
+ options: any,
12
+ ) {
13
+ const { server, applicationConfig, routerContext, input } = ctx;
14
+ const { request, response } = routerContext;
15
+
16
+ const documentDataAccessor = ctx.server.getDataAccessor({
17
+ singularCode: "ecm_document",
18
+ });
19
+ const storageDataAccessor = ctx.server.getDataAccessor({
20
+ singularCode: "ecm_storage_object",
21
+ });
22
+
23
+ const document = await documentDataAccessor.findById(input.documentId);
24
+ if (!document) {
25
+ ctx.output = { error: new Error("Document not found.") };
26
+ return;
27
+ }
28
+ const storageObject = await storageDataAccessor.findById(document.storage_object_id);
29
+ if (!storageObject) {
30
+ ctx.output = { error: new Error("Storage object not found.") };
31
+ return;
32
+ }
33
+
34
+ const fileKey = storageObject.key;
35
+ const filePathName = path.join(server.config.localFileStoragePath, fileKey);
36
+ const attachmentFileName = document.name;
37
+
38
+ response.body = await readFile(filePathName);
39
+ response.headers.set("Content-Disposition", `attachment; filename="${encodeURIComponent(attachmentFileName)}"`)
40
+ }
@@ -0,0 +1,32 @@
1
+ import path from "path";
2
+ import { IPluginInstance } from "~/types";
3
+ import { readFile } from "~/utilities/fsUtility";
4
+ import { HttpHandlerContext } from "~/core/httpHandler";
5
+
6
+ export const code = "downloadFile";
7
+
8
+ export async function handler(
9
+ plugin: IPluginInstance,
10
+ ctx: HttpHandlerContext,
11
+ options: any,
12
+ ) {
13
+ const { server, applicationConfig, routerContext, input } = ctx;
14
+ const { request, response } = routerContext;
15
+
16
+ const dataAccessor = ctx.server.getDataAccessor({
17
+ singularCode: "ecm_storage_object",
18
+ });
19
+
20
+ const storageObject = await dataAccessor.findById(input.fileId);
21
+ if (!storageObject) {
22
+ ctx.output = { error: new Error("Storage object not found.") };
23
+ return;
24
+ }
25
+
26
+ const fileKey = storageObject.key;
27
+ const filePathName = path.join(server.config.localFileStoragePath, fileKey);
28
+ const attachmentFileName = input.fileName || path.basename(fileKey);
29
+
30
+ response.body = await readFile(filePathName);
31
+ response.headers.set("Content-Disposition", `attachment; filename="${encodeURIComponent(attachmentFileName)}"`)
32
+ }
@@ -0,0 +1,37 @@
1
+ import { v1 as uuidv1 } from "uuid";
2
+ import { IPluginInstance } from "~/types";
3
+ import { appendFile } from "~/utilities/fsUtility";
4
+ import { HttpHandlerContext } from "~/core/httpHandler";
5
+ import path from "path";
6
+ import { isArray } from "lodash";
7
+
8
+ export const code = "uploadFile";
9
+
10
+ export async function handler(
11
+ plugin: IPluginInstance,
12
+ ctx: HttpHandlerContext,
13
+ options: any,
14
+ ) {
15
+ const { server, applicationConfig, routerContext, input } = ctx;
16
+ const { request, response } = routerContext;
17
+
18
+ let file: File | File[] | null = input.files;
19
+ if (isArray(file)) {
20
+ file = file[0];
21
+ }
22
+
23
+ if (!file) {
24
+ ctx.status = 400;
25
+ ctx.output = { error: "File not found in request body."};
26
+ return;
27
+ }
28
+
29
+ const extName = path.extname(file.name);
30
+ const fileKey = `${uuidv1()}${extName}`
31
+ const filePathName = path.join(server.config.localFileStoragePath, fileKey);
32
+
33
+ const fileBuffer = await file.arrayBuffer();
34
+ await appendFile(filePathName, fileBuffer);
35
+
36
+ ctx.output = { ok: true, fileKey };
37
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * File manager plugin
3
+ */
4
+
5
+ import * as _ from "lodash";
6
+ import {
7
+ IPluginInstance,
8
+ RpdApplicationConfig,
9
+ } from "~/types";
10
+
11
+ import * as downloadDocumentHttpHandler from "./httpHandlers/downloadDocument";
12
+ import * as downloadFileHttpHandler from "./httpHandlers/downloadFile";
13
+ import * as uploadFileHttpHandler from "./httpHandlers/uploadFile";
14
+ import { IRpdServer, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "~/core/server";
15
+
16
+ export const code = "fileManager";
17
+ export const description = "fileManager";
18
+ export const extendingAbilities: RpdServerPluginExtendingAbilities[] = [];
19
+ export const configurableTargets: RpdServerPluginConfigurableTargetOptions[] = [];
20
+ export const configurations: RpdConfigurationItemOptions[] = [];
21
+
22
+ let _plugin: IPluginInstance;
23
+
24
+ export async function initPlugin(plugin: IPluginInstance, server: IRpdServer) {
25
+ _plugin = plugin;
26
+ }
27
+
28
+ export async function registerHttpHandlers(server: IRpdServer) {
29
+ server.registerHttpHandler(_plugin, downloadDocumentHttpHandler);
30
+ server.registerHttpHandler(_plugin, downloadFileHttpHandler);
31
+ server.registerHttpHandler(_plugin, uploadFileHttpHandler);
32
+ }
33
+
34
+ export async function registerEventHandlers(server: IRpdServer) {
35
+ }
36
+
37
+ export async function configureModels(
38
+ server: IRpdServer,
39
+ applicationConfig: RpdApplicationConfig,
40
+ ) {
41
+ }
42
+
43
+ export async function onApplicationLoaded(
44
+ server: IRpdServer,
45
+ applicationConfig: RpdApplicationConfig,
46
+ ) {
47
+ console.log("fileManager.onApplicationLoaded");
48
+ }
@@ -0,0 +1,62 @@
1
+ import fs from 'fs';
2
+
3
+ export async function readFile(path: string): Promise<Buffer> {
4
+ return new Promise((resolve, reject) => {
5
+ fs.readFile(path, null, (err, data) => {
6
+ if (err) {
7
+ reject(err);
8
+ } else {
9
+ resolve(data);
10
+ }
11
+ })
12
+ })
13
+ }
14
+
15
+ export async function copyFile(fromPath: string, toPath: string): Promise<void> {
16
+ return new Promise((resolve, reject) => {
17
+ fs.copyFile(fromPath, toPath, (err) => {
18
+ if (err) {
19
+ reject(err);
20
+ } else {
21
+ resolve();
22
+ }
23
+ })
24
+ })
25
+ }
26
+
27
+ export async function removeFile(path: string): Promise<void> {
28
+ return new Promise((resolve, reject) => {
29
+ fs.rm(path, (err) => {
30
+ if (err) {
31
+ reject(err);
32
+ } else {
33
+ resolve();
34
+ }
35
+ })
36
+ })
37
+ }
38
+
39
+ export async function moveFile(fromPath: string, toPath: string): Promise<void> {
40
+ return new Promise((resolve, reject) => {
41
+ fs.rename(fromPath, toPath, (err) => {
42
+ if (err) {
43
+ reject(err);
44
+ } else {
45
+ resolve();
46
+ }
47
+ })
48
+ })
49
+ }
50
+
51
+ export async function appendFile(path: string, data: ArrayBuffer): Promise<void> {
52
+ return new Promise((resolve, reject) => {
53
+ fs.appendFile(path, Buffer.from(data), (err) => {
54
+ if (err) {
55
+ reject(err);
56
+ } else {
57
+ resolve();
58
+ }
59
+ })
60
+ })
61
+
62
+ }