arkos 1.4.0-canary.92 → 1.4.1-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.
Files changed (170) hide show
  1. package/dist/cjs/app.js +1 -1
  2. package/dist/cjs/app.js.map +1 -1
  3. package/dist/cjs/exports/index.js.map +1 -1
  4. package/dist/cjs/modules/auth/auth.controller.js +1 -1
  5. package/dist/cjs/modules/auth/auth.controller.js.map +1 -1
  6. package/dist/cjs/modules/auth/auth.service.js +3 -4
  7. package/dist/cjs/modules/auth/auth.service.js.map +1 -1
  8. package/dist/cjs/modules/auth/utils/services/auth-action.service.js +56 -8
  9. package/dist/cjs/modules/auth/utils/services/auth-action.service.js.map +1 -1
  10. package/dist/cjs/modules/base/base.controller.js +6 -3
  11. package/dist/cjs/modules/base/base.controller.js.map +1 -1
  12. package/dist/cjs/modules/base/base.middlewares.js +17 -5
  13. package/dist/cjs/modules/base/base.middlewares.js.map +1 -1
  14. package/dist/cjs/modules/error-handler/error-handler.controller.js +2 -2
  15. package/dist/cjs/modules/error-handler/error-handler.controller.js.map +1 -1
  16. package/dist/cjs/modules/error-handler/utils/catch-async.js.map +1 -1
  17. package/dist/cjs/modules/swagger/swagger.router.js +6 -4
  18. package/dist/cjs/modules/swagger/swagger.router.js.map +1 -1
  19. package/dist/cjs/modules/swagger/utils/built-in-route-path-object-manager.js +7 -0
  20. package/dist/cjs/modules/swagger/utils/built-in-route-path-object-manager.js.map +1 -0
  21. package/dist/cjs/modules/swagger/utils/helpers/get-authentication-json-schema-paths.js +326 -183
  22. package/dist/cjs/modules/swagger/utils/helpers/get-authentication-json-schema-paths.js.map +1 -1
  23. package/dist/cjs/modules/swagger/utils/helpers/get-file-upload-json-schema-paths.js +374 -288
  24. package/dist/cjs/modules/swagger/utils/helpers/get-file-upload-json-schema-paths.js.map +1 -1
  25. package/dist/cjs/modules/swagger/utils/helpers/get-swagger-default-configs.js +1 -5
  26. package/dist/cjs/modules/swagger/utils/helpers/get-swagger-default-configs.js.map +1 -1
  27. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-main-routes-paths.js +280 -243
  28. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-main-routes-paths.js.map +1 -1
  29. package/dist/cjs/modules/swagger/utils/helpers/missing-json-schemas-generator.js +3 -0
  30. package/dist/cjs/modules/swagger/utils/helpers/missing-json-schemas-generator.js.map +1 -1
  31. package/dist/cjs/modules/swagger/utils/helpers/swagger.router.helpers.js +8 -6
  32. package/dist/cjs/modules/swagger/utils/helpers/swagger.router.helpers.js.map +1 -1
  33. package/dist/cjs/server.js +17 -15
  34. package/dist/cjs/server.js.map +1 -1
  35. package/dist/cjs/types/index.js.map +1 -1
  36. package/dist/cjs/types/new-arkos-config.js.map +1 -1
  37. package/dist/cjs/utils/arkos-router/index.js +50 -10
  38. package/dist/cjs/utils/arkos-router/index.js.map +1 -1
  39. package/dist/cjs/utils/arkos-router/types/index.js.map +1 -1
  40. package/dist/cjs/utils/arkos-router/utils/helpers/index.js +11 -0
  41. package/dist/cjs/utils/arkos-router/utils/helpers/index.js.map +1 -1
  42. package/dist/cjs/utils/cli/dev.js +13 -55
  43. package/dist/cjs/utils/cli/dev.js.map +1 -1
  44. package/dist/cjs/utils/cli/export-auth-action.js +1 -1
  45. package/dist/cjs/utils/cli/export-auth-action.js.map +1 -1
  46. package/dist/cjs/utils/cli/generate.js +3 -3
  47. package/dist/cjs/utils/cli/generate.js.map +1 -1
  48. package/dist/cjs/utils/cli/index.js +1 -1
  49. package/dist/cjs/utils/cli/index.js.map +1 -1
  50. package/dist/cjs/utils/cli/start.js +19 -12
  51. package/dist/cjs/utils/cli/start.js.map +1 -1
  52. package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
  53. package/dist/cjs/utils/cli/utils/runtime-cli-commander.js +51 -6
  54. package/dist/cjs/utils/cli/utils/runtime-cli-commander.js.map +1 -1
  55. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator/create-dto-template.js +3 -3
  56. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator/create-dto-template.js.map +1 -1
  57. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator/update-dto-template.js +3 -3
  58. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator/update-dto-template.js.map +1 -1
  59. package/dist/cjs/utils/cli/utils/template-generator/templates/middlewares-template.js +6 -3
  60. package/dist/cjs/utils/cli/utils/template-generator/templates/middlewares-template.js.map +1 -1
  61. package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js +3 -1
  62. package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js.map +1 -1
  63. package/dist/cjs/utils/dotenv.helpers.js +15 -7
  64. package/dist/cjs/utils/dotenv.helpers.js.map +1 -1
  65. package/dist/cjs/utils/helpers/api.features.helpers.js +174 -81
  66. package/dist/cjs/utils/helpers/api.features.helpers.js.map +1 -1
  67. package/dist/cjs/utils/helpers/prisma.helpers.js +40 -1
  68. package/dist/cjs/utils/helpers/prisma.helpers.js.map +1 -1
  69. package/dist/cjs/utils/helpers/routers.helpers.js +0 -1
  70. package/dist/cjs/utils/helpers/routers.helpers.js.map +1 -1
  71. package/dist/cjs/utils/prisma/prisma-json-schema-generator.js +19 -4
  72. package/dist/cjs/utils/prisma/prisma-json-schema-generator.js.map +1 -1
  73. package/dist/cjs/utils/validate-dto.js +1 -5
  74. package/dist/cjs/utils/validate-dto.js.map +1 -1
  75. package/dist/cjs/utils/validate-schema.js +2 -7
  76. package/dist/cjs/utils/validate-schema.js.map +1 -1
  77. package/dist/esm/app.js +1 -1
  78. package/dist/esm/app.js.map +1 -1
  79. package/dist/esm/exports/index.js.map +1 -1
  80. package/dist/esm/modules/auth/auth.controller.js +1 -1
  81. package/dist/esm/modules/auth/auth.controller.js.map +1 -1
  82. package/dist/esm/modules/auth/auth.service.js +4 -5
  83. package/dist/esm/modules/auth/auth.service.js.map +1 -1
  84. package/dist/esm/modules/auth/utils/services/auth-action.service.js +56 -5
  85. package/dist/esm/modules/auth/utils/services/auth-action.service.js.map +1 -1
  86. package/dist/esm/modules/base/base.controller.js +6 -3
  87. package/dist/esm/modules/base/base.controller.js.map +1 -1
  88. package/dist/esm/modules/base/base.middlewares.js +17 -5
  89. package/dist/esm/modules/base/base.middlewares.js.map +1 -1
  90. package/dist/esm/modules/error-handler/error-handler.controller.js +2 -2
  91. package/dist/esm/modules/error-handler/error-handler.controller.js.map +1 -1
  92. package/dist/esm/modules/error-handler/utils/catch-async.js.map +1 -1
  93. package/dist/esm/modules/swagger/swagger.router.js +6 -4
  94. package/dist/esm/modules/swagger/swagger.router.js.map +1 -1
  95. package/dist/esm/modules/swagger/utils/built-in-route-path-object-manager.js +5 -0
  96. package/dist/esm/modules/swagger/utils/built-in-route-path-object-manager.js.map +1 -0
  97. package/dist/esm/modules/swagger/utils/helpers/get-authentication-json-schema-paths.js +326 -183
  98. package/dist/esm/modules/swagger/utils/helpers/get-authentication-json-schema-paths.js.map +1 -1
  99. package/dist/esm/modules/swagger/utils/helpers/get-file-upload-json-schema-paths.js +374 -288
  100. package/dist/esm/modules/swagger/utils/helpers/get-file-upload-json-schema-paths.js.map +1 -1
  101. package/dist/esm/modules/swagger/utils/helpers/get-swagger-default-configs.js +1 -2
  102. package/dist/esm/modules/swagger/utils/helpers/get-swagger-default-configs.js.map +1 -1
  103. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-main-routes-paths.js +280 -243
  104. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-main-routes-paths.js.map +1 -1
  105. package/dist/esm/modules/swagger/utils/helpers/missing-json-schemas-generator.js +3 -0
  106. package/dist/esm/modules/swagger/utils/helpers/missing-json-schemas-generator.js.map +1 -1
  107. package/dist/esm/modules/swagger/utils/helpers/swagger.router.helpers.js +8 -6
  108. package/dist/esm/modules/swagger/utils/helpers/swagger.router.helpers.js.map +1 -1
  109. package/dist/esm/server.js +17 -15
  110. package/dist/esm/server.js.map +1 -1
  111. package/dist/esm/types/index.js.map +1 -1
  112. package/dist/esm/types/new-arkos-config.js.map +1 -1
  113. package/dist/esm/utils/arkos-router/index.js +51 -11
  114. package/dist/esm/utils/arkos-router/index.js.map +1 -1
  115. package/dist/esm/utils/arkos-router/types/index.js.map +1 -1
  116. package/dist/esm/utils/arkos-router/utils/helpers/index.js +10 -0
  117. package/dist/esm/utils/arkos-router/utils/helpers/index.js.map +1 -1
  118. package/dist/esm/utils/cli/dev.js +14 -56
  119. package/dist/esm/utils/cli/dev.js.map +1 -1
  120. package/dist/esm/utils/cli/export-auth-action.js +1 -1
  121. package/dist/esm/utils/cli/export-auth-action.js.map +1 -1
  122. package/dist/esm/utils/cli/generate.js +3 -3
  123. package/dist/esm/utils/cli/generate.js.map +1 -1
  124. package/dist/esm/utils/cli/index.js +1 -1
  125. package/dist/esm/utils/cli/index.js.map +1 -1
  126. package/dist/esm/utils/cli/start.js +19 -12
  127. package/dist/esm/utils/cli/start.js.map +1 -1
  128. package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
  129. package/dist/esm/utils/cli/utils/runtime-cli-commander.js +52 -7
  130. package/dist/esm/utils/cli/utils/runtime-cli-commander.js.map +1 -1
  131. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator/create-dto-template.js +3 -3
  132. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator/create-dto-template.js.map +1 -1
  133. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator/update-dto-template.js +3 -3
  134. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator/update-dto-template.js.map +1 -1
  135. package/dist/esm/utils/cli/utils/template-generator/templates/middlewares-template.js +6 -3
  136. package/dist/esm/utils/cli/utils/template-generator/templates/middlewares-template.js.map +1 -1
  137. package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js +3 -1
  138. package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js.map +1 -1
  139. package/dist/esm/utils/dotenv.helpers.js +15 -7
  140. package/dist/esm/utils/dotenv.helpers.js.map +1 -1
  141. package/dist/esm/utils/helpers/api.features.helpers.js +174 -81
  142. package/dist/esm/utils/helpers/api.features.helpers.js.map +1 -1
  143. package/dist/esm/utils/helpers/prisma.helpers.js +39 -1
  144. package/dist/esm/utils/helpers/prisma.helpers.js.map +1 -1
  145. package/dist/esm/utils/helpers/routers.helpers.js +0 -1
  146. package/dist/esm/utils/helpers/routers.helpers.js.map +1 -1
  147. package/dist/esm/utils/prisma/prisma-json-schema-generator.js +19 -4
  148. package/dist/esm/utils/prisma/prisma-json-schema-generator.js.map +1 -1
  149. package/dist/esm/utils/validate-dto.js +1 -2
  150. package/dist/esm/utils/validate-dto.js.map +1 -1
  151. package/dist/esm/utils/validate-schema.js +2 -4
  152. package/dist/esm/utils/validate-schema.js.map +1 -1
  153. package/dist/types/exports/index.d.ts +2 -1
  154. package/dist/types/modules/auth/auth.router.d.ts +1 -1
  155. package/dist/types/modules/auth/auth.service.d.ts +2 -2
  156. package/dist/types/modules/base/base.router.d.ts +1 -1
  157. package/dist/types/modules/swagger/utils/built-in-route-path-object-manager.d.ts +4 -0
  158. package/dist/types/modules/swagger/utils/helpers/get-authentication-json-schema-paths.d.ts +1 -1
  159. package/dist/types/modules/swagger/utils/helpers/get-file-upload-json-schema-paths.d.ts +1 -1
  160. package/dist/types/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-main-routes-paths.d.ts +1 -1
  161. package/dist/types/modules/swagger/utils/helpers/swagger.router.helpers.d.ts +1 -1
  162. package/dist/types/types/index.d.ts +5 -5
  163. package/dist/types/types/new-arkos-config.d.ts +1 -1
  164. package/dist/types/utils/arkos-router/index.d.ts +2 -1
  165. package/dist/types/utils/arkos-router/types/index.d.ts +15 -14
  166. package/dist/types/utils/arkos-router/utils/helpers/index.d.ts +1 -0
  167. package/dist/types/utils/cli/dev.d.ts +1 -1
  168. package/dist/types/utils/cli/start.d.ts +1 -1
  169. package/dist/types/utils/helpers/prisma.helpers.d.ts +1 -0
  170. package/package.json +2 -2
