@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.
- package/dist/src/accounts/accounts.controller.js +89 -0
- package/dist/src/accounts/accounts.route.js +101 -0
- package/dist/src/accounts/accounts.schemas.js +12 -0
- package/dist/src/accounts/accounts.service.js +65 -0
- package/dist/src/accounts/accounts.validation.js +99 -0
- package/dist/src/accounts/auth0.service.js +188 -0
- package/dist/src/config/config.js +48 -0
- package/dist/src/config/logger.js +27 -0
- package/dist/src/config/morgan.js +16 -0
- package/dist/src/config/passport.cjs +28 -0
- package/dist/src/config/roles.js +11 -0
- package/dist/src/config/tokens.cjs +10 -0
- package/dist/src/devices/devices.controller.js +172 -0
- package/dist/src/devices/devices.model.js +94 -0
- package/dist/src/devices/devices.route.js +153 -0
- package/dist/src/devices/devices.schemas.js +84 -0
- package/dist/src/devices/devices.service.js +198 -0
- package/dist/src/devices/devices.types.js +1 -0
- package/dist/src/devices/devices.validation.js +257 -0
- package/dist/src/devicesNotifications/devicesNotifications.controller.js +69 -0
- package/dist/src/devicesNotifications/devicesNotifications.model.js +39 -0
- package/dist/src/devicesNotifications/devicesNotifications.route.js +124 -0
- package/dist/src/devicesNotifications/devicesNotifications.schemas.js +10 -0
- package/dist/src/devicesNotifications/devicesNotifications.service.js +181 -0
- package/dist/src/devicesNotifications/devicesNotifications.validation.js +46 -0
- package/dist/src/email/email.service.js +580 -0
- package/dist/src/files/upload.service.js +124 -0
- package/dist/src/i18n/i18n.js +38 -0
- package/dist/src/i18n/saveMissingLocalJsonBackend.js +53 -0
- package/dist/src/i18n/types.js +1 -0
- package/dist/src/index.js +48 -0
- package/dist/src/iotdevice/iotdevice.controller.js +96 -0
- package/dist/src/iotdevice/iotdevice.model.js +17 -0
- package/dist/src/iotdevice/iotdevice.route.js +143 -0
- package/dist/src/iotdevice/iotdevice.schemas.js +60 -0
- package/dist/src/iotdevice/iotdevice.service.js +579 -0
- package/dist/src/iotdevice/iotdevice.types.js +1 -0
- package/dist/src/iotdevice/iotdevice.validation.js +54 -0
- package/dist/src/middlewares/auth.js +75 -0
- package/dist/src/middlewares/checkJwt.cjs +17 -0
- package/dist/src/middlewares/error.js +36 -0
- package/dist/src/middlewares/mongooseValidations/ensureSameOrganization.js +13 -0
- package/dist/src/middlewares/rateLimiter.js +7 -0
- package/dist/src/middlewares/validate.js +18 -0
- package/dist/src/middlewares/validateAction.js +35 -0
- package/dist/src/middlewares/validateAdmin.js +18 -0
- package/dist/src/middlewares/validateAi.js +16 -0
- package/dist/src/middlewares/validateCurrentAuthUser.js +17 -0
- package/dist/src/middlewares/validateCurrentUser.js +20 -0
- package/dist/src/middlewares/validateDevice.js +98 -0
- package/dist/src/middlewares/validateDeviceUserOrganization.js +26 -0
- package/dist/src/middlewares/validateOrganization.js +63 -0
- package/dist/src/middlewares/validateQuerySearchUserAndOrganization.js +44 -0
- package/dist/src/middlewares/validateTokens.js +23 -0
- package/dist/src/middlewares/validateUser.js +38 -0
- package/dist/src/middlewares/validateZod.js +33 -0
- package/dist/src/models/plugins/index.js +4 -0
- package/dist/src/models/plugins/paginate.plugin.js +117 -0
- package/dist/src/models/plugins/paginateNew.plugin.js +185 -0
- package/dist/src/models/plugins/simplePopulate.js +16 -0
- package/dist/src/models/plugins/toJSON.plugin.js +35 -0
- package/dist/src/organizations/organizations.controller.js +64 -0
- package/dist/src/organizations/organizations.model.js +41 -0
- package/dist/src/organizations/organizations.route.js +98 -0
- package/dist/src/organizations/organizations.schemas.js +7 -0
- package/dist/src/organizations/organizations.service.js +59 -0
- package/dist/src/organizations/organizations.validation.js +62 -0
- package/dist/src/pdf/pdf.controller.js +24 -0
- package/dist/src/pdf/pdf.route.js +22 -0
- package/dist/src/pdf/pdf.schemas.js +6 -0
- package/dist/src/pdf/pdf.service.js +65 -0
- package/dist/src/pdf/pdf.validation.js +27 -0
- package/dist/src/tokens/tokens.controller.js +60 -0
- package/dist/src/tokens/tokens.model.js +17 -0
- package/dist/src/tokens/tokens.route.js +52 -0
- package/dist/src/tokens/tokens.schemas.js +14 -0
- package/dist/src/tokens/tokens.service.js +30 -0
- package/dist/src/tokens/tokens.validation.js +9 -0
- package/dist/src/types/routeSpec.js +1 -0
- package/dist/src/users/users.controller.js +147 -0
- package/dist/src/users/users.model.js +50 -0
- package/dist/src/users/users.route.js +137 -0
- package/dist/src/users/users.schemas.js +69 -0
- package/dist/src/users/users.service.js +295 -0
- package/dist/src/users/users.types.js +1 -0
- package/dist/src/users/users.validation.js +144 -0
- package/dist/src/utils/ApiError.js +16 -0
- package/dist/src/utils/buildRouterAndDocs.js +72 -0
- package/dist/src/utils/catchAsync.js +4 -0
- package/dist/src/utils/comparePapers.service.js +32 -0
- package/dist/src/utils/deviceUtils.js +63 -0
- package/dist/src/utils/filterOptions.js +24 -0
- package/dist/src/utils/medicationName.js +10 -0
- package/dist/src/utils/pick.js +16 -0
- package/dist/src/utils/registerOpenApi.js +67 -0
- package/dist/src/utils/urlUtils.js +15 -0
- package/dist/src/utils/userName.js +22 -0
- package/dist/src/utils/zValidations.js +143 -0
- package/dist/src/validations/auth.validation.cjs +53 -0
- package/dist/src/validations/custom.validation.js +19 -0
- package/dist/src/validations/index.cjs +3 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +97 -80
- package/scripts/release-and-sync-paperless.mjs +137 -0
- package/src/accounts/accounts.controller.ts +1 -0
- package/src/accounts/accounts.service.ts +1 -0
- package/src/accounts/accounts.validation.ts +8 -5
- package/src/accounts/auth0.service.ts +55 -28
- package/src/config/config.ts +6 -0
- package/src/config/logger.ts +15 -9
- package/src/devices/devices.controller.ts +7 -1
- package/src/devices/devices.model.ts +4 -1
- package/src/devices/devices.schemas.ts +11 -9
- package/src/devices/devices.service.ts +1 -0
- package/src/devices/devices.types.ts +1 -0
- package/src/devices/devices.validation.ts +93 -32
- package/src/devicesNotifications/devicesNotifications.controller.ts +57 -28
- package/src/devicesNotifications/devicesNotifications.model.ts +20 -12
- package/src/devicesNotifications/devicesNotifications.service.ts +35 -17
- package/src/files/upload.service.ts +52 -28
- package/src/i18n/i18n.ts +1 -1
- package/src/i18n/types.ts +1 -0
- package/src/index.ts +47 -0
- package/src/iotdevice/iotdevice.controller.ts +1 -0
- package/src/iotdevice/iotdevice.model.ts +6 -3
- package/src/iotdevice/iotdevice.route.ts +85 -76
- package/src/iotdevice/iotdevice.service.ts +4 -3
- package/src/iotdevice/iotdevice.types.ts +6 -0
- package/src/middlewares/auth.ts +2 -8
- package/src/middlewares/error.ts +26 -12
- package/src/middlewares/mongooseValidations/ensureSameOrganization.ts +4 -3
- package/src/middlewares/validateAi.ts +17 -9
- package/src/middlewares/validateDevice.ts +1 -0
- package/src/middlewares/validateDeviceUserOrganization.ts +1 -0
- package/src/middlewares/validateOrganization.ts +1 -1
- package/src/middlewares/validateQuerySearchUserAndOrganization.ts +1 -0
- package/src/middlewares/validateTokens.ts +2 -1
- package/src/middlewares/validateUser.ts +1 -0
- package/src/middlewares/validateZod.ts +5 -5
- package/src/models/plugins/index.ts +5 -4
- package/src/models/plugins/paginate.plugin.ts +26 -16
- package/src/models/plugins/paginateNew.plugin.ts +33 -21
- package/src/models/plugins/simplePopulate.ts +8 -3
- package/src/models/plugins/toJSON.plugin.ts +12 -5
- package/src/organizations/organizations.controller.ts +1 -2
- package/src/organizations/organizations.model.ts +4 -4
- package/src/organizations/organizations.route.ts +1 -1
- package/src/organizations/organizations.service.ts +15 -6
- package/src/organizations/organizations.validation.ts +1 -1
- package/src/pdf/pdf.controller.ts +18 -1
- package/src/pdf/pdf.service.ts +25 -16
- package/src/tokens/tokens.controller.ts +6 -8
- package/src/tokens/tokens.model.ts +3 -1
- package/src/tokens/tokens.service.ts +3 -2
- package/src/types/express.d.ts +17 -0
- package/src/types/mongoose.d.ts +22 -0
- package/src/users/users.controller.ts +8 -9
- package/src/users/users.model.ts +6 -5
- package/src/users/users.route.ts +0 -1
- package/src/users/users.service.ts +16 -0
- package/src/users/users.types.ts +1 -0
- package/src/users/users.validation.ts +6 -2
- package/src/utils/ApiError.ts +8 -1
- package/src/utils/buildRouterAndDocs.ts +57 -22
- package/src/utils/catchAsync.ts +27 -3
- package/src/utils/medicationName.ts +5 -4
- package/src/utils/pick.ts +5 -1
- package/src/utils/registerOpenApi.ts +75 -24
- package/src/utils/userName.ts +1 -0
- package/src/utils/zValidations.ts +98 -27
- 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> =
|
|
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,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
|
|
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 (
|
|
25
|
+
if (auth0users[0]) {
|
|
26
26
|
const userFound = await userService.getUserByOwner(
|
|
27
|
-
|
|
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
|
|
105
|
-
|
|
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
|
-
|
|
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,
|
package/src/users/users.model.ts
CHANGED
|
@@ -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:
|
|
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 =
|
|
87
|
-
|
|
88
|
-
userSchema
|
|
89
|
-
);
|
|
88
|
+
export const User =
|
|
89
|
+
(mongoose.models.User as IUserModel) ||
|
|
90
|
+
mongoose.model<IUserDocument, IUserModel>("User", userSchema);
|
package/src/users/users.route.ts
CHANGED
|
@@ -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:
|
|
54
|
+
organization: zObjectIdFor("organization").openapi({
|
|
53
55
|
description: "Filter users by organization ObjectId",
|
|
54
|
-
example:
|
|
56
|
+
example:
|
|
57
|
+
process.env.SCHEMA_EXAMPLE_ORGANIZATION_ID ||
|
|
58
|
+
"60c72b2f9b1e8d001c8e4f3a",
|
|
55
59
|
}),
|
|
56
60
|
}),
|
|
57
61
|
};
|
package/src/utils/ApiError.ts
CHANGED
|
@@ -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(
|
|
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 {
|
|
1
|
+
import type { RequestHandler, Router } from "express";
|
|
2
|
+
import { registry } from "../utils/registerOpenApi";
|
|
2
3
|
|
|
3
|
-
import { validateZod } from
|
|
4
|
-
import { bearerAuth, xApiKey } from
|
|
4
|
+
import { validateZod } from "../middlewares/validateZod";
|
|
5
|
+
import { bearerAuth, xApiKey } from "../utils/registerOpenApi";
|
|
5
6
|
|
|
6
|
-
import { extendZodWithOpenApi } from
|
|
7
|
-
import { z } from
|
|
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 = [
|
|
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:
|
|
19
|
+
method: "get" | "post" | "put" | "patch" | "delete" | "options" | "head";
|
|
18
20
|
path: string;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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(
|
|
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 = [
|
|
46
|
+
spec.validateWithRequestSchema = [
|
|
47
|
+
validateZod(spec.requestSchema),
|
|
48
|
+
...spec.validate,
|
|
49
|
+
];
|
|
35
50
|
}
|
|
36
51
|
|
|
37
52
|
if (spec.validateWithRequestSchema) {
|
|
38
|
-
router[spec.method](
|
|
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
|
-
|
|
65
|
+
"application/json": {
|
|
47
66
|
schema: body,
|
|
48
67
|
},
|
|
49
68
|
},
|
|
50
69
|
};
|
|
51
70
|
}
|
|
52
71
|
|
|
53
|
-
|
|
72
|
+
console.log("spec.requestScbn");
|
|
54
73
|
|
|
55
|
-
if (
|
|
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(
|
|
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:
|
|
91
|
+
path: openApiPath,
|
|
62
92
|
summary: spec.summary,
|
|
63
93
|
request: rest,
|
|
64
94
|
|
|
65
95
|
// append middleware names to the description
|
|
66
|
-
description: [
|
|
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
|
-
|
|
104
|
+
"x-middlewares": middlewareNames,
|
|
70
105
|
|
|
71
106
|
security: [{ [bearerAuth.name]: [] }, { [xApiKey.name]: [] }],
|
|
72
107
|
responses: {
|
|
73
108
|
200: {
|
|
74
|
-
description:
|
|
109
|
+
description: "Object with user data.",
|
|
75
110
|
content: {
|
|
76
|
-
|
|
111
|
+
"application/json": { schema: spec.responseSchema },
|
|
77
112
|
},
|
|
78
113
|
},
|
|
79
114
|
},
|
package/src/utils/catchAsync.ts
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
|
-
import type { Request, Response, NextFunction } from
|
|
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
|
-
|
|
5
|
-
|
|
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
|
-
|
|
2
|
-
import
|
|
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(
|
|
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
|
-
|
|
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
|
|
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(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
*/
|
package/src/utils/userName.ts
CHANGED