@cogenta/core 0.1.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 (193) hide show
  1. package/dist/cache/entry.d.ts +32 -0
  2. package/dist/cache/entry.d.ts.map +1 -0
  3. package/dist/cache/entry.js +72 -0
  4. package/dist/cache/entry.js.map +1 -0
  5. package/dist/cache/file.d.ts +16 -0
  6. package/dist/cache/file.d.ts.map +1 -0
  7. package/dist/cache/file.js +191 -0
  8. package/dist/cache/file.js.map +1 -0
  9. package/dist/cache/index.d.ts +20 -0
  10. package/dist/cache/index.d.ts.map +1 -0
  11. package/dist/cache/index.js +25 -0
  12. package/dist/cache/index.js.map +1 -0
  13. package/dist/cache/memory.d.ts +11 -0
  14. package/dist/cache/memory.d.ts.map +1 -0
  15. package/dist/cache/memory.js +89 -0
  16. package/dist/cache/memory.js.map +1 -0
  17. package/dist/cache/redis.d.ts +54 -0
  18. package/dist/cache/redis.d.ts.map +1 -0
  19. package/dist/cache/redis.js +167 -0
  20. package/dist/cache/redis.js.map +1 -0
  21. package/dist/cache/types.d.ts +37 -0
  22. package/dist/cache/types.d.ts.map +1 -0
  23. package/dist/cache/types.js +2 -0
  24. package/dist/cache/types.js.map +1 -0
  25. package/dist/config/define-config.d.ts +19 -0
  26. package/dist/config/define-config.d.ts.map +1 -0
  27. package/dist/config/define-config.js +20 -0
  28. package/dist/config/define-config.js.map +1 -0
  29. package/dist/config/env.d.ts +30 -0
  30. package/dist/config/env.d.ts.map +1 -0
  31. package/dist/config/env.js +139 -0
  32. package/dist/config/env.js.map +1 -0
  33. package/dist/config/index.d.ts +7 -0
  34. package/dist/config/index.d.ts.map +1 -0
  35. package/dist/config/index.js +5 -0
  36. package/dist/config/index.js.map +1 -0
  37. package/dist/config/load-config.d.ts +30 -0
  38. package/dist/config/load-config.d.ts.map +1 -0
  39. package/dist/config/load-config.js +83 -0
  40. package/dist/config/load-config.js.map +1 -0
  41. package/dist/config/resolve-config.d.ts +14 -0
  42. package/dist/config/resolve-config.d.ts.map +1 -0
  43. package/dist/config/resolve-config.js +146 -0
  44. package/dist/config/resolve-config.js.map +1 -0
  45. package/dist/config/schema.d.ts +68 -0
  46. package/dist/config/schema.d.ts.map +1 -0
  47. package/dist/config/schema.js +75 -0
  48. package/dist/config/schema.js.map +1 -0
  49. package/dist/config/types.d.ts +126 -0
  50. package/dist/config/types.d.ts.map +1 -0
  51. package/dist/config/types.js +6 -0
  52. package/dist/config/types.js.map +1 -0
  53. package/dist/db/dialect.d.ts +64 -0
  54. package/dist/db/dialect.d.ts.map +1 -0
  55. package/dist/db/dialect.js +147 -0
  56. package/dist/db/dialect.js.map +1 -0
  57. package/dist/db/drizzle.d.ts +35 -0
  58. package/dist/db/drizzle.d.ts.map +1 -0
  59. package/dist/db/drizzle.js +128 -0
  60. package/dist/db/drizzle.js.map +1 -0
  61. package/dist/db/index.d.ts +28 -0
  62. package/dist/db/index.d.ts.map +1 -0
  63. package/dist/db/index.js +30 -0
  64. package/dist/db/index.js.map +1 -0
  65. package/dist/db/mysql.d.ts +39 -0
  66. package/dist/db/mysql.d.ts.map +1 -0
  67. package/dist/db/mysql.js +224 -0
  68. package/dist/db/mysql.js.map +1 -0
  69. package/dist/db/postgres.d.ts +47 -0
  70. package/dist/db/postgres.d.ts.map +1 -0
  71. package/dist/db/postgres.js +174 -0
  72. package/dist/db/postgres.js.map +1 -0
  73. package/dist/db/sqlite.d.ts +41 -0
  74. package/dist/db/sqlite.d.ts.map +1 -0
  75. package/dist/db/sqlite.js +213 -0
  76. package/dist/db/sqlite.js.map +1 -0
  77. package/dist/db/types.d.ts +71 -0
  78. package/dist/db/types.d.ts.map +1 -0
  79. package/dist/db/types.js +2 -0
  80. package/dist/db/types.js.map +1 -0
  81. package/dist/drivers/index.d.ts +5 -0
  82. package/dist/drivers/index.d.ts.map +1 -0
  83. package/dist/drivers/index.js +3 -0
  84. package/dist/drivers/index.js.map +1 -0
  85. package/dist/drivers/registry.d.ts +27 -0
  86. package/dist/drivers/registry.d.ts.map +1 -0
  87. package/dist/drivers/registry.js +162 -0
  88. package/dist/drivers/registry.js.map +1 -0
  89. package/dist/drivers/types.d.ts +59 -0
  90. package/dist/drivers/types.d.ts.map +1 -0
  91. package/dist/drivers/types.js +2 -0
  92. package/dist/drivers/types.js.map +1 -0
  93. package/dist/errors/codes.d.ts +8 -0
  94. package/dist/errors/codes.d.ts.map +1 -0
  95. package/dist/errors/codes.js +201 -0
  96. package/dist/errors/codes.js.map +1 -0
  97. package/dist/errors/cogenta-error.d.ts +38 -0
  98. package/dist/errors/cogenta-error.d.ts.map +1 -0
  99. package/dist/errors/cogenta-error.js +31 -0
  100. package/dist/errors/cogenta-error.js.map +1 -0
  101. package/dist/errors/index.d.ts +5 -0
  102. package/dist/errors/index.d.ts.map +1 -0
  103. package/dist/errors/index.js +3 -0
  104. package/dist/errors/index.js.map +1 -0
  105. package/dist/id.d.ts +5 -0
  106. package/dist/id.d.ts.map +1 -0
  107. package/dist/id.js +82 -0
  108. package/dist/id.js.map +1 -0
  109. package/dist/index.d.ts +12 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +12 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/logger/index.d.ts +5 -0
  114. package/dist/logger/index.d.ts.map +1 -0
  115. package/dist/logger/index.js +4 -0
  116. package/dist/logger/index.js.map +1 -0
  117. package/dist/logger/logger.d.ts +10 -0
  118. package/dist/logger/logger.d.ts.map +1 -0
  119. package/dist/logger/logger.js +108 -0
  120. package/dist/logger/logger.js.map +1 -0
  121. package/dist/logger/redact.d.ts +12 -0
  122. package/dist/logger/redact.d.ts.map +1 -0
  123. package/dist/logger/redact.js +96 -0
  124. package/dist/logger/redact.js.map +1 -0
  125. package/dist/logger/types.d.ts +32 -0
  126. package/dist/logger/types.d.ts.map +1 -0
  127. package/dist/logger/types.js +3 -0
  128. package/dist/logger/types.js.map +1 -0
  129. package/dist/media/format-sniff.d.ts +22 -0
  130. package/dist/media/format-sniff.d.ts.map +1 -0
  131. package/dist/media/format-sniff.js +77 -0
  132. package/dist/media/format-sniff.js.map +1 -0
  133. package/dist/media/index.d.ts +5 -0
  134. package/dist/media/index.d.ts.map +1 -0
  135. package/dist/media/index.js +4 -0
  136. package/dist/media/index.js.map +1 -0
  137. package/dist/media/store.d.ts +13 -0
  138. package/dist/media/store.d.ts.map +1 -0
  139. package/dist/media/store.js +211 -0
  140. package/dist/media/store.js.map +1 -0
  141. package/dist/media/types.d.ts +70 -0
  142. package/dist/media/types.d.ts.map +1 -0
  143. package/dist/media/types.js +2 -0
  144. package/dist/media/types.js.map +1 -0
  145. package/dist/migrations/index.d.ts +4 -0
  146. package/dist/migrations/index.d.ts.map +1 -0
  147. package/dist/migrations/index.js +2 -0
  148. package/dist/migrations/index.js.map +1 -0
  149. package/dist/migrations/migrator.d.ts +18 -0
  150. package/dist/migrations/migrator.d.ts.map +1 -0
  151. package/dist/migrations/migrator.js +247 -0
  152. package/dist/migrations/migrator.js.map +1 -0
  153. package/dist/migrations/types.d.ts +63 -0
  154. package/dist/migrations/types.d.ts.map +1 -0
  155. package/dist/migrations/types.js +2 -0
  156. package/dist/migrations/types.js.map +1 -0
  157. package/dist/queue/bullmq.d.ts +119 -0
  158. package/dist/queue/bullmq.d.ts.map +1 -0
  159. package/dist/queue/bullmq.js +391 -0
  160. package/dist/queue/bullmq.js.map +1 -0
  161. package/dist/queue/database.d.ts +17 -0
  162. package/dist/queue/database.d.ts.map +1 -0
  163. package/dist/queue/database.js +242 -0
  164. package/dist/queue/database.js.map +1 -0
  165. package/dist/queue/index.d.ts +7 -0
  166. package/dist/queue/index.d.ts.map +1 -0
  167. package/dist/queue/index.js +4 -0
  168. package/dist/queue/index.js.map +1 -0
  169. package/dist/queue/types.d.ts +61 -0
  170. package/dist/queue/types.d.ts.map +1 -0
  171. package/dist/queue/types.js +2 -0
  172. package/dist/queue/types.js.map +1 -0
  173. package/dist/storage/index.d.ts +14 -0
  174. package/dist/storage/index.d.ts.map +1 -0
  175. package/dist/storage/index.js +17 -0
  176. package/dist/storage/index.js.map +1 -0
  177. package/dist/storage/key.d.ts +12 -0
  178. package/dist/storage/key.d.ts.map +1 -0
  179. package/dist/storage/key.js +43 -0
  180. package/dist/storage/key.js.map +1 -0
  181. package/dist/storage/local.d.ts +23 -0
  182. package/dist/storage/local.d.ts.map +1 -0
  183. package/dist/storage/local.js +204 -0
  184. package/dist/storage/local.js.map +1 -0
  185. package/dist/storage/s3.d.ts +54 -0
  186. package/dist/storage/s3.d.ts.map +1 -0
  187. package/dist/storage/s3.js +240 -0
  188. package/dist/storage/s3.js.map +1 -0
  189. package/dist/storage/types.d.ts +45 -0
  190. package/dist/storage/types.d.ts.map +1 -0
  191. package/dist/storage/types.js +2 -0
  192. package/dist/storage/types.js.map +1 -0
  193. package/package.json +82 -0
