@getstrata/bootstrap 0.1.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/README.md +29 -0
- package/dist/bootstrap/applicationRegistry.d.ts +16 -0
- package/dist/bootstrap/config.d.ts +20 -0
- package/dist/bootstrap/contracts.d.ts +63 -0
- package/dist/bootstrap/httpKernel.d.ts +26 -0
- package/dist/bootstrap/prefixRouteMap.d.ts +2 -0
- package/dist/bootstrap/public-api.d.ts +10 -0
- package/dist/bootstrap/web/forms.d.ts +10 -0
- package/dist/bootstrap/web/index.d.ts +7 -0
- package/dist/bootstrap/web/server.d.ts +7 -0
- package/dist/bootstrap/web/session.d.ts +23 -0
- package/dist/bootstrap/web/slug.d.ts +1 -0
- package/dist/config/app.d.ts +10 -0
- package/dist/config/contentSecurityPolicy.d.ts +5 -0
- package/dist/config/cors.d.ts +9 -0
- package/dist/config/database.d.ts +10 -0
- package/dist/config/features.d.ts +18 -0
- package/dist/config/frontend.d.ts +6 -0
- package/dist/config/rateLimit.d.ts +9 -0
- package/dist/core/auth/accessControl.d.ts +8 -0
- package/dist/core/auth/authContext.d.ts +12 -0
- package/dist/core/auth/guard.d.ts +36 -0
- package/dist/core/auth/membershipContext.d.ts +16 -0
- package/dist/core/auth/membershipContextMiddleware.d.ts +3 -0
- package/dist/core/auth/membershipMiddleware.d.ts +2 -0
- package/dist/core/auth/oauth/oidcProvider.d.ts +18 -0
- package/dist/core/auth/oauth/providers.d.ts +22 -0
- package/dist/core/auth/oauth/samlProvider.d.ts +9 -0
- package/dist/core/auth/oauth/types.d.ts +11 -0
- package/dist/core/auth/password.d.ts +3 -0
- package/dist/core/auth/policy.d.ts +15 -0
- package/dist/core/auth/tokenHash.d.ts +3 -0
- package/dist/core/crypto/fieldEncryption.d.ts +13 -0
- package/dist/core/crypto/mfaSecret.d.ts +3 -0
- package/dist/core/database/baseRepository.d.ts +44 -0
- package/dist/core/database/connection.d.ts +7 -0
- package/dist/core/database/connectionContext.d.ts +7 -0
- package/dist/core/database/errors.d.ts +12 -0
- package/dist/core/database/index.d.ts +11 -0
- package/dist/core/database/query.d.ts +51 -0
- package/dist/core/database/relationships.d.ts +26 -0
- package/dist/core/database/table.d.ts +13 -0
- package/dist/core/database/transaction.d.ts +3 -0
- package/dist/core/database/types.d.ts +29 -0
- package/dist/core/errors/http.d.ts +33 -0
- package/dist/core/events/eventBus.d.ts +10 -0
- package/dist/core/events/index.d.ts +4 -0
- package/dist/core/http/authMiddleware.d.ts +5 -0
- package/dist/core/http/authorizeMiddleware.d.ts +5 -0
- package/dist/core/http/bodySizeLimitMiddleware.d.ts +4 -0
- package/dist/core/http/contentNegotiation.d.ts +2 -0
- package/dist/core/http/corsMiddleware.d.ts +3 -0
- package/dist/core/http/csrfMiddleware.d.ts +3 -0
- package/dist/core/http/csrfToken.d.ts +14 -0
- package/dist/core/http/flashMiddleware.d.ts +3 -0
- package/dist/core/http/flashSession.d.ts +12 -0
- package/dist/core/http/loginThrottleMiddleware.d.ts +11 -0
- package/dist/core/http/memoryThrottleMiddleware.d.ts +9 -0
- package/dist/core/http/metricsMiddleware.d.ts +4 -0
- package/dist/core/http/middleware.d.ts +8 -0
- package/dist/core/http/requestMetaContext.d.ts +16 -0
- package/dist/core/http/requireAbilityMiddleware.d.ts +4 -0
- package/dist/core/http/requireAuthMiddleware.d.ts +4 -0
- package/dist/core/http/requireGlobalAdminMiddleware.d.ts +3 -0
- package/dist/core/http/requireWebAuthMiddleware.d.ts +4 -0
- package/dist/core/http/routeMiddleware.d.ts +3 -0
- package/dist/core/http/securityHeadersMiddleware.d.ts +3 -0
- package/dist/core/http/throttleMiddleware.d.ts +11 -0
- package/dist/core/logging/logger.d.ts +17 -0
- package/dist/core/logging/requestLoggingMiddleware.d.ts +3 -0
- package/dist/core/metrics/prometheus.d.ts +26 -0
- package/dist/core/pagination/index.d.ts +17 -0
- package/dist/core/queue/index.d.ts +19 -0
- package/dist/core/security/publicReads.d.ts +3 -0
- package/dist/core/security/securityEvents.d.ts +6 -0
- package/dist/core/security/tokenExpiry.d.ts +2 -0
- package/dist/core/security/totp.d.ts +3 -0
- package/dist/core/tenant/databaseTenantContext.d.ts +2 -0
- package/dist/core/tenant/resolveTenant.d.ts +3 -0
- package/dist/core/tenant/tenantContext.d.ts +14 -0
- package/dist/core/tenant/tenantDatabaseScope.d.ts +7 -0
- package/dist/core/tenant/tenantMiddleware.d.ts +6 -0
- package/dist/core/tracing/otel.d.ts +26 -0
- package/dist/core/tracing/traceContext.d.ts +10 -0
- package/dist/core/tracing/tracingMiddleware.d.ts +3 -0
- package/dist/db/connection/createConnection.d.ts +6 -0
- package/dist/db/connection/index.d.ts +11 -0
- package/dist/domain/abilities.d.ts +5 -0
- package/dist/domain/auth.d.ts +4 -0
- package/dist/index.js +1751 -0
- package/dist/modules/organization/memberRepository.d.ts +14 -0
- package/dist/modules/organization/memberTypes.d.ts +9 -0
- package/dist/modules/user/apiTokenRepository.d.ts +8 -0
- package/dist/modules/user/apiTokenTable.d.ts +3 -0
- package/dist/modules/user/authService.d.ts +23 -0
- package/dist/modules/user/notificationRepository.d.ts +6 -0
- package/dist/modules/user/notificationService.d.ts +25 -0
- package/dist/modules/user/notificationTable.d.ts +3 -0
- package/dist/modules/user/notificationTypes.d.ts +12 -0
- package/dist/modules/user/oauthIdentityRepository.d.ts +9 -0
- package/dist/modules/user/provider.d.ts +11 -0
- package/dist/modules/user/repository.d.ts +12 -0
- package/dist/modules/user/table.d.ts +3 -0
- package/dist/modules/user/tokenService.d.ts +29 -0
- package/dist/modules/user/types.d.ts +46 -0
- package/dist/types/services.d.ts +16 -0
- package/package.json +38 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { TableDefinition } from "./table.ts";
|
|
2
|
+
import type { MutationValues, QueryOptions, QueryWhere, UpdateValues } from "./types.ts";
|
|
3
|
+
declare function quoteIdentifier(identifier: string): string;
|
|
4
|
+
declare function qualifyColumn(tableName: string, column: string): string;
|
|
5
|
+
declare function buildWhereClause<TEntity>(tableName: string, where?: QueryWhere<TEntity>): {
|
|
6
|
+
clause: string;
|
|
7
|
+
params: unknown[];
|
|
8
|
+
};
|
|
9
|
+
declare function resolveSoftDeleteColumn<TEntity>(table: TableDefinition<TEntity>): string | null;
|
|
10
|
+
declare function buildQueryWhereClause<TEntity>(table: TableDefinition<TEntity>, options?: Pick<QueryOptions<TEntity>, "where" | "withTrashed" | "onlyTrashed">): {
|
|
11
|
+
clause: string;
|
|
12
|
+
params: unknown[];
|
|
13
|
+
};
|
|
14
|
+
declare function buildOrderByClause<TEntity>(tableName: string, orderBy?: QueryOptions<TEntity>["orderBy"]): string;
|
|
15
|
+
declare function buildSelectQuery<TEntity>(table: TableDefinition<TEntity>, options?: QueryOptions<TEntity>): {
|
|
16
|
+
text: string;
|
|
17
|
+
params: unknown[];
|
|
18
|
+
};
|
|
19
|
+
declare function buildCountQuery<TEntity>(table: TableDefinition<TEntity>, where?: QueryWhere<TEntity>, options?: Pick<QueryOptions<TEntity>, "withTrashed" | "onlyTrashed">): {
|
|
20
|
+
text: string;
|
|
21
|
+
params: unknown[];
|
|
22
|
+
};
|
|
23
|
+
declare function buildProjectionQuery<TEntity>(table: TableDefinition<TEntity>, expression: string, alias: string, options?: QueryOptions<TEntity>): {
|
|
24
|
+
text: string;
|
|
25
|
+
params: unknown[];
|
|
26
|
+
};
|
|
27
|
+
declare function buildGroupedCountQuery<TEntity, K extends keyof TEntity & string>(table: TableDefinition<TEntity>, column: K, where?: QueryWhere<TEntity>, options?: Pick<QueryOptions<TEntity>, "withTrashed" | "onlyTrashed">): {
|
|
28
|
+
text: string;
|
|
29
|
+
params: unknown[];
|
|
30
|
+
};
|
|
31
|
+
declare function buildInsertQuery<TEntity, PrimaryKey extends keyof TEntity & string>(table: TableDefinition<TEntity, PrimaryKey>, values: MutationValues<TEntity>): {
|
|
32
|
+
text: string;
|
|
33
|
+
params: unknown[];
|
|
34
|
+
};
|
|
35
|
+
declare function buildUpdateQuery<TEntity, PrimaryKey extends keyof TEntity & string>(table: TableDefinition<TEntity, PrimaryKey>, id: TEntity[PrimaryKey], changes: UpdateValues<TEntity, PrimaryKey>): {
|
|
36
|
+
text: string;
|
|
37
|
+
params: unknown[];
|
|
38
|
+
};
|
|
39
|
+
declare function buildSoftDeleteByIdQuery<TEntity, PrimaryKey extends keyof TEntity & string>(table: TableDefinition<TEntity, PrimaryKey>, id: TEntity[PrimaryKey], deletedAt: Date): {
|
|
40
|
+
text: string;
|
|
41
|
+
params: unknown[];
|
|
42
|
+
};
|
|
43
|
+
declare function buildRestoreByIdQuery<TEntity, PrimaryKey extends keyof TEntity & string>(table: TableDefinition<TEntity, PrimaryKey>, id: TEntity[PrimaryKey]): {
|
|
44
|
+
text: string;
|
|
45
|
+
params: unknown[];
|
|
46
|
+
};
|
|
47
|
+
declare function buildDeleteByIdQuery<TEntity, PrimaryKey extends keyof TEntity & string>(table: TableDefinition<TEntity, PrimaryKey>, id: TEntity[PrimaryKey]): {
|
|
48
|
+
text: string;
|
|
49
|
+
params: unknown[];
|
|
50
|
+
};
|
|
51
|
+
export { buildCountQuery, buildDeleteByIdQuery, buildGroupedCountQuery, buildInsertQuery, buildOrderByClause, buildProjectionQuery, buildQueryWhereClause, buildRestoreByIdQuery, buildSelectQuery, buildSoftDeleteByIdQuery, buildUpdateQuery, buildWhereClause, qualifyColumn, quoteIdentifier, resolveSoftDeleteColumn, };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface HasManyRelation<TParent, TChild, LocalKey extends keyof TParent & string = keyof TParent & string, ForeignKey extends keyof TChild & string = keyof TChild & string> {
|
|
2
|
+
type: "hasMany";
|
|
3
|
+
name: string;
|
|
4
|
+
localKey: LocalKey;
|
|
5
|
+
foreignKey: ForeignKey;
|
|
6
|
+
}
|
|
7
|
+
interface BelongsToRelation<TChild, TParent, ForeignKey extends keyof TChild & string = keyof TChild & string, OwnerKey extends keyof TParent & string = keyof TParent & string> {
|
|
8
|
+
type: "belongsTo";
|
|
9
|
+
name: string;
|
|
10
|
+
foreignKey: ForeignKey;
|
|
11
|
+
ownerKey: OwnerKey;
|
|
12
|
+
}
|
|
13
|
+
declare function hasMany<TParent, TChild, LocalKey extends keyof TParent & string = keyof TParent & string, ForeignKey extends keyof TChild & string = keyof TChild & string>(definition: {
|
|
14
|
+
name: string;
|
|
15
|
+
localKey: LocalKey;
|
|
16
|
+
foreignKey: ForeignKey;
|
|
17
|
+
}): HasManyRelation<TParent, TChild, LocalKey, ForeignKey>;
|
|
18
|
+
declare function belongsTo<TChild, TParent, ForeignKey extends keyof TChild & string = keyof TChild & string, OwnerKey extends keyof TParent & string = keyof TParent & string>(definition: {
|
|
19
|
+
name: string;
|
|
20
|
+
foreignKey: ForeignKey;
|
|
21
|
+
ownerKey: OwnerKey;
|
|
22
|
+
}): BelongsToRelation<TChild, TParent, ForeignKey, OwnerKey>;
|
|
23
|
+
declare function indexHasManyRelation<TParent, TChild, LocalKey extends keyof TParent & string, ForeignKey extends keyof TChild & string>(parents: readonly TParent[], children: readonly TChild[], relation: HasManyRelation<TParent, TChild, LocalKey, ForeignKey>): Map<TParent[LocalKey], TChild[]>;
|
|
24
|
+
declare function indexBelongsToRelation<TChild, TParent, ForeignKey extends keyof TChild & string, OwnerKey extends keyof TParent & string>(children: readonly TChild[], parents: readonly TParent[], relation: BelongsToRelation<TChild, TParent, ForeignKey, OwnerKey>): Map<TChild[ForeignKey], TParent>;
|
|
25
|
+
export type { BelongsToRelation, HasManyRelation };
|
|
26
|
+
export { belongsTo, hasMany, indexBelongsToRelation, indexHasManyRelation };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { QueryOrder } from "./types.ts";
|
|
2
|
+
interface TableDefinition<TEntity, PrimaryKey extends keyof TEntity & string = keyof TEntity & string> {
|
|
3
|
+
name: string;
|
|
4
|
+
primaryKey: PrimaryKey;
|
|
5
|
+
columns: readonly (keyof TEntity & string)[];
|
|
6
|
+
defaultOrderBy?: QueryOrder<TEntity> | QueryOrder<TEntity>[];
|
|
7
|
+
softDeletes?: boolean | {
|
|
8
|
+
column?: keyof TEntity & string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
declare function defineTable<TEntity, PrimaryKey extends keyof TEntity & string = keyof TEntity & string>(definition: TableDefinition<TEntity, PrimaryKey>): TableDefinition<TEntity, PrimaryKey>;
|
|
12
|
+
export type { TableDefinition };
|
|
13
|
+
export { defineTable };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type DatabaseComparable = string | number | Date;
|
|
2
|
+
type DatabaseScalar = DatabaseComparable | boolean | null;
|
|
3
|
+
type QueryOperator = {
|
|
4
|
+
eq?: DatabaseScalar;
|
|
5
|
+
in?: readonly DatabaseScalar[];
|
|
6
|
+
gt?: DatabaseComparable;
|
|
7
|
+
gte?: DatabaseComparable;
|
|
8
|
+
lt?: DatabaseComparable;
|
|
9
|
+
lte?: DatabaseComparable;
|
|
10
|
+
isNull?: boolean;
|
|
11
|
+
};
|
|
12
|
+
type QueryFilterValue = DatabaseScalar | readonly DatabaseScalar[] | QueryOperator;
|
|
13
|
+
type QueryWhere<TEntity> = Partial<Record<keyof TEntity & string, QueryFilterValue>>;
|
|
14
|
+
type QueryOrder<TEntity> = {
|
|
15
|
+
column: keyof TEntity & string;
|
|
16
|
+
direction?: "ASC" | "DESC" | "asc" | "desc";
|
|
17
|
+
};
|
|
18
|
+
type QueryOrderShorthand<TEntity> = Partial<Record<keyof TEntity & string, "ASC" | "DESC" | "asc" | "desc">>;
|
|
19
|
+
interface QueryOptions<TEntity> {
|
|
20
|
+
where?: QueryWhere<TEntity>;
|
|
21
|
+
orderBy?: QueryOrder<TEntity> | QueryOrder<TEntity>[] | QueryOrderShorthand<TEntity>;
|
|
22
|
+
limit?: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
withTrashed?: boolean;
|
|
25
|
+
onlyTrashed?: boolean;
|
|
26
|
+
}
|
|
27
|
+
type MutationValues<TEntity> = Partial<TEntity>;
|
|
28
|
+
type UpdateValues<TEntity, PrimaryKey extends keyof TEntity & string = keyof TEntity & string> = Partial<Omit<TEntity, PrimaryKey>>;
|
|
29
|
+
export type { DatabaseComparable, DatabaseScalar, MutationValues, QueryFilterValue, QueryOperator, QueryOptions, QueryOrder, QueryWhere, UpdateValues, };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
declare class HttpError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly details?: unknown;
|
|
4
|
+
constructor(status: number, message: string, details?: unknown);
|
|
5
|
+
}
|
|
6
|
+
declare class BadRequestError extends HttpError {
|
|
7
|
+
constructor(message?: string, details?: unknown);
|
|
8
|
+
}
|
|
9
|
+
declare class NotFoundError extends HttpError {
|
|
10
|
+
constructor(message?: string, details?: unknown);
|
|
11
|
+
}
|
|
12
|
+
declare class ConflictError extends HttpError {
|
|
13
|
+
constructor(message?: string, details?: unknown);
|
|
14
|
+
}
|
|
15
|
+
declare class UnprocessableEntityError extends HttpError {
|
|
16
|
+
constructor(message?: string, details?: unknown);
|
|
17
|
+
}
|
|
18
|
+
declare class ValidationError extends HttpError {
|
|
19
|
+
constructor(message?: string, details?: unknown);
|
|
20
|
+
}
|
|
21
|
+
declare class ForbiddenError extends HttpError {
|
|
22
|
+
constructor(message?: string, details?: unknown);
|
|
23
|
+
}
|
|
24
|
+
declare class UnauthorizedError extends HttpError {
|
|
25
|
+
constructor(message?: string, details?: unknown);
|
|
26
|
+
}
|
|
27
|
+
declare class PayloadTooLargeError extends HttpError {
|
|
28
|
+
constructor(message?: string, details?: unknown);
|
|
29
|
+
}
|
|
30
|
+
declare class PreconditionFailedError extends HttpError {
|
|
31
|
+
constructor(message?: string, details?: unknown);
|
|
32
|
+
}
|
|
33
|
+
export { BadRequestError, ConflictError, ForbiddenError, HttpError, NotFoundError, PayloadTooLargeError, PreconditionFailedError, UnauthorizedError, UnprocessableEntityError, ValidationError, };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type EventListener = (payload: unknown) => void | Promise<void>;
|
|
2
|
+
declare class EventBus {
|
|
3
|
+
constructor();
|
|
4
|
+
private readonly listeners;
|
|
5
|
+
listen(event: string, listener: EventListener): () => void;
|
|
6
|
+
dispatch(event: string, payload: unknown): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
declare const eventBus: EventBus;
|
|
9
|
+
export type { EventListener };
|
|
10
|
+
export { EventBus, eventBus };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type AuthUser, authContext } from "../auth/authContext";
|
|
2
|
+
import type { AuthManager } from "../auth/guard";
|
|
3
|
+
declare function createAuthMiddleware(auth: AuthManager): (request: Request, next: () => Promise<Response>) => Promise<Response>;
|
|
4
|
+
export type { AuthUser };
|
|
5
|
+
export { authContext, createAuthMiddleware };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AuthManager } from "../auth/guard";
|
|
2
|
+
import type { Policy, PolicyGate } from "../auth/policy";
|
|
3
|
+
import type { Middleware } from "./middleware";
|
|
4
|
+
declare function createAuthorizeMiddleware(gate: PolicyGate, auth: AuthManager, resource: string, action: keyof Policy): Middleware;
|
|
5
|
+
export { createAuthorizeMiddleware };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare const CSRF_COOKIE = "workhub_csrf";
|
|
2
|
+
declare function createCsrfTokenCookie(): {
|
|
3
|
+
token: string;
|
|
4
|
+
cookie: string;
|
|
5
|
+
};
|
|
6
|
+
declare function resolveCsrfToken(request: Request): {
|
|
7
|
+
token: string;
|
|
8
|
+
cookie?: string;
|
|
9
|
+
};
|
|
10
|
+
declare function readSubmittedCsrfToken(request: Request): string | null;
|
|
11
|
+
declare function readSubmittedCsrfTokenFromBody(request: Request): Promise<string | null>;
|
|
12
|
+
declare function verifyCsrfToken(request: Request, submittedToken: string | null): boolean;
|
|
13
|
+
declare function resolveCsrfTokenForRequest(request: Request): string;
|
|
14
|
+
export { CSRF_COOKIE, createCsrfTokenCookie, readSubmittedCsrfToken, readSubmittedCsrfTokenFromBody, resolveCsrfToken, resolveCsrfTokenForRequest, verifyCsrfToken, };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type FlashLevel = "success" | "error" | "info";
|
|
2
|
+
interface FlashMessage {
|
|
3
|
+
level: FlashLevel;
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
declare function createFlashCookie(message: FlashMessage): string;
|
|
7
|
+
declare function clearFlashCookie(): string;
|
|
8
|
+
declare function pullFlash(request: Request): FlashMessage | null;
|
|
9
|
+
declare function flashResponse(response: Response, message: FlashMessage): Response;
|
|
10
|
+
declare function withFlashClear(response: Response): Response;
|
|
11
|
+
export type { FlashLevel, FlashMessage };
|
|
12
|
+
export { clearFlashCookie, createFlashCookie, flashResponse, pullFlash, withFlashClear };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Middleware } from "./middleware";
|
|
2
|
+
interface LoginThrottleOptions {
|
|
3
|
+
redisUrl: string;
|
|
4
|
+
maxAttempts: number;
|
|
5
|
+
decaySeconds: number;
|
|
6
|
+
keyPrefix?: string;
|
|
7
|
+
}
|
|
8
|
+
declare function resolveLoginIdentity(request: Request): string;
|
|
9
|
+
declare function createLoginThrottleMiddleware(options: LoginThrottleOptions): Middleware;
|
|
10
|
+
export type { LoginThrottleOptions };
|
|
11
|
+
export { createLoginThrottleMiddleware, resolveLoginIdentity };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Middleware } from "./middleware";
|
|
2
|
+
interface MemoryThrottleOptions {
|
|
3
|
+
maxAttempts: number;
|
|
4
|
+
decaySeconds: number;
|
|
5
|
+
keyPrefix?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function createMemoryThrottleMiddleware(options: MemoryThrottleOptions): Middleware;
|
|
8
|
+
export type { MemoryThrottleOptions };
|
|
9
|
+
export { createMemoryThrottleMiddleware };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type Middleware = (request: Request, next: () => Promise<Response>) => Promise<Response>;
|
|
2
|
+
type RouteHandler = (request: Request) => Response | Promise<Response>;
|
|
3
|
+
declare function composeMiddleware(...middleware: Middleware[]): (handler: RouteHandler) => RouteHandler;
|
|
4
|
+
declare function requestIdMiddleware(request: Request, next: () => Promise<Response>): Promise<Response>;
|
|
5
|
+
declare function wrapRouteHandler<T>(handler: T, middleware: Middleware[]): T;
|
|
6
|
+
declare function applyMiddlewareToRoutes<T extends Record<string, unknown>>(routes: T, middleware: Middleware[]): T;
|
|
7
|
+
export type { Middleware, RouteHandler };
|
|
8
|
+
export { applyMiddlewareToRoutes, composeMiddleware, requestIdMiddleware, wrapRouteHandler };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
type RequestMeta = {
|
|
3
|
+
ipAddress: string | null;
|
|
4
|
+
userAgent: string | null;
|
|
5
|
+
request?: Request;
|
|
6
|
+
flash?: {
|
|
7
|
+
level: string;
|
|
8
|
+
message: string;
|
|
9
|
+
} | null;
|
|
10
|
+
csrfToken?: string;
|
|
11
|
+
};
|
|
12
|
+
declare const requestMetaContext: AsyncLocalStorage<RequestMeta>;
|
|
13
|
+
declare function runWithRequestMeta<T>(meta: RequestMeta, callback: () => T | Promise<T>): T | Promise<T>;
|
|
14
|
+
declare function currentRequestMeta(): RequestMeta;
|
|
15
|
+
export type { RequestMeta };
|
|
16
|
+
export { currentRequestMeta, requestMetaContext, runWithRequestMeta };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Middleware } from "./middleware";
|
|
2
|
+
interface ThrottleOptions {
|
|
3
|
+
redisUrl: string;
|
|
4
|
+
maxAttempts: number;
|
|
5
|
+
decaySeconds: number;
|
|
6
|
+
keyPrefix?: string;
|
|
7
|
+
}
|
|
8
|
+
declare function resolveThrottleIdentity(request: Request): string;
|
|
9
|
+
declare function createThrottleMiddleware(options: ThrottleOptions): Middleware;
|
|
10
|
+
export type { ThrottleOptions };
|
|
11
|
+
export { createThrottleMiddleware, resolveThrottleIdentity };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
2
|
+
interface LogContext {
|
|
3
|
+
requestId?: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
declare class Logger {
|
|
7
|
+
private readonly channel;
|
|
8
|
+
constructor(channel?: string);
|
|
9
|
+
private write;
|
|
10
|
+
debug(message: string, context?: LogContext): void;
|
|
11
|
+
info(message: string, context?: LogContext): void;
|
|
12
|
+
warn(message: string, context?: LogContext): void;
|
|
13
|
+
error(message: string, context?: LogContext): void;
|
|
14
|
+
}
|
|
15
|
+
declare const appLogger: Logger;
|
|
16
|
+
export type { LogContext, LogLevel };
|
|
17
|
+
export { appLogger, Logger };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface MetricLabels {
|
|
2
|
+
method: string;
|
|
3
|
+
path: string;
|
|
4
|
+
status: string;
|
|
5
|
+
}
|
|
6
|
+
declare class PrometheusRegistry {
|
|
7
|
+
private readonly httpRequestsTotal;
|
|
8
|
+
private readonly httpRequestDurationMs;
|
|
9
|
+
incrementHttpRequest(labels: MetricLabels): void;
|
|
10
|
+
observeHttpDuration(labels: MetricLabels, durationMs: number): void;
|
|
11
|
+
renderMetrics(): string;
|
|
12
|
+
resetForTests(): void;
|
|
13
|
+
getHttpRequestSummary(): {
|
|
14
|
+
totalRequests: number;
|
|
15
|
+
byStatus: Record<string, number>;
|
|
16
|
+
topPaths: Array<{
|
|
17
|
+
method: string;
|
|
18
|
+
path: string;
|
|
19
|
+
count: number;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
private metricKey;
|
|
23
|
+
}
|
|
24
|
+
declare const prometheusRegistry: PrometheusRegistry;
|
|
25
|
+
export type { MetricLabels };
|
|
26
|
+
export { PrometheusRegistry, prometheusRegistry };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface PaginationMeta {
|
|
2
|
+
page: number;
|
|
3
|
+
per_page: number;
|
|
4
|
+
total: number;
|
|
5
|
+
last_page: number;
|
|
6
|
+
}
|
|
7
|
+
interface PaginatedResult<T> {
|
|
8
|
+
data: T[];
|
|
9
|
+
meta: PaginationMeta;
|
|
10
|
+
}
|
|
11
|
+
declare function buildPaginationMeta(input: {
|
|
12
|
+
page: number;
|
|
13
|
+
perPage: number;
|
|
14
|
+
total: number;
|
|
15
|
+
}): PaginationMeta;
|
|
16
|
+
export type { PaginatedResult, PaginationMeta };
|
|
17
|
+
export { buildPaginationMeta };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type QueuePriority = "high" | "default" | "low";
|
|
2
|
+
declare abstract class Job<TPayload extends object = object> {
|
|
3
|
+
readonly maxAttempts?: number;
|
|
4
|
+
readonly backoffMs?: number;
|
|
5
|
+
readonly priority?: QueuePriority;
|
|
6
|
+
abstract handle(payload: TPayload): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
interface Queue {
|
|
9
|
+
dispatch<TPayload extends object>(job: Job<TPayload>, payload: TPayload): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
declare class SyncQueue implements Queue {
|
|
12
|
+
dispatch<TPayload extends object>(job: Job<TPayload>, payload: TPayload): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
declare class AsyncQueue implements Queue {
|
|
15
|
+
dispatch<TPayload extends object>(job: Job<TPayload>, payload: TPayload): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
declare function createQueue(driver: "sync" | "async"): Queue;
|
|
18
|
+
export type { Queue, QueuePriority };
|
|
19
|
+
export { AsyncQueue, createQueue, Job, SyncQueue };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
type TenantContext = {
|
|
3
|
+
id: number;
|
|
4
|
+
slug: string;
|
|
5
|
+
plan: "free" | "pro" | "enterprise";
|
|
6
|
+
region: "eu" | "us" | "apac";
|
|
7
|
+
};
|
|
8
|
+
declare const tenantContext: AsyncLocalStorage<TenantContext>;
|
|
9
|
+
declare function runWithTenant<T>(tenant: TenantContext, callback: () => T | Promise<T>): T | Promise<T>;
|
|
10
|
+
declare function currentTenant(): TenantContext | null;
|
|
11
|
+
declare function currentTenantId(): number;
|
|
12
|
+
declare function rateLimitMultiplierForPlan(plan: TenantContext["plan"]): number;
|
|
13
|
+
export type { TenantContext };
|
|
14
|
+
export { currentTenant, currentTenantId, rateLimitMultiplierForPlan, runWithTenant, tenantContext };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type TenantContext } from "./tenantContext";
|
|
2
|
+
type TransactionHandle = {
|
|
3
|
+
unsafe(query: string, params?: readonly unknown[]): Promise<unknown[]>;
|
|
4
|
+
};
|
|
5
|
+
declare function applyTenantContextToTransaction(transaction: TransactionHandle, tenantId: number): Promise<void>;
|
|
6
|
+
declare function runWithTenantDatabase<T>(tenant: TenantContext, callback: () => T | Promise<T>): Promise<T>;
|
|
7
|
+
export { applyTenantContextToTransaction, runWithTenantDatabase };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TenantContext } from "./tenantContext";
|
|
2
|
+
declare const DEFAULT_TENANT: TenantContext;
|
|
3
|
+
declare function resolveUserTenantId(userId: number): Promise<number>;
|
|
4
|
+
declare function auditChecksum(payload: Record<string, unknown>): string;
|
|
5
|
+
declare function createTenantMiddleware(): (request: Request, next: () => Promise<Response>) => Promise<Response>;
|
|
6
|
+
export { auditChecksum, createTenantMiddleware, DEFAULT_TENANT, resolveUserTenantId };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface OtelSpan {
|
|
2
|
+
traceId: string;
|
|
3
|
+
spanId: string;
|
|
4
|
+
name: string;
|
|
5
|
+
startTimeUnixNano: string;
|
|
6
|
+
endTimeUnixNano: string;
|
|
7
|
+
attributes: Array<{
|
|
8
|
+
key: string;
|
|
9
|
+
value: {
|
|
10
|
+
stringValue: string;
|
|
11
|
+
};
|
|
12
|
+
}>;
|
|
13
|
+
status: {
|
|
14
|
+
code: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
declare function createSpan(input: {
|
|
18
|
+
traceId: string;
|
|
19
|
+
name: string;
|
|
20
|
+
startedAt: number;
|
|
21
|
+
endedAt: number;
|
|
22
|
+
attributes?: Record<string, string>;
|
|
23
|
+
}): OtelSpan;
|
|
24
|
+
declare function exportOtelSpan(span: OtelSpan): Promise<void>;
|
|
25
|
+
export type { OtelSpan };
|
|
26
|
+
export { createSpan, exportOtelSpan };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
type TraceContext = {
|
|
3
|
+
traceId: string;
|
|
4
|
+
spanId: string;
|
|
5
|
+
};
|
|
6
|
+
declare const traceContextStorage: AsyncLocalStorage<TraceContext>;
|
|
7
|
+
declare function runWithTraceContext<T>(context: TraceContext, callback: () => T | Promise<T>): T | Promise<T>;
|
|
8
|
+
declare function currentTraceId(): string | null;
|
|
9
|
+
export type { TraceContext };
|
|
10
|
+
export { currentTraceId, runWithTraceContext, traceContextStorage };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SQL } from "bun";
|
|
2
|
+
import type { DatabaseConfig } from "../../config/database";
|
|
3
|
+
type DatabaseConnection = InstanceType<typeof SQL>;
|
|
4
|
+
declare function createDatabaseConnection(config: DatabaseConfig): DatabaseConnection;
|
|
5
|
+
export type { DatabaseConnection };
|
|
6
|
+
export { createDatabaseConnection };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type DatabaseConnection } from "./createConnection";
|
|
2
|
+
declare function getDatabase(): DatabaseConnection;
|
|
3
|
+
declare function pingDatabase(connection?: DatabaseConnection): Promise<boolean>;
|
|
4
|
+
declare function ensureDatabaseConnection(): Promise<DatabaseConnection>;
|
|
5
|
+
declare function closeDatabase(): Promise<void>;
|
|
6
|
+
declare function replaceDatabaseConnectionForTests(connection?: DatabaseConnection): Promise<void>;
|
|
7
|
+
declare function resetDatabaseConnectionForTests(connection: DatabaseConnection): void;
|
|
8
|
+
declare const db: Bun.SQL;
|
|
9
|
+
export default db;
|
|
10
|
+
export type { DatabaseConnection };
|
|
11
|
+
export { closeDatabase, ensureDatabaseConnection, getDatabase, pingDatabase, replaceDatabaseConnectionForTests, resetDatabaseConnectionForTests, };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
declare const MEMBER_ABILITIES: readonly ["organizations:read", "projects:read", "projects:create", "tasks:read", "tasks:create", "comments:read", "comments:create", "attachments:read", "attachments:create", "auth:tokens:read", "auth:tokens:write"];
|
|
2
|
+
declare const ADMIN_ABILITIES: readonly ["organizations:read", "projects:read", "projects:create", "tasks:read", "tasks:create", "comments:read", "comments:create", "attachments:read", "attachments:create", "auth:tokens:read", "auth:tokens:write", "organizations:create", "organizations:update", "organizations:delete", "projects:update", "projects:delete", "tasks:update", "tasks:delete", "comments:update", "comments:delete", "attachments:delete", "webhooks:read", "webhooks:write", "audit:read"];
|
|
3
|
+
declare const PLATFORM_ADMIN_ABILITIES: readonly ["*"];
|
|
4
|
+
declare function resolveAbilitiesForRole(role: string | null | undefined): string[];
|
|
5
|
+
export { ADMIN_ABILITIES, MEMBER_ABILITIES, PLATFORM_ADMIN_ABILITIES, resolveAbilitiesForRole };
|