@getstrata/bootstrap 0.2.10 → 0.2.13

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/dist/index.js CHANGED
@@ -1,16 +1,4 @@
1
1
  // @bun
2
- // ../../src/bootstrap/public-api.ts
3
- import {
4
- resolveApplicationAuth as resolveApplicationAuth2,
5
- resolveApplicationCache as resolveApplicationCache3,
6
- resolveApplicationConfig,
7
- resolveApplicationDependencies as resolveApplicationDependencies2,
8
- resolveApplicationLogger,
9
- resolveApplicationPolicyGate as resolveApplicationPolicyGate2,
10
- resolveApplicationQueue as resolveApplicationQueue2,
11
- setActiveApplicationContext as setActiveApplicationContext2
12
- } from "@getstrata/core";
13
-
14
2
  // ../../src/core/scheduler/schedule.ts
15
3
  class Schedule {
16
4
  tasks = [];
@@ -515,6 +503,85 @@ async function scheduleRunCommand() {
515
503
  }
516
504
  await runDueScheduledTasks(appSchedule);
517
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
+ }
518
585
  // ../../src/bootstrap/config.ts
519
586
  var APP_PORT_CONFIG_KEY = "app.port";
520
587
  var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
@@ -522,21 +589,12 @@ var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
522
589
  var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
523
590
  var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
524
591
  var DATABASE_URL_CONFIG_KEY = "database.url";
525
- var CORE_CONFIG_TOKEN = "core.config";
526
- var CORE_CACHE_TOKEN = "core.cache";
527
- var CORE_QUEUE_TOKEN = "core.queue";
528
- var CORE_POLICY_GATE_TOKEN = "core.policyGate";
529
- var CORE_AUTH_TOKEN = "core.auth";
530
- var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
531
592
  var DEFAULT_APP_PORT = 3000;
532
593
  var DEFAULT_CACHE_TTL_MS = 3600000;
533
594
  var DEFAULT_CACHE_MAX_ENTRIES = 100;
534
595
  var DEFAULT_CACHE_DRIVER = "array";
535
596
  var DEFAULT_API_TOKEN = "";
536
597
  var DEFAULT_QUEUE_DRIVER = "sync";
537
- // ../../src/bootstrap/context.ts
538
- import { setActiveApplicationContext } from "@getstrata/core";
539
-
540
598
  // ../../src/bootstrap/contracts.ts
