@getstrata/core 2.1.0 → 2.2.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.
- package/CHANGELOG.md +40 -0
- package/dist/core/cache/createCacheStore.d.ts +3 -1
- package/dist/core/cache/redisCacheStore.d.ts +21 -8
- package/dist/core/cache/repository.d.ts +3 -2
- package/dist/core/cache/store.d.ts +4 -1
- package/dist/core/cache/taggedCache.d.ts +1 -1
- package/dist/core/contracts/di.d.ts +4 -2
- package/dist/core/contracts/serviceTokens.d.ts +7 -1
- package/dist/core/database/baseRepository.d.ts +0 -1
- package/dist/core/database/index.d.ts +1 -1
- package/dist/core/database/model.d.ts +51 -22
- package/dist/core/database/repositoryQuery.d.ts +16 -1
- package/dist/core/database/types.d.ts +25 -2
- package/dist/core/database/whereBuilder.d.ts +5 -5
- package/dist/core/events/deferredModelEvents.d.ts +2 -1
- package/dist/core/http/loginThrottleMiddleware.d.ts +6 -5
- package/dist/core/http/memoryThrottleMiddleware.d.ts +11 -3
- package/dist/core/http/requestMetaContext.d.ts +2 -0
- package/dist/core/http/scimThrottleMiddleware.d.ts +12 -3
- package/dist/core/http/throttleMiddleware.d.ts +24 -6
- package/dist/core/lifecycle/gracefulShutdown.d.ts +33 -5
- package/dist/core/queue/createAppQueue.d.ts +2 -1
- package/dist/core/queue/failedJobService.d.ts +3 -1
- package/dist/core/queue/index.d.ts +17 -2
- package/dist/core/queue/jobRunner.d.ts +7 -1
- package/dist/core/queue/publicQueue.d.ts +2 -1
- package/dist/core/queue/queueConfig.d.ts +3 -0
- package/dist/core/queue/redisQueue.d.ts +6 -7
- package/dist/core/queue/redisQueueKeys.d.ts +8 -0
- package/dist/core/queue/redisStreams.d.ts +73 -0
- package/dist/core/queue/resilientQueue.d.ts +2 -2
- package/dist/core/queue/types.d.ts +1 -0
- package/dist/core/runtime/applicationRegistry.d.ts +2 -1
- package/dist/core/runtime/boundedThrottleStore.d.ts +29 -0
- package/dist/core/scheduler/leases.d.ts +40 -0
- package/dist/core/scheduler/schedule.d.ts +29 -5
- package/dist/core/tenant/publicTenantHost.d.ts +11 -0
- package/dist/core/tenant/tenantContext.d.ts +5 -4
- package/dist/core/tenant/tenantMiddleware.d.ts +11 -1
- package/dist/core/tracing/otel.d.ts +28 -26
- package/dist/core/tracing/tracingMiddleware.d.ts +4 -1
- package/dist/entries/audit/exportAuditLogs.js +14 -2
- package/dist/entries/auth/basicAuthGuard.js +81 -0
- package/dist/entries/auth/jwtGuard.js +81 -0
- package/dist/entries/auth/scimAuthMiddleware.js +17 -7
- package/dist/entries/auth/sessionGuard.js +81 -0
- package/dist/entries/cache/createCacheStore.js +365 -119
- package/dist/entries/cache/repository.js +5 -0
- package/dist/entries/contracts/serviceTokens.js +85 -0
- package/dist/entries/database/factory.js +0 -3
- package/dist/entries/database/model.js +1 -2486
- package/dist/entries/database/repositoryQuery.js +67 -9
- package/dist/entries/http/bodySizeLimitMiddleware.js +76 -10
- package/dist/entries/http/memoryThrottleMiddleware.js +276 -21
- package/dist/entries/http/scimThrottleMiddleware.js +576 -54
- package/dist/entries/http/throttleMiddleware.js +65 -16
- package/dist/entries/jobs/exportAuditLogsJob.js +44 -7
- package/dist/entries/jobs/invalidateCacheTagsJob.js +30 -5
- package/dist/entries/queue/createAppQueue.js +748 -72
- package/dist/entries/queue/failedJobRepository.js +1 -1
- package/dist/entries/queue/failedJobService.js +5 -1
- package/dist/entries/queue/jobRunner.js +67 -2
- package/dist/entries/queue/publicQueue.js +746 -71
- package/dist/entries/queue/queueMetrics.js +761 -78
- package/dist/entries/queue/redisQueue.js +768 -148
- package/dist/entries/queue.js +30 -5
- package/dist/entries/scheduler/schedule.js +1 -72
- package/dist/entries/tenant/databaseTenantContext.js +14 -2
- package/dist/entries/tenant/tenantDatabaseScope.js +14 -2
- package/dist/entries/tracing/tracingMiddleware.js +186 -454
- package/dist/framework/public-api.d.ts +14 -10
- package/dist/index.js +2444 -688
- package/dist/types/services.d.ts +3 -3
- package/package.json +17 -8
|
@@ -300,7 +300,88 @@ var init_dialect = __esm(() => {
|
|
|
300
300
|
dialectContext = createAsyncContextStore("@getstrata/sqlDialect");
|
|
301
301
|
});
|
|
302
302
|
|
|
303
|
+
// ../../src/core/contracts/container.ts
|
|
304
|
+
function createServiceToken(key) {
|
|
305
|
+
if (!key.trim())
|
|
306
|
+
throw new Error("Service token key must not be empty.");
|
|
307
|
+
return key;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
class ServiceContainer {
|
|
311
|
+
services = new Map;
|
|
312
|
+
singletonFactories = new Map;
|
|
313
|
+
bindings = new Map;
|
|
314
|
+
set(key, value) {
|
|
315
|
+
this.singletonFactories.delete(key);
|
|
316
|
+
this.bindings.delete(key);
|
|
317
|
+
this.services.set(key, value);
|
|
318
|
+
return value;
|
|
319
|
+
}
|
|
320
|
+
singleton(key, factory) {
|
|
321
|
+
this.bindings.delete(key);
|
|
322
|
+
this.services.delete(key);
|
|
323
|
+
this.singletonFactories.set(key, factory);
|
|
324
|
+
}
|
|
325
|
+
bind(key, factory) {
|
|
326
|
+
this.singletonFactories.delete(key);
|
|
327
|
+
this.services.delete(key);
|
|
328
|
+
this.bindings.set(key, factory);
|
|
329
|
+
}
|
|
330
|
+
get(key) {
|
|
331
|
+
if (this.services.has(key)) {
|
|
332
|
+
return this.services.get(key);
|
|
333
|
+
}
|
|
334
|
+
const singletonFactory = this.singletonFactories.get(key);
|
|
335
|
+
if (singletonFactory) {
|
|
336
|
+
const value = singletonFactory(this);
|
|
337
|
+
this.services.set(key, value);
|
|
338
|
+
return value;
|
|
339
|
+
}
|
|
340
|
+
const binding = this.bindings.get(key);
|
|
341
|
+
if (binding) {
|
|
342
|
+
return binding(this);
|
|
343
|
+
}
|
|
344
|
+
throw new Error(`Service "${key}" is not registered.`);
|
|
345
|
+
}
|
|
346
|
+
resolve(key) {
|
|
347
|
+
return this.get(key);
|
|
348
|
+
}
|
|
349
|
+
make(key) {
|
|
350
|
+
return this.resolve(key);
|
|
351
|
+
}
|
|
352
|
+
instance(key, value) {
|
|
353
|
+
return this.set(key, value);
|
|
354
|
+
}
|
|
355
|
+
has(key) {
|
|
356
|
+
return this.services.has(key) || this.singletonFactories.has(key) || this.bindings.has(key);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
class ConfigStore {
|
|
361
|
+
values = new Map;
|
|
362
|
+
set(key, value) {
|
|
363
|
+
this.values.set(key, value);
|
|
364
|
+
return value;
|
|
365
|
+
}
|
|
366
|
+
get(key) {
|
|
367
|
+
return this.values.get(key);
|
|
368
|
+
}
|
|
369
|
+
require(key) {
|
|
370
|
+
if (!this.values.has(key)) {
|
|
371
|
+
throw new Error(`Config key "${key}" is not defined.`);
|
|
372
|
+
}
|
|
373
|
+
return this.values.get(key);
|
|
374
|
+
}
|
|
375
|
+
has(key) {
|
|
376
|
+
return this.values.has(key);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
303
380
|
// ../../src/core/contracts/serviceTokens.ts
|
|
381
|
+
var CORE_THROTTLE_QUOTA_POLICY_TOKEN = createServiceToken("core.throttleQuotaPolicy");
|
|
382
|
+
var CORE_PUBLIC_TENANCY_TOKEN = createServiceToken("core.publicTenancy");
|
|
383
|
+
var CORE_TENANT_RESOLVER_TOKEN = createServiceToken("core.tenantResolver");
|
|
384
|
+
var CORE_HTTP_CLEANUP_TOKEN = createServiceToken("core.httpCleanup");
|
|
304
385
|
var CORE_CONFIG_TOKEN = "core.config";
|
|
305
386
|
var CORE_CACHE_TOKEN = "core.cache";
|
|
306
387
|
var CORE_QUEUE_TOKEN = "core.queue";
|
|
@@ -1,5 +1,86 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// ../../src/core/contracts/container.ts
|
|
3
|
+
function createServiceToken(key) {
|
|
4
|
+
if (!key.trim())
|
|
5
|
+
throw new Error("Service token key must not be empty.");
|
|
6
|
+
return key;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class ServiceContainer {
|
|
10
|
+
services = new Map;
|
|
11
|
+
singletonFactories = new Map;
|
|
12
|
+
bindings = new Map;
|
|
13
|
+
set(key, value) {
|
|
14
|
+
this.singletonFactories.delete(key);
|
|
15
|
+
this.bindings.delete(key);
|
|
16
|
+
this.services.set(key, value);
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
singleton(key, factory) {
|
|
20
|
+
this.bindings.delete(key);
|
|
21
|
+
this.services.delete(key);
|
|
22
|
+
this.singletonFactories.set(key, factory);
|
|
23
|
+
}
|
|
24
|
+
bind(key, factory) {
|
|
25
|
+
this.singletonFactories.delete(key);
|
|
26
|
+
this.services.delete(key);
|
|
27
|
+
this.bindings.set(key, factory);
|
|
28
|
+
}
|
|
29
|
+
get(key) {
|
|
30
|
+
if (this.services.has(key)) {
|
|
31
|
+
return this.services.get(key);
|
|
32
|
+
}
|
|
33
|
+
const singletonFactory = this.singletonFactories.get(key);
|
|
34
|
+
if (singletonFactory) {
|
|
35
|
+
const value = singletonFactory(this);
|
|
36
|
+
this.services.set(key, value);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
const binding = this.bindings.get(key);
|
|
40
|
+
if (binding) {
|
|
41
|
+
return binding(this);
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Service "${key}" is not registered.`);
|
|
44
|
+
}
|
|
45
|
+
resolve(key) {
|
|
46
|
+
return this.get(key);
|
|
47
|
+
}
|
|
48
|
+
make(key) {
|
|
49
|
+
return this.resolve(key);
|
|
50
|
+
}
|
|
51
|
+
instance(key, value) {
|
|
52
|
+
return this.set(key, value);
|
|
53
|
+
}
|
|
54
|
+
has(key) {
|
|
55
|
+
return this.services.has(key) || this.singletonFactories.has(key) || this.bindings.has(key);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
class ConfigStore {
|
|
60
|
+
values = new Map;
|
|
61
|
+
set(key, value) {
|
|
62
|
+
this.values.set(key, value);
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
get(key) {
|
|
66
|
+
return this.values.get(key);
|
|
67
|
+
}
|
|
68
|
+
require(key) {
|
|
69
|
+
if (!this.values.has(key)) {
|
|
70
|
+
throw new Error(`Config key "${key}" is not defined.`);
|
|
71
|
+
}
|
|
72
|
+
return this.values.get(key);
|
|
73
|
+
}
|
|
74
|
+
has(key) {
|
|
75
|
+
return this.values.has(key);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
2
79
|
// ../../src/core/contracts/serviceTokens.ts
|
|
80
|
+
var CORE_THROTTLE_QUOTA_POLICY_TOKEN = createServiceToken("core.throttleQuotaPolicy");
|
|
81
|
+
var CORE_PUBLIC_TENANCY_TOKEN = createServiceToken("core.publicTenancy");
|
|
82
|
+
var CORE_TENANT_RESOLVER_TOKEN = createServiceToken("core.tenantResolver");
|
|
83
|
+
var CORE_HTTP_CLEANUP_TOKEN = createServiceToken("core.httpCleanup");
|
|
3
84
|
var CORE_CONFIG_TOKEN = "core.config";
|
|
4
85
|
var CORE_CACHE_TOKEN = "core.cache";
|
|
5
86
|
var CORE_QUEUE_TOKEN = "core.queue";
|
|
@@ -262,9 +262,12 @@ async function runWithDeferredModelEvents(callback) {
|
|
|
262
262
|
const existing = deferredModelEvents.getStore();
|
|
263
263
|
if (existing) {
|
|
264
264
|
existing.frames.push([]);
|
|
265
|
+
existing.rollbackFrames.push([]);
|
|
265
266
|
try {
|
|
266
267
|
const result = await callback();
|
|
267
268
|
const nested = existing.frames.pop() ?? [];
|
|
269
|
+
const rollback = existing.rollbackFrames.pop() ?? [];
|
|
270
|
+
existing.rollbackFrames.at(-1)?.push(...rollback);
|
|
268
271
|
const parent = existing.frames[existing.frames.length - 1];
|
|
269
272
|
if (parent) {
|
|
270
273
|
parent.push(...nested);
|
|
@@ -272,11 +275,20 @@ async function runWithDeferredModelEvents(callback) {
|
|
|
272
275
|
return result;
|
|
273
276
|
} catch (error) {
|
|
274
277
|
existing.frames.pop();
|
|
278
|
+
for (const rollback of (existing.rollbackFrames.pop() ?? []).reverse())
|
|
279
|
+
rollback();
|
|
275
280
|
throw error;
|
|
276
281
|
}
|
|
277
282
|
}
|
|
278
|
-
const state = { frames: [[]] };
|
|
279
|
-
|
|
283
|
+
const state = { frames: [[]], rollbackFrames: [[]] };
|
|
284
|
+
let result;
|
|
285
|
+
try {
|
|
286
|
+
result = await deferredModelEvents.run(state, callback);
|
|
287
|
+
} catch (error) {
|
|
288
|
+
for (const rollback of (state.rollbackFrames[0] ?? []).reverse())
|
|
289
|
+
rollback();
|
|
290
|
+
throw error;
|
|
291
|
+
}
|
|
280
292
|
await dispatchQueuedModelEvents(state.frames[0] ?? []);
|
|
281
293
|
return result;
|
|
282
294
|
}
|
|
@@ -849,19 +861,17 @@ async function resolveTenant(tenantId) {
|
|
|
849
861
|
if (!isTenancyEnabled()) {
|
|
850
862
|
return {
|
|
851
863
|
id: tenantId,
|
|
852
|
-
slug: "default"
|
|
853
|
-
plan: "free",
|
|
854
|
-
region: "eu"
|
|
864
|
+
slug: "default"
|
|
855
865
|
};
|
|
856
866
|
}
|
|
857
867
|
const rows = await db`
|
|
858
|
-
SELECT id, slug
|
|
868
|
+
SELECT id, slug
|
|
859
869
|
FROM tenant
|
|
860
870
|
WHERE id = ${tenantId}
|
|
861
871
|
LIMIT 1
|
|
862
872
|
`;
|
|
863
873
|
const row = rows[0];
|
|
864
|
-
return row ? { id: row.id, slug: row.slug
|
|
874
|
+
return row ? { id: row.id, slug: row.slug } : null;
|
|
865
875
|
}
|
|
866
876
|
|
|
867
877
|
// ../../src/core/auth/scimAuthMiddleware.ts
|
|
@@ -1,5 +1,86 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// ../../src/core/contracts/container.ts
|
|
3
|
+
function createServiceToken(key) {
|
|
4
|
+
if (!key.trim())
|
|
5
|
+
throw new Error("Service token key must not be empty.");
|
|
6
|
+
return key;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class ServiceContainer {
|
|
10
|
+
services = new Map;
|
|
11
|
+
singletonFactories = new Map;
|
|
12
|
+
bindings = new Map;
|
|
13
|
+
set(key, value) {
|
|
14
|
+
this.singletonFactories.delete(key);
|
|
15
|
+
this.bindings.delete(key);
|
|
16
|
+
this.services.set(key, value);
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
singleton(key, factory) {
|
|
20
|
+
this.bindings.delete(key);
|
|
21
|
+
this.services.delete(key);
|
|
22
|
+
this.singletonFactories.set(key, factory);
|
|
23
|
+
}
|
|
24
|
+
bind(key, factory) {
|
|
25
|
+
this.singletonFactories.delete(key);
|
|
26
|
+
this.services.delete(key);
|
|
27
|
+
this.bindings.set(key, factory);
|
|
28
|
+
}
|
|
29
|
+
get(key) {
|
|
30
|
+
if (this.services.has(key)) {
|
|
31
|
+
return this.services.get(key);
|
|
32
|
+
}
|
|
33
|
+
const singletonFactory = this.singletonFactories.get(key);
|
|
34
|
+
if (singletonFactory) {
|
|
35
|
+
const value = singletonFactory(this);
|
|
36
|
+
this.services.set(key, value);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
const binding = this.bindings.get(key);
|
|
40
|
+
if (binding) {
|
|
41
|
+
return binding(this);
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Service "${key}" is not registered.`);
|
|
44
|
+
}
|
|
45
|
+
resolve(key) {
|
|
46
|
+
return this.get(key);
|
|
47
|
+
}
|
|
48
|
+
make(key) {
|
|
49
|
+
return this.resolve(key);
|
|
50
|
+
}
|
|
51
|
+
instance(key, value) {
|
|
52
|
+
return this.set(key, value);
|
|
53
|
+
}
|
|
54
|
+
has(key) {
|
|
55
|
+
return this.services.has(key) || this.singletonFactories.has(key) || this.bindings.has(key);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
class ConfigStore {
|
|
60
|
+
values = new Map;
|
|
61
|
+
set(key, value) {
|
|
62
|
+
this.values.set(key, value);
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
get(key) {
|
|
66
|
+
return this.values.get(key);
|
|
67
|
+
}
|
|
68
|
+
require(key) {
|
|
69
|
+
if (!this.values.has(key)) {
|
|
70
|
+
throw new Error(`Config key "${key}" is not defined.`);
|
|
71
|
+
}
|
|
72
|
+
return this.values.get(key);
|
|
73
|
+
}
|
|
74
|
+
has(key) {
|
|
75
|
+
return this.values.has(key);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
2
79
|
// ../../src/core/contracts/serviceTokens.ts
|
|
80
|
+
var CORE_THROTTLE_QUOTA_POLICY_TOKEN = createServiceToken("core.throttleQuotaPolicy");
|
|
81
|
+
var CORE_PUBLIC_TENANCY_TOKEN = createServiceToken("core.publicTenancy");
|
|
82
|
+
var CORE_TENANT_RESOLVER_TOKEN = createServiceToken("core.tenantResolver");
|
|
83
|
+
var CORE_HTTP_CLEANUP_TOKEN = createServiceToken("core.httpCleanup");
|
|
3
84
|
var CORE_CONFIG_TOKEN = "core.config";
|
|
4
85
|
var CORE_CACHE_TOKEN = "core.cache";
|
|
5
86
|
var CORE_QUEUE_TOKEN = "core.queue";
|