@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.
@@ -43,6 +43,14 @@ function resolveAbilitiesForRole(role) {
43
43
  return [...MEMBER_ABILITIES];
44
44
  }
45
45
 
46
+ // ../../src/core/contracts/serviceTokens.ts
47
+ var CORE_CONFIG_TOKEN = "core.config";
48
+ var CORE_CACHE_TOKEN = "core.cache";
49
+ var CORE_QUEUE_TOKEN = "core.queue";
50
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
51
+ var CORE_AUTH_TOKEN = "core.auth";
52
+ var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
53
+
46
54
  // ../../src/bootstrap/config.ts
47
55
  var APP_PORT_CONFIG_KEY = "app.port";
48
56
  var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
@@ -50,12 +58,6 @@ var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
50
58
  var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
51
59
  var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
52
60
  var DATABASE_URL_CONFIG_KEY = "database.url";
53
- var CORE_CONFIG_TOKEN = "core.config";
54
- var CORE_CACHE_TOKEN = "core.cache";
55
- var CORE_QUEUE_TOKEN = "core.queue";
56
- var CORE_POLICY_GATE_TOKEN = "core.policyGate";
57
- var CORE_AUTH_TOKEN = "core.auth";
58
- var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
59
61
  var AUTH_DEV_HEADERS_CONFIG_KEY = "auth.allowDevHeaders";
60
62
  var DEFAULT_APP_PORT = 3000;
61
63
  var DEFAULT_CACHE_TTL_MS = 3600000;
@@ -1311,44 +1313,6 @@ function discoverListeners() {
1311
1313
  return appListeners;
1312
1314
  }
1313
1315
 