541
599
  class ServiceContainer {
542
600
  services = new Map;
@@ -606,7 +664,7 @@ var requiredDependencyKeys = [
606
664
  "cache",
607
665
  "storage"
608
666
  ];
609
- function getRequiredDependency(dependencies, key) {
667
+ function getRequiredDependency2(dependencies, key) {
610
668
  const dependency = dependencies[key];
611
669
  if (dependency === undefined) {
612
670
  throw new Error(`Required dependency "${key}" is not registered.`);
@@ -615,36 +673,12 @@ function getRequiredDependency(dependencies, key) {
615
673
  }
616
674
  function assertAppDependenciesComplete(dependencies) {
617
675
  for (const key of requiredDependencyKeys) {
618
- getRequiredDependency(dependencies, key);
676
+ getRequiredDependency2(dependencies, key);
619
677
  }
620
678
  }
621
679
  function resolveService(dependencies, token) {
622
680
  return dependencies.container.resolve(token);
623
681
  }
624
-
625
- // ../../src/bootstrap/discoverModules.ts
626
- import { readdirSync } from "fs";
627
- import { join } from "path";
628
- import { pathToFileURL } from "url";
629
- async function loadDiscoveredModules() {
630
- const modulesDirectory = join(import.meta.dir, "../modules");
631
- let moduleNames;
632
- try {
633
- moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
634
- } catch (error) {
635
- if (error.code === "ENOENT") {
636
- return [];
637
- }
638
- throw error;
639
- }
640
- const modules = await Promise.all(moduleNames.map(async (moduleName) => {
641
- const moduleUrl = pathToFileURL(join(modulesDirectory, moduleName, "index.ts")).href;
642
- const loaded = await import(moduleUrl);
643
- return loaded.default;
644
- }));
645
- return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
646
- }
647
- var appModules = await loadDiscoveredModules();
648
682
  // ../../src/config/auth.ts
649
683
  var authConfig = {
650
684
  allowDevHeaders: (process.env.AUTH_DEV_HEADERS ?? "true") !== "false",
@@ -1773,14 +1807,14 @@ var eventsProvider = {
1773
1807
  var events_default = eventsProvider;
1774
1808
 
1775
1809
  // ../../src/bootstrap/discoverListeners.ts
1776
- import { readdirSync as readdirSync2 } from "fs";
1777
- import { join as join2 } from "path";
1778
- import { pathToFileURL as pathToFileURL2 } from "url";
1810
+ import { readdirSync } from "fs";
1811
+ import { join } from "path";
1812
+ import { pathToFileURL } from "url";
1779
1813
  async function loadDiscoveredListeners() {
1780
- const listenersDirectory = join2(import.meta.dir, "../listeners");
1814
+ const listenersDirectory = join(import.meta.dir, "../listeners");
1781
1815
  let entries;
1782
1816
  try {
1783
- entries = readdirSync2(listenersDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => entry.name);
1817
+ entries = readdirSync(listenersDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => entry.name);
1784
1818
  } catch (error) {
1785
1819
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
1786
1820
  return [];
@@ -1788,7 +1822,7 @@ async function loadDiscoveredListeners() {
1788
1822
  throw error;
1789
1823
  }
1790
1824
  const listeners = await Promise.all(entries.map(async (fileName) => {
1791
- const moduleUrl = pathToFileURL2(join2(listenersDirectory, fileName)).href;
1825
+ const moduleUrl = pathToFileURL(join(listenersDirectory, fileName)).href;
1792
1826
  const loaded = await import(moduleUrl);
1793
1827
  return loaded.default;
1794
1828
  }));
@@ -1799,21 +1833,6 @@ function discoverListeners() {
1799
1833
  return appListeners;
1800
1834
  }
1801
1835
 
1802
- // ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
1803
- import { resolveApplicationCache as resolveApplicationCache2, resolveApplicationQueue } from "@getstrata/core";
1804
-
1805
- // ../../src/core/cache/modelCacheTags.ts
1806
- function cacheTagsForModelWrite(tableName, action) {
1807
- const module = appModules.find((entry) => entry.tableName === tableName);
1808
- const baseTags = module?.cacheTags ?? [`${tableName}s`];
1809
- const isDelete = action === "deleted" || action === "force-deleted";
1810
- const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
1811
- return [...new Set([...baseTags, ...extraTags])];
1812
- }
1813
- function discoverModelTableNames() {
1814
- return appModules.map((module) => module.tableName).filter((tableName) => tableName !== undefined);
1815
- }
1816
-
1817
1836
  // ../../src/core/queue/index.ts
1818
1837
  class Job {
1819
1838
  maxAttempts;
@@ -2124,10 +2143,10 @@ function buildHavingClause(tableName, having, params) {
2124
2143
  return body.length > 0 ? ` HAVING ${body}` : "";
2125
2144
  }
2126
2145
  function buildJoinClause(joins = []) {
2127
- return joins.map((join3) => {
2128
- const joinType = join3.type === "left" ? "LEFT JOIN" : "INNER JOIN";
2129
- const onClause = join3.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
2130
- return ` ${joinType} ${quoteIdentifier(join3.table)} ON ${onClause}`;
2146
+ return joins.map((join2) => {
2147
+ const joinType = join2.type === "left" ? "LEFT JOIN" : "INNER JOIN";
2148
+ const onClause = join2.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
2149
+ return ` ${joinType} ${quoteIdentifier(join2.table)} ON ${onClause}`;
2131
2150
  }).join("");
2132
2151
  }
2133
2152
  function buildLimitClause(limit) {
@@ -2540,7 +2559,7 @@ class RepositoryQuery {
2540
2559
  const rightRef = parseQualifiedColumn(right);
2541
2560
  const table = type === "inner" ? rightRef.table : rightRef.table;
2542
2561
  const joins = this.queryOptions.joins ?? [];
2543
- const existing = joins.find((join3) => join3.table === table && join3.type === type);
2562
+ const existing = joins.find((join2) => join2.table === table && join2.type === type);
2544
2563
  if (existing) {
2545
2564
  existing.on.push({ left: leftRef, right: rightRef });
2546
2565
  return this;
@@ -3703,9 +3722,6 @@ function createProductionQueue(driver, options = {}) {
3703
3722
  return new ResilientQueue(failedJobs, driver === "async");
3704
3723
  }
3705
3724
 
3706
- // ../../src/bootstrap/queue/defaultJobs.ts
3707
- import { resolveApplicationCache } from "@getstrata/core";
3708
-
3709
3725
  // ../../src/core/jobs/dispatchWebhookJob.ts
3710
3726
  import { createHmac as createHmac2 } from "crypto";
3711
3727
  class DispatchWebhookJob extends Job {
@@ -3798,7 +3814,7 @@ function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
3798
3814
  let cache;
3799
3815
  let queue;
3800
3816
  try {
3801
- cache = resolveApplicationCache2();
3817
+ cache = resolveApplicationCache();
3802
3818
  queue = resolveApplicationQueue();
3803
3819
  } catch {
3804
3820
  return;
@@ -3896,7 +3912,7 @@ var queue_default = queueProvider;
3896
3912
 
3897
3913
  // ../../src/core/storage/storage.ts
3898
3914
  import { mkdir, readFile, unlink, writeFile } from "fs/promises";
3899
- import { dirname, join as join3 } from "path";
3915
+ import { dirname, join as join2 } from "path";
3900
3916
  var {S3Client } = globalThis.Bun;
3901
3917
 
3902
3918
  class LocalStorageDriver {
@@ -3908,7 +3924,7 @@ class LocalStorageDriver {
3908
3924
  return this.rootDirectory ?? process.env.STORAGE_PATH ?? "storage";
3909
3925
  }
3910
3926
  resolvePath(path) {
3911
- return join3(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
3927
+ return join2(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
3912
3928
  }
3913
3929
  async put(path, contents) {
3914
3930
  const absolutePath = this.resolvePath(path);
@@ -4041,9 +4057,9 @@ function currentRequestMeta() {
4041
4057
  }
4042
4058
 
4043
4059
  // ../../src/core/view/etaViewEngine.ts
4044
- import { join as join4 } from "path";
4060
+ import { join as join3 } from "path";
4045
4061
  import { Eta } from "eta";
4046
- var DEFAULT_VIEWS_DIRECTORY = join4(process.cwd(), "resources/views");
4062
+ var DEFAULT_VIEWS_DIRECTORY = join3(process.cwd(), "resources/views");
4047
4063
  var DEFAULT_LAYOUT = "layouts/app.eta";
4048
4064
 
4049
4065
  class EtaViewEngine {
@@ -4369,7 +4385,7 @@ function createAppContext() {
4369
4385
  return appContext;
4370
4386
  }
4371
4387
  // ../../src/bootstrap/createWebRoutes.ts
4372
- import { join as join5 } from "path";
4388
+ import { join as join4 } from "path";
4373
4389
 
4374
4390
  // ../../src/core/http/middleware.ts
4375
4391
  function isRouteHandler(value) {
@@ -4703,7 +4719,7 @@ function createWebRoutes(dependencies) {
4703
4719
  registerRoute("GET", "/assets/*", ["global", "web"]);
4704
4720
  const pathname = new URL(request.url).pathname;
4705
4721
  const relativePath = pathname.replace(/^\//, "");
4706
- const file = Bun.file(join5(process.cwd(), "public", relativePath));
4722
+ const file = Bun.file(join4(process.cwd(), "public", relativePath));
4707
4723
  if (!await file.exists()) {
4708
4724
  return htmlResponse("Not Found", { status: 404 });
4709
4725
  }
@@ -4721,9 +4737,6 @@ function mergeWebRoutes(dependencies, routes) {
4721
4737
  ...routes
4722
4738
  };
4723
4739
  }
4724
- // ../../src/bootstrap/http/securedRouteModelBinding.ts
4725
- import { resolveApplicationAuth, resolveApplicationPolicyGate } from "@getstrata/core";
4726
-
4727
4740
  // ../../src/core/crypto/nonCryptographicHash.ts
4728
4741
  function nonCryptographicDigest(input) {
4729
4742
  return Bun.hash(input).toString(16);
@@ -4874,9 +4887,6 @@ function securedBindRouteModelByKey(param, resolver, authorization, handler) {
4874
4887
  return response;
4875
4888
  };
4876
4889
  }
4877
- // ../../src/bootstrap/membershipService.ts
4878
- import { resolveApplicationDependencies } from "@getstrata/core";
4879
-
4880
4890
  // ../../src/core/auth/accessControl.ts
4881
4891
  var ROLE_RANK = {
4882
4892
  member: 1,
@@ -5252,7 +5262,7 @@ export {
5252
5262
  wrapSecuredRouteModelByKey,
5253
5263
  toRouteRequest,
5254
5264
  slugify,
5255
- setActiveApplicationContext2 as setActiveApplicationContext,
5265
+ setActiveApplicationContext,
5256
5266
  securedBindRouteModelByKey,
5257
5267
  securedBindRouteModel,
5258
5268
  scheduleRunCommand,
@@ -5261,18 +5271,19 @@ export {
5261
5271
  routeParams,
5262
5272
  resolveService,
5263
5273
  resolveMembershipService,
5264
- resolveApplicationQueue2 as resolveApplicationQueue,
5265
- resolveApplicationPolicyGate2 as resolveApplicationPolicyGate,
5274
+ resolveApplicationQueue,
5275
+ resolveApplicationPolicyGate,
5266
5276
  resolveApplicationLogger,
5267
- resolveApplicationDependencies2 as resolveApplicationDependencies,
5277
+ resolveApplicationDependencies,
5268
5278
  resolveApplicationConfig,
5269
- resolveApplicationCache3 as resolveApplicationCache,
5270
- resolveApplicationAuth2 as resolveApplicationAuth,
5279
+ resolveApplicationCache,
5280
+ resolveApplicationAuth,
5271
5281
  registerDefaultJobs,
5272
5282
  prefixRouteMap,
5273
5283
  parseFormBody,
5274
5284
  mergeWebRoutes,
5275
- getRequiredDependency,
5285
+ getRequiredDependency2 as getRequiredDependency,
5286
+ discoverModelTableNames,
5276
5287
  createWebServer,
5277
5288
  createWebRoutes,
5278
5289
  createRouteKernel,
@@ -5281,6 +5292,7 @@ export {
5281
5292
  createAppContext,
5282
5293
  coreProviders,
5283
5294
  collectProviders,
5295
+ cacheTagsForModelWrite,
5284
5296
  assertAppDependenciesComplete,
5285
5297
  appSchedule,
5286
5298
  ServiceContainer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/bootstrap",
3
- "version": "0.2.10",
3
+ "version": "0.2.13",
4
4
  "description": "Strata application bootstrap — HttpKernel, DI, web session helpers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -89,7 +89,7 @@
89
89
  "access": "public"
90
90
  },
91
91
  "peerDependencies": {
92
- "@getstrata/core": "^0.5.18",
92
+ "@getstrata/core": "^0.5.21",
93
93
  "typescript": "^5.9.0"
94
94
  }
95
95
  }