@getstrata/bootstrap 0.1.0 → 0.2.0
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/bootstrap/context.d.ts +6 -0
- package/dist/bootstrap/createWebRoutes.d.ts +4 -0
- package/dist/bootstrap/discoverListeners.d.ts +5 -0
- package/dist/bootstrap/discoverModules.d.ts +4 -0
- package/dist/bootstrap/env.d.ts +9 -0
- package/dist/bootstrap/httpKernel.d.ts +2 -0
- package/dist/bootstrap/listeners/invalidateCacheOnModelWrite.d.ts +3 -0
- package/dist/bootstrap/modules.d.ts +1 -0
- package/dist/bootstrap/providers/auth.d.ts +3 -0
- package/dist/bootstrap/providers/cache.d.ts +3 -0
- package/dist/bootstrap/providers/config.d.ts +5 -0
- package/dist/bootstrap/providers/events.d.ts +5 -0
- package/dist/bootstrap/providers/index.d.ts +3 -0
- package/dist/bootstrap/providers/listeners.d.ts +3 -0
- package/dist/bootstrap/providers/policy.d.ts +3 -0
- package/dist/bootstrap/providers/queue.d.ts +3 -0
- package/dist/bootstrap/providers/view.d.ts +5 -0
- package/dist/bootstrap/public-api.d.ts +7 -1
- package/dist/bootstrap/routeRegistry.d.ts +14 -0
- package/dist/bootstrap/schedule.d.ts +1 -0
- package/dist/bootstrap/secretsGuard.d.ts +2 -0
- package/dist/bootstrap/web/session.d.ts +2 -0
- package/dist/cli/commands/scheduleRun.d.ts +3 -0
- package/dist/config/auth.d.ts +7 -0
- package/dist/config/queue.d.ts +8 -0
- package/dist/config/rateLimit.d.ts +2 -1
- package/dist/core/audit/exportAuditLogs.d.ts +8 -0
- package/dist/core/audit/siemFormatter.d.ts +30 -0
- package/dist/core/auth/abilityChecker.d.ts +6 -0
- package/dist/core/auth/policy.d.ts +2 -2
- package/dist/core/auth/sessionCookie.d.ts +6 -0
- package/dist/core/auth/sessionGuard.d.ts +9 -0
- package/dist/core/cache/createCacheStore.d.ts +11 -0
- package/dist/core/cache/modelCacheTags.d.ts +3 -0
- package/dist/core/cache/redisCacheStore.d.ts +23 -0
- package/dist/core/cache/repository.d.ts +17 -0
- package/dist/core/cache/simpleCache.d.ts +23 -0
- package/dist/core/cache/simpleCacheStore.d.ts +16 -0
- package/dist/core/cache/store.d.ts +12 -0
- package/dist/core/cache/taggedCache.d.ts +9 -0
- package/dist/core/config/envSchema.d.ts +12 -0
- package/dist/core/database/baseRepository.d.ts +22 -7
- package/dist/core/database/boundConnection.d.ts +5 -0
- package/dist/core/database/index.d.ts +11 -4
- package/dist/core/database/migrations/types.d.ts +15 -0
- package/dist/core/database/model.d.ts +57 -0
- package/dist/core/database/query.d.ts +26 -14
- package/dist/core/database/relationships.d.ts +32 -2
- package/dist/core/database/repositoryConnection.d.ts +4 -0
- package/dist/core/database/repositoryQuery.d.ts +35 -0
- package/dist/core/database/schema/blueprint.d.ts +47 -0
- package/dist/core/database/schema/columnDefinition.d.ts +36 -0
- package/dist/core/database/schema/driver.d.ts +8 -0
- package/dist/core/database/schema/errors.d.ts +4 -0
- package/dist/core/database/schema/grammars/compileStatements.d.ts +8 -0
- package/dist/core/database/schema/grammars/createGrammar.d.ts +4 -0
- package/dist/core/database/schema/grammars/grammar.d.ts +10 -0
- package/dist/core/database/schema/grammars/index.d.ts +7 -0
- package/dist/core/database/schema/grammars/mysqlGrammar.d.ts +2 -0
- package/dist/core/database/schema/grammars/postgresGrammar.d.ts +2 -0
- package/dist/core/database/schema/grammars/sqliteGrammar.d.ts +2 -0
- package/dist/core/database/schema/index.d.ts +12 -0
- package/dist/core/database/schema/schema.d.ts +21 -0
- package/dist/core/database/types.d.ts +39 -2
- package/dist/core/database/whereBuilder.d.ts +17 -0
- package/dist/core/http/requireAbilityMiddleware.d.ts +2 -2
- package/dist/core/jobs/dispatchWebhookJob.d.ts +14 -0
- package/dist/core/jobs/invalidateCacheTagsJob.d.ts +12 -0
- package/dist/core/pagination/index.d.ts +11 -1
- package/dist/core/queue/createAppQueue.d.ts +6 -0
- package/dist/core/queue/failedJobRepository.d.ts +6 -0
- package/dist/core/queue/failedJobService.d.ts +15 -0
- package/dist/core/queue/failedJobTable.d.ts +3 -0
- package/dist/core/queue/jobRegistry.d.ts +14 -0
- package/dist/core/queue/jobRunner.d.ts +9 -0
- package/dist/core/queue/publicQueue.d.ts +15 -0
- package/dist/core/queue/redisQueue.d.ts +29 -0
- package/dist/core/queue/resilientQueue.d.ts +9 -0
- package/dist/core/queue/types.d.ts +8 -0
- package/dist/core/scheduler/schedule.d.ts +15 -0
- package/dist/core/security/safeFetch.d.ts +8 -0
- package/dist/core/security/safeUrl.d.ts +5 -0
- package/dist/core/view/etaViewEngine.d.ts +15 -0
- package/dist/core/view/htmlResponse.d.ts +6 -0
- package/dist/core/view/index.d.ts +5 -0
- package/dist/core/view/viewEngine.d.ts +6 -0
- package/dist/core/view/webLayoutData.d.ts +17 -0
- package/dist/domain/scim.d.ts +9 -0
- package/dist/index.js +4194 -466
- package/dist/modules/user/apiTokenRepository.d.ts +1 -1
- package/dist/modules/user/apiTokenTable.d.ts +1 -1
- package/dist/modules/user/authService.d.ts +1 -1
- package/dist/modules/user/notificationRepository.d.ts +1 -1
- package/dist/modules/user/notificationService.d.ts +1 -1
- package/dist/modules/user/notificationTable.d.ts +1 -1
- package/dist/modules/user/oauthIdentityRepository.d.ts +2 -2
- package/dist/modules/user/provider.d.ts +1 -1
- package/dist/modules/user/repository.d.ts +1 -1
- package/dist/modules/user/table.d.ts +1 -1
- package/dist/modules/user/tokenService.d.ts +1 -1
- package/package.json +44 -3
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AppContext, type AppModule, type ProviderContext, type ServiceProvider } from "./contracts";
|
|
2
|
+
declare function collectProviders(modules?: AppModule[]): ServiceProvider[];
|
|
3
|
+
declare function runProviderPhase(providers: ServiceProvider[], phase: "register" | "boot", context: ProviderContext): void;
|
|
4
|
+
declare function createAppContext(): AppContext;
|
|
5
|
+
declare const appContext: AppContext;
|
|
6
|
+
export { appContext, collectProviders, createAppContext, runProviderPhase };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AppDependencies, AppRouteMap } from "./contracts";
|
|
2
|
+
declare function createWebRoutes(dependencies: AppDependencies): AppRouteMap;
|
|
3
|
+
declare function mergeWebRoutes(dependencies: AppDependencies, routes: AppRouteMap): AppRouteMap;
|
|
4
|
+
export { createWebRoutes, mergeWebRoutes };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type EnvSchema } from "../core/config/envSchema";
|
|
2
|
+
declare const appEnvSchema: EnvSchema;
|
|
3
|
+
declare const appConfigKeys: {
|
|
4
|
+
readonly databaseUrl: "database.url";
|
|
5
|
+
readonly port: "app.port";
|
|
6
|
+
readonly cacheTtlMs: "cache.ttlMs";
|
|
7
|
+
readonly cacheMaxEntries: "cache.maxEntries";
|
|
8
|
+
};
|
|
9
|
+
export { appConfigKeys, appEnvSchema };
|
|
@@ -20,6 +20,8 @@ declare class HttpKernel {
|
|
|
20
20
|
wrapAbility(ability: string, handler: RouteHandler): RouteHandler;
|
|
21
21
|
wrapPolicy(resource: string, action: keyof Policy, handler: RouteHandler): RouteHandler;
|
|
22
22
|
wrapLogin(handler: RouteHandler): RouteHandler;
|
|
23
|
+
wrapRegister(handler: RouteHandler): RouteHandler;
|
|
24
|
+
private wrapThrottle;
|
|
23
25
|
}
|
|
24
26
|
declare function createHttpKernel(dependencies: AppDependencies): HttpKernel;
|
|
25
27
|
export type { MiddlewareGroupName };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { appModules, discoverModules } from "./discoverModules";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ServiceProvider } from "../contracts";
|
|
2
|
+
declare const CORE_VIEW_TOKEN = "core.view";
|
|
3
|
+
declare const VIEW_DIRECTORY_CONFIG_KEY = "view.directory";
|
|
4
|
+
declare const viewProvider: ServiceProvider;
|
|
5
|
+
export { CORE_VIEW_TOKEN, VIEW_DIRECTORY_CONFIG_KEY, viewProvider };
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @getstrata/bootstrap — application shell for Strata sibling apps.
|
|
3
3
|
*/
|
|
4
|
+
export { scheduleRunCommand } from "../cli/commands/scheduleRun.ts";
|
|
5
|
+
export type { ScheduledTask } from "../core/scheduler/schedule.ts";
|
|
6
|
+
export { appSchedule, runDueScheduledTasks, Schedule } from "../core/scheduler/schedule.ts";
|
|
4
7
|
export { resolveApplicationQueue, setActiveApplicationContext } from "./applicationRegistry.ts";
|
|
5
8
|
export { APP_PORT_CONFIG_KEY, CORE_AUTH_TOKEN, CORE_CACHE_TOKEN, CORE_CONFIG_TOKEN, CORE_POLICY_GATE_TOKEN, CORE_QUEUE_TOKEN, CORE_TOKEN_SERVICE_TOKEN, DATABASE_URL_CONFIG_KEY, DEFAULT_APP_PORT, REDIS_URL_CONFIG_KEY, } from "./config.ts";
|
|
9
|
+
export { collectProviders, createAppContext, runProviderPhase } from "./context.ts";
|
|
6
10
|
export type { AppContext, AppDependencies, AppModule, AppRouteMap, CachedJson, ConfigStore, ModuleRouteContext, MutableAppDependencies, ProviderContext, ServiceFactory, ServiceProvider, } from "./contracts.ts";
|
|
7
11
|
export { assertAppDependenciesComplete, getRequiredDependency, resolveService, ServiceContainer, } from "./contracts.ts";
|
|
8
|
-
export {
|
|
12
|
+
export { createWebRoutes, mergeWebRoutes } from "./createWebRoutes.ts";
|
|
13
|
+
export { createHttpKernel, type HttpKernel, type MiddlewareGroupName } from "./httpKernel.ts";
|
|
9
14
|
export { prefixRouteMap } from "./prefixRouteMap.ts";
|
|
15
|
+
export { coreProviders } from "./providers/index.ts";
|
|
10
16
|
export { CookieSessionStore, createCsrfProtection, createWebServer, type ParsedForm, parseFormBody, type SessionUser, slugify, type WebServerOptions, } from "./web/index.ts";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface RegisteredRoute {
|
|
2
|
+
method: string;
|
|
3
|
+
path: string;
|
|
4
|
+
middleware: string[];
|
|
5
|
+
}
|
|
6
|
+
declare class RouteRegistry {
|
|
7
|
+
private readonly routes;
|
|
8
|
+
register(route: RegisteredRoute): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
list(): RegisteredRoute[];
|
|
11
|
+
}
|
|
12
|
+
declare const routeRegistry: RouteRegistry;
|
|
13
|
+
export type { RegisteredRoute };
|
|
14
|
+
export { RouteRegistry, routeRegistry };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,6 +2,7 @@ export interface SessionUser {
|
|
|
2
2
|
id: number;
|
|
3
3
|
name: string;
|
|
4
4
|
email: string;
|
|
5
|
+
learn_subscriber?: boolean;
|
|
5
6
|
}
|
|
6
7
|
type SqlClient = {
|
|
7
8
|
unsafe<T>(query: string, params?: readonly unknown[]): Promise<T[]>;
|
|
@@ -14,6 +15,7 @@ export declare class CookieSessionStore {
|
|
|
14
15
|
constructor(sql: SqlClient, secret: string, cookieName?: string, maxAgeSeconds?: number);
|
|
15
16
|
cookieHeader(_user: SessionUser, sessionId: string): string;
|
|
16
17
|
clearCookieHeader(): string;
|
|
18
|
+
private withSecureFlag;
|
|
17
19
|
create(user: SessionUser): Promise<string>;
|
|
18
20
|
destroy(sessionId: string): Promise<void>;
|
|
19
21
|
read(request: Request): Promise<SessionUser | null>;
|
|
@@ -5,5 +5,6 @@ interface LoginRateLimitConfig {
|
|
|
5
5
|
declare const LOCAL_LOGIN_RATE_LIMIT: LoginRateLimitConfig;
|
|
6
6
|
declare const PRODUCTION_LOGIN_RATE_LIMIT: LoginRateLimitConfig;
|
|
7
7
|
declare function resolveLoginRateLimit(): LoginRateLimitConfig;
|
|
8
|
+
declare function resolveRegisterRateLimit(): LoginRateLimitConfig;
|
|
8
9
|
export type { LoginRateLimitConfig };
|
|
9
|
-
export { LOCAL_LOGIN_RATE_LIMIT, PRODUCTION_LOGIN_RATE_LIMIT, resolveLoginRateLimit };
|
|
10
|
+
export { LOCAL_LOGIN_RATE_LIMIT, PRODUCTION_LOGIN_RATE_LIMIT, resolveLoginRateLimit, resolveRegisterRateLimit, };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface AuditExportConfig {
|
|
2
|
+
endpoint: string;
|
|
3
|
+
format: "json" | "cef";
|
|
4
|
+
batchSize: number;
|
|
5
|
+
}
|
|
6
|
+
declare function resolveAuditExportConfig(): AuditExportConfig | null;
|
|
7
|
+
declare function exportPendingAuditLogs(): Promise<number>;
|
|
8
|
+
export { exportPendingAuditLogs, resolveAuditExportConfig };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
interface SiemAuditEvent {
|
|
2
|
+
timestamp: string;
|
|
3
|
+
event_type: string;
|
|
4
|
+
actor_user_id: number | null;
|
|
5
|
+
tenant_id: number | null;
|
|
6
|
+
trace_id: string | null;
|
|
7
|
+
action: string;
|
|
8
|
+
subject_type: string;
|
|
9
|
+
subject_id: number | null;
|
|
10
|
+
ip_address: string | null;
|
|
11
|
+
user_agent: string | null;
|
|
12
|
+
checksum: string | null;
|
|
13
|
+
payload: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
declare function formatSiemAuditEvent(input: {
|
|
16
|
+
action: string;
|
|
17
|
+
subject_type: string;
|
|
18
|
+
subject_id: number | null;
|
|
19
|
+
user_id: number | null;
|
|
20
|
+
tenant_id?: number | null;
|
|
21
|
+
trace_id?: string | null;
|
|
22
|
+
ip_address?: string | null;
|
|
23
|
+
user_agent?: string | null;
|
|
24
|
+
checksum?: string | null;
|
|
25
|
+
payload?: Record<string, unknown>;
|
|
26
|
+
created_at: Date;
|
|
27
|
+
}): SiemAuditEvent;
|
|
28
|
+
declare function formatCefLine(event: SiemAuditEvent): string;
|
|
29
|
+
export type { SiemAuditEvent };
|
|
30
|
+
export { formatCefLine, formatSiemAuditEvent };
|
|
@@ -9,7 +9,7 @@ declare class PolicyGate {
|
|
|
9
9
|
constructor();
|
|
10
10
|
private readonly policies;
|
|
11
11
|
register(resource: string, policy: Policy): void;
|
|
12
|
-
allows(resource: string, action:
|
|
13
|
-
authorize(resource: string, action:
|
|
12
|
+
allows(resource: string, action: string, user?: unknown, model?: unknown): boolean;
|
|
13
|
+
authorize(resource: string, action: string, user?: unknown, model?: unknown): void;
|
|
14
14
|
}
|
|
15
15
|
export { Policy, PolicyGate };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const SESSION_COOKIE = "workhub_session";
|
|
2
|
+
declare const SESSION_TTL_SECONDS: number;
|
|
3
|
+
declare function readSessionUserId(request: Request): number | null;
|
|
4
|
+
declare function createSessionCookie(userId: number): string;
|
|
5
|
+
declare function clearSessionCookie(): string;
|
|
6
|
+
export { clearSessionCookie, createSessionCookie, readSessionUserId, SESSION_COOKIE, SESSION_TTL_SECONDS, };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ServiceContainer } from "../../bootstrap/contracts";
|
|
2
|
+
import type { AuthUser } from "./authContext";
|
|
3
|
+
import type { AuthGuard } from "./guard";
|
|
4
|
+
declare class SessionGuard implements AuthGuard {
|
|
5
|
+
private readonly container;
|
|
6
|
+
constructor(container: ServiceContainer);
|
|
7
|
+
resolve(request: Request): Promise<AuthUser | null>;
|
|
8
|
+
}
|
|
9
|
+
export { SessionGuard };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CacheStore } from "./store";
|
|
2
|
+
type CacheDriver = "array" | "redis";
|
|
3
|
+
interface CreateCacheStoreOptions {
|
|
4
|
+
driver: CacheDriver;
|
|
5
|
+
ttlMs: number;
|
|
6
|
+
maxEntries: number;
|
|
7
|
+
redisUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
declare function createCacheStore(options: CreateCacheStoreOptions): CacheStore;
|
|
10
|
+
export type { CacheDriver, CreateCacheStoreOptions };
|
|
11
|
+
export { createCacheStore };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CacheStore } from "./store";
|
|
2
|
+
declare class RedisCacheStore implements CacheStore {
|
|
3
|
+
private readonly ttlMs;
|
|
4
|
+
private readonly maxEntries;
|
|
5
|
+
private readonly client;
|
|
6
|
+
private readonly inflight;
|
|
7
|
+
private readonly keyTags;
|
|
8
|
+
constructor(redisUrl: string, ttlMs: number, maxEntries: number);
|
|
9
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
10
|
+
set<T>(key: string, value: T, ttlMs?: number): Promise<void>;
|
|
11
|
+
getOrSet<T>(key: string, loader: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
12
|
+
attachTags(key: string, tags: string[]): Promise<void>;
|
|
13
|
+
flushTags(tags: string[]): Promise<number>;
|
|
14
|
+
invalidate(key: string): Promise<boolean>;
|
|
15
|
+
invalidateByPrefix(prefix: string): Promise<number>;
|
|
16
|
+
clear(): Promise<void>;
|
|
17
|
+
size(): Promise<number>;
|
|
18
|
+
private storageKey;
|
|
19
|
+
private tagKey;
|
|
20
|
+
private detachKeyFromTags;
|
|
21
|
+
private enforceMaxEntries;
|
|
22
|
+
}
|
|
23
|
+
export default RedisCacheStore;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CacheStore } from "./store";
|
|
2
|
+
import TaggedCache from "./taggedCache";
|
|
3
|
+
declare class CacheRepository {
|
|
4
|
+
private readonly store;
|
|
5
|
+
constructor(store: CacheStore);
|
|
6
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
7
|
+
remember<T>(key: string, callback: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
8
|
+
forget(key: string): Promise<boolean>;
|
|
9
|
+
flush(): Promise<void>;
|
|
10
|
+
tags(...names: string[]): TaggedCache;
|
|
11
|
+
getOrSet<T>(key: string, loader: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
12
|
+
invalidate(key: string): Promise<boolean>;
|
|
13
|
+
invalidateByPrefix(prefix: string): Promise<number>;
|
|
14
|
+
clear(): Promise<void>;
|
|
15
|
+
size(): Promise<number>;
|
|
16
|
+
}
|
|
17
|
+
export default CacheRepository;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare class SimpleCache {
|
|
2
|
+
private readonly ttlMs;
|
|
3
|
+
private readonly maxEntries;
|
|
4
|
+
private readonly cache;
|
|
5
|
+
private readonly inflight;
|
|
6
|
+
private readonly tagIndex;
|
|
7
|
+
private readonly keyTags;
|
|
8
|
+
constructor(ttlMs?: number, maxEntries?: number);
|
|
9
|
+
get<T>(key: string): T | undefined;
|
|
10
|
+
set<T>(key: string, value: T, ttlMs?: number): void;
|
|
11
|
+
getOrSet<T>(key: string, loader: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
12
|
+
attachTags(key: string, tags: string[]): void;
|
|
13
|
+
flushTags(tags: string[]): number;
|
|
14
|
+
invalidate(key: string): boolean;
|
|
15
|
+
invalidateByPrefix(prefix: string): number;
|
|
16
|
+
clear(): void;
|
|
17
|
+
size(): number;
|
|
18
|
+
private detachKeyFromTags;
|
|
19
|
+
private getFreshEntry;
|
|
20
|
+
private pruneExpired;
|
|
21
|
+
private evictOverflow;
|
|
22
|
+
}
|
|
23
|
+
export default SimpleCache;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type SimpleCache from "./simpleCache";
|
|
2
|
+
import type { CacheStore } from "./store";
|
|
3
|
+
declare class SimpleCacheStore implements CacheStore {
|
|
4
|
+
private readonly cache;
|
|
5
|
+
constructor(cache: SimpleCache);
|
|
6
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
7
|
+
set<T>(key: string, value: T, ttlMs?: number): Promise<void>;
|
|
8
|
+
getOrSet<T>(key: string, loader: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
9
|
+
attachTags(key: string, tags: string[]): Promise<void>;
|
|
10
|
+
flushTags(tags: string[]): Promise<number>;
|
|
11
|
+
invalidate(key: string): Promise<boolean>;
|
|
12
|
+
invalidateByPrefix(prefix: string): Promise<number>;
|
|
13
|
+
clear(): Promise<void>;
|
|
14
|
+
size(): Promise<number>;
|
|
15
|
+
}
|
|
16
|
+
export default SimpleCacheStore;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface CacheStore {
|
|
2
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
3
|
+
set<T>(key: string, value: T, ttlMs?: number): Promise<void>;
|
|
4
|
+
getOrSet<T>(key: string, loader: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
5
|
+
attachTags(key: string, tags: string[]): Promise<void>;
|
|
6
|
+
flushTags(tags: string[]): Promise<number>;
|
|
7
|
+
invalidate(key: string): Promise<boolean>;
|
|
8
|
+
invalidateByPrefix(prefix: string): Promise<number>;
|
|
9
|
+
clear(): Promise<void>;
|
|
10
|
+
size(): Promise<number>;
|
|
11
|
+
}
|
|
12
|
+
export type { CacheStore };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CacheStore } from "./store";
|
|
2
|
+
declare class TaggedCache {
|
|
3
|
+
private readonly store;
|
|
4
|
+
private readonly tags;
|
|
5
|
+
constructor(store: CacheStore, tags: string[]);
|
|
6
|
+
remember<T>(key: string, callback: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
7
|
+
flush(): Promise<number>;
|
|
8
|
+
}
|
|
9
|
+
export default TaggedCache;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface EnvRule {
|
|
2
|
+
required?: boolean;
|
|
3
|
+
integer?: boolean;
|
|
4
|
+
minimum?: number;
|
|
5
|
+
default?: string;
|
|
6
|
+
pattern?: RegExp;
|
|
7
|
+
}
|
|
8
|
+
type EnvSchema = Record<string, EnvRule>;
|
|
9
|
+
declare function defineEnvSchema(schema: EnvSchema): EnvSchema;
|
|
10
|
+
declare function validateEnv(schema: EnvSchema, env?: Record<string, string | undefined>): Record<string, string>;
|
|
11
|
+
export type { EnvRule, EnvSchema };
|
|
12
|
+
export { defineEnvSchema, validateEnv };
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import { type PaginatedResult } from "../pagination/index.ts";
|
|
1
|
+
import { type CursorPaginatedResult, type PaginatedResult } from "../pagination/index.ts";
|
|
2
2
|
import { type BelongsToRelation, type HasManyRelation } from "./relationships.ts";
|
|
3
|
+
import { RepositoryQuery } from "./repositoryQuery.ts";
|
|
3
4
|
import type { TableDefinition } from "./table.ts";
|
|
4
5
|
import type { MutationValues, QueryOptions, QueryWhere, UpdateValues } from "./types.ts";
|
|
6
|
+
import type { WhereNode } from "./whereBuilder.ts";
|
|
7
|
+
type ExtendedQueryOptions<TEntity extends object> = QueryOptions<TEntity> & {
|
|
8
|
+
whereNodes?: WhereNode<TEntity>[];
|
|
9
|
+
};
|
|
5
10
|
interface DatabaseConnection {
|
|
6
11
|
unsafe<T>(query: string, params?: readonly unknown[]): Promise<T[]>;
|
|
7
12
|
}
|
|
@@ -10,11 +15,18 @@ declare class BaseRepository<TEntity extends object, PrimaryKey extends keyof TE
|
|
|
10
15
|
protected readonly table: TableDefinition<TEntity, PrimaryKey>;
|
|
11
16
|
protected readonly connection: DatabaseConnection;
|
|
12
17
|
constructor(table: TableDefinition<TEntity, PrimaryKey>, connection?: DatabaseConnection);
|
|
13
|
-
findAll(options?:
|
|
18
|
+
findAll(options?: ExtendedQueryOptions<TEntity>): Promise<TEntity[]>;
|
|
14
19
|
paginate(options: {
|
|
15
20
|
page: number;
|
|
16
21
|
perPage: number;
|
|
17
|
-
} & Omit<
|
|
22
|
+
} & Omit<ExtendedQueryOptions<TEntity>, "limit" | "offset">): Promise<PaginatedResult<TEntity>>;
|
|
23
|
+
chunk(count: number, callback: (rows: TEntity[]) => Promise<boolean | void>, options?: Omit<ExtendedQueryOptions<TEntity>, "limit" | "offset">): Promise<void>;
|
|
24
|
+
cursorPaginate(options: {
|
|
25
|
+
perPage: number;
|
|
26
|
+
cursor?: TEntity[PrimaryKey];
|
|
27
|
+
cursorColumn?: PrimaryKey;
|
|
28
|
+
direction?: "asc" | "desc";
|
|
29
|
+
} & Omit<ExtendedQueryOptions<TEntity>, "limit" | "offset">): Promise<CursorPaginatedResult<TEntity, TEntity[PrimaryKey]>>;
|
|
18
30
|
findById(id: TEntity[PrimaryKey]): Promise<TEntity | null>;
|
|
19
31
|
findByIdOrThrow(id: TEntity[PrimaryKey], errorFactory?: ErrorFactory<TEntity[PrimaryKey]>): Promise<TEntity>;
|
|
20
32
|
findByIds(ids: readonly TEntity[PrimaryKey][]): Promise<TEntity[]>;
|
|
@@ -27,8 +39,11 @@ declare class BaseRepository<TEntity extends object, PrimaryKey extends keyof TE
|
|
|
27
39
|
forceDeleteById(id: TEntity[PrimaryKey]): Promise<boolean>;
|
|
28
40
|
restoreById(id: TEntity[PrimaryKey]): Promise<TEntity | null>;
|
|
29
41
|
withConnection(connection: DatabaseConnection): this;
|
|
42
|
+
getConnection(): DatabaseConnection;
|
|
43
|
+
getTable(): TableDefinition<TEntity, PrimaryKey>;
|
|
44
|
+
query(where?: QueryWhere<TEntity>): RepositoryQuery<TEntity, PrimaryKey>;
|
|
30
45
|
protected findWhere(where: QueryWhere<TEntity>, options?: Omit<QueryOptions<TEntity>, "where">): Promise<TEntity[]>;
|
|
31
|
-
protected countWhere(where?: QueryWhere<TEntity>, options?: Pick<QueryOptions<TEntity>, "withTrashed" | "onlyTrashed">): Promise<number>;
|
|
46
|
+
protected countWhere(where?: QueryWhere<TEntity>, options?: Pick<QueryOptions<TEntity>, "withTrashed" | "onlyTrashed" | "joins" | "groupBy">, whereNodes?: readonly WhereNode<TEntity>[]): Promise<number>;
|
|
32
47
|
protected averageColumn(column: keyof TEntity & string, where?: QueryWhere<TEntity>): Promise<number>;
|
|
33
48
|
protected averageExpression(expression: string, alias: string, where?: QueryWhere<TEntity>): Promise<number>;
|
|
34
49
|
protected pluckNumberValues(expression: string, alias: string, options?: QueryOptions<TEntity>): Promise<number[]>;
|
|
@@ -36,9 +51,9 @@ declare class BaseRepository<TEntity extends object, PrimaryKey extends keyof TE
|
|
|
36
51
|
value: TEntity[K] | null;
|
|
37
52
|
count: number;
|
|
38
53
|
}>>;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
findByHasManyRelation<TParent extends object, LocalKey extends keyof TParent & string, ForeignKey extends keyof TEntity & string>(relation: HasManyRelation<TParent, TEntity, LocalKey, ForeignKey>, parentId: TParent[LocalKey], options?: Omit<QueryOptions<TEntity>, "where">): Promise<TEntity[]>;
|
|
55
|
+
loadHasManyForParents<TParent extends object, LocalKey extends keyof TParent & string, ForeignKey extends keyof TEntity & string>(parents: readonly TParent[], relation: HasManyRelation<TParent, TEntity, LocalKey, ForeignKey>, options?: Omit<QueryOptions<TEntity>, "where">): Promise<Map<TParent[LocalKey], TEntity[]>>;
|
|
56
|
+
loadBelongsToForParents<TChild extends object, TParent extends object, ForeignKey extends keyof TChild & string, OwnerKey extends keyof TParent & string>(children: readonly TChild[], relation: BelongsToRelation<TChild, TParent, ForeignKey, OwnerKey>, parentRepository: BaseRepository<TParent, OwnerKey>, options?: Omit<QueryOptions<TParent>, "where">): Promise<Map<TChild[ForeignKey], TParent>>;
|
|
42
57
|
}
|
|
43
58
|
export default BaseRepository;
|
|
44
59
|
export type { DatabaseConnection };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DatabaseConnection } from "./baseRepository";
|
|
2
|
+
declare function bindDatabaseConnection(connection: DatabaseConnection): void;
|
|
3
|
+
declare function getBoundDatabaseConnection(): DatabaseConnection | null;
|
|
4
|
+
declare function resetBoundDatabaseConnection(): void;
|
|
5
|
+
export { bindDatabaseConnection, getBoundDatabaseConnection, resetBoundDatabaseConnection };
|
|
@@ -2,10 +2,17 @@ export type { DatabaseConnection } from "./baseRepository.ts";
|
|
|
2
2
|
export { default as BaseRepository } from "./baseRepository.ts";
|
|
3
3
|
export { createDatabaseConnection } from "./connection.ts";
|
|
4
4
|
export { mapDatabaseError, withDatabaseErrorHandling } from "./errors.ts";
|
|
5
|
-
export {
|
|
6
|
-
export
|
|
7
|
-
export {
|
|
5
|
+
export type { CastType, GlobalScopeFn, ModelConstructor } from "./model.ts";
|
|
6
|
+
export { applyCasts, dehydrateValue, filterMassAssignable, hydrateValue, Model, registerModelRepository, } from "./model.ts";
|
|
7
|
+
export { buildAdvancedWhereClause, buildCountQuery, buildDeleteByIdQuery, buildGroupedCountQuery, buildInsertQuery, buildJoinClause, buildOrderByClause, buildProjectionQuery, buildQueryWhereClause, buildRestoreByIdQuery, buildSelectQuery, buildSoftDeleteByIdQuery, buildUpdateQuery, buildWhereClause, parseQualifiedColumn, qualifyColumn, quoteIdentifier, resolveQualifiedColumn, resolveSoftDeleteColumn, } from "./query.ts";
|
|
8
|
+
export type { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasOneRelation, } from "./relationships.ts";
|
|
9
|
+
export { belongsTo, belongsToMany, hasMany, hasOne, indexBelongsToManyRelation, indexBelongsToRelation, indexHasManyRelation, indexHasOneRelation, } from "./relationships.ts";
|
|
10
|
+
export { RepositoryQuery } from "./repositoryQuery.ts";
|
|
11
|
+
export type { BlueprintAction, BlueprintCallback, ColumnKind, DatabaseDriver, ForeignKeyOptions, Grammar, IndexDefinition, IndexKind, ResolveDatabaseDriverOptions, SchemaBuilder, } from "./schema/index.ts";
|
|
12
|
+
export { Blueprint, ColumnDefinition, compileBlueprint, createSchemaBuilder, ForeignIdColumnDefinition, grammarForDriver, inferReferencedTable, MySqlGrammar, PostgresGrammar, resolveDatabaseDriver, Schema, SqliteGrammar, UnsupportedSchemaFeatureError, } from "./schema/index.ts";
|
|
8
13
|
export type { TableDefinition } from "./table.ts";
|
|
9
14
|
export { defineTable } from "./table.ts";
|
|
10
15
|
export { runInTransaction } from "./transaction.ts";
|
|
11
|
-
export type { DatabaseComparable, DatabaseScalar, MutationValues, QueryFilterValue, QueryOperator, QueryOptions, QueryOrder, QueryWhere, UpdateValues, } from "./types.ts";
|
|
16
|
+
export type { DatabaseComparable, DatabaseScalar, MutationValues, QueryFilterValue, QueryJoin, QueryJoinOn, QueryOperator, QueryOptions, QueryOrder, QuerySelectItem, QueryWhere, UpdateValues, } from "./types.ts";
|
|
17
|
+
export type { WhereNode } from "./whereBuilder.ts";
|
|
18
|
+
export { WhereBuilder } from "./whereBuilder.ts";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface MigrationDatabase {
|
|
2
|
+
unsafe<T = unknown>(query: string, params?: readonly unknown[]): Promise<T[]>;
|
|
3
|
+
schema?: import("../schema/schema.ts").SchemaBuilder;
|
|
4
|
+
}
|
|
5
|
+
interface Migration {
|
|
6
|
+
name: string;
|
|
7
|
+
up(db: MigrationDatabase): Promise<void>;
|
|
8
|
+
down(db: MigrationDatabase): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
type MigrationStatus = {
|
|
11
|
+
name: string;
|
|
12
|
+
status: "up" | "pending";
|
|
13
|
+
batch: number | null;
|
|
14
|
+
};
|
|
15
|
+
export type { Migration, MigrationDatabase, MigrationStatus };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type BaseRepository from "./baseRepository.ts";
|
|
2
|
+
import type { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasOneRelation } from "./relationships.ts";
|
|
3
|
+
import type { RepositoryQuery } from "./repositoryQuery.ts";
|
|
4
|
+
import type { QueryOptions, QueryWhere } from "./types.ts";
|
|
5
|
+
type CastType = "date" | "datetime" | "json" | "bool" | "boolean";
|
|
6
|
+
type LoadedAttributes = Record<string, unknown>;
|
|
7
|
+
type ModelCasts = Partial<Record<string, CastType>>;
|
|
8
|
+
type GlobalScopeFn<TEntity extends object, PrimaryKey extends keyof TEntity & string> = (query: RepositoryQuery<TEntity, PrimaryKey>) => RepositoryQuery<TEntity, PrimaryKey>;
|
|
9
|
+
type ModelClassType<TEntity extends object, PrimaryKey extends keyof TEntity & string> = typeof Model & (new (attributes: TEntity, repository: BaseRepository<TEntity, PrimaryKey>, exists?: boolean) => Model<TEntity, PrimaryKey>);
|
|
10
|
+
interface ModelConstructor<TEntity extends object, PrimaryKey extends keyof TEntity & string, TModel extends Model<TEntity, PrimaryKey>> extends ModelClassType<TEntity, PrimaryKey> {
|
|
11
|
+
new (attributes: TEntity, repository: BaseRepository<TEntity, PrimaryKey>, exists?: boolean): TModel;
|
|
12
|
+
}
|
|
13
|
+
declare function hydrateValue(value: unknown, cast: CastType): unknown;
|
|
14
|
+
declare function dehydrateValue(value: unknown, cast: CastType): unknown;
|
|
15
|
+
declare function filterMassAssignable(fillable: readonly string[] | undefined, guarded: readonly string[] | true | undefined, input: LoadedAttributes): LoadedAttributes;
|
|
16
|
+
declare function applyCasts(values: LoadedAttributes, casts: ModelCasts, direction: "hydrate" | "dehydrate"): LoadedAttributes;
|
|
17
|
+
declare class Model<TEntity extends object, PrimaryKey extends keyof TEntity & string> {
|
|
18
|
+
protected attributes: TEntity;
|
|
19
|
+
protected readonly repository: BaseRepository<TEntity, PrimaryKey>;
|
|
20
|
+
static $fillable?: readonly string[];
|
|
21
|
+
static $guarded?: readonly string[] | true;
|
|
22
|
+
static $casts: ModelCasts;
|
|
23
|
+
static $timestamps: boolean;
|
|
24
|
+
private _exists;
|
|
25
|
+
constructor(attributes: TEntity, repository: BaseRepository<TEntity, PrimaryKey>, exists?: boolean);
|
|
26
|
+
get $exists(): boolean;
|
|
27
|
+
get<K extends keyof TEntity>(key: K): TEntity[K];
|
|
28
|
+
get id(): TEntity[PrimaryKey];
|
|
29
|
+
toObject(): TEntity;
|
|
30
|
+
protected primaryKey(): PrimaryKey;
|
|
31
|
+
protected static primaryKeyField(this: typeof Model): string;
|
|
32
|
+
protected static hydrateAttributes<TEntity extends object>(this: typeof Model, attributes: TEntity): TEntity;
|
|
33
|
+
protected static dehydrateAttributes(this: typeof Model, attributes: LoadedAttributes): LoadedAttributes;
|
|
34
|
+
protected static fromRecord<TEntity extends object, PrimaryKey extends keyof TEntity & string>(this: typeof Model, record: TEntity, repository: BaseRepository<TEntity, PrimaryKey>, exists?: boolean): Model<TEntity, PrimaryKey>;
|
|
35
|
+
static boot(): void;
|
|
36
|
+
static addGlobalScope<TEntity extends object, PrimaryKey extends keyof TEntity & string>(this: object, _name: string, scope: GlobalScopeFn<TEntity, PrimaryKey>): void;
|
|
37
|
+
static repository<TEntity extends object, PrimaryKey extends keyof TEntity & string>(this: object): BaseRepository<TEntity, PrimaryKey>;
|
|
38
|
+
static query<TEntity extends object, PrimaryKey extends keyof TEntity & string>(this: object): RepositoryQuery<TEntity, PrimaryKey>;
|
|
39
|
+
static create(this: object, attributes: Record<string, unknown>): Promise<Model<Record<string, unknown>, "id">>;
|
|
40
|
+
static find(this: object, id: unknown): Promise<Model<Record<string, unknown>, "id"> | null>;
|
|
41
|
+
static findOrFail(this: object, id: unknown, errorFactory?: (id: unknown) => Error): Promise<Model<Record<string, unknown>, "id">>;
|
|
42
|
+
static all(this: object, options?: Omit<QueryOptions<object>, "where">): Promise<Array<Model<Record<string, unknown>, "id">>>;
|
|
43
|
+
static firstWhere(this: object, where: QueryWhere<object>, options?: Omit<QueryOptions<object>, "where">): Promise<Model<Record<string, unknown>, "id"> | null>;
|
|
44
|
+
save(): Promise<this>;
|
|
45
|
+
update(changes: Partial<TEntity>): Promise<this>;
|
|
46
|
+
delete(): Promise<boolean>;
|
|
47
|
+
forceDelete(): Promise<boolean>;
|
|
48
|
+
restore(): Promise<this | null>;
|
|
49
|
+
loadHasMany<TChild extends object, LocalKey extends keyof TEntity & string, ForeignKey extends keyof TChild & string, Alias extends string>(as: Alias, relation: HasManyRelation<TEntity, TChild, LocalKey, ForeignKey>, childRepository: BaseRepository<TChild, keyof TChild & string>, options?: Omit<QueryOptions<TChild>, "where">): Promise<this & Record<Alias, TChild[]>>;
|
|
50
|
+
loadHasOne<TChild extends object, LocalKey extends keyof TEntity & string, ForeignKey extends keyof TChild & string, Alias extends string>(as: Alias, relation: HasOneRelation<TEntity, TChild, LocalKey, ForeignKey>, childRepository: BaseRepository<TChild, keyof TChild & string>, options?: Omit<QueryOptions<TChild>, "where">): Promise<this & Record<Alias, TChild | undefined>>;
|
|
51
|
+
loadBelongsTo<TParent extends object, ForeignKey extends keyof TEntity & string, OwnerKey extends keyof TParent & string, Alias extends string>(as: Alias, relation: BelongsToRelation<TEntity, TParent, ForeignKey, OwnerKey>, parentRepository: BaseRepository<TParent, OwnerKey>, options?: Omit<QueryOptions<TParent>, "where">): Promise<this & Record<Alias, TParent | undefined>>;
|
|
52
|
+
loadBelongsToMany<TRelated extends object, Pivot extends object, ParentKey extends keyof TEntity & string, RelatedKey extends keyof TRelated & string, ForeignPivotKey extends keyof Pivot & string, RelatedPivotKey extends keyof Pivot & string, Alias extends string>(as: Alias, relation: BelongsToManyRelation<TEntity, TRelated, Pivot, ParentKey, RelatedKey, ForeignPivotKey, RelatedPivotKey>, relatedRepository: BaseRepository<TRelated, RelatedKey>, options?: Omit<QueryOptions<TRelated>, "where">): Promise<this & Record<Alias, TRelated[]>>;
|
|
53
|
+
mergeAttributes(patch: Partial<TEntity>): this;
|
|
54
|
+
}
|
|
55
|
+
declare function registerModelRepository<TModelClass>(model: TModelClass, repository: object): TModelClass;
|
|
56
|
+
export type { CastType, GlobalScopeFn, ModelClassType, ModelConstructor };
|
|
57
|
+
export { applyCasts, dehydrateValue, filterMassAssignable, hydrateValue, Model, registerModelRepository, };
|