@@ -0,0 +1,240 @@
1
+ import { CogentaError } from '../errors/index.js';
2
+ import { parseKey } from './key.js';
3
+ /**
4
+ * Loads the AWS SDK if the host application installed it.
5
+ *
6
+ * It is an optional peer, and a large one — which is exactly why it must not be
7
+ * a hard dependency. A site on local storage installs none of it.
8
+ */
9
+ export async function loadS3Modules() {
10
+ try {
11
+ const [s3, presigner, upload] = await Promise.all([
12
+ import('@aws-sdk/client-s3'),
13
+ import('@aws-sdk/s3-request-presigner'),
14
+ import('@aws-sdk/lib-storage'),
15
+ ]);
16
+ return { s3, presigner, upload };
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ function isNotFound(error) {
23
+ const status = error.$metadata?.httpStatusCode;
24
+ const name = error.name ?? '';
25
+ return status === 404 || name === 'NotFound' || name === 'NoSuchKey';
26
+ }
27
+ export function createS3Storage(options) {
28
+ const { client, bucket, modules } = options;
29
+ const prefix = options.prefix ?? '';
30
+ const baseUrl = (options.baseUrl ?? '').replace(/\/$/, '');
31
+ const objectKey = (key) => {
32
+ parseKey(key);
33
+ return `${prefix}${key}`;
34
+ };
35
+ return {
36
+ put: async (key, data, putOptions) => {
37
+ const input = {
38
+ Bucket: bucket,
39
+ Key: objectKey(key),
40
+ Body: data,
41
+ ...(putOptions?.contentType === undefined ? {} : { ContentType: putOptions.contentType }),
42
+ ...(putOptions?.cacheControl === undefined
43
+ ? {}
44
+ : { CacheControl: putOptions.cacheControl }),
45
+ };
46
+ try {
47
+ if (Buffer.isBuffer(data)) {
48
+ await client.send(new modules.s3.PutObjectCommand(input));
49
+ }
50
+ else {
51
+ // A stream has no known length, and PutObject requires one. Upload
52
+ // splits it into parts instead, so a large video never has to be
53
+ // buffered in memory to be stored.
54
+ await new modules.upload.Upload({ client, params: input }).done();
55
+ }
56
+ }
57
+ catch (error) {
58
+ throw new CogentaError({
59
+ code: 'STORAGE_FAILED',
60
+ message: `Could not store the media object "${key}".`,
61
+ hint: 'Check the bucket name, the region and the credentials in the environment.',
62
+ cause: error,
63
+ details: { key, bucket },
64
+ });
65
+ }
66
+ },
67
+ get: async (key) => {
68
+ try {
69
+ const result = await client.send(new modules.s3.GetObjectCommand({ Bucket: bucket, Key: objectKey(key) }));
70
+ if (result.Body === undefined)
71
+ throw new Error('the response had no body');
72
+ return result.Body;
73
+ }
74
+ catch (error) {
75
+ throw new CogentaError({
76
+ code: 'STORAGE_FAILED',
77
+ message: `No media object stored under "${key}".`,
78
+ hint: 'Check the key, or upload the object first.',
79
+ cause: error,
80
+ details: { key },
81
+ });
82
+ }
83
+ },
84
+ head: async (key) => {
85
+ try {
86
+ const result = await client.send(new modules.s3.HeadObjectCommand({ Bucket: bucket, Key: objectKey(key) }));
87
+ return {
88
+ key,
89
+ size: result.ContentLength ?? 0,
90
+ contentType: result.ContentType,
91
+ cacheControl: result.CacheControl,
92
+ };
93
+ }
94
+ catch (error) {
95
+ if (isNotFound(error))
96
+ return null;
97
+ throw error;
98
+ }
99
+ },
100
+ delete: async (key) => {
101
+ await client.send(new modules.s3.DeleteObjectCommand({ Bucket: bucket, Key: objectKey(key) }));
102
+ },
103
+ exists: async (key) => {
104
+ // Validated outside the try, so an unsafe key raises rather than being
105
+ // reported as an ordinary miss.
106
+ const resolved = objectKey(key);
107
+ try {
108
+ await client.send(new modules.s3.HeadObjectCommand({ Bucket: bucket, Key: resolved }));
109
+ return true;
110
+ }
111
+ catch (error) {
112
+ if (isNotFound(error))
113
+ return false;
114
+ throw error;
115
+ }
116
+ },
117
+ signedUrl: async (key, expiresIn) => {
118
+ const resolved = objectKey(key);
119
+ if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
120
+ throw new CogentaError({
121
+ code: 'STORAGE_FAILED',
122
+ message: `A signed URL must expire in a positive number of seconds, received ${String(expiresIn)}.`,
123
+ hint: 'Pass the lifetime in seconds, for example 300 for five minutes.',
124
+ });
125
+ }
126
+ return modules.presigner.getSignedUrl(client, new modules.s3.GetObjectCommand({ Bucket: bucket, Key: resolved }), { expiresIn: Math.floor(expiresIn) });
127
+ },
128
+ publicUrl: (key) => {
129
+ const resolved = objectKey(key);
130
+ if (baseUrl === '') {
131
+ throw new CogentaError({
132
+ code: 'STORAGE_FAILED',
133
+ message: 'This bucket has no public URL configured.',
134
+ hint: 'Set storage.baseUrl to the CDN or bucket origin that serves these objects, or use signedUrl() for private media.',
135
+ });
136
+ }
137
+ return `${baseUrl}/${resolved}`;
138
+ },
139
+ };
140
+ }
141
+ export function s3StorageDriver(options = {}) {
142
+ let client;
143
+ let bucket;
144
+ const buildClient = (config, modules) => new modules.s3.S3Client({
145
+ region: config.region ?? 'us-east-1',
146
+ ...(config.endpoint === undefined
147
+ ? {}
148
+ : {
149
+ endpoint: config.endpoint,
150
+ // MinIO, R2 and most self-hosted gateways serve buckets as a path
151
+ // rather than a subdomain. Assuming virtual-host style breaks all
152
+ // of them, and the failure looks like a DNS error.
153
+ forcePathStyle: true,
154
+ }),
155
+ ...(config.accessKeyId === undefined || config.secretAccessKey === undefined
156
+ ? {}
157
+ : {
158
+ credentials: {
159
+ accessKeyId: config.accessKeyId,
160
+ secretAccessKey: config.secretAccessKey,
161
+ },
162
+ }),
163
+ });
164
+ return {
165
+ name: 's3',
166
+ tier: 'optimal',
167
+ available: async (config) => {
168
+ if (config.bucket === undefined)
169
+ return false;
170
+ const modules = await loadS3Modules();
171
+ if (modules === null)
172
+ return false;
173
+ let probe;
174
+ try {
175
+ probe = buildClient(config, modules);
176
+ // A HEAD on a key that does not exist still proves the endpoint answers
177
+ // and the credentials are accepted; only a missing object comes back.
178
+ await probe
179
+ .send(new modules.s3.HeadObjectCommand({
180
+ Bucket: config.bucket,
181
+ Key: '.cogenta-availability-probe',
182
+ }))
183
+ .catch((error) => {
184
+ if (!isNotFound(error))
185
+ throw error;
186
+ });
187
+ return true;
188
+ }
189
+ catch {
190
+ return false;
191
+ }
192
+ finally {
193
+ probe?.destroy();
194
+ }
195
+ },
196
+ init: async (config) => {
197
+ const modules = await loadS3Modules();
198
+ if (modules === null) {
199
+ throw new CogentaError({
200
+ code: 'DRIVER_INIT_FAILED',
201
+ message: 'The S3 storage driver needs the AWS SDK.',
202
+ hint: 'Run `pnpm add @aws-sdk/client-s3 @aws-sdk/s3-request-presigner @aws-sdk/lib-storage`, or leave storage.driver unset to store media on disk.',
203
+ });
204
+ }
205
+ if (config.bucket === undefined) {
206
+ throw new CogentaError({
207
+ code: 'CONFIG_INVALID',
208
+ message: 'The S3 storage driver needs a bucket.',
209
+ hint: 'Set storage.bucket, or the COGENTA_STORAGE_BUCKET environment variable.',
210
+ });
211
+ }
212
+ bucket = config.bucket;
213
+ client ??= buildClient(config, modules);
214
+ return createS3Storage({
215
+ ...options,
216
+ modules,
217
+ client,
218
+ bucket,
219
+ ...(config.baseUrl === undefined ? {} : { baseUrl: config.baseUrl }),
220
+ });
221
+ },
222
+ dispose: async () => {
223
+ client?.destroy();
224
+ client = undefined;
225
+ },
226
+ health: async () => {
227
+ if (client === undefined) {
228
+ return { status: 'down', driver: 's3', tier: 'optimal', message: 'Not connected.' };
229
+ }
230
+ return {
231
+ status: 'ok',
232
+ driver: 's3',
233
+ tier: 'optimal',
234
+ // The bucket is safe to name; the credentials and endpoint are not.
235
+ message: `Media in the "${bucket ?? 'unknown'}" bucket.`,
236
+ };
237
+ },
238
+ };
239
+ }
240
+ //# sourceMappingURL=s3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { Readable } from 'node:stream';
2
+ export interface StoragePutOptions {
3
+ readonly contentType?: string;
4
+ readonly cacheControl?: string;
5
+ }
6
+ export interface StorageObjectInfo {
7
+ readonly key: string;
8
+ readonly size: number;
9
+ readonly contentType: string | undefined;
10
+ readonly cacheControl: string | undefined;
11
+ }
12
+ /**
13
+ * Where media lives.
14
+ *
15
+ * Objects are addressed by key, never by path: a key is opaque text chosen by
16
+ * Cogenta, and every driver is responsible for mapping it somewhere safe.
17
+ */
18
+ export interface StorageDriver {
19
+ put(key: string, data: Buffer | Readable, options?: StoragePutOptions): Promise<void>;
20
+ get(key: string): Promise<Readable>;
21
+ /** Metadata without the body. Needed to serve an object with its content type. */
22
+ head(key: string): Promise<StorageObjectInfo | null>;
23
+ delete(key: string): Promise<void>;
24
+ exists(key: string): Promise<boolean>;
25
+ /** A time-limited URL for a private object. `expiresIn` is in seconds. */
26
+ signedUrl(key: string, expiresIn: number): Promise<string>;
27
+ /** The stable URL of a public object. */
28
+ publicUrl(key: string): string;
29
+ }
30
+ /** The resolved `storage` section of the configuration. */
31
+ export interface StorageConfig {
32
+ readonly driver?: string;
33
+ readonly bucket?: string | undefined;
34
+ readonly region?: string | undefined;
35
+ readonly endpoint?: string | undefined;
36
+ readonly path?: string;
37
+ readonly baseUrl?: string | undefined;
38
+ readonly accessKeyId?: string | undefined;
39
+ readonly secretAccessKey?: string | undefined;
40
+ }
41
+ export interface StorageDriverOptions {
42
+ /** Injected so signed-URL expiry can be tested without waiting. Milliseconds. */
43
+ readonly now?: () => number;
44
+ }
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACnC,kFAAkF;IAClF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IACpD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACrC,0EAA0E;IAC1E,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1D,yCAAyC;IACzC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAC/B;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9C;AAED,MAAM,WAAW,oBAAoB;IACnC,iFAAiF;IACjF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@cogenta/core",
3
+ "version": "0.1.0",
4
+ "description": "Configuration, typed errors, structured logging and the driver system behind Cogenta.",
5
+ "license": "MPL-2.0",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "engines": {
18
+ "node": ">=22.11.0"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public",
22
+ "provenance": true
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/cogenta-cms/cogenta.git",
27
+ "directory": "packages/core"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.json",
31
+ "typecheck": "tsc -p tsconfig.typecheck.json",
32
+ "test": "vitest run --passWithNoTests",
33
+ "test:integration": "vitest run --config vitest.integration.config.ts --passWithNoTests"
34
+ },
35
+ "dependencies": {
36
+ "zod": "catalog:",
37
+ "drizzle-orm": "catalog:"
38
+ },
39
+ "devDependencies": {
40
+ "typescript": "catalog:",
41
+ "vitest": "catalog:",
42
+ "@redis/client": "catalog:",
43
+ "postgres": "catalog:",
44
+ "mysql2": "catalog:",
45
+ "@aws-sdk/client-s3": "catalog:",
46
+ "@aws-sdk/s3-request-presigner": "catalog:",
47
+ "@aws-sdk/lib-storage": "catalog:",
48
+ "bullmq": "catalog:"
49
+ },
50
+ "peerDependencies": {
51
+ "@redis/client": "^6.2.1",
52
+ "postgres": "^3.4.9",
53
+ "mysql2": "^3.23.3",
54
+ "@aws-sdk/client-s3": "^3.1109.0",
55
+ "@aws-sdk/s3-request-presigner": "^3.1109.0",
56
+ "@aws-sdk/lib-storage": "^3.1109.0",
57
+ "bullmq": "^6.1.0"
58
+ },
59
+ "peerDependenciesMeta": {
60
+ "@redis/client": {
61
+ "optional": true
62
+ },
63
+ "postgres": {
64
+ "optional": true
65
+ },
66
+ "mysql2": {
67
+ "optional": true
68
+ },
69
+ "@aws-sdk/client-s3": {
70
+ "optional": true
71
+ },
72
+ "@aws-sdk/s3-request-presigner": {
73
+ "optional": true
74
+ },
75
+ "@aws-sdk/lib-storage": {
76
+ "optional": true
77
+ },
78
+ "bullmq": {
79
+ "optional": true
80
+ }
81
+ }
82
+ }