@getstrata/bootstrap 0.2.12 → 0.2.16

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.
@@ -349,7 +349,6 @@ var invalidateCacheTagsJob_default = InvalidateCacheTagsJob;
349
349
 
350
350
  // ../../src/core/queue/jobRegistry.ts
351
351
  class JobRegistry {
352
- constructor() {}
353
352
  factories = new Map;
354
353
  instances = new WeakMap;
355
354
  register(name, factory) {
@@ -373,7 +372,34 @@ class JobRegistry {
373
372
  return [...this.factories.keys()];
374
373
  }
375
374
  }
376
- var jobRegistry = new JobRegistry;
375
+ var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
376
+ function readSharedJobRegistry() {
377
+ const globalRegistry = globalThis[JOB_REGISTRY_KEY];
378
+ if (globalRegistry) {
379
+ return globalRegistry;
380
+ }
381
+ const registry = new JobRegistry;
382
+ globalThis[JOB_REGISTRY_KEY] = registry;
383
+ return registry;
384
+ }
385
+ var jobRegistry = readSharedJobRegistry();
386
+
387
+ // ../../src/core/contracts/applicationContext.ts
388
+ function getRequiredDependency(dependencies, key) {
389
+ const dependency = dependencies[key];
390
+ if (dependency === undefined) {
391
+ throw new Error(`Required dependency "${String(key)}" is not registered.`);
392
+ }
393
+ return dependency;
394
+ }
395
+
396
+ // ../../src/core/contracts/serviceTokens.ts
397
+ var CORE_CONFIG_TOKEN = "core.config";
398
+ var CORE_CACHE_TOKEN = "core.cache";
399
+ var CORE_QUEUE_TOKEN = "core.queue";
400
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
401
+ var CORE_AUTH_TOKEN = "core.auth";
402
+ var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
377
403
 
378
404
  // ../../src/core/logging/logger.ts
379
405
  class Logger {
@@ -411,113 +437,7 @@ class Logger {
411
437
  }
412
438
  var appLogger = new Logger("app");
413
439
 
414
- // ../../src/bootstrap/config.ts
415
- var APP_PORT_CONFIG_KEY = "app.port";
416
- var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
417
- var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
418
- var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
419
- var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
420
- var DATABASE_URL_CONFIG_KEY = "database.url";
421
- var CORE_CONFIG_TOKEN = "core.config";
422
- var CORE_CACHE_TOKEN = "core.cache";
423
- var CORE_QUEUE_TOKEN = "core.queue";
424
- var CORE_POLICY_GATE_TOKEN = "core.policyGate";
425
- var CORE_AUTH_TOKEN = "core.auth";
426
- var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
427
- var AUTH_DEV_HEADERS_CONFIG_KEY = "auth.allowDevHeaders";
428
- var DEFAULT_APP_PORT = 3000;
429
- var DEFAULT_CACHE_TTL_MS = 3600000;
430
- var DEFAULT_CACHE_MAX_ENTRIES = 100;
431
- var DEFAULT_CACHE_DRIVER = "array";
432
- var DEFAULT_API_TOKEN = "";
433
- var DEFAULT_QUEUE_DRIVER = "sync";
434
-
435
- // ../../src/bootstrap/contracts.ts
436
- class ServiceContainer {
437
- services = new Map;
438
- singletonFactories = new Map;
439
- bindings = new Map;
440
- set(key, value) {
441
- this.singletonFactories.delete(key);
442
- this.bindings.delete(key);
443
- this.services.set(key, value);
444
- return value;
445
- }
446
- singleton(key, factory) {
447
- this.bindings.delete(key);
448
- this.services.delete(key);
449
- this.singletonFactories.set(key, factory);
450
- }
451
- bind(key, factory) {
452
- this.singletonFactories.delete(key);
453
- this.services.delete(key);
454
- this.bindings.set(key, factory);
455
- }
456
- get(key) {
457
- if (this.services.has(key)) {
458
- return this.services.get(key);
459
- }
460
- const singletonFactory = this.singletonFactories.get(key);
461
- if (singletonFactory) {
462
- const value = singletonFactory(this);
463
- this.services.set(key, value);
464
- return value;
465
- }
466
- const binding = this.bindings.get(key);
467
- if (binding) {
468
- return binding(this);
469
- }
470
- throw new Error(`Service "${key}" is not registered.`);
471
- }
472
- resolve(key) {
473
- return this.get(key);
474
- }
475
- has(key) {
476
- return this.services.has(key) || this.singletonFactories.has(key) || this.bindings.has(key);
477
- }
478
- }
479
-
480
- class ConfigStore {
481
- values = new Map;
482
- set(key, value) {
483
- this.values.set(key, value);
484
- return value;
485
- }
486
- get(key) {
487
- return this.values.get(key);
488
- }
489
- require(key) {
490
- if (!this.values.has(key)) {
491
- throw new Error(`Config key "${key}" is not defined.`);
492
- }
493
- return this.values.get(key);
494
- }
495
- has(key) {
496
- return this.values.has(key);
497
- }
498
- }
499
- var requiredDependencyKeys = [
500
- "container",
501
- "cache",
502
- "storage"
503
- ];
504
- function getRequiredDependency(dependencies, key) {
505
- const dependency = dependencies[key];
506
- if (dependency === undefined) {
507
- throw new Error(`Required dependency "${key}" is not registered.`);
508
- }
509
- return dependency;
510
- }
511
- function assertAppDependenciesComplete(dependencies) {
512
- for (const key of requiredDependencyKeys) {
513
- getRequiredDependency(dependencies, key);
514
- }
515
- }
516
- function resolveService(dependencies, token) {
517
- return dependencies.container.resolve(token);
518
- }
519
-
520
- // ../../src/bootstrap/applicationRegistry.ts
440
+ // ../../src/core/runtime/applicationRegistry.ts
521
441
  var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
522
442
  var activeContext;
523
443
  function readStoredApplicationContext() {
@@ -2,7 +2,6 @@
2
2
  * Stable framework surface for application modules and future package extraction.
3
3
  * Import from `@getstrata/core` (workspace) or `src/framework/public-api`.
4
4
  */
5
- export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "../bootstrap/applicationRegistry.ts";
6
5
  export type { ServiceProvider } from "../bootstrap/contracts.ts";
7
6
  export { ConfigStore, resolveService, ServiceContainer, } from "../bootstrap/contracts.ts";
8
7
  export type { AdminColumn, AdminColumnType, AdminResource, AdminResourceDefinition, AdminResourceHandlers, } from "../core/admin/index.ts";
@@ -20,7 +19,6 @@ export { default as MembershipService, resolveMembershipService, } from "../core
20
19
  export { Policy, PolicyGate } from "../core/auth/policy.ts";
21
20
  export { createScimAuthMiddleware } from "../core/auth/scimAuthMiddleware.ts";
22
21
  export { type CacheDriver, type CreateCacheStoreOptions, createCacheStore, } from "../core/cache/createCacheStore.ts";
23
- export { cacheTagsForModelWrite, discoverModelTableNames } from "../core/cache/modelCacheTags.ts";
24
22
  export { default as CacheRepository } from "../core/cache/repository.ts";
25
23
  export { CACHE_TAGS } from "../core/cache/tags.ts";
26
24
  export type { DatabaseConnection } from "../core/database/baseRepository.ts";
@@ -96,6 +94,7 @@ export { AsyncQueue, createQueue, Job, SyncQueue } from "../core/queue/index.ts"
96
94
  export { createFailedJobService, createProductionQueue, createQueueWorker, createTrackedJob, FailedJobRepository, FailedJobService, jobRegistry, QueueWorker, RedisQueue, ResilientQueue, runQueueJob, } from "../core/queue/publicQueue.ts";
97
95
  export type { QueueMetricsSnapshot } from "../core/queue/queueMetrics.ts";
98
96
  export { collectQueueMetrics } from "../core/queue/queueMetrics.ts";
97
+ export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "../core/runtime/applicationRegistry.ts";
99
98
  export type { ScheduledTask } from "../core/scheduler/schedule.ts";
100
99
  export { appSchedule, runDueScheduledTasks, Schedule } from "../core/scheduler/schedule.ts";
101
100
  export { guestCanViewResource, isPublicReadsEnabled } from "../core/security/publicReads.ts";
package/dist/index.js CHANGED
@@ -503,6 +503,85 @@ async function scheduleRunCommand() {
503
503
  }
504
504
  await runDueScheduledTasks(appSchedule);
505
505
  }
506
+ // ../../src/core/contracts/applicationContext.ts
507
+ function getRequiredDependency(dependencies, key) {
508
+ const dependency = dependencies[key];
509
+ if (dependency === undefined) {
510
+ throw new Error(`Required dependency "${String(key)}" is not registered.`);
511
+ }
512
+ return dependency;
513
+ }
514
+
515
+ // ../../src/core/contracts/serviceTokens.ts
516
+ var CORE_CONFIG_TOKEN = "core.config";
517
+ var CORE_CACHE_TOKEN = "core.cache";
518
+ var CORE_QUEUE_TOKEN = "core.queue";
519
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
520
+ var CORE_AUTH_TOKEN = "core.auth";
521
+ var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
522
+
523
+ // ../../src/core/runtime/applicationRegistry.ts
524
+ var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
525
+ var activeContext;
526
+ function readStoredApplicationContext() {
527
+ if (activeContext) {
528
+ return activeContext;
529
+ }
530
+ const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
531
+ if (globalContext) {
532
+ activeContext = globalContext;
533
+ }
534
+ return activeContext;
535
+ }
536
+ function setActiveApplicationContext(context) {
537
+ activeContext = context;
538
+ globalThis[APPLICATION_CONTEXT_KEY] = context;
539
+ }
540
+ function requireActiveApplicationContext() {
541
+ const context = readStoredApplicationContext();
542
+ if (!context) {
543
+ throw new Error("The application context has not been bootstrapped.");
544
+ }
545
+ return context;
546
+ }
547
+ function resolveApplicationCache() {
548
+ return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
549
+ }
550
+ function resolveApplicationQueue() {
551
+ return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
552
+ }
553
+ function resolveApplicationAuth() {
554
+ return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
555
+ }
556
+ function resolveApplicationPolicyGate() {
557
+ return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
558
+ }
559
+ function resolveApplicationConfig() {
560
+ return requireActiveApplicationContext().config;
561
+ }
562
+ function resolveApplicationLogger() {
563
+ return appLogger;
564
+ }
565
+ function resolveApplicationDependencies() {
566
+ return requireActiveApplicationContext().dependencies;
567
+ }
568
+ // ../../src/bootstrap/discoverModules.ts
569
+ var appModules = [];
570
+ function discoverModules() {
571
+ return appModules;
572
+ }
573
+
574
+ // ../../src/bootstrap/cache/modelCacheTags.ts
575
+ function cacheTagsForModelWrite(tableName, action) {
576
+ const module = discoverModules().find((entry) => entry.tableName === tableName);
577
+ const baseTags = module?.cacheTags ?? [`${tableName}s`];
578
+ const isDelete = action === "deleted" || action === "force-deleted";
579
+ const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
580
+ return [...new Set([...baseTags, ...extraTags])];
581
+ }
582
+ function discoverModelTableNames() {
583
+ return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
584
+ }
506
585
  // ../../src/bootstrap/config.ts
507
586
  var APP_PORT_CONFIG_KEY = "app.port";
508
587
  var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
@@ -510,19 +589,12 @@ var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
510
589
  var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
511
590
  var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
512
591
  var DATABASE_URL_CONFIG_KEY = "database.url";
513
- var CORE_CONFIG_TOKEN = "core.config";
514
- var CORE_CACHE_TOKEN = "core.cache";
515
- var CORE_QUEUE_TOKEN = "core.queue";
516
- var CORE_POLICY_GATE_TOKEN = "core.policyGate";
517
- var CORE_AUTH_TOKEN = "core.auth";
518
- var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
519
592
  var DEFAULT_APP_PORT = 3000;
520
593
  var DEFAULT_CACHE_TTL_MS = 3600000;
521
594
  var DEFAULT_CACHE_MAX_ENTRIES = 100;
522
595
  var DEFAULT_CACHE_DRIVER = "array";
523
596
  var DEFAULT_API_TOKEN = "";
524
597
  var DEFAULT_QUEUE_DRIVER = "sync";
525
-
526
598
  // ../../src/bootstrap/contracts.ts
527
599
  class ServiceContainer {
528
600
  services = new Map;
@@ -592,7 +664,7 @@ var requiredDependencyKeys = [
592
664
  "cache",
593
665
  "storage"
594
666
  ];
595
- function getRequiredDependency(dependencies, key) {
667
+ function getRequiredDependency2(dependencies, key) {
596
668
  const dependency = dependencies[key];
597
669
  if (dependency === undefined) {
598
670
  throw new Error(`Required dependency "${key}" is not registered.`);
@@ -601,75 +673,12 @@ function getRequiredDependency(dependencies, key) {
601
673
  }
602
674
  function assertAppDependenciesComplete(dependencies) {
603
675
  for (const key of requiredDependencyKeys) {
604
- getRequiredDependency(dependencies, key);
676
+ getRequiredDependency2(dependencies, key);
605
677
  }
606
678
  }
607
679
  function resolveService(dependencies, token) {
608
680
  return dependencies.container.resolve(token);
609
681
  }
610
-
611
- // ../../src/bootstrap/applicationRegistry.ts
612
- var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
613
- var activeContext;
614
- function readStoredApplicationContext() {
615
- if (activeContext) {
616
- return activeContext;
617
- }
618
- const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
619
- if (globalContext) {
620
- activeContext = globalContext;
621
- }
622
- return activeContext;
623
- }
624
- function setActiveApplicationContext(context) {
625
- activeContext = context;
626
- globalThis[APPLICATION_CONTEXT_KEY] = context;
627
- }
628
- function requireActiveApplicationContext() {
629
- const context = readStoredApplicationContext();
630
- if (!context) {
631
- throw new Error("The application context has not been bootstrapped.");
632
- }
633
- return context;
634
- }
635
- function resolveApplicationCache() {
636
- return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
637
- }
638
- function resolveApplicationQueue() {
639
- return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
640
- }
641
- function resolveApplicationAuth() {
642
- return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
643
- }
644
- function resolveApplicationPolicyGate() {
645
- return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
646
- }
647
- function resolveApplicationConfig() {
648
- return requireActiveApplicationContext().config;
649
- }
650
- function resolveApplicationLogger() {
651
- return appLogger;
652
- }
653
- function resolveApplicationDependencies() {
654
- return requireActiveApplicationContext().dependencies;
655
- }
656
- // ../../src/bootstrap/discoverModules.ts
657
- var appModules = [];
658
- function discoverModules() {
659
- return appModules;
660
- }
661
-
662
- // ../../src/bootstrap/cache/modelCacheTags.ts
663
- function cacheTagsForModelWrite(tableName, action) {
664
- const module = discoverModules().find((entry) => entry.tableName === tableName);
665
- const baseTags = module?.cacheTags ?? [`${tableName}s`];
666
- const isDelete = action === "deleted" || action === "force-deleted";
667
- const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
668
- return [...new Set([...baseTags, ...extraTags])];
669
- }
670
- function discoverModelTableNames() {
671
- return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
672
- }
673
682
  // ../../src/config/auth.ts
674
683
  var authConfig = {
675
684
  allowDevHeaders: (process.env.AUTH_DEV_HEADERS ?? "true") !== "false",
@@ -3573,7 +3582,6 @@ var failedJobService_default = FailedJobService;
3573
3582
 
3574
3583
  // ../../src/core/queue/jobRegistry.ts
3575
3584
  class JobRegistry {
3576
- constructor() {}
3577
3585
  factories = new Map;
3578
3586
  instances = new WeakMap;
3579
3587
  register(name, factory) {
@@ -3597,7 +3605,17 @@ class JobRegistry {
3597
3605
  return [...this.factories.keys()];
3598
3606
  }
3599
3607
  }
3600
- var jobRegistry = new JobRegistry;
3608
+ var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
3609
+ function readSharedJobRegistry() {
3610
+ const globalRegistry = globalThis[JOB_REGISTRY_KEY];
3611
+ if (globalRegistry) {
3612
+ return globalRegistry;
3613
+ }
3614
+ const registry = new JobRegistry;
3615
+ globalThis[JOB_REGISTRY_KEY] = registry;
3616
+ return registry;
3617
+ }
3618
+ var jobRegistry = readSharedJobRegistry();
3601
3619
 
3602
3620
  // ../../src/core/queue/jobRunner.ts
3603
3621
  async function runQueueJob(envelope, failedJobs) {
@@ -3713,75 +3731,6 @@ function createProductionQueue(driver, options = {}) {
3713
3731
  return new ResilientQueue(failedJobs, driver === "async");
3714
3732
  }
3715
3733
 
3716
- // ../../src/core/jobs/dispatchWebhookJob.ts
3717
- import { createHmac as createHmac2 } from "crypto";
3718
- class DispatchWebhookJob extends Job {
3719
- maxAttempts = 3;
3720
- backoffMs = 2000;
3721
- async handle(payload) {
3722
- const rows = await repositoryConnection`
3723
- SELECT id, url, secret
3724
- FROM webhook
3725
- WHERE id = ${payload.webhookId} AND active = TRUE
3726
- LIMIT 1
3727
- `;
3728
- const webhook = rows[0];
3729
- if (!webhook) {
3730
- return;
3731
- }
3732
- const body = JSON.stringify({ event: payload.event, payload: payload.payload });
3733
- const signature = createHmac2("sha256", webhook.secret).update(body).digest("hex");
3734
- assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
3735
- let responseStatus = null;
3736
- let errorMessage = null;
3737
- try {
3738
- const response = await safeFetch(webhook.url, {
3739
- method: "POST",
3740
- headers: {
3741
- "content-type": "application/json",
3742
- "x-workhub-signature": signature
3743
- },
3744
- body
3745
- }, { allowHttp: appConfig.env !== "production" });
3746
- responseStatus = response.status;
3747
- if (!response.ok) {
3748
- throw new Error(`Webhook delivery failed with status ${response.status}.`);
3749
- }
3750
- } catch (error) {
3751
- errorMessage = error instanceof Error ? error.message : String(error);
3752
- await repositoryConnection`
3753
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
3754
- VALUES (
3755
- ${webhook.id},
3756
- ${payload.event},
3757
- ${JSON.stringify(payload.payload)}::jsonb,
3758
- ${responseStatus},
3759
- ${errorMessage}
3760
- )
3761
- `;
3762
- throw error instanceof Error ? error : new Error(errorMessage);
3763
- }
3764
- await repositoryConnection`
3765
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
3766
- VALUES (
3767
- ${webhook.id},
3768
- ${payload.event},
3769
- ${JSON.stringify(payload.payload)}::jsonb,
3770
- ${responseStatus}
3771
- )
3772
- `;
3773
- }
3774
- }
3775
- var dispatchWebhookJob_default = DispatchWebhookJob;
3776
-
3777
- // ../../src/bootstrap/queue/defaultJobs.ts
3778
- function registerDefaultJobs() {
3779
- jobRegistry.register("cache.invalidate-tags", () => {
3780
- return new invalidateCacheTagsJob_default(resolveApplicationCache());
3781
- });
3782
- jobRegistry.register("webhook.dispatch", () => new dispatchWebhookJob_default);
3783
- }
3784
-
3785
3734
  // ../../src/core/queue/createAppQueue.ts
3786
3735
  var FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
3787
3736
  function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(), registerJobs) {
@@ -3887,6 +3836,75 @@ var policyProvider = {
3887
3836
  };
3888
3837
  var policy_default = policyProvider;
3889
3838
 
3839
+ // ../../src/core/jobs/dispatchWebhookJob.ts
3840
+ import { createHmac as createHmac2 } from "crypto";
3841
+ class DispatchWebhookJob extends Job {
3842
+ maxAttempts = 3;
3843
+ backoffMs = 2000;
3844
+ async handle(payload) {
3845
+ const rows = await repositoryConnection`
3846
+ SELECT id, url, secret
3847
+ FROM webhook
3848
+ WHERE id = ${payload.webhookId} AND active = TRUE
3849
+ LIMIT 1
3850
+ `;
3851
+ const webhook = rows[0];
3852
+ if (!webhook) {
3853
+ return;
3854
+ }
3855
+ const body = JSON.stringify({ event: payload.event, payload: payload.payload });
3856
+ const signature = createHmac2("sha256", webhook.secret).update(body).digest("hex");
3857
+ assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
3858
+ let responseStatus = null;
3859
+ let errorMessage = null;
3860
+ try {
3861
+ const response = await safeFetch(webhook.url, {
3862
+ method: "POST",
3863
+ headers: {
3864
+ "content-type": "application/json",
3865
+ "x-workhub-signature": signature
3866
+ },
3867
+ body
3868
+ }, { allowHttp: appConfig.env !== "production" });
3869
+ responseStatus = response.status;
3870
+ if (!response.ok) {
3871
+ throw new Error(`Webhook delivery failed with status ${response.status}.`);
3872
+ }
3873
+ } catch (error) {
3874
+ errorMessage = error instanceof Error ? error.message : String(error);
3875
+ await repositoryConnection`
3876
+ INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
3877
+ VALUES (
3878
+ ${webhook.id},
3879
+ ${payload.event},
3880
+ ${JSON.stringify(payload.payload)}::jsonb,
3881
+ ${responseStatus},
3882
+ ${errorMessage}
3883
+ )
3884
+ `;
3885
+ throw error instanceof Error ? error : new Error(errorMessage);
3886
+ }
3887
+ await repositoryConnection`
3888
+ INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
3889
+ VALUES (
3890
+ ${webhook.id},
3891
+ ${payload.event},
3892
+ ${JSON.stringify(payload.payload)}::jsonb,
3893
+ ${responseStatus}
3894
+ )
3895
+ `;
3896
+ }
3897
+ }
3898
+ var dispatchWebhookJob_default = DispatchWebhookJob;
3899
+
3900
+ // ../../src/bootstrap/queue/defaultJobs.ts
3901
+ function registerDefaultJobs() {
3902
+ jobRegistry.register("cache.invalidate-tags", () => {
3903
+ return new invalidateCacheTagsJob_default(resolveApplicationCache());
3904
+ });
3905
+ jobRegistry.register("webhook.dispatch", () => new dispatchWebhookJob_default);
3906
+ }
3907
+
3890
3908
  // ../../src/bootstrap/providers/queue.ts
3891
3909
  var queueProvider = {
3892
3910
  name: "core.queue",
@@ -4831,7 +4849,7 @@ function parsePositiveIntParam(value, name = "id") {
4831
4849
  return parsed;
4832
4850
  }
4833
4851
 
4834
- // ../../src/bootstrap/http/securedRouteModelBinding.ts
4852
+ // ../../src/core/http/securedRouteModelBinding.ts
4835
4853
  function isMutatingPolicyAction(action) {
4836
4854
  return action === "update" || action === "delete";
4837
4855
  }
@@ -5012,7 +5030,7 @@ class MembershipService {
5012
5030
  }
5013
5031
  var membershipService_default = MembershipService;
5014
5032
 
5015
- // ../../src/bootstrap/membershipService.ts
5033
+ // ../../src/core/auth/resolveMembershipService.ts
5016
5034
  function resolveMembershipService() {
5017
5035
  const dependencies = resolveApplicationDependencies();
5018
5036
  if (dependencies.container.has("core.membership")) {
@@ -5273,7 +5291,7 @@ export {
5273
5291
  prefixRouteMap,
5274
5292
  parseFormBody,
5275
5293
  mergeWebRoutes,
5276
- getRequiredDependency,
5294
+ getRequiredDependency2 as getRequiredDependency,
5277
5295
  discoverModelTableNames,
5278
5296
  createWebServer,
5279
5297
  createWebRoutes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/bootstrap",
3
- "version": "0.2.12",
3
+ "version": "0.2.16",
4
4
  "description": "Strata application bootstrap — HttpKernel, DI, web session helpers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -15,11 +15,6 @@
15
15
  "import": "./dist/index.js",
16
16
  "default": "./dist/index.js"
17
17
  },
18
- "./cache/modelCacheTags": {
19
- "types": "./dist/bootstrap/cache/modelCacheTags.d.ts",
20
- "import": "./dist/entries/cache/modelCacheTags.js",
21
- "default": "./dist/entries/cache/modelCacheTags.js"
22
- },
23
18
  "./applicationRegistry": {
24
19
  "types": "./dist/bootstrap/applicationRegistry.d.ts",
25
20
  "import": "./dist/entries/applicationRegistry.js",
@@ -87,14 +82,14 @@
87
82
  "build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external @getstrata/core",
88
83
  "build:types": "tsc -p tsconfig.types.json",
89
84
  "prepublishOnly": "bun run build",
90
- "build:subpaths": "bun build entries/applicationRegistry.ts entries/cache/modelCacheTags.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/membershipService.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core",
85
+ "build:subpaths": "bun build entries/applicationRegistry.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/membershipService.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core",
91
86
  "build:shims": "true"
92
87
  },
93
88
  "publishConfig": {
94
89
  "access": "public"
95
90
  },
96
91
  "peerDependencies": {
97
- "@getstrata/core": "^0.5.20",
92
+ "@getstrata/core": "^0.5.24",
98
93
  "typescript": "^5.9.0"
99
94
  }
100
95
  }
@@ -1 +0,0 @@
1
- export { cacheTagsForModelWrite, discoverModelTableNames, } from "../../bootstrap/cache/modelCacheTags.ts";
@@ -1,22 +0,0 @@
1
- // @bun
2
- // ../../src/bootstrap/discoverModules.ts
3
- var appModules = [];
4
- function discoverModules() {
5
- return appModules;
6
- }
7
-
8
- // ../../src/bootstrap/cache/modelCacheTags.ts
9
- function cacheTagsForModelWrite(tableName, action) {
10
- const module = discoverModules().find((entry) => entry.tableName === tableName);
11
- const baseTags = module?.cacheTags ?? [`${tableName}s`];
12
- const isDelete = action === "deleted" || action === "force-deleted";
13
- const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
14
- return [...new Set([...baseTags, ...extraTags])];
15
- }
16
- function discoverModelTableNames() {
17
- return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
18
- }
19
- export {
20
- discoverModelTableNames,
21
- cacheTagsForModelWrite
22
- };