arkos 1.0.19-beta → 1.0.20-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/app.js +1 -1
- package/dist/cjs/app.js.map +1 -1
- package/dist/cjs/exports/middlewares/index.js +7 -0
- package/dist/cjs/exports/middlewares/index.js.map +1 -0
- package/dist/cjs/modules/auth/auth.controller.js +31 -26
- package/dist/cjs/modules/auth/auth.controller.js.map +1 -1
- package/dist/cjs/modules/auth/auth.router.js +4 -5
- package/dist/cjs/modules/auth/auth.router.js.map +1 -1
- package/dist/cjs/modules/auth/auth.service.js +27 -24
- package/dist/cjs/modules/auth/auth.service.js.map +1 -1
- package/dist/cjs/modules/auth/utils/helpers/auth.controller.helpers.js +4 -4
- package/dist/cjs/modules/auth/utils/helpers/auth.controller.helpers.js.map +1 -1
- package/dist/cjs/modules/base/base.controller.js +2 -29
- package/dist/cjs/modules/base/base.controller.js.map +1 -1
- package/dist/cjs/modules/base/base.middlewares.js +37 -1
- package/dist/cjs/modules/base/base.middlewares.js.map +1 -1
- package/dist/cjs/modules/base/base.router.js +2 -2
- package/dist/cjs/modules/base/base.router.js.map +1 -1
- package/dist/cjs/modules/base/utils/helpers/base.router.helpers.js +2 -3
- package/dist/cjs/modules/base/utils/helpers/base.router.helpers.js.map +1 -1
- package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js +9 -11
- package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js.map +1 -1
- package/dist/cjs/modules/error-handler/error-handler.controller.js +2 -0
- package/dist/cjs/modules/error-handler/error-handler.controller.js.map +1 -1
- package/dist/cjs/modules/error-handler/utils/catch-async.js +1 -1
- package/dist/cjs/modules/error-handler/utils/catch-async.js.map +1 -1
- package/dist/cjs/modules/file-uploader/file-uploader.service.js +4 -4
- package/dist/cjs/modules/file-uploader/file-uploader.service.js.map +1 -1
- package/dist/cjs/modules/file-uploader/utils/helpers/file-uploader.helpers.js +7 -5
- package/dist/cjs/modules/file-uploader/utils/helpers/file-uploader.helpers.js.map +1 -1
- package/dist/cjs/server.js +1 -1
- package/dist/cjs/server.js.map +1 -1
- package/dist/cjs/types/auth.js.map +1 -1
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/utils/features/api.features.js +3 -2
- package/dist/cjs/utils/features/api.features.js.map +1 -1
- package/dist/cjs/utils/helpers/api.features.helpers.js +4 -4
- package/dist/cjs/utils/helpers/api.features.helpers.js.map +1 -1
- package/dist/cjs/utils/helpers/base.controller.helpers.js +77 -35
- package/dist/cjs/utils/helpers/base.controller.helpers.js.map +1 -1
- package/dist/cjs/utils/helpers/change-case.helpers.js +3 -3
- package/dist/cjs/utils/helpers/change-case.helpers.js.map +1 -1
- package/dist/cjs/utils/helpers/fs.helpers.js.map +1 -1
- package/dist/cjs/utils/helpers/models.helpers.js +35 -30
- package/dist/cjs/utils/helpers/models.helpers.js.map +1 -1
- package/dist/cjs/utils/scripts/generate-insomnia-collection.js +228 -0
- package/dist/cjs/utils/scripts/generate-insomnia-collection.js.map +1 -0
- package/dist/cjs/utils/scripts/index.js +12 -0
- package/dist/cjs/utils/scripts/index.js.map +1 -0
- package/dist/es2020/app.js +1 -1
- package/dist/es2020/app.js.map +1 -1
- package/dist/es2020/exports/middlewares/index.js +2 -0
- package/dist/es2020/exports/middlewares/index.js.map +1 -0
- package/dist/es2020/modules/auth/auth.controller.js +32 -27
- package/dist/es2020/modules/auth/auth.controller.js.map +1 -1
- package/dist/es2020/modules/auth/auth.router.js +1 -2
- package/dist/es2020/modules/auth/auth.router.js.map +1 -1
- package/dist/es2020/modules/auth/auth.service.js +27 -24
- package/dist/es2020/modules/auth/auth.service.js.map +1 -1
- package/dist/es2020/modules/auth/utils/helpers/auth.controller.helpers.js +4 -4
- package/dist/es2020/modules/auth/utils/helpers/auth.controller.helpers.js.map +1 -1
- package/dist/es2020/modules/base/base.controller.js +2 -29
- package/dist/es2020/modules/base/base.controller.js.map +1 -1
- package/dist/es2020/modules/base/base.middlewares.js +33 -1
- package/dist/es2020/modules/base/base.middlewares.js.map +1 -1
- package/dist/es2020/modules/base/base.router.js +2 -2
- package/dist/es2020/modules/base/base.router.js.map +1 -1
- package/dist/es2020/modules/base/utils/helpers/base.router.helpers.js +1 -2
- package/dist/es2020/modules/base/utils/helpers/base.router.helpers.js.map +1 -1
- package/dist/es2020/modules/base/utils/helpers/base.service.helpers.js +9 -11
- package/dist/es2020/modules/base/utils/helpers/base.service.helpers.js.map +1 -1
- package/dist/es2020/modules/error-handler/error-handler.controller.js +2 -0
- package/dist/es2020/modules/error-handler/error-handler.controller.js.map +1 -1
- package/dist/es2020/modules/error-handler/utils/catch-async.js +1 -1
- package/dist/es2020/modules/error-handler/utils/catch-async.js.map +1 -1
- package/dist/es2020/modules/file-uploader/file-uploader.service.js +4 -4
- package/dist/es2020/modules/file-uploader/file-uploader.service.js.map +1 -1
- package/dist/es2020/modules/file-uploader/utils/helpers/file-uploader.helpers.js +7 -5
- package/dist/es2020/modules/file-uploader/utils/helpers/file-uploader.helpers.js.map +1 -1
- package/dist/es2020/server.js +1 -1
- package/dist/es2020/server.js.map +1 -1
- package/dist/es2020/types/auth.js.map +1 -1
- package/dist/es2020/types/index.js.map +1 -1
- package/dist/es2020/utils/features/api.features.js +3 -2
- package/dist/es2020/utils/features/api.features.js.map +1 -1
- package/dist/es2020/utils/helpers/api.features.helpers.js +4 -4
- package/dist/es2020/utils/helpers/api.features.helpers.js.map +1 -1
- package/dist/es2020/utils/helpers/base.controller.helpers.js +75 -31
- package/dist/es2020/utils/helpers/base.controller.helpers.js.map +1 -1
- package/dist/es2020/utils/helpers/change-case.helpers.js +3 -3
- package/dist/es2020/utils/helpers/change-case.helpers.js.map +1 -1
- package/dist/es2020/utils/helpers/fs.helpers.js.map +1 -1
- package/dist/es2020/utils/helpers/models.helpers.js +35 -30
- package/dist/es2020/utils/helpers/models.helpers.js.map +1 -1
- package/dist/es2020/utils/scripts/generate-insomnia-collection.js +189 -0
- package/dist/es2020/utils/scripts/generate-insomnia-collection.js.map +1 -0
- package/dist/es2020/utils/scripts/index.js +10 -0
- package/dist/es2020/utils/scripts/index.js.map +1 -0
- package/dist/types/exports/middlewares/index.d.ts +1 -0
- package/dist/types/modules/auth/auth.service.d.ts +3 -3
- package/dist/types/modules/base/base.middlewares.d.ts +6 -1
- package/dist/types/modules/base/utils/helpers/base.service.helpers.d.ts +1 -1
- package/dist/types/types/auth.d.ts +9 -8
- package/dist/types/types/index.d.ts +2 -1
- package/dist/types/utils/helpers/base.controller.helpers.d.ts +4 -6
- package/dist/types/utils/scripts/generate-insomnia-collection.d.ts +1 -0
- package/dist/types/utils/scripts/index.d.ts +2 -0
- package/package.json +10 -1
|
@@ -11,10 +11,10 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.removeApiAction = removeApiAction;
|
|
14
15
|
exports.isPrismaRelationFormat = isPrismaRelationFormat;
|
|
15
16
|
exports.handleRelationFieldsInBody = handleRelationFieldsInBody;
|
|
16
17
|
exports.canBeUsedToConnect = canBeUsedToConnect;
|
|
17
|
-
exports.isListFieldAnArray = isListFieldAnArray;
|
|
18
18
|
const models_helpers_1 = require("../../../../utils/helpers/models.helpers");
|
|
19
19
|
function removeApiAction(obj) {
|
|
20
20
|
if (!obj || typeof obj !== "object")
|
|
@@ -61,7 +61,7 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
|
|
|
61
61
|
if (isPrismaRelationFormat(body[field.name])) {
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
|
-
if (!
|
|
64
|
+
if (!Array.isArray(body[field.name])) {
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
const createData = [];
|
|
@@ -70,7 +70,8 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
|
|
|
70
70
|
const disconnectData = [];
|
|
71
71
|
const deleteManyIds = [];
|
|
72
72
|
(_a = body[field.name]) === null || _a === void 0 ? void 0 : _a.forEach((bodyField) => {
|
|
73
|
-
|
|
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))
|
|
74
75
|
return;
|
|
75
76
|
const apiAction = bodyField === null || bodyField === void 0 ? void 0 : bodyField.apiAction;
|
|
76
77
|
if (apiAction === "delete") {
|
|
@@ -113,10 +114,10 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
|
|
|
113
114
|
: {}));
|
|
114
115
|
});
|
|
115
116
|
(_b = relationFields === null || relationFields === void 0 ? void 0 : relationFields.singular) === null || _b === void 0 ? void 0 : _b.forEach((field) => {
|
|
116
|
-
var _a;
|
|
117
|
+
var _a, _b;
|
|
117
118
|
if (!body[field.name])
|
|
118
119
|
return;
|
|
119
|
-
if (ignoreActions === null || ignoreActions === void 0 ? void 0 : ignoreActions.includes((
|
|
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))
|
|
120
121
|
return;
|
|
121
122
|
if (isPrismaRelationFormat(body[field.name])) {
|
|
122
123
|
return;
|
|
@@ -158,16 +159,16 @@ function handleRelationFieldsInBody(body, relationFields, ignoreActions = []) {
|
|
|
158
159
|
return removeApiAction(mutableBody);
|
|
159
160
|
}
|
|
160
161
|
function canBeUsedToConnect(modelName, bodyField) {
|
|
161
|
-
var _a, _b;
|
|
162
|
+
var _a, _b, _c;
|
|
162
163
|
if (!bodyField)
|
|
163
164
|
return false;
|
|
164
|
-
if (bodyField.apiAction && !((_a = ["connect"]) === null || _a === void 0 ? void 0 : _a.includes(bodyField.apiAction))) {
|
|
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))) {
|
|
165
166
|
return false;
|
|
166
167
|
}
|
|
167
168
|
if (bodyField.apiAction === "connect") {
|
|
168
169
|
return true;
|
|
169
170
|
}
|
|
170
|
-
if (((
|
|
171
|
+
if (((_c = Object.keys(bodyField)) === null || _c === void 0 ? void 0 : _c.length) === 1 && (bodyField === null || bodyField === void 0 ? void 0 : bodyField.id)) {
|
|
171
172
|
return true;
|
|
172
173
|
}
|
|
173
174
|
const uniqueFields = (0, models_helpers_1.getModelUniqueFields)(modelName);
|
|
@@ -177,7 +178,4 @@ function canBeUsedToConnect(modelName, bodyField) {
|
|
|
177
178
|
}
|
|
178
179
|
return false;
|
|
179
180
|
}
|
|
180
|
-
function isListFieldAnArray(field) {
|
|
181
|
-
return Array.isArray(field);
|
|
182
|
-
}
|
|
183
181
|
//# sourceMappingURL=base.service.helpers.js.map
|
|
@@ -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 */\nfunction 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 (!isListFieldAnArray(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 */\nexport 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.controller.js","sourceRoot":"","sources":["../../../../src/modules/error-handler/error-handler.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,+BAwEC;AA3FD,kEAAyC;AACzC,qFAAuE;AACvE,yCAAsC;AAiBtC,SAAwB,YAAY,CAClC,GAAa,EACb,GAAY,EACZ,GAAa,EACb,IAAkB;IAGlB,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC;IACvC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC;IAGnC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC1C,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACpC,OAAO;IACT,CAAC;IAGD,IAAI,KAAK,mCAAQ,GAAG,KAAE,OAAO,EAAE,GAAG,CAAC,OAAO,GAAE,CAAC;IAG7C,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB;QAClC,KAAK,GAAG,qBAAqB,CAAC,cAAc,EAAE,CAAC;IACjD,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB;QAClC,KAAK,GAAG,qBAAqB,CAAC,gBAAgB,EAAE,CAAC;IAGnD,IAAI,GAAG,CAAC,IAAI,KAAK,6BAA6B;QAC5C,KAAK,GAAG,qBAAqB,CAAC,iCAAiC,CAAC,GAAG,CAAC,CAAC;IAGvE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;IAC/D,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC;IACnE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAC;IAClE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;IACjE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC;IACnE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;IAC/D,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;IACjE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;IACrE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;IACjE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;IACrE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,kCAAkC,CAAC,GAAG,CAAC,CAAC;IACxE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,gCAAgC,CAAC,GAAG,CAAC,CAAC;IACtE,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QACtB,KAAK,GAAG,qBAAqB,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;IAShE,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc;QAC7B,KAAK,GAAG,qBAAqB,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAGxD,IAAI,CAAC,GAAG,CAAC,aAAa;QAAE,KAAK,GAAG,IAAI,mBAAQ,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;IAG3E,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC;AAcD,SAAS,oBAAoB,CAC3B,GAAa,EACb,GAAY,EACZ,GAAa;;IAEb,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAE9C,IAAI,GAAG,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC;QACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;YAC9B,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACpE,KAAK,EAAE,GAAG;YACV,KAAK,EAAE,MAAA,GAAG,CAAC,KAAK,0CAAE,KAAK,CAAC,IAAI,CAAC;SAC9B,CAAC,CAAC;;QAEH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;YAC9B,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC,CAAC;AACP,CAAC;AAcD,SAAS,mBAAmB,CAAC,GAAa,EAAE,GAAY,EAAE,GAAa;IACrE,IAAI,GAAG,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,aAAa;YACnB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;gBAC9B,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC,CAAC;;YAEH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,uBAAuB;aACjC,CAAC,CAAC;QAEL,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;QACtB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;YAC9B,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC9B,KAAK,EAAE,uBAAuB;QAC9B,OAAO,EAAE,yBAAyB;KACnC,CAAC,CAAC;AACL,CAAC;AAWD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,IACE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;QACrC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,EAClC,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAE3E,eAAM,CAAC,KAAK,CAAC,GAAG,EAAE;YAChB,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC","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 // 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 console.error(\"[\\x1b[31mERROR\\x1b[0m]:\", err);\n\n if (req.originalUrl.startsWith(\"/api\"))\n res.status(err.statusCode).json({\n message: err.message.split(\"\\n\")[err.message.split(\"\\n\").length - 1],\n error: err,\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 });\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 // 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 console.error(\"[\\x1b[31mERROR\\x1b[0m]:\", err);\n\n if (req.originalUrl.startsWith(\"/api\"))\n res.status(err.statusCode).json({\n message: err.message.split(\"\\n\")[err.message.split(\"\\n\").length - 1],\n error: err,\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 || \"\",\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"]}
|
|
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const catchAsync = (fn) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
13
|
try {
|
|
14
|
-
yield fn(req, res, next);
|
|
14
|
+
return yield fn(req, res, next);
|
|
15
15
|
}
|
|
16
16
|
catch (err) {
|
|
17
17
|
next(err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catch-async.js","sourceRoot":"","sources":["../../../../../src/modules/error-handler/utils/catch-async.ts"],"names":[],"mappings":";;;;;;;;;;;
|
|
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"]}
|
|
@@ -206,11 +206,11 @@ class FileUploaderService {
|
|
|
206
206
|
? this.getUploader().array(this.getFieldName(), this.maxCount)
|
|
207
207
|
: this.getUploader().single(this.getFieldName());
|
|
208
208
|
uploadHandler(req, res, (err) => __awaiter(this, void 0, void 0, function* () {
|
|
209
|
-
var _a, _b, _c;
|
|
209
|
+
var _a, _b, _c, _d, _e, _f;
|
|
210
210
|
if (err)
|
|
211
211
|
return reject(err);
|
|
212
212
|
try {
|
|
213
|
-
const protocol = ((_a = req.get("host")) === null || _a === void 0 ? void 0 : _a.includes("localhost"))
|
|
213
|
+
const protocol = ((_b = (_a = req.get("host")) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, "localhost"))
|
|
214
214
|
? "http"
|
|
215
215
|
: "https";
|
|
216
216
|
const baseURL = `${protocol}://${req.get("host")}`;
|
|
@@ -220,7 +220,7 @@ class FileUploaderService {
|
|
|
220
220
|
: dirParts[dirParts.length - 1]) || "files";
|
|
221
221
|
let data;
|
|
222
222
|
if (req.files && Array.isArray(req.files) && req.files.length > 0) {
|
|
223
|
-
const isImageUploader = (
|
|
223
|
+
const isImageUploader = (_d = (_c = this.uploadDir) === null || _c === void 0 ? void 0 : _c.includes) === null || _d === void 0 ? void 0 : _d.call(_c, "/images");
|
|
224
224
|
if (isImageUploader) {
|
|
225
225
|
data = yield Promise.all(req.files.map((file) => (0, file_uploader_helpers_1.processImage)(req, file.path, options)));
|
|
226
226
|
}
|
|
@@ -230,7 +230,7 @@ class FileUploaderService {
|
|
|
230
230
|
data = data.filter((url) => url !== null);
|
|
231
231
|
}
|
|
232
232
|
else if (req.file) {
|
|
233
|
-
const isImageUploader = (
|
|
233
|
+
const isImageUploader = (_f = (_e = this.uploadDir) === null || _e === void 0 ? void 0 : _e.includes) === null || _f === void 0 ? void 0 : _f.call(_e, "/images");
|
|
234
234
|
if (isImageUploader) {
|
|
235
235
|
data = yield (0, file_uploader_helpers_1.processImage)(req, req.file.path, options);
|
|
236
236
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-uploader.service.js","sourceRoot":"","sources":["../../../../src/modules/file-uploader/file-uploader.service.ts"],"names":[],"mappings":"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","sourcesContent":["import multer, { StorageEngine } from \"multer\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { NextFunction } from \"express\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { promisify } from \"util\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { ArkosRequest, ArkosResponse } from \"../../types\";\nimport {\n processFile,\n processImage,\n} from \"./utils/helpers/file-uploader.helpers\";\nimport { removeBothSlashes } from \"../../utils/helpers/text.helpers\";\n\n/**\n * Service to handle file uploads, including single and multiple file uploads,\n * file validation (type, size), and file deletion.\n */\nexport class FileUploaderService {\n public readonly uploadDir: string;\n private fileSizeLimit: number;\n private allowedFileTypes: RegExp;\n private storage: StorageEngine;\n private maxCount: number;\n\n /**\n * Constructor to initialize the file uploader service.\n * @param {string} uploadDir - The directory where files will be uploaded.\n * @param {number} fileSizeLimit - The maximum allowed file size.\n * @param {RegExp} allowedFileTypes - The regular expression for allowed file types.\n */\n constructor(\n uploadDir: string,\n fileSizeLimit: number = 1024 * 1024 * 5,\n allowedFileTypes: RegExp = /.*/,\n maxCount: number = 30\n ) {\n uploadDir = uploadDir.startsWith(\"/\") ? uploadDir.substring(1) : uploadDir;\n uploadDir = uploadDir.endsWith(\"/\") ? uploadDir.slice(0, -1) : uploadDir;\n\n this.uploadDir = path.resolve(process.cwd(), `${uploadDir}/`);\n this.fileSizeLimit = fileSizeLimit;\n this.allowedFileTypes = allowedFileTypes;\n this.maxCount = maxCount;\n\n if (!fs.existsSync(this.uploadDir)) {\n fs.mkdirSync(this.uploadDir, { recursive: true });\n }\n\n this.storage = multer.diskStorage({\n destination: (req, file, cb) => {\n cb(null, this.uploadDir);\n },\n filename: (req, file, cb) => {\n const uniqueSuffix = Date.now() + \"-\" + Math.round(Math.random() * 1e9);\n cb(null, `${uniqueSuffix}${path.extname(file.originalname)}`);\n },\n });\n }\n\n /**\n * Validates the file's type and MIME type.\n * @param {Request} req - The Express request object.\n * @param {Express.Multer.File} file - The uploaded file.\n * @param {Function} cb - The callback function to indicate if file is valid.\n */\n private fileFilter = (req: any, file: any, cb: any) => {\n const extName = this.allowedFileTypes.test(\n path.extname(file.originalname).toLowerCase()\n );\n const mimeType = this.allowedFileTypes.test(file.mimetype);\n\n if (mimeType && extName) {\n cb(null, true);\n } else {\n cb(new AppError(\"Invalid file type\", 400));\n }\n };\n\n /**\n * Returns the multer upload configuration.\n * @returns {multer.Instance} The multer instance configured for file uploads.\n */\n public getUploader() {\n return multer({\n storage: this.storage,\n fileFilter: this.fileFilter,\n limits: { fileSize: this.fileSizeLimit },\n });\n }\n\n /**\n * Middleware to handle single file upload.\n * @param {string} [oldFilePath] - The path to the file to delete before uploading.\n * @returns {Function} Middleware function for handling file upload.\n */\n public handleSingleUpload(oldFilePath?: string) {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUploader().single(this.getFieldName());\n upload(req, res, async (err) => {\n if (err instanceof multer.MulterError) {\n return next(err);\n } else if (err) {\n return next(err);\n }\n\n if (oldFilePath) {\n const { fileUpload: configs } = getArkosConfig();\n\n const filePath = path.resolve(\n process.cwd(),\n removeBothSlashes(configs?.baseUploadDir!),\n removeBothSlashes(oldFilePath)\n );\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) await promisify(fs.unlink)(filePath);\n } catch (err) {\n console.error(err);\n }\n }\n\n next();\n });\n };\n }\n\n /**\n * Middleware to handle multiple file uploads.\n * @param {number} maxCount - The maximum number of files allowed for upload.\n * @returns {Function} Middleware function for handling multiple file uploads.\n */\n public handleMultipleUpload() {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUploader().array(\n this.getFieldName(),\n this.maxCount\n );\n upload(req, res, (err) => {\n if (err instanceof multer.MulterError) return next(err);\n else if (err) return next(err);\n next();\n });\n };\n }\n\n /**\n * Middleware to handle deletion of a single file from the filesystem.\n * @param {string} oldFilePath - The path to the file to be deleted.\n * @returns {Function} Middleware function for handling file deletion.\n */\n public handleDeleteSingleFile(oldFilePath: string) {\n return async (\n req: ArkosRequest,\n res: ArkosResponse,\n next: NextFunction\n ) => {\n const filePath = path.join(oldFilePath);\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) {\n await promisify(fs.unlink)(filePath);\n }\n } catch (err) {\n console.error(err);\n }\n\n next();\n };\n }\n\n /**\n * Deletes a file based on its URL by identifying the appropriate uploader service\n * @param {string} fileUrl - The URL of the file to delete\n * @returns {Promise<boolean>} - True if deletion successful, false otherwise\n */\n public async deleteFileByUrl(fileUrl: string): Promise<boolean> {\n try {\n // Get configuration values\n const { fileUpload } = getArkosConfig();\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n\n // Parse the URL to get the path\n let urlPath: string;\n if (fileUrl.startsWith(\"http\")) {\n const url = new URL(fileUrl);\n urlPath = url.pathname;\n } else {\n urlPath = fileUrl;\n }\n\n // Extract the path after the base route\n const baseRouteIndex = urlPath.indexOf(baseRoute);\n if (baseRouteIndex === -1) {\n throw new AppError(\"Invalid file URL: base route not found\", 400);\n }\n\n const pathAfterBaseRoute = urlPath.substring(\n baseRouteIndex + baseRoute.length\n );\n const cleanPath = pathAfterBaseRoute.startsWith(\"/\")\n ? pathAfterBaseRoute.substring(1)\n : pathAfterBaseRoute;\n\n // Determine file type and file name\n const fileTypes = [\"images\", \"videos\", \"documents\", \"files\"];\n let fileType: string | null = null;\n let fileName: string | null = null;\n\n for (const type of fileTypes) {\n const typeIndex = cleanPath.indexOf(type + \"/\");\n if (typeIndex !== -1) {\n fileType = type;\n fileName = cleanPath.substring(typeIndex + type.length + 1);\n break;\n }\n }\n\n if (!fileType || !fileName) {\n throw new AppError(\n \"Unable to determine file type or file name from URL\",\n 400\n );\n }\n\n // Get the appropriate uploader service based on file type\n const {\n documentUploaderService,\n fileUploaderService,\n imageUploaderService,\n videoUploaderService,\n } = getFileUploaderServices();\n\n let filePath: string;\n switch (fileType) {\n case \"images\":\n filePath = path.join(imageUploaderService.uploadDir, fileName);\n break;\n case \"videos\":\n filePath = path.join(videoUploaderService.uploadDir, fileName);\n break;\n case \"documents\":\n filePath = path.join(documentUploaderService.uploadDir, fileName);\n break;\n case \"files\":\n filePath = path.join(fileUploaderService.uploadDir, fileName);\n break;\n default:\n throw new AppError(`Unsupported file type: ${fileType}`, 400);\n }\n\n // Delete the file\n\n await promisify(fs.stat)(filePath);\n await promisify(fs.unlink)(filePath);\n\n return true;\n } catch (error: any) {\n if (error instanceof AppError) {\n throw error;\n }\n\n if (error.code === \"ENOENT\") {\n throw new AppError(\"File not found\", 404);\n }\n\n throw new AppError(`Failed to delete file: ${error.message}`, 500);\n }\n }\n\n private getFieldName() {\n let fieldName = \"files\";\n if (this.uploadDir.endsWith(\"images\") || this.uploadDir.endsWith(\"images/\"))\n fieldName = \"images\";\n if (this.uploadDir.endsWith(\"videos\") || this.uploadDir.endsWith(\"videos/\"))\n fieldName = \"videos\";\n if (\n this.uploadDir.endsWith(\"documents\") ||\n this.uploadDir.endsWith(\"documents/\")\n )\n fieldName = \"documents\";\n if (this.uploadDir.endsWith(\"files\") || this.uploadDir.endsWith(\"files/\"))\n fieldName = \"files\";\n return fieldName;\n }\n\n /**\n * Handles the upload process and returns the full URLs of uploaded files\n * @param {ArkosRequest} req - Arkos request object containing the files\n * @param {ArkosResponse} res - Arkos response object\n * @param {object} options - Optional parameters for image processing\n * @returns {Promise<string|string[]>} URL or array of URLs to the uploaded files\n */\n public async upload(\n req: ArkosRequest,\n res: ArkosResponse,\n options: {\n format?: string;\n width?: number;\n height?: number;\n resizeTo?: number;\n } = {}\n ): Promise<string | string[] | null> {\n const { fileUpload } = getArkosConfig();\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n\n return new Promise((resolve, reject) => {\n // Determine if it's a single or multiple file upload\n const isMultiple = Array.isArray(req.query.multiple)\n ? req.query.multiple[0] == \"true\"\n : req.query.multiple == \"true\";\n\n // Use appropriate upload handler\n const uploadHandler = isMultiple\n ? this.getUploader().array(this.getFieldName(), this.maxCount)\n : this.getUploader().single(this.getFieldName());\n\n uploadHandler(req, res, async (err) => {\n if (err) return reject(err);\n\n try {\n // Determine the base URL for file access\n const protocol = req.get(\"host\")?.includes(\"localhost\")\n ? \"http\"\n : \"https\";\n const baseURL = `${protocol}://${req.get(\"host\")}`;\n\n // Get file type from uploadDir path\n const dirParts = this.uploadDir.split(\"/\");\n const fileType =\n (this.uploadDir.endsWith(\"/\")\n ? dirParts[dirParts.length - 2]\n : dirParts[dirParts.length - 1]) || \"files\";\n\n // Process all uploaded files\n let data;\n if (req.files && Array.isArray(req.files) && req.files.length > 0) {\n // Process multiple files\n const isImageUploader = this.uploadDir?.includes(\"/images\");\n if (isImageUploader) {\n data = await Promise.all(\n req.files.map((file) => processImage(req, file.path, options))\n );\n } else {\n data = await Promise.all(\n req.files.map((file) => processFile(req, file.path))\n );\n }\n // Filter out any null values from failed processing\n data = data.filter((url) => url !== null);\n } else if (req.file) {\n // Process a single file\n const isImageUploader = this.uploadDir?.includes(\"/images\");\n if (isImageUploader) {\n data = await processImage(req, req.file.path, options);\n } else {\n data = await processFile(req, req.file.path);\n }\n } else {\n return reject(new AppError(\"No file uploaded\", 400));\n }\n\n resolve(data);\n } catch (error) {\n reject(error);\n }\n });\n });\n }\n}\n\n/**\n * Creates and returns all file uploader services based on config\n * @returns Object containing all specialized file uploader services\n */\nexport const getFileUploaderServices = () => {\n const { fileUpload } = getArkosConfig();\n const baseUploadDir = fileUpload?.baseUploadDir || \"/uploads\";\n\n // Default regex patterns for each file type\n const defaultRegexPatterns = {\n images:\n /jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif|heic|ico|jfif|raw|cr2|nef|orf|sr2|arw|dng|pef|raf|rw2|psd|ai|eps|xcf|jxr|wdp|hdp|jp2|j2k|jpf|jpx|jpm|mj2|avif/,\n videos:\n /mp4|avi|mov|mkv|flv|wmv|webm|mpg|mpeg|3gp|m4v|ts|rm|rmvb|vob|ogv|dv|qt|asf|m2ts|mts|divx|f4v|swf|mxf|roq|nsv|mvb|svi|mpe|m2v|mp2|mpv|h264|h265|hevc/,\n documents:\n /pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odg|odp|txt|rtf|csv|epub|md|tex|pages|numbers|key|xml|json|yaml|yml|ini|cfg|conf|log|html|htm|xhtml|djvu|mobi|azw|azw3|fb2|lit|ps|wpd|wps|dot|dotx|xlt|xltx|pot|potx|oft|one|onetoc2|opf|oxps|hwp/,\n files: /.*/,\n };\n\n // Default upload restrictions\n const defaultRestrictions = {\n images: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 15, // 15 MB\n supportedFilesRegex:\n /jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif|heic|ico|jfif|raw|cr2|nef|orf|sr2|arw|dng|pef|raf|rw2|psd|ai|eps|xcf|jxr|wdp|hdp|jp2|j2k|jpf|jpx|jpm|mj2|avif/,\n },\n videos: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex:\n /mp4|avi|mov|mkv|flv|wmv|webm|mpg|mpeg|3gp|m4v|ts|rm|rmvb|vob|ogv|dv|qt|asf|m2ts|mts|divx|f4v|swf|mxf|roq|nsv|mvb|svi|mpe|m2v|mp2|mpv|h264|h265|hevc/,\n },\n documents: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 50, // 50 MB\n supportedFilesRegex:\n /pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odg|odp|txt|rtf|csv|epub|md|tex|pages|numbers|key|xml|json|yaml|yml|ini|cfg|conf|log|html|htm|xhtml|djvu|mobi|azw|azw3|fb2|lit|ps|wpd|wps|dot|dotx|xlt|xltx|pot|potx|oft|one|onetoc2|opf|oxps|hwp/,\n },\n files: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex: /.*/,\n },\n };\n\n // Merge with user configuration (if any)\n const restrictions = fileUpload?.restrictions\n ? deepmerge(defaultRestrictions, fileUpload.restrictions)\n : defaultRestrictions;\n\n /**\n * Specialized file uploader service for handling image uploads.\n */\n const imageUploaderService = new FileUploaderService(\n `${baseUploadDir}/images`,\n restrictions.images.maxSize,\n restrictions.images.supportedFilesRegex,\n restrictions.images.maxCount\n );\n\n /**\n * Specialized file uploader service for handling video uploads.\n */\n const videoUploaderService = new FileUploaderService(\n `${baseUploadDir}/videos`,\n restrictions.videos.maxSize,\n restrictions.videos.supportedFilesRegex,\n restrictions.videos.maxCount\n );\n\n /**\n * Specialized file uploader service for handling document uploads.\n */\n const documentUploaderService = new FileUploaderService(\n `${baseUploadDir}/documents`,\n restrictions.documents.maxSize,\n restrictions.documents.supportedFilesRegex,\n restrictions.documents.maxCount\n );\n\n /**\n * Generic file uploader service for handling all file uploads.\n */\n const fileUploaderService = new FileUploaderService(\n `${baseUploadDir}/files`,\n restrictions.files.maxSize,\n restrictions.files.supportedFilesRegex,\n restrictions.files.maxCount\n );\n\n return {\n imageUploaderService,\n videoUploaderService,\n documentUploaderService,\n fileUploaderService,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"file-uploader.service.js","sourceRoot":"","sources":["../../../../src/modules/file-uploader/file-uploader.service.ts"],"names":[],"mappings":"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","sourcesContent":["import multer, { StorageEngine } from \"multer\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { NextFunction } from \"express\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { promisify } from \"util\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { ArkosRequest, ArkosResponse } from \"../../types\";\nimport {\n processFile,\n processImage,\n} from \"./utils/helpers/file-uploader.helpers\";\nimport { removeBothSlashes } from \"../../utils/helpers/text.helpers\";\n\n/**\n * Service to handle file uploads, including single and multiple file uploads,\n * file validation (type, size), and file deletion.\n */\nexport class FileUploaderService {\n public readonly uploadDir: string;\n private fileSizeLimit: number;\n private allowedFileTypes: RegExp;\n private storage: StorageEngine;\n private maxCount: number;\n\n /**\n * Constructor to initialize the file uploader service.\n * @param {string} uploadDir - The directory where files will be uploaded.\n * @param {number} fileSizeLimit - The maximum allowed file size.\n * @param {RegExp} allowedFileTypes - The regular expression for allowed file types.\n */\n constructor(\n uploadDir: string,\n fileSizeLimit: number = 1024 * 1024 * 5,\n allowedFileTypes: RegExp = /.*/,\n maxCount: number = 30\n ) {\n uploadDir = uploadDir.startsWith(\"/\") ? uploadDir.substring(1) : uploadDir;\n uploadDir = uploadDir.endsWith(\"/\") ? uploadDir.slice(0, -1) : uploadDir;\n\n this.uploadDir = path.resolve(process.cwd(), `${uploadDir}/`);\n this.fileSizeLimit = fileSizeLimit;\n this.allowedFileTypes = allowedFileTypes;\n this.maxCount = maxCount;\n\n if (!fs.existsSync(this.uploadDir)) {\n fs.mkdirSync(this.uploadDir, { recursive: true });\n }\n\n this.storage = multer.diskStorage({\n destination: (req, file, cb) => {\n cb(null, this.uploadDir);\n },\n filename: (req, file, cb) => {\n const uniqueSuffix = Date.now() + \"-\" + Math.round(Math.random() * 1e9);\n cb(null, `${uniqueSuffix}${path.extname(file.originalname)}`);\n },\n });\n }\n\n /**\n * Validates the file's type and MIME type.\n * @param {Request} req - The Express request object.\n * @param {Express.Multer.File} file - The uploaded file.\n * @param {Function} cb - The callback function to indicate if file is valid.\n */\n private fileFilter = (req: any, file: any, cb: any) => {\n const extName = this.allowedFileTypes.test(\n path.extname(file.originalname).toLowerCase()\n );\n const mimeType = this.allowedFileTypes.test(file.mimetype);\n\n if (mimeType && extName) {\n cb(null, true);\n } else {\n cb(new AppError(\"Invalid file type\", 400));\n }\n };\n\n /**\n * Returns the multer upload configuration.\n * @returns {multer.Instance} The multer instance configured for file uploads.\n */\n public getUploader() {\n return multer({\n storage: this.storage,\n fileFilter: this.fileFilter,\n limits: { fileSize: this.fileSizeLimit },\n });\n }\n\n /**\n * Middleware to handle single file upload.\n * @param {string} [oldFilePath] - The path to the file to delete before uploading.\n * @returns {Function} Middleware function for handling file upload.\n */\n public handleSingleUpload(oldFilePath?: string) {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUploader().single(this.getFieldName());\n upload(req, res, async (err) => {\n if (err instanceof multer.MulterError) {\n return next(err);\n } else if (err) {\n return next(err);\n }\n\n if (oldFilePath) {\n const { fileUpload: configs } = getArkosConfig();\n\n const filePath = path.resolve(\n process.cwd(),\n removeBothSlashes(configs?.baseUploadDir!),\n removeBothSlashes(oldFilePath)\n );\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) await promisify(fs.unlink)(filePath);\n } catch (err) {\n console.error(err);\n }\n }\n\n next();\n });\n };\n }\n\n /**\n * Middleware to handle multiple file uploads.\n * @param {number} maxCount - The maximum number of files allowed for upload.\n * @returns {Function} Middleware function for handling multiple file uploads.\n */\n public handleMultipleUpload() {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUploader().array(\n this.getFieldName(),\n this.maxCount\n );\n upload(req, res, (err) => {\n if (err instanceof multer.MulterError) return next(err);\n else if (err) return next(err);\n next();\n });\n };\n }\n\n /**\n * Middleware to handle deletion of a single file from the filesystem.\n * @param {string} oldFilePath - The path to the file to be deleted.\n * @returns {Function} Middleware function for handling file deletion.\n */\n public handleDeleteSingleFile(oldFilePath: string) {\n return async (\n req: ArkosRequest,\n res: ArkosResponse,\n next: NextFunction\n ) => {\n const filePath = path.join(oldFilePath);\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) {\n await promisify(fs.unlink)(filePath);\n }\n } catch (err) {\n console.error(err);\n }\n\n next();\n };\n }\n\n /**\n * Deletes a file based on its URL by identifying the appropriate uploader service\n * @param {string} fileUrl - The URL of the file to delete\n * @returns {Promise<boolean>} - True if deletion successful, false otherwise\n */\n public async deleteFileByUrl(fileUrl: string): Promise<boolean> {\n try {\n // Get configuration values\n const { fileUpload } = getArkosConfig();\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n\n // Parse the URL to get the path\n let urlPath: string;\n if (fileUrl.startsWith(\"http\")) {\n const url = new URL(fileUrl);\n urlPath = url.pathname;\n } else {\n urlPath = fileUrl;\n }\n\n // Extract the path after the base route\n const baseRouteIndex = urlPath.indexOf(baseRoute);\n if (baseRouteIndex === -1) {\n throw new AppError(\"Invalid file URL: base route not found\", 400);\n }\n\n const pathAfterBaseRoute = urlPath.substring(\n baseRouteIndex + baseRoute.length\n );\n const cleanPath = pathAfterBaseRoute.startsWith(\"/\")\n ? pathAfterBaseRoute.substring(1)\n : pathAfterBaseRoute;\n\n // Determine file type and file name\n const fileTypes = [\"images\", \"videos\", \"documents\", \"files\"];\n let fileType: string | null = null;\n let fileName: string | null = null;\n\n for (const type of fileTypes) {\n const typeIndex = cleanPath.indexOf(type + \"/\");\n if (typeIndex !== -1) {\n fileType = type;\n fileName = cleanPath.substring(typeIndex + type.length + 1);\n break;\n }\n }\n\n if (!fileType || !fileName) {\n throw new AppError(\n \"Unable to determine file type or file name from URL\",\n 400\n );\n }\n\n // Get the appropriate uploader service based on file type\n const {\n documentUploaderService,\n fileUploaderService,\n imageUploaderService,\n videoUploaderService,\n } = getFileUploaderServices();\n\n let filePath: string;\n switch (fileType) {\n case \"images\":\n filePath = path.join(imageUploaderService.uploadDir, fileName);\n break;\n case \"videos\":\n filePath = path.join(videoUploaderService.uploadDir, fileName);\n break;\n case \"documents\":\n filePath = path.join(documentUploaderService.uploadDir, fileName);\n break;\n case \"files\":\n filePath = path.join(fileUploaderService.uploadDir, fileName);\n break;\n default:\n throw new AppError(`Unsupported file type: ${fileType}`, 400);\n }\n\n // Delete the file\n\n await promisify(fs.stat)(filePath);\n await promisify(fs.unlink)(filePath);\n\n return true;\n } catch (error: any) {\n if (error instanceof AppError) {\n throw error;\n }\n\n if (error.code === \"ENOENT\") {\n throw new AppError(\"File not found\", 404);\n }\n\n throw new AppError(`Failed to delete file: ${error.message}`, 500);\n }\n }\n\n private getFieldName() {\n let fieldName = \"files\";\n if (this.uploadDir.endsWith(\"images\") || this.uploadDir.endsWith(\"images/\"))\n fieldName = \"images\";\n if (this.uploadDir.endsWith(\"videos\") || this.uploadDir.endsWith(\"videos/\"))\n fieldName = \"videos\";\n if (\n this.uploadDir.endsWith(\"documents\") ||\n this.uploadDir.endsWith(\"documents/\")\n )\n fieldName = \"documents\";\n if (this.uploadDir.endsWith(\"files\") || this.uploadDir.endsWith(\"files/\"))\n fieldName = \"files\";\n return fieldName;\n }\n\n /**\n * Handles the upload process and returns the full URLs of uploaded files\n * @param {ArkosRequest} req - Arkos request object containing the files\n * @param {ArkosResponse} res - Arkos response object\n * @param {object} options - Optional parameters for image processing\n * @returns {Promise<string|string[]>} URL or array of URLs to the uploaded files\n */\n public async upload(\n req: ArkosRequest,\n res: ArkosResponse,\n options: {\n format?: string;\n width?: number;\n height?: number;\n resizeTo?: number;\n } = {}\n ): Promise<string | string[] | null> {\n const { fileUpload } = getArkosConfig();\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n\n return new Promise((resolve, reject) => {\n // Determine if it's a single or multiple file upload\n const isMultiple = Array.isArray(req.query.multiple)\n ? req.query.multiple[0] == \"true\"\n : req.query.multiple == \"true\";\n\n // Use appropriate upload handler\n const uploadHandler = isMultiple\n ? this.getUploader().array(this.getFieldName(), this.maxCount)\n : this.getUploader().single(this.getFieldName());\n\n uploadHandler(req, res, async (err) => {\n if (err) return reject(err);\n\n try {\n // Determine the base URL for file access\n const protocol = req.get(\"host\")?.includes?.(\"localhost\")\n ? \"http\"\n : \"https\";\n const baseURL = `${protocol}://${req.get(\"host\")}`;\n\n // Get file type from uploadDir path\n const dirParts = this.uploadDir.split(\"/\");\n const fileType =\n (this.uploadDir.endsWith(\"/\")\n ? dirParts[dirParts.length - 2]\n : dirParts[dirParts.length - 1]) || \"files\";\n\n // Process all uploaded files\n let data;\n if (req.files && Array.isArray(req.files) && req.files.length > 0) {\n // Process multiple files\n const isImageUploader = this.uploadDir?.includes?.(\"/images\");\n if (isImageUploader) {\n data = await Promise.all(\n req.files.map((file) => processImage(req, file.path, options))\n );\n } else {\n data = await Promise.all(\n req.files.map((file) => processFile(req, file.path))\n );\n }\n // Filter out any null values from failed processing\n data = data.filter((url) => url !== null);\n } else if (req.file) {\n // Process a single file\n const isImageUploader = this.uploadDir?.includes?.(\"/images\");\n if (isImageUploader) {\n data = await processImage(req, req.file.path, options);\n } else {\n data = await processFile(req, req.file.path);\n }\n } else {\n return reject(new AppError(\"No file uploaded\", 400));\n }\n\n resolve(data);\n } catch (error) {\n reject(error);\n }\n });\n });\n }\n}\n\n/**\n * Creates and returns all file uploader services based on config\n * @returns Object containing all specialized file uploader services\n */\nexport const getFileUploaderServices = () => {\n const { fileUpload } = getArkosConfig();\n const baseUploadDir = fileUpload?.baseUploadDir || \"/uploads\";\n\n // Default regex patterns for each file type\n const defaultRegexPatterns = {\n images:\n /jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif|heic|ico|jfif|raw|cr2|nef|orf|sr2|arw|dng|pef|raf|rw2|psd|ai|eps|xcf|jxr|wdp|hdp|jp2|j2k|jpf|jpx|jpm|mj2|avif/,\n videos:\n /mp4|avi|mov|mkv|flv|wmv|webm|mpg|mpeg|3gp|m4v|ts|rm|rmvb|vob|ogv|dv|qt|asf|m2ts|mts|divx|f4v|swf|mxf|roq|nsv|mvb|svi|mpe|m2v|mp2|mpv|h264|h265|hevc/,\n documents:\n /pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odg|odp|txt|rtf|csv|epub|md|tex|pages|numbers|key|xml|json|yaml|yml|ini|cfg|conf|log|html|htm|xhtml|djvu|mobi|azw|azw3|fb2|lit|ps|wpd|wps|dot|dotx|xlt|xltx|pot|potx|oft|one|onetoc2|opf|oxps|hwp/,\n files: /.*/,\n };\n\n // Default upload restrictions\n const defaultRestrictions = {\n images: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 15, // 15 MB\n supportedFilesRegex:\n /jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif|heic|ico|jfif|raw|cr2|nef|orf|sr2|arw|dng|pef|raf|rw2|psd|ai|eps|xcf|jxr|wdp|hdp|jp2|j2k|jpf|jpx|jpm|mj2|avif/,\n },\n videos: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex:\n /mp4|avi|mov|mkv|flv|wmv|webm|mpg|mpeg|3gp|m4v|ts|rm|rmvb|vob|ogv|dv|qt|asf|m2ts|mts|divx|f4v|swf|mxf|roq|nsv|mvb|svi|mpe|m2v|mp2|mpv|h264|h265|hevc/,\n },\n documents: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 50, // 50 MB\n supportedFilesRegex:\n /pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odg|odp|txt|rtf|csv|epub|md|tex|pages|numbers|key|xml|json|yaml|yml|ini|cfg|conf|log|html|htm|xhtml|djvu|mobi|azw|azw3|fb2|lit|ps|wpd|wps|dot|dotx|xlt|xltx|pot|potx|oft|one|onetoc2|opf|oxps|hwp/,\n },\n files: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex: /.*/,\n },\n };\n\n // Merge with user configuration (if any)\n const restrictions = fileUpload?.restrictions\n ? deepmerge(defaultRestrictions, fileUpload.restrictions)\n : defaultRestrictions;\n\n /**\n * Specialized file uploader service for handling image uploads.\n */\n const imageUploaderService = new FileUploaderService(\n `${baseUploadDir}/images`,\n restrictions.images.maxSize,\n restrictions.images.supportedFilesRegex,\n restrictions.images.maxCount\n );\n\n /**\n * Specialized file uploader service for handling video uploads.\n */\n const videoUploaderService = new FileUploaderService(\n `${baseUploadDir}/videos`,\n restrictions.videos.maxSize,\n restrictions.videos.supportedFilesRegex,\n restrictions.videos.maxCount\n );\n\n /**\n * Specialized file uploader service for handling document uploads.\n */\n const documentUploaderService = new FileUploaderService(\n `${baseUploadDir}/documents`,\n restrictions.documents.maxSize,\n restrictions.documents.supportedFilesRegex,\n restrictions.documents.maxCount\n );\n\n /**\n * Generic file uploader service for handling all file uploads.\n */\n const fileUploaderService = new FileUploaderService(\n `${baseUploadDir}/files`,\n restrictions.files.maxSize,\n restrictions.files.supportedFilesRegex,\n restrictions.files.maxCount\n );\n\n return {\n imageUploaderService,\n videoUploaderService,\n documentUploaderService,\n fileUploaderService,\n };\n};\n"]}
|
|
@@ -21,10 +21,12 @@ const util_1 = require("util");
|
|
|
21
21
|
const server_1 = require("../../../../server");
|
|
22
22
|
const mimetype_1 = __importDefault(require("mimetype"));
|
|
23
23
|
function extractRequestInfo(req) {
|
|
24
|
-
var _a, _b, _c;
|
|
24
|
+
var _a, _b, _c, _d;
|
|
25
25
|
const { fileUpload } = (0, server_1.getArkosConfig)();
|
|
26
|
-
const protocol = ((_b = (_a = req.get) === null || _a === void 0 ? void 0 : _a.call(req, "host")) === null || _b === void 0 ? void 0 : _b.includes
|
|
27
|
-
|
|
26
|
+
const protocol = ((_c = (_b = (_a = req.get) === null || _a === void 0 ? void 0 : _a.call(req, "host")) === null || _b === void 0 ? void 0 : _b.includes) === null || _c === void 0 ? void 0 : _c.call(_b, "localhost"))
|
|
27
|
+
? "http"
|
|
28
|
+
: "https";
|
|
29
|
+
const baseURL = `${protocol}://${(_d = req.get) === null || _d === void 0 ? void 0 : _d.call(req, "host")}`;
|
|
28
30
|
const baseRoute = (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseRoute) || "/api/uploads";
|
|
29
31
|
return { baseURL, baseRoute };
|
|
30
32
|
}
|
|
@@ -47,12 +49,12 @@ const processFile = (req, filePath) => __awaiter(void 0, void 0, void 0, functio
|
|
|
47
49
|
});
|
|
48
50
|
exports.processFile = processFile;
|
|
49
51
|
const processImage = (req, filePath, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
-
var _a;
|
|
52
|
+
var _a, _b;
|
|
51
53
|
const { baseURL, baseRoute } = extractRequestInfo(req);
|
|
52
54
|
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
53
55
|
const originalFormat = ext.replace(".", "");
|
|
54
56
|
const outputFormat = options.format || originalFormat;
|
|
55
|
-
if (!((_a = mimetype_1.default.lookup(ext)) === null || _a === void 0 ? void 0 : _a.includes("image"))) {
|
|
57
|
+
if (!((_b = (_a = mimetype_1.default.lookup(ext)) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, "image"))) {
|
|
56
58
|
const relativePath = generateRelativePath(filePath, req.params.fileType);
|
|
57
59
|
return `${baseURL}${baseRoute}/${relativePath}`;
|
|
58
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-uploader.helpers.js","sourceRoot":"","sources":["../../../../../../src/modules/file-uploader/utils/helpers/file-uploader.helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAQA,
|
|
1
|
+
{"version":3,"file":"file-uploader.helpers.js","sourceRoot":"","sources":["../../../../../../src/modules/file-uploader/utils/helpers/file-uploader.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport sharp from \"sharp\";\nimport { promisify } from \"util\";\nimport { getArkosConfig } from \"../../../../server\";\nimport mimetype from \"mimetype\";\nimport { ArkosRequest } from \"../../../../types\";\n\nexport function extractRequestInfo(req: Partial<ArkosRequest>) {\n const { fileUpload } = getArkosConfig();\n\n // Determine the base URL for file access\n const protocol = req.get?.(\"host\")?.includes?.(\"localhost\")\n ? \"http\"\n : \"https\";\n const baseURL = `${protocol}://${req.get?.(\"host\")}`;\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n return { baseURL, baseRoute };\n}\n\n/**\n * Generates the correct relative path regardless of upload directory location\n */\nconst generateRelativePath = (filePath: string, fileType: string) => {\n const { fileUpload } = getArkosConfig();\n\n const baseUploadDir = fileUpload?.baseUploadDir || \"/uploads\";\n if (baseUploadDir.startsWith(\"..\")) {\n // For paths outside project directory\n return path.join(fileType, path.basename(filePath));\n } else {\n // For paths within project\n return filePath\n .replace(`${baseUploadDir}/`, \"\")\n .replace(process.cwd() + \"/\", \"\");\n }\n};\n\n/**\n * Handles basic file processing for non-image files\n */\nexport const processFile = async (\n req: Partial<ArkosRequest>,\n filePath: string\n): Promise<string> => {\n const { baseURL, baseRoute } = extractRequestInfo(req);\n\n const relativePath = generateRelativePath(filePath, req.params!.fileType);\n return `${baseURL}${baseRoute === \"/\" ? \"\" : baseRoute}/${relativePath}`;\n};\n\n/**\n * Processes image files using Sharp for resizing and format conversion\n */\nexport const processImage = async (\n req: Partial<ArkosRequest>,\n filePath: string,\n options: Record<string, any>\n): Promise<string | null> => {\n const { baseURL, baseRoute } = extractRequestInfo(req);\n\n const ext = path.extname(filePath).toLowerCase();\n const originalFormat = ext.replace(\".\", \"\");\n const outputFormat = options.format || originalFormat;\n\n if (!mimetype.lookup(ext)?.includes?.(\"image\")) {\n const relativePath = generateRelativePath(filePath, req.params!.fileType);\n return `${baseURL}${baseRoute}/${relativePath}`;\n }\n\n // Create a temp filename with original name + random string\n const tempName = `${path.basename(filePath, ext)}_${Date.now()}${ext}`;\n const tempPath = path.join(path.dirname(filePath), tempName);\n\n try {\n let transformer = sharp(filePath);\n const metadata = await transformer.metadata();\n\n // Apply resize transformations if requested\n if (options.resizeTo && metadata.width && metadata.height) {\n const targetSize = options.resizeTo;\n const scaleFactor =\n targetSize / Math.min(metadata.width, metadata.height);\n const newWidth = Math.round(metadata.width * scaleFactor);\n const newHeight = Math.round(metadata.height * scaleFactor);\n transformer = transformer.resize(newWidth, newHeight);\n } else if (options.width || options.height) {\n transformer = transformer.resize(\n options.width || null,\n options.height || null,\n {\n fit: \"inside\",\n }\n );\n }\n\n // Apply format transformations if requested\n if (outputFormat === \"webp\") {\n transformer = transformer.toFormat(\"webp\");\n } else if (outputFormat === \"jpeg\" || outputFormat === \"jpg\") {\n transformer = transformer.toFormat(\"jpeg\");\n }\n\n // Save to temp file first\n await transformer.toFile(tempPath);\n\n // Rename temp file to original filename\n await promisify(fs.rename)(tempPath, filePath);\n\n // Return the public URL for the file\n const relativePath = generateRelativePath(filePath, req?.params!.fileType);\n\n return `${baseURL}${baseRoute}/${relativePath}`;\n } catch (error) {\n // Clean up temp file if it exists\n try {\n await promisify(fs.stat)(tempPath);\n await promisify(fs.unlink)(tempPath);\n } catch (err) {\n // If temp file doesn't exist, no need to clean up\n }\n throw error;\n }\n};\n"]}
|
package/dist/cjs/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var __awaiter=this&&this.__awaiter||function(e,t,n,s){function u(r){return r instanceof n?r:new n(function(i){i(r)})}return new(n||(n=Promise))(function(r,i){function l(o){try{p(s.next(o))}catch(c){i(c)}}function a(o){try{p(s.throw(o))}catch(c){i(c)}}function p(o){o.done?r(o.value):u(o.value).then(l,a)}p((s=s.apply(e,t||[])).next())})},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.server=void 0,exports.getArkosConfig=getArkosConfig,exports.getExpressApp=getExpressApp,exports.initApp=initApp;const app_1=require("./app"),deepmerge_helper_1=__importDefault(require("./utils/helpers/deepmerge.helper"));process.on("uncaughtException",e=>{console.error("UNCAUGHT EXCEPTION! SHUTTING DOWN..."),console.error(e.name,e.message),console.error(e),process.exit(1)});let server,_app,_arkosConfig={welcomeMessage:"Welcome to our RESTful API generated by Arkos, find out more about Arkos at www.arkosjs.com",port:8e3,fileUpload:{baseUploadDir:"uploads",baseRoute:"/api/uploads"}};function initApp(){return __awaiter(this,arguments,void 0,function*(e={}){_arkosConfig=(0,deepmerge_helper_1.default)(_arkosConfig,e);const t=_arkosConfig.port;return _app=yield(0,app_1.bootstrap)(_arkosConfig),t&&(exports.server=server=_app.listen(e?.host?[t,e?.host]:t,()=>{const n=new Date().toTimeString().split(" ")[0];console.info(`[\x1B[32mREADY\x1B[0m] \x1B[90m${n}\x1B[0m App running on port \x1B[33m${t}\x1B[0m, server waiting on http://localhost:${t}`),process.env.NODE_ENV&&console.info(`${`Environment: ${process.env.NODE_ENV}`}`)})),_app})}process.on("unhandledRejection",e=>{console.error("UNHANDLED REJECTION! SHUTTING DOWN..."),console.error(e.name,e.message),server.close(()=>{process.exit(1)})});function getArkosConfig(){return _arkosConfig}function getExpressApp(){return _app}
|
|
1
|
+
"use strict";var __awaiter=this&&this.__awaiter||function(e,t,n,s){function u(r){return r instanceof n?r:new n(function(i){i(r)})}return new(n||(n=Promise))(function(r,i){function l(o){try{p(s.next(o))}catch(c){i(c)}}function a(o){try{p(s.throw(o))}catch(c){i(c)}}function p(o){o.done?r(o.value):u(o.value).then(l,a)}p((s=s.apply(e,t||[])).next())})},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.server=void 0,exports.getArkosConfig=getArkosConfig,exports.getExpressApp=getExpressApp,exports.initApp=initApp;const app_1=require("./app"),deepmerge_helper_1=__importDefault(require("./utils/helpers/deepmerge.helper"));process.on("uncaughtException",e=>{console.error("UNCAUGHT EXCEPTION! SHUTTING DOWN..."),console.error(e.name,e.message),console.error(e),process.exit(1)});let server,_app,_arkosConfig={welcomeMessage:"Welcome to our RESTful API generated by Arkos, find out more about Arkos at www.arkosjs.com",port:8e3,fileUpload:{baseUploadDir:"uploads",baseRoute:"/api/uploads"}};function initApp(){return __awaiter(this,arguments,void 0,function*(e={}){_arkosConfig=(0,deepmerge_helper_1.default)(_arkosConfig,e);const t=_arkosConfig.port;return _app=yield(0,app_1.bootstrap)(_arkosConfig),t&&(exports.server=server=_app.listen(e?.host?[t,e?.host]:t,()=>{const n=new Date().toTimeString().split(" ")[0];console.info(`[\x1B[32mREADY\x1B[0m] \x1B[90m${n}\x1B[0m App running on port \x1B[33m${t}\x1B[0m, server waiting on http://localhost:${t}`),process.env.NODE_ENV&&console.info(`${`Environment: ${process.env.NODE_ENV}`}`)})),_app})}process.on("unhandledRejection",e=>{console.error("UNHANDLED REJECTION! SHUTTING DOWN..."),console.error(e.name,e.message),console.error(e),server.close(()=>{process.exit(1)})});function getArkosConfig(){return _arkosConfig}function getExpressApp(){return _app}
|
package/dist/cjs/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAwEA,wCAEC;AAED,sCAEC;AAEgB,0BAAO;AA7ExB,+BAAkC;AAElC,wFAAyD;AAEzD,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,IAAI,MAA6D,CAAC;AAClE,IAAI,IAAa,CAAC;AAElB,IAAI,YAAY,GAAgB;IAC9B,cAAc,EACZ,6FAA6F;IAC/F,IAAI,EAAE,IAAI;IACV,UAAU,EAAE;QACV,aAAa,EAAE,SAAS;QACxB,SAAS,EAAE,cAAc;KAC1B;CACF,CAAC;AAeF,SAAe,OAAO;yDAAC,cAA2B,EAAE;QAClD,YAAY,GAAG,IAAA,0BAAS,EAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAEpD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;QAC/B,IAAI,GAAG,MAAM,IAAA,eAAS,EAAC,YAAY,CAAC,CAAC;QAErC,IAAI,IAAI;YACN,iBAAA,MAAM,GAAG,IAAI,CAAC,MAAM,CAClB,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,EAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EACrD,GAAG,EAAE;gBACH,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrD,OAAO,CAAC,IAAI,CACV,kCAAkC,IAAI,uCAAuC,IAAI,+CAA+C,IAAI,EAAE,CACvI,CAAC;gBAEF,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ;oBACxB,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC9D,CAAC,CACF,CAAC;QAEJ,OAAO,IAAI,CAAC;IACd,CAAC;CAAA;AAED,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,GAAa,EAAE,EAAE;IACjD,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACvD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAgB,cAAc;IAC5B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { IncomingMessage, Server, ServerResponse } from \"http\";\nimport AppError from \"./modules/error-handler/utils/app-error\";\nimport { Express } from \"express\";\nimport { bootstrap } from \"./app\";\nimport { ArkosConfig } from \"./types/arkos-config\";\nimport deepmerge from \"./utils/helpers/deepmerge.helper\";\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(\"UNCAUGHT EXCEPTION! SHUTTING DOWN...\");\n console.error(err.name, err.message);\n console.error(err);\n process.exit(1);\n});\n\nlet server: Server<typeof IncomingMessage, typeof ServerResponse>;\nlet _app: Express;\n\nlet _arkosConfig: ArkosConfig = {\n welcomeMessage:\n \"Welcome to our RESTful API generated by Arkos, find out more about Arkos at www.arkosjs.com\",\n port: 8000,\n fileUpload: {\n baseUploadDir: \"uploads\",\n baseRoute: \"/api/uploads\",\n },\n};\n\n/**\n * Initializes the application server.\n *\n * This function starts the server by listening on a specified port.\n * The port is determined by the following order of precedence:\n * 1. The `port` argument passed to the function.\n * 2. Defaults to `8000` if neither is provided.\n *\n * @param {ArkosConfig} arkosConfig - initial configs for the api ( authentication, port).\n * @returns {Promise<Express>} This function returns the Express App after all middlewares configurations.\n * You can prevent it from listen py passing port as undefined\n *\n */\nasync function initApp(arkosConfig: ArkosConfig = {}): Promise<Express> {\n _arkosConfig = deepmerge(_arkosConfig, arkosConfig);\n\n const port = _arkosConfig.port;\n _app = await bootstrap(_arkosConfig);\n\n if (port)\n server = _app.listen(\n arkosConfig?.host ? [port, arkosConfig?.host!] : port,\n () => {\n const time = new Date().toTimeString().split(\" \")[0];\n console.info(\n `[\\x1b[32mREADY\\x1b[0m] \\x1b[90m${time}\\x1b[0m App running on port \\x1b[33m${port}\\x1b[0m, server waiting on http://localhost:${port}`\n );\n\n if (!!process.env.NODE_ENV)\n console.info(`${`Environment: ${process.env.NODE_ENV}`}`);\n }\n );\n\n return _app;\n}\n\nprocess.on(\"unhandledRejection\", (err: AppError) => {\n console.error(\"UNHANDLED REJECTION! SHUTTING DOWN...\");\n console.error(err.name, err.message);\n console.error(err);\n server.close(() => {\n process.exit(1);\n });\n});\n\nexport function getArkosConfig() {\n return _arkosConfig;\n}\n\nexport function getExpressApp() {\n return _app;\n}\n\nexport { server, initApp };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/types/auth.ts"],"names":[],"mappings":"","sourcesContent":["import { JwtPayload } from \"jsonwebtoken\";\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/types/auth.ts"],"names":[],"mappings":"","sourcesContent":["import { JwtPayload } from \"jsonwebtoken\";\n\n/**\n * Base set of controller actions available to all controllers.\n */\nexport type BaseControllerActions = \"create\" | \"update\" | \"delete\" | \"view\";\n\n/**\n * Extends the base controller actions with custom actions.\n *\n * @typeParam T - Additional action types that extend the base actions.\n */\nexport type ExtendedControllerActions<T extends string = never> =\n | BaseControllerActions\n | T;\n\n/**\n * Rules defining access control for different controller actions.\n *\n * @typeParam T - Additional action types that extend the base actions.\n * @typeParam Role - A type representing a role or set of roles allowed to perform the action.\n */\nexport type AccessControlRules<T extends string = never> = {\n /**\n * Maps each controller action to the roles allowed to perform it.\n */\n [key in ExtendedControllerActions<T>]: any[];\n};\n\n/**\n * Rules defining authentication requirements for different controller actions.\n *\n * @typeParam T - Additional action types that extend the base actions.\n */\nexport type AuthenticationControlRules<T extends string = never> = {\n /**\n * Maps each controller action to whether authentication is required to perform it.\n */\n [key in ExtendedControllerActions<T>]: boolean;\n};\n\n/**\n * Configuration for authentication and access control.\n *\n * @typeParam T - Additional action types that extend the base actions.\n */\nexport type AuthConfigs<T extends string = never> = {\n /**\n * Defines authentication requirements for actions.\n * - When boolean: applies to all actions\n * - When partial rules: applies to specified actions\n *\n * @type {boolean | Partial<AuthenticationControlRules<T>>}\n */\n authenticationControl?: boolean | Partial<AuthenticationControlRules<T>>;\n\n /**\n * Defines role-based access control.\n * - When array: list of roles allowed for all actions\n * - When partial rules: specific roles for each action\n *\n * @type {any[] | Partial<AccessControlRules<T>>}\n */\n accessControl?: any[] | Partial<AccessControlRules<T>>;\n};\n\n/**\n * Payload structure for JWT-based authentication, extending the standard `JwtPayload`.\n */\nexport interface AuthJwtPayload extends JwtPayload {\n /**\n * The unique identifier of the authenticated user.\n *\n * @type {number | string}\n */\n id?: number | string;\n\n /**\n * Additional properties can be added to the payload.\n */\n [x: string]: any;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":";;;AAuCA,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,yCAAiB,CAAA;IACjB,qCAAa,CAAA;IACb,yCAAiB,CAAA;IACjB,yCAAiB,CAAA;AACnB,CAAC,EALW,oBAAoB,oCAApB,oBAAoB,QAK/B","sourcesContent":["import { Prisma } from \"@prisma/client\";\nimport { NextFunction, Request, RequestHandler, Response } from \"express\";\n\nexport type PrismaOperations = \"findMany\";\n\nexport type PrismaQueryOptions<T> = {\n queryOptions?: Omit<\n Prisma.Args<T, \"findMany\">,\n \"where\" | \"cursor\" | \"take\" | \"skip\" | \"orderBy\"\n >;\n findOne?: Partial<Partial<Prisma.Args<T, \"findUnique\">>>;\n findMany?: Partial<Prisma.Args<T, \"findMany\">>;\n deleteMany?: Partial<Prisma.Args<T, \"deleteMany\">>;\n updateMany?: Partial<Prisma.Args<T, \"updateMany\">>;\n createMany?: Partial<Prisma.Args<T, \"createMany\">>;\n createOne?: Partial<Prisma.Args<T, \"create\">>;\n updateOne?: Partial<Prisma.Args<T, \"update\">>;\n deleteOne?: Partial<Prisma.Args<T, \"delete\">>;\n};\n\nexport interface UserRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n roleId: string;\n role: AuthRole;\n user: User;\n userId: string;\n}\n\nexport interface AuthRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n name: string;\n permissions: AuthPermission[];\n userRoles: UserRole[];\n}\n\nexport enum AuthPermissionAction {\n create = \"create\",\n view = \"view\",\n update = \"update\",\n delete = \"delete\",\n}\n\nexport interface AuthPermission {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n resource: string;\n action: AuthPermissionAction;\n roleId: string;\n role: AuthRole;\n}\n\nexport interface User {\n id: string;\n isStaff: boolean;\n isSuperUser: boolean;\n password: string;\n passwordChangedAt?: Date;\n deletedSelfAccountAt: Date;\n isActive: boolean;\n roles?: UserRole[] | any[];\n role?: UserRole | any;\n}\n\nexport interface ArkosRequest extends Request {\n user?: User & Record<string, any>;\n relationFields?: Record<string, boolean>;\n include?: Record<string, any>;\n responseData?: Record<string, any> | null | undefined;\n additionalData?: Record<string, any> | null | undefined;\n responseStatus?: number | string | null | undefined;\n}\n\nexport interface ArkosResponse extends Response {}\nexport interface ArkosNextFunction extends NextFunction {}\nexport interface ArkosRequestHandler extends RequestHandler {}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":";;;AAuCA,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,yCAAiB,CAAA;IACjB,qCAAa,CAAA;IACb,yCAAiB,CAAA;IACjB,yCAAiB,CAAA;AACnB,CAAC,EALW,oBAAoB,oCAApB,oBAAoB,QAK/B","sourcesContent":["import { Prisma } from \"@prisma/client\";\nimport { NextFunction, Request, RequestHandler, Response } from \"express\";\n\nexport type PrismaOperations = \"findMany\";\n\nexport type PrismaQueryOptions<T> = {\n queryOptions?: Omit<\n Prisma.Args<T, \"findMany\">,\n \"where\" | \"cursor\" | \"take\" | \"skip\" | \"orderBy\"\n >;\n findOne?: Partial<Partial<Prisma.Args<T, \"findUnique\">>>;\n findMany?: Partial<Prisma.Args<T, \"findMany\">>;\n deleteMany?: Partial<Prisma.Args<T, \"deleteMany\">>;\n updateMany?: Partial<Prisma.Args<T, \"updateMany\">>;\n createMany?: Partial<Prisma.Args<T, \"createMany\">>;\n createOne?: Partial<Prisma.Args<T, \"create\">>;\n updateOne?: Partial<Prisma.Args<T, \"update\">>;\n deleteOne?: Partial<Prisma.Args<T, \"delete\">>;\n};\n\nexport interface UserRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n roleId: string;\n role: AuthRole;\n user: User;\n userId: string;\n}\n\nexport interface AuthRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n name: string;\n permissions: AuthPermission[];\n userRoles: UserRole[];\n}\n\nexport enum AuthPermissionAction {\n create = \"create\",\n view = \"view\",\n update = \"update\",\n delete = \"delete\",\n}\n\nexport interface AuthPermission {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n resource: string;\n action: AuthPermissionAction;\n roleId: string;\n role: AuthRole;\n}\n\nexport interface User {\n id: string;\n isStaff: boolean;\n isSuperUser: boolean;\n password: string;\n passwordChangedAt?: Date;\n deletedSelfAccountAt: Date;\n isActive: boolean;\n roles?: UserRole[] | any[];\n role?: UserRole | any;\n}\n\nexport interface ArkosRequest<Body = any, Query = any> extends Request {\n user?: User & Record<string, any>;\n relationFields?: Record<string, boolean>;\n include?: Record<string, any>;\n responseData?: Record<string, any> | null | undefined;\n additionalData?: Record<string, any> | null | undefined;\n responseStatus?: number | string | null | undefined;\n body: Body;\n // query: Query extends Request['ParsedQs'];\n}\n\nexport interface ArkosResponse extends Response {}\nexport interface ArkosNextFunction extends NextFunction {}\nexport interface ArkosRequestHandler extends RequestHandler {}\n"]}
|
|
@@ -60,13 +60,14 @@ class APIFeatures {
|
|
|
60
60
|
if (!!this.searchParams.search) {
|
|
61
61
|
const prisma = (0, prisma_helpers_1.getPrismaInstance)();
|
|
62
62
|
Object.keys(prisma[this.modelName].fields).forEach((key) => {
|
|
63
|
+
var _a, _b;
|
|
63
64
|
const field = prisma[this.modelName].fields[key];
|
|
64
65
|
if (field.typeName === "String" &&
|
|
65
66
|
key !== "id" &&
|
|
66
67
|
key !== "password" &&
|
|
67
68
|
!field.isList &&
|
|
68
|
-
!(key === null || key === void 0 ? void 0 : key.includes("Id")) &&
|
|
69
|
-
!(key === null || key === void 0 ? void 0 : key.includes("ID"))) {
|
|
69
|
+
!((_a = key === null || key === void 0 ? void 0 : key.includes) === null || _a === void 0 ? void 0 : _a.call(key, "Id")) &&
|
|
70
|
+
!((_b = key === null || key === void 0 ? void 0 : key.includes) === null || _b === void 0 ? void 0 : _b.call(key, "ID"))) {
|
|
70
71
|
searchableFields.push({
|
|
71
72
|
[`${key}`]: {
|
|
72
73
|
contains: this.searchParams.search,
|