@getstrata/core 0.2.0 → 0.3.2

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.
Files changed (130) hide show
  1. package/README.md +6 -0
  2. package/dist/bootstrap/applicationRegistry.d.ts +16 -0
  3. package/dist/bootstrap/config.d.ts +20 -0
  4. package/dist/bootstrap/contracts.d.ts +63 -0
  5. package/dist/bootstrap/httpKernel.d.ts +26 -0
  6. package/dist/config/app.d.ts +10 -0
  7. package/dist/config/contentSecurityPolicy.d.ts +5 -0
  8. package/dist/config/cors.d.ts +9 -0
  9. package/dist/config/database.d.ts +10 -0
  10. package/dist/config/features.d.ts +18 -0
  11. package/dist/config/frontend.d.ts +6 -0
  12. package/dist/config/rateLimit.d.ts +9 -0
  13. package/dist/config/uploads.d.ts +5 -0
  14. package/dist/core/auth/accessControl.d.ts +8 -0
  15. package/dist/core/auth/authContext.d.ts +12 -0
  16. package/dist/core/auth/guard.d.ts +36 -0
  17. package/dist/core/auth/membershipContext.d.ts +16 -0
  18. package/dist/core/auth/membershipContextMiddleware.d.ts +3 -0
  19. package/dist/core/auth/membershipMiddleware.d.ts +2 -0
  20. package/dist/core/auth/oauth/oidcProvider.d.ts +18 -0
  21. package/dist/core/auth/oauth/providers.d.ts +22 -0
  22. package/dist/core/auth/oauth/samlProvider.d.ts +9 -0
  23. package/dist/core/auth/oauth/types.d.ts +11 -0
  24. package/dist/core/auth/password.d.ts +3 -0
  25. package/dist/core/auth/policy.d.ts +15 -0
  26. package/dist/core/auth/tokenHash.d.ts +3 -0
  27. package/dist/core/cache/repository.d.ts +17 -0
  28. package/dist/core/cache/store.d.ts +12 -0
  29. package/dist/core/cache/taggedCache.d.ts +9 -0
  30. package/dist/core/cache/tags.d.ts +11 -0
  31. package/dist/core/crypto/fieldEncryption.d.ts +13 -0
  32. package/dist/core/crypto/mfaSecret.d.ts +3 -0
  33. package/dist/core/database/baseRepository.d.ts +47 -0
  34. package/dist/core/database/connection.d.ts +7 -0
  35. package/dist/core/database/connectionContext.d.ts +7 -0
  36. package/dist/core/database/errors.d.ts +12 -0
  37. package/dist/core/database/index.d.ts +12 -0
  38. package/dist/core/database/query.d.ts +51 -0
  39. package/dist/core/database/relationships.d.ts +26 -0
  40. package/dist/core/database/repositoryQuery.d.ts +20 -0
  41. package/dist/core/database/table.d.ts +13 -0
  42. package/dist/core/database/transaction.d.ts +3 -0
  43. package/dist/core/database/types.d.ts +29 -0
  44. package/dist/core/errors/http.d.ts +33 -0
  45. package/dist/core/events/eventBus.d.ts +10 -0
  46. package/dist/core/events/index.d.ts +4 -0
  47. package/dist/core/facades/index.d.ts +10 -0
  48. package/dist/core/http/authMiddleware.d.ts +5 -0
  49. package/dist/core/http/authorizeMiddleware.d.ts +5 -0
  50. package/dist/core/http/bodySizeLimitMiddleware.d.ts +4 -0
  51. package/dist/core/http/conditionalResponse.d.ts +2 -0
  52. package/dist/core/http/contentNegotiation.d.ts +2 -0
  53. package/dist/core/http/corsMiddleware.d.ts +3 -0
  54. package/dist/core/http/csrfMiddleware.d.ts +3 -0
  55. package/dist/core/http/csrfToken.d.ts +14 -0
  56. package/dist/core/http/etag.d.ts +18 -0
  57. package/dist/core/http/flashMiddleware.d.ts +3 -0
  58. package/dist/core/http/flashSession.d.ts +12 -0
  59. package/dist/core/http/formRequest.d.ts +10 -0
  60. package/dist/core/http/index.d.ts +27 -0
  61. package/dist/core/http/loginThrottleMiddleware.d.ts +11 -0
  62. package/dist/core/http/memoryThrottleMiddleware.d.ts +9 -0
  63. package/dist/core/http/metricsMiddleware.d.ts +4 -0
  64. package/dist/core/http/middleware.d.ts +8 -0
  65. package/dist/core/http/pagination.d.ts +11 -0
  66. package/dist/core/http/parseFormBody.d.ts +6 -0
  67. package/dist/core/http/parseMultipartUpload.d.ts +10 -0
  68. package/dist/core/http/requestMetaContext.d.ts +16 -0
  69. package/dist/core/http/requireAbilityMiddleware.d.ts +4 -0
  70. package/dist/core/http/requireAuthMiddleware.d.ts +4 -0
  71. package/dist/core/http/requireGlobalAdminMiddleware.d.ts +3 -0
  72. package/dist/core/http/requireWebAuthMiddleware.d.ts +4 -0
  73. package/dist/core/http/resources.d.ts +7 -0
  74. package/dist/core/http/route.d.ts +6 -0
  75. package/dist/core/http/routeMiddleware.d.ts +3 -0
  76. package/dist/core/http/routeModelBinding.d.ts +3 -0
  77. package/dist/core/http/securedRouteModelBinding.d.ts +10 -0
  78. package/dist/core/http/securityHeadersMiddleware.d.ts +3 -0
  79. package/dist/core/http/throttleMiddleware.d.ts +11 -0
  80. package/dist/core/http/validation.d.ts +23 -0
  81. package/dist/core/http/webErrorResponse.d.ts +5 -0
  82. package/dist/core/http/webFormRequest.d.ts +6 -0
  83. package/dist/core/logging/logger.d.ts +17 -0
  84. package/dist/core/logging/requestLoggingMiddleware.d.ts +3 -0
  85. package/dist/core/mail/mailer.d.ts +36 -0
  86. package/dist/core/metrics/prometheus.d.ts +26 -0
  87. package/dist/core/pagination/index.d.ts +17 -0
  88. package/dist/core/queue/index.d.ts +19 -0
  89. package/dist/core/security/publicReads.d.ts +3 -0
  90. package/dist/core/security/securityEvents.d.ts +6 -0
  91. package/dist/core/security/tokenExpiry.d.ts +2 -0
  92. package/dist/core/security/totp.d.ts +3 -0
  93. package/dist/core/storage/storage.d.ts +41 -0
  94. package/dist/core/tenant/databaseTenantContext.d.ts +2 -0
  95. package/dist/core/tenant/resolveTenant.d.ts +3 -0
  96. package/dist/core/tenant/tenantContext.d.ts +14 -0
  97. package/dist/core/tenant/tenantDatabaseScope.d.ts +7 -0
  98. package/dist/core/tenant/tenantMiddleware.d.ts +6 -0
  99. package/dist/core/tracing/otel.d.ts +26 -0
  100. package/dist/core/tracing/traceContext.d.ts +10 -0
  101. package/dist/core/tracing/tracingMiddleware.d.ts +3 -0
  102. package/dist/core/view/etaViewEngine.d.ts +15 -0
  103. package/dist/core/view/htmlResponse.d.ts +6 -0
  104. package/dist/core/view/index.d.ts +5 -0
  105. package/dist/core/view/viewEngine.d.ts +6 -0
  106. package/dist/core/view/webLayoutData.d.ts +17 -0
  107. package/dist/db/connection/createConnection.d.ts +6 -0
  108. package/dist/db/connection/index.d.ts +11 -0
  109. package/dist/domain/abilities.d.ts +5 -0
  110. package/dist/domain/auth.d.ts +4 -0
  111. package/dist/framework/public-api.d.ts +35 -0
  112. package/dist/index.js +120 -2
  113. package/dist/modules/organization/memberRepository.d.ts +14 -0
  114. package/dist/modules/organization/memberTypes.d.ts +9 -0
  115. package/dist/modules/user/apiTokenRepository.d.ts +8 -0
  116. package/dist/modules/user/apiTokenTable.d.ts +3 -0
  117. package/dist/modules/user/authService.d.ts +23 -0
  118. package/dist/modules/user/notificationRepository.d.ts +6 -0
  119. package/dist/modules/user/notificationService.d.ts +25 -0
  120. package/dist/modules/user/notificationTable.d.ts +3 -0
  121. package/dist/modules/user/notificationTypes.d.ts +12 -0
  122. package/dist/modules/user/oauthIdentityRepository.d.ts +9 -0
  123. package/dist/modules/user/provider.d.ts +11 -0
  124. package/dist/modules/user/repository.d.ts +12 -0
  125. package/dist/modules/user/table.d.ts +3 -0
  126. package/dist/modules/user/tokenService.d.ts +29 -0
  127. package/dist/modules/user/types.d.ts +46 -0
  128. package/dist/types/services.d.ts +16 -0
  129. package/package.json +7 -6
  130. package/index.ts +0 -1
