@zudojs/storage 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +38 -0
  2. package/dist/database/connectionPool.core.d.ts.map +1 -0
  3. package/dist/database/connectionPool.core.js +166 -0
  4. package/dist/database/connectionPool.core.js.map +1 -0
  5. package/dist/database/index.d.ts +5 -0
  6. package/dist/database/index.d.ts.map +1 -0
  7. package/dist/database/index.js +5 -0
  8. package/dist/database/index.js.map +1 -0
  9. package/dist/health/healthChecker.core.d.ts +53 -0
  10. package/dist/health/healthChecker.core.d.ts.map +1 -0
  11. package/dist/health/healthChecker.core.js +84 -0
  12. package/dist/health/healthChecker.core.js.map +1 -0
  13. package/dist/health/index.d.ts +6 -0
  14. package/dist/health/index.d.ts.map +1 -0
  15. package/dist/health/index.js +5 -0
  16. package/dist/health/index.js.map +1 -0
  17. package/dist/index.d.ts +39 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +36 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/lifecycle/index.d.ts +5 -0
  22. package/dist/lifecycle/index.d.ts.map +1 -0
  23. package/dist/lifecycle/index.js +5 -0
  24. package/dist/lifecycle/index.js.map +1 -0
  25. package/dist/lifecycle/storageLifecycle.core.d.ts +26 -0
  26. package/dist/lifecycle/storageLifecycle.core.d.ts.map +1 -0
  27. package/dist/lifecycle/storageLifecycle.core.js +71 -0
  28. package/dist/lifecycle/storageLifecycle.core.js.map +1 -0
  29. package/dist/locking/inMemoryLock.core.d.ts +28 -0
  30. package/dist/locking/inMemoryLock.core.d.ts.map +1 -0
  31. package/dist/locking/inMemoryLock.core.js +120 -0
  32. package/dist/locking/inMemoryLock.core.js.map +1 -0
  33. package/dist/locking/index.d.ts +5 -0
  34. package/dist/locking/index.d.ts.map +1 -0
  35. package/dist/locking/index.js +5 -0
  36. package/dist/locking/index.js.map +1 -0
  37. package/dist/objectStorage/index.d.ts +5 -0
  38. package/dist/objectStorage/index.d.ts.map +1 -0
  39. package/dist/objectStorage/index.js +5 -0
  40. package/dist/objectStorage/index.js.map +1 -0
  41. package/dist/objectStorage/localObjectStorage.core.d.ts +24 -0
  42. package/dist/objectStorage/localObjectStorage.core.d.ts.map +1 -0
  43. package/dist/objectStorage/localObjectStorage.core.js +151 -0
  44. package/dist/objectStorage/localObjectStorage.core.js.map +1 -0
  45. package/dist/repository/baseRepository.core.d.ts +64 -0
  46. package/dist/repository/baseRepository.core.d.ts.map +1 -0
  47. package/dist/repository/baseRepository.core.js +145 -0
  48. package/dist/repository/baseRepository.core.js.map +1 -0
  49. package/dist/repository/index.d.ts +6 -0
  50. package/dist/repository/index.d.ts.map +1 -0
  51. package/dist/repository/index.js +5 -0
  52. package/dist/repository/index.js.map +1 -0
  53. package/dist/serialization/index.d.ts +5 -0
  54. package/dist/serialization/index.d.ts.map +1 -0
  55. package/dist/serialization/index.js +5 -0
  56. package/dist/serialization/index.js.map +1 -0
  57. package/dist/serialization/jsonSerializer.core.d.ts +21 -0
  58. package/dist/serialization/jsonSerializer.core.d.ts.map +1 -0
  59. package/dist/serialization/jsonSerializer.core.js +29 -0
  60. package/dist/serialization/jsonSerializer.core.js.map +1 -0
  61. package/dist/types/index.d.ts +7 -0
  62. package/dist/types/index.d.ts.map +1 -0
  63. package/dist/types/index.js +7 -0
  64. package/dist/types/index.js.map +1 -0
  65. package/dist/types/storage.type.d.ts +9 -0
  66. package/dist/types/storage.type.d.ts.map +1 -0
  67. package/dist/types/storage.type.js +9 -0
  68. package/dist/types/storage.type.js.map +1 -0
  69. package/package.json +55 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inMemoryLock.core.d.ts","sourceRoot":"","sources":["../../src/locking/inMemoryLock.core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAgB/E;;GAEG;AACH,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAMvB;IAEE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBpE;IAEK,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAEtE;IAEK,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUjD;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,CAQd;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAQZ;IAED,OAAO,CAAC,cAAc;IA0CtB,OAAO,CAAC,aAAa;CAQtB"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * @zudojs/storage — In-Memory Lock Manager