@@ -8,8 +8,8 @@ const dynamic_loader_1 = require("../../../../utils/dynamic-loader");
8
8
  const base_router_helpers_1 = require("../../../base/utils/helpers/base.router.helpers");
9
9
  const deepmerge_helper_1 = __importDefault(require("../../../../utils/helpers/deepmerge.helper"));
10
10
  const file_upload_service_1 = require("../../../file-upload/file-upload.service");
11
- function getFileUploadJsonSchemaPaths(arkosConfig) {
12
- const paths = {};
11
+ function getFileUploadJsonSchemaPaths(arkosConfig, existingPaths) {
12
+ const paths = { ...existingPaths };
13
13
  if (!arkosConfig.fileUpload)
14
14
  return paths;
15
15
  const FileUploadModuleComponents = (0, dynamic_loader_1.getModuleComponents)("file-upload");
@@ -60,359 +60,445 @@ function getFileUploadJsonSchemaPaths(arkosConfig) {
60
60
  const cleanBasePath = basePathname.endsWith("/")
61
61
  ? basePathname.slice(0, -1)
62
62
  : basePathname;
63
- paths[`${cleanBasePath}/{filePath*}`] = {
64
- get: {
65
- tags: ["File Upload"],
66
- summary: "Retrieve uploaded file",
67
- description: `Serves static files from the upload directory (${baseUploadDir}). This endpoint uses wildcard path matching to serve files from any subdirectory.`,
68
- operationId: "findFile",
69
- ...(shouldIncludeSecurity("View") && {
70
- security: [{ BearerAuth: [] }],
71
- }),
72
- parameters: [
73
- {
74
- name: "filePath",
75
- in: "path",
76
- required: true,
77
- schema: { type: "string" },
78
- description: "Path to the file including file type directory (e.g., images/photo.jpg, videos/clip.mp4)",
79
- },
80
- ],
81
- responses: {
82
- "200": {
83
- description: "File retrieved successfully",
84
- content: {
85
- "application/octet-stream": {
86
- schema: {
87
- type: "string",
88
- format: "binary",
89
- },
63
+ const pathname = `${cleanBasePath}/{filePath*}`;
64
+ if (!paths[pathname])
65
+ paths[pathname] = {};
66
+ const currentPath = paths[pathname].get;
67
+ const defaultParameters = [
68
+ {
69
+ name: "filePath",
70
+ in: "path",
71
+ required: true,
72
+ schema: { type: "string" },
73
+ description: "Path to the file including file type directory (e.g., images/photo.jpg, videos/clip.mp4)",
74
+ },
75
+ ];
76
+ const existingParams = currentPath?.parameters || [];
77
+ const existingParamKeys = new Set(existingParams.map((p) => `${p.in}-${p.name}`));
78
+ const mergedParameters = [
79
+ ...existingParams,
80
+ ...defaultParameters.filter((p) => !existingParamKeys.has(`${p.in}-${p.name}`)),
81
+ ];
82
+ const defaultSpec = {
83
+ tags: ["File Upload", ...(currentPath?.tags || [])].filter((tag) => tag !== "Defaults"),
84
+ summary: currentPath?.summary === pathname || !currentPath?.summary
85
+ ? "Retrieve uploaded file"
86
+ : currentPath?.summary,
87
+ description: currentPath?.description === pathname || !currentPath?.description
88
+ ? `Serves static files from the upload directory (${baseUploadDir}). This endpoint uses wildcard path matching to serve files from any subdirectory.`
89
+ : currentPath?.description,
90
+ operationId: currentPath?.operationId?.includes(pathname) ||
91
+ !currentPath?.operationId
92
+ ? "findFile"
93
+ : currentPath?.operationId,
94
+ ...(shouldIncludeSecurity("View") && {
95
+ security: [{ BearerAuth: [] }],
96
+ }),
97
+ parameters: mergedParameters,
98
+ responses: {
99
+ ...(currentPath?.responses || {}),
100
+ "200": currentPath?.responses?.["200"] || {
101
+ description: "File retrieved successfully",
102
+ content: {
103
+ "application/octet-stream": {
104
+ schema: {
105
+ type: "string",
106
+ format: "binary",
90
107
  },
91
108
  },
92
109
  },
93
- "404": {
94
- description: "File not found",
95
- },
96
- ...(shouldIncludeSecurity("View") && {
97
- "401": { description: "Authentication required" },
98
- "403": { description: "Insufficient permissions to view files" },
99
- }),
100
110
  },
111
+ "404": currentPath?.responses?.["404"] || {
112
+ description: "File not found",
113
+ },
114
+ ...(shouldIncludeSecurity("View") && {
115
+ "401": currentPath?.responses?.["401"] || {
116
+ description: "Authentication required",
117
+ },
118
+ "403": currentPath?.responses?.["403"] || {
119
+ description: "Insufficient permissions to view files",
120
+ },
121
+ }),
101
122
  },
102
123
  };
124
+ paths[pathname].get = { ...(currentPath || {}), ...defaultSpec };
103
125
  }
104
126
  if (!isFileUploadEndpointDisabled("uploadFile")) {
105
127
  const cleanBasePath = basePathname.endsWith("/")
106
128
  ? basePathname.slice(0, -1)
107
129
  : basePathname;
108
- paths[`${cleanBasePath}/{fileType}`] = {
109
- post: {
110
- tags: ["File Upload"],
111
- summary: "Upload file(s)",
112
- description: "Upload one or multiple files. Supports image processing options for image uploads.",
113
- operationId: "uploadFile",
114
- ...(shouldIncludeSecurity("Create") && {
115
- security: [{ BearerAuth: [] }],
116
- }),
117
- parameters: [
118
- {
119
- name: "fileType",
120
- in: "path",
121
- required: true,
122
- schema: {
123
- type: "string",
124
- enum: ["images", "videos", "documents", "files"],
125
- },
126
- description: "Type of file being uploaded",
127
- },
128
- {
129
- name: "format",
130
- in: "query",
131
- required: false,
132
- schema: {
133
- type: "string",
134
- enum: ["jpeg", "jpg", "png", "webp", "gif", "avif"],
135
- },
136
- description: "Image format for conversion (only applicable for fileType=images)",
137
- },
138
- {
139
- name: "width",
140
- in: "query",
141
- required: false,
142
- schema: { type: "integer", minimum: 1 },
143
- description: "Target width for image resize (only applicable for fileType=images)",
144
- },
145
- {
146
- name: "height",
147
- in: "query",
148
- required: false,
149
- schema: { type: "integer", minimum: 1 },
150
- description: "Target height for image resize (only applicable for fileType=images)",
151
- },
152
- {
153
- name: "resizeTo",
154
- in: "query",
155
- required: false,
130
+ const pathname = `${cleanBasePath}/{fileType}`;
131
+ if (!paths[pathname])
132
+ paths[pathname] = {};
133
+ const currentPath = paths[pathname].post;
134
+ const defaultParameters = [
135
+ {
136
+ name: "fileType",
137
+ in: "path",
138
+ required: true,
139
+ schema: {
140
+ type: "string",
141
+ enum: ["images", "videos", "documents", "files"],
142
+ },
143
+ description: "Type of file being uploaded",
144
+ },
145
+ {
146
+ name: "format",
147
+ in: "query",
148
+ required: false,
149
+ schema: {
150
+ type: "string",
151
+ enum: ["jpeg", "jpg", "png", "webp", "gif", "avif"],
152
+ },
153
+ description: "Image format for conversion (only applicable for fileType=images)",
154
+ },
155
+ {
156
+ name: "width",
157
+ in: "query",
158
+ required: false,
159
+ schema: { type: "integer", minimum: 1 },
160
+ description: "Target width for image resize (only applicable for fileType=images)",
161
+ },
162
+ {
163
+ name: "height",
164
+ in: "query",
165
+ required: false,
166
+ schema: { type: "integer", minimum: 1 },
167
+ description: "Target height for image resize (only applicable for fileType=images)",
168
+ },
169
+ {
170
+ name: "resizeTo",
171
+ in: "query",
172
+ required: false,
173
+ schema: {
174
+ type: "string",
175
+ enum: ["cover", "contain", "fill", "inside", "outside"],
176
+ },
177
+ description: "Resize strategy (only applicable for fileType=images)",
178
+ },
179
+ ];
180
+ const existingParams = currentPath?.parameters || [];
181
+ const existingParamKeys = new Set(existingParams.map((p) => `${p.in}-${p.name}`));
182
+ const mergedParameters = [
183
+ ...existingParams,
184
+ ...defaultParameters.filter((p) => !existingParamKeys.has(`${p.in}-${p.name}`)),
185
+ ];
186
+ const defaultSpec = {
187
+ tags: ["File Upload", ...(currentPath?.tags || [])].filter((tag) => tag !== "Defaults"),
188
+ summary: currentPath?.summary === pathname || !currentPath?.summary
189
+ ? "Upload file(s)"
190
+ : currentPath?.summary,
191
+ description: currentPath?.description === pathname || !currentPath?.description
192
+ ? "Upload one or multiple files. Supports image processing options for image uploads."
193
+ : currentPath?.description,
194
+ operationId: currentPath?.operationId?.includes(pathname) ||
195
+ !currentPath?.operationId
196
+ ? "uploadFile"
197
+ : currentPath?.operationId,
198
+ ...(shouldIncludeSecurity("Create") && {
199
+ security: [{ BearerAuth: [] }],
200
+ }),
201
+ parameters: mergedParameters,
202
+ requestBody: currentPath?.requestBody || {
203
+ required: true,
204
+ content: {
205
+ "multipart/form-data": {
156
206
  schema: {
157
- type: "string",
158
- enum: ["cover", "contain", "fill", "inside", "outside"],
207
+ type: "object",
208
+ properties: {
209
+ images: {
210
+ type: "array",
211
+ items: { type: "string", format: "binary" },
212
+ description: getFileTypeDescription("images"),
213
+ },
214
+ videos: {
215
+ type: "array",
216
+ items: { type: "string", format: "binary" },
217
+ description: getFileTypeDescription("videos"),
218
+ },
219
+ documents: {
220
+ type: "array",
221
+ items: { type: "string", format: "binary" },
222
+ description: getFileTypeDescription("documents"),
223
+ },
224
+ files: {
225
+ type: "array",
226
+ items: { type: "string", format: "binary" },
227
+ description: getFileTypeDescription("files"),
228
+ },
229
+ },
159
230
  },
160
- description: "Resize strategy (only applicable for fileType=images)",
161
231
  },
162
- ],
163
- requestBody: {
164
- required: true,
232
+ },
233
+ },
234
+ responses: {
235
+ ...(currentPath?.responses || {}),
236
+ "200": currentPath?.responses?.["200"] || {
237
+ description: "File(s) uploaded successfully",
165
238
  content: {
166
- "multipart/form-data": {
239
+ "application/json": {
167
240
  schema: {
168
241
  type: "object",
169
242
  properties: {
170
- images: {
171
- type: "array",
172
- items: { type: "string", format: "binary" },
173
- description: getFileTypeDescription("images"),
174
- },
175
- videos: {
176
- type: "array",
177
- items: { type: "string", format: "binary" },
178
- description: getFileTypeDescription("videos"),
179
- },
180
- documents: {
181
- type: "array",
182
- items: { type: "string", format: "binary" },
183
- description: getFileTypeDescription("documents"),
184
- },
185
- files: {
186
- type: "array",
187
- items: { type: "string", format: "binary" },
188
- description: getFileTypeDescription("files"),
243
+ success: { type: "boolean", example: true },
244
+ data: {
245
+ oneOf: [
246
+ { type: "string", description: "URL of uploaded file" },
247
+ {
248
+ type: "array",
249
+ items: { type: "string" },
250
+ description: "URLs of uploaded files",
251
+ },
252
+ ],
189
253
  },
254
+ message: { type: "string" },
190
255
  },
191
256
  },
192
257
  },
193
258
  },
194
259
  },
195
- responses: {
196
- "200": {
197
- description: "File(s) uploaded successfully",
198
- content: {
199
- "application/json": {
200
- schema: {
201
- type: "object",
202
- properties: {
203
- success: { type: "boolean", example: true },
204
- data: {
205
- oneOf: [
206
- { type: "string", description: "URL of uploaded file" },
207
- {
208
- type: "array",
209
- items: { type: "string" },
210
- description: "URLs of uploaded files",
211
- },
212
- ],
213
- },
214
- message: { type: "string" },
215
- },
216
- },
217
- },
218
- },
260
+ "400": currentPath?.responses?.["400"] || {
261
+ description: "Invalid file type, size limit exceeded, or no file uploaded",
262
+ },
263
+ ...(shouldIncludeSecurity("Create") && {
264
+ "401": currentPath?.responses?.["401"] || {
265
+ description: "Authentication required",
219
266
  },
220
- "400": {
221
- description: "Invalid file type, size limit exceeded, or no file uploaded",
267
+ "403": currentPath?.responses?.["403"] || {
268
+ description: "Insufficient permissions to upload files",
222
269
  },
223
- ...(shouldIncludeSecurity("Create") && {
224
- "401": { description: "Authentication required" },
225
- "403": { description: "Insufficient permissions to upload files" },
226
- }),
227
- },
270
+ }),
228
271
  },
229
272
  };
273
+ paths[pathname].post = { ...(currentPath || {}), ...defaultSpec };
230
274
  }
231
275
  if (!isFileUploadEndpointDisabled("updateFile")) {
232
276
  const cleanBasePath = basePathname.endsWith("/")
233
277
  ? basePathname.slice(0, -1)
234
278
  : basePathname;
235
- paths[`${cleanBasePath}/{fileType}/{fileName}`] = {
236
- ...(paths[`${cleanBasePath}/{fileType}/{fileName}`] || {}),
237
- patch: {
238
- tags: ["File Upload"],
239
- summary: "Update existing file",
240
- description: "Replace an existing file with a new one. Deletes the old file and uploads the new one.",
241
- operationId: "updateFile",
242
- ...(shouldIncludeSecurity("Update") && {
243
- security: [{ BearerAuth: [] }],
244
- }),
245
- parameters: [
246
- {
247
- name: "fileType",
248
- in: "path",
249
- required: true,
250
- schema: {
251
- type: "string",
252
- enum: ["images", "videos", "documents", "files"],
253
- },
254
- description: "Type of file being updated",
255
- },
256
- {
257
- name: "fileName",
258
- in: "path",
259
- required: true,
260
- schema: { type: "string" },
261
- description: "Name of the file to update",
262
- },
263
- {
264
- name: "format",
265
- in: "query",
266
- required: false,
267
- schema: {
268
- type: "string",
269
- enum: ["jpeg", "jpg", "png", "webp", "gif", "avif"],
270
- },
271
- description: "Image format for conversion (only applicable for fileType=images)",
272
- },
273
- {
274
- name: "width",
275
- in: "query",
276
- required: false,
277
- schema: { type: "integer", minimum: 1 },
278
- description: "Target width for image resize (only applicable for fileType=images)",
279
- },
280
- {
281
- name: "height",
282
- in: "query",
283
- required: false,
284
- schema: { type: "integer", minimum: 1 },
285
- description: "Target height for image resize (only applicable for fileType=images)",
286
- },
287
- {
288
- name: "resizeTo",
289
- in: "query",
290
- required: false,
279
+ const pathname = `${cleanBasePath}/{fileType}/{fileName}`;
280
+ if (!paths[pathname])
281
+ paths[pathname] = {};
282
+ const currentPath = paths[pathname].patch;
283
+ const defaultParameters = [
284
+ {
285
+ name: "fileType",
286
+ in: "path",
287
+ required: true,
288
+ schema: {
289
+ type: "string",
290
+ enum: ["images", "videos", "documents", "files"],
291
+ },
292
+ description: "Type of file being updated",
293
+ },
294
+ {
295
+ name: "fileName",
296
+ in: "path",
297
+ required: true,
298
+ schema: { type: "string" },
299
+ description: "Name of the file to update",
300
+ },
301
+ {
302
+ name: "format",
303
+ in: "query",
304
+ required: false,
305
+ schema: {
306
+ type: "string",
307
+ enum: ["jpeg", "jpg", "png", "webp", "gif", "avif"],
308
+ },
309
+ description: "Image format for conversion (only applicable for fileType=images)",
310
+ },
311
+ {
312
+ name: "width",
313
+ in: "query",
314
+ required: false,
315
+ schema: { type: "integer", minimum: 1 },
316
+ description: "Target width for image resize (only applicable for fileType=images)",
317
+ },
318
+ {
319
+ name: "height",
320
+ in: "query",
321
+ required: false,
322
+ schema: { type: "integer", minimum: 1 },
323
+ description: "Target height for image resize (only applicable for fileType=images)",
324
+ },
325
+ {
326
+ name: "resizeTo",
327
+ in: "query",
328
+ required: false,
329
+ schema: {
330
+ type: "string",
331
+ enum: ["cover", "contain", "fill", "inside", "outside"],
332
+ },
333
+ description: "Resize strategy (only applicable for fileType=images)",
334
+ },
335
+ ];
336
+ const existingParams = currentPath?.parameters || [];
337
+ const existingParamKeys = new Set(existingParams.map((p) => `${p.in}-${p.name}`));
338
+ const mergedParameters = [
339
+ ...existingParams,
340
+ ...defaultParameters.filter((p) => !existingParamKeys.has(`${p.in}-${p.name}`)),
341
+ ];
342
+ const defaultSpec = {
343
+ tags: ["File Upload", ...(currentPath?.tags || [])].filter((tag) => tag !== "Defaults"),
344
+ summary: currentPath?.summary === pathname || !currentPath?.summary
345
+ ? "Update existing file"
346
+ : currentPath?.summary,
347
+ description: currentPath?.description === pathname || !currentPath?.description
348
+ ? "Replace an existing file with a new one. Deletes the old file and uploads the new one."
349
+ : currentPath?.description,
350
+ operationId: currentPath?.operationId?.includes(pathname) ||
351
+ !currentPath?.operationId
352
+ ? "updateFile"
353
+ : currentPath?.operationId,
354
+ ...(shouldIncludeSecurity("Update") && {
355
+ security: [{ BearerAuth: [] }],
356
+ }),
357
+ parameters: mergedParameters,
358
+ requestBody: currentPath?.requestBody || {
359
+ required: true,
360
+ content: {
361
+ "multipart/form-data": {
291
362
  schema: {
292
- type: "string",
293
- enum: ["cover", "contain", "fill", "inside", "outside"],
363
+ type: "object",
364
+ properties: {
365
+ images: {
366
+ type: "array",
367
+ items: { type: "string", format: "binary" },
368
+ description: getFileTypeDescription("images"),
369
+ },
370
+ videos: {
371
+ type: "array",
372
+ items: { type: "string", format: "binary" },
373
+ description: getFileTypeDescription("videos"),
374
+ },
375
+ documents: {
376
+ type: "array",
377
+ items: { type: "string", format: "binary" },
378
+ description: getFileTypeDescription("documents"),
379
+ },
380
+ files: {
381
+ type: "array",
382
+ items: { type: "string", format: "binary" },
383
+ description: getFileTypeDescription("files"),
384
+ },
385
+ },
294
386
  },
295
- description: "Resize strategy (only applicable for fileType=images)",
296
387
  },
297
- ],
298
- requestBody: {
299
- required: true,
388
+ },
389
+ },
390
+ responses: {
391
+ ...(currentPath?.responses || {}),
392
+ "200": currentPath?.responses?.["200"] || {
393
+ description: "File updated successfully",
300
394
  content: {
301
- "multipart/form-data": {
395
+ "application/json": {
302
396
  schema: {
303
397
  type: "object",
304
398
  properties: {
305
- images: {
306
- type: "array",
307
- items: { type: "string", format: "binary" },
308
- description: getFileTypeDescription("images"),
309
- },
310
- videos: {
311
- type: "array",
312
- items: { type: "string", format: "binary" },
313
- description: getFileTypeDescription("videos"),
314
- },
315
- documents: {
316
- type: "array",
317
- items: { type: "string", format: "binary" },
318
- description: getFileTypeDescription("documents"),
319
- },
320
- files: {
321
- type: "array",
322
- items: { type: "string", format: "binary" },
323
- description: getFileTypeDescription("files"),
399
+ success: { type: "boolean", example: true },
400
+ data: {
401
+ oneOf: [
402
+ { type: "string", description: "URL of updated file" },
403
+ {
404
+ type: "array",
405
+ items: { type: "string" },
406
+ description: "URLs of updated files",
407
+ },
408
+ ],
324
409
  },
410
+ message: { type: "string" },
325
411
  },
326
412
  },
327
413
  },
328
414
  },
329
415
  },
330
- responses: {
331
- "200": {
332
- description: "File updated successfully",
333
- content: {
334
- "application/json": {
335
- schema: {
336
- type: "object",
337
- properties: {
338
- success: { type: "boolean", example: true },
339
- data: {
340
- oneOf: [
341
- { type: "string", description: "URL of updated file" },
342
- {
343
- type: "array",
344
- items: { type: "string" },
345
- description: "URLs of updated files",
346
- },
347
- ],
348
- },
349
- message: { type: "string" },
350
- },
351
- },
352
- },
353
- },
354
- },
355
- "400": {
356
- description: "Invalid file type, size limit exceeded, or no file uploaded",
416
+ "400": currentPath?.responses?.["400"] || {
417
+ description: "Invalid file type, size limit exceeded, or no file uploaded",
418
+ },
419
+ "404": currentPath?.responses?.["404"] || {
420
+ description: "Original file not found",
421
+ },
422
+ ...(shouldIncludeSecurity("Update") && {
423
+ "401": currentPath?.responses?.["401"] || {
424
+ description: "Authentication required",
357
425
  },
358
- "404": {
359
- description: "Original file not found",
426
+ "403": currentPath?.responses?.["403"] || {
427
+ description: "Insufficient permissions to update files",
360
428
  },
361
- ...(shouldIncludeSecurity("Update") && {
362
- "401": { description: "Authentication required" },
363
- "403": { description: "Insufficient permissions to update files" },
364
- }),
365
- },
429
+ }),
366
430
  },
367
431
  };
432
+ paths[pathname].patch = { ...(currentPath || {}), ...defaultSpec };
368
433
  }
369
434
  if (!isFileUploadEndpointDisabled("deleteFile")) {
370
435
  const cleanBasePath = basePathname.endsWith("/")
371
436
  ? basePathname.slice(0, -1)
372
437
  : basePathname;
373
- if (!paths[`${cleanBasePath}/{fileType}/{fileName}`]) {
374
- paths[`${cleanBasePath}/{fileType}/{fileName}`] = {};
375
- }
376
- paths[`${cleanBasePath}/{fileType}/{fileName}`].delete = {
377
- tags: ["File Upload"],
378
- summary: "Delete file",
379
- description: "Delete an uploaded file from the server",
380
- operationId: "deleteFile",
438
+ const pathname = `${cleanBasePath}/{fileType}/{fileName}`;
439
+ if (!paths[pathname])
440
+ paths[pathname] = {};
441
+ const currentPath = paths[pathname].delete;
442
+ const defaultParameters = [
443
+ {
444
+ name: "fileType",
445
+ in: "path",
446
+ required: true,
447
+ schema: {
448
+ type: "string",
449
+ enum: ["images", "videos", "documents", "files"],
450
+ },
451
+ description: "Type of file being deleted",
452
+ },
453
+ {
454
+ name: "fileName",
455
+ in: "path",
456
+ required: true,
457
+ schema: { type: "string" },
458
+ description: "Name of the file to delete",
459
+ },
460
+ ];
461
+ const existingParams = currentPath?.parameters || [];
462
+ const existingParamKeys = new Set(existingParams.map((p) => `${p.in}-${p.name}`));
463
+ const mergedParameters = [
464
+ ...existingParams,
465
+ ...defaultParameters.filter((p) => !existingParamKeys.has(`${p.in}-${p.name}`)),
466
+ ];
467
+ const defaultSpec = {
468
+ tags: ["File Upload", ...(currentPath?.tags || [])].filter((tag) => tag !== "Defaults"),
469
+ summary: currentPath?.summary === pathname || !currentPath?.summary
470
+ ? "Delete file"
471
+ : currentPath?.summary,
472
+ description: currentPath?.description === pathname || !currentPath?.description
473
+ ? "Delete an uploaded file from the server"
474
+ : currentPath?.description,
475
+ operationId: currentPath?.operationId?.includes(pathname) ||
476
+ !currentPath?.operationId
477
+ ? "deleteFile"
478
+ : currentPath?.operationId,
381
479
  ...(shouldIncludeSecurity("Delete") && {
382
480
  security: [{ BearerAuth: [] }],
383
481
  }),
384
- parameters: [
385
- {
386
- name: "fileType",
387
- in: "path",
388
- required: true,
389
- schema: {
390
- type: "string",
391
- enum: ["images", "videos", "documents", "files"],
392
- },
393
- description: "Type of file being deleted",
394
- },
395
- {
396
- name: "fileName",
397
- in: "path",
398
- required: true,
399
- schema: { type: "string" },
400
- description: "Name of the file to delete",
401
- },
402
- ],
482
+ parameters: mergedParameters,
403
483
  responses: {
404
- "204": {
484
+ ...(currentPath?.responses || {}),
485
+ "204": currentPath?.responses?.["204"] || {
405
486
  description: "File deleted successfully",
406
487
  },
407
- "404": {
488
+ "404": currentPath?.responses?.["404"] || {
408
489
  description: "File not found",
409
490
  },
410
491
  ...(shouldIncludeSecurity("Delete") && {
411
- "401": { description: "Authentication required" },
412
- "403": { description: "Insufficient permissions to delete files" },
492
+ "401": currentPath?.responses?.["401"] || {
493
+ description: "Authentication required",
494
+ },
495
+ "403": currentPath?.responses?.["403"] || {
496
+ description: "Insufficient permissions to delete files",
497
+ },
413
498
  }),
414
499
  },
415
500
  };
501
+ paths[pathname].delete = { ...(currentPath || {}), ...defaultSpec };
416
502
  }
417
503
  return paths;
418
504
  }