arkos 1.1.12-test → 1.1.13-test

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 (133) hide show
  1. package/dist/cjs/app.js +1 -1
  2. package/dist/cjs/app.js.map +1 -1
  3. package/dist/cjs/modules/auth/auth.controller.js +53 -64
  4. package/dist/cjs/modules/auth/auth.controller.js.map +1 -1
  5. package/dist/cjs/modules/auth/auth.router.js +46 -58
  6. package/dist/cjs/modules/auth/auth.router.js.map +1 -1
  7. package/dist/cjs/modules/auth/auth.service.js +75 -97
  8. package/dist/cjs/modules/auth/auth.service.js.map +1 -1
  9. package/dist/cjs/modules/auth/utils/helpers/auth.controller.helpers.js +6 -7
  10. package/dist/cjs/modules/auth/utils/helpers/auth.controller.helpers.js.map +1 -1
  11. package/dist/cjs/modules/base/base.controller.js +30 -46
  12. package/dist/cjs/modules/base/base.controller.js.map +1 -1
  13. package/dist/cjs/modules/base/base.middlewares.js +17 -21
  14. package/dist/cjs/modules/base/base.middlewares.js.map +1 -1
  15. package/dist/cjs/modules/base/base.router.js +6 -17
  16. package/dist/cjs/modules/base/base.router.js.map +1 -1
  17. package/dist/cjs/modules/base/base.service.js +128 -116
  18. package/dist/cjs/modules/base/base.service.js.map +1 -1
  19. package/dist/cjs/modules/base/utils/helpers/base.controller.helpers.js +3 -5
  20. package/dist/cjs/modules/base/utils/helpers/base.controller.helpers.js.map +1 -1
  21. package/dist/cjs/modules/base/utils/helpers/base.router.helpers.js +36 -47
  22. package/dist/cjs/modules/base/utils/helpers/base.router.helpers.js.map +1 -1
  23. package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js +30 -40
  24. package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js.map +1 -1
  25. package/dist/cjs/modules/email/email.service.js +28 -39
  26. package/dist/cjs/modules/email/email.service.js.map +1 -1
  27. package/dist/cjs/modules/error-handler/error-handler.controller.js +6 -3
  28. package/dist/cjs/modules/error-handler/error-handler.controller.js.map +1 -1
  29. package/dist/cjs/modules/error-handler/utils/catch-async.js +3 -12
  30. package/dist/cjs/modules/error-handler/utils/catch-async.js.map +1 -1
  31. package/dist/cjs/modules/error-handler/utils/error-handler.helpers.js +17 -31
  32. package/dist/cjs/modules/error-handler/utils/error-handler.helpers.js.map +1 -1
  33. package/dist/cjs/modules/file-uploader/file-uploader.controller.js +18 -27
  34. package/dist/cjs/modules/file-uploader/file-uploader.controller.js.map +1 -1
  35. package/dist/cjs/modules/file-uploader/file-uploader.router.js +23 -34
  36. package/dist/cjs/modules/file-uploader/file-uploader.router.js.map +1 -1
  37. package/dist/cjs/modules/file-uploader/file-uploader.service.js +117 -131
  38. package/dist/cjs/modules/file-uploader/file-uploader.service.js.map +1 -1
  39. package/dist/cjs/modules/file-uploader/utils/helpers/file-uploader.helpers.js +15 -26
  40. package/dist/cjs/modules/file-uploader/utils/helpers/file-uploader.helpers.js.map +1 -1
  41. package/dist/cjs/server.js +1 -1
  42. package/dist/cjs/server.js.map +1 -1
  43. package/dist/cjs/utils/cli/build.js +9 -2
  44. package/dist/cjs/utils/cli/build.js.map +1 -1
  45. package/dist/cjs/utils/cli/dev.js +43 -48
  46. package/dist/cjs/utils/cli/dev.js.map +1 -1
  47. package/dist/cjs/utils/cli/start.js +35 -38
  48. package/dist/cjs/utils/cli/start.js.map +1 -1
  49. package/dist/cjs/utils/features/api.features.js +26 -33
  50. package/dist/cjs/utils/features/api.features.js.map +1 -1
  51. package/dist/cjs/utils/helpers/api.features.helpers.js +4 -6
  52. package/dist/cjs/utils/helpers/api.features.helpers.js.map +1 -1
  53. package/dist/cjs/utils/helpers/change-case.helpers.js +28 -36
  54. package/dist/cjs/utils/helpers/change-case.helpers.js.map +1 -1
  55. package/dist/cjs/utils/helpers/deepmerge.helper.js +4 -8
  56. package/dist/cjs/utils/helpers/deepmerge.helper.js.map +1 -1
  57. package/dist/cjs/utils/helpers/global.helpers.js +2 -13
  58. package/dist/cjs/utils/helpers/global.helpers.js.map +1 -1
  59. package/dist/cjs/utils/helpers/models.helpers.js +65 -80
  60. package/dist/cjs/utils/helpers/models.helpers.js.map +1 -1
  61. package/dist/cjs/utils/helpers/prisma.helpers.js +23 -34
  62. package/dist/cjs/utils/helpers/prisma.helpers.js.map +1 -1
  63. package/dist/cjs/utils/validate-dto.js +6 -17
  64. package/dist/cjs/utils/validate-dto.js.map +1 -1
  65. package/dist/cjs/utils/validate-schema.js +6 -17
  66. package/dist/cjs/utils/validate-schema.js.map +1 -1
  67. package/dist/es2020/app.js +1 -1
  68. package/dist/es2020/app.js.map +1 -1
  69. package/dist/es2020/modules/auth/auth.controller.js +53 -64
  70. package/dist/es2020/modules/auth/auth.controller.js.map +1 -1
  71. package/dist/es2020/modules/auth/auth.router.js +46 -58
  72. package/dist/es2020/modules/auth/auth.router.js.map +1 -1
  73. package/dist/es2020/modules/auth/auth.service.js +75 -97
  74. package/dist/es2020/modules/auth/auth.service.js.map +1 -1
  75. package/dist/es2020/modules/auth/utils/helpers/auth.controller.helpers.js +6 -7
  76. package/dist/es2020/modules/auth/utils/helpers/auth.controller.helpers.js.map +1 -1
  77. package/dist/es2020/modules/base/base.controller.js +30 -46
  78. package/dist/es2020/modules/base/base.controller.js.map +1 -1
  79. package/dist/es2020/modules/base/base.middlewares.js +17 -21
  80. package/dist/es2020/modules/base/base.middlewares.js.map +1 -1
  81. package/dist/es2020/modules/base/base.router.js +6 -17
  82. package/dist/es2020/modules/base/base.router.js.map +1 -1
  83. package/dist/es2020/modules/base/base.service.js +128 -116
  84. package/dist/es2020/modules/base/base.service.js.map +1 -1
  85. package/dist/es2020/modules/base/utils/helpers/base.controller.helpers.js +3 -5
  86. package/dist/es2020/modules/base/utils/helpers/base.controller.helpers.js.map +1 -1
  87. package/dist/es2020/modules/base/utils/helpers/base.router.helpers.js +36 -47
  88. package/dist/es2020/modules/base/utils/helpers/base.router.helpers.js.map +1 -1
  89. package/dist/es2020/modules/base/utils/helpers/base.service.helpers.js +30 -40
  90. package/dist/es2020/modules/base/utils/helpers/base.service.helpers.js.map +1 -1
  91. package/dist/es2020/modules/email/email.service.js +28 -39
  92. package/dist/es2020/modules/email/email.service.js.map +1 -1
  93. package/dist/es2020/modules/error-handler/error-handler.controller.js +6 -3
  94. package/dist/es2020/modules/error-handler/error-handler.controller.js.map +1 -1
  95. package/dist/es2020/modules/error-handler/utils/catch-async.js +3 -12
  96. package/dist/es2020/modules/error-handler/utils/catch-async.js.map +1 -1
  97. package/dist/es2020/modules/error-handler/utils/error-handler.helpers.js +17 -31
  98. package/dist/es2020/modules/error-handler/utils/error-handler.helpers.js.map +1 -1
  99. package/dist/es2020/modules/file-uploader/file-uploader.controller.js +18 -27
  100. package/dist/es2020/modules/file-uploader/file-uploader.controller.js.map +1 -1
  101. package/dist/es2020/modules/file-uploader/file-uploader.router.js +23 -34
  102. package/dist/es2020/modules/file-uploader/file-uploader.router.js.map +1 -1
  103. package/dist/es2020/modules/file-uploader/file-uploader.service.js +117 -131
  104. package/dist/es2020/modules/file-uploader/file-uploader.service.js.map +1 -1
  105. package/dist/es2020/modules/file-uploader/utils/helpers/file-uploader.helpers.js +15 -26
  106. package/dist/es2020/modules/file-uploader/utils/helpers/file-uploader.helpers.js.map +1 -1
  107. package/dist/es2020/server.js +1 -1
  108. package/dist/es2020/server.js.map +1 -1
  109. package/dist/es2020/utils/cli/build.js +9 -2
  110. package/dist/es2020/utils/cli/build.js.map +1 -1
  111. package/dist/es2020/utils/cli/dev.js +43 -48
  112. package/dist/es2020/utils/cli/dev.js.map +1 -1
  113. package/dist/es2020/utils/cli/start.js +35 -38
  114. package/dist/es2020/utils/cli/start.js.map +1 -1
  115. package/dist/es2020/utils/features/api.features.js +26 -33
  116. package/dist/es2020/utils/features/api.features.js.map +1 -1
  117. package/dist/es2020/utils/helpers/api.features.helpers.js +4 -6
  118. package/dist/es2020/utils/helpers/api.features.helpers.js.map +1 -1
  119. package/dist/es2020/utils/helpers/change-case.helpers.js +28 -36
  120. package/dist/es2020/utils/helpers/change-case.helpers.js.map +1 -1
  121. package/dist/es2020/utils/helpers/deepmerge.helper.js +4 -8
  122. package/dist/es2020/utils/helpers/deepmerge.helper.js.map +1 -1
  123. package/dist/es2020/utils/helpers/global.helpers.js +2 -13
  124. package/dist/es2020/utils/helpers/global.helpers.js.map +1 -1
  125. package/dist/es2020/utils/helpers/models.helpers.js +65 -80
  126. package/dist/es2020/utils/helpers/models.helpers.js.map +1 -1
  127. package/dist/es2020/utils/helpers/prisma.helpers.js +23 -34
  128. package/dist/es2020/utils/helpers/prisma.helpers.js.map +1 -1
  129. package/dist/es2020/utils/validate-dto.js +6 -17
  130. package/dist/es2020/utils/validate-dto.js.map +1 -1
  131. package/dist/es2020/utils/validate-schema.js +6 -17
  132. package/dist/es2020/utils/validate-schema.js.map +1 -1
  133. package/package.json +1 -1
