@takaro/db 0.0.1

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 (263) hide show
  1. package/README.md +1 -0
  2. package/dist/TakaroModel.d.ts +15 -0
  3. package/dist/TakaroModel.js +23 -0
  4. package/dist/TakaroModel.js.map +1 -0
  5. package/dist/config.d.ts +98 -0
  6. package/dist/config.js +81 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/encryption.d.ts +4 -0
  9. package/dist/encryption.js +24 -0
  10. package/dist/encryption.js.map +1 -0
  11. package/dist/errorTypeGuards.d.ts +2 -0
  12. package/dist/errorTypeGuards.js +11 -0
  13. package/dist/errorTypeGuards.js.map +1 -0
  14. package/dist/knex.d.ts +16 -0
  15. package/dist/knex.js +46 -0
  16. package/dist/knex.js.map +1 -0
  17. package/dist/main.d.ts +8 -0
  18. package/dist/main.js +9 -0
  19. package/dist/main.js.map +1 -0
  20. package/dist/migrations/index.d.ts +2 -0
  21. package/dist/migrations/index.js +59 -0
  22. package/dist/migrations/index.js.map +1 -0
  23. package/dist/migrations/sql/20220827191938_init.d.ts +3 -0
  24. package/dist/migrations/sql/20220827191938_init.js +155 -0
  25. package/dist/migrations/sql/20220827191938_init.js.map +1 -0
  26. package/dist/migrations/sql/20221019173729_settings.d.ts +3 -0
  27. package/dist/migrations/sql/20221019173729_settings.js +61 -0
  28. package/dist/migrations/sql/20221019173729_settings.js.map +1 -0
  29. package/dist/migrations/sql/20221029103554_refactor_function_assignments.d.ts +3 -0
  30. package/dist/migrations/sql/20221029103554_refactor_function_assignments.js +33 -0
  31. package/dist/migrations/sql/20221029103554_refactor_function_assignments.js.map +1 -0
  32. package/dist/migrations/sql/20221102190532_commands.d.ts +3 -0
  33. package/dist/migrations/sql/20221102190532_commands.js +58 -0
  34. package/dist/migrations/sql/20221102190532_commands.js.map +1 -0
  35. package/dist/migrations/sql/20221203135001-builtin_modules.d.ts +3 -0
  36. package/dist/migrations/sql/20221203135001-builtin_modules.js +44 -0
  37. package/dist/migrations/sql/20221203135001-builtin_modules.js.map +1 -0
  38. package/dist/migrations/sql/20230308183400-persistent-variables.d.ts +3 -0
  39. package/dist/migrations/sql/20230308183400-persistent-variables.js +63 -0
  40. package/dist/migrations/sql/20230308183400-persistent-variables.js.map +1 -0
  41. package/dist/migrations/sql/20230314183400-auth-ory.d.ts +3 -0
  42. package/dist/migrations/sql/20230314183400-auth-ory.js +23 -0
  43. package/dist/migrations/sql/20230314183400-auth-ory.js.map +1 -0
  44. package/dist/migrations/sql/20230325156123_command-arguments.d.ts +3 -0
  45. package/dist/migrations/sql/20230325156123_command-arguments.js +19 -0
  46. package/dist/migrations/sql/20230325156123_command-arguments.js.map +1 -0
  47. package/dist/migrations/sql/20230407132022-module-descriptions.d.ts +3 -0
  48. package/dist/migrations/sql/20230407132022-module-descriptions.js +11 -0
  49. package/dist/migrations/sql/20230407132022-module-descriptions.js.map +1 -0
  50. package/dist/migrations/sql/20230407143733-module-json-schema-config.d.ts +3 -0
  51. package/dist/migrations/sql/20230407143733-module-json-schema-config.js +14 -0
  52. package/dist/migrations/sql/20230407143733-module-json-schema-config.js.map +1 -0
  53. package/dist/migrations/sql/20230407173055-hook-regex-optional.d.ts +3 -0
  54. package/dist/migrations/sql/20230407173055-hook-regex-optional.js +11 -0
  55. package/dist/migrations/sql/20230407173055-hook-regex-optional.js.map +1 -0
  56. package/dist/migrations/sql/20230415154935-cronjob-configs.d.ts +3 -0
  57. package/dist/migrations/sql/20230415154935-cronjob-configs.js +16 -0
  58. package/dist/migrations/sql/20230415154935-cronjob-configs.js.map +1 -0
  59. package/dist/migrations/sql/20230503132906-variables-extra-meta.d.ts +3 -0
  60. package/dist/migrations/sql/20230503132906-variables-extra-meta.js +26 -0
  61. package/dist/migrations/sql/20230503132906-variables-extra-meta.js.map +1 -0
  62. package/dist/migrations/sql/20230604130951-fix-hook-eventtypes.d.ts +3 -0
  63. package/dist/migrations/sql/20230604130951-fix-hook-eventtypes.js +8 -0
  64. package/dist/migrations/sql/20230604130951-fix-hook-eventtypes.js.map +1 -0
  65. package/dist/migrations/sql/20230617081049-discordId-for-users.d.ts +3 -0
  66. package/dist/migrations/sql/20230617081049-discordId-for-users.js +14 -0
  67. package/dist/migrations/sql/20230617081049-discordId-for-users.js.map +1 -0
  68. package/dist/migrations/sql/20230618053611-discord-funtionality.d.ts +3 -0
  69. package/dist/migrations/sql/20230618053611-discord-funtionality.js +26 -0
  70. package/dist/migrations/sql/20230618053611-discord-funtionality.js.map +1 -0
  71. package/dist/migrations/sql/20230622192402-discord-hooks.d.ts +3 -0
  72. package/dist/migrations/sql/20230622192402-discord-hooks.js +14 -0
  73. package/dist/migrations/sql/20230622192402-discord-hooks.js.map +1 -0
  74. package/dist/migrations/sql/20230707081218-playerOnGameServerExtension.d.ts +3 -0
  75. package/dist/migrations/sql/20230707081218-playerOnGameServerExtension.js +19 -0
  76. package/dist/migrations/sql/20230707081218-playerOnGameServerExtension.js.map +1 -0
  77. package/dist/migrations/sql/20230710174340-events.d.ts +3 -0
  78. package/dist/migrations/sql/20230710174340-events.js +16 -0
  79. package/dist/migrations/sql/20230710174340-events.js.map +1 -0
  80. package/dist/migrations/sql/20230712061220-roles-permissions-extension.d.ts +3 -0
  81. package/dist/migrations/sql/20230712061220-roles-permissions-extension.js +43 -0
  82. package/dist/migrations/sql/20230712061220-roles-permissions-extension.js.map +1 -0
  83. package/dist/migrations/sql/20230713184927-variables-modulescoped.d.ts +3 -0
  84. package/dist/migrations/sql/20230713184927-variables-modulescoped.js +27 -0
  85. package/dist/migrations/sql/20230713184927-variables-modulescoped.js.map +1 -0
  86. package/dist/migrations/sql/20230714045136-domain-index.d.ts +3 -0
  87. package/dist/migrations/sql/20230714045136-domain-index.js +37 -0
  88. package/dist/migrations/sql/20230714045136-domain-index.js.map +1 -0
  89. package/dist/migrations/sql/20230714045727-events-index.d.ts +3 -0
  90. package/dist/migrations/sql/20230714045727-events-index.js +17 -0
  91. package/dist/migrations/sql/20230714045727-events-index.js.map +1 -0
  92. package/dist/migrations/sql/20230715102519-module-permissions-extra-fields.d.ts +3 -0
  93. package/dist/migrations/sql/20230715102519-module-permissions-extra-fields.js +32 -0
  94. package/dist/migrations/sql/20230715102519-module-permissions-extra-fields.js.map +1 -0
  95. package/dist/migrations/sql/20230724062109-roles-constraints.d.ts +3 -0
  96. package/dist/migrations/sql/20230724062109-roles-constraints.js +14 -0
  97. package/dist/migrations/sql/20230724062109-roles-constraints.js.map +1 -0
  98. package/dist/migrations/sql/20230811095701-userId-on-events.d.ts +3 -0
  99. package/dist/migrations/sql/20230811095701-userId-on-events.js +12 -0
  100. package/dist/migrations/sql/20230811095701-userId-on-events.js.map +1 -0
  101. package/dist/migrations/sql/20230921123717-count-for-permissions.d.ts +3 -0
  102. package/dist/migrations/sql/20230921123717-count-for-permissions.js +84 -0
  103. package/dist/migrations/sql/20230921123717-count-for-permissions.js.map +1 -0
  104. package/dist/migrations/sql/20231111102812-details-system-permissions.d.ts +36 -0
  105. package/dist/migrations/sql/20231111102812-details-system-permissions.js +179 -0
  106. package/dist/migrations/sql/20231111102812-details-system-permissions.js.map +1 -0
  107. package/dist/migrations/sql/20231114151343-system-roles.d.ts +3 -0
  108. package/dist/migrations/sql/20231114151343-system-roles.js +41 -0
  109. package/dist/migrations/sql/20231114151343-system-roles.js.map +1 -0
  110. package/dist/migrations/sql/20231118082301-add-new-permissions.d.ts +36 -0
  111. package/dist/migrations/sql/20231118082301-add-new-permissions.js +186 -0
  112. package/dist/migrations/sql/20231118082301-add-new-permissions.js.map +1 -0
  113. package/dist/migrations/sql/20231119115037-timedRoles.d.ts +3 -0
  114. package/dist/migrations/sql/20231119115037-timedRoles.js +19 -0
  115. package/dist/migrations/sql/20231119115037-timedRoles.js.map +1 -0
  116. package/dist/migrations/sql/20231123150854-economy-base.d.ts +3 -0
  117. package/dist/migrations/sql/20231123150854-economy-base.js +13 -0
  118. package/dist/migrations/sql/20231123150854-economy-base.js.map +1 -0
  119. package/dist/migrations/sql/20231123171611-economy-settings.d.ts +3 -0
  120. package/dist/migrations/sql/20231123171611-economy-settings.js +13 -0
  121. package/dist/migrations/sql/20231123171611-economy-settings.js.map +1 -0
  122. package/dist/migrations/sql/20231124140441-json-module-assignments.d.ts +3 -0
  123. package/dist/migrations/sql/20231124140441-json-module-assignments.js +25 -0
  124. package/dist/migrations/sql/20231124140441-json-module-assignments.js.map +1 -0
  125. package/dist/migrations/sql/20231208114507-settings-refactor.d.ts +3 -0
  126. package/dist/migrations/sql/20231208114507-settings-refactor.js +95 -0
  127. package/dist/migrations/sql/20231208114507-settings-refactor.js.map +1 -0
  128. package/dist/migrations/sql/20231208171234-game-items.d.ts +3 -0
  129. package/dist/migrations/sql/20231208171234-game-items.js +18 -0
  130. package/dist/migrations/sql/20231208171234-game-items.js.map +1 -0
  131. package/dist/migrations/sql/20231216100720-player-inventory.d.ts +3 -0
  132. package/dist/migrations/sql/20231216100720-player-inventory.js +14 -0
  133. package/dist/migrations/sql/20231216100720-player-inventory.js.map +1 -0
  134. package/dist/migrations/sql/20231222180438-steam-data.d.ts +3 -0
  135. package/dist/migrations/sql/20231222180438-steam-data.js +25 -0
  136. package/dist/migrations/sql/20231222180438-steam-data.js.map +1 -0
  137. package/dist/migrations/sql/20231223132631-pog-online.d.ts +3 -0
  138. package/dist/migrations/sql/20231223132631-pog-online.js +11 -0
  139. package/dist/migrations/sql/20231223132631-pog-online.js.map +1 -0
  140. package/dist/migrations/sql/20231223212031-unique-index-item-def.d.ts +3 -0
  141. package/dist/migrations/sql/20231223212031-unique-index-item-def.js +24 -0
  142. package/dist/migrations/sql/20231223212031-unique-index-item-def.js.map +1 -0
  143. package/dist/migrations/sql/20231224135126-gameserver-online-status.d.ts +3 -0
  144. package/dist/migrations/sql/20231224135126-gameserver-online-status.js +11 -0
  145. package/dist/migrations/sql/20231224135126-gameserver-online-status.js.map +1 -0
  146. package/dist/migrations/sql/20231224155226-unique-pog.d.ts +3 -0
  147. package/dist/migrations/sql/20231224155226-unique-pog.js +24 -0
  148. package/dist/migrations/sql/20231224155226-unique-pog.js.map +1 -0
  149. package/dist/migrations/sql/20231225140650-extra-ip-info.d.ts +3 -0
  150. package/dist/migrations/sql/20231225140650-extra-ip-info.js +23 -0
  151. package/dist/migrations/sql/20231225140650-extra-ip-info.js.map +1 -0
  152. package/dist/migrations/sql/20231227144315-unique-constraints-player.d.ts +3 -0
  153. package/dist/migrations/sql/20231227144315-unique-constraints-player.js +67 -0
  154. package/dist/migrations/sql/20231227144315-unique-constraints-player.js.map +1 -0
  155. package/dist/migrations/sql/20231229144707-more-player-constraints.d.ts +3 -0
  156. package/dist/migrations/sql/20231229144707-more-player-constraints.js +17 -0
  157. package/dist/migrations/sql/20231229144707-more-player-constraints.js.map +1 -0
  158. package/dist/migrations/sql/20240101162751-add-settings-constraint.d.ts +3 -0
  159. package/dist/migrations/sql/20240101162751-add-settings-constraint.js +34 -0
  160. package/dist/migrations/sql/20240101162751-add-settings-constraint.js.map +1 -0
  161. package/dist/migrations/sql/20240105130846-remove-some-module-perms.d.ts +3 -0
  162. package/dist/migrations/sql/20240105130846-remove-some-module-perms.js +80 -0
  163. package/dist/migrations/sql/20240105130846-remove-some-module-perms.js.map +1 -0
  164. package/dist/migrations/sql/20240116141936-add-ui-schema-to-module.d.ts +3 -0
  165. package/dist/migrations/sql/20240116141936-add-ui-schema-to-module.js +11 -0
  166. package/dist/migrations/sql/20240116141936-add-ui-schema-to-module.js.map +1 -0
  167. package/dist/migrations/sql/20240119152426-remove-hook-check.d.ts +3 -0
  168. package/dist/migrations/sql/20240119152426-remove-hook-check.js +14 -0
  169. package/dist/migrations/sql/20240119152426-remove-hook-check.js.map +1 -0
  170. package/dist/migrations/sql/20240121142329-move-ip-history.d.ts +3 -0
  171. package/dist/migrations/sql/20240121142329-move-ip-history.js +44 -0
  172. package/dist/migrations/sql/20240121142329-move-ip-history.js.map +1 -0
  173. package/dist/migrations/sql/20240202101208-rename-economy-to-economyUtils.d.ts +3 -0
  174. package/dist/migrations/sql/20240202101208-rename-economy-to-economyUtils.js +13 -0
  175. package/dist/migrations/sql/20240202101208-rename-economy-to-economyUtils.js.map +1 -0
  176. package/dist/migrations/sql/20240216120143-domain-state.d.ts +3 -0
  177. package/dist/migrations/sql/20240216120143-domain-state.js +11 -0
  178. package/dist/migrations/sql/20240216120143-domain-state.js.map +1 -0
  179. package/dist/migrations/sql/20240229141340-looser-fks-events.d.ts +3 -0
  180. package/dist/migrations/sql/20240229141340-looser-fks-events.js +18 -0
  181. package/dist/migrations/sql/20240229141340-looser-fks-events.js.map +1 -0
  182. package/dist/migrations/sql/20240301063505-module-functions.d.ts +3 -0
  183. package/dist/migrations/sql/20240301063505-module-functions.js +14 -0
  184. package/dist/migrations/sql/20240301063505-module-functions.js.map +1 -0
  185. package/dist/migrations/util/alterEnum.d.ts +1 -0
  186. package/dist/migrations/util/alterEnum.js +9 -0
  187. package/dist/migrations/util/alterEnum.js.map +1 -0
  188. package/dist/queryBuilder.d.ts +28 -0
  189. package/dist/queryBuilder.js +132 -0
  190. package/dist/queryBuilder.js.map +1 -0
  191. package/dist/redis.d.ts +20 -0
  192. package/dist/redis.js +49 -0
  193. package/dist/redis.js.map +1 -0
  194. package/package.json +29 -0
  195. package/src/TakaroModel.ts +32 -0
  196. package/src/__tests__/encryption.integration.test.ts +56 -0
  197. package/src/__tests__/queryBuilder.integration.test.ts +202 -0
  198. package/src/config.ts +101 -0
  199. package/src/encryption.ts +27 -0
  200. package/src/errorTypeGuards.ts +11 -0
  201. package/src/knex.ts +54 -0
  202. package/src/main.ts +15 -0
  203. package/src/migrations/index.ts +70 -0
  204. package/src/migrations/sql/20220827191938_init.ts +183 -0
  205. package/src/migrations/sql/20221019173729_settings.ts +70 -0
  206. package/src/migrations/sql/20221029103554_refactor_function_assignments.ts +41 -0
  207. package/src/migrations/sql/20221102190532_commands.ts +66 -0
  208. package/src/migrations/sql/20221203135001-builtin_modules.ts +56 -0
  209. package/src/migrations/sql/20230308183400-persistent-variables.ts +74 -0
  210. package/src/migrations/sql/20230314183400-auth-ory.ts +27 -0
  211. package/src/migrations/sql/20230325156123_command-arguments.ts +24 -0
  212. package/src/migrations/sql/20230407132022-module-descriptions.ts +13 -0
  213. package/src/migrations/sql/20230407143733-module-json-schema-config.ts +16 -0
  214. package/src/migrations/sql/20230407173055-hook-regex-optional.ts +13 -0
  215. package/src/migrations/sql/20230415154935-cronjob-configs.ts +18 -0
  216. package/src/migrations/sql/20230503132906-variables-extra-meta.ts +31 -0
  217. package/src/migrations/sql/20230604130951-fix-hook-eventtypes.ts +12 -0
  218. package/src/migrations/sql/20230617081049-discordId-for-users.ts +16 -0
  219. package/src/migrations/sql/20230618053611-discord-funtionality.ts +34 -0
  220. package/src/migrations/sql/20230622192402-discord-hooks.ts +20 -0
  221. package/src/migrations/sql/20230707081218-playerOnGameServerExtension.ts +21 -0
  222. package/src/migrations/sql/20230710174340-events.ts +21 -0
  223. package/src/migrations/sql/20230712061220-roles-permissions-extension.ts +50 -0
  224. package/src/migrations/sql/20230713184927-variables-modulescoped.ts +32 -0
  225. package/src/migrations/sql/20230714045136-domain-index.ts +40 -0
  226. package/src/migrations/sql/20230714045727-events-index.ts +19 -0
  227. package/src/migrations/sql/20230715102519-module-permissions-extra-fields.ts +38 -0
  228. package/src/migrations/sql/20230724062109-roles-constraints.ts +16 -0
  229. package/src/migrations/sql/20230811095701-userId-on-events.ts +14 -0
  230. package/src/migrations/sql/20230921123717-count-for-permissions.ts +101 -0
  231. package/src/migrations/sql/20231111102812-details-system-permissions.ts +192 -0
  232. package/src/migrations/sql/20231114151343-system-roles.ts +46 -0
  233. package/src/migrations/sql/20231118082301-add-new-permissions.ts +200 -0
  234. package/src/migrations/sql/20231119115037-timedRoles.ts +23 -0
  235. package/src/migrations/sql/20231123150854-economy-base.ts +15 -0
  236. package/src/migrations/sql/20231123171611-economy-settings.ts +15 -0
  237. package/src/migrations/sql/20231124140441-json-module-assignments.ts +29 -0
  238. package/src/migrations/sql/20231208114507-settings-refactor.ts +114 -0
  239. package/src/migrations/sql/20231208171234-game-items.ts +20 -0
  240. package/src/migrations/sql/20231216100720-player-inventory.ts +16 -0
  241. package/src/migrations/sql/20231222180438-steam-data.ts +27 -0
  242. package/src/migrations/sql/20231223132631-pog-online.ts +13 -0
  243. package/src/migrations/sql/20231223212031-unique-index-item-def.ts +27 -0
  244. package/src/migrations/sql/20231224135126-gameserver-online-status.ts +13 -0
  245. package/src/migrations/sql/20231224155226-unique-pog.ts +27 -0
  246. package/src/migrations/sql/20231225140650-extra-ip-info.ts +27 -0
  247. package/src/migrations/sql/20231227144315-unique-constraints-player.ts +74 -0
  248. package/src/migrations/sql/20231229144707-more-player-constraints.ts +20 -0
  249. package/src/migrations/sql/20240101162751-add-settings-constraint.ts +39 -0
  250. package/src/migrations/sql/20240105130846-remove-some-module-perms.ts +104 -0
  251. package/src/migrations/sql/20240116141936-add-ui-schema-to-module.ts +13 -0
  252. package/src/migrations/sql/20240119152426-remove-hook-check.ts +18 -0
  253. package/src/migrations/sql/20240121142329-move-ip-history.ts +53 -0
  254. package/src/migrations/sql/20240202101208-rename-economy-to-economyUtils.ts +15 -0
  255. package/src/migrations/sql/20240216120143-domain-state.ts +13 -0
  256. package/src/migrations/sql/20240229141340-looser-fks-events.ts +20 -0
  257. package/src/migrations/sql/20240301063505-module-functions.ts +17 -0
  258. package/src/migrations/util/alterEnum.ts +10 -0
  259. package/src/queryBuilder.ts +133 -0
  260. package/src/redis.ts +58 -0
  261. package/tsconfig.build.json +9 -0
  262. package/tsconfig.json +8 -0
  263. package/typedoc.json +3 -0
