@internetderdinge/api 1.229.0 → 1.229.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 (171) hide show
  1. package/dist/src/accounts/accounts.controller.js +89 -0
  2. package/dist/src/accounts/accounts.route.js +101 -0
  3. package/dist/src/accounts/accounts.schemas.js +12 -0
  4. package/dist/src/accounts/accounts.service.js +65 -0
  5. package/dist/src/accounts/accounts.validation.js +99 -0
  6. package/dist/src/accounts/auth0.service.js +188 -0
  7. package/dist/src/config/config.js +48 -0
  8. package/dist/src/config/logger.js +27 -0
  9. package/dist/src/config/morgan.js +16 -0
  10. package/dist/src/config/passport.cjs +28 -0
  11. package/dist/src/config/roles.js +11 -0
  12. package/dist/src/config/tokens.cjs +10 -0
  13. package/dist/src/devices/devices.controller.js +172 -0
  14. package/dist/src/devices/devices.model.js +94 -0
  15. package/dist/src/devices/devices.route.js +153 -0
  16. package/dist/src/devices/devices.schemas.js +84 -0
  17. package/dist/src/devices/devices.service.js +198 -0
  18. package/dist/src/devices/devices.types.js +1 -0
  19. package/dist/src/devices/devices.validation.js +257 -0
  20. package/dist/src/devicesNotifications/devicesNotifications.controller.js +69 -0
  21. package/dist/src/devicesNotifications/devicesNotifications.model.js +39 -0
  22. package/dist/src/devicesNotifications/devicesNotifications.route.js +124 -0
  23. package/dist/src/devicesNotifications/devicesNotifications.schemas.js +10 -0
  24. package/dist/src/devicesNotifications/devicesNotifications.service.js +181 -0
  25. package/dist/src/devicesNotifications/devicesNotifications.validation.js +46 -0
  26. package/dist/src/email/email.service.js +580 -0
  27. package/dist/src/files/upload.service.js +124 -0
  28. package/dist/src/i18n/i18n.js +38 -0
  29. package/dist/src/i18n/saveMissingLocalJsonBackend.js +53 -0
  30. package/dist/src/i18n/types.js +1 -0
  31. package/dist/src/index.js +48 -0
  32. package/dist/src/iotdevice/iotdevice.controller.js +96 -0
  33. package/dist/src/iotdevice/iotdevice.model.js +17 -0
  34. package/dist/src/iotdevice/iotdevice.route.js +143 -0
  35. package/dist/src/iotdevice/iotdevice.schemas.js +60 -0
  36. package/dist/src/iotdevice/iotdevice.service.js +579 -0
  37. package/dist/src/iotdevice/iotdevice.types.js +1 -0
  38. package/dist/src/iotdevice/iotdevice.validation.js +54 -0
  39. package/dist/src/middlewares/auth.js +75 -0
  40. package/dist/src/middlewares/checkJwt.cjs +17 -0
  41. package/dist/src/middlewares/error.js +36 -0
  42. package/dist/src/middlewares/mongooseValidations/ensureSameOrganization.js +13 -0
  43. package/dist/src/middlewares/rateLimiter.js +7 -0
  44. package/dist/src/middlewares/validate.js +18 -0
  45. package/dist/src/middlewares/validateAction.js +35 -0
  46. package/dist/src/middlewares/validateAdmin.js +18 -0
  47. package/dist/src/middlewares/validateAi.js +16 -0
  48. package/dist/src/middlewares/validateCurrentAuthUser.js +17 -0
  49. package/dist/src/middlewares/validateCurrentUser.js +20 -0
  50. package/dist/src/middlewares/validateDevice.js +98 -0
  51. package/dist/src/middlewares/validateDeviceUserOrganization.js +26 -0
  52. package/dist/src/middlewares/validateOrganization.js +63 -0
  53. package/dist/src/middlewares/validateQuerySearchUserAndOrganization.js +44 -0
  54. package/dist/src/middlewares/validateTokens.js +23 -0
  55. package/dist/src/middlewares/validateUser.js +38 -0
  56. package/dist/src/middlewares/validateZod.js +33 -0
  57. package/dist/src/models/plugins/index.js +4 -0
  58. package/dist/src/models/plugins/paginate.plugin.js +117 -0
  59. package/dist/src/models/plugins/paginateNew.plugin.js +185 -0
  60. package/dist/src/models/plugins/simplePopulate.js +16 -0
  61. package/dist/src/models/plugins/toJSON.plugin.js +35 -0
  62. package/dist/src/organizations/organizations.controller.js +64 -0
  63. package/dist/src/organizations/organizations.model.js +41 -0
  64. package/dist/src/organizations/organizations.route.js +98 -0
  65. package/dist/src/organizations/organizations.schemas.js +7 -0
  66. package/dist/src/organizations/organizations.service.js +59 -0
  67. package/dist/src/organizations/organizations.validation.js +62 -0
  68. package/dist/src/pdf/pdf.controller.js +24 -0
  69. package/dist/src/pdf/pdf.route.js +22 -0
  70. package/dist/src/pdf/pdf.schemas.js +6 -0
  71. package/dist/src/pdf/pdf.service.js +65 -0
  72. package/dist/src/pdf/pdf.validation.js +27 -0
  73. package/dist/src/tokens/tokens.controller.js +60 -0
  74. package/dist/src/tokens/tokens.model.js +17 -0
  75. package/dist/src/tokens/tokens.route.js +52 -0
  76. package/dist/src/tokens/tokens.schemas.js +14 -0
  77. package/dist/src/tokens/tokens.service.js +30 -0
  78. package/dist/src/tokens/tokens.validation.js +9 -0
  79. package/dist/src/types/routeSpec.js +1 -0
  80. package/dist/src/users/users.controller.js +147 -0
  81. package/dist/src/users/users.model.js +50 -0
  82. package/dist/src/users/users.route.js +137 -0
  83. package/dist/src/users/users.schemas.js +69 -0
  84. package/dist/src/users/users.service.js +295 -0
  85. package/dist/src/users/users.types.js +1 -0
  86. package/dist/src/users/users.validation.js +144 -0
  87. package/dist/src/utils/ApiError.js +16 -0
  88. package/dist/src/utils/buildRouterAndDocs.js +72 -0
  89. package/dist/src/utils/catchAsync.js +4 -0
  90. package/dist/src/utils/comparePapers.service.js +32 -0
  91. package/dist/src/utils/deviceUtils.js +63 -0
  92. package/dist/src/utils/filterOptions.js +24 -0
  93. package/dist/src/utils/medicationName.js +10 -0
  94. package/dist/src/utils/pick.js +16 -0
  95. package/dist/src/utils/registerOpenApi.js +67 -0
  96. package/dist/src/utils/urlUtils.js +15 -0
  97. package/dist/src/utils/userName.js +22 -0
  98. package/dist/src/utils/zValidations.js +143 -0
  99. package/dist/src/validations/auth.validation.cjs +53 -0
  100. package/dist/src/validations/custom.validation.js +19 -0
  101. package/dist/src/validations/index.cjs +3 -0
  102. package/dist/tsconfig.tsbuildinfo +1 -0
  103. package/package.json +97 -80
  104. package/scripts/release-and-sync-paperless.mjs +137 -0
  105. package/src/accounts/accounts.controller.ts +1 -0
  106. package/src/accounts/accounts.service.ts +1 -0
  107. package/src/accounts/accounts.validation.ts +8 -5
  108. package/src/accounts/auth0.service.ts +55 -28
  109. package/src/config/config.ts +6 -0
  110. package/src/config/logger.ts +15 -9
  111. package/src/devices/devices.controller.ts +7 -1
  112. package/src/devices/devices.model.ts +4 -1
  113. package/src/devices/devices.schemas.ts +11 -9
  114. package/src/devices/devices.service.ts +1 -0
  115. package/src/devices/devices.types.ts +1 -0
  116. package/src/devices/devices.validation.ts +93 -32
  117. package/src/devicesNotifications/devicesNotifications.controller.ts +57 -28
  118. package/src/devicesNotifications/devicesNotifications.model.ts +20 -12
  119. package/src/devicesNotifications/devicesNotifications.service.ts +35 -17
  120. package/src/files/upload.service.ts +52 -28
  121. package/src/i18n/i18n.ts +1 -1
  122. package/src/i18n/types.ts +1 -0
  123. package/src/index.ts +47 -0
  124. package/src/iotdevice/iotdevice.controller.ts +1 -0
  125. package/src/iotdevice/iotdevice.model.ts +6 -3
  126. package/src/iotdevice/iotdevice.route.ts +85 -76
  127. package/src/iotdevice/iotdevice.service.ts +4 -3
  128. package/src/iotdevice/iotdevice.types.ts +6 -0
  129. package/src/middlewares/auth.ts +2 -8
  130. package/src/middlewares/error.ts +26 -12
  131. package/src/middlewares/mongooseValidations/ensureSameOrganization.ts +4 -3
  132. package/src/middlewares/validateAi.ts +17 -9
  133. package/src/middlewares/validateDevice.ts +1 -0
  134. package/src/middlewares/validateDeviceUserOrganization.ts +1 -0
  135. package/src/middlewares/validateOrganization.ts +1 -1
  136. package/src/middlewares/validateQuerySearchUserAndOrganization.ts +1 -0
  137. package/src/middlewares/validateTokens.ts +2 -1
  138. package/src/middlewares/validateUser.ts +1 -0
  139. package/src/middlewares/validateZod.ts +5 -5
  140. package/src/models/plugins/index.ts +5 -4
  141. package/src/models/plugins/paginate.plugin.ts +26 -16
  142. package/src/models/plugins/paginateNew.plugin.ts +33 -21
  143. package/src/models/plugins/simplePopulate.ts +8 -3
  144. package/src/models/plugins/toJSON.plugin.ts +12 -5
  145. package/src/organizations/organizations.controller.ts +1 -2
  146. package/src/organizations/organizations.model.ts +4 -4
  147. package/src/organizations/organizations.route.ts +1 -1
  148. package/src/organizations/organizations.service.ts +15 -6
  149. package/src/organizations/organizations.validation.ts +1 -1
  150. package/src/pdf/pdf.controller.ts +18 -1
  151. package/src/pdf/pdf.service.ts +25 -16
  152. package/src/tokens/tokens.controller.ts +6 -8
  153. package/src/tokens/tokens.model.ts +3 -1
  154. package/src/tokens/tokens.service.ts +3 -2
  155. package/src/types/express.d.ts +17 -0
  156. package/src/types/mongoose.d.ts +22 -0
  157. package/src/users/users.controller.ts +8 -9
  158. package/src/users/users.model.ts +6 -5
  159. package/src/users/users.route.ts +0 -1
  160. package/src/users/users.service.ts +16 -0
  161. package/src/users/users.types.ts +1 -0
  162. package/src/users/users.validation.ts +6 -2
  163. package/src/utils/ApiError.ts +8 -1
  164. package/src/utils/buildRouterAndDocs.ts +57 -22
  165. package/src/utils/catchAsync.ts +27 -3
  166. package/src/utils/medicationName.ts +5 -4
  167. package/src/utils/pick.ts +5 -1
  168. package/src/utils/registerOpenApi.ts +75 -24
  169. package/src/utils/userName.ts +1 -0
  170. package/src/utils/zValidations.ts +98 -27
  171. package/tsconfig.json +13 -4
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import mongoose, { Schema, Model } from "mongoose";
2
3
  import crypto from "crypto";