@@ -1,15 +1,4 @@
1
1
  "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
12
- };
13
2
  Object.defineProperty(exports, "__esModule", { value: true });
14
3
  exports.removeApiAction = removeApiAction;
15
4
  exports.isPrismaRelationFormat = isPrismaRelationFormat;
@@ -52,10 +41,8 @@ function isPrismaRelationFormat(obj) {
52
41
  return prismaOperations.some((op) => op in obj);
53
42
  }
54
43
  function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
55
- var _a, _b;
56
- let mutableBody = Object.assign({}, body);
57
- (_a = relationFields === null || relationFields === void 0 ? void 0 : relationFields.list) === null || _a === void 0 ? void 0 : _a.forEach((field) => {
58
- var _a;
44
+ let mutableBody = { ...body };
45
+ relationFields?.list?.forEach((field) => {
59
46
  if (!body[field.name])
60
47
  return;
61
48
  if (isPrismaRelationFormat(body[field.name])) {
@@ -69,11 +56,10 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
69
56
  const updateData = [];
70
57
  const disconnectData = [];
71
58
  const deleteManyIds = [];
72
- (_a = body[field.name]) === null || _a === void 0 ? void 0 : _a.forEach((bodyField) => {
73
- var _a;
74
- if ((_a = ignoreActions === null || ignoreActions === void 0 ? void 0 : ignoreActions.includes) === null || _a === void 0 ? void 0 : _a.call(ignoreActions, bodyField === null || bodyField === void 0 ? void 0 : bodyField.apiAction))
59
+ body[field.name]?.forEach((bodyField) => {
60
+ if (ignoreActions?.includes?.(bodyField?.apiAction))
75
61
  return;
76
- const apiAction = bodyField === null || bodyField === void 0 ? void 0 : bodyField.apiAction;
62
+ const apiAction = bodyField?.apiAction;
77
63
  if (apiAction === "delete") {
78
64
  deleteManyIds.push(bodyField.id);
79
65
  }
@@ -81,23 +67,23 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
81
67
  disconnectData.push({ id: bodyField.id });
82
68
  }
83
69
  else if (canBeUsedToConnect(field.type, bodyField)) {
84
- const { apiAction: _ } = bodyField, cleanedData = __rest(bodyField, ["apiAction"]);
70
+ const { apiAction: _, ...cleanedData } = bodyField;
85
71
  connectData.push(cleanedData);
86
72
  }
87
- else if (!(bodyField === null || bodyField === void 0 ? void 0 : bodyField.id)) {
73
+ else if (!bodyField?.id) {
88
74
  let nestedRelations = (0, models_helpers_1.getPrismaModelRelations)(field.type);
89
- let dataToPush = Object.assign({}, bodyField);
75
+ let dataToPush = { ...bodyField };
90
76
  if (nestedRelations) {
91
77
  dataToPush = handleRelationFieldsInBody(dataToPush, nestedRelations, ignoreActions);
92
78
  }
93
79
  if ("apiAction" in dataToPush) {
94
- const { apiAction: _ } = dataToPush, rest = __rest(dataToPush, ["apiAction"]);
80
+ const { apiAction: _, ...rest } = dataToPush;
95
81
  dataToPush = rest;
96
82
  }
97
83
  createData.push(dataToPush);
98
84
  }
99
85
  else {
100
- const { id, apiAction: _ } = bodyField, data = __rest(bodyField, ["id", "apiAction"]);
86
+ const { id, apiAction: _, ...data } = bodyField;
101
87
  let nestedRelations = (0, models_helpers_1.getPrismaModelRelations)(field.type);
102
88
  let dataToPush = data;
103
89
  if (nestedRelations) {
@@ -109,15 +95,20 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
109
95
  });
110
96
  }
111
97
  });
112
- mutableBody[field.name] = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (createData.length ? { create: createData } : {})), (connectData.length ? { connect: connectData } : {})), (updateData.length ? { update: updateData } : {})), (disconnectData.length ? { disconnect: disconnectData } : {})), (deleteManyIds.length
113
- ? { deleteMany: { id: { in: deleteManyIds } } }
114
- : {}));
98
+ mutableBody[field.name] = {
99
+ ...(createData.length ? { create: createData } : {}),
100
+ ...(connectData.length ? { connect: connectData } : {}),
101
+ ...(updateData.length ? { update: updateData } : {}),
102
+ ...(disconnectData.length ? { disconnect: disconnectData } : {}),
103
+ ...(deleteManyIds.length
104
+ ? { deleteMany: { id: { in: deleteManyIds } } }
105
+ : {}),
106
+ };
115
107
  });