3
+ *
4
+ * Provides distributed-style locking for single-process scenarios.
5
+ * For multi-process/multi-node, replace with Redis/Database-backed lock.
6
+ */
7
+ import { randomBytes } from "node:crypto";
8
+ import { StorageError } from "@zudojs/errors";
9
+ /** Default lock options. */
10
+ const DEFAULT_LOCK_OPTIONS = {
11
+ timeout: 10_000,
12
+ ttl: 30_000,
13
+ retryInterval: 100,
14
+ };
15
+ /**
16
+ * In-memory lock manager implementation.
17
+ */
18
+ export class InMemoryLockManager {
19
+ locks = new Map();
20
+ waitQueues = new Map();
21
+ async acquire(resource, options) {
22
+ const opts = { ...DEFAULT_LOCK_OPTIONS, ...options };
23
+ const deadline = Date.now() + opts.timeout;
24
+ while (Date.now() < deadline) {
25
+ const lock = this.tryAcquireLock(resource, opts.ttl);
26
+ if (lock)
27
+ return lock;
28
+ // Wait before retrying
29
+ await new Promise((resolve) => setTimeout(resolve, opts.retryInterval));
30
+ }
31
+ throw new StorageError(`Failed to acquire lock on "${resource}" within ${opts.timeout}ms`, {
32
+ code: "STORAGE_LOCK_ACQUIRE_TIMEOUT",
33
+ statusCode: 504,
34
+ });
35
+ }
36
+ async tryAcquire(resource, ttlMs) {
37
+ return this.tryAcquireLock(resource, ttlMs);
38
+ }
39
+ async isLocked(resource) {
40
+ const entry = this.locks.get(resource);
41
+ if (!entry)
42
+ return false;
43
+ if (Date.now() > entry.expiresAt.getTime()) {
44
+ this.locks.delete(resource);
45
+ return false;
46
+ }
47
+ return true;
48
+ }
49
+ /**
50
+ * Clean up expired locks.
51
+ */
52
+ cleanup() {
53
+ const now = Date.now();
54
+ for (const [resource, entry] of this.locks) {
55
+ if (now > entry.expiresAt.getTime()) {
56
+ this.locks.delete(resource);
57
+ this.notifyWaiters(resource);
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * Release all locks and clean up.
63
+ */
64
+ clear() {
65
+ this.locks.clear();
66
+ for (const queue of this.waitQueues.values()) {
67
+ for (const waiter of queue) {
68
+ clearTimeout(waiter.timer);
69
+ }
70
+ }
71
+ this.waitQueues.clear();
72
+ }
73
+ tryAcquireLock(resource, ttlMs) {
74
+ this.cleanup();
75
+ const existing = this.locks.get(resource);
76
+ if (existing) {
77
+ if (Date.now() > existing.expiresAt.getTime()) {
78
+ this.locks.delete(resource);
79
+ }
80
+ else {
81
+ return null;
82
+ }
83
+ }
84
+ const lockId = randomBytes(16).toString("hex");
85
+ const acquiredAt = new Date();
86
+ const expiresAt = new Date(Date.now() + ttlMs);
87
+ const entry = { lockId, resource, acquiredAt, expiresAt };
88
+ this.locks.set(resource, entry);
89
+ return {
90
+ lockId,
91
+ resource,
92
+ acquiredAt,
93
+ get expiresAt() {
94
+ return entry.expiresAt;
95
+ },
96
+ release: async () => {
97
+ const current = this.locks.get(resource);
98
+ if (current?.lockId === lockId) {
99
+ this.locks.delete(resource);
100
+ this.notifyWaiters(resource);
101
+ }
102
+ },
103
+ extend: async (durationMs) => {
104
+ const current = this.locks.get(resource);
105
+ if (current?.lockId === lockId) {
106
+ current.expiresAt = new Date(Date.now() + durationMs);
107
+ }
108
+ },
109
+ };
110
+ }
111
+ notifyWaiters(resource) {
112
+ const queue = this.waitQueues.get(resource);
113
+ if (queue && queue.length > 0) {
114
+ const waiter = queue.shift();
115
+ clearTimeout(waiter.timer);
116
+ waiter.resolve();
117
+ }
118
+ }
119
+ }
120
+ //# sourceMappingURL=inMemoryLock.core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inMemoryLock.core.js","sourceRoot":"","sources":["../../src/locking/inMemoryLock.core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @zudojs/storage — Locking Barrel
3
+ */
4
+ export { InMemoryLockManager } from "./inMemoryLock.core.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locking/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @zudojs/storage — Locking Barrel
3
+ */
4
+ export { InMemoryLockManager } from "./inMemoryLock.core.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/locking/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @zudojs/storage — Object Storage Barrel
3
+ */
4
+ export { LocalObjectStorage } from "./localObjectStorage.core.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/objectStorage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @zudojs/storage — Object Storage Barrel
3
+ */
4
+ export { LocalObjectStorage } from "./localObjectStorage.core.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/objectStorage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @zudojs/storage — Local Object Storage
3
+ *
4
+ * Filesystem-based object storage for development and testing.
5
+ */
6
+ import type { ObjectStorage, ObjectPutOptions, ObjectMetadata, ObjectData, ListObjectsResult } from "../types/storage.type.js";
7
+ /**
8
+ * Local filesystem object storage implementation.
9
+ */
10
+ export declare class LocalObjectStorage implements ObjectStorage {
11
+ private readonly basePath;
12
+ constructor(basePath: string);
13
+ put(key: string, data: Uint8Array | ReadableStream<Uint8Array>, options?: ObjectPutOptions): Promise<ObjectMetadata>;
14
+ get(key: string): Promise<ObjectData | null>;
15
+ delete(key: string): Promise<void>;
16
+ exists(key: string): Promise<boolean>;
17
+ metadata(key: string): Promise<ObjectMetadata | null>;
18
+ list(prefix?: string, options?: {
19
+ readonly maxKeys?: number;
20
+ readonly continuationToken?: string;
21
+ }): Promise<ListObjectsResult>;
22
+ private resolvePath;
23
+ }
24
+ //# sourceMappingURL=localObjectStorage.core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localObjectStorage.core.d.ts","sourceRoot":"","sources":["../../src/objectStorage/localObjectStorage.core.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAArC,YAA6B,QAAQ,EAAE,MAAM,EAAI;IAE3C,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,EAC7C,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,cAAc,CAAC,CAmCzB;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA4BjD;IAEK,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvC;IAEK,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ1C;IAEK,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAY1D;IAEK,IAAI,CACR,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KACrC,GACA,OAAO,CAAC,iBAAiB,CAAC,CAgC5B;IAED,OAAO,CAAC,WAAW;CAWpB"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * @zudojs/storage — Local Object Storage
3
+ *
4
+ * Filesystem-based object storage for development and testing.
5
+ */
6
+ import { readFile, writeFile, unlink, stat, mkdir, readdir, } from "node:fs/promises";
7
+ import { join, dirname } from "node:path";
8
+ import { StorageError } from "@zudojs/errors";
9
+ /**
10
+ * Local filesystem object storage implementation.
11
+ */
12
+ export class LocalObjectStorage {
13
+ basePath;
14
+ constructor(basePath) {
15
+ this.basePath = basePath;
16
+ }
17
+ async put(key, data, options) {
18
+ const filePath = this.resolvePath(key);
19
+ await mkdir(dirname(filePath), { recursive: true });
20
+ let buffer;
21
+ if (data instanceof Uint8Array) {
22
+ buffer = Buffer.from(data);
23
+ }
24
+ else {
25
+ // Read stream to buffer
26
+ const chunks = [];
27
+ const reader = data.getReader();
28
+ while (true) {
29
+ const { done, value } = await reader.read();
30
+ if (done)
31
+ break;
32
+ chunks.push(value);
33
+ }
34
+ const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
35
+ buffer = Buffer.alloc(totalLength);
36
+ let offset = 0;
37
+ for (const chunk of chunks) {
38
+ buffer.set(chunk, offset);
39
+ offset += chunk.length;
40
+ }
41
+ }
42
+ await writeFile(filePath, buffer);
43
+ const stats = await stat(filePath);
44
+ return {
45
+ key,
46
+ contentType: options?.contentType,
47
+ size: stats.size,
48
+ lastModified: stats.mtime,
49
+ metadata: options?.metadata,
50
+ };
51
+ }
52
+ async get(key) {
53
+ const filePath = this.resolvePath(key);
54
+ try {
55
+ const stats = await stat(filePath);
56
+ const buffer = await readFile(filePath);
57
+ const metadata = {
58
+ key,
59
+ size: stats.size,
60
+ lastModified: stats.mtime,
61
+ };
62
+ return {
63
+ metadata,
64
+ body: new ReadableStream({
65
+ start(controller) {
66
+ controller.enqueue(new Uint8Array(buffer));
67
+ controller.close();
68
+ },
69
+ }),
70
+ async arrayBuffer() {
71
+ return buffer.buffer;
72
+ },
73
+ };
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ async delete(key) {
80
+ const filePath = this.resolvePath(key);
81
+ await unlink(filePath);
82
+ }
83
+ async exists(key) {
84
+ const filePath = this.resolvePath(key);
85
+ try {
86
+ await stat(filePath);
87
+ return true;
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ async metadata(key) {
94
+ const filePath = this.resolvePath(key);
95
+ try {
96
+ const stats = await stat(filePath);
97
+ return {
98
+ key,
99
+ size: stats.size,
100
+ lastModified: stats.mtime,
101
+ };
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ async list(prefix, options) {
108
+ const dirPath = prefix ? this.resolvePath(prefix) : this.basePath;
109
+ const maxKeys = options?.maxKeys ?? 1000;
110
+ try {
111
+ const entries = await readdir(dirPath, { recursive: true });
112
+ const objects = [];
113
+ for (const entry of entries.slice(0, maxKeys)) {
114
+ const fullPath = join(dirPath, entry);
115
+ try {
116
+ const stats = await stat(fullPath);
117
+ if (stats.isFile()) {
118
+ const key = fullPath.slice(this.basePath.length + 1);
119
+ objects.push({
120
+ key,
121
+ size: stats.size,
122
+ lastModified: stats.mtime,
123
+ });
124
+ }
125
+ }
126
+ catch {
127
+ // Skip inaccessible entries
128
+ }
129
+ }
130
+ return {
131
+ objects,
132
+ isTruncated: entries.length > maxKeys,
133
+ };
134
+ }
135
+ catch {
136
+ return { objects: [], isTruncated: false };
137
+ }
138
+ }
139
+ resolvePath(key) {
140
+ // Prevent path traversal
141
+ const resolved = join(this.basePath, key);
142
+ if (!resolved.startsWith(this.basePath)) {
143
+ throw new StorageError(`Path traversal detected: ${key}`, {
144
+ code: "STORAGE_PATH_TRAVERSAL",
145
+ statusCode: 400,
146
+ });
147
+ }
148
+ return resolved;
149
+ }
150
+ }
151
+ //# sourceMappingURL=localObjectStorage.core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localObjectStorage.core.js","sourceRoot":"","sources":["../../src/objectStorage/localObjectStorage.core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @zudojs/storage — Base Repository
3
+ *
4
+ * Provides a base implementation for repository CRUD operations.
5
+ * Concrete repositories can extend this for domain-specific queries.
6
+ */
7
+ import type { Database, QueryParameter } from "../types/storage.type.js";
8
+ /**
9
+ * Options for the base repository.
10
+ */
11
+ export interface BaseRepositoryOptions {
12
+ /** The database table name. */
13
+ readonly tableName: string;
14
+ /** The primary key column name (default: "id"). */
15
+ readonly primaryKey?: string;
16
+ }
17
+ /**
18
+ * Base repository providing common CRUD operations.
19
+ * Override methods for domain-specific behavior.
20
+ */
21
+ export declare class BaseRepository<Entity extends Record<string, unknown>, ID = string> {
22
+ protected readonly database: Database;
23
+ protected readonly tableName: string;
24
+ protected readonly primaryKey: string;
25
+ constructor(database: Database, options: BaseRepositoryOptions);
26
+ /**
27
+ * Find an entity by its primary key.
28
+ */
29
+ findById(id: ID): Promise<Entity | null>;
30
+ /**
31
+ * Find multiple entities by their IDs.
32
+ */
33
+ findByIds(ids: readonly ID[]): Promise<readonly Entity[]>;
34
+ /**
35
+ * Create a new entity.
36
+ */
37
+ create(entity: Entity): Promise<Entity>;
38
+ /**
39
+ * Update an entity by primary key.
40
+ */
41
+ update(id: ID, changes: Partial<Entity>): Promise<Entity>;
42
+ /**
43
+ * Delete an entity by primary key.
44
+ */
45
+ delete(id: ID): Promise<void>;
46
+ /**
47
+ * Check if an entity exists by primary key.
48
+ */
49
+ exists(id: ID): Promise<boolean>;
50
+ /**
51
+ * Find all entities with optional limit and offset.
52
+ */
53
+ findAll(options?: {
54
+ readonly limit?: number;
55
+ readonly offset?: number;
56
+ readonly orderBy?: string;
57
+ readonly order?: "ASC" | "DESC";
58
+ }): Promise<readonly Entity[]>;
59
+ /**
60
+ * Count entities matching optional where conditions.
61
+ */
62
+ count(where?: Record<string, QueryParameter>): Promise<number>;
63
+ }
64
+ //# sourceMappingURL=baseRepository.core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseRepository.core.d.ts","sourceRoot":"","sources":["../../src/repository/baseRepository.core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,QAAQ,EAER,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,qBAAa,cAAc,CACzB,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,EAAE,GAAG,MAAM;IAMT,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAJvC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IACrC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAEtC,YACqB,QAAQ,EAAE,QAAQ,EACrC,OAAO,EAAE,qBAAqB,EAI/B;IAED;;OAEG;IACG,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO7C;IAED;;OAEG;IACG,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAU9D;IAED;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY5C;IAED;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB9D;IAED;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMlC;IAED;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrC;IAED;;OAEG;IACG,OAAO,CAAC,OAAO,CAAC,EAAE;QACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;KACjC,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAiB7B;IAED;;OAEG;IACG,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBnE;CACF"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * @zudojs/storage — Base Repository
3
+ *
4
+ * Provides a base implementation for repository CRUD operations.
5
+ * Concrete repositories can extend this for domain-specific queries.
6
+ */
7
+ import { NotFoundError } from "@zudojs/errors";
8
+ /**
9
+ * Base repository providing common CRUD operations.
10
+ * Override methods for domain-specific behavior.
11
+ */
12
+ export class BaseRepository {
13
+ database;
14
+ tableName;
15
+ primaryKey;
16
+ constructor(database, options) {
17
+ this.database = database;
18
+ this.tableName = options.tableName;
19
+ this.primaryKey = options.primaryKey ?? "id";
20
+ }
21
+ /**
22
+ * Find an entity by its primary key.
23
+ */
24
+ async findById(id) {
25
+ const query = {
26
+ text: `SELECT * FROM ${this.tableName} WHERE ${this.primaryKey} = $1`,
27
+ parameters: [id],
28
+ };
29
+ const result = await this.database.query(query);
30
+ return result.rows[0] ?? null;
31
+ }
32
+ /**
33
+ * Find multiple entities by their IDs.
34
+ */
35
+ async findByIds(ids) {
36
+ if (ids.length === 0)
37
+ return [];
38
+ const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ");
39
+ const query = {
40
+ text: `SELECT * FROM ${this.tableName} WHERE ${this.primaryKey} IN (${placeholders})`,
41
+ parameters: [...ids],
42
+ };
43
+ const result = await this.database.query(query);
44
+ return result.rows;
45
+ }
46
+ /**
47
+ * Create a new entity.
48
+ */
49
+ async create(entity) {
50
+ const keys = Object.keys(entity);
51
+ const values = Object.values(entity);
52
+ const placeholders = keys.map((_, i) => `$${i + 1}`).join(", ");
53
+ const columns = keys.join(", ");
54
+ const query = {
55
+ text: `INSERT INTO ${this.tableName} (${columns}) VALUES (${placeholders}) RETURNING *`,
56
+ parameters: values,
57
+ };
58
+ const result = await this.database.query(query);
59
+ return result.rows[0];
60
+ }
61
+ /**
62
+ * Update an entity by primary key.
63
+ */
64
+ async update(id, changes) {
65
+ const keys = Object.keys(changes);
66
+ const values = Object.values(changes);
67
+ if (keys.length === 0) {
68
+ const existing = await this.findById(id);
69
+ if (!existing) {
70
+ throw new NotFoundError(`Entity not found: ${id}`, {
71
+ code: "STORAGE_ENTITY_NOT_FOUND",
72
+ statusCode: 404,
73
+ });
74
+ }
75
+ return existing;
76
+ }
77
+ const setClauses = keys.map((key, i) => `${key} = $${i + 1}`).join(", ");
78
+ const parameters = [...values, id];
79
+ const query = {
80
+ text: `UPDATE ${this.tableName} SET ${setClauses} WHERE ${this.primaryKey} = $${keys.length + 1} RETURNING *`,
81
+ parameters,
82
+ };
83
+ const result = await this.database.query(query);
84
+ return result.rows[0];
85
+ }
86
+ /**
87
+ * Delete an entity by primary key.
88
+ */
89
+ async delete(id) {
90
+ const query = {
91
+ text: `DELETE FROM ${this.tableName} WHERE ${this.primaryKey} = $1`,
92
+ parameters: [id],
93
+ };
94
+ await this.database.execute(query);
95
+ }
96
+ /**
97
+ * Check if an entity exists by primary key.
98
+ */
99
+ async exists(id) {
100
+ const query = {
101
+ text: `SELECT 1 FROM ${this.tableName} WHERE ${this.primaryKey} = $1 LIMIT 1`,
102
+ parameters: [id],
103
+ };
104
+ const result = await this.database.query(query);
105
+ return result.rowCount > 0;
106
+ }
107
+ /**
108
+ * Find all entities with optional limit and offset.
109
+ */
110
+ async findAll(options) {
111
+ let text = `SELECT * FROM ${this.tableName}`;
112
+ if (options?.orderBy) {
113
+ text += ` ORDER BY ${options.orderBy} ${options.order ?? "ASC"}`;
114
+ }
115
+ if (options?.limit !== undefined) {
116
+ text += ` LIMIT ${options.limit}`;
117
+ }
118
+ if (options?.offset !== undefined) {
119
+ text += ` OFFSET ${options.offset}`;
120
+ }
121
+ const result = await this.database.query({ text });
122
+ return result.rows;
123
+ }
124
+ /**
125
+ * Count entities matching optional where conditions.
126
+ */
127
+ async count(where) {
128
+ let text = `SELECT COUNT(*) as count FROM ${this.tableName}`;
129
+ const parameters = [];
130
+ if (where) {
131
+ const keys = Object.keys(where);
132
+ if (keys.length > 0) {
133
+ const conditions = keys.map((key, i) => `${key} = $${i + 1}`);
134
+ text += ` WHERE ${conditions.join(" AND ")}`;
135
+ parameters.push(...Object.values(where));
136
+ }
137
+ }
138
+ const result = await this.database.query({
139
+ text,
140
+ parameters,
141
+ });
142
+ return parseInt(result.rows[0]?.count ?? "0", 10);
143
+ }
144
+ }
145
+ //# sourceMappingURL=baseRepository.core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseRepository.core.js","sourceRoot":"","sources":["../../src/repository/baseRepository.core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkB/C;;;GAGG;AACH,MAAM,OAAO,cAAc;IAQJ,QAAQ;IAJV,SAAS,CAAS;IAClB,UAAU,CAAS;IAEtC,YACqB,QAAkB,EACrC,OAA8B;wBADX,QAAQ;QAG3B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAM;QACnB,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,iBAAiB,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,UAAU,OAAO;YACrE,UAAU,EAAE,CAAC,EAAoB,CAAC;SACnC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAS,KAAK,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,GAAkB;QAChC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEhC,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,iBAAiB,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,UAAU,QAAQ,YAAY,GAAG;YACrF,UAAU,EAAE,CAAC,GAAG,GAAG,CAAqB;SACzC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAS,KAAK,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,MAAc;QACzB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,eAAe,IAAI,CAAC,SAAS,KAAK,OAAO,aAAa,YAAY,eAAe;YACvF,UAAU,EAAE,MAA0B;SACvC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAS,KAAK,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAM,EAAE,OAAwB;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEtC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,aAAa,CAAC,qBAAqB,EAAE,EAAE,EAAE;oBACjD,IAAI,EAAE,0BAA0B;oBAChC,UAAU,EAAE,GAAG;iBAChB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,UAAU,GAAG,CAAC,GAAG,MAAM,EAAE,EAAE,CAAqB,CAAC;QAEvD,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,UAAU,IAAI,CAAC,SAAS,QAAQ,UAAU,UAAU,IAAI,CAAC,UAAU,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,cAAc;YAC7G,UAAU;SACX,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAS,KAAK,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAM;QACjB,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,eAAe,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,UAAU,OAAO;YACnE,UAAU,EAAE,CAAC,EAAoB,CAAC;SACnC,CAAC;QACF,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAM;QACjB,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,iBAAiB,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,UAAU,eAAe;YAC7E,UAAU,EAAE,CAAC,EAAoB,CAAC;SACnC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,OAKb;QACC,IAAI,IAAI,GAAG,iBAAiB,IAAI,CAAC,SAAS,EAAE,CAAC;QAE7C,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,IAAI,IAAI,aAAa,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;QACnE,CAAC;QAED,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,IAAI,UAAU,OAAO,CAAC,KAAK,EAAE,CAAC;QACpC,CAAC;QAED,IAAI,OAAO,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,IAAI,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC;QACtC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,KAAsC;QAChD,IAAI,IAAI,GAAG,iCAAiC,IAAI,CAAC,SAAS,EAAE,CAAC;QAC7D,MAAM,UAAU,GAAqB,EAAE,CAAC;QAExC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC9D,IAAI,IAAI,UAAU,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7C,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAoB;YAC1D,IAAI;YACJ,UAAU;SACX,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @zudojs/storage — Repository Barrel
3
+ */
4
+ export { BaseRepository } from "./baseRepository.core.js";
5
+ export type { BaseRepositoryOptions } from "./baseRepository.core.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repository/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @zudojs/storage — Repository Barrel
3
+ */
4
+ export { BaseRepository } from "./baseRepository.core.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repository/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @zudojs/storage — Serialization Barrel
3
+ */
4
+ export { JsonSerializer } from "./jsonSerializer.core.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/serialization/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @zudojs/storage — Serialization Barrel
3
+ */
4
+ export { JsonSerializer } from "./jsonSerializer.core.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/serialization/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @zudojs/storage — JSON Serializer
3
+ *
4
+ * Serializes/deserializes data for storage with support for BigInt, Date,
5
+ * Map, Set, and Uint8Array via @zudojs/serialization's type preservation.
6
+ */
7
+ import type { Serializer, SerializationFormat } from "../types/storage.type.js";
8
+ /**
9
+ * JSON serializer with extended type support for storage operations.
10
+ *
11
+ * Delegates to @zudojs/serialization's JSONSerializer for type preservation
12
+ * (BigInt, Date, Map, Set, Uint8Array) and wraps the output as Uint8Array
13
+ * to satisfy the storage Serializer contract.
14
+ */
15
+ export declare class JsonSerializer implements Serializer {
16
+ private readonly inner;
17
+ constructor();
18
+ serialize<T>(value: T, _format?: SerializationFormat): Uint8Array;
19
+ deserialize<T>(data: Uint8Array, _format?: SerializationFormat): T;
20
+ }
21
+ //# sourceMappingURL=jsonSerializer.core.d.ts.map