3
4
  import { toJSON, paginate } from "../models/plugins/index.js";
@@ -19,6 +20,7 @@ const tokenSchema: Schema = new mongoose.Schema(
19
20
  tokenSchema.plugin(toJSON, true);
20
21
  tokenSchema.plugin(paginate);
21
22
 
22
- const Token: Model<any> = mongoose.model("Token", tokenSchema);
23
+ const Token: Model<any> =
24
+ (mongoose.models.Token as Model<any>) || mongoose.model("Token", tokenSchema);
23
25
 
24
26
  export default Token;
@@ -1,12 +1,13 @@
1
1
  import crypto from "crypto";
2
2
  import type { Document } from "mongoose";
3
3
  import Token from "./tokens.model.js";
4
+ import type { QueryResult } from "../models/plugins/paginate.plugin.js";
4
5
 
5
6
  export const queryTokens = async (
6
7
  filter: Record<string, any>,
7
8
  options: { sortBy?: string; limit?: number; page?: number },
8
- ): Promise<QueryResult> => {
9
- return Token.paginate(filter, options);
9
+ ): Promise<QueryResult<any>> => {
10
+ return (Token as any).paginate(filter, options);
10
11
  };
11
12
 
12
13
  export const createToken = async (
@@ -0,0 +1,17 @@
1
+ declare global {
2
+ namespace Express {
3
+ interface Request {
4
+ auth?: {
5
+ sub: string;
6
+ id?: string;
7
+ tokenId?: string;
8
+ type?: string;
9
+ [key: string]: any;
10
+ };
11
+ currentUser?: any;
12
+ user?: any;
13
+ }
14
+ }
15
+ }
16
+
17
+ export {};
@@ -0,0 +1,22 @@
1
+ declare module "mongoose" {
2
+ const mongoose: any;
3
+ export default mongoose;
4
+
5
+ export type ObjectId = any;
6
+ export type Document = any;
7
+ export type Model<T = any> = any;
8
+ export type Schema<T = any> = any;
9
+ export type Query<T = any> = any;
10
+ export type FilterQuery<T = any> = any;
11
+ export type PaginateOptions = any;
12
+ export type PaginateModel<T = any> = any;
13
+ export type PipelineStage = any;
14
+
15
+ export const Schema: any;
16
+ export const Types: any;
17
+ export function model<T = any>(...args: any[]): Model<T>;
18
+
19
+ export namespace Types {
20
+ type ObjectId = any;
21
+ }
22
+ }
@@ -18,13 +18,13 @@ export const createUser = catchAsync(
18
18
  async (req: AuthRequest<{}, any, {}>, res: Response) => {
19
19
  const { body } = req;
20
20
  if (body.email) {
21
- const auth0user = await auth0Service.getUserIdByEmail(body.email);
21
+ const auth0users = await auth0Service.getUserIdByEmail(body.email);
22
22
  body.status = "invited";
23
23
  body.inviteCode = crypto.randomBytes(48).toString("base64url");
24
24
 
25
- if (auth0user.data[0]) {
25
+ if (auth0users[0]) {
26
26
  const userFound = await userService.getUserByOwner(
27
- auth0user.data[0].user_id,
27
+ auth0users[0].user_id,
28
28
  body.organization,
29
29
  );
30
30
  if (userFound) {
@@ -101,10 +101,8 @@ export const getCurrentUser = catchAsync(
101
101
  req: AuthRequest<{}, any, { organization?: string }>,
102
102
  res: Response,
103
103
  ) => {
104
- const result = await userService.getUserByOwner(
105
- req.auth.sub,
106
- req.query.organization,
107
- );
104
+ const organization = req.query.organization as string;
105
+ const result = await userService.getUserByOwner(req.auth.sub, organization);
108
106
  res.send(result);
109
107
  },
110
108
  );
@@ -181,9 +179,10 @@ export const getInvite = catchAsync(
181
179
  `User not found token: ${authReq.params.inviteCode}`,
182
180
  );
183
181
  }
182
+ const organizationId = String(user.organization);
184
183
  const already = await userService.getUserByOwner(
185
184
  authReq.auth.sub,
186
- user.organization,
185
+ organizationId,
187
186
  );
188
187
  if (already) {
189
188
  throw new ApiError(httpStatus.CONFLICT, "User already in organization");
@@ -222,7 +221,7 @@ export const organizationRemove = catchAsync(
222
221
  export const cleanup = catchAsync(async (_req: Request, res: Response) => {
223
222
  const all = await userService.queryAllCalendars();
224
223
  const filtered = all.filter((e) => e.organizationData === null);
225
- const ids = filtered.map((e) => e._id);
224
+ const ids = filtered.map((e) => String(e._id));
226
225
  const deleted = await userService.deleteMany(ids);
227
226
  res.send({
228
227
  deleted,
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import mongoose, { Schema, Document, Model, Types } from "mongoose";
2
3
  import validator from "validator";
3
4
  import { toJSON, paginate } from "../models/plugins/index.js";
@@ -9,9 +10,10 @@ export interface IUser {
9
10
  timezone: string;
10
11
  owner?: string;
11
12
  organization?: Types.ObjectId;
13
+ organizationData?: any;
12
14
  inviteCode?: string;
13
15
  email?: string;
14
- role: keyof typeof roles;
16
+ role: (typeof roles)[number];
15
17
  category: string;
16
18
  status?: string;
17
19
  meta?: Record<string, any>;
@@ -83,7 +85,6 @@ userSchema.methods.isPasswordMatch = async function (
83
85
  return false;
84
86
  };
85
87
 
86
- export const User = mongoose.model<IUserDocument, IUserModel>(
87
- "User",
88
- userSchema,
89
- );
88
+ export const User =
89
+ (mongoose.models.User as IUserModel) ||
90
+ mongoose.model<IUserDocument, IUserModel>("User", userSchema);
@@ -108,7 +108,6 @@ export const userRouteSpecs: RouteSpec[] = [
108
108
  privateDocs: true,
109
109
  summary: "Get invite details by code",
110
110
  description: "Retrieves information about a pending invite using its code.",
111
- privateDocs: true,
112
111
  },
113
112
  {
114
113
  method: "post",
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import httpStatus from "http-status";
2
3
  import type { FilterQuery, PaginateOptions } from "mongoose";
3
4
  import { User } from "./users.model.js";
@@ -315,6 +316,18 @@ export const updateInvite = async (params: {
315
316
  return user;
316
317
  };
317
318
 
319
+ /**
320
+ * Update a user's organization membership (placeholder for legacy callers)
321
+ */
322
+ export const organizationUpdate = async (
323
+ _body: any,
324
+ ): Promise<IUserDocument> => {
325
+ throw new ApiError(
326
+ httpStatus.NOT_IMPLEMENTED,
327
+ "organizationUpdate not implemented",
328
+ );
329
+ };
330
+
318
331
  /**
319
332
  * Remove a user from an organization
320
333
  */
@@ -383,6 +396,7 @@ export default {
383
396
  organizationInvite,
384
397
  getInvite,
385
398
  updateInvite,
399
+ organizationUpdate,
386
400
  organizationRemove,
387
401
  queryUsers,
388
402
  queryAllCalendars,
@@ -391,3 +405,5 @@ export default {
391
405
  populateAuth0User,
392
406
  populateAuth0Users,
393
407
  };
408
+
409
+ export type UserService = typeof import("./users.service");
@@ -0,0 +1 @@
1
+ export type User = any;
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import { z } from "zod";
2
3
  import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
3
4
  import { objectId, password } from "../validations/custom.validation.js";
@@ -5,6 +6,7 @@ import {
5
6
  zPagination,
6
7
  zGet,
7
8
  zObjectId,
9
+ zObjectIdFor,
8
10
  zPatchBody,
9
11
  zUpdate,
10
12
  zDelete,
@@ -49,9 +51,11 @@ export const createCurrentUserSchema = createUserSchema;
49
51
  export const queryUsersSchema = {
50
52
  ...zPagination,
51
53
  query: zPagination.query.extend({
52
- organization: zObjectId.optional().openapi({
54
+ organization: zObjectIdFor("organization").openapi({
53
55
  description: "Filter users by organization ObjectId",
54
- example: "60c72b2f9b1e8d001c8e4f3a",
56
+ example:
57
+ process.env.SCHEMA_EXAMPLE_ORGANIZATION_ID ||
58
+ "60c72b2f9b1e8d001c8e4f3a",
55
59
  }),
56
60
  }),
57
61
  };
@@ -1,8 +1,15 @@
1
+ // @ts-nocheck
1
2
  export class ApiError extends Error {
2
3
  statusCode: number;
3
4
  isOperational: boolean;
4
5
 
5
- constructor(statusCode: number, message: string, isOperational = true, stack = '', raw: any = null) {
6
+ constructor(
7
+ statusCode: number,
8
+ message: string,
9
+ isOperational = true,
10
+ stack = "",
11
+ raw: any = null,
12
+ ) {
6
13
  super(message);
7
14
  this.statusCode = statusCode;
8
15
  this.isOperational = isOperational;
@@ -1,28 +1,40 @@
1
- import { registry } from '../utils/registerOpenApi';
1
+ import type { RequestHandler, Router } from "express";
2
+ import { registry } from "../utils/registerOpenApi";
2
3
 
3
- import { validateZod } from '../middlewares/validateZod';
4
- import { bearerAuth, xApiKey } from '../utils/registerOpenApi';
4
+ import { validateZod } from "../middlewares/validateZod";
5
+ import { bearerAuth, xApiKey } from "../utils/registerOpenApi";
5
6
 
6
- import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
7
- import { z } from 'zod';
7
+ import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
8
+ import { z } from "zod";
9
+ import type { ZodTypeAny } from "zod";
8
10
 
9
11
  extendZodWithOpenApi(z);
10
12
 
11
- const roleValidatorNames = ['validateAiRole', 'validateAdmin'];
13
+ const roleValidatorNames = ["validateAiRole", "validateAdmin"];
12
14
  function hasRoleValidation(validators: Function[] = []): boolean {
13
15
  return validators.some((fn) => roleValidatorNames.includes(fn.name));
14
16
  }
15
17
 
16
18
  export type RouteSpec = {
17
- method: 'post';
19
+ method: "get" | "post" | "put" | "patch" | "delete" | "options" | "head";
18
20
  path: string;
19
- requestBody: AnyZodObject;
20
- responseSchema?: AnyZodObject;
21
- handler: RequestHandler;
21
+ validate?: RequestHandler<any, any, any, any, any>[];
22
+ validateWithRequestSchema?: RequestHandler<any, any, any, any, any>[];
23
+ requestSchema?: Partial<Record<string, ZodTypeAny>>;
24
+ responseSchema?: ZodTypeAny;
25
+ handler: RequestHandler<any, any, any, any, any>;
22
26
  summary: string;
27
+ description?: string;
28
+ privateDocs?: boolean;
29
+ memoOnly?: boolean;
23
30
  };
24
31
 
25
- export default function buildAiRouterAndDocs(router: Router, routeSpecs: any, basePath = '/', tags: string[] = []) {
32
+ export default function buildAiRouterAndDocs(
33
+ router: Router,
34
+ routeSpecs: any,
35
+ basePath = "/",
36
+ tags: string[] = [],
37
+ ) {
26
38
  routeSpecs.forEach((spec) => {
27
39
  // mount Express
28
40
 
@@ -31,11 +43,18 @@ export default function buildAiRouterAndDocs(router: Router, routeSpecs: any, ba
31
43
  }
32
44
 
33
45
  if (spec.requestSchema) {
34
- spec.validateWithRequestSchema = [validateZod(spec.requestSchema), ...spec.validate];
46
+ spec.validateWithRequestSchema = [
47
+ validateZod(spec.requestSchema),
48
+ ...spec.validate,
49
+ ];
35
50
  }
36
51
 
37
52
  if (spec.validateWithRequestSchema) {
38
- router[spec.method](spec.path, ...spec.validateWithRequestSchema, spec.handler);
53
+ router[spec.method](
54
+ spec.path,
55
+ ...spec.validateWithRequestSchema,
56
+ spec.handler,
57
+ );
39
58
  }
40
59
 
41
60
  var { body, ...rest } = spec.requestSchema || {};
@@ -43,37 +62,53 @@ export default function buildAiRouterAndDocs(router: Router, routeSpecs: any, ba
43
62
  if (body) {
44
63
  rest.body = {
45
64
  content: {
46
- 'application/json': {
65
+ "application/json": {
47
66
  schema: body,
48
67
  },
49
68
  },
50
69
  };
51
70
  }
52
71
 
53
- // console.log('spec.requestSchema', body);
72
+ console.log("spec.requestScbn");
54
73
 
55
- if (spec.responseSchema && !hasRoleValidation(spec.validate) && spec.privateDocs !== true && spec.memoOnly !== true) {
74
+ if (
75
+ spec.responseSchema &&
76
+ !hasRoleValidation(spec.validate) &&
77
+ spec.privateDocs !== true &&
78
+ spec.memoOnly !== true
79
+ ) {
56
80
  // collect all middleware fn names (falls back to '<anonymous>' if unnamed)
57
- const middlewareNames = (spec.validate || []).map((fn) => `\`${fn.name}\`` || '<anonymous>');
81
+ const middlewareNames = (spec.validate || []).map(
82
+ (fn) => `\`${fn.name}\`` || "<anonymous>",
83
+ );
84
+ const openApiPath = (basePath + spec.path).replace(
85
+ /:([A-Za-z0-9_]+)/g,
86
+ "{$1}",
87
+ );
58
88
 
59
89
  registry.registerPath({
60
90
  method: spec.method,
61
- path: basePath + spec.path,
91
+ path: openApiPath,
62
92
  summary: spec.summary,
63
93
  request: rest,
64
94
 
65
95
  // append middleware names to the description
66
- description: [spec.description, `\n\nMiddlewares: ${middlewareNames.join(', ')}`].filter(Boolean).join('\n'),
96
+ description: [
97
+ spec.description,
98
+ `\n\nMiddlewares: ${middlewareNames.join(", ")}`,
99
+ ]
100
+ .filter(Boolean)
101
+ .join("\n"),
67
102
 
68
103
  // (optionally) expose them as a custom extension instead:
69
- 'x-middlewares': middlewareNames,
104
+ "x-middlewares": middlewareNames,
70
105
 
71
106
  security: [{ [bearerAuth.name]: [] }, { [xApiKey.name]: [] }],
72
107
  responses: {
73
108
  200: {
74
- description: 'Object with user data.',
109
+ description: "Object with user data.",
75
110
  content: {
76
- 'application/json': { schema: spec.responseSchema },
111
+ "application/json": { schema: spec.responseSchema },
77
112
  },
78
113
  },
79
114
  },
@@ -1,8 +1,32 @@
1
- import type { Request, Response, NextFunction } from 'express';
1
+ import type { Request, Response, NextFunction } from "express";
2
+
3
+ type AsyncRequestHandler<
4
+ P = any,
5
+ ResBody = any,
6
+ ReqBody = any,
7
+ ReqQuery = any,
8
+ Locals extends Record<string, any> = Record<string, any>,
9
+ > = (
10
+ req: Request<P, ResBody, ReqBody, ReqQuery, Locals>,
11
+ res: Response<ResBody, Locals>,
12
+ next: NextFunction,
13
+ ) => Promise<any>;
2
14
 
3
15
  const catchAsync =
4
- (fn: (req: Request, res: Response, next: NextFunction) => Promise<any>) =>
5
- (req: Request, res: Response, next: NextFunction): void => {
16
+ <
17
+ P = any,
18
+ ResBody = any,
19
+ ReqBody = any,
20
+ ReqQuery = any,
21
+ Locals extends Record<string, any> = Record<string, any>,
22
+ >(
23
+ fn: AsyncRequestHandler<P, ResBody, ReqBody, ReqQuery, Locals>,
24
+ ) =>
25
+ (
26
+ req: Request<P, ResBody, ReqBody, ReqQuery, Locals>,
27
+ res: Response<ResBody, Locals>,
28
+ next: NextFunction,
29
+ ): void => {
6
30
  Promise.resolve(fn(req, res, next)).catch((err) => next(err));
7
31
  };
8
32
 
@@ -1,12 +1,13 @@
1
- import i18n from '../i18n/i18n';
2
- import type { MedicationEntry } from '../types/MedicationEntry';
1
+ // @ts-nocheck
2
+ import i18n from "../i18n/i18n";
3
+ import type { MedicationEntry } from "../types/MedicationEntry";
3
4
 
4
5
  export const medicationName = (entry: MedicationEntry, lng: string): string => {
5
6
  const name = entry.medicationData?.Kurzname
6
7
  ? entry.medicationData.Kurzname
7
8
  : entry.localMedicationData?.meta?.name
8
- ? entry.localMedicationData.meta.name.replace(/ .*/, '')
9
- : i18n.t('A medication', { lng });
9
+ ? entry.localMedicationData.meta.name.replace(/ .*/, "")
10
+ : i18n.t("A medication", { lng });
10
11
 
11
12
  return name;
12
13
  };
package/src/utils/pick.ts CHANGED
@@ -4,7 +4,11 @@
4
4
  * @param {string[]} keys - The keys to pick
5
5
  * @returns {Partial<Record<string, any>>} - The new object with picked properties
6
6
  */
7
- const pick = <T extends Record<string, any>>(object: T, keys: (keyof T)[]): Partial<T> => {
7
+ // @ts-nocheck
8
+ const pick = <T extends Record<string, any>>(
9
+ object: T,
10
+ keys: string[],
11
+ ): Partial<T> => {
8
12
  return keys.reduce((obj, key) => {
9
13
  if (object && Object.prototype.hasOwnProperty.call(object, key)) {
10
14
  obj[key] = object[key];
@@ -1,32 +1,83 @@
1
- import { OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
1
+ import { OpenAPIRegistry } from "@asteasolutions/zod-to-openapi";
2
+ import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
3
+ import { z } from "zod";
4
+
5
+ extendZodWithOpenApi(z);
2
6
 
3
7
  export const registry = new OpenAPIRegistry();
4
8
 
5
9
  // add Bearer JWT auth
6
- export const bearerAuth = registry.registerComponent('securitySchemes', 'bearerAuth', {
7
- type: 'http',
8
- scheme: 'bearer',
9
- bearerFormat: 'JWT',
10
- description: 'JWT Bearer authentication',
11
- });
10
+ export const bearerAuth = registry.registerComponent(
11
+ "securitySchemes",
12
+ "bearerAuth",
13
+ {
14
+ type: "http",
15
+ scheme: "bearer",
16
+ bearerFormat: "JWT",
17
+ description: "JWT Bearer authentication",
18
+ },
19
+ );
20
+
21
+ export const xApiKey = registry.registerComponent(
22
+ "securitySchemes",
23
+ "x-api-key",
24
+ {
25
+ type: "apiKey",
26
+ in: "header",
27
+ name: "x-api-key",
28
+ description: "API key for authentication",
29
+ },
30
+ );
31
+
32
+ const UserSchema = z
33
+ .object({
34
+ id: z.string().openapi({ example: "1212121" }),
35
+ name: z.string().openapi({ example: "John Doe" }),
36
+ age: z.number().openapi({ example: 42 }),
37
+ })
38
+ .openapi("User");
39
+
40
+ registry.registerPath({
41
+ method: "get",
42
+ path: "/usersnnn/{id}",
43
+ summary: "Get a single user",
44
+ request: {
45
+ params: z.object({ id: z.string() }),
46
+ },
12
47
 
13
- export const xApiKey = registry.registerComponent('securitySchemes', 'x-api-key', {
14
- type: 'apiKey',
15
- in: 'header',
16
- name: 'x-api-key',
17
- description: 'API key for authentication',
48
+ responses: {
49
+ 200: {
50
+ description: "Object with user data.",
51
+ content: {
52
+ "application/json": {
53
+ schema: UserSchema,
54
+ },
55
+ },
56
+ },
57
+ },
18
58
  });
19
59
 
20
- /*
21
- registry.registerComponent('global', 'wwww', [
22
- { name: 'ai', description: 'All AI-powered endpoints.' },
23
- { name: 'auth', description: 'Authentication and authorization.' },
24
- { name: 'Users', description: 'User management (create, read, update, delete).' },
25
- // add more as needed
26
- ]);
27
-
28
- registry.registerComponent('tag', 'users', {
29
- name: 'users',
30
- description: 'Operations about users',
60
+ registry.registerPath({
61
+ method: "get",
62
+ path: "/users/{id}",
63
+ description: "Get user data by its id",
64
+ summary: "Get a single user",
65
+ request: {
66
+ params: z.object({
67
+ id: z.string().openapi({ example: "1212121" }),
68
+ }),
69
+ },
70
+ responses: {
71
+ 200: {
72
+ description: "Object with user data.",
73
+ content: {
74
+ "application/json": {
75
+ schema: UserSchema,
76
+ },
77
+ },
78
+ },
79
+ 204: {
80
+ description: "No content - successful operation",
81
+ },
82
+ },
31
83
  });
32
- */
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import { getUserById } from "../accounts/auth0.service";
2
3
  import type { Patient } from "../types/patient"; // Assuming a `Patient` type exists in your project
3
4