@vobase/core 0.10.0 → 0.12.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.
- package/package.json +7 -9
- package/src/__tests__/drizzle-introspection.test.ts +77 -0
- package/src/__tests__/e2e.test.ts +225 -0
- package/src/__tests__/permissions.test.ts +157 -0
- package/src/__tests__/rpc-types.test.ts +92 -0
- package/src/app.test.ts +99 -0
- package/src/app.ts +178 -0
- package/src/audit.test.ts +126 -0
- package/src/auth.test.ts +74 -0
- package/src/contracts/auth.ts +37 -0
- package/{dist/contracts/module.d.ts → src/contracts/module.ts} +6 -6
- package/src/contracts/notify.ts +47 -0
- package/src/contracts/permissions.ts +10 -0
- package/src/contracts/storage.ts +61 -0
- package/src/ctx.test.ts +162 -0
- package/src/ctx.ts +64 -0
- package/src/db/client.test.ts +75 -0
- package/src/db/client.ts +15 -0
- package/src/db/helpers.test.ts +147 -0
- package/src/db/helpers.ts +51 -0
- package/src/db/index.ts +8 -0
- package/{dist/index.d.ts → src/index.ts} +103 -6
- package/src/infra/circuit-breaker.test.ts +74 -0
- package/src/infra/circuit-breaker.ts +57 -0
- package/src/infra/errors.test.ts +175 -0
- package/src/infra/errors.ts +64 -0
- package/src/infra/http-client.test.ts +482 -0
- package/src/infra/http-client.ts +221 -0
- package/src/infra/index.ts +35 -0
- package/src/infra/job.test.ts +85 -0
- package/src/infra/job.ts +94 -0
- package/src/infra/logger.test.ts +65 -0
- package/src/infra/logger.ts +18 -0
- package/src/infra/queue.test.ts +46 -0
- package/src/infra/queue.ts +147 -0
- package/src/infra/throw-proxy.test.ts +34 -0
- package/src/infra/throw-proxy.ts +17 -0
- package/src/infra/webhooks-schema.ts +17 -0
- package/src/infra/webhooks.test.ts +364 -0
- package/src/infra/webhooks.ts +146 -0
- package/src/mcp/auth.test.ts +129 -0
- package/src/mcp/crud.test.ts +128 -0
- package/src/mcp/crud.ts +171 -0
- package/{dist/mcp/index.d.ts → src/mcp/index.ts} +0 -1
- package/src/mcp/server.test.ts +153 -0
- package/src/mcp/server.ts +178 -0
- package/src/middleware/audit.test.ts +169 -0
- package/src/module-registry.ts +18 -0
- package/src/module.test.ts +168 -0
- package/src/module.ts +111 -0
- package/src/modules/audit/index.ts +18 -0
- package/src/modules/audit/middleware.ts +33 -0
- package/src/modules/audit/schema.ts +35 -0
- package/src/modules/audit/track-changes.ts +70 -0
- package/src/modules/auth/audit-hooks.ts +74 -0
- package/src/modules/auth/index.ts +101 -0
- package/src/modules/auth/middleware.ts +51 -0
- package/src/modules/auth/permissions.ts +46 -0
- package/src/modules/auth/schema.ts +184 -0
- package/src/modules/credentials/encrypt.ts +95 -0
- package/src/modules/credentials/index.ts +15 -0
- package/src/modules/credentials/schema.ts +10 -0
- package/src/modules/notify/index.ts +90 -0
- package/src/modules/notify/notify.test.ts +145 -0
- package/src/modules/notify/providers/resend.ts +47 -0
- package/src/modules/notify/providers/smtp.ts +117 -0
- package/src/modules/notify/providers/waba.ts +82 -0
- package/src/modules/notify/schema.ts +27 -0
- package/src/modules/notify/service.ts +93 -0
- package/src/modules/sequences/index.ts +15 -0
- package/src/modules/sequences/next-sequence.ts +48 -0
- package/src/modules/sequences/schema.ts +12 -0
- package/src/modules/storage/index.ts +44 -0
- package/src/modules/storage/providers/local.ts +124 -0
- package/src/modules/storage/providers/s3.ts +83 -0
- package/src/modules/storage/routes.ts +76 -0
- package/src/modules/storage/schema.ts +26 -0
- package/src/modules/storage/service.ts +202 -0
- package/src/modules/storage/storage.test.ts +225 -0
- package/src/schemas.test.ts +44 -0
- package/src/schemas.ts +63 -0
- package/src/sequence.test.ts +56 -0
- package/dist/app.d.ts +0 -37
- package/dist/app.d.ts.map +0 -1
- package/dist/contracts/auth.d.ts +0 -35
- package/dist/contracts/auth.d.ts.map +0 -1
- package/dist/contracts/module.d.ts.map +0 -1
- package/dist/contracts/notify.d.ts +0 -46
- package/dist/contracts/notify.d.ts.map +0 -1
- package/dist/contracts/permissions.d.ts +0 -10
- package/dist/contracts/permissions.d.ts.map +0 -1
- package/dist/contracts/storage.d.ts +0 -54
- package/dist/contracts/storage.d.ts.map +0 -1
- package/dist/ctx.d.ts +0 -40
- package/dist/ctx.d.ts.map +0 -1
- package/dist/db/client.d.ts +0 -4
- package/dist/db/client.d.ts.map +0 -1
- package/dist/db/helpers.d.ts +0 -26
- package/dist/db/helpers.d.ts.map +0 -1
- package/dist/db/index.d.ts +0 -3
- package/dist/db/index.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -98611
- package/dist/infra/circuit-breaker.d.ts +0 -17
- package/dist/infra/circuit-breaker.d.ts.map +0 -1
- package/dist/infra/errors.d.ts +0 -26
- package/dist/infra/errors.d.ts.map +0 -1
- package/dist/infra/http-client.d.ts +0 -31
- package/dist/infra/http-client.d.ts.map +0 -1
- package/dist/infra/index.d.ts +0 -11
- package/dist/infra/index.d.ts.map +0 -1
- package/dist/infra/job.d.ts +0 -14
- package/dist/infra/job.d.ts.map +0 -1
- package/dist/infra/logger.d.ts +0 -7
- package/dist/infra/logger.d.ts.map +0 -1
- package/dist/infra/queue.d.ts +0 -18
- package/dist/infra/queue.d.ts.map +0 -1
- package/dist/infra/throw-proxy.d.ts +0 -7
- package/dist/infra/throw-proxy.d.ts.map +0 -1
- package/dist/infra/webhooks-schema.d.ts +0 -60
- package/dist/infra/webhooks-schema.d.ts.map +0 -1
- package/dist/infra/webhooks.d.ts +0 -46
- package/dist/infra/webhooks.d.ts.map +0 -1
- package/dist/mcp/crud.d.ts +0 -12
- package/dist/mcp/crud.d.ts.map +0 -1
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/server.d.ts +0 -16
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/module-registry.d.ts +0 -3
- package/dist/module-registry.d.ts.map +0 -1
- package/dist/module.d.ts +0 -29
- package/dist/module.d.ts.map +0 -1
- package/dist/modules/audit/index.d.ts +0 -5
- package/dist/modules/audit/index.d.ts.map +0 -1
- package/dist/modules/audit/middleware.d.ts +0 -3
- package/dist/modules/audit/middleware.d.ts.map +0 -1
- package/dist/modules/audit/schema.d.ts +0 -247
- package/dist/modules/audit/schema.d.ts.map +0 -1
- package/dist/modules/audit/track-changes.d.ts +0 -3
- package/dist/modules/audit/track-changes.d.ts.map +0 -1
- package/dist/modules/auth/audit-hooks.d.ts +0 -6
- package/dist/modules/auth/audit-hooks.d.ts.map +0 -1
- package/dist/modules/auth/index.d.ts +0 -25
- package/dist/modules/auth/index.d.ts.map +0 -1
- package/dist/modules/auth/middleware.d.ts +0 -15
- package/dist/modules/auth/middleware.d.ts.map +0 -1
- package/dist/modules/auth/permissions.d.ts +0 -5
- package/dist/modules/auth/permissions.d.ts.map +0 -1
- package/dist/modules/auth/schema.d.ts +0 -2519
- package/dist/modules/auth/schema.d.ts.map +0 -1
- package/dist/modules/credentials/encrypt.d.ts +0 -12
- package/dist/modules/credentials/encrypt.d.ts.map +0 -1
- package/dist/modules/credentials/index.d.ts +0 -4
- package/dist/modules/credentials/index.d.ts.map +0 -1
- package/dist/modules/credentials/schema.d.ts +0 -56
- package/dist/modules/credentials/schema.d.ts.map +0 -1
- package/dist/modules/notify/index.d.ts +0 -36
- package/dist/modules/notify/index.d.ts.map +0 -1
- package/dist/modules/notify/providers/resend.d.ts +0 -7
- package/dist/modules/notify/providers/resend.d.ts.map +0 -1
- package/dist/modules/notify/providers/smtp.d.ts +0 -18
- package/dist/modules/notify/providers/smtp.d.ts.map +0 -1
- package/dist/modules/notify/providers/waba.d.ts +0 -12
- package/dist/modules/notify/providers/waba.d.ts.map +0 -1
- package/dist/modules/notify/schema.d.ts +0 -337
- package/dist/modules/notify/schema.d.ts.map +0 -1
- package/dist/modules/notify/service.d.ts +0 -22
- package/dist/modules/notify/service.d.ts.map +0 -1
- package/dist/modules/sequences/index.d.ts +0 -4
- package/dist/modules/sequences/index.d.ts.map +0 -1
- package/dist/modules/sequences/next-sequence.d.ts +0 -8
- package/dist/modules/sequences/next-sequence.d.ts.map +0 -1
- package/dist/modules/sequences/schema.d.ts +0 -72
- package/dist/modules/sequences/schema.d.ts.map +0 -1
- package/dist/modules/storage/index.d.ts +0 -24
- package/dist/modules/storage/index.d.ts.map +0 -1
- package/dist/modules/storage/providers/local.d.ts +0 -3
- package/dist/modules/storage/providers/local.d.ts.map +0 -1
- package/dist/modules/storage/providers/s3.d.ts +0 -3
- package/dist/modules/storage/providers/s3.d.ts.map +0 -1
- package/dist/modules/storage/routes.d.ts +0 -4
- package/dist/modules/storage/routes.d.ts.map +0 -1
- package/dist/modules/storage/schema.d.ts +0 -273
- package/dist/modules/storage/schema.d.ts.map +0 -1
- package/dist/modules/storage/service.d.ts +0 -35
- package/dist/modules/storage/service.d.ts.map +0 -1
- package/dist/schemas.d.ts +0 -19
- package/dist/schemas.d.ts.map +0 -1
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { Database } from 'bun:sqlite';
|
|
2
|
+
import { mkdirSync, rmSync } from 'node:fs';
|
|
3
|
+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
|
|
4
|
+
import { drizzle } from 'drizzle-orm/bun-sqlite';
|
|
5
|
+
|
|
6
|
+
import type { VobaseDb } from '../../db/client';
|
|
7
|
+
import { VobaseError } from '../../infra/errors';
|
|
8
|
+
import { createLocalProvider } from './providers/local';
|
|
9
|
+
import { createStorageService, type BucketConfig } from './service';
|
|
10
|
+
import * as storageSchemaModule from './schema';
|
|
11
|
+
|
|
12
|
+
const testBasePath = '/tmp/vobase-test-storage-v2';
|
|
13
|
+
|
|
14
|
+
function createTestDb(): { db: VobaseDb; sqlite: Database } {
|
|
15
|
+
const sqlite = new Database(':memory:');
|
|
16
|
+
sqlite.run('PRAGMA journal_mode=WAL');
|
|
17
|
+
sqlite.exec(`
|
|
18
|
+
CREATE TABLE _storage_objects (
|
|
19
|
+
id TEXT PRIMARY KEY,
|
|
20
|
+
bucket TEXT NOT NULL,
|
|
21
|
+
key TEXT NOT NULL,
|
|
22
|
+
size INTEGER NOT NULL,
|
|
23
|
+
content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
|
|
24
|
+
metadata TEXT,
|
|
25
|
+
uploaded_by TEXT,
|
|
26
|
+
created_at INTEGER NOT NULL
|
|
27
|
+
)
|
|
28
|
+
`);
|
|
29
|
+
sqlite.exec(
|
|
30
|
+
'CREATE UNIQUE INDEX storage_objects_bucket_key_idx ON _storage_objects(bucket, key)',
|
|
31
|
+
);
|
|
32
|
+
const db = drizzle({ client: sqlite, schema: storageSchemaModule }) as unknown as VobaseDb;
|
|
33
|
+
return { db, sqlite };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('Local Provider', () => {
|
|
37
|
+
beforeAll(() => {
|
|
38
|
+
try {
|
|
39
|
+
rmSync(testBasePath, { recursive: true, force: true });
|
|
40
|
+
} catch {}
|
|
41
|
+
mkdirSync(testBasePath, { recursive: true });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
afterAll(() => {
|
|
45
|
+
try {
|
|
46
|
+
rmSync(testBasePath, { recursive: true, force: true });
|
|
47
|
+
} catch {}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('uploads and downloads a file', async () => {
|
|
51
|
+
const provider = createLocalProvider({ type: 'local', basePath: testBasePath });
|
|
52
|
+
const data = new Uint8Array([1, 2, 3, 4, 5]);
|
|
53
|
+
|
|
54
|
+
await provider.upload('test-bucket/file.bin', data);
|
|
55
|
+
const downloaded = await provider.download('test-bucket/file.bin');
|
|
56
|
+
|
|
57
|
+
expect(downloaded).toEqual(data);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('checks file existence', async () => {
|
|
61
|
+
const provider = createLocalProvider({ type: 'local', basePath: testBasePath });
|
|
62
|
+
const data = new Uint8Array([42]);
|
|
63
|
+
|
|
64
|
+
await provider.upload('test-bucket/exists.bin', data);
|
|
65
|
+
|
|
66
|
+
expect(await provider.exists('test-bucket/exists.bin')).toBe(true);
|
|
67
|
+
expect(await provider.exists('test-bucket/nonexistent.bin')).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('deletes a file', async () => {
|
|
71
|
+
const provider = createLocalProvider({ type: 'local', basePath: testBasePath });
|
|
72
|
+
const data = new Uint8Array([99]);
|
|
73
|
+
|
|
74
|
+
await provider.upload('test-bucket/to-delete.bin', data);
|
|
75
|
+
await provider.delete('test-bucket/to-delete.bin');
|
|
76
|
+
|
|
77
|
+
expect(await provider.exists('test-bucket/to-delete.bin')).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('rejects directory traversal', async () => {
|
|
81
|
+
const provider = createLocalProvider({ type: 'local', basePath: testBasePath });
|
|
82
|
+
|
|
83
|
+
expect(() => provider.presign('../etc/passwd', {})).toThrow(VobaseError);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('returns proxy URL from presign', () => {
|
|
87
|
+
const provider = createLocalProvider({ type: 'local', basePath: testBasePath });
|
|
88
|
+
const url = provider.presign('avatars/user-123/pic.jpg', {});
|
|
89
|
+
|
|
90
|
+
expect(url).toBe('/api/storage/avatars/user-123/pic.jpg');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('enforces maxSize on upload', async () => {
|
|
94
|
+
const provider = createLocalProvider({ type: 'local', basePath: testBasePath });
|
|
95
|
+
const largeData = new Uint8Array(1000);
|
|
96
|
+
|
|
97
|
+
await expect(
|
|
98
|
+
provider.upload('test-bucket/large.bin', largeData, { maxSize: 100 }),
|
|
99
|
+
).rejects.toThrow(VobaseError);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('lists files in a directory', async () => {
|
|
103
|
+
const listPath = `${testBasePath}/list-test`;
|
|
104
|
+
rmSync(listPath, { recursive: true, force: true });
|
|
105
|
+
mkdirSync(listPath, { recursive: true });
|
|
106
|
+
|
|
107
|
+
const provider = createLocalProvider({ type: 'local', basePath: listPath });
|
|
108
|
+
await provider.upload('mybucket/a.txt', new Uint8Array([1]));
|
|
109
|
+
await provider.upload('mybucket/b.txt', new Uint8Array([2, 3]));
|
|
110
|
+
|
|
111
|
+
const result = await provider.list('mybucket');
|
|
112
|
+
|
|
113
|
+
expect(result.objects.length).toBe(2);
|
|
114
|
+
expect(result.objects.map((o) => o.key).sort()).toEqual(['mybucket/a.txt', 'mybucket/b.txt']);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('StorageService', () => {
|
|
119
|
+
let db: VobaseDb;
|
|
120
|
+
let sqlite: Database;
|
|
121
|
+
|
|
122
|
+
const buckets: Record<string, BucketConfig> = {
|
|
123
|
+
avatars: { access: 'public', maxSize: 5 * 1024 * 1024 },
|
|
124
|
+
documents: { access: 'private', allowedTypes: ['application/pdf', 'image/*'] },
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
beforeEach(() => {
|
|
128
|
+
const result = createTestDb();
|
|
129
|
+
db = result.db;
|
|
130
|
+
sqlite = result.sqlite;
|
|
131
|
+
try {
|
|
132
|
+
rmSync(`${testBasePath}/svc`, { recursive: true, force: true });
|
|
133
|
+
} catch {}
|
|
134
|
+
mkdirSync(`${testBasePath}/svc`, { recursive: true });
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
afterEach(() => {
|
|
138
|
+
sqlite.close();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('throws for unknown bucket name', () => {
|
|
142
|
+
const provider = createLocalProvider({ type: 'local', basePath: `${testBasePath}/svc` });
|
|
143
|
+
const svc = createStorageService(provider, buckets, db);
|
|
144
|
+
|
|
145
|
+
expect(() => svc.bucket('nonexistent')).toThrow(VobaseError);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('uploads and tracks metadata in SQLite', async () => {
|
|
149
|
+
const provider = createLocalProvider({ type: 'local', basePath: `${testBasePath}/svc` });
|
|
150
|
+
const svc = createStorageService(provider, buckets, db);
|
|
151
|
+
|
|
152
|
+
const handle = svc.bucket('avatars');
|
|
153
|
+
const obj = await handle.upload('user-1/pic.jpg', new Uint8Array([1, 2, 3]), {
|
|
154
|
+
contentType: 'image/jpeg',
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
expect(obj.bucket).toBe('avatars');
|
|
158
|
+
expect(obj.key).toBe('user-1/pic.jpg');
|
|
159
|
+
expect(obj.size).toBe(3);
|
|
160
|
+
expect(obj.contentType).toBe('image/jpeg');
|
|
161
|
+
|
|
162
|
+
const meta = await handle.metadata('user-1/pic.jpg');
|
|
163
|
+
expect(meta).not.toBeNull();
|
|
164
|
+
expect(meta?.size).toBe(3);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('downloads uploaded file', async () => {
|
|
168
|
+
const provider = createLocalProvider({ type: 'local', basePath: `${testBasePath}/svc` });
|
|
169
|
+
const svc = createStorageService(provider, buckets, db);
|
|
170
|
+
|
|
171
|
+
const data = new Uint8Array([10, 20, 30]);
|
|
172
|
+
await svc.bucket('avatars').upload('dl-test.bin', data);
|
|
173
|
+
const downloaded = await svc.bucket('avatars').download('dl-test.bin');
|
|
174
|
+
|
|
175
|
+
expect(downloaded).toEqual(data);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('deletes file and removes metadata', async () => {
|
|
179
|
+
const provider = createLocalProvider({ type: 'local', basePath: `${testBasePath}/svc` });
|
|
180
|
+
const svc = createStorageService(provider, buckets, db);
|
|
181
|
+
|
|
182
|
+
await svc.bucket('avatars').upload('del-test.bin', new Uint8Array([1]));
|
|
183
|
+
await svc.bucket('avatars').delete('del-test.bin');
|
|
184
|
+
|
|
185
|
+
const meta = await svc.bucket('avatars').metadata('del-test.bin');
|
|
186
|
+
expect(meta).toBeNull();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('enforces bucket maxSize', async () => {
|
|
190
|
+
const provider = createLocalProvider({ type: 'local', basePath: `${testBasePath}/svc` });
|
|
191
|
+
const smallBuckets = { tiny: { access: 'private' as const, maxSize: 10 } };
|
|
192
|
+
const svc = createStorageService(provider, smallBuckets, db);
|
|
193
|
+
|
|
194
|
+
await expect(
|
|
195
|
+
svc.bucket('tiny').upload('big.bin', new Uint8Array(100)),
|
|
196
|
+
).rejects.toThrow(VobaseError);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('enforces allowedTypes', async () => {
|
|
200
|
+
const provider = createLocalProvider({ type: 'local', basePath: `${testBasePath}/svc` });
|
|
201
|
+
const svc = createStorageService(provider, buckets, db);
|
|
202
|
+
|
|
203
|
+
await svc.bucket('documents').upload('doc.pdf', new Uint8Array([1]), {
|
|
204
|
+
contentType: 'application/pdf',
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
await svc.bucket('documents').upload('pic.png', new Uint8Array([1]), {
|
|
208
|
+
contentType: 'image/png',
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
await expect(
|
|
212
|
+
svc.bucket('documents').upload('file.txt', new Uint8Array([1]), {
|
|
213
|
+
contentType: 'text/plain',
|
|
214
|
+
}),
|
|
215
|
+
).rejects.toThrow(VobaseError);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('presign returns proxy URL with bucket prefix', () => {
|
|
219
|
+
const provider = createLocalProvider({ type: 'local', basePath: `${testBasePath}/svc` });
|
|
220
|
+
const svc = createStorageService(provider, buckets, db);
|
|
221
|
+
|
|
222
|
+
const url = svc.bucket('avatars').presign('user-1/pic.jpg');
|
|
223
|
+
expect(url).toBe('/api/storage/avatars/user-1/pic.jpg');
|
|
224
|
+
});
|
|
225
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import { getActiveSchemas } from './schemas';
|
|
3
|
+
|
|
4
|
+
describe('getActiveSchemas', () => {
|
|
5
|
+
test('returns auth, audit, sequences, webhook_dedup, and credentials by default', () => {
|
|
6
|
+
const schemas = getActiveSchemas();
|
|
7
|
+
// Auth tables (always active)
|
|
8
|
+
expect(schemas.user).toBeDefined();
|
|
9
|
+
expect(schemas.session).toBeDefined();
|
|
10
|
+
expect(schemas.account).toBeDefined();
|
|
11
|
+
expect(schemas.verification).toBeDefined();
|
|
12
|
+
// Audit tables (always active)
|
|
13
|
+
expect(schemas.auditLog).toBeDefined();
|
|
14
|
+
expect(schemas.recordAudits).toBeDefined();
|
|
15
|
+
// Sequences (always active)
|
|
16
|
+
expect(schemas.sequences).toBeDefined();
|
|
17
|
+
// Webhook dedup (always active)
|
|
18
|
+
expect(schemas.webhookDedup).toBeDefined();
|
|
19
|
+
// Credentials (default: included)
|
|
20
|
+
expect(schemas.credentialsTable).toBeDefined();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('excludes credentials when credentials: false', () => {
|
|
24
|
+
const schemas = getActiveSchemas({ credentials: false });
|
|
25
|
+
expect(schemas.credentialsTable).toBeUndefined();
|
|
26
|
+
// Other tables still present
|
|
27
|
+
expect(schemas.user).toBeDefined();
|
|
28
|
+
expect(schemas.auditLog).toBeDefined();
|
|
29
|
+
expect(schemas.sequences).toBeDefined();
|
|
30
|
+
expect(schemas.webhookDedup).toBeDefined();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('includes credentials when credentials: true', () => {
|
|
34
|
+
const schemas = getActiveSchemas({ credentials: true });
|
|
35
|
+
expect(schemas.credentialsTable).toBeDefined();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('returns a plain object with all table definitions', () => {
|
|
39
|
+
const schemas = getActiveSchemas();
|
|
40
|
+
const keys = Object.keys(schemas);
|
|
41
|
+
// At minimum: 4 auth + 2 audit + 1 sequences + 1 webhook + 1 credentials = 9
|
|
42
|
+
expect(keys.length).toBeGreaterThanOrEqual(9);
|
|
43
|
+
});
|
|
44
|
+
});
|
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { authSchema, apikeySchema, organizationSchema } from './modules/auth/schema';
|
|
2
|
+
import { auditLog, recordAudits } from './modules/audit/schema';
|
|
3
|
+
import { credentialsTable } from './modules/credentials/schema';
|
|
4
|
+
import { sequences } from './modules/sequences/schema';
|
|
5
|
+
import { notifyLog } from './modules/notify/schema';
|
|
6
|
+
import { storageObjects } from './modules/storage/schema';
|
|
7
|
+
import { webhookDedup } from './infra/webhooks-schema';
|
|
8
|
+
|
|
9
|
+
export interface SchemaConfig {
|
|
10
|
+
/** Include credentials table. Default: true */
|
|
11
|
+
credentials?: boolean;
|
|
12
|
+
/** Include storage tables (Phase 2). Default: false */
|
|
13
|
+
storage?: boolean;
|
|
14
|
+
/** Include notify tables (Phase 3). Default: false */
|
|
15
|
+
notify?: boolean;
|
|
16
|
+
/** Include organization tables (better-auth organization plugin). Default: false */
|
|
17
|
+
organization?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns a merged schema object containing all active Drizzle table
|
|
22
|
+
* definitions based on config. Use with drizzle-kit for migration generation.
|
|
23
|
+
*
|
|
24
|
+
* Always included: auth, audit, sequences, webhook dedup.
|
|
25
|
+
* Conditionally included: credentials, storage (Phase 2), notify (Phase 3).
|
|
26
|
+
*/
|
|
27
|
+
export function getActiveSchemas(config?: SchemaConfig): Record<string, unknown> {
|
|
28
|
+
const schema: Record<string, unknown> = {
|
|
29
|
+
// Auth tables (always active)
|
|
30
|
+
...authSchema,
|
|
31
|
+
// API key table (always active — needed for MCP auth)
|
|
32
|
+
...apikeySchema,
|
|
33
|
+
// Audit tables (always active)
|
|
34
|
+
auditLog,
|
|
35
|
+
recordAudits,
|
|
36
|
+
// Sequences table (always active)
|
|
37
|
+
sequences,
|
|
38
|
+
// Webhook dedup table (always active)
|
|
39
|
+
webhookDedup,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Organization (optional — better-auth organization plugin)
|
|
43
|
+
if (config?.organization) {
|
|
44
|
+
Object.assign(schema, organizationSchema);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Credentials (default: included)
|
|
48
|
+
if (config?.credentials !== false) {
|
|
49
|
+
schema.credentialsTable = credentialsTable;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Storage (Phase 2)
|
|
53
|
+
if (config?.storage) {
|
|
54
|
+
schema.storageObjects = storageObjects;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Notify (Phase 3)
|
|
58
|
+
if (config?.notify) {
|
|
59
|
+
schema.notifyLog = notifyLog;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return schema;
|
|
63
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Database } from 'bun:sqlite';
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
|
|
3
|
+
import { drizzle } from 'drizzle-orm/bun-sqlite';
|
|
4
|
+
|
|
5
|
+
import type { VobaseDb } from './db';
|
|
6
|
+
import * as schema from './modules/sequences/schema';
|
|
7
|
+
import { nextSequence } from './modules/sequences/next-sequence';
|
|
8
|
+
|
|
9
|
+
describe('nextSequence()', () => {
|
|
10
|
+
let sqlite: Database;
|
|
11
|
+
let db: VobaseDb;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
sqlite = new Database(':memory:');
|
|
15
|
+
sqlite.run('PRAGMA journal_mode=WAL');
|
|
16
|
+
sqlite.exec(`
|
|
17
|
+
CREATE TABLE _sequences (
|
|
18
|
+
id TEXT PRIMARY KEY,
|
|
19
|
+
prefix TEXT NOT NULL UNIQUE,
|
|
20
|
+
current_value INTEGER NOT NULL DEFAULT 0,
|
|
21
|
+
updated_at INTEGER NOT NULL
|
|
22
|
+
)
|
|
23
|
+
`);
|
|
24
|
+
|
|
25
|
+
db = drizzle({ client: sqlite, schema }) as unknown as VobaseDb;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
sqlite.close();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('returns gap-free numbers for same prefix', () => {
|
|
33
|
+
const values = Array.from({ length: 5 }, () => nextSequence(db, 'INV'));
|
|
34
|
+
expect(values).toEqual([
|
|
35
|
+
'INV-0001',
|
|
36
|
+
'INV-0002',
|
|
37
|
+
'INV-0003',
|
|
38
|
+
'INV-0004',
|
|
39
|
+
'INV-0005',
|
|
40
|
+
]);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('maintains independent counters per prefix', () => {
|
|
44
|
+
expect(nextSequence(db, 'INV')).toBe('INV-0001');
|
|
45
|
+
expect(nextSequence(db, 'ORD')).toBe('ORD-0001');
|
|
46
|
+
expect(nextSequence(db, 'INV')).toBe('INV-0002');
|
|
47
|
+
expect(nextSequence(db, 'ORD')).toBe('ORD-0002');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('formats sequence with year prefix when enabled', () => {
|
|
51
|
+
const year = new Date().getFullYear();
|
|
52
|
+
expect(nextSequence(db, 'INV', { yearPrefix: true })).toBe(
|
|
53
|
+
`INV-${year}-0001`,
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
});
|
package/dist/app.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { type HttpClientOptions } from './infra/http-client';
|
|
2
|
-
import { type AuthModuleConfig } from './modules/auth';
|
|
3
|
-
import { type NotifyModuleConfig } from './modules/notify';
|
|
4
|
-
import { type StorageModuleConfig } from './modules/storage';
|
|
5
|
-
import type { VobaseModule } from './module';
|
|
6
|
-
import { type WebhookConfig } from './infra/webhooks';
|
|
7
|
-
export interface CreateAppConfig {
|
|
8
|
-
modules: VobaseModule[];
|
|
9
|
-
database: string;
|
|
10
|
-
storage?: StorageModuleConfig;
|
|
11
|
-
notify?: NotifyModuleConfig;
|
|
12
|
-
http?: HttpClientOptions;
|
|
13
|
-
webhooks?: Record<string, WebhookConfig>;
|
|
14
|
-
mcp?: {
|
|
15
|
-
enabled?: boolean;
|
|
16
|
-
};
|
|
17
|
-
trustedOrigins?: string[];
|
|
18
|
-
auth?: Omit<AuthModuleConfig, 'trustedOrigins'>;
|
|
19
|
-
/** Enable the credentials module (encrypted credential store). Default: false */
|
|
20
|
-
credentials?: {
|
|
21
|
-
enabled: boolean;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
export declare function createApp(config: CreateAppConfig): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
25
|
-
"/health": {
|
|
26
|
-
$get: {
|
|
27
|
-
input: {};
|
|
28
|
-
output: {
|
|
29
|
-
status: string;
|
|
30
|
-
uptime: number;
|
|
31
|
-
};
|
|
32
|
-
outputFormat: "json";
|
|
33
|
-
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
}, "/", "/health">;
|
|
37
|
-
//# sourceMappingURL=app.d.ts.map
|
package/dist/app.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM/E,OAAO,EAA+C,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEpG,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAElF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAqC3E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAChD,iFAAiF;IACjF,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CACpC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe;;;;;;;;;;;;mBA0GhD"}
|
package/dist/contracts/auth.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core contract for authentication. The auth adapter translates an incoming
|
|
3
|
-
* request into a user identity. Core uses this in the session middleware
|
|
4
|
-
* to populate ctx.user. The built-in auth module implements this via
|
|
5
|
-
* better-auth; users can swap in their own implementation.
|
|
6
|
-
*/
|
|
7
|
-
export interface AuthAdapter {
|
|
8
|
-
/**
|
|
9
|
-
* Extract user identity from a request. Returns null if unauthenticated.
|
|
10
|
-
* Must not throw — return null for invalid/expired sessions.
|
|
11
|
-
*/
|
|
12
|
-
getSession(headers: Headers): Promise<AuthSession | null>;
|
|
13
|
-
/**
|
|
14
|
-
* The raw request handler for auth routes (sign-in, sign-up, etc.)
|
|
15
|
-
* Mounted at /api/auth/* by the auth module.
|
|
16
|
-
*/
|
|
17
|
-
handler: (request: Request) => Promise<Response>;
|
|
18
|
-
}
|
|
19
|
-
export interface AuthSession {
|
|
20
|
-
user: AuthUser;
|
|
21
|
-
session: {
|
|
22
|
-
id: string;
|
|
23
|
-
expiresAt: Date;
|
|
24
|
-
token: string;
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
export interface AuthUser {
|
|
28
|
-
id: string;
|
|
29
|
-
email: string;
|
|
30
|
-
name: string;
|
|
31
|
-
role: string;
|
|
32
|
-
/** Set when the user has an active organization (better-auth organization plugin) */
|
|
33
|
-
activeOrganizationId?: string;
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/contracts/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1D;;;OAGG;IACH,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,IAAI,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/contracts/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,QAAQ,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider interfaces for the notify module. Each channel (email, WhatsApp)
|
|
3
|
-
* has its own provider interface with channel-specific options.
|
|
4
|
-
*/
|
|
5
|
-
export interface EmailProvider {
|
|
6
|
-
send(message: EmailMessage): Promise<EmailResult>;
|
|
7
|
-
}
|
|
8
|
-
export interface EmailMessage {
|
|
9
|
-
to: string | string[];
|
|
10
|
-
subject: string;
|
|
11
|
-
html?: string;
|
|
12
|
-
text?: string;
|
|
13
|
-
from?: string;
|
|
14
|
-
cc?: string[];
|
|
15
|
-
bcc?: string[];
|
|
16
|
-
replyTo?: string;
|
|
17
|
-
attachments?: EmailAttachment[];
|
|
18
|
-
}
|
|
19
|
-
export interface EmailAttachment {
|
|
20
|
-
filename: string;
|
|
21
|
-
content: Buffer | Uint8Array;
|
|
22
|
-
contentType?: string;
|
|
23
|
-
}
|
|
24
|
-
export interface EmailResult {
|
|
25
|
-
success: boolean;
|
|
26
|
-
messageId?: string;
|
|
27
|
-
error?: string;
|
|
28
|
-
}
|
|
29
|
-
export interface WhatsAppProvider {
|
|
30
|
-
send(message: WhatsAppMessage): Promise<WhatsAppResult>;
|
|
31
|
-
}
|
|
32
|
-
export interface WhatsAppMessage {
|
|
33
|
-
to: string;
|
|
34
|
-
template?: {
|
|
35
|
-
name: string;
|
|
36
|
-
language: string;
|
|
37
|
-
parameters?: string[];
|
|
38
|
-
};
|
|
39
|
-
text?: string;
|
|
40
|
-
}
|
|
41
|
-
export interface WhatsAppResult {
|
|
42
|
-
success: boolean;
|
|
43
|
-
messageId?: string;
|
|
44
|
-
error?: string;
|
|
45
|
-
}
|
|
46
|
-
//# sourceMappingURL=notify.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/contracts/notify.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/contracts/permissions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B"}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider interface for storage backends. Each provider implements
|
|
3
|
-
* the physical operations; the storage module handles bucket resolution,
|
|
4
|
-
* metadata tracking, and access control on top.
|
|
5
|
-
*/
|
|
6
|
-
export interface StorageProvider {
|
|
7
|
-
upload(fullKey: string, data: Buffer | Uint8Array, opts?: UploadOptions): Promise<void>;
|
|
8
|
-
download(fullKey: string): Promise<Uint8Array>;
|
|
9
|
-
delete(fullKey: string): Promise<void>;
|
|
10
|
-
exists(fullKey: string): Promise<boolean>;
|
|
11
|
-
presign(fullKey: string, opts: PresignOptions): string;
|
|
12
|
-
list(prefix: string, opts?: ListOptions): Promise<StorageListResult>;
|
|
13
|
-
}
|
|
14
|
-
export interface UploadOptions {
|
|
15
|
-
contentType?: string;
|
|
16
|
-
metadata?: Record<string, string>;
|
|
17
|
-
/** Max upload size in bytes. Enforced server-side for direct uploads. */
|
|
18
|
-
maxSize?: number;
|
|
19
|
-
}
|
|
20
|
-
export interface PresignOptions {
|
|
21
|
-
expiresIn?: number;
|
|
22
|
-
method?: 'GET' | 'PUT';
|
|
23
|
-
}
|
|
24
|
-
export interface ListOptions {
|
|
25
|
-
cursor?: string;
|
|
26
|
-
limit?: number;
|
|
27
|
-
}
|
|
28
|
-
export interface StorageListResult {
|
|
29
|
-
objects: StorageObjectInfo[];
|
|
30
|
-
cursor?: string;
|
|
31
|
-
}
|
|
32
|
-
export interface StorageObjectInfo {
|
|
33
|
-
key: string;
|
|
34
|
-
size: number;
|
|
35
|
-
contentType: string;
|
|
36
|
-
lastModified: Date;
|
|
37
|
-
}
|
|
38
|
-
/** Local filesystem provider */
|
|
39
|
-
export interface LocalProviderConfig {
|
|
40
|
-
type: 'local';
|
|
41
|
-
basePath: string;
|
|
42
|
-
baseUrl?: string;
|
|
43
|
-
}
|
|
44
|
-
/** S3-compatible provider (AWS, R2, MinIO) using Bun native S3 */
|
|
45
|
-
export interface S3ProviderConfig {
|
|
46
|
-
type: 's3';
|
|
47
|
-
bucket: string;
|
|
48
|
-
region?: string;
|
|
49
|
-
endpoint?: string;
|
|
50
|
-
accessKeyId: string;
|
|
51
|
-
secretAccessKey: string;
|
|
52
|
-
}
|
|
53
|
-
export type StorageProviderConfig = LocalProviderConfig | S3ProviderConfig;
|
|
54
|
-
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/contracts/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAAC;IACvD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,IAAI,CAAC;CACpB;AAED,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,qBAAqB,GAAG,mBAAmB,GAAG,gBAAgB,CAAC"}
|
package/dist/ctx.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { Context } from 'hono';
|
|
2
|
-
import type { VobaseDb } from './db';
|
|
3
|
-
import type { HttpClient } from './infra/http-client';
|
|
4
|
-
import type { Scheduler } from './infra/queue';
|
|
5
|
-
import type { NotifyService } from './modules/notify/service';
|
|
6
|
-
import type { StorageService } from './modules/storage/service';
|
|
7
|
-
export interface VobaseUser {
|
|
8
|
-
id: string;
|
|
9
|
-
email: string;
|
|
10
|
-
name: string;
|
|
11
|
-
role: string;
|
|
12
|
-
/** Set when the user has an active organization (better-auth organization plugin) */
|
|
13
|
-
activeOrganizationId?: string;
|
|
14
|
-
}
|
|
15
|
-
export interface VobaseCtx {
|
|
16
|
-
db: VobaseDb;
|
|
17
|
-
user: VobaseUser | null;
|
|
18
|
-
scheduler: Scheduler;
|
|
19
|
-
storage: StorageService;
|
|
20
|
-
notify: NotifyService;
|
|
21
|
-
http: HttpClient;
|
|
22
|
-
}
|
|
23
|
-
declare module 'hono' {
|
|
24
|
-
interface ContextVariableMap {
|
|
25
|
-
db: VobaseDb;
|
|
26
|
-
scheduler: Scheduler;
|
|
27
|
-
storage: StorageService;
|
|
28
|
-
notify: NotifyService;
|
|
29
|
-
http: HttpClient;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export declare function contextMiddleware(deps: {
|
|
33
|
-
db: VobaseDb;
|
|
34
|
-
scheduler: Scheduler;
|
|
35
|
-
storage: StorageService;
|
|
36
|
-
notify: NotifyService;
|
|
37
|
-
http: HttpClient;
|
|
38
|
-
}): import("hono").MiddlewareHandler<any, string, {}, Response>;
|
|
39
|
-
export declare function getCtx(c: Context): VobaseCtx;
|
|
40
|
-
//# sourceMappingURL=ctx.d.ts.map
|
package/dist/ctx.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ctx.d.ts","sourceRoot":"","sources":["../src/ctx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,QAAQ,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,EAAE,EAAE,QAAQ,CAAC;QACb,SAAS,EAAE,SAAS,CAAC;QACrB,OAAO,EAAE,cAAc,CAAC;QACxB,MAAM,EAAE,aAAa,CAAC;QACtB,IAAI,EAAE,UAAU,CAAC;KAClB;CACF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,EAAE,EAAE,QAAQ,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,UAAU,CAAC;CAClB,+DASA;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,CAS5C"}
|
package/dist/db/client.d.ts
DELETED
package/dist/db/client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAElD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CASvD"}
|