116
- (_b = relationFields === null || relationFields === void 0 ? void 0 : relationFields.singular) === null || _b === void 0 ? void 0 : _b.forEach((field) => {
117
- var _a, _b;
108
+ relationFields?.singular?.forEach((field) => {
118
109
  if (!body[field.name])
119
110
  return;
120
- if ((_a = ignoreActions === null || ignoreActions === void 0 ? void 0 : ignoreActions.includes) === null || _a === void 0 ? void 0 : _a.call(ignoreActions, (_b = body[field.name]) === null || _b === void 0 ? void 0 : _b.apiAction))
111
+ if (ignoreActions?.includes?.(body[field.name]?.apiAction))
121
112
  return;
122
113
  if (isPrismaRelationFormat(body[field.name])) {
123
114
  return;
@@ -125,13 +116,13 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
125
116
  const relationData = body[field.name];
126
117
  let nestedRelations = (0, models_helpers_1.getPrismaModelRelations)(field.type);
127
118
  if (canBeUsedToConnect(field.type, relationData)) {
128
- const { apiAction: _ } = relationData, cleanedData = __rest(relationData, ["apiAction"]);
119
+ const { apiAction: _, ...cleanedData } = relationData;
129
120
  mutableBody[field.name] = { connect: cleanedData };
130
121
  }
131
- else if (!(relationData === null || relationData === void 0 ? void 0 : relationData.id)) {
132
- let dataToCreate = Object.assign({}, relationData);
122
+ else if (!relationData?.id) {
123
+ let dataToCreate = { ...relationData };
133
124
  if ("apiAction" in dataToCreate) {
134
- const { apiAction: _ } = dataToCreate, rest = __rest(dataToCreate, ["apiAction"]);
125
+ const { apiAction: _, ...rest } = dataToCreate;
135
126
  dataToCreate = rest;
136
127
  }
137
128
  if (nestedRelations) {
@@ -140,7 +131,7 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
140
131
  mutableBody[field.name] = { create: dataToCreate };
141
132
  }
142
133
  else {
143
- const { id, apiAction: _ } = relationData, data = __rest(relationData, ["id", "apiAction"]);
134
+ const { id, apiAction: _, ...data } = relationData;
144
135
  let dataToUpdate = data;
145
136
  if (nestedRelations) {
146
137
  dataToUpdate = handleRelationFieldsInBody(data, nestedRelations, ignoreActions);
@@ -153,28 +144,27 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
153
144
  }
154
145
  });
155
146
  if ("apiAction" in mutableBody) {
156
- const { apiAction } = mutableBody, rest = __rest(mutableBody, ["apiAction"]);
147
+ const { apiAction, ...rest } = mutableBody;
157
148
  mutableBody = rest;
158
149
  }
159
150
  return removeApiAction(mutableBody);
160
151
  }
161
152
  function canBeUsedToConnect(modelName, bodyField) {
162
- var _a, _b, _c;
163
153
  if (!bodyField)
164
154
  return false;
165
- if (bodyField.apiAction && !((_b = (_a = ["connect"]) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, bodyField.apiAction))) {
155
+ if (bodyField.apiAction && !["connect"]?.includes?.(bodyField.apiAction)) {
166
156
  return false;
167
157
  }
168
158
  if (bodyField.apiAction === "connect") {
169
159
  return true;
170
160
  }
171
- if (((_c = Object.keys(bodyField)) === null || _c === void 0 ? void 0 : _c.length) === 1 && (bodyField === null || bodyField === void 0 ? void 0 : bodyField.id)) {
161
+ if (Object.keys(bodyField)?.length === 1 && bodyField?.id) {
172
162
  return true;
173
163
  }
174
164
  const uniqueFields = (0, models_helpers_1.getModelUniqueFields)(modelName);
175
165
  if (Object.keys(bodyField).length === 1) {
176
166
  const fieldName = Object.keys(bodyField)[0];
177
- return uniqueFields === null || uniqueFields === void 0 ? void 0 : uniqueFields.some((field) => field.name === fieldName);
167
+ return uniqueFields?.some((field) => field.name === fieldName);
178
168
  }
179
169
  return false;
180
170
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base.service.helpers.js","sourceRoot":"","sources":["../../../../../../src/modules/base/utils/helpers/base.service.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getPrismaModelRelations,\n RelationFields,\n getModelUniqueFields,\n} from \"../../../../utils/helpers/models.helpers\";\n\n/**\n * Removes apiAction field from an object and all nested objects\n *\n * @param {Record<string, any>} obj - The object to clean\n * @returns {Record<string, any>} - The cleaned object\n */\nexport function removeApiAction(obj: Record<string, any>): Record<string, any> {\n if (!obj || typeof obj !== \"object\") return obj;\n\n const result: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n if (key === \"apiAction\") continue;\n\n if (Array.isArray(value)) {\n result[key] = value.map((item) =>\n typeof item === \"object\" && item !== null ? removeApiAction(item) : item\n );\n } else if (typeof value === \"object\" && value !== null) {\n result[key] = removeApiAction(value);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Checks if an object is already formatted as a Prisma relation operation\n *\n * @param {Record<string, any>} obj - The object to check\n * @returns {boolean} - True if the object contains Prisma relation operations\n */\nexport function isPrismaRelationFormat(obj: Record<string, any>): boolean {\n if (!obj || typeof obj !== \"object\") return false;\n\n // Common Prisma relation operations\n const prismaOperations = [\n \"create\",\n \"connect\",\n \"update\",\n \"delete\",\n \"disconnect\",\n \"deleteMany\",\n \"connectOrCreate\",\n \"upsert\",\n \"set\",\n ];\n\n // Check if any key is a Prisma operation\n return prismaOperations.some((op) => op in obj);\n}\n\n/**\n * Determines the appropriate Prisma operation (`create`, `connect`, `update`, `delete`, or `disconnect`)\n * for each relation field in the provided body based on its nested data and recursively does the same for each relation field.\n *\n * This function handles the following types of relations:\n * - **One-to-one**\n * - **One-to-many**\n *\n *\n * ### Operation Rules:\n *\n *\n * - **Create**: Used when the nested relation data is provided **without an `id` or unique field**.\n * - **Connect**: Used when the nested relation data contains **only an `id` or a unique field** (e.g., email).\n * - **Update**: Used when the nested relation data contains **both an `id` and additional fields**.\n * - **Delete**: Used when the nested relation data includes **`apiAction: \"delete\"`**.\n * - **Disconnect**: Used when the nested relation data includes **`apiAction: \"disconnect\"`**.\n *\n * The function will preserve existing Prisma operation formats if detected,\n * allowing developers to manually structure relation operations when needed.\n *\n * @param {Record<string, any>} body - The object containing relation fields to be processed.\n * @param {Object} relationFields - Defines relation field types.\n * @param {RelationFields[]} relationFields.singular - List of one-side relation field names (one-to-one).\n * @param {RelationFields[]} relationFields.list - List of many-side relation field names (one-to-many).\n * @param {string[]} ignoreActions - Optional list of apiAction values to ignore.\n * @returns {Record<string, any>} The transformed data with appropriate Prisma operations applied.\n */\nexport function handleRelationFieldsInBody(\n body: Record<string, any>,\n relationFields: RelationFields,\n ignoreActions: string[] = []\n) {\n let mutableBody = { ...body };\n\n relationFields?.list?.forEach((field) => {\n if (!body[field.name]) return;\n\n // Skip if the field is already in Prisma relation format\n if (isPrismaRelationFormat(body[field.name])) {\n return;\n }\n\n // Skip if the field is not an array (likely already handled manually)\n if (!Array.isArray(body[field.name])) {\n return;\n }\n\n const createData: any[] = [];\n const connectData: any[] = [];\n const updateData: any[] = [];\n const disconnectData: any[] = [];\n const deleteManyIds: any[] = [];\n\n body[field.name]?.forEach((bodyField: any) => {\n if (ignoreActions?.includes?.(bodyField?.apiAction)) return;\n\n const apiAction = bodyField?.apiAction;\n\n if (apiAction === \"delete\") {\n deleteManyIds.push(bodyField.id);\n } else if (apiAction === \"disconnect\") {\n disconnectData.push({ id: bodyField.id });\n } else if (canBeUsedToConnect(field.type, bodyField)) {\n // Handle connection with unique fields or ID\n const { apiAction: _, ...cleanedData } = bodyField;\n connectData.push(cleanedData);\n } else if (!bodyField?.id) {\n // If no ID, assume create operation\n let nestedRelations = getPrismaModelRelations(field.type);\n\n let dataToPush = { ...bodyField };\n\n if (nestedRelations) {\n dataToPush = handleRelationFieldsInBody(\n dataToPush,\n nestedRelations,\n ignoreActions\n );\n }\n\n // Ensure apiAction is removed\n if (\"apiAction\" in dataToPush) {\n const { apiAction: _, ...rest } = dataToPush;\n dataToPush = rest;\n }\n\n createData.push(dataToPush);\n } else {\n // If ID and other fields, assume update operation\n const { id, apiAction: _, ...data } = bodyField;\n\n let nestedRelations = getPrismaModelRelations(field.type);\n\n let dataToPush = data;\n if (nestedRelations) {\n dataToPush = handleRelationFieldsInBody(\n data,\n nestedRelations,\n ignoreActions\n );\n }\n\n updateData.push({\n where: { id },\n data: dataToPush,\n });\n }\n });\n\n mutableBody[field.name] = {\n ...(createData.length ? { create: createData } : {}),\n ...(connectData.length ? { connect: connectData } : {}),\n ...(updateData.length ? { update: updateData } : {}),\n ...(disconnectData.length ? { disconnect: disconnectData } : {}),\n ...(deleteManyIds.length\n ? { deleteMany: { id: { in: deleteManyIds } } }\n : {}),\n };\n });\n\n relationFields?.singular?.forEach((field) => {\n if (!body[field.name]) return;\n if (ignoreActions?.includes?.(body[field.name]?.apiAction)) return;\n\n // Skip if the field is already in Prisma relation format\n if (isPrismaRelationFormat(body[field.name])) {\n return;\n }\n\n const relationData = body[field.name];\n let nestedRelations = getPrismaModelRelations(field.type);\n\n if (canBeUsedToConnect(field.type, relationData)) {\n // Handle connection with unique fields or ID\n const { apiAction: _, ...cleanedData } = relationData;\n mutableBody[field.name] = { connect: cleanedData };\n } else if (!relationData?.id) {\n // If no ID, assume create operation\n let dataToCreate = { ...relationData };\n\n if (\"apiAction\" in dataToCreate) {\n const { apiAction: _, ...rest } = dataToCreate;\n dataToCreate = rest;\n }\n\n if (nestedRelations) {\n dataToCreate = handleRelationFieldsInBody(\n dataToCreate,\n nestedRelations,\n ignoreActions\n );\n }\n\n mutableBody[field.name] = { create: dataToCreate };\n } else {\n // If ID and other fields, assume update operation\n const { id, apiAction: _, ...data } = relationData;\n\n let dataToUpdate = data;\n if (nestedRelations) {\n dataToUpdate = handleRelationFieldsInBody(\n data,\n nestedRelations,\n ignoreActions\n );\n }\n\n mutableBody[field.name] = {\n update: {\n data: dataToUpdate,\n },\n };\n }\n });\n\n // Remove any remaining apiAction fields from the top level\n if (\"apiAction\" in mutableBody) {\n const { apiAction, ...rest } = mutableBody;\n mutableBody = rest;\n }\n\n // As a final step, recursively remove any remaining apiAction fields\n return removeApiAction(mutableBody);\n}\n\n/**\n * Checks if a field value can be used to connect to a model\n * This happens when the field contains only an ID or a single unique field\n *\n * @param {string} modelName - The model name to get unique fields for\n * @param {Record<string, any>} bodyField - The field value from the body\n * @returns {boolean} True if the field can be used for a connect operation\n */\nexport function canBeUsedToConnect(\n modelName: string,\n bodyField: Record<string, any> | undefined | null\n): boolean {\n // If the field is null or undefined, it can't be used to connect\n if (!bodyField) return false;\n\n // If the field has an apiAction that's not for connecting, return false\n if (bodyField.apiAction && ![\"connect\"]?.includes?.(bodyField.apiAction)) {\n return false;\n }\n\n // If explicitly marked for connect, allow it\n if (bodyField.apiAction === \"connect\") {\n return true;\n }\n\n // If only ID is present, it can be used to connect\n if (Object.keys(bodyField)?.length === 1 && bodyField?.id) {\n return true;\n }\n\n // Get unique fields for the model\n const uniqueFields = getModelUniqueFields(modelName);\n\n // If the field has exactly one property and it's a unique field, it can be used to connect\n if (Object.keys(bodyField).length === 1) {\n const fieldName = Object.keys(bodyField)[0];\n return uniqueFields?.some((field) => field.name === fieldName);\n }\n\n return false;\n}\n\n// /**\n// * Checks if a list field is actually an array\n// *\n// * @param {any} field - The field to check\n// * @returns {boolean} - True if the field is an array\n// */\n// export function isListFieldAnArray(field: any): boolean {\n// return Array.isArray(field);\n// }\n"]}
1
+ {"version":3,"file":"base.service.helpers.js","sourceRoot":"","sources":["../../../../../../src/modules/base/utils/helpers/base.service.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getPrismaModelRelations,\n RelationFields,\n getModelUniqueFields,\n} from \"../../../../utils/helpers/models.helpers\";\n\n/**\n * Removes apiAction field from an object and all nested objects\n *\n * @param {Record<string, any>} obj - The object to clean\n * @returns {Record<string, any>} - The cleaned object\n */\nexport function removeApiAction(obj: Record<string, any>): Record<string, any> {\n if (!obj || typeof obj !== \"object\") return obj;\n\n const result: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n if (key === \"apiAction\") continue;\n\n if (Array.isArray(value)) {\n result[key] = value.map((item) =>\n typeof item === \"object\" && item !== null ? removeApiAction(item) : item\n );\n } else if (typeof value === \"object\" && value !== null) {\n result[key] = removeApiAction(value);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Checks if an object is already formatted as a Prisma relation operation\n *\n * @param {Record<string, any>} obj - The object to check\n * @returns {boolean} - True if the object contains Prisma relation operations\n */\nexport function isPrismaRelationFormat(obj: Record<string, any>): boolean {\n if (!obj || typeof obj !== \"object\") return false;\n\n // Common Prisma relation operations\n const prismaOperations = [\n \"create\",\n \"connect\",\n \"update\",\n \"delete\",\n \"disconnect\",\n \"deleteMany\",\n \"connectOrCreate\",\n \"upsert\",\n \"set\",\n ];\n\n // Check if any key is a Prisma operation\n return prismaOperations.some((op) => op in obj);\n}\n\n/**\n * Determines the appropriate Prisma operation (`create`, `connect`, `update`, `delete`, or `disconnect`)\n * for each relation field in the provided body based on its nested data and recursively does the same for each relation field.\n *\n * This function handles the following types of relations:\n * - **One-to-one**\n * - **One-to-many**\n *\n *\n * ### Operation Rules:\n *\n *\n * - **Create**: Used when the nested relation data is provided **without an `id` or unique field**.\n * - **Connect**: Used when the nested relation data contains **only an `id` or a unique field** (e.g., email).\n * - **Update**: Used when the nested relation data contains **both an `id` and additional fields**.\n * - **Delete**: Used when the nested relation data includes **`apiAction: \"delete\"`**.\n * - **Disconnect**: Used when the nested relation data includes **`apiAction: \"disconnect\"`**.\n *\n * The function will preserve existing Prisma operation formats if detected,\n * allowing developers to manually structure relation operations when needed.\n *\n * @param {Record<string, any>} body - The object containing relation fields to be processed.\n * @param {Object} relationFields - Defines relation field types.\n * @param {RelationFields[]} relationFields.singular - List of one-side relation field names (one-to-one).\n * @param {RelationFields[]} relationFields.list - List of many-side relation field names (one-to-many).\n * @param {string[]} ignoreActions - Optional list of apiAction values to ignore.\n * @returns {Record<string, any>} The transformed data with appropriate Prisma operations applied.\n */\nexport function handleRelationFieldsInBody(\n body: Record<string, any>,\n relationFields: RelationFields,\n ignoreActions: string[] = []\n) {\n let mutableBody = { ...body };\n\n relationFields?.list?.forEach((field) => {\n if (!body[field.name]) return;\n\n // Skip if the field is already in Prisma relation format\n if (isPrismaRelationFormat(body[field.name])) {\n return;\n }\n\n // Skip if the field is not an array (likely already handled manually)\n if (!Array.isArray(body[field.name])) {\n return;\n }\n\n const createData: any[] = [];\n const connectData: any[] = [];\n const updateData: any[] = [];\n const disconnectData: any[] = [];\n const deleteManyIds: any[] = [];\n\n body[field.name]?.forEach((bodyField: any) => {\n if (ignoreActions?.includes?.(bodyField?.apiAction)) return;\n\n const apiAction = bodyField?.apiAction;\n\n if (apiAction === \"delete\") {\n deleteManyIds.push(bodyField.id);\n } else if (apiAction === \"disconnect\") {\n disconnectData.push({ id: bodyField.id });\n } else if (canBeUsedToConnect(field.type, bodyField)) {\n // Handle connection with unique fields or ID\n const { apiAction: _, ...cleanedData } = bodyField;\n connectData.push(cleanedData);\n } else if (!bodyField?.id) {\n // If no ID, assume create operation\n let nestedRelations = getPrismaModelRelations(field.type);\n\n let dataToPush = { ...bodyField };\n\n if (nestedRelations) {\n dataToPush = handleRelationFieldsInBody(\n dataToPush,\n nestedRelations,\n ignoreActions\n );\n }\n\n // Ensure apiAction is removed\n if (\"apiAction\" in dataToPush) {\n const { apiAction: _, ...rest } = dataToPush;\n dataToPush = rest;\n }\n\n createData.push(dataToPush);\n } else {\n // If ID and other fields, assume update operation\n const { id, apiAction: _, ...data } = bodyField;\n\n let nestedRelations = getPrismaModelRelations(field.type);\n\n let dataToPush = data;\n if (nestedRelations) {\n dataToPush = handleRelationFieldsInBody(\n data,\n nestedRelations,\n ignoreActions\n );\n }\n\n updateData.push({\n where: { id },\n data: dataToPush,\n });\n }\n });\n\n mutableBody[field.name] = {\n ...(createData.length ? { create: createData } : {}),\n ...(connectData.length ? { connect: connectData } : {}),\n ...(updateData.length ? { update: updateData } : {}),\n ...(disconnectData.length ? { disconnect: disconnectData } : {}),\n ...(deleteManyIds.length\n ? { deleteMany: { id: { in: deleteManyIds } } }\n : {}),\n };\n });\n\n relationFields?.singular?.forEach((field) => {\n if (!body[field.name]) return;\n if (ignoreActions?.includes?.(body[field.name]?.apiAction)) return;\n\n // Skip if the field is already in Prisma relation format\n if (isPrismaRelationFormat(body[field.name])) {\n return;\n }\n\n const relationData = body[field.name];\n let nestedRelations = getPrismaModelRelations(field.type);\n\n if (canBeUsedToConnect(field.type, relationData)) {\n // Handle connection with unique fields or ID\n const { apiAction: _, ...cleanedData } = relationData;\n mutableBody[field.name] = { connect: cleanedData };\n } else if (!relationData?.id) {\n // If no ID, assume create operation\n let dataToCreate = { ...relationData };\n\n if (\"apiAction\" in dataToCreate) {\n const { apiAction: _, ...rest } = dataToCreate;\n dataToCreate = rest;\n }\n\n if (nestedRelations) {\n dataToCreate = handleRelationFieldsInBody(\n dataToCreate,\n nestedRelations,\n ignoreActions\n );\n }\n\n mutableBody[field.name] = { create: dataToCreate };\n } else {\n // If ID and other fields, assume update operation\n const { id, apiAction: _, ...data } = relationData;\n\n let dataToUpdate = data;\n if (nestedRelations) {\n dataToUpdate = handleRelationFieldsInBody(\n data,\n nestedRelations,\n ignoreActions\n );\n }\n\n mutableBody[field.name] = {\n update: {\n data: dataToUpdate,\n },\n };\n }\n });\n\n // Remove any remaining apiAction fields from the top level\n if (\"apiAction\" in mutableBody) {\n const { apiAction, ...rest } = mutableBody;\n mutableBody = rest;\n }\n\n // As a final step, recursively remove any remaining apiAction fields\n return removeApiAction(mutableBody);\n}\n\n/**\n * Checks if a field value can be used to connect to a model\n * This happens when the field contains only an ID or a single unique field\n *\n * @param {string} modelName - The model name to get unique fields for\n * @param {Record<string, any>} bodyField - The field value from the body\n * @returns {boolean} True if the field can be used for a connect operation\n */\nexport function canBeUsedToConnect(\n modelName: string,\n bodyField: Record<string, any> | undefined | null\n): boolean {\n // If the field is null or undefined, it can't be used to connect\n if (!bodyField) return false;\n\n // If the field has an apiAction that's not for connecting, return false\n if (bodyField.apiAction && ![\"connect\"]?.includes?.(bodyField.apiAction)) {\n return false;\n }\n\n // If explicitly marked for connect, allow it\n if (bodyField.apiAction === \"connect\") {\n return true;\n }\n\n // If only ID is present, it can be used to connect\n if (Object.keys(bodyField)?.length === 1 && bodyField?.id) {\n return true;\n }\n\n // Get unique fields for the model\n const uniqueFields = getModelUniqueFields(modelName);\n\n // If the field has exactly one property and it's a unique field, it can be used to connect\n if (Object.keys(bodyField).length === 1) {\n const fieldName = Object.keys(bodyField)[0];\n return uniqueFields?.some((field) => field.name === fieldName);\n }\n\n return false;\n}\n\n// /**\n// * Checks if a list field is actually an array\n// *\n// * @param {any} field - The field to check\n// * @returns {boolean} - True if the field is an array\n// */\n// export function isListFieldAnArray(field: any): boolean {\n// return Array.isArray(field);\n// }\n"]}
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -26,7 +17,6 @@ class EmailService {
26
17
  }
27
18
  }
28
19
  getEmailConfig() {
29
- var _a, _b;
30
20
  if (this.customConfig) {
31
21
  return this.customConfig;
32
22
  }
@@ -41,8 +31,8 @@ class EmailService {
41
31
  port: emailConfigs.port || 465,
42
32
  secure: emailConfigs.secure !== undefined ? emailConfigs.secure : true,
43
33
  auth: {
44
- user: (_a = emailConfigs.auth) === null || _a === void 0 ? void 0 : _a.user,
45
- pass: (_b = emailConfigs.auth) === null || _b === void 0 ? void 0 : _b.pass,
34
+ user: emailConfigs.auth?.user,
35
+ pass: emailConfigs.auth?.pass,
46
36
  },
47
37
  name: emailConfigs.name,
48
38
  };
@@ -70,36 +60,35 @@ class EmailService {
70
60
  }
71
61
  return this.transporter;
72
62
  }
73
- send(options_1, connectionOptions_1) {
74
- return __awaiter(this, arguments, void 0, function* (options, connectionOptions, skipVerification = false) {
75
- var _a, _b;
76
- const config = this.getEmailConfig();
77
- const transporter = connectionOptions
78
- ? this.getTransporter(connectionOptions)
79
- : this.getTransporter();
80
- const fromAddress = options.from || ((_a = connectionOptions === null || connectionOptions === void 0 ? void 0 : connectionOptions.auth) === null || _a === void 0 ? void 0 : _a.user) || ((_b = config.auth) === null || _b === void 0 ? void 0 : _b.user);
81
- if (connectionOptions || !skipVerification) {
82
- const isConnected = yield this.verifyConnection(transporter);
83
- if (!isConnected) {
84
- throw new Error("Failed to connect to email server");
85
- }
63
+ async send(options, connectionOptions, skipVerification = false) {
64
+ const config = this.getEmailConfig();
65
+ const transporter = connectionOptions
66
+ ? this.getTransporter(connectionOptions)
67
+ : this.getTransporter();
68
+ const fromAddress = options.from || connectionOptions?.auth?.user || config.auth?.user;
69
+ if (connectionOptions || !skipVerification) {
70
+ const isConnected = await this.verifyConnection(transporter);
71
+ if (!isConnected) {
72
+ throw new Error("Failed to connect to email server");
86
73
  }
87
- const info = yield transporter.sendMail(Object.assign(Object.assign({}, options), { from: fromAddress, text: (options === null || options === void 0 ? void 0 : options.text) || (0, html_to_text_1.convert)(options.html) }));
88
- return { success: true, messageId: info.messageId };
74
+ }
75
+ const info = await transporter.sendMail({
76
+ ...options,
77
+ from: fromAddress,
78
+ text: options?.text || (0, html_to_text_1.convert)(options.html),
89
79
  });
80
+ return { success: true, messageId: info.messageId };
90
81
  }
91
- verifyConnection(transporterToVerify) {
92
- return __awaiter(this, void 0, void 0, function* () {
93
- try {
94
- const transporter = transporterToVerify || this.getTransporter();
95
- yield transporter.verify();
96
- return true;
97
- }
98
- catch (error) {
99
- console.error("Email Server Connection Failed", error);
100
- return false;
101
- }
102
- });
82
+ async verifyConnection(transporterToVerify) {
83
+ try {
84
+ const transporter = transporterToVerify || this.getTransporter();
85
+ await transporter.verify();
86
+ return true;
87
+ }
88
+ catch (error) {
89
+ console.error("Email Server Connection Failed", error);
90
+ return false;
91
+ }
103
92
  }
104
93
  updateConfig(config) {
105
94
  this.customConfig = config;
@@ -1 +1 @@
1
- {"version":3,"file":"email.service.js","sourceRoot":"","sources":["../../../../src/modules/email/email.service.ts"],"names":[],"mappings":"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","sourcesContent":["import nodemailer, { Transporter } from \"nodemailer\";\nimport { convert } from \"html-to-text\";\nimport { getArkosConfig } from \"../../server\";\nimport AppError from \"../error-handler/utils/app-error\";\n\n/**\n * Defines the options for sending an email.\n */\nexport type EmailOptions = {\n from?: string; // Sender's email address (optional).\n to: string | string[]; // Recipient's email address or an array of email addresses.\n subject: string; // Subject of the email.\n text?: string; // Plain text body of the email (optional).\n html: string; // HTML body of the email.\n};\n\n/**\n * Defines the authentication options for SMTP.\n */\nexport type SMTPAuthOptions = {\n user: string;\n pass: string;\n};\n\n/**\n * Defines the connection options for SMTP server.\n */\nexport type SMTPConnectionOptions = {\n host?: string;\n port?: number;\n secure?: boolean;\n auth?: SMTPAuthOptions;\n name?: string;\n};\n\n/**\n * A service class to handle email-related tasks, including sending emails.\n *\n * See the api reference [www.arkosjs.com/docs/api-reference/the-email-service-class](https://www.arkosjs.com/docs/api-reference/the-email-service-class)\n */\nexport class EmailService {\n private transporter: Transporter | null = null;\n private customConfig: SMTPConnectionOptions | null = null;\n\n /**\n * Creates an instance of the EmailService class.\n *\n * @param {SMTPConnectionOptions} [config] - Optional custom SMTP configuration.\n * If provided, these settings will be used instead of the Arkos config.\n */\n constructor(config?: SMTPConnectionOptions) {\n if (config) {\n this.customConfig = config;\n }\n }\n\n /**\n * Gets the email configuration, either from constructor-provided config or ArkosConfig\n * @returns Configuration object with host, port, and auth details\n * @throws AppError if email configuration is not set\n */\n private getEmailConfig(): SMTPConnectionOptions {\n // If custom config was provided through constructor, use it\n if (this.customConfig) {\n return this.customConfig;\n }\n\n // Otherwise, get from Arkos config\n const { email: emailConfigs } = getArkosConfig();\n\n if (!emailConfigs) {\n throw new AppError(\n \"You are trying to use emailService without setting arkosConfig.email configurations\",\n 500,\n {\n docs: \"Read more about emailService at https://www.arkosjs.com/docs/core-concepts/sending-emails\",\n }\n );\n }\n\n return {\n host: emailConfigs.host,\n port: emailConfigs.port || 465,\n secure: emailConfigs.secure !== undefined ? emailConfigs.secure : true,\n auth: {\n user: emailConfigs.auth?.user,\n pass: emailConfigs.auth?.pass,\n },\n name: emailConfigs.name,\n };\n }\n\n /**\n * Gets or creates a transporter using provided config or default config\n * @param customConfig Optional override connection settings\n * @returns A configured nodemailer transporter\n */\n private getTransporter(customConfig?: SMTPConnectionOptions): Transporter {\n if (customConfig) {\n // Create temporary transporter with custom settings\n const defaultConfig = this.getEmailConfig();\n return nodemailer.createTransport({\n host: customConfig.host || defaultConfig.host,\n port: customConfig.port || defaultConfig.port,\n secure:\n customConfig.secure !== undefined\n ? customConfig.secure\n : defaultConfig.secure,\n auth: customConfig.auth || defaultConfig.auth,\n });\n }\n\n // Use cached transporter or create new one with default settings\n if (!this.transporter) {\n const config = this.getEmailConfig();\n this.transporter = nodemailer.createTransport({\n host: config.host,\n port: config.port,\n secure: config.secure,\n auth: config.auth,\n });\n }\n\n return this.transporter;\n }\n\n /**\n * Sends an email with the provided options.\n * Can use either the default configuration or custom connection options.\n *\n * @param {EmailOptions} options - The options for the email to be sent.\n * @param {SMTPConnectionOptions} [connectionOptions] - Optional custom connection settings.\n * @param {boolean} [skipVerification=false] - Whether to skip connection verification.\n * @returns {Promise<{ success: boolean; messageId?: string }>} Result with message ID on success.\n */\n public async send(\n options: EmailOptions,\n connectionOptions?: SMTPConnectionOptions,\n skipVerification = false\n ): Promise<{ success: boolean; messageId?: string }> {\n const config = this.getEmailConfig();\n const transporter = connectionOptions\n ? this.getTransporter(connectionOptions)\n : this.getTransporter();\n\n // Determine from address with proper fallbacks\n const fromAddress =\n options.from || connectionOptions?.auth?.user || config.auth?.user;\n\n // Optionally verify connection\n if (connectionOptions || !skipVerification) {\n const isConnected = await this.verifyConnection(transporter);\n\n if (!isConnected) {\n throw new Error(\"Failed to connect to email server\");\n }\n }\n\n // Send the email\n const info = await transporter.sendMail({\n ...options,\n from: fromAddress,\n text: options?.text || convert(options.html),\n });\n\n return { success: true, messageId: info.messageId };\n }\n\n /**\n * Verifies the connection to the email server.\n * @param {Transporter} [transporterToVerify] - Optional transporter to verify.\n * @returns {Promise<boolean>} A promise that resolves to true if connection is valid.\n */\n public async verifyConnection(\n transporterToVerify?: Transporter\n ): Promise<boolean> {\n try {\n const transporter = transporterToVerify || this.getTransporter();\n await transporter.verify();\n return true;\n } catch (error) {\n console.error(\"Email Server Connection Failed\", error);\n return false;\n }\n }\n\n /**\n * Updates the custom configuration for this email service instance.\n * @param {SMTPConnectionOptions} config - The new connection options.\n */\n public updateConfig(config: SMTPConnectionOptions): void {\n this.customConfig = config;\n this.transporter = null; // Reset transporter so it will be recreated with new config\n }\n\n /**\n * Creates a new instance of EmailService with custom configuration.\n * @param {SMTPConnectionOptions} config - The connection options for the new instance.\n * @returns {EmailService} A new EmailService instance.\n */\n public static create(config: SMTPConnectionOptions): EmailService {\n return new EmailService(config);\n }\n}\n\n// Create default instance\nconst emailService = new EmailService();\nexport default emailService;\n"]}
1
+ {"version":3,"file":"email.service.js","sourceRoot":"","sources":["../../../../src/modules/email/email.service.ts"],"names":[],"mappings":"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","sourcesContent":["import nodemailer, { Transporter } from \"nodemailer\";\nimport { convert } from \"html-to-text\";\nimport { getArkosConfig } from \"../../server\";\nimport AppError from \"../error-handler/utils/app-error\";\n\n/**\n * Defines the options for sending an email.\n */\nexport type EmailOptions = {\n from?: string; // Sender's email address (optional).\n to: string | string[]; // Recipient's email address or an array of email addresses.\n subject: string; // Subject of the email.\n text?: string; // Plain text body of the email (optional).\n html: string; // HTML body of the email.\n};\n\n/**\n * Defines the authentication options for SMTP.\n */\nexport type SMTPAuthOptions = {\n user: string;\n pass: string;\n};\n\n/**\n * Defines the connection options for SMTP server.\n */\nexport type SMTPConnectionOptions = {\n host?: string;\n port?: number;\n secure?: boolean;\n auth?: SMTPAuthOptions;\n name?: string;\n};\n\n/**\n * A service class to handle email-related tasks, including sending emails.\n *\n * See the api reference [www.arkosjs.com/docs/api-reference/the-email-service-class](https://www.arkosjs.com/docs/api-reference/the-email-service-class)\n */\nexport class EmailService {\n private transporter: Transporter | null = null;\n private customConfig: SMTPConnectionOptions | null = null;\n\n /**\n * Creates an instance of the EmailService class.\n *\n * @param {SMTPConnectionOptions} [config] - Optional custom SMTP configuration.\n * If provided, these settings will be used instead of the Arkos config.\n */\n constructor(config?: SMTPConnectionOptions) {\n if (config) {\n this.customConfig = config;\n }\n }\n\n /**\n * Gets the email configuration, either from constructor-provided config or ArkosConfig\n * @returns Configuration object with host, port, and auth details\n * @throws AppError if email configuration is not set\n */\n private getEmailConfig(): SMTPConnectionOptions {\n // If custom config was provided through constructor, use it\n if (this.customConfig) {\n return this.customConfig;\n }\n\n // Otherwise, get from Arkos config\n const { email: emailConfigs } = getArkosConfig();\n\n if (!emailConfigs) {\n throw new AppError(\n \"You are trying to use emailService without setting arkosConfig.email configurations\",\n 500,\n {\n docs: \"Read more about emailService at https://www.arkosjs.com/docs/core-concepts/sending-emails\",\n }\n );\n }\n\n return {\n host: emailConfigs.host,\n port: emailConfigs.port || 465,\n secure: emailConfigs.secure !== undefined ? emailConfigs.secure : true,\n auth: {\n user: emailConfigs.auth?.user,\n pass: emailConfigs.auth?.pass,\n },\n name: emailConfigs.name,\n };\n }\n\n /**\n * Gets or creates a transporter using provided config or default config\n * @param customConfig Optional override connection settings\n * @returns A configured nodemailer transporter\n */\n private getTransporter(customConfig?: SMTPConnectionOptions): Transporter {\n if (customConfig) {\n // Create temporary transporter with custom settings\n const defaultConfig = this.getEmailConfig();\n return nodemailer.createTransport({\n host: customConfig.host || defaultConfig.host,\n port: customConfig.port || defaultConfig.port,\n secure:\n customConfig.secure !== undefined\n ? customConfig.secure\n : defaultConfig.secure,\n auth: customConfig.auth || defaultConfig.auth,\n });\n }\n\n // Use cached transporter or create new one with default settings\n if (!this.transporter) {\n const config = this.getEmailConfig();\n this.transporter = nodemailer.createTransport({\n host: config.host,\n port: config.port,\n secure: config.secure,\n auth: config.auth,\n });\n }\n\n return this.transporter;\n }\n\n /**\n * Sends an email with the provided options.\n * Can use either the default configuration or custom connection options.\n *\n * @param {EmailOptions} options - The options for the email to be sent.\n * @param {SMTPConnectionOptions} [connectionOptions] - Optional custom connection settings.\n * @param {boolean} [skipVerification=false] - Whether to skip connection verification.\n * @returns {Promise<{ success: boolean; messageId?: string }>} Result with message ID on success.\n */\n public async send(\n options: EmailOptions,\n connectionOptions?: SMTPConnectionOptions,\n skipVerification = false\n ): Promise<{ success: boolean; messageId?: string }> {\n const config = this.getEmailConfig();\n const transporter = connectionOptions\n ? this.getTransporter(connectionOptions)\n : this.getTransporter();\n\n // Determine from address with proper fallbacks\n const fromAddress =\n options.from || connectionOptions?.auth?.user || config.auth?.user;\n\n // Optionally verify connection\n if (connectionOptions || !skipVerification) {\n const isConnected = await this.verifyConnection(transporter);\n\n if (!isConnected) {\n throw new Error(\"Failed to connect to email server\");\n }\n }\n\n // Send the email\n const info = await transporter.sendMail({\n ...options,\n from: fromAddress,\n text: options?.text || convert(options.html),\n });\n\n return { success: true, messageId: info.messageId };\n }\n\n /**\n * Verifies the connection to the email server.\n * @param {Transporter} [transporterToVerify] - Optional transporter to verify.\n * @returns {Promise<boolean>} A promise that resolves to true if connection is valid.\n */\n public async verifyConnection(\n transporterToVerify?: Transporter\n ): Promise<boolean> {\n try {\n const transporter = transporterToVerify || this.getTransporter();\n await transporter.verify();\n return true;\n } catch (error) {\n console.error(\"Email Server Connection Failed\", error);\n return false;\n }\n }\n\n /**\n * Updates the custom configuration for this email service instance.\n * @param {SMTPConnectionOptions} config - The new connection options.\n */\n public updateConfig(config: SMTPConnectionOptions): void {\n this.customConfig = config;\n this.transporter = null; // Reset transporter so it will be recreated with new config\n }\n\n /**\n * Creates a new instance of EmailService with custom configuration.\n * @param {SMTPConnectionOptions} config - The connection options for the new instance.\n * @returns {EmailService} A new EmailService instance.\n */\n public static create(config: SMTPConnectionOptions): EmailService {\n return new EmailService(config);\n }\n}\n\n// Create default instance\nconst emailService = new EmailService();\nexport default emailService;\n"]}
@@ -48,7 +48,7 @@ function errorHandler(err, req, res, next) {
48
48
  sendDevelopmentError(err, req, res);
49
49
  return;
50
50
  }
51
- let error = Object.assign(Object.assign({}, err), { message: err.message });
51
+ let error = { ...err, message: err.message };
52
52
  if (err.name === "JsonWebTokenError")
53
53
  error = errorControllerHelper.handleJWTError();
54
54
  if (err.name === "TokenExpiredError")
@@ -88,9 +88,12 @@ function errorHandler(err, req, res, next) {
88
88
  sendProductionError(error, req, res);
89
89
  }
90
90
  function sendDevelopmentError(err, req, res) {
91
- var _a;
92
91
  if (req.originalUrl.startsWith("/api"))
93
- res.status(err.statusCode).json(Object.assign(Object.assign({}, err), { message: err.message.split("\n")[err.message.split("\n").length - 1], stack: (_a = err.stack) === null || _a === void 0 ? void 0 : _a.split("\n") }));
92
+ res.status(err.statusCode).json({
93
+ ...err,
94
+ message: err.message.split("\n")[err.message.split("\n").length - 1],
95
+ stack: err.stack?.split("\n"),
96
+ });
94
97
  else
95
98
  res.status(err.statusCode).json({
96
99
  title: "Something went wrong!",
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.controller.js","sourceRoot":"","sources":["../../../../src/modules/error-handler/error-handler.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport AppError from \"./utils/app-error\";\nimport * as errorControllerHelper from \"./utils/error-handler.helpers\";\nimport { server } from \"../../server\";\n\n/**\n * Error handling middleware for Express.\n *\n * This middleware function handles all errors in the Express application.\n * It checks for the environment (development or production) and sends appropriate error responses\n * based on whether the environment is production or not. It also maps specific errors such as\n * JWT errors, Prisma client errors, and database-related errors to specific helper functions for handling.\n *\n * @param {AppError} err - The error object thrown by the application.\n * @param {Request} req - The Express request object.\n * @param {Response} res - The Express response object.\n * @param {NextFunction} next - The next middleware function in the chain.\n *\n * @returns {void} - Sends the response with the error details to the client.\n */\nexport default function errorHandler(\n err: AppError,\n req: Request,\n res: Response,\n next: NextFunction\n): void {\n console.error(\"[\\x1b[31mERROR\\x1b[0m]:\", err);\n // Default error status\n err.statusCode = err.statusCode || 500;\n err.status = err.status || \"error\";\n\n // If the environment is not production, send detailed error information\n if (process.env.NODE_ENV !== \"production\") {\n sendDevelopmentError(err, req, res);\n return;\n }\n\n // Prepare error object for response, copying the original error's properties\n let error = { ...err, message: err.message };\n\n // Handle specific error cases (JWT errors, Prisma validation errors, etc.)\n if (err.name === \"JsonWebTokenError\")\n error = errorControllerHelper.handleJWTError();\n if (err.name === \"TokenExpiredError\")\n error = errorControllerHelper.handleJWTExpired();\n\n // Handle specific Prisma client validation errors\n if (err.name === \"PrismaClientValidationError\")\n error = errorControllerHelper.handlePrismaClientValidationError(err);\n\n // Handle Prisma database-specific error codes (P1000 to P3005)\n if (err.code === \"P1000\")\n error = errorControllerHelper.handleAuthenticationError(err);\n if (err.code === \"P1001\")\n error = errorControllerHelper.handleServerNotReachableError(err);\n if (err.code === \"P1002\")\n error = errorControllerHelper.handleConnectionTimeoutError(err);\n if (err.code === \"P1003\")\n error = errorControllerHelper.handleDatabaseNotFoundError(err);\n if (err.code === \"P2000\")\n error = errorControllerHelper.handleFieldValueTooLargeError(err);\n if (err.code === \"P2001\")\n error = errorControllerHelper.handleRecordNotFoundError(err);\n if (err.code === \"P2002\")\n error = errorControllerHelper.handleUniqueConstraintError(err);\n if (err.code === \"P2003\")\n error = errorControllerHelper.handleForeignKeyConstraintError(err);\n if (err.code === \"P2004\")\n error = errorControllerHelper.handleConstraintFailedError(err);\n if (err.code === \"P3000\")\n error = errorControllerHelper.handleSchemaCreationFailedError(err);\n if (err.code === \"P3001\")\n error = errorControllerHelper.handleMigrationAlreadyAppliedError(err);\n if (err.code === \"P3002\")\n error = errorControllerHelper.handleMigrationScriptFailedError(err);\n if (err.code === \"P3003\")\n error = errorControllerHelper.handleVersionMismatchError(err);\n\n // Handle general error types (e.g., syntax errors, type errors, etc.)\n // if (err.name === \"SyntaxError\")\n // error = errorControllerHelper.handleSchemaSyntaxError(err);\n // if (err.name === \"TypeError\")\n // error = errorControllerHelper.handleClientTypeError(err);\n // if (err.name === \"BinaryError\")\n // error = errorControllerHelper.handleBinaryError(err);\n if (err.name === \"NetworkError\")\n error = errorControllerHelper.handleNetworkError(err);\n // if (err.name === \"UnhandledPromiseRejection\")\n // error = errorControllerHelper.handleUnhandledPromiseError(err);\n if (!err.isOperational) error = new AppError(\"Something went wrong!\", 500);\n\n // Send the error response for production environment\n sendProductionError(error, req, res);\n}\n\n/**\n * Sends a detailed error response in development mode.\n *\n * In development, the error response includes full error details, including\n * the stack trace and the complete error message.\n *\n * @param {AppError} err - The error object.\n * @param {Request} req - The Express request object.\n * @param {Response} res - The Express response object.\n *\n * @returns {void} - Sends the response with the error details to the client.\n */\nfunction sendDevelopmentError(\n err: AppError,\n req: Request,\n res: Response\n): void {\n if (req.originalUrl.startsWith(\"/api\"))\n res.status(err.statusCode).json({\n ...err,\n message: err.message.split(\"\\n\")[err.message.split(\"\\n\").length - 1],\n stack: err.stack?.split(\"\\n\"),\n });\n else\n res.status(err.statusCode).json({\n title: \"Something went wrong!\",\n message: err.message,\n });\n}\n\n/**\n * Sends a generic error response in production mode.\n *\n * In production, sensitive error details (such as stack traces) are not exposed\n * to the client. Only operational errors are shown with a generic message.\n *\n * @param {AppError} err - The error object.\n * @param {Request} req - The Express request object.\n * @param {Response} res - The Express response object.\n *\n * @returns {void} - Sends the response with the error details to the client.\n */\nfunction sendProductionError(err: AppError, req: Request, res: Response): void {\n if (req.originalUrl.startsWith(\"/api\")) {\n if (err.isOperational)\n res.status(err.statusCode).json({\n status: err.status,\n message: err.message,\n meta: err.meta || {},\n code: err.code || \"unknown\",\n });\n else\n res.status(500).json({\n status: \"error\",\n message: \"Something went wrong!\",\n });\n\n return;\n }\n\n if (err.isOperational) {\n res.status(err.statusCode).json({\n title: \"Something went wrong!\",\n message: err.message,\n });\n return;\n }\n\n res.status(err.statusCode).json({\n title: \"Something went wrong!\",\n message: \"Please try again later.\",\n });\n}\n\n/**\n * Gracefully handles process termination by listening for SIGTERM signal.\n *\n * - In production and staging environments, it will log a shutdown message\n * and attempt to close the server gracefully.\n * - In development or non-production environments, it will immediately exit the process.\n *\n * @returns {void}\n */\nprocess.on(\"SIGTERM\", () => {\n if (\n process.env.NODE_ENV !== \"production\" &&\n process.env.NODE_ENV !== \"staging\"\n ) {\n process.exit();\n } else {\n console.error(\"SIGTERM RECEIVED in Production. Shutting down gracefully!\");\n\n server.close(() => {\n console.error(\"Process terminated!!!\");\n });\n }\n});\n"]}
1
+ {"version":3,"file":"error-handler.controller.js","sourceRoot":"","sources":["../../../../src/modules/error-handler/error-handler.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport AppError from \"./utils/app-error\";\nimport * as errorControllerHelper from \"./utils/error-handler.helpers\";\nimport { server } from \"../../server\";\n\n/**\n * Error handling middleware for Express.\n *\n * This middleware function handles all errors in the Express application.\n * It checks for the environment (development or production) and sends appropriate error responses\n * based on whether the environment is production or not. It also maps specific errors such as\n * JWT errors, Prisma client errors, and database-related errors to specific helper functions for handling.\n *\n * @param {AppError} err - The error object thrown by the application.\n * @param {Request} req - The Express request object.\n * @param {Response} res - The Express response object.\n * @param {NextFunction} next - The next middleware function in the chain.\n *\n * @returns {void} - Sends the response with the error details to the client.\n */\nexport default function errorHandler(\n err: AppError,\n req: Request,\n res: Response,\n next: NextFunction\n): void {\n console.error(\"[\\x1b[31mERROR\\x1b[0m]:\", err);\n // Default error status\n err.statusCode = err.statusCode || 500;\n err.status = err.status || \"error\";\n\n // If the environment is not production, send detailed error information\n if (process.env.NODE_ENV !== \"production\") {\n sendDevelopmentError(err, req, res);\n return;\n }\n\n // Prepare error object for response, copying the original error's properties\n let error = { ...err, message: err.message };\n\n // Handle specific error cases (JWT errors, Prisma validation errors, etc.)\n if (err.name === \"JsonWebTokenError\")\n error = errorControllerHelper.handleJWTError();\n if (err.name === \"TokenExpiredError\")\n error = errorControllerHelper.handleJWTExpired();\n\n // Handle specific Prisma client validation errors\n if (err.name === \"PrismaClientValidationError\")\n error = errorControllerHelper.handlePrismaClientValidationError(err);\n\n // Handle Prisma database-specific error codes (P1000 to P3005)\n if (err.code === \"P1000\")\n error = errorControllerHelper.handleAuthenticationError(err);\n if (err.code === \"P1001\")\n error = errorControllerHelper.handleServerNotReachableError(err);\n if (err.code === \"P1002\")\n error = errorControllerHelper.handleConnectionTimeoutError(err);\n if (err.code === \"P1003\")\n error = errorControllerHelper.handleDatabaseNotFoundError(err);\n if (err.code === \"P2000\")\n error = errorControllerHelper.handleFieldValueTooLargeError(err);\n if (err.code === \"P2001\")\n error = errorControllerHelper.handleRecordNotFoundError(err);\n if (err.code === \"P2002\")\n error = errorControllerHelper.handleUniqueConstraintError(err);\n if (err.code === \"P2003\")\n error = errorControllerHelper.handleForeignKeyConstraintError(err);\n if (err.code === \"P2004\")\n error = errorControllerHelper.handleConstraintFailedError(err);\n if (err.code === \"P3000\")\n error = errorControllerHelper.handleSchemaCreationFailedError(err);\n if (err.code === \"P3001\")\n error = errorControllerHelper.handleMigrationAlreadyAppliedError(err);\n if (err.code === \"P3002\")\n error = errorControllerHelper.handleMigrationScriptFailedError(err);\n if (err.code === \"P3003\")\n error = errorControllerHelper.handleVersionMismatchError(err);\n\n // Handle general error types (e.g., syntax errors, type errors, etc.)\n // if (err.name === \"SyntaxError\")\n // error = errorControllerHelper.handleSchemaSyntaxError(err);\n // if (err.name === \"TypeError\")\n // error = errorControllerHelper.handleClientTypeError(err);\n // if (err.name === \"BinaryError\")\n // error = errorControllerHelper.handleBinaryError(err);\n if (err.name === \"NetworkError\")\n error = errorControllerHelper.handleNetworkError(err);\n // if (err.name === \"UnhandledPromiseRejection\")\n // error = errorControllerHelper.handleUnhandledPromiseError(err);\n if (!err.isOperational) error = new AppError(\"Something went wrong!\", 500);\n\n // Send the error response for production environment\n sendProductionError(error, req, res);\n}\n\n/**\n * Sends a detailed error response in development mode.\n *\n * In development, the error response includes full error details, including\n * the stack trace and the complete error message.\n *\n * @param {AppError} err - The error object.\n * @param {Request} req - The Express request object.\n * @param {Response} res - The Express response object.\n *\n * @returns {void} - Sends the response with the error details to the client.\n */\nfunction sendDevelopmentError(\n err: AppError,\n req: Request,\n res: Response\n): void {\n if (req.originalUrl.startsWith(\"/api\"))\n res.status(err.statusCode).json({\n ...err,\n message: err.message.split(\"\\n\")[err.message.split(\"\\n\").length - 1],\n stack: err.stack?.split(\"\\n\"),\n });\n else\n res.status(err.statusCode).json({\n title: \"Something went wrong!\",\n message: err.message,\n });\n}\n\n/**\n * Sends a generic error response in production mode.\n *\n * In production, sensitive error details (such as stack traces) are not exposed\n * to the client. Only operational errors are shown with a generic message.\n *\n * @param {AppError} err - The error object.\n * @param {Request} req - The Express request object.\n * @param {Response} res - The Express response object.\n *\n * @returns {void} - Sends the response with the error details to the client.\n */\nfunction sendProductionError(err: AppError, req: Request, res: Response): void {\n if (req.originalUrl.startsWith(\"/api\")) {\n if (err.isOperational)\n res.status(err.statusCode).json({\n status: err.status,\n message: err.message,\n meta: err.meta || {},\n code: err.code || \"unknown\",\n });\n else\n res.status(500).json({\n status: \"error\",\n message: \"Something went wrong!\",\n });\n\n return;\n }\n\n if (err.isOperational) {\n res.status(err.statusCode).json({\n title: \"Something went wrong!\",\n message: err.message,\n });\n return;\n }\n\n res.status(err.statusCode).json({\n title: \"Something went wrong!\",\n message: \"Please try again later.\",\n });\n}\n\n/**\n * Gracefully handles process termination by listening for SIGTERM signal.\n *\n * - In production and staging environments, it will log a shutdown message\n * and attempt to close the server gracefully.\n * - In development or non-production environments, it will immediately exit the process.\n *\n * @returns {void}\n */\nprocess.on(\"SIGTERM\", () => {\n if (\n process.env.NODE_ENV !== \"production\" &&\n process.env.NODE_ENV !== \"staging\"\n ) {\n process.exit();\n } else {\n console.error(\"SIGTERM RECEIVED in Production. Shutting down gracefully!\");\n\n server.close(() => {\n console.error(\"Process terminated!!!\");\n });\n }\n});\n"]}
@@ -1,21 +1,12 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const catchAsync = (fn) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
3
+ const catchAsync = (fn) => async (req, res, next) => {
13
4
  try {
14
- return yield fn(req, res, next);
5
+ return await fn(req, res, next);
15
6
  }
16
7
  catch (err) {
17
8
  next(err);
18
9
  }
19
- });
10
+ };
20
11
  exports.default = catchAsync;
21
12
  //# sourceMappingURL=catch-async.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"catch-async.js","sourceRoot":"","sources":["../../../../../src/modules/error-handler/utils/catch-async.ts"],"names":[],"mappings":";;;;;;;;;;;AAwBA,MAAM,UAAU,GACd,CAAC,EAAuB,EAAE,EAAE,CAC5B,CAAO,GAAiB,EAAE,GAAkB,EAAE,IAAuB,EAAE,EAAE;IACvE,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CAAA,CAAC;AAEJ,kBAAe,UAAU,CAAC","sourcesContent":["import {\n ArkosRequest,\n ArkosResponse,\n ArkosNextFunction,\n ArkosRequestHandler,\n} from \"../../../types\";\n\n/**\n * Used to wrap request handlers and middleware for automatic catch async errors and throw to next to invoke the global error handler\n *\n * @param {ArkosRequestHandler} fn - an express request handler or middleware that will be called with req, res, next, with catch attached for error handling\n * @returns\n *\n * @example\n * ```typescript\n * import { ArkosRequest, ArkosResponse, ArkosNextFunction } from 'arkos'\n *\n * export const getManyPosts = catchAsync(async\n * (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n * const posts = await getSomePosts()\n * res.status(200).json({ data: posts })\n * })\n * ```\n */\nconst catchAsync =\n (fn: ArkosRequestHandler) =>\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n try {\n return await fn(req, res, next);\n } catch (err) {\n next(err);\n }\n };\n\nexport default catchAsync;\n"]}
1
+ {"version":3,"file":"catch-async.js","sourceRoot":"","sources":["../../../../../src/modules/error-handler/utils/catch-async.ts"],"names":[],"mappings":";;AAwBA,MAAM,UAAU,GACd,CAAC,EAAuB,EAAE,EAAE,CAC5B,KAAK,EAAE,GAAiB,EAAE,GAAkB,EAAE,IAAuB,EAAE,EAAE;IACvE,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEJ,kBAAe,UAAU,CAAC","sourcesContent":["import {\n ArkosRequest,\n ArkosResponse,\n ArkosNextFunction,\n ArkosRequestHandler,\n} from \"../../../types\";\n\n/**\n * Used to wrap request handlers and middleware for automatic catch async errors and throw to next to invoke the global error handler\n *\n * @param {ArkosRequestHandler} fn - an express request handler or middleware that will be called with req, res, next, with catch attached for error handling\n * @returns\n *\n * @example\n * ```typescript\n * import { ArkosRequest, ArkosResponse, ArkosNextFunction } from 'arkos'\n *\n * export const getManyPosts = catchAsync(async\n * (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n * const posts = await getSomePosts()\n * res.status(200).json({ data: posts })\n * })\n * ```\n */\nconst catchAsync =\n (fn: ArkosRequestHandler) =>\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n try {\n return await fn(req, res, next);\n } catch (err) {\n next(err);\n }\n };\n\nexport default catchAsync;\n"]}