@ruiapp/rapid-core 0.1.2 → 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.
Files changed (42) hide show
  1. package/dist/bootstrapApplicationConfig.d.ts +289 -2
  2. package/dist/core/http/formDataParser.d.ts +22 -0
  3. package/dist/core/providers/runtimeProvider.d.ts +4 -0
  4. package/dist/core/routeContext.d.ts +0 -1
  5. package/dist/deno-std/encoding/base64.d.ts +11 -0
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +492 -147
  8. package/dist/plugins/authManager/routes/getMyProfile.d.ts +11 -2
  9. package/dist/plugins/authManager/routes/index.d.ts +21 -1
  10. package/dist/plugins/authManager/routes/signin.d.ts +11 -2
  11. package/dist/plugins/authManager/routes/signout.d.ts +11 -2
  12. package/dist/plugins/fileManager/httpHandlers/downloadDocument.d.ts +4 -0
  13. package/dist/plugins/fileManager/httpHandlers/downloadFile.d.ts +4 -0
  14. package/dist/plugins/fileManager/httpHandlers/uploadFile.d.ts +4 -0
  15. package/dist/plugins/fileManager/mod.d.ts +15 -0
  16. package/dist/types.d.ts +2 -2
  17. package/dist/utilities/fsUtility.d.ts +6 -0
  18. package/dist/utilities/jwtUtility.d.ts +5 -8
  19. package/package.json +5 -3
  20. package/src/bootstrapApplicationConfig.ts +5 -5
  21. package/src/core/http/formDataParser.ts +101 -0
  22. package/src/core/pluginManager.ts +2 -0
  23. package/src/core/providers/runtimeProvider.ts +5 -0
  24. package/src/core/request.ts +2 -1
  25. package/src/core/routeContext.ts +0 -1
  26. package/src/core/routesBuilder.ts +3 -15
  27. package/src/deno-std/encoding/base64.ts +145 -0
  28. package/src/index.ts +2 -0
  29. package/src/plugins/authManager/httpHandlers/createSession.ts +4 -3
  30. package/src/plugins/authManager/routes/getMyProfile.ts +2 -2
  31. package/src/plugins/authManager/routes/signin.ts +2 -2
  32. package/src/plugins/authManager/routes/signout.ts +2 -2
  33. package/src/plugins/dataManager/httpHandlers/addEntityRelations.ts +0 -2
  34. package/src/plugins/dataManager/mod.ts +9 -9
  35. package/src/plugins/fileManager/httpHandlers/downloadDocument.ts +40 -0
  36. package/src/plugins/fileManager/httpHandlers/downloadFile.ts +32 -0
  37. package/src/plugins/fileManager/httpHandlers/uploadFile.ts +37 -0
  38. package/src/plugins/fileManager/mod.ts +48 -0
  39. package/src/server.ts +0 -1
  40. package/src/types.ts +2 -2
  41. package/src/utilities/fsUtility.ts +62 -0
  42. package/src/utilities/jwtUtility.ts +22 -8
@@ -39,55 +39,55 @@ const routeConfigs: {
39
39
  }[] = [
40
40
  {
41
41
  code: "createBatch",
42
- method: "post",
42
+ method: "POST",
43
43
  endpoint: "/operations/create_batch",
44
44
  handlerCode: "createCollectionEntitiesBatch",
45
45
  },
46
46
  {
47
47
  code: "find",
48
- method: "post",
48
+ method: "POST",
49
49
  endpoint: "/operations/find",
50
50
  handlerCode: "findCollectionEntities",
51
51
  },
52
52
  {
53
53
  code: "count",
54
- method: "post",
54
+ method: "POST",
55
55
  endpoint: "/operations/count",
56
56
  handlerCode: "countCollectionEntities",
57
57
  },
58
58
  {
59
59
  code: "addRelations",
60
- method: "post",
60
+ method: "POST",
61
61
  endpoint: "/operations/add_relations",
62
62
  handlerCode: "addEntityRelations",
63
63
  },
64
64
  {
65
65
  code: "removeRelations",
66
- method: "post",
66
+ method: "POST",
67
67
  endpoint: "/operations/remove_relations",
68
68
  handlerCode: "removeEntityRelations",
69
69
  },
70
70
  {
71
71
  code: "getById",
72
- method: "get",
72
+ method: "GET",
73
73
  endpoint: "/:id",
74
74
  handlerCode: "findCollectionEntityById",
75
75
  },
76
76
  {
77
77
  code: "create",
78
- method: "post",
78
+ method: "POST",
79
79
  endpoint: "",
80
80
  handlerCode: "createCollectionEntity",
81
81
  },
82
82
  {
83
83
  code: "updateById",
84
- method: "patch",
84
+ method: "PATCH",
85
85
  endpoint: "/:id",
86
86
  handlerCode: "updateCollectionEntityById",
87
87
  },
88
88
  {
89
89
  code: "deleteById",
90
- method: "delete",
90
+ method: "DELETE",
91
91
  endpoint: "/:id",
92
92
  handlerCode: "deleteCollectionEntityById",
93
93
  },
@@ -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
+ }
package/src/server.ts CHANGED
@@ -223,7 +223,6 @@ export class RapidServer implements IRpdServer {
223
223
  const rapidRequest = new RapidRequest(request);
224
224
  await rapidRequest.parseBody();
225
225
  const routeContext = new RouteContext(rapidRequest);
226
- console.log('routeContext', routeContext)
227
226
  await this.#buildedRoutes(routeContext, next);
228
227
  return routeContext.response.getResponse();
229
228
  }
package/src/types.ts CHANGED
@@ -304,11 +304,11 @@ export interface RpdRoute {
304
304
  handlers: RpdHttpHandler[];
305
305
  }
306
306
 
307
- export type RpdHttpMethod = "get" | "post" | "put" | "delete" | "patch";
307
+ export type RpdHttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
308
308
 
309
309
  export interface RpdHttpHandler {
310
310
  code: string;
311
- config: any;
311
+ config?: any;
312
312
  }
313
313
 
314
314
  export interface IRpdDataAccessor<T = any> {
@@ -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
+ }
@@ -1,16 +1,30 @@
1
+ import { sign, verify, decode, Secret } from "jsonwebtoken";
2
+ import { encode as base64Encode } from "~/deno-std/encoding/base64";
3
+ import crypto from "crypto";
1
4
 
2
- export function getJWTKey() {
3
- return "";
5
+ export function createJwt(payload: Record<string, any>, secret: Secret) {
6
+ return sign(payload, secret, {
7
+ algorithm: 'HS512',
8
+ });
4
9
  }
5
10
 
6
- export async function createJWT(payload: Record<string, any>) {
7
- return "";
11
+ export function verifyJwt(token: string, secret: Secret) {
12
+ return verify(token, secret, {
13
+ algorithms: ['HS512'],
14
+ });
8
15
  }
9
16
 
10
- export async function verifyJWT(jwt: string) {
11
- return {};
17
+ export function decodeJwt(token: string) {
18
+ return decode(token, { complete: true});
12
19
  }
13
20
 
14
- export async function decodeJWT(jwt: string) {
15
- return { header: {}, payload: {}, signature: {} };
21
+ export async function generateJwtSecretKey() {
22
+ const key = await crypto.subtle.generateKey(
23
+ { name: "HMAC", hash: "SHA-512" },
24
+ true,
25
+ ["sign", "verify"],
26
+ );
27
+
28
+ const exportedKey = await crypto.subtle.exportKey("raw", key);
29
+ return base64Encode(exportedKey);
16
30
  }