@getstrata/core 0.5.21 → 0.5.25

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.
@@ -20,4 +20,4 @@ declare class MembershipService {
20
20
  }
21
21
  export type { MembershipRepositoryLike };
22
22
  export default MembershipService;
23
- export { resolveMembershipService } from "../../bootstrap/membershipService.ts";
23
+ export { resolveMembershipService } from "./resolveMembershipService.ts";
@@ -1,3 +1,3 @@
1
- import MembershipService from "../core/auth/membershipService";
1
+ import MembershipService from "./membershipService";
2
2
  declare function resolveMembershipService(): MembershipService;
3
3
  export { resolveMembershipService };
@@ -1,2 +1,11 @@
1
- export type { RouteModelAuthorization } from "../../bootstrap/http/securedRouteModelBinding.ts";
2
- export { securedBindRouteModel, securedBindRouteModelByKey, } from "../../bootstrap/http/securedRouteModelBinding.ts";
1
+ import type { Policy } from "../auth/policy";
2
+ import type { RouteRequest } from "./route";
3
+ interface RouteModelAuthorization {
4
+ resource: string;
5
+ action: keyof Policy;
6
+ requireIfMatch?: boolean;
7
+ }
8
+ declare function securedBindRouteModel<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (id: number, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
9
+ declare function securedBindRouteModelByKey<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (key: string, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
10
+ export type { RouteModelAuthorization };
11
+ export { securedBindRouteModel, securedBindRouteModelByKey };
@@ -2,5 +2,4 @@ import type { Queue } from "./index";
2
2
  import { createFailedJobService, createQueueWorker, createTrackedJob, type FailedJobService } from "./publicQueue";
3
3
  declare const FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
4
4
  declare function createAppQueue(driver: "sync" | "async" | "redis", redisUrl?: string, failedJobs?: FailedJobService, registerJobs?: () => void): Queue;
5
- export { registerDefaultJobs } from "../../bootstrap/queue/defaultJobs.ts";
6
5
  export { createAppQueue, createFailedJobService, createQueueWorker, createTrackedJob, FAILED_JOB_SERVICE_TOKEN, };
@@ -1,7 +1,6 @@
1
1
  import type { Job } from "./index";
2
2
  type JobFactory = () => Job;
3
3
  declare class JobRegistry {
4
- constructor();
5
4
  private readonly factories;
6
5
  private readonly instances;
7
6
  register(name: string, factory: JobFactory): void;
@@ -0,0 +1,16 @@
1
+ // @bun
2
+ // ../../src/core/contracts/serviceTokens.ts
3
+ var CORE_CONFIG_TOKEN = "core.config";
4
+ var CORE_CACHE_TOKEN = "core.cache";
5
+ var CORE_QUEUE_TOKEN = "core.queue";
6
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
7
+ var CORE_AUTH_TOKEN = "core.auth";
8
+ var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
9
+ export {
10
+ CORE_TOKEN_SERVICE_TOKEN,
11
+ CORE_QUEUE_TOKEN,
12
+ CORE_POLICY_GATE_TOKEN,
13
+ CORE_CONFIG_TOKEN,
14
+ CORE_CACHE_TOKEN,
15
+ CORE_AUTH_TOKEN
16
+ };
@@ -183,6 +183,11 @@ function isHtmxRequest(request) {
183
183
  return request.headers.get("HX-Request") === "true";
184
184
  }
185
185
  // ../../src/core/contracts/serviceTokens.ts
186
+ var CORE_CONFIG_TOKEN = "core.config";
187
+ var CORE_CACHE_TOKEN = "core.cache";
188
+ var CORE_QUEUE_TOKEN = "core.queue";
189
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
190
+ var CORE_AUTH_TOKEN = "core.auth";
186
191
  var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
187
192
  // ../../src/bootstrap/config.ts
188
193
  var DEFAULT_QUEUE_DRIVER = "sync";
@@ -1,7 +1,4 @@
1
1
  // @bun
2
- // ../../src/core/jobs/dispatchWebhookJob.ts
3
- import { createHmac } from "crypto";
4
-
5
2
  // ../../src/config/app.ts
6
3
  var appConfig = {
7
4
  name: "WorkHub",
@@ -96,13 +93,6 @@ var repositoryConnection = new Proxy(function repositoryConnection2() {}, {
96
93
  }
97
94
  });
98
95
 
99
- // ../../src/core/queue/index.ts
100
- class Job {
101
- maxAttempts;
102
- backoffMs;
103
- priority;
104
- }
105
-
106
96
  // ../../src/core/security/safeUrl.ts
107
97
  import { lookup as dnsLookupImpl } from "dns/promises";
108
98
 
@@ -266,97 +256,3 @@ function setDnsLookupForTests(lookupFn) {
266
256
  function resetDnsLookupForTests() {
267
257
  dnsLookup = dnsLookupImpl;
268
258
  }
269
-
270
- // ../../src/core/security/safeFetch.ts
271
- var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
272
- async function safeFetch(input, init = {}, options = {}) {
273
- const timeoutMs = options.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
274
- const maxRedirects = options.maxRedirects ?? 0;
275
- const resolveDns = options.resolveDns ?? appConfig.env === "production";
276
- const urlOptions = { allowHttp: options.allowHttp, resolveDns };
277
- const controller = new AbortController;
278
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
279
- try {
280
- let currentUrl = (await assertSafeOutboundUrlResolved(input, urlOptions)).toString();
281
- let redirectCount = 0;
282
- while (true) {
283
- const response = await fetch(currentUrl, {
284
- ...init,
285
- signal: controller.signal,
286
- redirect: "manual"
287
- });
288
- if (response.status >= 300 && response.status < 400) {
289
- const location = response.headers.get("location");
290
- if (!location || redirectCount >= maxRedirects) {
291
- return response;
292
- }
293
- currentUrl = (await assertSafeOutboundUrlResolved(new URL(location, currentUrl).toString(), urlOptions)).toString();
294
- redirectCount += 1;
295
- continue;
296
- }
297
- return response;
298
- }
299
- } finally {
300
- clearTimeout(timeout);
301
- }
302
- }
303
-
304
- // ../../src/core/jobs/dispatchWebhookJob.ts
305
- class DispatchWebhookJob extends Job {
306
- maxAttempts = 3;
307
- backoffMs = 2000;
308
- async handle(payload) {
309
- const rows = await repositoryConnection`
310
- SELECT id, url, secret
311
- FROM webhook
312
- WHERE id = ${payload.webhookId} AND active = TRUE
313
- LIMIT 1
314
- `;
315
- const webhook = rows[0];
316
- if (!webhook) {
317
- return;
318
- }
319
- const body = JSON.stringify({ event: payload.event, payload: payload.payload });
320
- const signature = createHmac("sha256", webhook.secret).update(body).digest("hex");
321
- assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
322
- let responseStatus = null;
323
- let errorMessage = null;
324
- try {
325
- const response = await safeFetch(webhook.url, {
326
- method: "POST",
327
- headers: {
328
- "content-type": "application/json",
329
- "x-workhub-signature": signature
330
- },
331
- body
332
- }, { allowHttp: appConfig.env !== "production" });
333
- responseStatus = response.status;
334
- if (!response.ok) {
335
- throw new Error(`Webhook delivery failed with status ${response.status}.`);
336
- }
337
- } catch (error) {
338
- errorMessage = error instanceof Error ? error.message : String(error);
339
- await repositoryConnection`
340
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
341
- VALUES (
342
- ${webhook.id},
343
- ${payload.event},
344
- ${JSON.stringify(payload.payload)}::jsonb,
345
- ${responseStatus},
346
- ${errorMessage}
347
- )
348
- `;
349
- throw error instanceof Error ? error : new Error(errorMessage);
350
- }
351
- await repositoryConnection`
352
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
353
- VALUES (
354
- ${webhook.id},
355
- ${payload.event},
356
- ${JSON.stringify(payload.payload)}::jsonb,
357
- ${responseStatus}
358
- )
359
- `;
360
- }
361
- }
362
- var dispatchWebhookJob_default = DispatchWebhookJob;
@@ -1911,7 +1911,6 @@ var failedJobService_default = FailedJobService;
1911
1911
 
1912
1912
  // ../../src/core/queue/jobRegistry.ts
1913
1913
  class JobRegistry {
1914
- constructor() {}
1915
1914
  factories = new Map;
1916
1915
  instances = new WeakMap;
1917
1916
  register(name, factory) {
@@ -1935,9 +1934,24 @@ class JobRegistry {
1935
1934
  return [...this.factories.keys()];
1936
1935
  }
1937
1936
  }
1938
- var jobRegistry = new JobRegistry;
1937
+ var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
1938
+ function readSharedJobRegistry() {
1939
+ const globalRegistry = globalThis[JOB_REGISTRY_KEY];
1940
+ if (globalRegistry) {
1941
+ return globalRegistry;
1942
+ }
1943
+ const registry = new JobRegistry;
1944
+ globalThis[JOB_REGISTRY_KEY] = registry;
1945
+ return registry;
1946
+ }
1947
+ var jobRegistry = readSharedJobRegistry();
1939
1948
 
1940
1949
  // ../../src/core/contracts/serviceTokens.ts
1950
+ var CORE_CONFIG_TOKEN = "core.config";
1951
+ var CORE_CACHE_TOKEN = "core.cache";
1952
+ var CORE_QUEUE_TOKEN = "core.queue";
1953
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
1954
+ var CORE_AUTH_TOKEN = "core.auth";
1941
1955
  var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
1942
1956
  // ../../src/bootstrap/config.ts
1943
1957
  var DEFAULT_QUEUE_DRIVER = "sync";
@@ -2154,304 +2168,6 @@ function createQueueWorker(redisUrl, failedJobs = createFailedJobService()) {
2154
2168
  return new QueueWorker(redisUrl, failedJobs);
2155
2169
  }
2156
2170
 
2157
- // ../../src/core/jobs/dispatchWebhookJob.ts
2158
- import { createHmac } from "crypto";
2159
-
2160
- // ../../src/config/app.ts
2161
- var appConfig = {
2162
- name: "WorkHub",
2163
- env: process.env.APP_ENV ?? "local",
2164
- debug: (process.env.APP_DEBUG ?? "true") !== "false",
2165
- url: process.env.APP_URL ?? "http://localhost:3000",
2166
- apiPrefix: process.env.API_PREFIX ?? "/api/v1"
2167
- };
2168
-
2169
- // ../../src/core/queue/index.ts
2170
- class Job {
2171
- maxAttempts;
2172
- backoffMs;
2173
- priority;
2174
- }
2175
-
2176
- // ../../src/core/security/safeUrl.ts
2177
- import { lookup as dnsLookupImpl } from "dns/promises";
2178
- var dnsLookup = dnsLookupImpl;
2179
- var BLOCKED_HOSTNAMES = new Set([
2180
- "localhost",
2181
- "127.0.0.1",
2182
- "0.0.0.0",
2183
- "::1",
2184
- "metadata.google.internal"
2185
- ]);
2186
- function isPrivateIpv4(hostname) {
2187
- const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(hostname);
2188
- if (!match) {
2189
- return false;
2190
- }
2191
- const octets = match.slice(1, 5).map((part) => Number.parseInt(part, 10));
2192
- if (octets.some((octet) => octet < 0 || octet > 255)) {
2193
- return true;
2194
- }
2195
- const [a = 0, b = 0] = octets;
2196
- if (a === 10) {
2197
- return true;
2198
- }
2199
- if (a === 127) {
2200
- return true;
2201
- }
2202
- if (a === 0) {
2203
- return true;
2204
- }
2205
- if (a === 169 && b === 254) {
2206
- return true;
2207
- }
2208
- if (a === 172 && b >= 16 && b <= 31) {
2209
- return true;
2210
- }
2211
- if (a === 192 && b === 168) {
2212
- return true;
2213
- }
2214
- return false;
2215
- }
2216
- function isBlockedHostname(hostname) {
2217
- const normalized = hostname.trim().toLowerCase();
2218
- if (normalized.length === 0) {
2219
- return true;
2220
- }
2221
- if (BLOCKED_HOSTNAMES.has(normalized)) {
2222
- return true;
2223
- }
2224
- if (normalized.endsWith(".local") || normalized.endsWith(".internal")) {
2225
- return true;
2226
- }
2227
- if (normalized.includes(":")) {
2228
- return true;
2229
- }
2230
- return isPrivateIpv4(normalized);
2231
- }
2232
- function assertSafeOutboundUrl(rawUrl, options = {}) {
2233
- let parsed;
2234
- try {
2235
- parsed = new URL(rawUrl);
2236
- } catch {
2237
- throw new BadRequestError("Webhook URL is invalid.");
2238
- }
2239
- if (parsed.protocol !== "https:" && !(options.allowHttp && parsed.protocol === "http:")) {
2240
- throw new BadRequestError("Webhook URL must use HTTPS.");
2241
- }
2242
- if (parsed.username || parsed.password) {
2243
- throw new BadRequestError("Webhook URL must not include credentials.");
2244
- }
2245
- if (isBlockedHostname(parsed.hostname)) {
2246
- throw new BadRequestError("Webhook URL targets a blocked host.");
2247
- }
2248
- return parsed;
2249
- }
2250
- function isBlockedIpAddress(address) {
2251
- return isBlockedHostname(address.trim().toLowerCase());
2252
- }
2253
- async function assertSafeOutboundUrlResolved(rawUrl, options = {}) {
2254
- const parsed = assertSafeOutboundUrl(rawUrl, options);
2255
- if (options.resolveDns === false) {
2256
- return parsed;
2257
- }
2258
- const hostname = parsed.hostname.trim().toLowerCase();
2259
- const results = await dnsLookup(hostname, { all: true, verbatim: true });
2260
- if (results.some((result) => isBlockedIpAddress(result.address))) {
2261
- throw new BadRequestError("Webhook URL targets a blocked host.");
2262
- }
2263
- return parsed;
2264
- }
2265
- function setDnsLookupForTests(lookupFn) {
2266
- dnsLookup = lookupFn;
2267
- }
2268
- function resetDnsLookupForTests() {
2269
- dnsLookup = dnsLookupImpl;
2270
- }
2271
-
2272
- // ../../src/core/security/safeFetch.ts
2273
- var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
2274
- async function safeFetch(input, init = {}, options = {}) {
2275
- const timeoutMs = options.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
2276
- const maxRedirects = options.maxRedirects ?? 0;
2277
- const resolveDns = options.resolveDns ?? appConfig.env === "production";
2278
- const urlOptions = { allowHttp: options.allowHttp, resolveDns };
2279
- const controller = new AbortController;
2280
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
2281
- try {
2282
- let currentUrl = (await assertSafeOutboundUrlResolved(input, urlOptions)).toString();
2283
- let redirectCount = 0;
2284
- while (true) {
2285
- const response = await fetch(currentUrl, {
2286
- ...init,
2287
- signal: controller.signal,
2288
- redirect: "manual"
2289
- });
2290
- if (response.status >= 300 && response.status < 400) {
2291
- const location = response.headers.get("location");
2292
- if (!location || redirectCount >= maxRedirects) {
2293
- return response;
2294
- }
2295
- currentUrl = (await assertSafeOutboundUrlResolved(new URL(location, currentUrl).toString(), urlOptions)).toString();
2296
- redirectCount += 1;
2297
- continue;
2298
- }
2299
- return response;
2300
- }
2301
- } finally {
2302
- clearTimeout(timeout);
2303
- }
2304
- }
2305
-
2306
- // ../../src/core/jobs/dispatchWebhookJob.ts
2307
- class DispatchWebhookJob extends Job {
2308
- maxAttempts = 3;
2309
- backoffMs = 2000;
2310
- async handle(payload) {
2311
- const rows = await repositoryConnection`
2312
- SELECT id, url, secret
2313
- FROM webhook
2314
- WHERE id = ${payload.webhookId} AND active = TRUE
2315
- LIMIT 1
2316
- `;
2317
- const webhook = rows[0];
2318
- if (!webhook) {
2319
- return;
2320
- }
2321
- const body = JSON.stringify({ event: payload.event, payload: payload.payload });
2322
- const signature = createHmac("sha256", webhook.secret).update(body).digest("hex");
2323
- assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
2324
- let responseStatus = null;
2325
- let errorMessage = null;
2326
- try {
2327
- const response = await safeFetch(webhook.url, {
2328
- method: "POST",
2329
- headers: {
2330
- "content-type": "application/json",
2331
- "x-workhub-signature": signature
2332
- },
2333
- body
2334
- }, { allowHttp: appConfig.env !== "production" });
2335
- responseStatus = response.status;
2336
- if (!response.ok) {
2337
- throw new Error(`Webhook delivery failed with status ${response.status}.`);
2338
- }
2339
- } catch (error) {
2340
- errorMessage = error instanceof Error ? error.message : String(error);
2341
- await repositoryConnection`
2342
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
2343
- VALUES (
2344
- ${webhook.id},
2345
- ${payload.event},
2346
- ${JSON.stringify(payload.payload)}::jsonb,
2347
- ${responseStatus},
2348
- ${errorMessage}
2349
- )
2350
- `;
2351
- throw error instanceof Error ? error : new Error(errorMessage);
2352
- }
2353
- await repositoryConnection`
2354
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
2355
- VALUES (
2356
- ${webhook.id},
2357
- ${payload.event},
2358
- ${JSON.stringify(payload.payload)}::jsonb,
2359
- ${responseStatus}
2360
- )
2361
- `;
2362
- }
2363
- }
2364
- var dispatchWebhookJob_default = DispatchWebhookJob;
2365
-
2366
- // ../../src/core/jobs/invalidateCacheTagsJob.ts
2367
- class InvalidateCacheTagsJob extends Job {
2368
- cache;
2369
- constructor(cache) {
2370
- super();
2371
- this.cache = cache;
2372
- }
2373
- async handle(payload) {
2374
- await this.cache.tags(...payload.tags).flush();
2375
- }
2376
- }
2377
- var invalidateCacheTagsJob_default = InvalidateCacheTagsJob;
2378
-
2379
- // ../../src/core/contracts/applicationContext.ts
2380
- function getRequiredDependency(dependencies, key) {
2381
- const dependency = dependencies[key];
2382
- if (dependency === undefined) {
2383
- throw new Error(`Required dependency "${String(key)}" is not registered.`);
2384
- }
2385
- return dependency;
2386
- }
2387
-
2388
- // ../../src/core/logging/logger.ts
2389
- class Logger {
2390
- channel;
2391
- constructor(channel = "app") {
2392
- this.channel = channel;
2393
- }
2394
- write(level, message, context = {}) {
2395
- const entry = {
2396
- level,
2397
- channel: this.channel,
2398
- message,
2399
- timestamp: new Date().toISOString(),
2400
- ...context
2401
- };
2402
- const line = JSON.stringify(entry);
2403
- if (level === "error") {
2404
- console.error(line);
2405
- return;
2406
- }
2407
- console.log(line);
2408
- }
2409
- debug(message, context) {
2410
- this.write("debug", message, context);
2411
- }
2412
- info(message, context) {
2413
- this.write("info", message, context);
2414
- }
2415
- warn(message, context) {
2416
- this.write("warn", message, context);
2417
- }
2418
- error(message, context) {
2419
- this.write("error", message, context);
2420
- }
2421
- }
2422
- var appLogger = new Logger("app");
2423
-
2424
- // ../../src/core/runtime/applicationRegistry.ts
2425
- var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
2426
- var activeContext;
2427
- function readStoredApplicationContext() {
2428
- if (activeContext) {
2429
- return activeContext;
2430
- }
2431
- const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
2432
- if (globalContext) {
2433
- activeContext = globalContext;
2434
- }
2435
- return activeContext;
2436
- }
2437
- function requireActiveApplicationContext() {
2438
- const context = readStoredApplicationContext();
2439
- if (!context) {
2440
- throw new Error("The application context has not been bootstrapped.");
2441
- }
2442
- return context;
2443
- }
2444
- function resolveApplicationCache() {
2445
- return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
2446
- }
2447
- // ../../src/bootstrap/queue/defaultJobs.ts
2448
- function registerDefaultJobs() {
2449
- jobRegistry.register("cache.invalidate-tags", () => {
2450
- return new invalidateCacheTagsJob_default(resolveApplicationCache());
2451
- });
2452
- jobRegistry.register("webhook.dispatch", () => new dispatchWebhookJob_default);
2453
- }
2454
-
2455
2171
  // ../../src/core/queue/createAppQueue.ts
2456
2172
  var FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
2457
2173
  function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(), registerJobs) {
@@ -2462,7 +2178,6 @@ function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(),
2462
2178
  });
2463
2179
  }
2464
2180
  export {
2465
- registerDefaultJobs,
2466
2181
  createTrackedJob,
2467
2182
  createQueueWorker,
2468
2183
  createFailedJobService,
@@ -1,32 +1 @@
1
- // @bun
2
- // ../../src/core/queue/jobRegistry.ts
3
- class JobRegistry {
4
- constructor() {}
5
- factories = new Map;
6
- instances = new WeakMap;
7
- register(name, factory) {
8
- this.factories.set(name, factory);
9
- }
10
- resolveName(job) {
11
- return this.instances.get(job);
12
- }
13
- track(name, job) {
14
- this.instances.set(job, name);
15
- return job;
16
- }
17
- create(name) {
18
- const factory = this.factories.get(name);
19
- if (!factory) {
20
- return;
21
- }
22
- return factory();
23
- }
24
- names() {
25
- return [...this.factories.keys()];
26
- }
27
- }
28
- var jobRegistry = new JobRegistry;
29
- export {
30
- jobRegistry,
31
- JobRegistry
32
- };
1
+ export * from "../../index.js";
@@ -1,5 +1,10 @@
1
1
  // @bun
2
2
  // ../../src/core/contracts/serviceTokens.ts
3
+ var CORE_CONFIG_TOKEN = "core.config";
4
+ var CORE_CACHE_TOKEN = "core.cache";
5
+ var CORE_QUEUE_TOKEN = "core.queue";
6
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
7
+ var CORE_AUTH_TOKEN = "core.auth";
3
8
  var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
4
9
  // ../../src/bootstrap/config.ts
5
10
  var DEFAULT_QUEUE_DRIVER = "sync";
@@ -13,7 +18,6 @@ var queueConfig = {
13
18
 
14
19
  // ../../src/core/queue/jobRegistry.ts
15
20
  class JobRegistry {
16
- constructor() {}
17
21
  factories = new Map;
18
22
  instances = new WeakMap;
19
23
  register(name, factory) {
@@ -37,7 +41,17 @@ class JobRegistry {
37
41
  return [...this.factories.keys()];
38
42
  }
39
43
  }
40
- var jobRegistry = new JobRegistry;
44
+ var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
45
+ function readSharedJobRegistry() {
46
+ const globalRegistry = globalThis[JOB_REGISTRY_KEY];
47
+ if (globalRegistry) {
48
+ return globalRegistry;
49
+ }
50
+ const registry = new JobRegistry;
51
+ globalThis[JOB_REGISTRY_KEY] = registry;
52
+ return registry;
53
+ }
54
+ var jobRegistry = readSharedJobRegistry();
41
55
 
42
56
  // ../../src/core/queue/jobRunner.ts
43
57
  async function runQueueJob(envelope, failedJobs) {
@@ -1911,7 +1911,6 @@ var failedJobService_default = FailedJobService;
1911
1911
 
1912
1912
  // ../../src/core/queue/jobRegistry.ts
1913
1913
  class JobRegistry {
1914
- constructor() {}
1915
1914
  factories = new Map;
1916
1915
  instances = new WeakMap;
1917
1916
  register(name, factory) {
@@ -1935,9 +1934,24 @@ class JobRegistry {
1935
1934
  return [...this.factories.keys()];
1936
1935
  }
1937
1936
  }
1938
- var jobRegistry = new JobRegistry;
1937
+ var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
1938
+ function readSharedJobRegistry() {
1939
+ const globalRegistry = globalThis[JOB_REGISTRY_KEY];
1940
+ if (globalRegistry) {
1941
+ return globalRegistry;
1942
+ }
1943
+ const registry = new JobRegistry;
1944
+ globalThis[JOB_REGISTRY_KEY] = registry;
1945
+ return registry;
1946
+ }
1947
+ var jobRegistry = readSharedJobRegistry();
1939
1948
 
1940
1949
  // ../../src/core/contracts/serviceTokens.ts
1950
+ var CORE_CONFIG_TOKEN = "core.config";
1951
+ var CORE_CACHE_TOKEN = "core.cache";
1952
+ var CORE_QUEUE_TOKEN = "core.queue";
1953
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
1954
+ var CORE_AUTH_TOKEN = "core.auth";
1941
1955
  var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
1942
1956
  // ../../src/bootstrap/config.ts
1943
1957
  var DEFAULT_QUEUE_DRIVER = "sync";
@@ -3,6 +3,11 @@
3
3
  var {RedisClient: RedisClient2 } = globalThis.Bun;
4
4
 
5
5
  // ../../src/core/contracts/serviceTokens.ts
6
+ var CORE_CONFIG_TOKEN = "core.config";
7
+ var CORE_CACHE_TOKEN = "core.cache";
8
+ var CORE_QUEUE_TOKEN = "core.queue";
9
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
10
+ var CORE_AUTH_TOKEN = "core.auth";
6
11
  var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
7
12
  // ../../src/bootstrap/config.ts
8
13
  var DEFAULT_QUEUE_DRIVER = "sync";
@@ -1926,7 +1931,6 @@ var failedJobService_default = FailedJobService;
1926
1931
 
1927
1932
  // ../../src/core/queue/jobRegistry.ts
1928
1933
  class JobRegistry {
1929
- constructor() {}
1930
1934
  factories = new Map;
1931
1935
  instances = new WeakMap;
1932
1936
  register(name, factory) {
@@ -1950,7 +1954,17 @@ class JobRegistry {
1950
1954
  return [...this.factories.keys()];
1951
1955
  }
1952
1956
  }
1953
- var jobRegistry = new JobRegistry;
1957
+ var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
1958
+ function readSharedJobRegistry() {
1959
+ const globalRegistry = globalThis[JOB_REGISTRY_KEY];
1960
+ if (globalRegistry) {
1961
+ return globalRegistry;
1962
+ }
1963
+ const registry = new JobRegistry;
1964
+ globalThis[JOB_REGISTRY_KEY] = registry;
1965
+ return registry;
1966
+ }
1967
+ var jobRegistry = readSharedJobRegistry();
1954
1968
 
1955
1969
  // ../../src/core/queue/jobRunner.ts
1956
1970
  async function runQueueJob(envelope, failedJobs) {
@@ -2157,304 +2171,6 @@ function createQueueWorker(redisUrl, failedJobs = createFailedJobService()) {
2157
2171
  return new QueueWorker(redisUrl, failedJobs);
2158
2172
  }
2159
2173
 
2160
- // ../../src/core/jobs/dispatchWebhookJob.ts
2161
- import { createHmac } from "crypto";
2162
-
2163
- // ../../src/config/app.ts
2164
- var appConfig = {
2165
- name: "WorkHub",
2166
- env: process.env.APP_ENV ?? "local",
2167
- debug: (process.env.APP_DEBUG ?? "true") !== "false",
2168
- url: process.env.APP_URL ?? "http://localhost:3000",
2169
- apiPrefix: process.env.API_PREFIX ?? "/api/v1"
2170
- };
2171
-
2172
- // ../../src/core/queue/index.ts
2173
- class Job {
2174
- maxAttempts;
2175
- backoffMs;
2176
- priority;
2177
- }
2178
-
2179
- // ../../src/core/security/safeUrl.ts
2180
- import { lookup as dnsLookupImpl } from "dns/promises";
2181
- var dnsLookup = dnsLookupImpl;
2182
- var BLOCKED_HOSTNAMES = new Set([
2183
- "localhost",
2184
- "127.0.0.1",
2185
- "0.0.0.0",
2186
- "::1",
2187
- "metadata.google.internal"
2188
- ]);
2189
- function isPrivateIpv4(hostname) {
2190
- const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(hostname);
2191
- if (!match) {
2192
- return false;
2193
- }
2194
- const octets = match.slice(1, 5).map((part) => Number.parseInt(part, 10));
2195
- if (octets.some((octet) => octet < 0 || octet > 255)) {
2196
- return true;
2197
- }
2198
- const [a = 0, b = 0] = octets;
2199
- if (a === 10) {
2200
- return true;
2201
- }
2202
- if (a === 127) {
2203
- return true;
2204
- }
2205
- if (a === 0) {
2206
- return true;
2207
- }
2208
- if (a === 169 && b === 254) {
2209
- return true;
2210
- }
2211
- if (a === 172 && b >= 16 && b <= 31) {
2212
- return true;
2213
- }
2214
- if (a === 192 && b === 168) {
2215
- return true;
2216
- }
2217
- return false;
2218
- }
2219
- function isBlockedHostname(hostname) {
2220
- const normalized = hostname.trim().toLowerCase();
2221
- if (normalized.length === 0) {
2222
- return true;
2223
- }
2224
- if (BLOCKED_HOSTNAMES.has(normalized)) {
2225
- return true;
2226
- }
2227
- if (normalized.endsWith(".local") || normalized.endsWith(".internal")) {
2228
- return true;
2229
- }
2230
- if (normalized.includes(":")) {
2231
- return true;
2232
- }
2233
- return isPrivateIpv4(normalized);
2234
- }
2235
- function assertSafeOutboundUrl(rawUrl, options = {}) {
2236
- let parsed;
2237
- try {
2238
- parsed = new URL(rawUrl);
2239
- } catch {
2240
- throw new BadRequestError("Webhook URL is invalid.");
2241
- }
2242
- if (parsed.protocol !== "https:" && !(options.allowHttp && parsed.protocol === "http:")) {
2243
- throw new BadRequestError("Webhook URL must use HTTPS.");
2244
- }
2245
- if (parsed.username || parsed.password) {
2246
- throw new BadRequestError("Webhook URL must not include credentials.");
2247
- }
2248
- if (isBlockedHostname(parsed.hostname)) {
2249
- throw new BadRequestError("Webhook URL targets a blocked host.");
2250
- }
2251
- return parsed;
2252
- }
2253
- function isBlockedIpAddress(address) {
2254
- return isBlockedHostname(address.trim().toLowerCase());
2255
- }
2256
- async function assertSafeOutboundUrlResolved(rawUrl, options = {}) {
2257
- const parsed = assertSafeOutboundUrl(rawUrl, options);
2258
- if (options.resolveDns === false) {
2259
- return parsed;
2260
- }
2261
- const hostname = parsed.hostname.trim().toLowerCase();
2262
- const results = await dnsLookup(hostname, { all: true, verbatim: true });
2263
- if (results.some((result) => isBlockedIpAddress(result.address))) {
2264
- throw new BadRequestError("Webhook URL targets a blocked host.");
2265
- }
2266
- return parsed;
2267
- }
2268
- function setDnsLookupForTests(lookupFn) {
2269
- dnsLookup = lookupFn;
2270
- }
2271
- function resetDnsLookupForTests() {
2272
- dnsLookup = dnsLookupImpl;
2273
- }
2274
-
2275
- // ../../src/core/security/safeFetch.ts
2276
- var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
2277
- async function safeFetch(input, init = {}, options = {}) {
2278
- const timeoutMs = options.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
2279
- const maxRedirects = options.maxRedirects ?? 0;
2280
- const resolveDns = options.resolveDns ?? appConfig.env === "production";
2281
- const urlOptions = { allowHttp: options.allowHttp, resolveDns };
2282
- const controller = new AbortController;
2283
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
2284
- try {
2285
- let currentUrl = (await assertSafeOutboundUrlResolved(input, urlOptions)).toString();
2286
- let redirectCount = 0;
2287
- while (true) {
2288
- const response = await fetch(currentUrl, {
2289
- ...init,
2290
- signal: controller.signal,
2291
- redirect: "manual"
2292
- });
2293
- if (response.status >= 300 && response.status < 400) {
2294
- const location = response.headers.get("location");
2295
- if (!location || redirectCount >= maxRedirects) {
2296
- return response;
2297
- }
2298
- currentUrl = (await assertSafeOutboundUrlResolved(new URL(location, currentUrl).toString(), urlOptions)).toString();
2299
- redirectCount += 1;
2300
- continue;
2301
- }
2302
- return response;
2303
- }
2304
- } finally {
2305
- clearTimeout(timeout);
2306
- }
2307
- }
2308
-
2309
- // ../../src/core/jobs/dispatchWebhookJob.ts
2310
- class DispatchWebhookJob extends Job {
2311
- maxAttempts = 3;
2312
- backoffMs = 2000;
2313
- async handle(payload) {
2314
- const rows = await repositoryConnection`
2315
- SELECT id, url, secret
2316
- FROM webhook
2317
- WHERE id = ${payload.webhookId} AND active = TRUE
2318
- LIMIT 1
2319
- `;
2320
- const webhook = rows[0];
2321
- if (!webhook) {
2322
- return;
2323
- }
2324
- const body = JSON.stringify({ event: payload.event, payload: payload.payload });
2325
- const signature = createHmac("sha256", webhook.secret).update(body).digest("hex");
2326
- assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
2327
- let responseStatus = null;
2328
- let errorMessage = null;
2329
- try {
2330
- const response = await safeFetch(webhook.url, {
2331
- method: "POST",
2332
- headers: {
2333
- "content-type": "application/json",
2334
- "x-workhub-signature": signature
2335
- },
2336
- body
2337
- }, { allowHttp: appConfig.env !== "production" });
2338
- responseStatus = response.status;
2339
- if (!response.ok) {
2340
- throw new Error(`Webhook delivery failed with status ${response.status}.`);
2341
- }
2342
- } catch (error) {
2343
- errorMessage = error instanceof Error ? error.message : String(error);
2344
- await repositoryConnection`
2345
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
2346
- VALUES (
2347
- ${webhook.id},
2348
- ${payload.event},
2349
- ${JSON.stringify(payload.payload)}::jsonb,
2350
- ${responseStatus},
2351
- ${errorMessage}
2352
- )
2353
- `;
2354
- throw error instanceof Error ? error : new Error(errorMessage);
2355
- }
2356
- await repositoryConnection`
2357
- INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
2358
- VALUES (
2359
- ${webhook.id},
2360
- ${payload.event},
2361
- ${JSON.stringify(payload.payload)}::jsonb,
2362
- ${responseStatus}
2363
- )
2364
- `;
2365
- }
2366
- }
2367
- var dispatchWebhookJob_default = DispatchWebhookJob;
2368
-
2369
- // ../../src/core/jobs/invalidateCacheTagsJob.ts
2370
- class InvalidateCacheTagsJob extends Job {
2371
- cache;
2372
- constructor(cache) {
2373
- super();
2374
- this.cache = cache;
2375
- }
2376
- async handle(payload) {
2377
- await this.cache.tags(...payload.tags).flush();
2378
- }
2379
- }
2380
- var invalidateCacheTagsJob_default = InvalidateCacheTagsJob;
2381
-
2382
- // ../../src/core/contracts/applicationContext.ts
2383
- function getRequiredDependency(dependencies, key) {
2384
- const dependency = dependencies[key];
2385
- if (dependency === undefined) {
2386
- throw new Error(`Required dependency "${String(key)}" is not registered.`);
2387
- }
2388
- return dependency;
2389
- }
2390
-
2391
- // ../../src/core/logging/logger.ts
2392
- class Logger {
2393
- channel;
2394
- constructor(channel = "app") {
2395
- this.channel = channel;
2396
- }
2397
- write(level, message, context = {}) {
2398
- const entry = {
2399
- level,
2400
- channel: this.channel,
2401
- message,
2402
- timestamp: new Date().toISOString(),
2403
- ...context
2404
- };
2405
- const line = JSON.stringify(entry);
2406
- if (level === "error") {
2407
- console.error(line);
2408
- return;
2409
- }
2410
- console.log(line);
2411
- }
2412
- debug(message, context) {
2413
- this.write("debug", message, context);
2414
- }
2415
- info(message, context) {
2416
- this.write("info", message, context);
2417
- }
2418
- warn(message, context) {
2419
- this.write("warn", message, context);
2420
- }
2421
- error(message, context) {
2422
- this.write("error", message, context);
2423
- }
2424
- }
2425
- var appLogger = new Logger("app");
2426
-
2427
- // ../../src/core/runtime/applicationRegistry.ts
2428
- var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
2429
- var activeContext;
2430
- function readStoredApplicationContext() {
2431
- if (activeContext) {
2432
- return activeContext;
2433
- }
2434
- const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
2435
- if (globalContext) {
2436
- activeContext = globalContext;
2437
- }
2438
- return activeContext;
2439
- }
2440
- function requireActiveApplicationContext() {
2441
- const context = readStoredApplicationContext();
2442
- if (!context) {
2443
- throw new Error("The application context has not been bootstrapped.");
2444
- }
2445
- return context;
2446
- }
2447
- function resolveApplicationCache() {
2448
- return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
2449
- }
2450
- // ../../src/bootstrap/queue/defaultJobs.ts
2451
- function registerDefaultJobs() {
2452
- jobRegistry.register("cache.invalidate-tags", () => {
2453
- return new invalidateCacheTagsJob_default(resolveApplicationCache());
2454
- });
2455
- jobRegistry.register("webhook.dispatch", () => new dispatchWebhookJob_default);
2456
- }
2457
-
2458
2174
  // ../../src/core/queue/createAppQueue.ts
2459
2175
  var FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
2460
2176
  function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(), registerJobs) {
@@ -45,6 +45,11 @@ function isHtmxRequest(request) {
45
45
  return request.headers.get("HX-Request") === "true";
46
46
  }
47
47
  // ../../src/core/contracts/serviceTokens.ts
48
+ var CORE_CONFIG_TOKEN = "core.config";
49
+ var CORE_CACHE_TOKEN = "core.cache";
50
+ var CORE_QUEUE_TOKEN = "core.queue";
51
+ var CORE_POLICY_GATE_TOKEN = "core.policyGate";
52
+ var CORE_AUTH_TOKEN = "core.auth";
48
53
  var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
49
54
  // ../../src/bootstrap/config.ts
50
55
  var DEFAULT_QUEUE_DRIVER = "sync";
@@ -19,7 +19,6 @@ export { default as MembershipService, resolveMembershipService, } from "../core
19
19
  export { Policy, PolicyGate } from "../core/auth/policy.ts";
20
20
  export { createScimAuthMiddleware } from "../core/auth/scimAuthMiddleware.ts";
21
21
  export { type CacheDriver, type CreateCacheStoreOptions, createCacheStore, } from "../core/cache/createCacheStore.ts";
22
- export { cacheTagsForModelWrite, discoverModelTableNames } from "../core/cache/modelCacheTags.ts";
23
22
  export { default as CacheRepository } from "../core/cache/repository.ts";
24
23
  export { CACHE_TAGS } from "../core/cache/tags.ts";
25
24
  export type { DatabaseConnection } from "../core/database/baseRepository.ts";
package/dist/index.js CHANGED
@@ -3311,7 +3311,8 @@ function resolveApplicationLogger() {
3311
3311
  function resolveApplicationDependencies() {
3312
3312
  return requireActiveApplicationContext().dependencies;
3313
3313
  }
3314
- // ../../src/bootstrap/membershipService.ts
3314
+
3315
+ // ../../src/core/auth/resolveMembershipService.ts
3315
3316
  function resolveMembershipService() {
3316
3317
  const dependencies = resolveApplicationDependencies();
3317
3318
  if (dependencies.container.has("core.membership")) {
@@ -3922,23 +3923,6 @@ function createCacheStore(options) {
3922
3923
  }
3923
3924
  return new simpleCacheStore_default(new simpleCache_default(options.ttlMs, options.maxEntries));
3924
3925
  }
3925
- // ../../src/bootstrap/discoverModules.ts
3926
- var appModules = [];
3927
- function discoverModules() {
3928
- return appModules;
3929
- }
3930
-
3931
- // ../../src/bootstrap/cache/modelCacheTags.ts
3932
- function cacheTagsForModelWrite(tableName, action) {
3933
- const module = discoverModules().find((entry) => entry.tableName === tableName);
3934
- const baseTags = module?.cacheTags ?? [`${tableName}s`];
3935
- const isDelete = action === "deleted" || action === "force-deleted";
3936
- const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
3937
- return [...new Set([...baseTags, ...extraTags])];
3938
- }
3939
- function discoverModelTableNames() {
3940
- return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
3941
- }
3942
3926
  // ../../src/core/cache/taggedCache.ts
3943
3927
  class TaggedCache {
3944
3928
  store;
@@ -5307,7 +5291,7 @@ function bindRouteModel(param, resolver, handler) {
5307
5291
  return await handler(request, model);
5308
5292
  };
5309
5293
  }
5310
- // ../../src/bootstrap/http/securedRouteModelBinding.ts
5294
+ // ../../src/core/http/securedRouteModelBinding.ts
5311
5295
  function isMutatingPolicyAction(action) {
5312
5296
  return action === "update" || action === "delete";
5313
5297
  }
@@ -6121,7 +6105,6 @@ var failedJobService_default = FailedJobService;
6121
6105
 
6122
6106
  // ../../src/core/queue/jobRegistry.ts
6123
6107
  class JobRegistry {
6124
- constructor() {}
6125
6108
  factories = new Map;
6126
6109
  instances = new WeakMap;
6127
6110
  register(name, factory) {
@@ -6145,7 +6128,17 @@ class JobRegistry {
6145
6128
  return [...this.factories.keys()];
6146
6129
  }
6147
6130
  }
6148
- var jobRegistry = new JobRegistry;
6131
+ var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
6132
+ function readSharedJobRegistry() {
6133
+ const globalRegistry = globalThis[JOB_REGISTRY_KEY];
6134
+ if (globalRegistry) {
6135
+ return globalRegistry;
6136
+ }
6137
+ const registry = new JobRegistry;
6138
+ globalThis[JOB_REGISTRY_KEY] = registry;
6139
+ return registry;
6140
+ }
6141
+ var jobRegistry = readSharedJobRegistry();
6149
6142
 
6150
6143
  // ../../src/config/queue.ts
6151
6144
  var queueConfig = {
@@ -6360,16 +6353,6 @@ function createQueueWorker(redisUrl, failedJobs = createFailedJobService()) {
6360
6353
  }
6361
6354
  // ../../src/core/queue/queueMetrics.ts
6362
6355
  var {RedisClient: RedisClient6 } = globalThis.Bun;
6363
-
6364
- // ../../src/core/security/safeUrl.ts
6365
- var BLOCKED_HOSTNAMES = new Set([
6366
- "localhost",
6367
- "127.0.0.1",
6368
- "0.0.0.0",
6369
- "::1",
6370
- "metadata.google.internal"
6371
- ]);
6372
- // ../../src/core/queue/queueMetrics.ts
6373
6356
  async function readRedisQueueDepth(redisUrl) {
6374
6357
  const client = new RedisClient6(redisUrl);
6375
6358
  const [high, defaultQueue, low] = await Promise.all([
@@ -6823,7 +6806,6 @@ export {
6823
6806
  etagFromResource,
6824
6807
  emptyPaginateResult,
6825
6808
  emailRule,
6826
- discoverModelTableNames,
6827
6809
  dehydrateValue,
6828
6810
  defineTable,
6829
6811
  currentTraceId,
@@ -6873,7 +6855,6 @@ export {
6873
6855
  composeMiddleware,
6874
6856
  compileBlueprint,
6875
6857
  collectQueueMetrics,
6876
- cacheTagsForModelWrite,
6877
6858
  cache,
6878
6859
  buildSmtpPayload,
6879
6860
  buildRequestCacheKey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/core",
3
- "version": "0.5.21",
3
+ "version": "0.5.25",
4
4
  "description": "Strata — Laravel-inspired Bun framework public API",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -95,6 +95,11 @@
95
95
  "import": "./dist/entries/cache/createCacheStore.js",
96
96
  "default": "./dist/entries/cache/createCacheStore.js"
97
97
  },
98
+ "./contracts/serviceTokens": {
99
+ "types": "./dist/core/contracts/serviceTokens.d.ts",
100
+ "import": "./dist/entries/contracts/serviceTokens.js",
101
+ "default": "./dist/entries/contracts/serviceTokens.js"
102
+ },
98
103
  "./crypto/fieldEncryption": {
99
104
  "types": "./dist/core/crypto/fieldEncryption.d.ts",
100
105
  "import": "./dist/entries/crypto/fieldEncryption.js",
@@ -322,7 +327,7 @@
322
327
  "build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta",
323
328
  "build:types": "tsc -p tsconfig.types.json",
324
329
  "prepublishOnly": "bun run build && bun ../../scripts/prepare-core-package-publish.ts",
325
- "build:subpaths": "bun build entries/auth/oauth/oidcProvider.ts entries/auth/oauth/providers.ts entries/auth/oauth/samlProvider.ts entries/auth/oauth/types.ts entries/auth/password.ts entries/auth/sessionCookie.ts entries/auth/tokenHash.ts entries/cache/tags.ts entries/cache/createCacheStore.ts entries/crypto/fieldEncryption.ts entries/crypto/mfaSecret.ts entries/database/factory.ts entries/database/seeders.ts entries/database/types.ts entries/errors/http.ts entries/http/contentNegotiation.ts entries/http/csrfToken.ts entries/http/etag.ts entries/http/flashSession.ts entries/http/parseFormBody.ts entries/http/resources.ts entries/http/webErrorResponse.ts entries/http/webFormRequest.ts entries/jobs/dispatchWebhookJob.ts entries/lifecycle/gracefulShutdown.ts entries/metrics/prometheus.ts entries/pagination.ts entries/queue/createAppQueue.ts entries/queue/failedJobService.ts entries/queue/jobRegistry.ts entries/queue/jobRunner.ts entries/queue/queueMetrics.ts entries/queue/publicQueue.ts entries/queue/types.ts entries/security/oauthState.ts entries/security/publicReads.ts entries/security/safeUrl.ts entries/security/stripeWebhook.ts entries/security/tokenExpiry.ts entries/security/totp.ts entries/storage/storage.ts entries/validation/rules.ts entries/view.ts --outdir dist --root . --target bun --external bun --external eta",
330
+ "build:subpaths": "bun build entries/auth/oauth/oidcProvider.ts entries/auth/oauth/providers.ts entries/auth/oauth/samlProvider.ts entries/auth/oauth/types.ts entries/auth/password.ts entries/auth/sessionCookie.ts entries/auth/tokenHash.ts entries/cache/tags.ts entries/cache/createCacheStore.ts entries/contracts/serviceTokens.ts entries/crypto/fieldEncryption.ts entries/crypto/mfaSecret.ts entries/database/factory.ts entries/database/seeders.ts entries/database/types.ts entries/errors/http.ts entries/http/contentNegotiation.ts entries/http/csrfToken.ts entries/http/etag.ts entries/http/flashSession.ts entries/http/parseFormBody.ts entries/http/resources.ts entries/http/webErrorResponse.ts entries/http/webFormRequest.ts entries/jobs/dispatchWebhookJob.ts entries/lifecycle/gracefulShutdown.ts entries/metrics/prometheus.ts entries/pagination.ts entries/queue/createAppQueue.ts entries/queue/failedJobService.ts entries/queue/jobRunner.ts entries/queue/queueMetrics.ts entries/queue/publicQueue.ts entries/queue/types.ts entries/security/oauthState.ts entries/security/publicReads.ts entries/security/safeUrl.ts entries/security/stripeWebhook.ts entries/security/tokenExpiry.ts entries/security/totp.ts entries/storage/storage.ts entries/validation/rules.ts entries/view.ts --outdir dist --root . --target bun --external bun --external eta",
326
331
  "build:shims": "bun ../../scripts/write-core-shared-shims.ts"
327
332
  },
328
333
  "publishConfig": {
@@ -1 +0,0 @@
1
- export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "../core/runtime/applicationRegistry.ts";
@@ -1,3 +0,0 @@
1
- declare function cacheTagsForModelWrite(tableName: string, action: string): string[];
2
- declare function discoverModelTableNames(): string[];
3
- export { cacheTagsForModelWrite, discoverModelTableNames };
@@ -1,5 +0,0 @@
1
- import type { AppModule } from "./contracts";
2
- declare let appModules: AppModule[];
3
- declare function ensureModulesLoaded(): Promise<AppModule[]>;
4
- declare function discoverModules(): AppModule[];
5
- export { appModules, discoverModules, ensureModulesLoaded };
@@ -1,11 +0,0 @@
1
- import type { Policy } from "../../core/auth/policy";
2
- import type { RouteRequest } from "../../core/http/route";
3
- interface RouteModelAuthorization {
4
- resource: string;
5
- action: keyof Policy;
6
- requireIfMatch?: boolean;
7
- }
8
- declare function securedBindRouteModel<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (id: number, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
9
- declare function securedBindRouteModelByKey<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (key: string, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
10
- export type { RouteModelAuthorization };
11
- export { securedBindRouteModel, securedBindRouteModelByKey };
@@ -1,2 +0,0 @@
1
- declare function registerDefaultJobs(): void;
2
- export { registerDefaultJobs };
@@ -1 +0,0 @@
1
- export { cacheTagsForModelWrite, discoverModelTableNames, } from "../../bootstrap/cache/modelCacheTags.ts";