@getstrata/bootstrap 0.2.8 → 0.2.10

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,6 +1,15 @@
1
1
  // @bun
2
2
  // ../../src/bootstrap/public-api.ts
3
- import { resolveApplicationQueue as resolveApplicationQueue2, setActiveApplicationContext as setActiveApplicationContext2 } from "@getstrata/core";
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";
4
13
 
5
14
  // ../../src/core/scheduler/schedule.ts
6
15
  class Schedule {
@@ -73,9 +82,22 @@ function getBoundDatabaseConnection() {
73
82
  return boundConnectionHolder.connection;
74
83
  }
75
84
 
76
- // ../../src/core/database/connectionContext.ts
85
+ // ../../src/core/runtime/asyncContextStore.ts
77
86
  import { AsyncLocalStorage } from "async_hooks";
78
- var activeConnection = new AsyncLocalStorage;
87
+ function createAsyncContextStore(key) {
88
+ const symbol = Symbol.for(key);
89
+ const globalRecord = globalThis;
90
+ const existing = globalRecord[symbol];
91
+ if (existing) {
92
+ return existing;
93
+ }
94
+ const store = new AsyncLocalStorage;
95
+ globalRecord[symbol] = store;
96
+ return store;
97
+ }
98
+
99
+ // ../../src/core/database/connectionContext.ts
100
+ var activeConnection = createAsyncContextStore("@getstrata/databaseConnectionContext");
79
101
  function getActiveDatabaseConnection(fallback) {
80
102
  return activeConnection.getStore() ?? fallback;
81
103
  }
@@ -728,6 +750,7 @@ var db = new Proxy(function database() {}, {
728
750
  return typeof value === "function" ? value.bind(connection) : value;
729
751
  }
730
752
  });
753
+ var connection_default = db;
731
754
 
732
755
  // ../../src/modules/user/apiTokenTable.ts
733
756
  import { defineTable } from "@getstrata/core/database";
@@ -911,8 +934,7 @@ import { resolveDefaultTokenExpiryDays as resolveDefaultTokenExpiryDays2 } from
911
934
  var tokenServiceToken = CORE_TOKEN_SERVICE_TOKEN;
912
935
 
913
936
  // ../../src/core/auth/authContext.ts
914
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
915
- var authContext = new AsyncLocalStorage2;
937
+ var authContext = createAsyncContextStore("@getstrata/authContext");
916
938
  function currentAuthUser() {
917
939
  return authContext.getStore() ?? null;
918
940
  }
@@ -1777,6 +1799,9 @@ function discoverListeners() {
1777
1799
  return appListeners;
1778
1800
  }
1779
1801
 
1802
+ // ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
1803
+ import { resolveApplicationCache as resolveApplicationCache2, resolveApplicationQueue } from "@getstrata/core";
1804
+
1780
1805
  // ../../src/core/cache/modelCacheTags.ts