@@ -0,0 +1,28 @@
1
+ import { QueryBuilder as ObjectionQueryBuilder, Model as ObjectionModel, Page } from 'objection';
2
+ export declare class ITakaroQuery<T> {
3
+ filters?: {
4
+ [key in keyof T]?: unknown[] | unknown;
5
+ };
6
+ search?: {
7
+ [key in keyof T]?: unknown[] | unknown;
8
+ };
9
+ page?: number;
10
+ limit?: number;
11
+ sortBy?: Extract<keyof T, string>;
12
+ sortDirection?: SortDirection;
13
+ startDate?: string;
14
+ endDate?: string;
15
+ extend?: string[];
16
+ }
17
+ export declare enum SortDirection {
18
+ asc = "asc",
19
+ desc = "desc"
20
+ }
21
+ export declare class QueryBuilder<Model extends ObjectionModel, OutputDTO> {
22
+ private readonly query;
23
+ constructor(query?: ITakaroQuery<OutputDTO>);
24
+ build(query: ObjectionQueryBuilder<Model, Model[]>): ObjectionQueryBuilder<Model, Page<Model>>;
25
+ private filters;
26
+ private sorting;
27
+ private pagination;
28
+ }
@@ -0,0 +1,132 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { IsDateString, IsEnum, IsNumber, IsOptional, IsString } from 'class-validator';
11
+ export class ITakaroQuery {
12
+ }
13
+ __decorate([
14
+ IsOptional(),
15
+ __metadata("design:type", Object)
16
+ ], ITakaroQuery.prototype, "filters", void 0);
17
+ __decorate([
18
+ IsOptional(),
19
+ __metadata("design:type", Object)
20
+ ], ITakaroQuery.prototype, "search", void 0);
21
+ __decorate([
22
+ IsOptional(),
23
+ IsNumber(),
24
+ __metadata("design:type", Number)
25
+ ], ITakaroQuery.prototype, "page", void 0);
26
+ __decorate([
27
+ IsOptional(),
28
+ IsNumber(),
29
+ __metadata("design:type", Number)
30
+ ], ITakaroQuery.prototype, "limit", void 0);
31
+ __decorate([
32
+ IsOptional(),
33
+ IsString(),
34
+ __metadata("design:type", Object)
35
+ ], ITakaroQuery.prototype, "sortBy", void 0);
36
+ __decorate([
37
+ IsOptional(),
38
+ IsString(),
39
+ IsEnum(['asc', 'desc']),
40
+ __metadata("design:type", String)
41
+ ], ITakaroQuery.prototype, "sortDirection", void 0);
42
+ __decorate([
43
+ IsOptional(),
44
+ IsDateString(),
45
+ __metadata("design:type", String)
46
+ ], ITakaroQuery.prototype, "startDate", void 0);
47
+ __decorate([
48
+ IsOptional(),
49
+ IsDateString(),
50
+ __metadata("design:type", String)
51
+ ], ITakaroQuery.prototype, "endDate", void 0);
52
+ __decorate([
53
+ IsOptional(),
54
+ IsString({ each: true }),
55
+ __metadata("design:type", Array)
56
+ ], ITakaroQuery.prototype, "extend", void 0);
57
+ export var SortDirection;
58
+ (function (SortDirection) {
59
+ SortDirection["asc"] = "asc";
60
+ SortDirection["desc"] = "desc";
61
+ })(SortDirection || (SortDirection = {}));
62
+ export class QueryBuilder {
63
+ constructor(query = new ITakaroQuery()) {
64
+ this.query = query;
65
+ }
66
+ build(query) {
67
+ const tableName = query.modelClass().tableName;
68
+ const pagination = this.pagination();
69
+ const sorting = this.sorting();
70
+ let qry = query.page(pagination.page, pagination.limit).orderBy(sorting.sortBy, sorting.sortDirection);
71
+ if (this.query.startDate) {
72
+ qry = qry.where(`${tableName}.createdAt`, '>=', this.query.startDate);
73
+ }
74
+ if (this.query.endDate) {
75
+ qry = qry.where(`${tableName}.createdAt`, '<=', this.query.endDate);
76
+ }
77
+ qry = this.filters(tableName, qry);
78
+ if (this.query.search) {
79
+ qry.where((builder) => {
80
+ for (const search in this.query.search) {
81
+ if (Object.prototype.hasOwnProperty.call(this.query.search, search)) {
82
+ const searchVal = this.query.search[search];
83
+ if (Array.isArray(searchVal)) {
84
+ searchVal.forEach((val) => {
85
+ if (val) {
86
+ builder.orWhere(`${tableName}.${search}`, 'ilike', `%${val}%`);
87
+ }
88
+ });
89
+ }
90
+ }
91
+ }
92
+ });
93
+ }
94
+ for (const extend of this.query.extend ?? []) {
95
+ qry.withGraphFetched(extend);
96
+ }
97
+ return qry;
98
+ }
99
+ filters(tableName, query) {
100
+ for (const filter in this.query.filters) {
101
+ if (Object.prototype.hasOwnProperty.call(this.query.filters, filter)) {
102
+ const searchVal = this.query.filters[filter];
103
+ if (searchVal && Array.isArray(searchVal)) {
104
+ const filtered = searchVal.filter(Boolean);
105
+ if (filtered.length) {
106
+ query.whereIn(`${tableName}.${filter}`, searchVal.filter(Boolean));
107
+ }
108
+ }
109
+ }
110
+ }
111
+ return query;
112
+ }
113
+ sorting() {
114
+ if (!this.query.sortBy) {
115
+ return {
116
+ sortBy: 'id',
117
+ sortDirection: SortDirection.asc,
118
+ };
119
+ }
120
+ return {
121
+ sortBy: this.query.sortBy,
122
+ sortDirection: this.query.sortDirection ?? SortDirection.asc,
123
+ };
124
+ }
125
+ pagination() {
126
+ return {
127
+ page: this.query.page ?? 0,
128
+ limit: this.query.limit ?? 100,
129
+ };
130
+ }
131
+ }
132
+ //# sourceMappingURL=queryBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryBuilder.js","sourceRoot":"","sources":["../src/queryBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { createClient, RedisClientOptions } from 'redis';
2
+ type RedisClient = ReturnType<typeof createClient>;
3
+ declare class RedisClass {
4
+ private log;
5
+ private clients;
6
+ /**
7
+ * Get a Redis client from the cache, or create a new one.
8
+ * The client will already be connected.
9
+ * @param name Name for the client, used to cache the client.
10
+ * @param extra Any extra Redis options to pass to the client.
11
+ * @returns
12
+ */
13
+ getClient(name: string, extra?: RedisClientOptions): Promise<RedisClient>;
14
+ /**
15
+ * Disconnect all clients and clear the cache.
16
+ */
17
+ destroy(): Promise<void>;
18
+ }
19
+ export declare const Redis: RedisClass;
20
+ export {};
package/dist/redis.js ADDED
@@ -0,0 +1,49 @@
1
+ import { createClient } from 'redis';
2
+ import { config } from './config.js';
3
+ import { logger, health } from '@takaro/util';
4
+ class RedisClass {
5
+ constructor() {
6
+ this.log = logger('redis');
7
+ this.clients = new Map();
8
+ }
9
+ /**
10
+ * Get a Redis client from the cache, or create a new one.
11
+ * The client will already be connected.
12
+ * @param name Name for the client, used to cache the client.
13
+ * @param extra Any extra Redis options to pass to the client.
14
+ * @returns
15
+ */
16
+ async getClient(name, extra = {}) {
17
+ const cachedClient = this.clients.get(name);
18
+ if (cachedClient)
19
+ return cachedClient;
20
+ this.log.debug(`Creating new Redis client for ${name}`);
21
+ const client = createClient({
22
+ name,
23
+ username: config.get('redis.username'),
24
+ password: config.get('redis.password'),
25
+ socket: {
26
+ host: config.get('redis.host'),
27
+ port: config.get('redis.port'),
28
+ },
29
+ ...extra,
30
+ });
31
+ await client.connect();
32
+ this.clients.set(name, client);
33
+ health.registerHook(name, async () => {
34
+ await client.ping();
35
+ });
36
+ return client;
37
+ }
38
+ /**
39
+ * Disconnect all clients and clear the cache.
40
+ */
41
+ async destroy() {
42
+ for (const [name, client] of this.clients.entries()) {
43
+ this.log.debug(`Disconnecting Redis client ${name}`);
44
+ await client.disconnect();
45
+ }
46
+ }
47
+ }
48
+ export const Redis = new RedisClass();
49
+ //# sourceMappingURL=redis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../src/redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAsB,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI9C,MAAM,UAAU;IAAhB;QACU,QAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAEtB,YAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IA8CnD,CAAC;IA5CC;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,QAA4B,EAAE;QAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,YAAY;YAAE,OAAO,YAAY,CAAC;QAEtC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG,YAAY,CAAC;YAC1B,IAAI;YACJ,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACtC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACtC,MAAM,EAAE;gBACN,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;gBAC9B,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;aAC/B;YACD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAE/B,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;YACnC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,IAAI,EAAE,CAAC,CAAC;YACrD,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@takaro/db",
3
+ "version": "0.0.1",
4
+ "description": "An opinionated data layer",
5
+ "main": "dist/main.js",
6
+ "types": "dist/main.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "start:dev": "tsc --watch --preserveWatchOutput -p ./tsconfig.build.json",
10
+ "build": "tsc -p ./tsconfig.build.json",
11
+ "test": "npm run test:unit --if-present && npm run test:integration --if-present",
12
+ "test:unit": "echo 'No tests (yet :))'",
13
+ "test:integration": "mocha --config ../../.mocharc.js src/**/*.integration.test.ts --exit",
14
+ "migrate:create": "run(){ touch ./src/migrations/sql/$(date -u +\"%Y%m%d%H%M%S\")-$1.ts; }; run"
15
+ },
16
+ "keywords": [],
17
+ "author": "",
18
+ "license": "ISC",
19
+ "dependencies": {
20
+ "convict": "^6.2.3",
21
+ "knex": "^2.2.0",
22
+ "objection": "^3.0.1",
23
+ "pg": "^8.8.0"
24
+ },
25
+ "devDependencies": {
26
+ "@takaro/test": "0.0.1",
27
+ "@types/convict": "^6.1.1"
28
+ }
29
+ }
@@ -0,0 +1,32 @@
1
+ import Objection, { Model } from 'objection';
2
+
3
+ export class NOT_DOMAIN_SCOPED_TakaroModel extends Model {
4
+ id: string;
5
+ createdAt: string;
6
+ updatedAt: string;
7
+
8
+ static get idColumn() {
9
+ return 'id';
10
+ }
11
+
12
+ $beforeInsert() {
13
+ this.createdAt = new Date().toISOString();
14
+ }
15
+
16
+ $beforeUpdate() {
17
+ this.updatedAt = new Date().toISOString();
18
+ }
19
+ }
20
+
21
+ export class TakaroModel extends NOT_DOMAIN_SCOPED_TakaroModel {
22
+ domain: string;
23
+
24
+ static get modifiers() {
25
+ return {
26
+ domainScoped(query: Objection.QueryBuilder<Model>, domainId: string) {
27
+ const tableName = query.modelClass().tableName;
28
+ query.where(`${tableName}.domain`, domainId);
29
+ },
30
+ };
31
+ }
32
+ }
@@ -0,0 +1,56 @@
1
+ import { compareHashed, decrypt, encrypt, hash } from '../encryption.js';
2
+ import { expect } from '@takaro/test';
3
+ import { getKnex } from '../knex.js';
4
+
5
+ describe('Database encryption', () => {
6
+ before(async () => {
7
+ const knex = await getKnex();
8
+ await knex.raw('CREATE EXTENSION IF NOT EXISTS pgcrypto;');
9
+ });
10
+
11
+ describe('Encryption', () => {
12
+ it('Can encrypt a simple string', async () => {
13
+ const encrypted = await encrypt('test');
14
+ expect(encrypted).to.not.eq('test');
15
+ });
16
+
17
+ it('Can decrypt a simple string', async () => {
18
+ const encrypted = await encrypt('test');
19
+ const decrypted = await decrypt(encrypted);
20
+ expect(decrypted).to.eq('test');
21
+ });
22
+
23
+ it('Can handle complex JSON structures', async () => {
24
+ const encrypted = await encrypt(JSON.stringify({ foo: 'bar' }));
25
+ const decrypted = await decrypt(encrypted);
26
+ expect(decrypted).to.eq(JSON.stringify({ foo: 'bar' }));
27
+ });
28
+
29
+ it('Can handle very long values', async () => {
30
+ const longValue = 'a'.repeat(10000);
31
+ const encrypted = await encrypt(longValue);
32
+ const decrypted = await decrypt(encrypted);
33
+ expect(decrypted).to.eq(longValue);
34
+ });
35
+ });
36
+
37
+ describe('Hashing', async () => {
38
+ it('Can hash a simple string', async () => {
39
+ const hashed = await hash('test');
40
+ expect(hashed).to.not.eq('test');
41
+ expect(hashed).to.match(/^\$2a\$06\$/);
42
+ });
43
+
44
+ it('Can compare a simple string', async () => {
45
+ const hashed = await hash('test');
46
+ const result = await compareHashed('test', hashed);
47
+ expect(result).to.eq(true);
48
+ });
49
+
50
+ it('Returns false when comparing different strings', async () => {
51
+ const hashed = await hash('test');
52
+ const result = await compareHashed('test2', hashed);
53
+ expect(result).to.eq(false);
54
+ });
55
+ });
56
+ });
@@ -0,0 +1,202 @@
1
+ import { disconnectKnex, getKnex } from '../knex.js';
2
+ import { QueryBuilder, SortDirection } from '../queryBuilder.js';
3
+ import { expect } from '@takaro/test';
4
+ import { TakaroModel } from '../TakaroModel.js';
5
+ import { Model } from 'objection';
6
+ import { sleep } from '@takaro/util';
7
+
8
+ const TEST_TABLE_USERS_NAME = 'test_users';
9
+ const TEST_TABLE_POSTS_NAME = 'test_posts';
10
+
11
+ class TestPostModel extends TakaroModel {
12
+ static tableName = TEST_TABLE_POSTS_NAME;
13
+ title!: string;
14
+ userId!: string;
15
+
16
+ static relationMappings = {
17
+ author: {
18
+ relation: Model.HasOneRelation,
19
+ modelClass: () => TestUserModel,
20
+ join: {
21
+ from: `${TEST_TABLE_POSTS_NAME}.userId`,
22
+ to: `${TEST_TABLE_USERS_NAME}.id`,
23
+ },
24
+ },
25
+ };
26
+ }
27
+
28
+ class TestUserModel extends TakaroModel {
29
+ static tableName = TEST_TABLE_USERS_NAME;
30
+ name!: string;
31
+
32
+ static relationMappings = {
33
+ posts: {
34
+ relation: Model.HasManyRelation,
35
+ modelClass: TestPostModel,
36
+ join: {
37
+ from: `${TEST_TABLE_USERS_NAME}.id`,
38
+ to: `${TEST_TABLE_POSTS_NAME}.userId`,
39
+ },
40
+ },
41
+ };
42
+ }
43
+
44
+ describe('QueryBuilder', () => {
45
+ beforeEach(async () => {
46
+ const knex = await getKnex();
47
+ await knex.schema.dropTableIfExists(TEST_TABLE_USERS_NAME);
48
+ await knex.schema.dropTableIfExists(TEST_TABLE_POSTS_NAME);
49
+ await knex.schema.createTable(TEST_TABLE_USERS_NAME, (table) => {
50
+ table.timestamps(true, true, true);
51
+ table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid ()'));
52
+ table.string('name');
53
+ });
54
+ await knex.schema.createTable(TEST_TABLE_POSTS_NAME, (table) => {
55
+ table.timestamps(true, true, true);
56
+ table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid ()'));
57
+ table.string('title');
58
+ table.uuid('userId');
59
+ });
60
+
61
+ TestUserModel.knex(knex);
62
+ TestPostModel.knex(knex);
63
+ });
64
+
65
+ afterEach(async () => {
66
+ const knex = await getKnex();
67
+ await knex.schema.dropTableIfExists(TEST_TABLE_USERS_NAME);
68
+ await disconnectKnex();
69
+ });
70
+
71
+ it('Can create basic filters', async () => {
72
+ await TestUserModel.query().insert({ name: 'test1' });
73
+ await TestUserModel.query().insert({ name: 'test2' });
74
+ await TestUserModel.query().insert({ name: 'test3' });
75
+
76
+ const res = await new QueryBuilder<TestUserModel, TestUserModel>({
77
+ filters: { name: ['test2'] },
78
+ }).build(TestUserModel.query());
79
+
80
+ expect(res.results).to.have.lengthOf(1);
81
+ expect(res.results[0].name).to.equal('test2');
82
+ });
83
+
84
+ it('Can filter based on multiple values', async () => {
85
+ await TestUserModel.query().insert({ name: 'test1' });
86
+ await TestUserModel.query().insert({ name: 'test2' });
87
+ await TestUserModel.query().insert({ name: 'test3' });
88
+
89
+ const res = await new QueryBuilder<TestUserModel, TestUserModel>({
90
+ filters: { name: ['test2', 'test3'] },
91
+ sortBy: 'name',
92
+ }).build(TestUserModel.query());
93
+
94
+ expect(res.results).to.have.lengthOf(2);
95
+ expect(res.results[0].name).to.equal('test2');
96
+ expect(res.results[1].name).to.equal('test3');
97
+ });
98
+
99
+ it('Can do paging', async () => {
100
+ const totalTestRecords = 100;
101
+
102
+ for (let i = 0; i < totalTestRecords; i++) {
103
+ const number = i.toString().padStart(3, '0');
104
+ await TestUserModel.query().insert({ name: `test${number}` });
105
+ }
106
+
107
+ const res = await new QueryBuilder<TestUserModel, TestUserModel>({
108
+ page: 2,
109
+ limit: 10,
110
+ sortBy: 'name',
111
+ sortDirection: SortDirection.asc,
112
+ }).build(TestUserModel.query());
113
+
114
+ expect(res.results).to.have.lengthOf(10);
115
+ expect(res.results[0].name).to.equal('test020');
116
+ expect(res.total).to.equal(totalTestRecords);
117
+ });
118
+
119
+ it('Can do sorting', async () => {
120
+ await TestUserModel.query().insert({ name: 'test1' });
121
+ await TestUserModel.query().insert({ name: 'test2' });
122
+ await TestUserModel.query().insert({ name: 'test3' });
123
+
124
+ const res = await new QueryBuilder<TestUserModel, TestUserModel>({
125
+ sortBy: 'name',
126
+ sortDirection: SortDirection.desc,
127
+ }).build(TestUserModel.query());
128
+
129
+ expect(res.results).to.have.lengthOf(3);
130
+ expect(res.results[0].name).to.equal('test3');
131
+ });
132
+
133
+ it('Can do extending', async () => {
134
+ const user = await TestUserModel.query().insert({ name: 'test1' });
135
+ await TestPostModel.query().insert({ title: 'test1', userId: user.id });
136
+
137
+ const res = await new QueryBuilder<
138
+ TestPostModel & { author?: TestUserModel },
139
+ TestPostModel & { author?: TestUserModel }
140
+ >({ extend: ['author'] }).build(TestPostModel.query());
141
+
142
+ expect(res.results).to.have.lengthOf(1);
143
+ expect(res.results[0].author?.name).to.equal('test1');
144
+ });
145
+
146
+ it('Can do partial matching of strings', async () => {
147
+ await TestUserModel.query().insert({ name: 'test1' });
148
+ await TestUserModel.query().insert({ name: 'test2' });
149
+ await TestUserModel.query().insert({ name: 'test3' });
150
+
151
+ const res = await new QueryBuilder<TestUserModel, TestUserModel>({
152
+ search: {
153
+ name: ['test'],
154
+ },
155
+ }).build(TestUserModel.query());
156
+
157
+ expect(res.results).to.have.lengthOf(3);
158
+
159
+ const res2 = await new QueryBuilder<TestUserModel, TestUserModel>({
160
+ search: {
161
+ name: ['1'],
162
+ },
163
+ }).build(TestUserModel.query());
164
+
165
+ expect(res2.results).to.have.lengthOf(1);
166
+ });
167
+
168
+ it('Can search for multiple values, ORs them', async () => {
169
+ await TestUserModel.query().insert({ name: 'test1' });
170
+ await TestUserModel.query().insert({ name: 'test2' });
171
+ await TestUserModel.query().insert({ name: 'test3' });
172
+
173
+ const res = await new QueryBuilder<TestUserModel, TestUserModel>({
174
+ search: {
175
+ name: ['st1', 'st2'],
176
+ },
177
+ }).build(TestUserModel.query());
178
+
179
+ expect(res.results).to.have.lengthOf(2);
180
+ });
181
+
182
+ it('Can search between a date range', async () => {
183
+ const start = new Date();
184
+ await TestUserModel.query().insert({ name: 'test1' });
185
+ await TestUserModel.query().insert({ name: 'test2' });
186
+
187
+ const end = new Date();
188
+
189
+ // Quick hack to make the test pass
190
+ // Relying on times like this with an external DB is troublesome...
191
+ await sleep(250);
192
+
193
+ await TestUserModel.query().insert({ name: 'test3', createdAt: end.toISOString() });
194
+
195
+ const res = await new QueryBuilder<TestUserModel, TestUserModel>({
196
+ startDate: start.toISOString(),
197
+ endDate: end.toISOString(),
198
+ }).build(TestUserModel.query());
199
+
200
+ expect(res.results).to.have.lengthOf(2);
201
+ });
202
+ });
package/src/config.ts ADDED
@@ -0,0 +1,101 @@
1
+ import { Config, IBaseConfig, baseConfigConvict } from '@takaro/config';
2
+
3
+ export interface IDbConfig extends IBaseConfig {
4
+ postgres: {
5
+ host: string;
6
+ port: number;
7
+ user: string;
8
+ password: string;
9
+ database: string;
10
+ };
11
+ redis: {
12
+ host: string;
13
+ port: number;
14
+ username: string;
15
+ password: string;
16
+ };
17
+ systemSchema: string;
18
+ baseDomainSchema: string;
19
+ encryptionKey: string;
20
+ }
21
+
22
+ export const configSchema = {
23
+ postgres: {
24
+ host: {
25
+ doc: 'The Postgres host to connect to',
26
+ format: String,
27
+ default: 'localhost',
28
+ env: 'POSTGRES_HOST',
29
+ },
30
+ port: {
31
+ doc: 'The Postgres port to connect to',
32
+ format: Number,
33
+ default: 5432,
34
+ env: 'POSTGRES_PORT',
35
+ },
36
+ user: {
37
+ doc: 'The Postgres user to connect as',
38
+ format: String,
39
+ default: 'postgres',
40
+ env: 'POSTGRES_USER',
41
+ },
42
+ password: {
43
+ doc: 'The Postgres password to use',
44
+ format: String,
45
+ default: 'postgres',
46
+ env: 'POSTGRES_PASSWORD',
47
+ },
48
+ database: {
49
+ doc: 'The Postgres database to use',
50
+ format: String,
51
+ default: 'postgres',
52
+ env: 'POSTGRES_DB',
53
+ },
54
+ },
55
+ redis: {
56
+ host: {
57
+ doc: 'The host of the redis server',
58
+ format: String,
59
+ default: 'localhost',
60
+ env: 'REDIS_HOST',
61
+ },
62
+ port: {
63
+ doc: 'The port of the redis server',
64
+ format: Number,
65
+ default: 6379,
66
+ env: 'REDIS_PORT',
67
+ },
68
+ username: {
69
+ doc: 'The username of the redis server',
70
+ format: String,
71
+ default: '',
72
+ env: 'REDIS_USERNAME',
73
+ },
74
+ password: {
75
+ doc: 'The password of the redis server',
76
+ format: String,
77
+ default: '',
78
+ env: 'REDIS_PASSWORD',
79
+ },
80
+ },
81
+ systemSchema: {
82
+ doc: 'The Postgres schema to use for system-related actions (like domain management)',
83
+ format: String,
84
+ default: 'takaro',
85
+ env: 'POSTGRES_SYSTEM_SCHEMA',
86
+ },
87
+ baseDomainSchema: {
88
+ doc: 'String used as base for creating name of domain-scoped schemas',
89
+ format: String,
90
+ default: 'domain_',
91
+ env: 'POSTGRES_BASE_DOMAIN_SCHEMA',
92
+ },
93
+ encryptionKey: {
94
+ doc: 'Encryption key used for encrypting sensitive data',
95
+ format: String,
96
+ default: null,
97
+ env: 'POSTGRES_ENCRYPTION_KEY',
98
+ },
99
+ };
100
+
101
+ export const config = new Config<IDbConfig>([configSchema, baseConfigConvict]);