arkos 1.4.0-canary.92 → 1.4.1-canary.2

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