1781
1806
  function cacheTagsForModelWrite(tableName, action) {
1782
1807
  const module = appModules.find((entry) => entry.tableName === tableName);
@@ -1809,116 +1834,6 @@ class InvalidateCacheTagsJob extends Job {
1809
1834
  }
1810
1835
  var invalidateCacheTagsJob_default = InvalidateCacheTagsJob;
1811
1836
 
1812
- // ../../src/bootstrap/applicationRegistry.ts
1813
- var activeContext;
1814
- function requireActiveApplicationContext() {
1815
- if (!activeContext) {
1816
- throw new Error("The application context has not been bootstrapped.");
1817
- }
1818
- return activeContext;
1819
- }
1820
- function resolveApplicationCache() {
1821
- return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
1822
- }
1823
- function resolveApplicationQueue() {
1824
- return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
1825
- }
1826
- function resolveApplicationAuth() {
1827
- return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
1828
- }
1829
- function resolveApplicationPolicyGate() {
1830
- return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
1831
- }
1832
-
1833
- // ../../src/core/jobs/dispatchWebhookJob.ts
1834
- import { createHmac as createHmac2 } from "crypto";
1835
- class DispatchWebhookJob extends Job {
1836
- maxAttempts = 3;
1837
- backoffMs = 2000;
1838
- async handle(payload) {
1839
- const rows = await repositoryConnection`
1840
- SELECT id, url, secret
1841
- FROM webhook
1842
- WHERE id = ${payload.webhookId} AND active = TRUE
1843
- LIMIT 1
1844
- `;
1845
- const webhook = rows[0];
1846
- if (!webhook) {
1847
- return;
1848
- }
1849
- const body = JSON.stringify({ event: payload.event, payload: payload.payload });
1850
- const signature = createHmac2("sha256", webhook.secret).update(body).digest("hex");
1851
- assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
1852
- let responseStatus = null;
1853
- let errorMessage = null;
1854
- try {
1855
- const response = await safeFetch(webhook.url, {
1856
- method: "POST",
1857
- headers: {
1858
- "content-type": "application/json",
1859
- "x-workhub-signature": signature
1860
- },
1861
- body
1862
- }, { allowHttp: appConfig.env !== "production" });
1863
- responseStatus = response.status;
1864
- if (!response.ok) {
1865
- throw new Error(`Webhook delivery failed with status ${response.status}.`);
1866
- }
1867
- } catch (error) {
1868
- errorMessage = error instanceof Error ? error.message : String(error);
1869
- await repositoryConnection`
1870
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
1871
- VALUES (
1872
- ${webhook.id},
1873
- ${payload.event},
1874
- ${JSON.stringify(payload.payload)}::jsonb,
1875
- ${responseStatus},
1876
- ${errorMessage}
1877
- )
1878
- `;
1879
- throw error instanceof Error ? error : new Error(errorMessage);
1880
- }
1881
- await repositoryConnection`
1882
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
1883
- VALUES (
1884
- ${webhook.id},
1885
- ${payload.event},
1886
- ${JSON.stringify(payload.payload)}::jsonb,
1887
- ${responseStatus}
1888
- )
1889
- `;
1890
- }
1891
- }
1892
- var dispatchWebhookJob_default = DispatchWebhookJob;
1893
-
1894
- // ../../src/core/queue/jobRegistry.ts
1895
- class JobRegistry {
1896
- constructor() {}
1897
- factories = new Map;
1898
- instances = new WeakMap;
1899
- register(name, factory) {
1900
- this.factories.set(name, factory);
1901
- }
1902
- resolveName(job) {
1903
- return this.instances.get(job);
1904
- }
1905
- track(name, job) {
1906
- this.instances.set(job, name);
1907
- return job;
1908
- }
1909
- create(name) {
1910
- const factory = this.factories.get(name);
1911
- if (!factory) {
1912
- return;
1913
- }
1914
- return factory();
1915
- }
1916
- names() {
1917
- return [...this.factories.keys()];
1918
- }
1919
- }
1920
- var jobRegistry = new JobRegistry;
1921
-
1922
1837
  // ../../src/core/pagination/index.ts
1923
1838
  function buildPaginationMeta(input) {
1924
1839
  const lastPage = Math.max(1, Math.ceil(input.total / input.perPage));
@@ -3646,6 +3561,34 @@ class FailedJobService {
3646
3561
  }
3647
3562
  var failedJobService_default = FailedJobService;
3648
3563
 
3564
+ // ../../src/core/queue/jobRegistry.ts
3565
+ class JobRegistry {
3566
+ constructor() {}
3567
+ factories = new Map;
3568
+ instances = new WeakMap;
3569
+ register(name, factory) {
3570
+ this.factories.set(name, factory);
3571
+ }
3572
+ resolveName(job) {
3573
+ return this.instances.get(job);
3574
+ }
3575
+ track(name, job) {
3576
+ this.instances.set(job, name);
3577
+ return job;
3578
+ }
3579
+ create(name) {
3580
+ const factory = this.factories.get(name);
3581
+ if (!factory) {
3582
+ return;
3583
+ }
3584
+ return factory();
3585
+ }
3586
+ names() {
3587
+ return [...this.factories.keys()];
3588
+ }
3589
+ }
3590
+ var jobRegistry = new JobRegistry;
3591
+
3649
3592
  // ../../src/core/queue/jobRunner.ts
3650
3593
  async function runQueueJob(envelope, failedJobs) {
3651
3594
  const job = jobRegistry.create(envelope.name);
@@ -3760,19 +3703,85 @@ function createProductionQueue(driver, options = {}) {
3760
3703
  return new ResilientQueue(failedJobs, driver === "async");
3761
3704
  }
3762
3705
 
3763
- // ../../src/core/queue/createAppQueue.ts
3764
- var FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
3706
+ // ../../src/bootstrap/queue/defaultJobs.ts
3707
+ import { resolveApplicationCache } from "@getstrata/core";
3708
+
3709
+ // ../../src/core/jobs/dispatchWebhookJob.ts
3710
+ import { createHmac as createHmac2 } from "crypto";
3711
+ class DispatchWebhookJob extends Job {
3712
+ maxAttempts = 3;
3713
+ backoffMs = 2000;
3714
+ async handle(payload) {
3715
+ const rows = await repositoryConnection`
3716
+ SELECT id, url, secret
3717
+ FROM webhook
3718
+ WHERE id = ${payload.webhookId} AND active = TRUE
3719
+ LIMIT 1
3720
+ `;
3721
+ const webhook = rows[0];
3722
+ if (!webhook) {
3723
+ return;
3724
+ }
3725
+ const body = JSON.stringify({ event: payload.event, payload: payload.payload });
3726
+ const signature = createHmac2("sha256", webhook.secret).update(body).digest("hex");
3727
+ assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
3728
+ let responseStatus = null;
3729
+ let errorMessage = null;
3730
+ try {
3731
+ const response = await safeFetch(webhook.url, {
3732
+ method: "POST",
3733
+ headers: {
3734
+ "content-type": "application/json",
3735
+ "x-workhub-signature": signature
3736
+ },
3737
+ body
3738
+ }, { allowHttp: appConfig.env !== "production" });
3739
+ responseStatus = response.status;
3740
+ if (!response.ok) {
3741
+ throw new Error(`Webhook delivery failed with status ${response.status}.`);
3742
+ }
3743
+ } catch (error) {
3744
+ errorMessage = error instanceof Error ? error.message : String(error);
3745
+ await repositoryConnection`
3746
+ INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
3747
+ VALUES (
3748
+ ${webhook.id},
3749
+ ${payload.event},
3750
+ ${JSON.stringify(payload.payload)}::jsonb,
3751
+ ${responseStatus},
3752
+ ${errorMessage}
3753
+ )
3754
+ `;
3755
+ throw error instanceof Error ? error : new Error(errorMessage);
3756
+ }
3757
+ await repositoryConnection`
3758
+ INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
3759
+ VALUES (
3760
+ ${webhook.id},
3761
+ ${payload.event},
3762
+ ${JSON.stringify(payload.payload)}::jsonb,
3763
+ ${responseStatus}
3764
+ )
3765
+ `;
3766
+ }
3767
+ }
3768
+ var dispatchWebhookJob_default = DispatchWebhookJob;
3769
+
3770
+ // ../../src/bootstrap/queue/defaultJobs.ts
3765
3771
  function registerDefaultJobs() {
3766
3772
  jobRegistry.register("cache.invalidate-tags", () => {
3767
3773
  return new invalidateCacheTagsJob_default(resolveApplicationCache());
3768
3774
  });
3769
3775
  jobRegistry.register("webhook.dispatch", () => new dispatchWebhookJob_default);
3770
3776
  }
3771
- function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService()) {
3777
+
3778
+ // ../../src/core/queue/createAppQueue.ts
3779
+ var FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
3780
+ function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(), registerJobs) {
3772
3781
  return createProductionQueue(driver, {
3773
3782
  redisUrl,
3774
3783
  failedJobs,
3775
- registerJobs: registerDefaultJobs
3784
+ registerJobs
3776
3785
  });
3777
3786
  }
3778
3787
 
@@ -3789,7 +3798,7 @@ function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
3789
3798
  let cache;
3790
3799
  let queue;
3791
3800
  try {
3792
- cache = resolveApplicationCache();
3801
+ cache = resolveApplicationCache2();
3793
3802
  queue = resolveApplicationQueue();
3794
3803
  } catch {
3795
3804
  return;
@@ -3880,7 +3889,7 @@ var queueProvider = {
3880
3889
  config.set("queue.driver", driver);
3881
3890
  const failedJobs = createFailedJobService();
3882
3891
  container.set(FAILED_JOB_SERVICE_TOKEN, failedJobs);
3883
- container.set(CORE_QUEUE_TOKEN, createAppQueue(driver, config.get(REDIS_URL_CONFIG_KEY) ?? process.env.REDIS_URL, failedJobs));
3892
+ container.set(CORE_QUEUE_TOKEN, createAppQueue(driver, config.get(REDIS_URL_CONFIG_KEY) ?? process.env.REDIS_URL, failedJobs, registerDefaultJobs));
3884
3893
  }
3885
3894
  };
3886
3895
  var queue_default = queueProvider;
@@ -4023,8 +4032,7 @@ function isViewsEnabled() {
4023
4032
  }
4024
4033
 
4025
4034
  // ../../src/core/http/requestMetaContext.ts
4026
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
4027
- var requestMetaContext = new AsyncLocalStorage3;
4035
+ var requestMetaContext = createAsyncContextStore("@getstrata/requestMetaContext");
4028
4036
  function currentRequestMeta() {
4029
4037
  return requestMetaContext.getStore() ?? {
4030
4038
  ipAddress: null,
@@ -4713,6 +4721,9 @@ function mergeWebRoutes(dependencies, routes) {
4713
4721
  ...routes
4714
4722
  };
4715
4723
  }
4724
+ // ../../src/bootstrap/http/securedRouteModelBinding.ts
4725
+ import { resolveApplicationAuth, resolveApplicationPolicyGate } from "@getstrata/core";
4726
+
4716
4727
  // ../../src/core/crypto/nonCryptographicHash.ts
4717
4728
  function nonCryptographicDigest(input) {
4718
4729
  return Bun.hash(input).toString(16);
@@ -4805,8 +4816,7 @@ function applyConditionalGet(request, response, etag) {
4805
4816
  }
4806
4817
 
4807
4818
  // ../../src/core/tenant/tenantContext.ts
4808
- import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
4809
- var tenantContext = new AsyncLocalStorage4;
4819
+ var tenantContext = createAsyncContextStore("@getstrata/tenantContext");
4810
4820
 
4811
4821
  // ../../src/core/http/validation.ts
4812
4822
  function parsePositiveIntParam(value, name = "id") {
@@ -4864,6 +4874,151 @@ function securedBindRouteModelByKey(param, resolver, authorization, handler) {
4864
4874
  return response;
4865
4875
  };
4866
4876
  }
4877
+ // ../../src/bootstrap/membershipService.ts
4878
+ import { resolveApplicationDependencies } from "@getstrata/core";
4879
+
4880
+ // ../../src/core/auth/accessControl.ts
4881
+ var ROLE_RANK = {
4882
+ member: 1,
4883
+ admin: 2,
4884
+ owner: 3
4885
+ };
4886
+ function isGlobalAdmin(user) {
4887
+ return user?.role === "admin";
4888
+ }
4889
+ function hasMinimumOrgRole(role, minimum) {
4890
+ if (!role) {
4891
+ return false;
4892
+ }
4893
+ return ROLE_RANK[role] >= ROLE_RANK[minimum];
4894
+ }
4895
+ function resolveUserId(user) {
4896
+ const userId = typeof user.id === "number" ? user.id : Number(user.id);
4897
+ if (!Number.isInteger(userId) || userId <= 0) {
4898
+ throw new ForbiddenError("Invalid authenticated user.");
4899
+ }
4900
+ return userId;
4901
+ }
4902
+
4903
+ // ../../src/modules/organization/memberRepository.ts
4904
+ class OrganizationMemberRepository {
4905
+ constructor() {}
4906
+ async findMembership(userId, organizationId) {
4907
+ const rows = await connection_default`
4908
+ SELECT id, organization_id, user_id, role, created_at
4909
+ FROM organization_member
4910
+ WHERE user_id = ${userId} AND organization_id = ${organizationId}
4911
+ LIMIT 1
4912
+ `;
4913
+ return rows[0] ?? null;
4914
+ }
4915
+ async listForUser(userId) {
4916
+ return await connection_default`
4917
+ SELECT id, organization_id, user_id, role, created_at
4918
+ FROM organization_member
4919
+ WHERE user_id = ${userId}
4920
+ ORDER BY organization_id
4921
+ `;
4922
+ }
4923
+ async listForOrganization(organizationId) {
4924
+ return await connection_default`
4925
+ SELECT id, organization_id, user_id, role, created_at
4926
+ FROM organization_member
4927
+ WHERE organization_id = ${organizationId}
4928
+ ORDER BY id
4929
+ `;
4930
+ }
4931
+ async addMember(input) {
4932
+ const rows = await connection_default`
4933
+ INSERT INTO organization_member (organization_id, user_id, role)
4934
+ VALUES (${input.organizationId}, ${input.userId}, ${input.role ?? "member"})
4935
+ RETURNING id, organization_id, user_id, role, created_at
4936
+ `;
4937
+ const row = rows[0];
4938
+ if (!row) {
4939
+ throw new Error("Organization member insert did not return a row.");
4940
+ }
4941
+ return row;
4942
+ }
4943
+ async removeMember(organizationId, userId) {
4944
+ const rows = await connection_default`
4945
+ DELETE FROM organization_member
4946
+ WHERE organization_id = ${organizationId} AND user_id = ${userId}
4947
+ RETURNING id
4948
+ `;
4949
+ return rows.length > 0;
4950
+ }
4951
+ }
4952
+ var memberRepository_default = OrganizationMemberRepository;
4953
+
4954
+ // ../../src/core/auth/membershipContext.ts
4955
+ var membershipContext = createAsyncContextStore("@getstrata/membershipContext");
4956
+ var membershipRepository = new memberRepository_default;
4957
+
4958
+ // ../../src/core/auth/membershipService.ts
4959
+ class MembershipService {
4960
+ members;
4961
+ constructor(members = membershipRepository) {
4962
+ this.members = members;
4963
+ }
4964
+ async listOrganizationIdsForUser(userId) {
4965
+ const memberships = await this.members.listForUser(userId);
4966
+ return memberships.map((membership) => membership.organization_id);
4967
+ }
4968
+ async getOrgRole(userId, organizationId) {
4969
+ const membership = await this.members.findMembership(userId, organizationId);
4970
+ return membership?.role ?? null;
4971
+ }
4972
+ async requireOrgAccess(organizationId, minimumRole = "member", user = currentAuthUser()) {
4973
+ if (!user) {
4974
+ throw new ForbiddenError("Authentication required.");
4975
+ }
4976
+ if (isGlobalAdmin(user)) {
4977
+ return "owner";
4978
+ }
4979
+ const role = await this.getOrgRole(resolveUserId(user), organizationId);
4980
+ if (!role || !hasMinimumOrgRole(role, minimumRole)) {
4981
+ throw new ForbiddenError("Organization membership required.");
4982
+ }
4983
+ return role;
4984
+ }
4985
+ async filterAccessibleOrganizationIds(organizationIds, user = currentAuthUser()) {
4986
+ if (!user) {
4987
+ return [];
4988
+ }
4989
+ if (isGlobalAdmin(user)) {
4990
+ return organizationIds;
4991
+ }
4992
+ const allowed = new Set(await this.listOrganizationIdsForUser(resolveUserId(user)));
4993
+ return organizationIds.filter((organizationId) => allowed.has(organizationId));
4994
+ }
4995
+ async addOwnerOnOrganizationCreate(organizationId, userId) {
4996
+ await this.members.addMember({
4997
+ organizationId,
4998
+ userId,
4999
+ role: "owner"
5000
+ });
5001
+ }
5002
+ listMembersForOrganization(organizationId) {
5003
+ return this.members.listForOrganization(organizationId);
5004
+ }
5005
+ addMember(input) {
5006
+ return this.members.addMember(input);
5007
+ }
5008
+ removeMember(organizationId, userId) {
5009
+ return this.members.removeMember(organizationId, userId);
5010
+ }
5011
+ }
5012
+ var membershipService_default = MembershipService;
5013
+
5014
+ // ../../src/bootstrap/membershipService.ts
5015
+ function resolveMembershipService() {
5016
+ const dependencies = resolveApplicationDependencies();
5017
+ if (dependencies.container.has("core.membership")) {
5018
+ return dependencies.container.resolve("core.membership");
5019
+ }
5020
+ return new membershipService_default;
5021
+ }
4867
5022
  // ../../src/bootstrap/prefixRouteMap.ts
4868
5023
  function prefixRouteMap(prefix, routes) {
4869
5024
  const normalizedPrefix = prefix.replace(/\/$/, "");
@@ -5105,7 +5260,15 @@ export {
5105
5260
  runDueScheduledTasks,
5106
5261
  routeParams,
5107
5262
  resolveService,
5263
+ resolveMembershipService,
5108
5264
  resolveApplicationQueue2 as resolveApplicationQueue,
5265
+ resolveApplicationPolicyGate2 as resolveApplicationPolicyGate,
5266
+ resolveApplicationLogger,
5267
+ resolveApplicationDependencies2 as resolveApplicationDependencies,
5268
+ resolveApplicationConfig,
5269
+ resolveApplicationCache3 as resolveApplicationCache,
5270
+ resolveApplicationAuth2 as resolveApplicationAuth,
5271
+ registerDefaultJobs,
5109
5272
  prefixRouteMap,
5110
5273
  parseFormBody,
5111
5274
  mergeWebRoutes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/bootstrap",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Strata application bootstrap — HttpKernel, DI, web session helpers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -50,6 +50,16 @@
50
50
  "import": "./dist/entries/httpKernel.js",
51
51
  "default": "./dist/entries/httpKernel.js"
52
52
  },
53
+ "./membershipService": {
54
+ "types": "./dist/bootstrap/membershipService.d.ts",
55
+ "import": "./dist/entries/membershipService.js",
56
+ "default": "./dist/entries/membershipService.js"
57
+ },
58
+ "./queue/defaultJobs": {
59
+ "types": "./dist/bootstrap/queue/defaultJobs.d.ts",
60
+ "import": "./dist/entries/queue/defaultJobs.js",
61
+ "default": "./dist/entries/queue/defaultJobs.js"
62
+ },
53
63
  "./providers": {
54
64
  "types": "./dist/bootstrap/providers/index.d.ts",
55
65
  "import": "./dist/entries/providers.js",
@@ -72,14 +82,14 @@
72
82
  "build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external @getstrata/core",
73
83
  "build:types": "tsc -p tsconfig.types.json",
74
84
  "prepublishOnly": "bun run build",
75
- "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/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",
76
86
  "build:shims": "true"
77
87
  },
78
88
  "publishConfig": {
79
89
  "access": "public"
80
90
  },
81
91
  "peerDependencies": {
82
- "@getstrata/core": "^0.5.16",
92
+ "@getstrata/core": "^0.5.18",
83
93
  "typescript": "^5.9.0"
84
94
  }
85
95
  }