1314
- // ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
1315
- import { resolveApplicationCache as resolveApplicationCache2, resolveApplicationQueue } from "@getstrata/core";
1316
-
1317
- // ../../src/bootstrap/discoverModules.ts
1318
- import { readdirSync as readdirSync2 } from "fs";
1319
- import { join as join2 } from "path";
1320
- import { pathToFileURL as pathToFileURL2 } from "url";
1321
- async function loadDiscoveredModules() {
1322
- const modulesDirectory = join2(import.meta.dir, "../modules");
1323
- let moduleNames;
1324
- try {
1325
- moduleNames = readdirSync2(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
1326
- } catch (error) {
1327
- if (error.code === "ENOENT") {
1328
- return [];
1329
- }
1330
- throw error;
1331
- }
1332
- const modules = await Promise.all(moduleNames.map(async (moduleName) => {
1333
- const moduleUrl = pathToFileURL2(join2(modulesDirectory, moduleName, "index.ts")).href;
1334
- const loaded = await import(moduleUrl);
1335
- return loaded.default;
1336
- }));
1337
- return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
1338
- }
1339
- var appModules = await loadDiscoveredModules();
1340
- // ../../src/core/cache/modelCacheTags.ts
1341
- function cacheTagsForModelWrite(tableName, action) {
1342
- const module = appModules.find((entry) => entry.tableName === tableName);
1343
- const baseTags = module?.cacheTags ?? [`${tableName}s`];
1344
- const isDelete = action === "deleted" || action === "force-deleted";
1345
- const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
1346
- return [...new Set([...baseTags, ...extraTags])];
1347
- }
1348
- function discoverModelTableNames() {
1349
- return appModules.map((module) => module.tableName).filter((tableName) => tableName !== undefined);
1350
- }
1351
-
1352
1316
  // ../../src/core/queue/index.ts
1353
1317
  class Job {
1354
1318
  maxAttempts;
@@ -1659,10 +1623,10 @@ function buildHavingClause(tableName, having, params) {
1659
1623
  return body.length > 0 ? ` HAVING ${body}` : "";
1660
1624
  }
1661
1625
  function buildJoinClause(joins = []) {
1662
- return joins.map((join3) => {
1663
- const joinType = join3.type === "left" ? "LEFT JOIN" : "INNER JOIN";
1664
- const onClause = join3.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
1665
- return ` ${joinType} ${quoteIdentifier(join3.table)} ON ${onClause}`;
1626
+ return joins.map((join2) => {
1627
+ const joinType = join2.type === "left" ? "LEFT JOIN" : "INNER JOIN";
1628
+ const onClause = join2.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
1629
+ return ` ${joinType} ${quoteIdentifier(join2.table)} ON ${onClause}`;
1666
1630
  }).join("");
1667
1631
  }
1668
1632
  function buildLimitClause(limit) {
@@ -2098,7 +2062,7 @@ class RepositoryQuery {
2098
2062
  const rightRef = parseQualifiedColumn(right);
2099
2063
  const table = type === "inner" ? rightRef.table : rightRef.table;
2100
2064
  const joins = this.queryOptions.joins ?? [];
2101
- const existing = joins.find((join3) => join3.table === table && join3.type === type);
2065
+ const existing = joins.find((join2) => join2.table === table && join2.type === type);
2102
2066
  if (existing) {
2103
2067
  existing.on.push({ left: leftRef, right: rightRef });
2104
2068
  return this;
@@ -3261,9 +3225,6 @@ function createProductionQueue(driver, options = {}) {
3261
3225
  return new ResilientQueue(failedJobs, driver === "async");
3262
3226
  }
3263
3227
 
3264
- // ../../src/bootstrap/queue/defaultJobs.ts
3265
- import { resolveApplicationCache } from "@getstrata/core";
3266
-
3267
3228
  // ../../src/core/jobs/dispatchWebhookJob.ts
3268
3229
  import { createHmac as createHmac2 } from "crypto";
3269
3230
 
@@ -3451,6 +3412,96 @@ class DispatchWebhookJob extends Job {
3451
3412
  }
3452
3413
  var dispatchWebhookJob_default = DispatchWebhookJob;
3453
3414
 
3415
+ // ../../src/core/contracts/applicationContext.ts
3416
+ function getRequiredDependency(dependencies, key) {
3417
+ const dependency = dependencies[key];
3418
+ if (dependency === undefined) {
3419
+ throw new Error(`Required dependency "${String(key)}" is not registered.`);
3420
+ }
3421
+ return dependency;
3422
+ }
3423
+
3424
+ // ../../src/core/logging/logger.ts
3425
+ class Logger {
3426
+ channel;
3427
+ constructor(channel = "app") {
3428
+ this.channel = channel;
3429
+ }
3430
+ write(level, message, context = {}) {
3431
+ const entry = {
3432
+ level,
3433
+ channel: this.channel,
3434
+ message,
3435
+ timestamp: new Date().toISOString(),
3436
+ ...context
3437
+ };
3438
+ const line = JSON.stringify(entry);
3439
+ if (level === "error") {
3440
+ console.error(line);
3441
+ return;
3442
+ }
3443
+ console.log(line);
3444
+ }
3445
+ debug(message, context) {
3446
+ this.write("debug", message, context);
3447
+ }
3448
+ info(message, context) {
3449
+ this.write("info", message, context);
3450
+ }
3451
+ warn(message, context) {
3452
+ this.write("warn", message, context);
3453
+ }
3454
+ error(message, context) {
3455
+ this.write("error", message, context);
3456
+ }
3457
+ }
3458
+ var appLogger = new Logger("app");
3459
+
3460
+ // ../../src/core/runtime/applicationRegistry.ts
3461
+ var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
3462
+ var activeContext;
3463
+ function readStoredApplicationContext() {
3464
+ if (activeContext) {
3465
+ return activeContext;
3466
+ }
3467
+ const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
3468
+ if (globalContext) {
3469
+ activeContext = globalContext;
3470
+ }
3471
+ return activeContext;
3472
+ }
3473
+ function setActiveApplicationContext(context) {
3474
+ activeContext = context;
3475
+ globalThis[APPLICATION_CONTEXT_KEY] = context;
3476
+ }
3477
+ function requireActiveApplicationContext() {
3478
+ const context = readStoredApplicationContext();
3479
+ if (!context) {
3480
+ throw new Error("The application context has not been bootstrapped.");
3481
+ }
3482
+ return context;
3483
+ }
3484
+ function resolveApplicationCache() {
3485
+ return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
3486
+ }
3487
+ function resolveApplicationQueue() {
3488
+ return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
3489
+ }
3490
+ function resolveApplicationAuth() {
3491
+ return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
3492
+ }
3493
+ function resolveApplicationPolicyGate() {
3494
+ return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
3495
+ }
3496
+ function resolveApplicationConfig() {
3497
+ return requireActiveApplicationContext().config;
3498
+ }
3499
+ function resolveApplicationLogger() {
3500
+ return appLogger;
3501
+ }
3502
+ function resolveApplicationDependencies() {
3503
+ return requireActiveApplicationContext().dependencies;
3504
+ }
3454
3505
  // ../../src/bootstrap/queue/defaultJobs.ts
3455
3506
  function registerDefaultJobs() {
3456
3507
  jobRegistry.register("cache.invalidate-tags", () => {
@@ -3469,6 +3520,24 @@ function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(),
3469
3520
  });
3470
3521
  }
3471
3522
 
3523
+ // ../../src/bootstrap/discoverModules.ts
3524
+ var appModules = [];
3525
+ function discoverModules() {
3526
+ return appModules;
3527
+ }
3528
+
3529
+ // ../../src/bootstrap/cache/modelCacheTags.ts
3530
+ function cacheTagsForModelWrite(tableName, action) {
3531
+ const module = discoverModules().find((entry) => entry.tableName === tableName);
3532
+ const baseTags = module?.cacheTags ?? [`${tableName}s`];
3533
+ const isDelete = action === "deleted" || action === "force-deleted";
3534
+ const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
3535
+ return [...new Set([...baseTags, ...extraTags])];
3536
+ }
3537
+ function discoverModelTableNames() {
3538
+ return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
3539
+ }
3540
+
3472
3541
  // ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
3473
3542
  var MODEL_WRITE_ACTIONS = ["created", "updated", "deleted", "restored", "force-deleted"];
3474
3543
  function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
@@ -3482,7 +3551,7 @@ function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
3482
3551
  let cache;
3483
3552
  let queue;
3484
3553
  try {
3485
- cache = resolveApplicationCache2();
3554
+ cache = resolveApplicationCache();
3486
3555
  queue = resolveApplicationQueue();
3487
3556
  } catch {
3488
3557
  return;
@@ -3580,7 +3649,7 @@ var queue_default = queueProvider;
3580
3649
 
3581
3650
  // ../../src/core/storage/storage.ts
3582
3651
  import { mkdir, readFile, unlink, writeFile } from "fs/promises";
3583
- import { dirname, join as join3 } from "path";
3652
+ import { dirname, join as join2 } from "path";
3584
3653
  var {S3Client } = globalThis.Bun;
3585
3654
 
3586
3655
  class LocalStorageDriver {
@@ -3592,7 +3661,7 @@ class LocalStorageDriver {
3592
3661
  return this.rootDirectory ?? process.env.STORAGE_PATH ?? "storage";
3593
3662
  }
3594
3663
  resolvePath(path) {
3595
- return join3(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
3664
+ return join2(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
3596
3665
  }
3597
3666
  async put(path, contents) {
3598
3667
  const absolutePath = this.resolvePath(path);
@@ -3725,9 +3794,9 @@ function currentRequestMeta() {
3725
3794
  }
3726
3795
 
3727
3796
  // ../../src/core/view/etaViewEngine.ts
3728
- import { join as join4 } from "path";
3797
+ import { join as join3 } from "path";
3729
3798
  import { Eta } from "eta";
3730
- var DEFAULT_VIEWS_DIRECTORY = join4(process.cwd(), "resources/views");
3799
+ var DEFAULT_VIEWS_DIRECTORY = join3(process.cwd(), "resources/views");
3731
3800
  var DEFAULT_LAYOUT = "layouts/app.eta";
3732
3801
 
3733
3802
  class EtaViewEngine {
@@ -1,7 +1,4 @@
1
1
  // @bun
2
- // ../../src/bootstrap/queue/defaultJobs.ts
3
- import { resolveApplicationCache } from "@getstrata/core";
4
-
5
2
  // ../../src/core/jobs/dispatchWebhookJob.ts
6
3
  import { createHmac } from "crypto";
7
4
 
@@ -378,6 +375,104 @@ class JobRegistry {
378
375
  }
379
376
  var jobRegistry = new JobRegistry;
380
377
 
378
+ // ../../src/core/contracts/applicationContext.ts
379
+ function getRequiredDependency(dependencies, key) {
380
+ const dependency = dependencies[key];
381
+ if (dependency === undefined) {
382
+ throw new Error(`Required dependency "${String(key)}" is not registered.`);
383
+ }
384
+ return dependency;
385
+ }
386
+
387
+ // ../../src/core/contracts/serviceTokens.ts
388
+ var CORE_CONFIG_TOKEN = "core.config";
389
+ var CORE_CACHE_TOKEN = "core.cache";
390
+ var CORE_QUEUE_TOKEN = "core.queue";
391
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
392
+ var CORE_AUTH_TOKEN = "core.auth";
393
+ var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
394
+
395
+ // ../../src/core/logging/logger.ts
396
+ class Logger {
397
+ channel;
398
+ constructor(channel = "app") {
399
+ this.channel = channel;
400
+ }
401
+ write(level, message, context = {}) {
402
+ const entry = {
403
+ level,
404
+ channel: this.channel,
405
+ message,
406
+ timestamp: new Date().toISOString(),
407
+ ...context
408
+ };
409
+ const line = JSON.stringify(entry);
410
+ if (level === "error") {
411
+ console.error(line);
412
+ return;
413
+ }
414
+ console.log(line);
415
+ }
416
+ debug(message, context) {
417
+ this.write("debug", message, context);
418
+ }
419
+ info(message, context) {
420
+ this.write("info", message, context);
421
+ }
422
+ warn(message, context) {
423
+ this.write("warn", message, context);
424
+ }
425
+ error(message, context) {
426
+ this.write("error", message, context);
427
+ }
428
+ }
429
+ var appLogger = new Logger("app");
430
+
431
+ // ../../src/core/runtime/applicationRegistry.ts
432
+ var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
433
+ var activeContext;
434
+ function readStoredApplicationContext() {
435
+ if (activeContext) {
436
+ return activeContext;
437
+ }
438
+ const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
439
+ if (globalContext) {
440
+ activeContext = globalContext;
441
+ }
442
+ return activeContext;
443
+ }
444
+ function setActiveApplicationContext(context) {
445
+ activeContext = context;
446
+ globalThis[APPLICATION_CONTEXT_KEY] = context;
447
+ }
448
+ function requireActiveApplicationContext() {
449
+ const context = readStoredApplicationContext();
450
+ if (!context) {
451
+ throw new Error("The application context has not been bootstrapped.");
452
+ }
453
+ return context;
454
+ }
455
+ function resolveApplicationCache() {
456
+ return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
457
+ }
458
+ function resolveApplicationQueue() {
459
+ return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
460
+ }
461
+ function resolveApplicationAuth() {
462
+ return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
463
+ }
464
+ function resolveApplicationPolicyGate() {
465
+ return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
466
+ }
467
+ function resolveApplicationConfig() {
468
+ return requireActiveApplicationContext().config;
469
+ }
470
+ function resolveApplicationLogger() {
471
+ return appLogger;
472
+ }
473
+ function resolveApplicationDependencies() {
474
+ return requireActiveApplicationContext().dependencies;
475
+ }
381
476
  // ../../src/bootstrap/queue/defaultJobs.ts
382
477
  function registerDefaultJobs() {
383
478
  jobRegistry.register("cache.invalidate-tags", () => {
@@ -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,6 +19,7 @@ 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";
22
+ export { cacheTagsForModelWrite, discoverModelTableNames } from "../core/cache/modelCacheTags.ts";
23
23
  export { default as CacheRepository } from "../core/cache/repository.ts";
24
24
  export { CACHE_TAGS } from "../core/cache/tags.ts";
25
25
  export type { DatabaseConnection } from "../core/database/baseRepository.ts";
@@ -95,6 +95,7 @@ export { AsyncQueue, createQueue, Job, SyncQueue } from "../core/queue/index.ts"
95
95
  export { createFailedJobService, createProductionQueue, createQueueWorker, createTrackedJob, FailedJobRepository, FailedJobService, jobRegistry, QueueWorker, RedisQueue, ResilientQueue, runQueueJob, } from "../core/queue/publicQueue.ts";
96
96
  export type { QueueMetricsSnapshot } from "../core/queue/queueMetrics.ts";
97
97
  export { collectQueueMetrics } from "../core/queue/queueMetrics.ts";
98
+ export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "../core/runtime/applicationRegistry.ts";
98
99
  export type { ScheduledTask } from "../core/scheduler/schedule.ts";
99
100
  export { appSchedule, runDueScheduledTasks, Schedule } from "../core/scheduler/schedule.ts";
100
101
  export { guestCanViewResource, isPublicReadsEnabled } from "../core/security/publicReads.ts";