@adaptivestone/framework 5.0.0-beta.4 → 5.0.0-beta.40
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/CHANGELOG.md +1107 -528
- package/LICENCE +1 -1
- package/dist/Cli.d.ts +7 -0
- package/dist/Cli.js +19 -0
- package/dist/Cli.js.map +1 -0
- package/dist/cluster.d.ts +1 -0
- package/dist/cluster.js +18 -0
- package/dist/cluster.js.map +1 -0
- package/dist/commands/CreateUser.d.ts +32 -0
- package/dist/commands/CreateUser.js +83 -0
- package/dist/commands/CreateUser.js.map +1 -0
- package/dist/commands/Documentation.d.ts +5 -0
- package/dist/commands/Documentation.js +15 -0
- package/dist/commands/Documentation.js.map +1 -0
- package/dist/commands/DropIndex.d.ts +16 -0
- package/dist/commands/DropIndex.js +30 -0
- package/dist/commands/DropIndex.js.map +1 -0
- package/dist/commands/GenerateRandomBytes.d.ts +7 -0
- package/dist/commands/GenerateRandomBytes.js +18 -0
- package/dist/commands/GenerateRandomBytes.js.map +1 -0
- package/dist/commands/GenerateTypes.d.ts +11 -0
- package/dist/commands/GenerateTypes.js +52 -0
- package/dist/commands/GenerateTypes.js.map +1 -0
- package/dist/commands/GetOpenApiJson.d.ts +17 -0
- package/dist/commands/GetOpenApiJson.js +272 -0
- package/dist/commands/GetOpenApiJson.js.map +1 -0
- package/dist/commands/SyncIndexes.d.ts +6 -0
- package/dist/commands/SyncIndexes.js +31 -0
- package/dist/commands/SyncIndexes.js.map +1 -0
- package/dist/commands/migration/Create.d.ts +18 -0
- package/dist/commands/migration/Create.js +57 -0
- package/dist/commands/migration/Create.js.map +1 -0
- package/dist/commands/migration/Migrate.d.ts +6 -0
- package/dist/commands/migration/Migrate.js +43 -0
- package/dist/commands/migration/Migrate.js.map +1 -0
- package/dist/config/auth.d.ts +6 -0
- package/dist/config/auth.js +7 -0
- package/dist/config/auth.js.map +1 -0
- package/dist/config/http.d.ts +8 -0
- package/dist/config/http.js +10 -0
- package/dist/config/http.js.map +1 -0
- package/dist/config/i18n.d.ts +13 -0
- package/dist/config/i18n.js +13 -0
- package/dist/config/i18n.js.map +1 -0
- package/dist/config/ipDetector.d.ts +5 -0
- package/dist/config/ipDetector.js +15 -0
- package/dist/config/ipDetector.js.map +1 -0
- package/dist/config/log.d.ts +11 -0
- package/dist/config/log.js +20 -0
- package/dist/config/log.js.map +1 -0
- package/dist/config/mongo.d.ts +4 -0
- package/dist/config/mongo.js +4 -0
- package/dist/config/mongo.js.map +1 -0
- package/dist/config/rateLimiter.d.ts +13 -0
- package/dist/config/rateLimiter.js +17 -0
- package/dist/config/rateLimiter.js.map +1 -0
- package/dist/config/redis.d.ts +5 -0
- package/dist/config/redis.js +5 -0
- package/dist/config/redis.js.map +1 -0
- package/dist/config/validate.d.ts +4 -0
- package/dist/config/validate.js +4 -0
- package/dist/config/validate.js.map +1 -0
- package/dist/controllers/Auth.d.ts +131 -0
- package/dist/controllers/Auth.js +186 -0
- package/dist/controllers/Auth.js.map +1 -0
- package/dist/controllers/Home.d.ts +15 -0
- package/dist/controllers/Home.js +22 -0
- package/dist/controllers/Home.js.map +1 -0
- package/dist/controllers/index.d.ts +16 -0
- package/dist/controllers/index.js +59 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/folderConfig.d.ts +34 -0
- package/dist/folderConfig.js +14 -0
- package/dist/folderConfig.js.map +1 -0
- package/dist/helpers/appInstance.d.ts +3 -0
- package/dist/helpers/appInstance.js +8 -0
- package/dist/helpers/appInstance.js.map +1 -0
- package/dist/helpers/crypto.d.ts +3 -0
- package/dist/helpers/crypto.js +17 -0
- package/dist/helpers/crypto.js.map +1 -0
- package/dist/helpers/files.d.ts +16 -0
- package/dist/helpers/files.js +76 -0
- package/dist/helpers/files.js.map +1 -0
- package/dist/helpers/logger.d.ts +4 -0
- package/dist/helpers/logger.js +20 -0
- package/dist/helpers/logger.js.map +1 -0
- package/dist/helpers/redis/clearNamespace.d.ts +2 -0
- package/dist/helpers/redis/clearNamespace.js +14 -0
- package/dist/helpers/redis/clearNamespace.js.map +1 -0
- package/dist/helpers/yup.d.ts +13 -0
- package/dist/helpers/yup.js +21 -0
- package/dist/helpers/yup.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/models/Lock.d.ts +90 -0
- package/dist/models/Lock.js +97 -0
- package/dist/models/Lock.js.map +1 -0
- package/dist/models/Migration.d.ts +13 -0
- package/dist/models/Migration.js +14 -0
- package/dist/models/Migration.js.map +1 -0
- package/dist/models/Sequence.d.ts +28 -0
- package/dist/models/Sequence.js +19 -0
- package/dist/models/Sequence.js.map +1 -0
- package/dist/models/User.d.ts +656 -0
- package/dist/models/User.js +291 -0
- package/dist/models/User.js.map +1 -0
- package/dist/models/UserOld.d.ts +179 -0
- package/dist/models/UserOld.js +230 -0
- package/dist/models/UserOld.js.map +1 -0
- package/dist/modules/AbstractCommand.d.ts +51 -0
- package/dist/modules/AbstractCommand.js +60 -0
- package/dist/modules/AbstractCommand.js.map +1 -0
- package/dist/modules/AbstractConnector.d.ts +5 -0
- package/dist/modules/AbstractConnector.js +8 -0
- package/dist/modules/AbstractConnector.js.map +1 -0
- package/dist/modules/AbstractController.d.ts +94 -0
- package/dist/modules/AbstractController.js +323 -0
- package/dist/modules/AbstractController.js.map +1 -0
- package/dist/modules/AbstractModel.d.ts +29 -0
- package/dist/modules/AbstractModel.js +42 -0
- package/dist/modules/AbstractModel.js.map +1 -0
- package/dist/modules/Base.d.ts +29 -0
- package/dist/modules/Base.js +58 -0
- package/dist/modules/Base.js.map +1 -0
- package/dist/modules/BaseCli.d.ts +25 -0
- package/dist/modules/BaseCli.js +147 -0
- package/dist/modules/BaseCli.js.map +1 -0
- package/dist/modules/BaseModel.d.ts +55 -0
- package/dist/modules/BaseModel.js +37 -0
- package/dist/modules/BaseModel.js.map +1 -0
- package/dist/server.d.ts +123 -0
- package/dist/server.js +468 -0
- package/dist/server.js.map +1 -0
- package/dist/services/cache/Cache.d.ts +31 -0
- package/dist/services/cache/Cache.js +113 -0
- package/dist/services/cache/Cache.js.map +1 -0
- package/dist/services/documentation/DocumentationGenerator.d.ts +11 -0
- package/dist/services/documentation/DocumentationGenerator.js +130 -0
- package/dist/services/documentation/DocumentationGenerator.js.map +1 -0
- package/dist/services/http/HttpServer.d.ts +35 -0
- package/dist/services/http/HttpServer.js +70 -0
- package/dist/services/http/HttpServer.js.map +1 -0
- package/dist/services/http/middleware/AbstractMiddleware.d.ts +25 -0
- package/dist/services/http/middleware/AbstractMiddleware.js +41 -0
- package/dist/services/http/middleware/AbstractMiddleware.js.map +1 -0
- package/dist/services/http/middleware/Auth.d.ts +9 -0
- package/dist/services/http/middleware/Auth.js +18 -0
- package/dist/services/http/middleware/Auth.js.map +1 -0
- package/dist/services/http/middleware/Cors.d.ts +12 -0
- package/dist/services/http/middleware/Cors.js +36 -0
- package/dist/services/http/middleware/Cors.js.map +1 -0
- package/dist/services/http/middleware/GetUserByToken.d.ts +20 -0
- package/dist/services/http/middleware/GetUserByToken.js +39 -0
- package/dist/services/http/middleware/GetUserByToken.js.map +1 -0
- package/dist/services/http/middleware/I18n.d.ts +23 -0
- package/dist/services/http/middleware/I18n.js +61 -0
- package/dist/services/http/middleware/I18n.js.map +1 -0
- package/dist/services/http/middleware/IpDetector.d.ts +14 -0
- package/dist/services/http/middleware/IpDetector.js +55 -0
- package/dist/services/http/middleware/IpDetector.js.map +1 -0
- package/dist/services/http/middleware/Pagination.d.ts +27 -0
- package/dist/services/http/middleware/Pagination.js +46 -0
- package/dist/services/http/middleware/Pagination.js.map +1 -0
- package/dist/services/http/middleware/PrepareAppInfo.d.ts +8 -0
- package/dist/services/http/middleware/PrepareAppInfo.js +17 -0
- package/dist/services/http/middleware/PrepareAppInfo.js.map +1 -0
- package/dist/services/http/middleware/RateLimiter.d.ts +26 -0
- package/dist/services/http/middleware/RateLimiter.js +118 -0
- package/dist/services/http/middleware/RateLimiter.js.map +1 -0
- package/dist/services/http/middleware/RequestLogger.d.ts +8 -0
- package/dist/services/http/middleware/RequestLogger.js +18 -0
- package/dist/services/http/middleware/RequestLogger.js.map +1 -0
- package/dist/services/http/middleware/RequestParser.d.ts +8 -0
- package/dist/services/http/middleware/RequestParser.js +35 -0
- package/dist/services/http/middleware/RequestParser.js.map +1 -0
- package/dist/services/http/middleware/Role.d.ts +12 -0
- package/dist/services/http/middleware/Role.js +24 -0
- package/dist/services/http/middleware/Role.js.map +1 -0
- package/dist/services/i18n/I18n.d.ts +15 -0
- package/dist/services/i18n/I18n.js +58 -0
- package/dist/services/i18n/I18n.js.map +1 -0
- package/dist/services/logging/SentryTransport.d.ts +14 -0
- package/dist/services/logging/SentryTransport.js +57 -0
- package/dist/services/logging/SentryTransport.js.map +1 -0
- package/dist/services/validate/ValidateService.d.ts +31 -0
- package/dist/services/validate/ValidateService.js +95 -0
- package/dist/services/validate/ValidateService.js.map +1 -0
- package/dist/services/validate/drivers/AbstractValidator.d.ts +14 -0
- package/dist/services/validate/drivers/AbstractValidator.js +29 -0
- package/dist/services/validate/drivers/AbstractValidator.js.map +1 -0
- package/dist/services/validate/drivers/CustomValidator.d.ts +14 -0
- package/dist/services/validate/drivers/CustomValidator.js +48 -0
- package/dist/services/validate/drivers/CustomValidator.js.map +1 -0
- package/dist/services/validate/drivers/YupValidator.d.ts +13 -0
- package/dist/services/validate/drivers/YupValidator.js +86 -0
- package/dist/services/validate/drivers/YupValidator.js.map +1 -0
- package/dist/tests/frameworkVitestSetup.d.ts +1 -0
- package/dist/tests/frameworkVitestSetup.js +9 -0
- package/dist/tests/frameworkVitestSetup.js.map +1 -0
- package/dist/tests/globalSetupVitest.d.ts +3 -0
- package/dist/tests/globalSetupVitest.js +29 -0
- package/dist/tests/globalSetupVitest.js.map +1 -0
- package/dist/tests/setupVitest.d.ts +1 -0
- package/dist/tests/setupVitest.js +91 -0
- package/dist/tests/setupVitest.js.map +1 -0
- package/dist/tests/testHelpers.d.ts +340 -0
- package/dist/tests/testHelpers.js +48 -0
- package/dist/tests/testHelpers.js.map +1 -0
- package/package.json +45 -39
- package/Cli.js +0 -22
- package/cluster.js +0 -27
- package/commands/CreateUser.js +0 -75
- package/commands/Documentation.js +0 -17
- package/commands/DropIndex.js +0 -29
- package/commands/GenerateRandomBytes.js +0 -21
- package/commands/GetOpenApiJson.js +0 -325
- package/commands/SyncIndexes.js +0 -39
- package/commands/migration/Create.js +0 -61
- package/commands/migration/Migrate.js +0 -55
- package/config/auth.js +0 -9
- package/config/http.js +0 -9
- package/config/i18n.js +0 -12
- package/config/ipDetector.js +0 -14
- package/config/log.js +0 -22
- package/config/mail.js +0 -29
- package/config/mongo.js +0 -3
- package/config/rateLimiter.js +0 -16
- package/config/redis.js +0 -4
- package/config/validate.js +0 -3
- package/controllers/Auth.js +0 -210
- package/controllers/Home.js +0 -28
- package/controllers/index.js +0 -60
- package/folderConfig.js +0 -14
- package/helpers/files.js +0 -79
- package/helpers/logger.js +0 -17
- package/helpers/redis/clearNamespace.js +0 -14
- package/helpers/yup.js +0 -24
- package/index.js +0 -8
- package/jsconfig.json +0 -9
- package/locales/en/translation.json +0 -27
- package/locales/ru/translation.json +0 -27
- package/migrations/.gitkeep +0 -0
- package/models/Migration.js +0 -15
- package/models/Sequence.js +0 -22
- package/models/User.js +0 -263
- package/modules/AbstractCommand.js +0 -43
- package/modules/AbstractConnector.js +0 -9
- package/modules/AbstractController.js +0 -413
- package/modules/AbstractModel.d.ts +0 -48
- package/modules/AbstractModel.js +0 -92
- package/modules/Base.d.ts +0 -37
- package/modules/Base.js +0 -63
- package/modules/BaseCli.js +0 -97
- package/server.d.ts +0 -98
- package/server.js +0 -438
- package/services/cache/Cache.d.ts +0 -35
- package/services/cache/Cache.js +0 -124
- package/services/documentation/DocumentationGenerator.js +0 -169
- package/services/http/HttpServer.js +0 -96
- package/services/http/middleware/AbstractMiddleware.js +0 -51
- package/services/http/middleware/Auth.js +0 -20
- package/services/http/middleware/Cors.js +0 -46
- package/services/http/middleware/GetUserByToken.js +0 -47
- package/services/http/middleware/I18n.js +0 -117
- package/services/http/middleware/IpDetector.js +0 -59
- package/services/http/middleware/Pagination.js +0 -57
- package/services/http/middleware/PrepareAppInfo.js +0 -18
- package/services/http/middleware/RateLimiter.js +0 -134
- package/services/http/middleware/RequestLogger.js +0 -22
- package/services/http/middleware/RequestParser.js +0 -40
- package/services/http/middleware/Role.js +0 -29
- package/services/messaging/email/index.js +0 -217
- package/services/messaging/email/resources/.gitkeep +0 -1
- package/services/messaging/email/templates/emptyTemplate/html.pug +0 -9
- package/services/messaging/email/templates/emptyTemplate/subject.pug +0 -1
- package/services/messaging/email/templates/emptyTemplate/text.pug +0 -1
- package/services/messaging/email/templates/recovery/html.pug +0 -8
- package/services/messaging/email/templates/recovery/subject.pug +0 -2
- package/services/messaging/email/templates/recovery/text.pug +0 -3
- package/services/messaging/email/templates/verification/html.pug +0 -10
- package/services/messaging/email/templates/verification/subject.pug +0 -1
- package/services/messaging/email/templates/verification/text.pug +0 -1
- package/services/messaging/index.js +0 -3
- package/services/validate/ValidateService.js +0 -157
- package/services/validate/drivers/AbstractValidator.js +0 -37
- package/services/validate/drivers/CustomValidator.js +0 -51
- package/services/validate/drivers/YupValidator.js +0 -103
- package/tests/globalSetupVitest.js +0 -35
- package/tests/setup.js +0 -118
- package/tests/setupVitest.js +0 -109
- package/types/Expand.d.ts +0 -11
- package/types/TFoldersConfig.d.ts +0 -17
- package/views/404.pug +0 -3
- package/views/home.pug +0 -3
- package/views/layouts/base.pug +0 -39
- package/vitest.config.js +0 -16
- /package/{commands → dist/migrations}/.gitkeep +0 -0
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import yup from 'yup';
|
|
2
|
-
import YupValidator from './drivers/YupValidator.js';
|
|
3
|
-
import CustomValidator from './drivers/CustomValidator.js';
|
|
4
|
-
import Base from '../../modules/Base.js';
|
|
5
|
-
|
|
6
|
-
class ValidateService extends Base {
|
|
7
|
-
constructor(app, validator) {
|
|
8
|
-
super(app);
|
|
9
|
-
this.validator = validator
|
|
10
|
-
? this.constructor.getDriverByValidatorBody(app, validator)
|
|
11
|
-
: null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
static drivers = {
|
|
15
|
-
YupValidator,
|
|
16
|
-
CustomValidator,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
static isValidatorExists(validator) {
|
|
20
|
-
if (!(validator instanceof Object)) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return Object.values(this.drivers).some(
|
|
25
|
-
(driver) => validator instanceof driver,
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
static getDriverByValidatorBody(app, body = {}) {
|
|
30
|
-
if (this.isValidatorExists(body)) {
|
|
31
|
-
return body;
|
|
32
|
-
}
|
|
33
|
-
if (yup.isSchema(body)) {
|
|
34
|
-
const yupValidator = new YupValidator(app, body);
|
|
35
|
-
return yupValidator;
|
|
36
|
-
}
|
|
37
|
-
const customValidator = new CustomValidator(app, body);
|
|
38
|
-
return customValidator;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Filter middlewares by route path and select all parameters
|
|
43
|
-
*/
|
|
44
|
-
filterRelatedParametersByRoute(middlewares, method, path) {
|
|
45
|
-
const middlewaresParams = middlewares
|
|
46
|
-
.filter(
|
|
47
|
-
(middleware) =>
|
|
48
|
-
middleware.method.toLowerCase() === method.toLowerCase() &&
|
|
49
|
-
middleware.fullPath.toLowerCase() === path.toLowerCase(),
|
|
50
|
-
)
|
|
51
|
-
?.map((middleware) => {
|
|
52
|
-
const instance = new middleware.MiddlewareFunction(
|
|
53
|
-
this.app,
|
|
54
|
-
middleware.params,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
return instance.relatedReqParameters;
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return middlewaresParams;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Group all middleware(routes + controller) parameters
|
|
65
|
-
*/
|
|
66
|
-
getMiddlewareParams(controllerMiddlewares, AllrouteMiddlewares, options) {
|
|
67
|
-
const { method, path } = options;
|
|
68
|
-
const routeMiddlewaresParams = this.filterRelatedParametersByRoute(
|
|
69
|
-
AllrouteMiddlewares,
|
|
70
|
-
method,
|
|
71
|
-
path,
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
const controllerMiddlewaresParams = this.filterRelatedParametersByRoute(
|
|
75
|
-
controllerMiddlewares,
|
|
76
|
-
method,
|
|
77
|
-
path,
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
request: [
|
|
82
|
-
...controllerMiddlewaresParams.map((x) => x.request),
|
|
83
|
-
...routeMiddlewaresParams.map((x) => x.request),
|
|
84
|
-
],
|
|
85
|
-
query: [
|
|
86
|
-
...controllerMiddlewaresParams.map((x) => x.query),
|
|
87
|
-
...routeMiddlewaresParams.map((x) => x.query),
|
|
88
|
-
],
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// eslint-disable-next-line class-methods-use-this
|
|
93
|
-
async validateSchema(req, validator, data) {
|
|
94
|
-
if (!validator) {
|
|
95
|
-
return {};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
await validator.validateFields(data, req);
|
|
99
|
-
|
|
100
|
-
return validator.castFields(data, req);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async validateArrayOfSchemas(req, validators, data) {
|
|
104
|
-
const result = [];
|
|
105
|
-
|
|
106
|
-
for (const validator of validators) {
|
|
107
|
-
const formatedValidator = this.constructor.getDriverByValidatorBody(
|
|
108
|
-
this.app,
|
|
109
|
-
validator,
|
|
110
|
-
);
|
|
111
|
-
result.push(this.validateSchema(req, formatedValidator, data));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return Promise.all(result);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Validate req data. For example req.body, req.query
|
|
119
|
-
*/
|
|
120
|
-
async validateReqData(req, options) {
|
|
121
|
-
const { selectedReqData, additionalMiddlewareFieldsData } = options;
|
|
122
|
-
const {
|
|
123
|
-
middlewaresInfo,
|
|
124
|
-
routeMiddlewaresReg,
|
|
125
|
-
options: routeOptions,
|
|
126
|
-
} = additionalMiddlewareFieldsData;
|
|
127
|
-
|
|
128
|
-
let validatedFields = await this.validateSchema(
|
|
129
|
-
req,
|
|
130
|
-
this.validator,
|
|
131
|
-
selectedReqData,
|
|
132
|
-
);
|
|
133
|
-
const additionalMiddlewareSchemas = this.getMiddlewareParams(
|
|
134
|
-
middlewaresInfo,
|
|
135
|
-
routeMiddlewaresReg,
|
|
136
|
-
routeOptions,
|
|
137
|
-
)[routeOptions.prefix];
|
|
138
|
-
|
|
139
|
-
if (additionalMiddlewareSchemas.length) {
|
|
140
|
-
const middlewareValidatedFields = await this.validateArrayOfSchemas(
|
|
141
|
-
req,
|
|
142
|
-
additionalMiddlewareSchemas,
|
|
143
|
-
selectedReqData,
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
validatedFields = Object.assign(
|
|
147
|
-
{},
|
|
148
|
-
validatedFields,
|
|
149
|
-
...middlewareValidatedFields,
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return validatedFields;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export default ValidateService;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import Base from '../../../modules/Base.js';
|
|
2
|
-
|
|
3
|
-
class AbstractValidator extends Base {
|
|
4
|
-
constructor(app, body) {
|
|
5
|
-
super(app);
|
|
6
|
-
this.body = body;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// eslint-disable-next-line no-unused-vars
|
|
10
|
-
static convertFieldsToJson(fields) {
|
|
11
|
-
// IMPLENT;
|
|
12
|
-
return {};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// eslint-disable-next-line class-methods-use-this
|
|
16
|
-
get fieldsInJsonFormat() {
|
|
17
|
-
// IMPLENT;
|
|
18
|
-
return {};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// eslint-disable-next-line class-methods-use-this
|
|
22
|
-
async validateFields() {
|
|
23
|
-
// IMPLENT;
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// eslint-disable-next-line class-methods-use-this
|
|
28
|
-
async castFields() {
|
|
29
|
-
// IMPLENT;
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static get loggerGroup() {
|
|
34
|
-
return 'AbstractValidator_';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export default AbstractValidator;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import yup from 'yup';
|
|
2
|
-
import AbstractValidator from './AbstractValidator.js';
|
|
3
|
-
|
|
4
|
-
class CustomValidator extends AbstractValidator {
|
|
5
|
-
async validateFields(data, { query, body, appInfo }) {
|
|
6
|
-
if (this.body) {
|
|
7
|
-
if (typeof this.body.validate !== 'function') {
|
|
8
|
-
this.logger.error('request.validate should be a function');
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
try {
|
|
12
|
-
await this.body.validate(data, {
|
|
13
|
-
req: {
|
|
14
|
-
query,
|
|
15
|
-
body,
|
|
16
|
-
appInfo,
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
} catch (e) {
|
|
20
|
-
this.logger.warn(`CustomValidator validateFields ${e}`);
|
|
21
|
-
if (e.path) {
|
|
22
|
-
throw new yup.ValidationError({
|
|
23
|
-
[e.path]: e.message,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
throw new Error(e);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async castFields(data, { query, body, appInfo }) {
|
|
31
|
-
if (this.body) {
|
|
32
|
-
if (typeof this.body.cast !== 'function') {
|
|
33
|
-
this.logger.error('request.validate should be a function');
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return this.body.cast(data, {
|
|
38
|
-
req: {
|
|
39
|
-
query,
|
|
40
|
-
body,
|
|
41
|
-
appInfo,
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
static get loggerGroup() {
|
|
47
|
-
return 'CustomValidator_';
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export default CustomValidator;
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import yup from 'yup';
|
|
2
|
-
import AbstractValidator from './AbstractValidator.js';
|
|
3
|
-
|
|
4
|
-
class YupValidator extends AbstractValidator {
|
|
5
|
-
get fieldsInJsonFormat() {
|
|
6
|
-
return this.constructor.convertFieldsToJson(this.body);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
static convertFieldsToJson(fields) {
|
|
10
|
-
const convertedFields = {};
|
|
11
|
-
const entries = Object.entries(fields.describe().fields);
|
|
12
|
-
|
|
13
|
-
if (!entries?.length) {
|
|
14
|
-
return convertedFields;
|
|
15
|
-
}
|
|
16
|
-
const requiredFields = [];
|
|
17
|
-
|
|
18
|
-
for (const [field, fieldProp] of entries) {
|
|
19
|
-
const isRequired = fieldProp?.tests?.find(
|
|
20
|
-
(prop) => prop.name === 'required',
|
|
21
|
-
);
|
|
22
|
-
if (isRequired) {
|
|
23
|
-
requiredFields.push(field);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
entries.forEach(([key, value]) => {
|
|
28
|
-
if (!convertedFields[key]) {
|
|
29
|
-
convertedFields[key] = {};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
convertedFields[key] = {
|
|
33
|
-
type: value.type,
|
|
34
|
-
required: requiredFields?.includes(key),
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return convertedFields;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async validateFields(data, { query, body, appInfo }) {
|
|
42
|
-
const yupSchema = this.body;
|
|
43
|
-
const { controllerValidationAbortEarly } = this.app.getConfig('validate');
|
|
44
|
-
if (yupSchema) {
|
|
45
|
-
if (typeof yupSchema.validate !== 'function') {
|
|
46
|
-
this.logger.error('request.validate should be a function');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
await yupSchema.validate(data, {
|
|
52
|
-
abortEarly: controllerValidationAbortEarly,
|
|
53
|
-
req: { query, body },
|
|
54
|
-
});
|
|
55
|
-
} catch (e) {
|
|
56
|
-
let { errors } = e;
|
|
57
|
-
// translate it
|
|
58
|
-
if (appInfo.i18n && errors) {
|
|
59
|
-
errors = errors.map((err) => appInfo.i18n.t(err, err));
|
|
60
|
-
}
|
|
61
|
-
this.logger.error(
|
|
62
|
-
`Request validation failed with message: ${e.message}. errors: ${errors}`,
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const errorAnswer = {};
|
|
66
|
-
if (!e.inner || !e.inner.length) {
|
|
67
|
-
errorAnswer[e.path] = errors;
|
|
68
|
-
} else {
|
|
69
|
-
e.inner.forEach((err) => {
|
|
70
|
-
errorAnswer[err.path] = err.errors;
|
|
71
|
-
if (appInfo.i18n && err.errors) {
|
|
72
|
-
errorAnswer[err.path] = err.errors.map((err1) =>
|
|
73
|
-
appInfo.i18n.t(err1, err1, err.params),
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
throw new yup.ValidationError({
|
|
80
|
-
...errorAnswer,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async castFields(data, { query, body }) {
|
|
86
|
-
const yupSchema = this.body;
|
|
87
|
-
if (yupSchema) {
|
|
88
|
-
if (typeof yupSchema.cast !== 'function') {
|
|
89
|
-
this.logger.error('request.cast should be a function');
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return yupSchema.cast(data, {
|
|
94
|
-
stripUnknown: true,
|
|
95
|
-
req: { query, body },
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
static get loggerGroup() {
|
|
100
|
-
return 'YupValidator_';
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
export default YupValidator;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { MongoMemoryReplSet } from 'mongodb-memory-server';
|
|
2
|
-
|
|
3
|
-
let isTeardown = false;
|
|
4
|
-
let mongoMemoryServerInstance;
|
|
5
|
-
|
|
6
|
-
const setup = async () => {
|
|
7
|
-
console.log('GLOBAL SETUP PREPARE RUNNING...');
|
|
8
|
-
console.time('GLOBAL TEST PREPARE. DONE');
|
|
9
|
-
mongoMemoryServerInstance = await MongoMemoryReplSet.create({
|
|
10
|
-
// binary: { version: '4.4.6' },
|
|
11
|
-
replSet: { count: 1, storageEngine: 'wiredTiger' },
|
|
12
|
-
});
|
|
13
|
-
await mongoMemoryServerInstance.waitUntilRunning();
|
|
14
|
-
const connectionStringMongo =
|
|
15
|
-
await mongoMemoryServerInstance.getUri('__DB_TO_REPLACE__');
|
|
16
|
-
process.env.TEST_MONGO_URI = connectionStringMongo;
|
|
17
|
-
// console.info('MONGO_URI: ', connectionStringMongo);
|
|
18
|
-
console.timeEnd('GLOBAL TEST PREPARE. DONE');
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const teardown = async () => {
|
|
22
|
-
if (isTeardown) {
|
|
23
|
-
throw new Error('teardown called twice');
|
|
24
|
-
}
|
|
25
|
-
console.time('GLOBAL TEARDOWN RUNNING. DONE');
|
|
26
|
-
|
|
27
|
-
isTeardown = true;
|
|
28
|
-
console.log('GLOBAL TEARDOWN RUNNING...');
|
|
29
|
-
await mongoMemoryServerInstance.stop();
|
|
30
|
-
console.timeEnd('GLOBAL TEARDOWN RUNNING. DONE');
|
|
31
|
-
|
|
32
|
-
return Promise.resolve();
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export { setup, teardown };
|
package/tests/setup.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-undef */
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { randomBytes } from 'node:crypto';
|
|
4
|
-
import { MongoMemoryReplSet } from 'mongodb-memory-server';
|
|
5
|
-
import mongoose from 'mongoose';
|
|
6
|
-
import redis from 'redis';
|
|
7
|
-
import Server from '../server.js';
|
|
8
|
-
|
|
9
|
-
import clearRedisNamespace from '../helpers/redis/clearNamespace.js';
|
|
10
|
-
|
|
11
|
-
mongoose.set('autoIndex', false);
|
|
12
|
-
|
|
13
|
-
let mongoMemoryServerInstance;
|
|
14
|
-
|
|
15
|
-
jest.setTimeout(1000000);
|
|
16
|
-
beforeAll(async () => {
|
|
17
|
-
mongoMemoryServerInstance = await MongoMemoryReplSet.create({
|
|
18
|
-
// binary: { version: '4.4.6' },
|
|
19
|
-
replSet: { count: 1, storageEngine: 'wiredTiger' },
|
|
20
|
-
});
|
|
21
|
-
await mongoMemoryServerInstance.waitUntilRunning();
|
|
22
|
-
process.env.LOGGER_CONSOLE_LEVEL = 'error';
|
|
23
|
-
process.env.AUTH_SALT = randomBytes(16).toString('hex');
|
|
24
|
-
|
|
25
|
-
const connectionStringMongo = await mongoMemoryServerInstance.getUri();
|
|
26
|
-
// console.info('MONGO_URI: ', connectionStringMongo);
|
|
27
|
-
global.server = new Server({
|
|
28
|
-
folders: {
|
|
29
|
-
config: process.env.TEST_FOLDER_CONFIG || path.resolve('./config'),
|
|
30
|
-
controllers:
|
|
31
|
-
process.env.TEST_FOLDER_CONTROLLERS || path.resolve('./controllers'),
|
|
32
|
-
views: process.env.TEST_FOLDER_VIEWS || path.resolve('./views'),
|
|
33
|
-
models: process.env.TEST_FOLDER_MODELS || path.resolve('./models'),
|
|
34
|
-
emails:
|
|
35
|
-
process.env.TEST_FOLDER_EMAIL ||
|
|
36
|
-
process.env.TEST_FOLDER_EMAILS ||
|
|
37
|
-
path.resolve('./services/messaging/email/templates'),
|
|
38
|
-
locales: process.env.TEST_FOLDER_LOCALES || path.resolve('./locales'),
|
|
39
|
-
commands: process.env.TEST_FOLDER_COMMANDS || path.resolve('./commands'),
|
|
40
|
-
migrations:
|
|
41
|
-
process.env.TEST_FOLDER_MIGRATIONS || path.resolve('./migrations'),
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
await global.server.init({ isSkipModelInit: true });
|
|
45
|
-
global.server.updateConfig('mongo', {
|
|
46
|
-
connectionString: connectionStringMongo,
|
|
47
|
-
});
|
|
48
|
-
global.server.updateConfig('http', { port: 0 }); // allow to use random
|
|
49
|
-
global.server.updateConfig('mail', { transport: 'stub' });
|
|
50
|
-
await global.server.initAllModels();
|
|
51
|
-
|
|
52
|
-
if (!global.testSetup) {
|
|
53
|
-
global.testSetup = {};
|
|
54
|
-
}
|
|
55
|
-
global.server.testingGetUrl = (urlPart) =>
|
|
56
|
-
`http://127.0.0.1:${global.server.getConfig('http').port}${urlPart}`;
|
|
57
|
-
if (!global.testSetup.disableUserCreate) {
|
|
58
|
-
const User = global.server.app.getModel('User');
|
|
59
|
-
global.user = await User.create({
|
|
60
|
-
email: 'test@test.com',
|
|
61
|
-
password: 'testPassword',
|
|
62
|
-
isVerified: true,
|
|
63
|
-
name: {
|
|
64
|
-
nick: 'testUserNickName',
|
|
65
|
-
},
|
|
66
|
-
}).catch((e) => {
|
|
67
|
-
// eslint-disable-next-line no-console
|
|
68
|
-
console.error(e);
|
|
69
|
-
// eslint-disable-next-line no-console
|
|
70
|
-
console.info(
|
|
71
|
-
'That error can happens in case you have custom user model. Please use global.testSetup.disableUserCreate flag to skip user creating',
|
|
72
|
-
);
|
|
73
|
-
});
|
|
74
|
-
global.authToken = await global.user.generateToken();
|
|
75
|
-
}
|
|
76
|
-
if (typeof global.testSetup.beforeAll === 'function') {
|
|
77
|
-
await global.testSetup.beforeAll();
|
|
78
|
-
}
|
|
79
|
-
await global.server.startServer();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
beforeEach(() => {
|
|
83
|
-
if (global.server) {
|
|
84
|
-
const key = `test-${Math.random().toString(36).substring(7)}`;
|
|
85
|
-
global.server.app.updateConfig('redis', {
|
|
86
|
-
namespace: key,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
afterEach(async () => {
|
|
92
|
-
if (global.server) {
|
|
93
|
-
const { url, namespace } = global.server.getConfig('redis');
|
|
94
|
-
const redisClient = redis.createClient({ url });
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
await redisClient.connect();
|
|
98
|
-
await clearRedisNamespace(redisClient, namespace);
|
|
99
|
-
await redisClient.disconnect();
|
|
100
|
-
} catch (err) {
|
|
101
|
-
// that ok. No redis connection
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
afterAll(async () => {
|
|
107
|
-
if (global.server) {
|
|
108
|
-
global.server.app.httpServer.shutdown();
|
|
109
|
-
global.server.app.events.emit('shutdown');
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (typeof global.testSetup.afterAll === 'function') {
|
|
113
|
-
await global.testSetup.afterAll();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
await mongoose.disconnect();
|
|
117
|
-
await mongoMemoryServerInstance.stop();
|
|
118
|
-
});
|
package/tests/setupVitest.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import crypto from 'node:crypto';
|
|
3
|
-
import { beforeAll, beforeEach, afterEach, afterAll } from 'vitest';
|
|
4
|
-
|
|
5
|
-
import mongoose from 'mongoose'; // we do not need create indexes on tests
|
|
6
|
-
|
|
7
|
-
import redis from 'redis';
|
|
8
|
-
import clearRedisNamespace from '../helpers/redis/clearNamespace.js';
|
|
9
|
-
import Server from '../server.js';
|
|
10
|
-
|
|
11
|
-
mongoose.set('autoIndex', false);
|
|
12
|
-
|
|
13
|
-
beforeAll(async () => {
|
|
14
|
-
process.env.LOGGER_CONSOLE_LEVEL = 'error';
|
|
15
|
-
process.env.AUTH_SALT = crypto.randomBytes(16).toString('hex');
|
|
16
|
-
global.server = new Server({
|
|
17
|
-
folders: {
|
|
18
|
-
config: process.env.TEST_FOLDER_CONFIG || path.resolve('./config'),
|
|
19
|
-
controllers:
|
|
20
|
-
process.env.TEST_FOLDER_CONTROLLERS || path.resolve('./controllers'),
|
|
21
|
-
views: process.env.TEST_FOLDER_VIEWS || path.resolve('./views'),
|
|
22
|
-
models: process.env.TEST_FOLDER_MODELS || path.resolve('./models'),
|
|
23
|
-
emails:
|
|
24
|
-
process.env.TEST_FOLDER_EMAIL ||
|
|
25
|
-
process.env.TEST_FOLDER_EMAILS ||
|
|
26
|
-
path.resolve('./services/messaging/email/templates'),
|
|
27
|
-
locales: process.env.TEST_FOLDER_LOCALES || path.resolve('./locales'),
|
|
28
|
-
commands: process.env.TEST_FOLDER_COMMANDS || path.resolve('./commands'),
|
|
29
|
-
migrations:
|
|
30
|
-
process.env.TEST_FOLDER_MIGRATIONS || path.resolve('./migrations'),
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
await global.server.init({ isSkipModelInit: true });
|
|
34
|
-
const connectionString = process.env.TEST_MONGO_URI.replace(
|
|
35
|
-
'__DB_TO_REPLACE__',
|
|
36
|
-
`TEST_${crypto.randomUUID()}`,
|
|
37
|
-
);
|
|
38
|
-
global.server.updateConfig('mongo', {
|
|
39
|
-
connectionString,
|
|
40
|
-
});
|
|
41
|
-
global.server.updateConfig('http', { port: 0 }); // allow to use random
|
|
42
|
-
global.server.updateConfig('mail', { transport: 'stub' });
|
|
43
|
-
await global.server.initAllModels();
|
|
44
|
-
|
|
45
|
-
if (!global.testSetup) {
|
|
46
|
-
global.testSetup = {};
|
|
47
|
-
}
|
|
48
|
-
global.server.testingGetUrl = (urlPart) =>
|
|
49
|
-
`http://127.0.0.1:${global.server.getConfig('http').port}${urlPart}`;
|
|
50
|
-
if (!global.testSetup.disableUserCreate) {
|
|
51
|
-
const User = global.server.app.getModel('User');
|
|
52
|
-
global.user = await User.create({
|
|
53
|
-
email: 'test@test.com',
|
|
54
|
-
password: 'testPassword',
|
|
55
|
-
isVerified: true,
|
|
56
|
-
name: {
|
|
57
|
-
nick: 'testUserNickName',
|
|
58
|
-
},
|
|
59
|
-
}).catch((e) => {
|
|
60
|
-
// eslint-disable-next-line no-console
|
|
61
|
-
console.error(e);
|
|
62
|
-
// eslint-disable-next-line no-console
|
|
63
|
-
console.info(
|
|
64
|
-
'That error can happens in case you have custom user model. Please use global.testSetup.disableUserCreate flag to skip user creating',
|
|
65
|
-
);
|
|
66
|
-
});
|
|
67
|
-
global.authToken = await global.user.generateToken();
|
|
68
|
-
}
|
|
69
|
-
if (typeof global.testSetup.beforeAll === 'function') {
|
|
70
|
-
await global.testSetup.beforeAll();
|
|
71
|
-
}
|
|
72
|
-
await global.server.startServer();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
beforeEach(() => {
|
|
76
|
-
if (global.server) {
|
|
77
|
-
const key = `test-${Math.random().toString(36).substring(7)}`;
|
|
78
|
-
global.server.app.updateConfig('redis', {
|
|
79
|
-
namespace: key,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
afterEach(async () => {
|
|
85
|
-
if (global.server) {
|
|
86
|
-
const { url, namespace } = global.server.getConfig('redis');
|
|
87
|
-
const redisClient = redis.createClient({ url });
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
await redisClient.connect();
|
|
91
|
-
await clearRedisNamespace(redisClient, namespace);
|
|
92
|
-
await redisClient.disconnect();
|
|
93
|
-
} catch (err) {
|
|
94
|
-
// that ok. No redis connection
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
afterAll(async () => {
|
|
100
|
-
if (global.server) {
|
|
101
|
-
global.server.app.httpServer.shutdown();
|
|
102
|
-
global.server.app.events.emit('shutdown');
|
|
103
|
-
}
|
|
104
|
-
if (typeof global.testSetup.afterAll === 'function') {
|
|
105
|
-
await global.testSetup.afterAll();
|
|
106
|
-
}
|
|
107
|
-
await mongoose.connection.db.dropDatabase(); // clean database after test
|
|
108
|
-
await mongoose.disconnect();
|
|
109
|
-
});
|
package/types/Expand.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param config path to folder with config files
|
|
3
|
-
* @param models path to folder with moidels files
|
|
4
|
-
* @param controllers path to folder with controllers files
|
|
5
|
-
* @param views path to folder with view files
|
|
6
|
-
* @param locales path to folder with locales files
|
|
7
|
-
* @param emails path to folder with emails files
|
|
8
|
-
*/
|
|
9
|
-
type FolderConfig = {
|
|
10
|
-
config: string;
|
|
11
|
-
models: string;
|
|
12
|
-
controllers: string;
|
|
13
|
-
views: string;
|
|
14
|
-
emails: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default FolderConfig;
|
package/views/404.pug
DELETED
package/views/home.pug
DELETED
package/views/layouts/base.pug
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
doctype html
|
|
2
|
-
html(lang=language)
|
|
3
|
-
head
|
|
4
|
-
meta(charset='utf-8')
|
|
5
|
-
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
|
6
|
-
meta(name='viewport', content='width=device-width, initial-scale=1')
|
|
7
|
-
// Title Of Site
|
|
8
|
-
title Site title
|
|
9
|
-
meta(name='description', content='Site description')
|
|
10
|
-
meta(name='keywords', content='Site keywords')
|
|
11
|
-
|
|
12
|
-
meta(name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1')
|
|
13
|
-
|
|
14
|
-
// Standard Favicon
|
|
15
|
-
link(rel='icon', type='image/x-icon', href='/favicon.png')
|
|
16
|
-
// For non-Retina iPhone, iPod Touch, and Android 2.1+ devices:
|
|
17
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='57x57', href='/favicons/apple-touch-icon-57x57-precomposed.png')
|
|
18
|
-
// iOS 7 devices:
|
|
19
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='60x60', href='/favicons/apple-touch-icon-60x60-precomposed.png')
|
|
20
|
-
// For the iPad mini and the first- and second-generation iPad on iOS ≤ 6:
|
|
21
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='72x72', href='/favicons/apple-touch-icon-72x72-precomposed.png')
|
|
22
|
-
// For the iPad mini and the first- and second-generation iPad on iOS ≥ 7:
|
|
23
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='76x76', href='/favicons/apple-touch-icon-76x76-precomposed.png')
|
|
24
|
-
// For iPhone with high-resolution Retina display running iOS ≤ 6:
|
|
25
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='114x114', href='/favicons/apple-touch-icon-114x114-precomposed.png')
|
|
26
|
-
// For iPhone with high-resolution Retina display running iOS ≥ 7:
|
|
27
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='120x120', href='/favicons/apple-touch-icon-120x120-precomposed.png')
|
|
28
|
-
// For iPad with high-resolution Retina display running iOS ≤ 6:
|
|
29
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='144x144', href='/favicons/apple-touch-icon-144x144-precomposed.png')
|
|
30
|
-
// For iPad with high-resolution Retina display running iOS ≥ 7:
|
|
31
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='152x152', href='/favicons/apple-touch-icon-152x152-precomposed.png')
|
|
32
|
-
// For Android :
|
|
33
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='196x196', href='/favicons/apple-touch-icon-196x196-precomposed.png')
|
|
34
|
-
// Opera Coast
|
|
35
|
-
link(rel='apple-touch-icon-precomposed apple-touch-icon icon', sizes='228x228', href='/favicons/apple-touch-icon-228x228-precomposed.png')
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
body
|
|
39
|
-
block content
|