@appweaver/core 1.0.0

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 (271) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +7 -0
  3. package/app/application.d.ts +43 -0
  4. package/app/application.js +112 -0
  5. package/app/create-app.d.ts +32 -0
  6. package/app/create-app.js +38 -0
  7. package/app/index.d.ts +2 -0
  8. package/app/index.js +18 -0
  9. package/app/lifecycle-manager.d.ts +20 -0
  10. package/app/lifecycle-manager.js +42 -0
  11. package/app/load-modules.d.ts +10 -0
  12. package/app/load-modules.js +50 -0
  13. package/app/load-providers.d.ts +8 -0
  14. package/app/load-providers.js +33 -0
  15. package/cache/cache-service.d.ts +72 -0
  16. package/cache/cache-service.js +202 -0
  17. package/cache/cache.d.ts +12 -0
  18. package/cache/cache.js +184 -0
  19. package/cache/caching.d.ts +8 -0
  20. package/cache/caching.js +72 -0
  21. package/cache/eviction/eviction-index.d.ts +35 -0
  22. package/cache/eviction/eviction-index.js +2 -0
  23. package/cache/eviction/fifo-eviction-index.d.ts +7 -0
  24. package/cache/eviction/fifo-eviction-index.js +28 -0
  25. package/cache/eviction/index.d.ts +4 -0
  26. package/cache/eviction/index.js +20 -0
  27. package/cache/eviction/lfu-eviction-index.d.ts +8 -0
  28. package/cache/eviction/lfu-eviction-index.js +82 -0
  29. package/cache/eviction/lru-eviction-index.d.ts +8 -0
  30. package/cache/eviction/lru-eviction-index.js +81 -0
  31. package/cache/index.d.ts +2 -0
  32. package/cache/index.js +18 -0
  33. package/cache/memory-cache.d.ts +4 -0
  34. package/cache/memory-cache.js +12 -0
  35. package/cache/redis-cache.d.ts +4 -0
  36. package/cache/redis-cache.js +12 -0
  37. package/context/context.d.ts +2 -0
  38. package/context/context.js +13 -0
  39. package/context/dependency-injection.d.ts +98 -0
  40. package/context/dependency-injection.js +276 -0
  41. package/context/index.d.ts +2 -0
  42. package/context/index.js +18 -0
  43. package/database/create-client.d.ts +11 -0
  44. package/database/create-client.js +142 -0
  45. package/database/index.d.ts +1 -0
  46. package/database/index.js +17 -0
  47. package/database/prisma-database.d.ts +15 -0
  48. package/database/prisma-database.js +53 -0
  49. package/errors/error-handler.d.ts +3 -0
  50. package/errors/error-handler.js +24 -0
  51. package/errors/error-schema.d.ts +32 -0
  52. package/errors/error-schema.js +31 -0
  53. package/errors/http-error.d.ts +21 -0
  54. package/errors/http-error.js +33 -0
  55. package/errors/index.d.ts +3 -0
  56. package/errors/index.js +19 -0
  57. package/events/node-events.d.ts +7 -0
  58. package/events/node-events.js +39 -0
  59. package/export/export-service.d.ts +19 -0
  60. package/export/export-service.js +154 -0
  61. package/export/index.d.ts +1 -0
  62. package/export/index.js +17 -0
  63. package/factory/create-model.d.ts +2 -0
  64. package/factory/create-model.js +366 -0
  65. package/factory/create-policy.d.ts +2 -0
  66. package/factory/create-policy.js +16 -0
  67. package/factory/create-routes.d.ts +2 -0
  68. package/factory/create-routes.js +21 -0
  69. package/factory/create-service.d.ts +3 -0
  70. package/factory/create-service.js +97 -0
  71. package/factory/index.d.ts +4 -0
  72. package/factory/index.js +20 -0
  73. package/health/health-routes.d.ts +2 -0
  74. package/health/health-routes.js +36 -0
  75. package/health/health-schema.d.ts +45 -0
  76. package/health/health-schema.js +52 -0
  77. package/health/health-service.d.ts +38 -0
  78. package/health/health-service.js +82 -0
  79. package/health/index.d.ts +2 -0
  80. package/health/index.js +18 -0
  81. package/index.d.ts +15 -0
  82. package/index.js +31 -0
  83. package/mailer/email-service.d.ts +36 -0
  84. package/mailer/email-service.js +89 -0
  85. package/mailer/index.d.ts +1 -0
  86. package/mailer/index.js +17 -0
  87. package/mailer/json-mailer.d.ts +7 -0
  88. package/mailer/json-mailer.js +32 -0
  89. package/mailer/smtp-mailer.d.ts +7 -0
  90. package/mailer/smtp-mailer.js +43 -0
  91. package/memory/in-memory.d.ts +24 -0
  92. package/memory/in-memory.js +164 -0
  93. package/memory/redis.d.ts +26 -0
  94. package/memory/redis.js +158 -0
  95. package/package.json +68 -0
  96. package/prisma/client/browser.d.ts +34 -0
  97. package/prisma/client/browser.js +56 -0
  98. package/prisma/client/client.d.ts +53 -0
  99. package/prisma/client/client.js +70 -0
  100. package/prisma/client/commonInputTypes.d.ts +395 -0
  101. package/prisma/client/commonInputTypes.js +11 -0
  102. package/prisma/client/enums.d.ts +1 -0
  103. package/prisma/client/enums.js +11 -0
  104. package/prisma/client/internal/class.d.ts +187 -0
  105. package/prisma/client/internal/class.js +85 -0
  106. package/prisma/client/internal/prismaNamespace.d.ts +987 -0
  107. package/prisma/client/internal/prismaNamespace.js +193 -0
  108. package/prisma/client/internal/prismaNamespaceBrowser.d.ts +125 -0
  109. package/prisma/client/internal/prismaNamespaceBrowser.js +164 -0
  110. package/prisma/client/models/ApiKey.d.ts +1167 -0
  111. package/prisma/client/models/ApiKey.js +2 -0
  112. package/prisma/client/models/File.d.ts +1248 -0
  113. package/prisma/client/models/File.js +2 -0
  114. package/prisma/client/models/OneTimeToken.d.ts +1083 -0
  115. package/prisma/client/models/OneTimeToken.js +2 -0
  116. package/prisma/client/models/Permission.d.ts +1209 -0
  117. package/prisma/client/models/Permission.js +2 -0
  118. package/prisma/client/models/Role.d.ts +1209 -0
  119. package/prisma/client/models/Role.js +2 -0
  120. package/prisma/client/models/Seeder.d.ts +1023 -0
  121. package/prisma/client/models/Seeder.js +2 -0
  122. package/prisma/client/models.d.ts +7 -0
  123. package/prisma/client/models.js +2 -0
  124. package/queue/bull-queue.d.ts +37 -0
  125. package/queue/bull-queue.js +207 -0
  126. package/queue/memory-queue.d.ts +54 -0
  127. package/queue/memory-queue.js +283 -0
  128. package/resource/index.d.ts +4 -0
  129. package/resource/index.js +20 -0
  130. package/resource/resource-loader.d.ts +26 -0
  131. package/resource/resource-loader.js +161 -0
  132. package/resource/resource-routes.d.ts +3 -0
  133. package/resource/resource-routes.js +174 -0
  134. package/resource/resource-schema.d.ts +33 -0
  135. package/resource/resource-schema.js +186 -0
  136. package/resource/resource-service.d.ts +89 -0
  137. package/resource/resource-service.js +772 -0
  138. package/resources.d.ts +9 -0
  139. package/resources.js +24 -0
  140. package/scheduler/cron-scheduler.d.ts +12 -0
  141. package/scheduler/cron-scheduler.js +73 -0
  142. package/security/account/account-routes.d.ts +2 -0
  143. package/security/account/account-routes.js +104 -0
  144. package/security/account/account-schema.d.ts +290 -0
  145. package/security/account/account-schema.js +166 -0
  146. package/security/account/account-service.d.ts +88 -0
  147. package/security/account/account-service.js +218 -0
  148. package/security/account/index.d.ts +3 -0
  149. package/security/account/index.js +19 -0
  150. package/security/api-key/api-key-auth.d.ts +4 -0
  151. package/security/api-key/api-key-auth.js +66 -0
  152. package/security/api-key/index.d.ts +1 -0
  153. package/security/api-key/index.js +17 -0
  154. package/security/auth-routes.d.ts +2 -0
  155. package/security/auth-routes.js +80 -0
  156. package/security/auth-schema.d.ts +215 -0
  157. package/security/auth-schema.js +129 -0
  158. package/security/auth-service.d.ts +117 -0
  159. package/security/auth-service.js +272 -0
  160. package/security/auth.d.ts +3 -0
  161. package/security/auth.js +127 -0
  162. package/security/basic/basic-auth.d.ts +4 -0
  163. package/security/basic/basic-auth.js +32 -0
  164. package/security/basic/index.d.ts +1 -0
  165. package/security/basic/index.js +17 -0
  166. package/security/create-auth-resources.d.ts +6 -0
  167. package/security/create-auth-resources.js +129 -0
  168. package/security/helper.d.ts +127 -0
  169. package/security/helper.js +329 -0
  170. package/security/index.d.ts +4 -0
  171. package/security/index.js +20 -0
  172. package/security/jwt/index.d.ts +2 -0
  173. package/security/jwt/index.js +18 -0
  174. package/security/jwt/jwt-auth.d.ts +4 -0
  175. package/security/jwt/jwt-auth.js +57 -0
  176. package/security/jwt/jwt-keys.d.ts +7 -0
  177. package/security/jwt/jwt-keys.js +43 -0
  178. package/security/oauth2/create-oauth2-plugin.d.ts +17 -0
  179. package/security/oauth2/create-oauth2-plugin.js +85 -0
  180. package/security/oauth2/index.d.ts +3 -0
  181. package/security/oauth2/index.js +19 -0
  182. package/security/oauth2/oauth2-custom.d.ts +7 -0
  183. package/security/oauth2/oauth2-custom.js +40 -0
  184. package/security/oauth2/oauth2-facebook.d.ts +1 -0
  185. package/security/oauth2/oauth2-facebook.js +30 -0
  186. package/security/oauth2/oauth2-google.d.ts +1 -0
  187. package/security/oauth2/oauth2-google.js +28 -0
  188. package/security/oauth2/oauth2-schema.d.ts +10 -0
  189. package/security/oauth2/oauth2-schema.js +53 -0
  190. package/security/recaptcha/index.d.ts +2 -0
  191. package/security/recaptcha/index.js +18 -0
  192. package/security/recaptcha/recaptcha-verify.d.ts +1 -0
  193. package/security/recaptcha/recaptcha-verify.js +33 -0
  194. package/security/recaptcha/recaptcha.d.ts +2 -0
  195. package/security/recaptcha/recaptcha.js +22 -0
  196. package/security/resources/api-key/model.d.ts +2 -0
  197. package/security/resources/api-key/model.js +63 -0
  198. package/security/resources/api-key/policy.d.ts +2 -0
  199. package/security/resources/api-key/policy.js +26 -0
  200. package/security/resources/api-key/routes.d.ts +2 -0
  201. package/security/resources/api-key/routes.js +15 -0
  202. package/security/resources/api-key/service.d.ts +3 -0
  203. package/security/resources/api-key/service.js +33 -0
  204. package/security/resources/one-time-token/model.d.ts +2 -0
  205. package/security/resources/one-time-token/model.js +32 -0
  206. package/security/resources/permission/model.d.ts +2 -0
  207. package/security/resources/permission/model.js +16 -0
  208. package/security/resources/role/model.d.ts +2 -0
  209. package/security/resources/role/model.js +22 -0
  210. package/security/store/database-security-store.d.ts +5 -0
  211. package/security/store/database-security-store.js +51 -0
  212. package/security/store/redis-security-store.d.ts +5 -0
  213. package/security/store/redis-security-store.js +32 -0
  214. package/seeder/create-seeder.d.ts +21 -0
  215. package/seeder/create-seeder.js +17 -0
  216. package/seeder/index.d.ts +2 -0
  217. package/seeder/index.js +18 -0
  218. package/seeder/resources/seeder/model.d.ts +2 -0
  219. package/seeder/resources/seeder/model.js +38 -0
  220. package/seeder/seeder.d.ts +20 -0
  221. package/seeder/seeder.js +175 -0
  222. package/server/create-server.d.ts +20 -0
  223. package/server/create-server.js +160 -0
  224. package/server/index.d.ts +4 -0
  225. package/server/index.js +20 -0
  226. package/server/info-route.d.ts +2 -0
  227. package/server/info-route.js +18 -0
  228. package/server/info-schema.d.ts +37 -0
  229. package/server/info-schema.js +19 -0
  230. package/server/register-model.d.ts +2 -0
  231. package/server/register-model.js +12 -0
  232. package/server/register-plugin.d.ts +2 -0
  233. package/server/register-plugin.js +13 -0
  234. package/server/register-route.d.ts +3 -0
  235. package/server/register-route.js +74 -0
  236. package/server/schemas.d.ts +3 -0
  237. package/server/schemas.js +30 -0
  238. package/server/swagger.d.ts +3 -0
  239. package/server/swagger.js +122 -0
  240. package/storage/file-route.d.ts +2 -0
  241. package/storage/file-route.js +39 -0
  242. package/storage/file-schema.d.ts +9 -0
  243. package/storage/file-schema.js +42 -0
  244. package/storage/file-service.d.ts +81 -0
  245. package/storage/file-service.js +384 -0
  246. package/storage/filesystem-storage.d.ts +10 -0
  247. package/storage/filesystem-storage.js +128 -0
  248. package/storage/index.d.ts +2 -0
  249. package/storage/index.js +18 -0
  250. package/storage/resources/file/model.d.ts +2 -0
  251. package/storage/resources/file/model.js +75 -0
  252. package/types/application-context.d.ts +20 -0
  253. package/types/application-context.js +2 -0
  254. package/types/auth.d.ts +31 -0
  255. package/types/auth.js +2 -0
  256. package/types/fastify-extensions.d.ts +24 -0
  257. package/types/fastify-extensions.js +4 -0
  258. package/types/generated.d.ts +193 -0
  259. package/types/generated.js +3 -0
  260. package/types/index.d.ts +4 -0
  261. package/types/index.js +20 -0
  262. package/types/server.d.ts +4 -0
  263. package/types/server.js +2 -0
  264. package/utils/export-util.d.ts +8 -0
  265. package/utils/export-util.js +25 -0
  266. package/utils/file-util.d.ts +64 -0
  267. package/utils/file-util.js +141 -0
  268. package/utils/index.d.ts +3 -0
  269. package/utils/index.js +19 -0
  270. package/utils/schema-util.d.ts +20 -0
  271. package/utils/schema-util.js +37 -0
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DatabaseSecurityStore = void 0;
4
+ const common_1 = require("@appweaver/common");
5
+ const context_1 = require("../../context");
6
+ const errors_1 = require("../../errors");
7
+ class DatabaseSecurityStore extends common_1.SecurityStore {
8
+ /** @internal */
9
+ _db = (0, context_1.inject)(common_1.Database);
10
+ async generateOneTimeToken(purpose, data, ttl) {
11
+ const token = (0, common_1.generateToken)('bytes', 64);
12
+ await this._db.client().oneTimeToken.create({
13
+ data: {
14
+ tokenHash: (0, common_1.makeHash)(token),
15
+ purpose,
16
+ expiresAt: new Date(Date.now() + ttl),
17
+ data: data
18
+ }
19
+ });
20
+ return token;
21
+ }
22
+ async useOneTimeToken(token, purpose, validateContent) {
23
+ const oneTimeToken = await this._db.client().oneTimeToken.findFirst({
24
+ where: {
25
+ purpose,
26
+ tokenHash: (0, common_1.makeHash)(token)
27
+ }
28
+ });
29
+ if (oneTimeToken === null ||
30
+ oneTimeToken.expiresAt.getTime() < Date.now()) {
31
+ if (oneTimeToken) {
32
+ await this.removeOneTimeToken(oneTimeToken.id);
33
+ }
34
+ throw new errors_1.HttpError('Invalid or expired token provided', 401);
35
+ }
36
+ const data = oneTimeToken.data;
37
+ if (validateContent) {
38
+ const result = validateContent(data);
39
+ if (!result.valid) {
40
+ throw new errors_1.HttpError(result.message, 401);
41
+ }
42
+ }
43
+ await this.removeOneTimeToken(oneTimeToken.id);
44
+ return data;
45
+ }
46
+ /** @internal */
47
+ async removeOneTimeToken(id) {
48
+ await this._db.client().oneTimeToken.delete({ where: { id } });
49
+ }
50
+ }
51
+ exports.DatabaseSecurityStore = DatabaseSecurityStore;
@@ -0,0 +1,5 @@
1
+ import { SecurityStore, ValidationResult } from '@appweaver/common';
2
+ export declare class RedisSecurityStore extends SecurityStore {
3
+ generateOneTimeToken<T = any>(purpose: string, data: T, ttl: number): Promise<string>;
4
+ useOneTimeToken<T = any>(token: string, purpose: string, validateContent?: (value: T) => ValidationResult): Promise<T>;
5
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisSecurityStore = void 0;
4
+ const common_1 = require("@appweaver/common");
5
+ const context_1 = require("../../context");
6
+ const errors_1 = require("../../errors");
7
+ const SECURITY_OTT_KEY = 'security:ott';
8
+ class RedisSecurityStore extends common_1.SecurityStore {
9
+ /** @internal */
10
+ _redis = (0, context_1.inject)(common_1.Redis);
11
+ async generateOneTimeToken(purpose, data, ttl) {
12
+ const token = (0, common_1.generateToken)('bytes', 64);
13
+ await this._redis.putValue(`${SECURITY_OTT_KEY}:${purpose}:${(0, common_1.makeHash)(token)}`, data, ttl);
14
+ return token;
15
+ }
16
+ async useOneTimeToken(token, purpose, validateContent) {
17
+ const tokenKey = `${SECURITY_OTT_KEY}:${purpose}:${(0, common_1.makeHash)(token)}`;
18
+ const value = await this._redis.getValue(tokenKey);
19
+ if (value === null) {
20
+ throw new errors_1.HttpError('Invalid or expired token provided', 401);
21
+ }
22
+ if (validateContent) {
23
+ const result = validateContent(value);
24
+ if (!result.valid) {
25
+ throw new errors_1.HttpError(result.message, 401);
26
+ }
27
+ }
28
+ await this._redis.removeValue(tokenKey);
29
+ return value;
30
+ }
31
+ }
32
+ exports.RedisSecurityStore = RedisSecurityStore;
@@ -0,0 +1,21 @@
1
+ import { Seeder } from './seeder';
2
+ export type CreateSeederParams = {
3
+ /** A relative path where the application source code is located.
4
+ * This is usually the directory from which the createApp() function is called.
5
+ * (default: ./dist/src) */
6
+ scanPath?: string;
7
+ /** A relative path where the seeder functions are located.
8
+ * (default: ./dist/database/seeders) */
9
+ seedersPath?: string;
10
+ /** A flag indication if the seeder should continue execution even if an error occurs.
11
+ * (default: false) */
12
+ continueOnError?: boolean;
13
+ /** A boolean flag indicating whether the seeder should automatically
14
+ * start seeding after being created. (default: true) **/
15
+ autoSeed?: boolean;
16
+ /** A boolean flag indicating whether to automatically fix all warnings
17
+ * related to the seeders like wrong checksum or deleted seeder files.
18
+ * (default: false) **/
19
+ fixWarnings?: boolean;
20
+ };
21
+ export declare function createSeeder(params?: CreateSeederParams): Promise<Seeder>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSeeder = createSeeder;
4
+ const common_1 = require("@appweaver/common");
5
+ const load_providers_1 = require("../app/load-providers");
6
+ const seeder_1 = require("./seeder");
7
+ async function createSeeder(params = {}) {
8
+ const scanPath = (0, common_1.resolveSourcePath)(common_1.config.APP_BUILD_PATH, common_1.config.APP_SOURCE_PATH, params.scanPath, './dist/src');
9
+ const seedersPath = (0, common_1.resolveSourcePath)(common_1.config.APP_BUILD_PATH, common_1.config.DATABASE_SEEDERS_DIR_PATH, params.seedersPath, './dist/database/seeders');
10
+ // Load all defined providers from this project
11
+ (0, load_providers_1.loadProviders)(scanPath);
12
+ const seeder = new seeder_1.Seeder(seedersPath, params.continueOnError, params.fixWarnings);
13
+ if (params.autoSeed !== false) {
14
+ await seeder.seed();
15
+ }
16
+ return seeder;
17
+ }
@@ -0,0 +1,2 @@
1
+ export * from './create-seeder';
2
+ export * from './seeder';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./create-seeder"), exports);
18
+ __exportStar(require("./seeder"), exports);
@@ -0,0 +1,2 @@
1
+ declare const _default: import("@appweaver/common").ResourceModel;
2
+ export default _default;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const factory_1 = require("../../../factory");
4
+ exports.default = (0, factory_1.createModel)({
5
+ name: 'Seeder',
6
+ tableName: '_seeders',
7
+ generateTypes: false,
8
+ id: {
9
+ type: 'string',
10
+ generator: 'uuid()'
11
+ },
12
+ audit: {
13
+ updatedAt: false,
14
+ createdAt: false,
15
+ createdById: false
16
+ },
17
+ scalars: {
18
+ checksum: {
19
+ type: 'string',
20
+ maxLength: 255
21
+ },
22
+ seederName: {
23
+ type: 'string',
24
+ unique: true,
25
+ maxLength: 511
26
+ },
27
+ startedAt: {
28
+ type: 'dateTime'
29
+ },
30
+ finishedAt: {
31
+ type: 'dateTime'
32
+ },
33
+ logs: {
34
+ type: 'string',
35
+ required: false
36
+ }
37
+ }
38
+ });
@@ -0,0 +1,20 @@
1
+ import { LifecycleManager } from '../app/lifecycle-manager';
2
+ /**
3
+ * Represents a seeder class that manages the application seeders processes.
4
+ */
5
+ export declare class Seeder extends LifecycleManager {
6
+ private readonly _dirPath;
7
+ private readonly _continueOnError;
8
+ private readonly _fixWarnings;
9
+ constructor(_dirPath: string, _continueOnError?: boolean, _fixWarnings?: boolean);
10
+ /**
11
+ * Executes the seeders by discovering, validating, and running seeder files.
12
+ * Logs the seeding process, including warnings for checksum mismatches
13
+ * and files that do not exist but are present in database table.
14
+ *
15
+ * @return Resolves when all seeders have been processed. Logs relevant
16
+ * information during execution.
17
+ */
18
+ seed(): Promise<void>;
19
+ close(): Promise<void>;
20
+ }
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Seeder = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const promises_1 = __importDefault(require("node:fs/promises"));
9
+ const common_1 = require("@appweaver/common");
10
+ const lifecycle_manager_1 = require("../app/lifecycle-manager");
11
+ const context_1 = require("../context");
12
+ /**
13
+ * Represents a seeder class that manages the application seeders processes.
14
+ */
15
+ class Seeder extends lifecycle_manager_1.LifecycleManager {
16
+ _dirPath;
17
+ _continueOnError;
18
+ _fixWarnings;
19
+ /** @internal */
20
+ _db = (0, context_1.inject)(common_1.Database);
21
+ constructor(_dirPath, _continueOnError = false, _fixWarnings = false) {
22
+ super();
23
+ this._dirPath = _dirPath;
24
+ this._continueOnError = _continueOnError;
25
+ this._fixWarnings = _fixWarnings;
26
+ }
27
+ /**
28
+ * Executes the seeders by discovering, validating, and running seeder files.
29
+ * Logs the seeding process, including warnings for checksum mismatches
30
+ * and files that do not exist but are present in database table.
31
+ *
32
+ * @return Resolves when all seeders have been processed. Logs relevant
33
+ * information during execution.
34
+ */
35
+ async seed() {
36
+ await this.init();
37
+ let seederFiles = [];
38
+ try {
39
+ seederFiles = await this.loadSeederFiles();
40
+ }
41
+ catch (error) {
42
+ console.error(`Seeders directory ${this._dirPath} is not accessible`);
43
+ return;
44
+ }
45
+ let calledSeedersCount = 0;
46
+ const relativePath = this._dirPath
47
+ .replace(process.cwd(), '.')
48
+ .replace(/\\/g, '/');
49
+ console.log(`${seederFiles.length} seeder${seederFiles.length === 1 ? '' : 's'} found in ${relativePath}`);
50
+ console.log('');
51
+ // For each seeder file, skip if it has already been seeded, otherwise
52
+ // execute all of it's exported functions and write results to a database
53
+ for (const seederFile of seederFiles) {
54
+ const seederName = this.seederName(seederFile);
55
+ const seeder = await this.getSeeder(seederFile);
56
+ if (seeder) {
57
+ const checksum = await this.seederHash(seederFile);
58
+ if (checksum !== seeder.checksum) {
59
+ console.warn(`Warning: seeder ${seederName} has different checksum: ${checksum}, expected checksum: ${seeder.checksum}`);
60
+ if (this._fixWarnings) {
61
+ await this._db.client().seeder.update({
62
+ where: { id: seeder.id },
63
+ data: { checksum }
64
+ });
65
+ console.log('Fix: seeder checksum updated');
66
+ }
67
+ console.log('');
68
+ }
69
+ continue;
70
+ }
71
+ console.log(`Seeding ${seederName}...`);
72
+ await this.executeSeeder(seederFile);
73
+ console.log(`${seederName} seeded`);
74
+ console.log('');
75
+ calledSeedersCount++;
76
+ }
77
+ const seedersWithoutFiles = await this.findSeedersWithoutFiles(seederFiles);
78
+ for (const seeder of seedersWithoutFiles) {
79
+ console.warn(`Warning: seeder ${seeder.seederName} does not exist but is present in database table`);
80
+ if (this._fixWarnings) {
81
+ await this._db.client().seeder.delete({ where: { id: seeder.id } });
82
+ console.log('Fix: removed seeder from database');
83
+ }
84
+ console.log('');
85
+ }
86
+ if (calledSeedersCount === 0) {
87
+ console.log(`No pending seeders to execute`);
88
+ }
89
+ else {
90
+ console.log(`Executed ${calledSeedersCount} seeder${calledSeedersCount === 1 ? '' : 's'}`);
91
+ }
92
+ }
93
+ async close() {
94
+ await this.destroy();
95
+ }
96
+ /** @internal */
97
+ async loadSeederFiles() {
98
+ const entries = await promises_1.default.readdir(this._dirPath, { withFileTypes: true });
99
+ return entries
100
+ .filter((e) => e.isFile() && /\.(js|ts)$/.test(e.name) && !e.name.endsWith('.d.ts'))
101
+ .map((e) => e.name)
102
+ .sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }))
103
+ .map((name) => node_path_1.default.join(this._dirPath, name));
104
+ }
105
+ /** @internal */
106
+ async executeSeeder(seederFile) {
107
+ const start = new Date();
108
+ const { value, error } = await (0, common_1.importModule)(seederFile);
109
+ if (error) {
110
+ if (this._continueOnError) {
111
+ console.error(error);
112
+ return;
113
+ }
114
+ throw error;
115
+ }
116
+ const logs = [];
117
+ // Execute all exported functions from a seeder file and log errors or
118
+ // function responses
119
+ for (const seederFn of Object.values(value)) {
120
+ if ((0, common_1.isFunction)(seederFn)) {
121
+ try {
122
+ const result = await seederFn();
123
+ if (result) {
124
+ logs.push(JSON.stringify(result));
125
+ }
126
+ }
127
+ catch (e) {
128
+ if (!this._continueOnError) {
129
+ throw e;
130
+ }
131
+ console.error(e);
132
+ logs.push(`Error: ${e.message}`);
133
+ }
134
+ }
135
+ }
136
+ const seederHash = await this.seederHash(seederFile);
137
+ // Insert seeder result into the database
138
+ await this._db.client().seeder.create({
139
+ data: {
140
+ checksum: seederHash,
141
+ seederName: this.seederName(seederFile),
142
+ startedAt: start,
143
+ finishedAt: new Date(),
144
+ logs: logs.length > 0 ? logs.join('\n') : null
145
+ }
146
+ });
147
+ }
148
+ /** @internal */
149
+ async findSeedersWithoutFiles(seederFiles) {
150
+ const seederNames = seederFiles.map((file) => this.seederName(file));
151
+ return this._db.client().seeder.findMany({
152
+ where: {
153
+ seederName: { notIn: seederNames }
154
+ }
155
+ });
156
+ }
157
+ /** @internal */
158
+ async getSeeder(seederFile) {
159
+ const seederName = this.seederName(seederFile);
160
+ return this._db.client().seeder.findFirst({ where: { seederName } });
161
+ }
162
+ /** @internal */
163
+ async seederHash(seederFile) {
164
+ const seederContent = await promises_1.default.readFile(seederFile, 'utf8');
165
+ return (0, common_1.makeHash)(seederContent);
166
+ }
167
+ /** @internal */
168
+ seederName(seederFile) {
169
+ if (seederFile.endsWith('.ts')) {
170
+ return node_path_1.default.basename(seederFile, '.ts');
171
+ }
172
+ return node_path_1.default.basename(seederFile, '.js');
173
+ }
174
+ }
175
+ exports.Seeder = Seeder;
@@ -0,0 +1,20 @@
1
+ import { Server } from '../types';
2
+ /**
3
+ * Creates and configures a new server instance.
4
+ *
5
+ * This function initializes a Fastify server with various plugins and configurations,
6
+ * including CORS, security rules (e.g., Helmet), multipart file uploads, rate limiting,
7
+ * static file serving, authentication, and Swagger documentation (if enabled).
8
+ * It also sets a global error handler for all routes.
9
+ *
10
+ * Additionally, this function:
11
+ * - Loads and registers all user-defined plugins
12
+ * - Registers schema models for route validation with $ref support
13
+ * - Sets up a global error handler for all routes
14
+ * - Registers built-in routes (health check, info, files)
15
+ * - Loads and registers resource API routes generated from the resource context
16
+ * - Loads and registers user-defined custom routes
17
+ *
18
+ * @return {Server} A configured Fastify server instance with TypeBox type provider.
19
+ */
20
+ export declare function createServer(): Server;
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createServer = createServer;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const fastify_1 = __importDefault(require("fastify"));
9
+ const cors_1 = __importDefault(require("@fastify/cors"));
10
+ const helmet_1 = __importDefault(require("@fastify/helmet"));
11
+ const static_1 = __importDefault(require("@fastify/static"));
12
+ const rate_limit_1 = __importDefault(require("@fastify/rate-limit"));
13
+ const multipart_1 = __importDefault(require("@fastify/multipart"));
14
+ const request_context_1 = require("@fastify/request-context");
15
+ const common_1 = require("@appweaver/common");
16
+ const context_1 = require("../context");
17
+ const errors_1 = require("../errors");
18
+ const storage_1 = require("../storage");
19
+ const health_1 = require("../health");
20
+ const auth_1 = __importDefault(require("../security/auth"));
21
+ const caching_1 = __importDefault(require("../cache/caching"));
22
+ const info_route_1 = require("./info-route");
23
+ const schemas_1 = __importDefault(require("./schemas"));
24
+ const swagger_1 = __importDefault(require("./swagger"));
25
+ /**
26
+ * Creates and configures a new server instance.
27
+ *
28
+ * This function initializes a Fastify server with various plugins and configurations,
29
+ * including CORS, security rules (e.g., Helmet), multipart file uploads, rate limiting,
30
+ * static file serving, authentication, and Swagger documentation (if enabled).
31
+ * It also sets a global error handler for all routes.
32
+ *
33
+ * Additionally, this function:
34
+ * - Loads and registers all user-defined plugins
35
+ * - Registers schema models for route validation with $ref support
36
+ * - Sets up a global error handler for all routes
37
+ * - Registers built-in routes (health check, info, files)
38
+ * - Loads and registers resource API routes generated from the resource context
39
+ * - Loads and registers user-defined custom routes
40
+ *
41
+ * @return {Server} A configured Fastify server instance with TypeBox type provider.
42
+ */
43
+ function createServer() {
44
+ // Create a Fastify server instance
45
+ const server = (0, fastify_1.default)({
46
+ ajv: {
47
+ customOptions: {
48
+ removeAdditional: 'all'
49
+ },
50
+ plugins: [(ajv) => ajv.addKeyword('example')]
51
+ },
52
+ routerOptions: {
53
+ maxParamLength: 512,
54
+ caseSensitive: false
55
+ },
56
+ trustProxy: common_1.config.SERVER_TRUST_PROXY,
57
+ bodyLimit: (0, common_1.textToBytes)(common_1.config.SERVER_BODY_MAX_SIZE),
58
+ disableRequestLogging: !common_1.config.SERVER_REQUEST_LOGGING_ENABLED,
59
+ logger: common_1.loggerConfig
60
+ }).withTypeProvider();
61
+ // Register CORS rules
62
+ server.register(cors_1.default, {
63
+ origin: common_1.config.CORS_ORIGIN,
64
+ methods: common_1.config.CORS_METHODS,
65
+ allowedHeaders: common_1.config.CORS_ALLOWED_HEADERS,
66
+ exposedHeaders: common_1.config.CORS_EXPOSED_HEADERS,
67
+ maxAge: common_1.config.CORS_MAX_AGE,
68
+ credentials: common_1.config.CORS_CREDENTIALS
69
+ });
70
+ // Register security rules
71
+ server.register(helmet_1.default, {
72
+ contentSecurityPolicy: {
73
+ directives: {
74
+ ...helmet_1.default.contentSecurityPolicy.getDefaultDirectives(),
75
+ 'connect-src': ['*']
76
+ }
77
+ }
78
+ });
79
+ // Register static public file serving
80
+ if (common_1.config.SERVER_STATIC_ENABLED) {
81
+ server.register(static_1.default, {
82
+ root: node_path_1.default.isAbsolute(common_1.config.SERVER_STATIC_DIR_PATH)
83
+ ? common_1.config.SERVER_STATIC_DIR_PATH
84
+ : node_path_1.default.join(process.cwd(), common_1.config.SERVER_STATIC_DIR_PATH),
85
+ prefix: common_1.config.SERVER_STATIC_ROUTE_PREFIX,
86
+ maxAge: common_1.config.SERVER_STATIC_MAX_AGE,
87
+ prefixAvoidTrailingSlash: true,
88
+ constraints: common_1.config.SERVER_STATIC_ALLOWED_HOST
89
+ ? { host: common_1.config.SERVER_STATIC_ALLOWED_HOST }
90
+ : {}
91
+ });
92
+ }
93
+ // Register multipart file upload plugin
94
+ server.register(multipart_1.default, { throwFileSizeLimit: false });
95
+ // Register global request rate limiter
96
+ if (common_1.config.RATE_LIMIT_ENABLED) {
97
+ server.register(rate_limit_1.default, {
98
+ max: common_1.config.RATE_LIMIT_MAX,
99
+ timeWindow: common_1.config.RATE_LIMIT_WINDOW,
100
+ allowList: common_1.config.RATE_LIMIT_ALLOW_LIST,
101
+ nameSpace: 'rate-limit:',
102
+ redis: common_1.config.RATE_LIMIT_STORE === common_1.MemoryType.Redis
103
+ ? (0, context_1.inject)(common_1.Redis).createClient({
104
+ connectTimeout: 500,
105
+ maxRetriesPerRequest: 1,
106
+ lazyConnect: true
107
+ })
108
+ : null
109
+ });
110
+ }
111
+ // Register request context plugin with default values
112
+ server.register(request_context_1.fastifyRequestContext, {
113
+ defaultStoreValues: {
114
+ authUser: null,
115
+ authType: null,
116
+ authSource: null,
117
+ apiKey: null,
118
+ cached: undefined
119
+ }
120
+ });
121
+ // Register all defined plugins
122
+ const plugins = (0, context_1.injectAll)(common_1.PLUGIN);
123
+ for (const plugin of plugins) {
124
+ server.register(plugin);
125
+ }
126
+ // Set global error handler for all routes
127
+ server.setErrorHandler(errors_1.errorHandler);
128
+ // Register swagger documentation and UI. Must be registered after
129
+ // loadResources and before any route registration
130
+ server.register(swagger_1.default);
131
+ // Register schema models to enable $ref usage in route validation
132
+ server.register(schemas_1.default);
133
+ // Register authentication plugin
134
+ server.register(auth_1.default);
135
+ // Register caching plugin
136
+ if (common_1.config.CACHE_ENABLED) {
137
+ server.register(caching_1.default);
138
+ }
139
+ // Register a health route
140
+ if (common_1.config.HEALTH_CHECK_ENABLED) {
141
+ server.register(health_1.health, { prefix: common_1.config.HEALTH_CHECK_ROUTE_PREFIX });
142
+ }
143
+ // Register files route
144
+ server.register(storage_1.files, { prefix: common_1.config.STORAGE_FILES_ROUTE_PREFIX });
145
+ // Register info route
146
+ server.register(info_route_1.info, { prefix: common_1.config.SERVER_API_PREFIX });
147
+ // Register resource routes
148
+ for (const route of context_1.context.resource.routes.values()) {
149
+ const prefix = [common_1.config.SERVER_API_PREFIX, route.basePath]
150
+ .join('/')
151
+ .replaceAll('//', '/');
152
+ server.register(route.handler, { prefix });
153
+ }
154
+ // Register other defined routes
155
+ const routes = (0, context_1.injectAll)(common_1.ROUTE);
156
+ for (const route of routes) {
157
+ server.register(route, { prefix: common_1.config.SERVER_API_PREFIX + '/' });
158
+ }
159
+ return server;
160
+ }
@@ -0,0 +1,4 @@
1
+ export * from './create-server';
2
+ export * from './register-model';
3
+ export * from './register-plugin';
4
+ export * from './register-route';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./create-server"), exports);
18
+ __exportStar(require("./register-model"), exports);
19
+ __exportStar(require("./register-plugin"), exports);
20
+ __exportStar(require("./register-route"), exports);
@@ -0,0 +1,2 @@
1
+ import { Server } from '../types';
2
+ export declare function info(server: Server): void;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.info = info;
4
+ const common_1 = require("@appweaver/common");
5
+ const info_schema_1 = require("./info-schema");
6
+ function info(server) {
7
+ server.get('/', {
8
+ schema: info_schema_1.infoSchema,
9
+ config: {
10
+ rateLimit: {
11
+ max: 60
12
+ }
13
+ }
14
+ }, () => ({
15
+ name: common_1.config.APP_NAME,
16
+ version: common_1.config.APP_VERSION
17
+ }));
18
+ }
@@ -0,0 +1,37 @@
1
+ export declare const InfoResponse: import("@sinclair/typebox").TObject<{
2
+ name: import("@sinclair/typebox").TString;
3
+ version: import("@sinclair/typebox").TString;
4
+ }>;
5
+ export declare const infoSchema: {
6
+ tags: string[];
7
+ summary: string;
8
+ description: string;
9
+ response: {
10
+ '4xx': {
11
+ description: string;
12
+ content: {
13
+ 'application/json': {
14
+ schema: import("@sinclair/typebox").TObject<{
15
+ errorCode: import("@sinclair/typebox").TInteger;
16
+ message: import("@sinclair/typebox").TString;
17
+ }>;
18
+ };
19
+ };
20
+ };
21
+ '5xx': {
22
+ description: string;
23
+ content: {
24
+ 'application/json': {
25
+ schema: import("@sinclair/typebox").TObject<{
26
+ errorCode: import("@sinclair/typebox").TInteger;
27
+ message: import("@sinclair/typebox").TString;
28
+ }>;
29
+ };
30
+ };
31
+ };
32
+ 200: import("@sinclair/typebox").TObject<{
33
+ name: import("@sinclair/typebox").TString;
34
+ version: import("@sinclair/typebox").TString;
35
+ }>;
36
+ };
37
+ };