@@ -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,20 @@
1
+ import type BaseRepository from "./baseRepository.ts";
2
+ import type { BelongsToRelation, HasManyRelation } from "./relationships.ts";
3
+ import type { QueryOptions, QueryWhere } from "./types.ts";
4
+ type LoadedRow = Record<string, unknown>;
5
+ declare class RepositoryQuery<TEntity extends object, PrimaryKey extends keyof TEntity & string> {
6
+ private readonly repository;
7
+ private whereClause;
8
+ private queryOptions;
9
+ private readonly eagerLoads;
10
+ constructor(repository: BaseRepository<TEntity, PrimaryKey>, whereClause?: QueryWhere<TEntity>, queryOptions?: Omit<QueryOptions<TEntity>, "where">);
11
+ where(where: QueryWhere<TEntity>): this;
12
+ orderBy(orderBy: QueryOptions<TEntity>["orderBy"]): this;
13
+ limit(limit: number): this;
14
+ withHasMany<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">): this;
15
+ withBelongsTo<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">): this;
16
+ get(): Promise<Array<TEntity & LoadedRow>>;
17
+ first(): Promise<(TEntity & LoadedRow) | null>;
18
+ private attach;
19
+ }
20
+ export { RepositoryQuery };
@@ -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,3 @@
1
+ import type { DatabaseConnection } from "./baseRepository.ts";
2
+ declare function runInTransaction<TValue>(operation: (connection: DatabaseConnection) => Promise<TValue>): Promise<TValue>;
3
+ export { runInTransaction };
@@ -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,4 @@
1
+ export type { EventListener } from "./eventBus";
2
+ export { EventBus, eventBus } from "./eventBus";
3
+ declare function modelEventName(tableName: string, action: string): string;
4
+ export { modelEventName };
@@ -0,0 +1,10 @@
1
+ declare function cache(): import("../../types/services").CacheLike;
2
+ declare function auth(): import("../auth/guard").AuthManager;
3
+ declare function policyGate(): import("../auth/policy").PolicyGate;
4
+ declare function queue(): import("../queue").Queue;
5
+ declare function events(): import("../events").EventBus;
6
+ declare function config<T>(key: string): T | undefined;
7
+ declare function log(): import("../logging/logger").Logger;
8
+ declare function mail(): import("../mail/mailer").Mailer;
9
+ declare function storageFacade(): import("../storage/storage").StorageManager;
10
+ export { auth, cache, config, events, log, mail, policyGate, queue, storageFacade as storage };
@@ -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,4 @@
1
+ import type { Middleware } from "./middleware";
2
+ declare function resolveMaxBodyBytes(): number;
3
+ declare function createBodySizeLimitMiddleware(maxBytes?: number): Middleware;
4
+ export { createBodySizeLimitMiddleware, resolveMaxBodyBytes };
@@ -0,0 +1,2 @@
1
+ declare function conditionalJsonResponse(request: Request | undefined, data: unknown, init?: ResponseInit): Response;
2
+ export { conditionalJsonResponse };
@@ -0,0 +1,2 @@
1
+ declare function requestPrefersJson(request?: Request): boolean;
2
+ export { requestPrefersJson };
@@ -0,0 +1,3 @@
1
+ import type { Middleware } from "./middleware";
2
+ declare function createCorsMiddleware(): Middleware;
3
+ export { createCorsMiddleware };
@@ -0,0 +1,3 @@
1
+ import type { Middleware } from "./middleware";
2
+ declare function createCsrfMiddleware(): Middleware;
3
+ export { createCsrfMiddleware };
@@ -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,18 @@
1
+ interface EtagVersioned {
2
+ id?: number | string;
3
+ updated_at?: Date | string | null;
4
+ created_at?: Date | string | null;
5
+ }
6
+ declare function isEtagEnabled(): boolean;
7
+ declare function computeEtagFromJson(data: unknown): string;
8
+ declare function etagFromResource(resource: EtagVersioned): string;
9
+ declare function etagValuesMatch(left: string, right: string): boolean;
10
+ declare function ifNoneMatchSatisfied(request: Request, etag: string): boolean;
11
+ declare function ifMatchSatisfied(request: Request, etag: string): boolean;
12
+ declare function assertIfMatch(request: Request, etag: string, options?: {
13
+ required?: boolean;
14
+ }): void;
15
+ declare function notModifiedResponse(etag: string): Response;
16
+ declare function applyConditionalGet(request: Request, response: Response, etag: string): Response;
17
+ export type { EtagVersioned };
18
+ export { applyConditionalGet, assertIfMatch, computeEtagFromJson, etagFromResource, etagValuesMatch, ifMatchSatisfied, ifNoneMatchSatisfied, isEtagEnabled, notModifiedResponse, };
@@ -0,0 +1,3 @@
1
+ import type { Middleware } from "./middleware";
2
+ declare function createFlashMiddleware(): Middleware;
3
+ export { createFlashMiddleware };
@@ -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,10 @@
1
+ declare abstract class FormRequest<TOutput> {
2
+ authorize(_request: Request): boolean | Promise<boolean>;
3
+ protected abstract parse(payload: unknown): TOutput;
4
+ validate(request: Request): Promise<TOutput>;
5
+ }
6
+ declare abstract class QueryFormRequest<TOutput> {
7
+ validate(request?: Request): TOutput;
8
+ protected abstract parseQuery(request?: Request): TOutput;
9
+ }
10
+ export { FormRequest, QueryFormRequest };
@@ -0,0 +1,27 @@
1
+ export { BadRequestError, ConflictError, ForbiddenError, HttpError, NotFoundError, PayloadTooLargeError, PreconditionFailedError, UnauthorizedError, UnprocessableEntityError, ValidationError, } from "../errors/http";
2
+ export type { PaginatedResult, PaginationMeta } from "../pagination";
3
+ export { createAuthMiddleware } from "./authMiddleware";
4
+ export { createAuthorizeMiddleware } from "./authorizeMiddleware";
5
+ export { conditionalJsonResponse } from "./conditionalResponse";
6
+ export type { EtagVersioned } from "./etag";
7
+ export { applyConditionalGet, assertIfMatch, computeEtagFromJson, etagFromResource, etagValuesMatch, ifMatchSatisfied, ifNoneMatchSatisfied, isEtagEnabled, notModifiedResponse, } from "./etag";
8
+ export { FormRequest, QueryFormRequest } from "./formRequest";
9
+ export type { Middleware, RouteHandler } from "./middleware";
10
+ export { applyMiddlewareToRoutes, composeMiddleware, requestIdMiddleware, wrapRouteHandler, } from "./middleware";
11
+ export { buildPaginationMeta, DEFAULT_PER_PAGE, MAX_PER_PAGE, paginatedResponse, parsePaginationQuery, } from "./pagination";
12
+ export { createRequireAuthMiddleware } from "./requireAuthMiddleware";
13
+ export { serializeDate, toPaginatedResourceCollection, toResourceCollection } from "./resources";
14
+ export { withMiddleware } from "./routeMiddleware";
15
+ export { bindRouteModel } from "./routeModelBinding";
16
+ export { securedBindRouteModel } from "./securedRouteModelBinding";
17
+ export { buildRequestCacheKey, expectObject, getQueryParams, parseJsonBody, parseOptionalBooleanQueryParam, parseOptionalEnumQueryParam, parseOptionalPositiveIntQueryParam, parsePositiveIntParam, readOptionalEnum, readOptionalPositiveInt, readOptionalString, readRequiredEnum, readRequiredPositiveInt, readRequiredString, } from "./validation";
18
+ declare function jsonResponse(data: unknown, init?: ResponseInit): Response;
19
+ declare function createdResponse(data: unknown, init?: ResponseInit): Response;
20
+ declare function noContentResponse(): Response;
21
+ declare function errorResponse(error: unknown): Response;
22
+ declare function withErrorHandling<TArgs extends unknown[]>(handler: (...args: TArgs) => Response | Promise<Response>): (...args: TArgs) => Promise<Response>;
23
+ export type { ParsedUpload } from "./parseMultipartUpload";
24
+ export { parseMultipartUpload, sanitizeUploadFileName } from "./parseMultipartUpload";
25
+ export type { RouteRequest } from "./route";
26
+ export { getRouteParams } from "./route";
27
+ export { createdResponse, errorResponse, jsonResponse, noContentResponse, withErrorHandling };
@@ -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,4 @@
1
+ import type { Middleware } from "./middleware";
2
+ declare function normalizeMetricPath(pathname: string): string;
3
+ declare function createMetricsMiddleware(): Middleware;
4
+ export { createMetricsMiddleware, normalizeMetricPath };
@@ -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,11 @@
1
+ import { buildPaginationMeta, type PaginatedResult, type PaginationMeta } from "../pagination";
2
+ declare const DEFAULT_PER_PAGE = 15;
3
+ declare const MAX_PER_PAGE = 100;
4
+ interface PaginationQuery {
5
+ page: number;
6
+ perPage: number;
7
+ }
8
+ declare function parsePaginationQuery(request?: Request): PaginationQuery;
9
+ declare function paginatedResponse<T>(data: T[], meta: PaginationMeta, init?: ResponseInit): Response;
10
+ export type { PaginatedResult, PaginationMeta, PaginationQuery };
11
+ export { buildPaginationMeta, DEFAULT_PER_PAGE, MAX_PER_PAGE, paginatedResponse, parsePaginationQuery, };
@@ -0,0 +1,6 @@
1
+ interface FormDataLike {
2
+ entries(): Iterable<[string, unknown]>;
3
+ }
4
+ declare function parseFormBody(request: Request): Promise<Record<string, string>>;
5
+ declare function formDataToRecord(formData: FormDataLike): Record<string, string>;
6
+ export { formDataToRecord, parseFormBody };
@@ -0,0 +1,10 @@
1
+ interface ParsedUpload {
2
+ fileName: string;
3
+ mimeType: string;
4
+ size: number;
5
+ contents: Uint8Array;
6
+ }
7
+ declare function sanitizeUploadFileName(name: string): string;
8
+ declare function parseMultipartUpload(request: Request, fieldName?: string): Promise<ParsedUpload>;
9
+ export type { ParsedUpload };
10
+ export { parseMultipartUpload, sanitizeUploadFileName };
@@ -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,4 @@
1
+ import type TokenService from "../../modules/user/tokenService";
2
+ import type { Middleware } from "./middleware";
3
+ declare function createRequireAbilityMiddleware(tokenService: TokenService): (ability: string) => Middleware;
4
+ export { createRequireAbilityMiddleware };
@@ -0,0 +1,4 @@
1
+ import type { AuthManager } from "../auth/guard";
2
+ import type { Middleware } from "./middleware";
3
+ declare function createRequireAuthMiddleware(auth: AuthManager): Middleware;
4
+ export { createRequireAuthMiddleware };
@@ -0,0 +1,3 @@
1
+ import type { Middleware } from "./middleware";
2
+ declare function createRequireGlobalAdminMiddleware(): Middleware;
3
+ export { createRequireGlobalAdminMiddleware };
@@ -0,0 +1,4 @@
1
+ import type { AuthManager } from "../auth/guard";
2
+ import type { Middleware } from "./middleware";
3
+ declare function createRequireWebAuthMiddleware(auth: AuthManager): Middleware;
4
+ export { createRequireWebAuthMiddleware };
@@ -0,0 +1,7 @@
1
+ declare function serializeDate(value: Date | string): string;
2
+ declare function toResourceCollection<TInput, TOutput>(items: readonly TInput[], transformer: (item: TInput) => TOutput): TOutput[];
3
+ declare function toPaginatedResourceCollection<TInput, TOutput, TMeta extends object>(items: readonly TInput[], meta: TMeta, transformer: (item: TInput) => TOutput): {
4
+ data: TOutput[];
5
+ meta: TMeta;
6
+ };
7
+ export { serializeDate, toPaginatedResourceCollection, toResourceCollection };
@@ -0,0 +1,6 @@
1
+ type RouteRequest<TParams extends Record<string, string>> = Request & {
2
+ params: TParams;
3
+ };
4
+ declare function getRouteParams<TParams extends Record<string, string>>(request: RouteRequest<TParams>): TParams;
5
+ export type { RouteRequest };
6
+ export { getRouteParams };
@@ -0,0 +1,3 @@
1
+ import { type Middleware, type RouteHandler } from "./middleware";
2
+ declare function withMiddleware(...middleware: Middleware[]): (handler: RouteHandler) => RouteHandler;
3
+ export { withMiddleware };
@@ -0,0 +1,3 @@
1
+ import type { RouteRequest } from "./route";
2
+ declare function bindRouteModel<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (id: number, request: RouteRequest<TParams>) => Promise<TModel>, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
3
+ export { bindRouteModel };
@@ -0,0 +1,10 @@
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
+ export type { RouteModelAuthorization };
10
+ export { securedBindRouteModel };
@@ -0,0 +1,3 @@
1
+ import type { Middleware } from "./middleware";
2
+ declare function createSecurityHeadersMiddleware(): Middleware;
3
+ export { createSecurityHeadersMiddleware };
@@ -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,23 @@
1
+ declare function buildRequestCacheKey(fallbackPath: string, request?: Request): string;
2
+ declare function getQueryParams(request?: Request): URLSearchParams;
3
+ declare function parseOptionalPositiveIntQueryParam(params: URLSearchParams, name: string): number | undefined;
4
+ declare function parseOptionalBooleanQueryParam(params: URLSearchParams, name: string): boolean | undefined;
5
+ declare function parseOptionalEnumQueryParam<TValue extends string>(params: URLSearchParams, name: string, allowedValues: readonly TValue[]): TValue | undefined;
6
+ declare function expectObject(value: unknown, label?: string): Record<string, unknown>;
7
+ declare function parseJsonBody<TValue>(request: Request, validator: (payload: unknown) => TValue): Promise<TValue>;
8
+ declare function readRequiredString(payload: Record<string, unknown>, field: string, options?: {
9
+ minLength?: number;
10
+ maxLength?: number;
11
+ pattern?: RegExp;
12
+ }): string;
13
+ declare function readOptionalString(payload: Record<string, unknown>, field: string, options?: {
14
+ minLength?: number;
15
+ maxLength?: number;
16
+ pattern?: RegExp;
17
+ }): string | undefined;
18
+ declare function readRequiredEnum<TValue extends string>(payload: Record<string, unknown>, field: string, allowedValues: readonly TValue[]): TValue;
19
+ declare function readOptionalEnum<TValue extends string>(payload: Record<string, unknown>, field: string, allowedValues: readonly TValue[]): TValue | undefined;
20
+ declare function readRequiredPositiveInt(payload: Record<string, unknown>, field: string): number;
21
+ declare function readOptionalPositiveInt(payload: Record<string, unknown>, field: string): number | undefined;
22
+ declare function parsePositiveIntParam(value: string, name?: string): number;
23
+ export { buildRequestCacheKey, expectObject, getQueryParams, parseJsonBody, parseOptionalBooleanQueryParam, parseOptionalEnumQueryParam, parseOptionalPositiveIntQueryParam, parsePositiveIntParam, readOptionalEnum, readOptionalPositiveInt, readOptionalString, readRequiredEnum, readRequiredPositiveInt, readRequiredString, };
@@ -0,0 +1,5 @@
1
+ type FieldErrors = Record<string, string[]>;
2
+ declare function normalizeFieldErrors(details: unknown): FieldErrors;
3
+ declare function webErrorResponse(error: unknown, request?: Request): Response | null;
4
+ export type { FieldErrors };
5
+ export { normalizeFieldErrors, webErrorResponse };
@@ -0,0 +1,6 @@
1
+ declare abstract class WebFormRequest<TOutput> {
2
+ authorize(_request: Request): boolean | Promise<boolean>;
3
+ protected abstract parse(payload: unknown): TOutput;
4
+ validate(request: Request): Promise<TOutput>;
5
+ }
6
+ export { WebFormRequest };
@@ -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,3 @@
1
+ import type { Middleware } from "../http/middleware";
2
+ declare function createRequestLoggingMiddleware(): Middleware;
3
+ export { createRequestLoggingMiddleware };
@@ -0,0 +1,36 @@
1
+ interface MailMessage {
2
+ to: string;
3
+ subject: string;
4
+ body: string;
5
+ }
6
+ interface MailDriver {
7
+ send(message: MailMessage): Promise<void>;
8
+ }
9
+ interface SmtpConfig {
10
+ host: string;
11
+ port: number;
12
+ username?: string;
13
+ password?: string;
14
+ from: string;
15
+ secure: boolean;
16
+ }
17
+ type SmtpTransport = (config: SmtpConfig, message: MailMessage) => Promise<void>;
18
+ declare function resolveSmtpConfig(): SmtpConfig;
19
+ declare class LogMailDriver implements MailDriver {
20
+ send(message: MailMessage): Promise<void>;
21
+ }
22
+ declare class SmtpMailDriver implements MailDriver {
23
+ private readonly config;
24
+ private readonly transport;
25
+ constructor(config: SmtpConfig, transport?: SmtpTransport);
26
+ send(message: MailMessage): Promise<void>;
27
+ }
28
+ declare class Mailer {
29
+ private readonly driver;
30
+ constructor(driver: MailDriver);
31
+ send(message: MailMessage): Promise<void>;
32
+ }
33
+ declare function createMailDriver(): MailDriver;
34
+ declare function mailer(): Mailer;
35
+ export type { MailDriver, MailMessage, SmtpConfig, SmtpTransport };
36
+ export { createMailDriver, LogMailDriver, Mailer, mailer, resolveSmtpConfig, SmtpMailDriver };