@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,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemory = void 0;
4
+ const promises_1 = require("node:timers/promises");
5
+ const flatted_1 = require("flatted");
6
+ const common_1 = require("@appweaver/common");
7
+ class InMemory extends common_1.Memory {
8
+ /** @internal */
9
+ _storage = new Map();
10
+ /** @internal */
11
+ _locks = new Map();
12
+ /** @internal */
13
+ _maxSizeBytes = (0, common_1.textToBytes)(common_1.config.MEMORY_MAX_SIZE);
14
+ /** @internal */
15
+ _approximatedSize = 0;
16
+ async onInit() {
17
+ await this.connect();
18
+ }
19
+ async onDestroy() {
20
+ await this.disconnect();
21
+ }
22
+ async connect() {
23
+ // no-op
24
+ }
25
+ async disconnect() {
26
+ // no-op
27
+ }
28
+ createClient() {
29
+ // no-op
30
+ }
31
+ async getValue(key) {
32
+ const entry = this._storage.get(key);
33
+ if (!entry) {
34
+ return null;
35
+ }
36
+ // Check if expired
37
+ if (entry.expiresAt && entry.expiresAt < Date.now()) {
38
+ await this.cleanupExpired();
39
+ return null;
40
+ }
41
+ return (0, flatted_1.parse)(entry.value);
42
+ }
43
+ async putValue(key, value, expireMs) {
44
+ await this.cleanupExpired();
45
+ const jsonValue = (0, flatted_1.stringify)(value);
46
+ const expiresAt = expireMs ? Date.now() + expireMs : undefined;
47
+ this._storage.set(key, {
48
+ value: jsonValue,
49
+ expiresAt
50
+ });
51
+ this._approximatedSize += Buffer.byteLength(jsonValue, 'utf8');
52
+ // If memory max size is reached, remove entries from start until the size
53
+ // is below the configured value
54
+ if (this._maxSizeBytes) {
55
+ while (this._approximatedSize > this._maxSizeBytes) {
56
+ await this.removeValue(this._storage.keys()[0]);
57
+ }
58
+ }
59
+ return true;
60
+ }
61
+ async hasKey(key) {
62
+ return this._storage.has(key);
63
+ }
64
+ async removeValue(key) {
65
+ const jsonValue = await this.getValue(key);
66
+ if (!jsonValue) {
67
+ return false;
68
+ }
69
+ const deleted = this._storage.delete(key);
70
+ this._approximatedSize -= Buffer.byteLength(jsonValue, 'utf8');
71
+ if (this._approximatedSize < 0) {
72
+ this._approximatedSize = 0;
73
+ }
74
+ return deleted;
75
+ }
76
+ async removeEntries(query) {
77
+ const keys = await this.findKeys(query);
78
+ const removeActions = Array.from(keys).map((key) => this.removeValue(key));
79
+ const results = await Promise.allSettled(removeActions);
80
+ return results.filter((r) => r.status === 'fulfilled' && r.value).length;
81
+ }
82
+ async findKeys(pattern = '*') {
83
+ const matchingKeys = new Set();
84
+ // Convert glob pattern to regex
85
+ const regexPattern = pattern
86
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
87
+ .replace(/\*/g, '.*')
88
+ .replace(/\?/g, '.');
89
+ const regex = new RegExp(`^${regexPattern}$`);
90
+ for (const key of this._storage.keys()) {
91
+ const entry = this._storage.get(key);
92
+ if (entry && entry.expiresAt && entry.expiresAt < Date.now()) {
93
+ this._storage.delete(key);
94
+ continue;
95
+ }
96
+ if (regex.test(key)) {
97
+ matchingKeys.add(key);
98
+ }
99
+ }
100
+ return matchingKeys;
101
+ }
102
+ async valueSizeBytes(key) {
103
+ const entry = this._storage.get(key);
104
+ return entry ? Buffer.byteLength(entry.value, 'utf8') : null;
105
+ }
106
+ async lock(resource, lockConfig = {}) {
107
+ const expireMs = lockConfig.expireMs ?? 5000;
108
+ const retryCount = lockConfig.retryCount ?? 10;
109
+ const retryDelay = lockConfig.retryDelay ?? 200;
110
+ const resourceKey = `lock:${resource}`;
111
+ const lockValue = (0, common_1.uuid)();
112
+ let retries = 0;
113
+ do {
114
+ // Try to acquire lock (NX semantics - only set if not exists)
115
+ const existingLock = this._locks.get(resourceKey);
116
+ // Check if the existing lock is expired
117
+ if (existingLock && existingLock.expiresAt < Date.now()) {
118
+ this._locks.delete(resourceKey);
119
+ }
120
+ // Try to acquire
121
+ if (!this._locks.has(resourceKey)) {
122
+ this._locks.set(resourceKey, {
123
+ value: lockValue,
124
+ expiresAt: Date.now() + expireMs
125
+ });
126
+ return {
127
+ release: async () => {
128
+ // Only release if the lock value matches
129
+ const currentLock = this._locks.get(resourceKey);
130
+ if (currentLock && currentLock.value === lockValue) {
131
+ this._locks.delete(resourceKey);
132
+ return true;
133
+ }
134
+ return false;
135
+ }
136
+ };
137
+ }
138
+ await (0, promises_1.setTimeout)(retryDelay);
139
+ retries++;
140
+ } while (retries < retryCount);
141
+ throw new Error('Unable to acquire lock on requested resource');
142
+ }
143
+ async checkHealth() {
144
+ return { success: true };
145
+ }
146
+ async cleanupExpired() {
147
+ const now = Date.now();
148
+ // Clean up expired storage entries
149
+ for (const key in this._storage.keys()) {
150
+ const entry = this._storage.get(key);
151
+ if (entry && entry.expiresAt && entry.expiresAt < now) {
152
+ await this.removeValue(key);
153
+ }
154
+ }
155
+ // Clean up expired locks
156
+ for (const key in this._locks.keys()) {
157
+ const lock = this._locks.get(key);
158
+ if (lock && lock.expiresAt < now) {
159
+ this._locks.delete(key);
160
+ }
161
+ }
162
+ }
163
+ }
164
+ exports.InMemory = InMemory;
@@ -0,0 +1,26 @@
1
+ import { Redis as RedisClient, RedisOptions } from 'ioredis';
2
+ import { HealthCheckResult, Redis as CommonRedis } from '@appweaver/common';
3
+ export declare class Redis extends CommonRedis<RedisOptions, RedisClient> {
4
+ constructor();
5
+ onInit(): Promise<void>;
6
+ onDestroy(): Promise<void>;
7
+ createClient(options?: RedisOptions): RedisClient;
8
+ connect(): Promise<void>;
9
+ disconnect(): Promise<void>;
10
+ getValue<T = any>(key: string): Promise<T | null>;
11
+ putValue(key: string, value: any, expireMs?: number): Promise<boolean>;
12
+ hasKey(key: string): Promise<boolean>;
13
+ removeValue(key: string): Promise<boolean>;
14
+ removeEntries(query: string): Promise<number>;
15
+ findKeys(pattern?: string): Promise<Set<string>>;
16
+ valueSizeBytes(key: string): Promise<number | null>;
17
+ lock(resource: string, lockConfig?: {
18
+ expireMs?: number;
19
+ retryCount?: number;
20
+ retryDelay?: number;
21
+ }): Promise<{
22
+ release: () => Promise<boolean>;
23
+ }>;
24
+ checkHealth(): Promise<HealthCheckResult>;
25
+ private parseConnectionUrl;
26
+ }
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Redis = void 0;
4
+ const promises_1 = require("node:timers/promises");
5
+ const ioredis_1 = require("ioredis");
6
+ const flatted_1 = require("flatted");
7
+ const common_1 = require("@appweaver/common");
8
+ class Redis extends common_1.Redis {
9
+ /** @internal */
10
+ _options;
11
+ /** @internal */
12
+ _client;
13
+ constructor() {
14
+ super();
15
+ this._options = this.parseConnectionUrl(common_1.config.REDIS_URL);
16
+ this._client = this.createClient({ lazyConnect: true });
17
+ }
18
+ async onInit() {
19
+ await this.connect();
20
+ }
21
+ async onDestroy() {
22
+ await this.disconnect();
23
+ }
24
+ createClient(options = {}) {
25
+ return new ioredis_1.Redis({
26
+ ...this._options,
27
+ ...options
28
+ });
29
+ }
30
+ async connect() {
31
+ await this._client.connect();
32
+ }
33
+ async disconnect() {
34
+ try {
35
+ await this._client.quit();
36
+ }
37
+ catch {
38
+ // Ignore already closed connection error
39
+ }
40
+ }
41
+ async getValue(key) {
42
+ const value = await this._client.get(key);
43
+ return value ? (0, flatted_1.parse)(value) : null;
44
+ }
45
+ async putValue(key, value, expireMs) {
46
+ const jsonValue = (0, flatted_1.stringify)(value);
47
+ const result = expireMs
48
+ ? await this._client.set(key, jsonValue, 'PX', expireMs)
49
+ : await this._client.set(key, jsonValue);
50
+ return result === 'OK';
51
+ }
52
+ async hasKey(key) {
53
+ const result = await this._client.exists(key);
54
+ return result === 1;
55
+ }
56
+ async removeValue(key) {
57
+ const result = await this._client.del(key);
58
+ return result > 0;
59
+ }
60
+ async removeEntries(query) {
61
+ const keys = await this.findKeys(query);
62
+ if (keys.size === 0) {
63
+ return 0;
64
+ }
65
+ return this._client.del(...keys);
66
+ }
67
+ async findKeys(pattern = '*') {
68
+ return new Promise((resolve) => {
69
+ const stream = this._client.scanStream({
70
+ match: pattern,
71
+ count: 10000
72
+ });
73
+ const keysSet = new Set();
74
+ stream.on('data', (keys) => {
75
+ stream.pause();
76
+ keys.forEach((key) => keysSet.add(key));
77
+ stream.resume();
78
+ });
79
+ stream.on('end', () => {
80
+ resolve(keysSet);
81
+ });
82
+ });
83
+ }
84
+ async valueSizeBytes(key) {
85
+ return this._client.memory('USAGE', key);
86
+ }
87
+ async lock(resource, lockConfig = {}) {
88
+ const redisLock = new RedisLock(this._client, resource, lockConfig.expireMs, lockConfig.retryCount, lockConfig.retryDelay);
89
+ return await redisLock.lock();
90
+ }
91
+ async checkHealth() {
92
+ try {
93
+ const result = await this._client.ping();
94
+ return { success: result === 'PONG' };
95
+ }
96
+ catch (e) {
97
+ return { success: false, message: e.message };
98
+ }
99
+ }
100
+ parseConnectionUrl(url) {
101
+ const urlPattern = /redis:\/\/(?:(.*?)(?::(.*?))?@)?(.*?):(\d+)(?:\/(\d+))?/;
102
+ const match = url.match(urlPattern);
103
+ if (!match) {
104
+ return { host: 'localhost', port: 6379 };
105
+ }
106
+ const username = match[2] ? match[1] : undefined;
107
+ const password = match[2] || match[1];
108
+ const host = match[3] || 'localhost';
109
+ const port = parseInt(match[4], 10) || 6379;
110
+ const db = match[5] ? parseInt(match[5], 10) : undefined;
111
+ return { username, password, host, port, db };
112
+ }
113
+ }
114
+ exports.Redis = Redis;
115
+ class RedisLock {
116
+ client;
117
+ resource;
118
+ expireMs;
119
+ retryCount;
120
+ retryDelay;
121
+ /** @internal */
122
+ _releaseLockCommand = 'releaseLock';
123
+ constructor(client, resource, expireMs = 5000, retryCount = 10, retryDelay = 200) {
124
+ this.client = client;
125
+ this.resource = resource;
126
+ this.expireMs = expireMs;
127
+ this.retryCount = retryCount;
128
+ this.retryDelay = retryDelay;
129
+ this.initReleaseLockScript();
130
+ }
131
+ async lock() {
132
+ const resourceKey = `lock:${this.resource}`;
133
+ const lockValue = (0, common_1.uuid)();
134
+ let retries = 0;
135
+ do {
136
+ const result = await this.client.set(resourceKey, lockValue, 'PX', this.expireMs, 'NX');
137
+ if (result === 'OK') {
138
+ return {
139
+ release: async () => (await this.client[this._releaseLockCommand](resourceKey, lockValue)) > 0
140
+ };
141
+ }
142
+ else {
143
+ await (0, promises_1.setTimeout)(this.retryDelay);
144
+ retries++;
145
+ }
146
+ } while (retries < this.retryCount);
147
+ throw new Error('Unable to acquire lock on requested resource');
148
+ }
149
+ initReleaseLockScript() {
150
+ if (this._releaseLockCommand in this.client) {
151
+ return;
152
+ }
153
+ this.client.defineCommand(this._releaseLockCommand, {
154
+ numberOfKeys: 1,
155
+ lua: 'if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end'
156
+ });
157
+ }
158
+ }
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@appweaver/core",
3
+ "version": "1.0.0",
4
+ "description": "Appweaver - simple, fast, and reliable web application builder tool (@core)",
5
+ "author": "Luka Matosevic",
6
+ "license": "UNLICENSED",
7
+ "main": "./index.js",
8
+ "types": "./index.d.ts",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/lmatosevic/appweaver.git",
12
+ "directory": "packages/core"
13
+ },
14
+ "maintainers": [
15
+ {
16
+ "name": "Luka Matosevic",
17
+ "email": "lukamatosevic5@gmail.com",
18
+ "web": "https://lukamatosevic.com"
19
+ }
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "engines": {
25
+ "node": ">= 20"
26
+ },
27
+ "scripts": {
28
+ "generate": "weaver generate --modelPattern ./**/model.ts --typesPath ./types/generated.ts --schemaPath ./prisma/schema.prisma --clientPath ./prisma/client",
29
+ "db:recreate": "rimraf dev.db && rimraf prisma/migrations --glob \"*_init\" && weaver migration new init"
30
+ },
31
+ "dependencies": {
32
+ "@fastify/auth": "5.0.4",
33
+ "@fastify/basic-auth": "6.2.0",
34
+ "@fastify/cors": "11.2.0",
35
+ "@fastify/helmet": "13.0.2",
36
+ "@fastify/jwt": "10.0.0",
37
+ "@fastify/multipart": "9.4.0",
38
+ "@fastify/oauth2": "8.2.0",
39
+ "@fastify/rate-limit": "10.3.0",
40
+ "@fastify/request-context": "6.2.1",
41
+ "@fastify/static": "9.1.3",
42
+ "@fastify/swagger": "9.6.1",
43
+ "@fastify/swagger-ui": "5.2.4",
44
+ "@fastify/type-provider-typebox": "6.1.0",
45
+ "@sinclair/typebox": "0.34.47",
46
+ "bcrypt": "6.0.0",
47
+ "csv-stringify": "6.6.0",
48
+ "date-fns": "4.1.0",
49
+ "fastify": "5.8.5",
50
+ "fastify-plugin": "5.1.0",
51
+ "flatted": "3.4.2"
52
+ },
53
+ "devDependencies": {
54
+ "@appweaver/common": "^1.0.0",
55
+ "@prisma/adapter-better-sqlite3": "^7.3.0",
56
+ "@prisma/client": "^7.3.0",
57
+ "bullmq": "^5.70.0",
58
+ "cron": "^4.4.0",
59
+ "ioredis": "^5.9.0",
60
+ "nodemailer": "^8.0.0",
61
+ "prisma": "^7.3.0",
62
+ "rimraf": "6.1.2"
63
+ },
64
+ "peerDependencies": {
65
+ "@appweaver/common": "^1.0.0",
66
+ "@prisma/client": "^7.3.0"
67
+ }
68
+ }
@@ -0,0 +1,34 @@
1
+ import * as Prisma from './internal/prismaNamespaceBrowser';
2
+ export { Prisma };
3
+ export * as $Enums from './enums';
4
+ export * from './enums';
5
+ /**
6
+ * Model ApiKey
7
+ *
8
+ */
9
+ export type ApiKey = Prisma.ApiKeyModel;
10
+ /**
11
+ * Model OneTimeToken
12
+ *
13
+ */
14
+ export type OneTimeToken = Prisma.OneTimeTokenModel;
15
+ /**
16
+ * Model Permission
17
+ *
18
+ */
19
+ export type Permission = Prisma.PermissionModel;
20
+ /**
21
+ * Model Role
22
+ *
23
+ */
24
+ export type Role = Prisma.RoleModel;
25
+ /**
26
+ * Model Seeder
27
+ *
28
+ */
29
+ export type Seeder = Prisma.SeederModel;
30
+ /**
31
+ * Model File
32
+ *
33
+ */
34
+ export type File = Prisma.FileModel;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /* !!! This is code generated by Prisma. Do not edit directly. !!! */
3
+ /* eslint-disable */
4
+ // biome-ignore-all lint: generated file
5
+ // @ts-nocheck
6
+ /*
7
+ * This file should be your main import to use Prisma-related types and utilities in a browser.
8
+ * Use it to get access to models, enums, and input types.
9
+ *
10
+ * This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
11
+ * See `client.ts` for the standard, server-side entry point.
12
+ *
13
+ * 🟢 You can import this file directly.
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
49
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
50
+ };
51
+ Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.$Enums = exports.Prisma = void 0;
53
+ const Prisma = __importStar(require("./internal/prismaNamespaceBrowser"));
54
+ exports.Prisma = Prisma;
55
+ exports.$Enums = __importStar(require("./enums"));
56
+ __exportStar(require("./enums"), exports);
@@ -0,0 +1,53 @@
1
+ import * as runtime from "@prisma/client/runtime/client";
2
+ import * as $Class from "./internal/class";
3
+ import * as Prisma from "./internal/prismaNamespace";
4
+ export * as $Enums from './enums';
5
+ export * from "./enums";
6
+ /**
7
+ * ## Prisma Client
8
+ *
9
+ * Type-safe database client for TypeScript
10
+ * @example
11
+ * ```
12
+ * const prisma = new PrismaClient({
13
+ * adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
14
+ * })
15
+ * // Fetch zero or more ApiKeys
16
+ * const apiKeys = await prisma.apiKey.findMany()
17
+ * ```
18
+ *
19
+ * Read more in our [docs](https://pris.ly/d/client).
20
+ */
21
+ export declare const PrismaClient: $Class.PrismaClientConstructor;
22
+ export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>;
23
+ export { Prisma };
24
+ /**
25
+ * Model ApiKey
26
+ *
27
+ */
28
+ export type ApiKey = Prisma.ApiKeyModel;
29
+ /**
30
+ * Model OneTimeToken
31
+ *
32
+ */
33
+ export type OneTimeToken = Prisma.OneTimeTokenModel;
34
+ /**
35
+ * Model Permission
36
+ *
37
+ */
38
+ export type Permission = Prisma.PermissionModel;
39
+ /**
40
+ * Model Role
41
+ *
42
+ */
43
+ export type Role = Prisma.RoleModel;
44
+ /**
45
+ * Model Seeder
46
+ *
47
+ */
48
+ export type Seeder = Prisma.SeederModel;
49
+ /**
50
+ * Model File
51
+ *
52
+ */
53
+ export type File = Prisma.FileModel;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /* !!! This is code generated by Prisma. Do not edit directly. !!! */
3
+ /* eslint-disable */
4
+ // biome-ignore-all lint: generated file
5
+ // @ts-nocheck
6
+ /*
7
+ * This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
8
+ * If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
9
+ *
10
+ * 🟢 You can import this file directly.
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
46
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
47
+ };
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.Prisma = exports.PrismaClient = exports.$Enums = void 0;
50
+ const $Class = __importStar(require("./internal/class"));
51
+ const Prisma = __importStar(require("./internal/prismaNamespace"));
52
+ exports.Prisma = Prisma;
53
+ exports.$Enums = __importStar(require("./enums"));
54
+ __exportStar(require("./enums"), exports);
55
+ /**
56
+ * ## Prisma Client
57
+ *
58
+ * Type-safe database client for TypeScript
59
+ * @example
60
+ * ```
61
+ * const prisma = new PrismaClient({
62
+ * adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
63
+ * })
64
+ * // Fetch zero or more ApiKeys
65
+ * const apiKeys = await prisma.apiKey.findMany()
66
+ * ```
67
+ *
68
+ * Read more in our [docs](https://pris.ly/d/client).
69
+ */
70
+ exports.PrismaClient = $Class.getPrismaClientClass();