@mrxsys/mrx-core 2.4.0 → 2.5.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/CHANGELOG.md +318 -33
- package/README.md +3 -3
- package/dist/chunk-1a3wj3m1.js +272 -0
- package/dist/chunk-370444pc.js +43 -0
- package/dist/chunk-5qtpggzv.js +38 -0
- package/dist/chunk-84mqvfsk.js +69 -0
- package/dist/chunk-cq973ydc.js +82 -0
- package/dist/chunk-f5z7x01b.js +352 -0
- package/dist/chunk-pc66jgqv.js +220 -0
- package/dist/chunk-s07amdhx.js +77 -0
- package/dist/chunk-v8v7982b.js +58 -0
- package/dist/chunk-vknq69e0.js +23 -0
- package/dist/chunk-yvyahr2h.js +40 -0
- package/dist/errors/baseError.d.ts +9 -0
- package/dist/errors/enums/httpErrorStatusCodes.d.ts +42 -0
- package/dist/errors/httpError.d.ts +14 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.js +11 -0
- package/dist/errors/types/baseErrorOptions.d.ts +15 -0
- package/dist/errors/types/httpErrorOptions.d.ts +13 -0
- package/dist/errors/types/index.d.ts +2 -0
- package/dist/modules/data/data.d.ts +115 -0
- package/dist/modules/data/enums/dataErrorKeys.d.ts +3 -0
- package/dist/modules/data/index.d.ts +1 -0
- package/dist/modules/data/index.js +16 -0
- package/dist/modules/data/transformers/camelCase.d.ts +25 -0
- package/dist/modules/data/transformers/index.d.ts +4 -0
- package/dist/modules/data/transformers/index.js +32 -0
- package/dist/modules/data/transformers/kebabCase.d.ts +25 -0
- package/dist/modules/data/transformers/pascalCase.d.ts +25 -0
- package/dist/modules/data/transformers/snakeCase.d.ts +25 -0
- package/dist/modules/data/types/camelCase.d.ts +1 -0
- package/dist/modules/data/types/caseTransformer.d.ts +13 -0
- package/dist/modules/data/types/index.d.ts +10 -0
- package/dist/modules/data/types/kebabCase.d.ts +1 -0
- package/dist/modules/data/types/pascalCase.d.ts +2 -0
- package/dist/modules/data/types/snakeCase.d.ts +1 -0
- package/dist/modules/data/types/transformKeysCamelCase.d.ts +4 -0
- package/dist/modules/data/types/transformKeysKebabCase.d.ts +4 -0
- package/dist/modules/data/types/transformKeysPascalCase.d.ts +4 -0
- package/dist/modules/data/types/transformKeysSnakeCase.d.ts +4 -0
- package/dist/modules/data/types/transformObjectKeys.d.ts +9 -0
- package/dist/modules/database/enums/databaseErrorKeys.d.ts +28 -0
- package/dist/modules/database/enums/mssqlErrorCode.d.ts +25 -0
- package/dist/modules/database/events/index.d.ts +2 -0
- package/dist/modules/database/events/mssqlEventMap.d.ts +6 -0
- package/dist/modules/database/events/tableEventMap.d.ts +7 -0
- package/dist/modules/database/index.d.ts +2 -0
- package/dist/modules/database/index.js +14 -0
- package/dist/{database → modules/database}/mssql.d.ts +21 -25
- package/dist/{database → modules/database}/table.d.ts +6 -6
- package/dist/modules/database/types/index.d.ts +3 -0
- package/dist/{database → modules/database}/types/mssqlDatabaseOption.d.ts +16 -37
- package/dist/modules/database/types/mssqlEventLog.d.ts +14 -0
- package/dist/modules/database/types/queryContext.d.ts +11 -0
- package/dist/modules/elysia/crud/crud.d.ts +46 -0
- package/dist/modules/elysia/crud/index.d.ts +1 -0
- package/dist/modules/elysia/crud/index.js +299 -0
- package/dist/modules/elysia/crud/types/crudOperationBaseOptions.d.ts +6 -0
- package/dist/modules/elysia/crud/types/crudOperationCountOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationDeleteOneOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationDeleteOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationFindOneOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationFindOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationInsertOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationUpdateOneOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationUpdateOptions.d.ts +2 -0
- package/dist/modules/elysia/crud/types/crudOperationsOptions.d.ts +18 -0
- package/dist/modules/elysia/crud/types/crudOptions.d.ts +23 -0
- package/dist/modules/elysia/crud/types/index.d.ts +11 -0
- package/dist/modules/elysia/crudSchema/crudSchema.d.ts +18 -0
- package/dist/modules/elysia/crudSchema/index.d.ts +1 -0
- package/dist/modules/elysia/crudSchema/index.js +10 -0
- package/dist/modules/elysia/crudSchema/types/adaptiveWhereClauseSchema.d.ts +31 -0
- package/dist/modules/elysia/crudSchema/types/crudModelsType.d.ts +14 -0
- package/dist/modules/elysia/crudSchema/types/crudSchemaOperations.d.ts +10 -0
- package/dist/modules/elysia/crudSchema/types/crudSchemaOptions.d.ts +13 -0
- package/dist/modules/elysia/crudSchema/types/index.d.ts +8 -0
- package/dist/modules/elysia/crudSchema/types/orderSchema.d.ts +11 -0
- package/dist/modules/elysia/crudSchema/types/qSchema.d.ts +15 -0
- package/dist/modules/elysia/crudSchema/types/queryOptionsBuilderOptions.d.ts +11 -0
- package/dist/modules/elysia/crudSchema/types/selectedFieldSchema.d.ts +6 -0
- package/dist/modules/elysia/crudSchema/utils/createAdaptiveWhereClauseSchema.d.ts +17 -0
- package/dist/modules/elysia/crudSchema/utils/createCountResponse200Schema.d.ts +11 -0
- package/dist/modules/elysia/crudSchema/utils/createCountSchema.d.ts +16 -0
- package/dist/modules/elysia/crudSchema/utils/createDeleteSchema.d.ts +18 -0
- package/dist/modules/elysia/crudSchema/utils/createFiltersSchema.d.ts +17 -0
- package/dist/modules/elysia/crudSchema/utils/createFindSchema.d.ts +22 -0
- package/dist/modules/elysia/crudSchema/utils/createIdParamSchema.d.ts +4 -0
- package/dist/modules/elysia/crudSchema/utils/createInsertSchema.d.ts +8 -0
- package/dist/modules/elysia/crudSchema/utils/createOrderSchema.d.ts +12 -0
- package/dist/modules/elysia/crudSchema/utils/createPropertiesSchema.d.ts +12 -0
- package/dist/modules/elysia/crudSchema/utils/createQSchema.d.ts +12 -0
- package/dist/modules/elysia/crudSchema/utils/createResponse200Schema.d.ts +5 -0
- package/dist/modules/elysia/crudSchema/utils/createSelectedFieldsSchema.d.ts +12 -0
- package/dist/modules/elysia/crudSchema/utils/createUpdateOneSchema.d.ts +4 -0
- package/dist/modules/elysia/crudSchema/utils/createUpdateSchema.d.ts +10 -0
- package/dist/modules/elysia/crudSchema/utils/index.d.ts +15 -0
- package/dist/modules/elysia/crudSchema/utils/index.js +37 -0
- package/dist/modules/elysia/crudSchema/utils/isDateFromElysiaTypeBox.d.ts +2 -0
- package/dist/modules/elysia/dbResolver/dbResolver.d.ts +17 -0
- package/dist/modules/elysia/dbResolver/enums/dbResolverErrorKeys.d.ts +3 -0
- package/dist/modules/elysia/dbResolver/index.d.ts +1 -0
- package/dist/modules/elysia/dbResolver/index.js +14 -0
- package/dist/modules/elysia/dbResolver/types/dynamicDbOptions.d.ts +7 -0
- package/dist/modules/elysia/dbResolver/types/index.d.ts +1 -0
- package/dist/modules/elysia/error/error.d.ts +34 -0
- package/dist/modules/elysia/error/index.d.ts +1 -0
- package/dist/modules/elysia/error/index.js +58 -0
- package/dist/modules/elysia/jwt/enums/jwtErrorKeys.d.ts +4 -0
- package/dist/modules/elysia/jwt/index.d.ts +1 -0
- package/dist/modules/elysia/jwt/index.js +81 -0
- package/dist/modules/elysia/jwt/jwt.d.ts +119 -0
- package/dist/modules/elysia/jwt/types/index.d.ts +1 -0
- package/dist/modules/elysia/jwt/types/jwtOptions.d.ts +98 -0
- package/dist/modules/elysia/microservice/index.d.ts +1 -0
- package/dist/modules/elysia/microservice/index.js +96 -0
- package/dist/{elysia → modules/elysia/microservice}/microservice.d.ts +1 -1
- package/dist/modules/elysia/ratelimit/enums/ratelimitErrorKeys.d.ts +3 -0
- package/dist/modules/elysia/ratelimit/index.d.ts +1 -0
- package/dist/modules/elysia/ratelimit/index.js +55 -0
- package/dist/{elysia → modules/elysia/ratelimit}/ratelimit.d.ts +3 -13
- package/dist/modules/elysia/ratelimit/types/index.d.ts +1 -0
- package/dist/{elysia → modules/elysia/ratelimit}/types/rateLimitOptions.d.ts +6 -16
- package/dist/modules/logger/enums/loggerErrorKeys.d.ts +6 -0
- package/dist/modules/logger/events/index.d.ts +1 -0
- package/dist/modules/logger/events/loggerEvents.d.ts +11 -0
- package/dist/modules/logger/index.d.ts +1 -0
- package/dist/modules/logger/index.js +139 -0
- package/dist/modules/logger/logger.d.ts +189 -0
- package/dist/{logger → modules/logger}/strategies/consoleLogger.d.ts +4 -4
- package/dist/{logger → modules/logger}/strategies/fileLogger.d.ts +4 -4
- package/dist/modules/logger/strategies/index.d.ts +2 -0
- package/dist/modules/logger/strategies/index.js +44 -0
- package/dist/modules/logger/types/index.d.ts +6 -0
- package/dist/modules/logger/types/index.js +1 -0
- package/dist/{logger → modules/logger}/types/logStreamChunk.d.ts +4 -4
- package/dist/{logger → modules/logger}/types/loggerStrategy.d.ts +1 -1
- package/dist/modules/mailer/enums/mailerErrorKeys.d.ts +5 -0
- package/dist/modules/mailer/index.d.ts +1 -0
- package/dist/modules/mailer/index.js +64 -0
- package/dist/{mailer → modules/mailer}/smtp.d.ts +6 -6
- package/dist/modules/mailer/types/index.d.ts +3 -0
- package/dist/modules/mailer/types/index.js +1 -0
- package/dist/{mailer → modules/mailer}/types/smtpCredentials.d.ts +2 -2
- package/dist/{mailer → modules/mailer}/types/smtpOptions.d.ts +5 -5
- package/dist/{mailer → modules/mailer}/types/smtpPoolOptions.d.ts +1 -1
- package/dist/modules/repository/index.d.ts +1 -0
- package/dist/modules/repository/index.js +10 -0
- package/dist/modules/repository/repository.d.ts +421 -0
- package/dist/modules/repository/types/adaptiveWhereClause.d.ts +30 -0
- package/dist/modules/repository/types/filter.d.ts +43 -0
- package/dist/modules/repository/types/index.d.ts +8 -0
- package/dist/modules/repository/types/index.js +1 -0
- package/dist/modules/repository/types/orderByItem.d.ts +42 -0
- package/dist/modules/repository/types/queryOptions.d.ts +36 -0
- package/dist/{repository → modules/repository}/types/queryOptionsExtendPagination.d.ts +2 -2
- package/dist/{repository → modules/repository}/types/queryOptionsExtendStream.d.ts +1 -1
- package/dist/modules/repository/types/selectedFields.d.ts +37 -0
- package/dist/modules/singletonManager/enums/singletonManagerErrorKeys.d.ts +4 -0
- package/dist/modules/singletonManager/index.d.ts +1 -0
- package/dist/modules/singletonManager/index.js +8 -0
- package/dist/modules/singletonManager/singletonManager.d.ts +75 -0
- package/dist/modules/typedEventEmitter/index.d.ts +1 -0
- package/dist/modules/typedEventEmitter/index.js +7 -0
- package/dist/{typedEventEmitter → modules/typedEventEmitter}/typedEventEmitter.d.ts +33 -11
- package/dist/modules/typedEventEmitter/types/index.d.ts +1 -0
- package/dist/modules/typedEventEmitter/types/index.js +1 -0
- package/dist/utils/enums/utilsErrorKeys.d.ts +3 -0
- package/dist/utils/env.d.ts +1 -1
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +32 -1
- package/dist/utils/isDateString.d.ts +16 -0
- package/dist/utils/stream.d.ts +12 -1
- package/dist/utils/types/index.d.ts +1 -1
- package/dist/utils/types/streamWithAsyncIterable.d.ts +12 -5
- package/package.json +128 -128
- package/dist/chunk-1c7w5cx7.js +0 -3
- package/dist/chunk-40pg2cqx.js +0 -2
- package/dist/chunk-4v4tp5qj.js +0 -2
- package/dist/chunk-4w7nd4nw.js +0 -2
- package/dist/chunk-5nvsx7md.js +0 -2
- package/dist/chunk-89mnpfvy.js +0 -2
- package/dist/chunk-91srr77d.js +0 -2
- package/dist/chunk-9hj714bv.js +0 -2
- package/dist/chunk-9rss6865.js +0 -2
- package/dist/chunk-df9xr1f5.js +0 -2
- package/dist/chunk-dq00mfya.js +0 -2
- package/dist/chunk-fnb68m68.js +0 -2
- package/dist/chunk-g6a16nyh.js +0 -2
- package/dist/chunk-gtgpa8nc.js +0 -2
- package/dist/chunk-gxjax5n3.js +0 -2
- package/dist/chunk-h9er1sh5.js +0 -2
- package/dist/chunk-mwpajm9x.js +0 -2
- package/dist/chunk-n5w9cwwg.js +0 -2
- package/dist/chunk-pt7wrvtr.js +0 -2
- package/dist/chunk-qndyhwdn.js +0 -2
- package/dist/chunk-v5dfx8mh.js +0 -2
- package/dist/chunk-wgq0yyqw.js +0 -2
- package/dist/chunk-wtfcgg9s.js +0 -2
- package/dist/chunk-z00b1r18.js +0 -2
- package/dist/data/data.d.ts +0 -99
- package/dist/data/enums/dataErrorKeys.d.ts +0 -7
- package/dist/data/enums/index.d.ts +0 -1
- package/dist/data/enums/index.js +0 -2
- package/dist/data/index.d.ts +0 -1
- package/dist/data/index.js +0 -2
- package/dist/data/transformers/camelCase.d.ts +0 -25
- package/dist/data/transformers/index.d.ts +0 -4
- package/dist/data/transformers/index.js +0 -2
- package/dist/data/transformers/kebabCase.d.ts +0 -25
- package/dist/data/transformers/pascalCase.d.ts +0 -25
- package/dist/data/transformers/snakeCase.d.ts +0 -25
- package/dist/data/types/index.d.ts +0 -1
- package/dist/data/types/keyTransformer.d.ts +0 -11
- package/dist/database/enums/databaseErrorKeys.d.ts +0 -52
- package/dist/database/enums/index.d.ts +0 -2
- package/dist/database/enums/index.js +0 -2
- package/dist/database/enums/mssqlErrorCode.d.ts +0 -25
- package/dist/database/events/index.d.ts +0 -2
- package/dist/database/events/mssqlEventMap.d.ts +0 -6
- package/dist/database/events/tableEventMap.d.ts +0 -7
- package/dist/database/index.d.ts +0 -2
- package/dist/database/index.js +0 -2
- package/dist/database/types/index.d.ts +0 -3
- package/dist/database/types/mssqlEventLog.d.ts +0 -29
- package/dist/database/types/queryContext.d.ts +0 -11
- package/dist/elysia/advancedSearch.d.ts +0 -460
- package/dist/elysia/crud.d.ts +0 -609
- package/dist/elysia/dynamicDatabaseSelector.d.ts +0 -352
- package/dist/elysia/enums/elysiaErrorKeys.d.ts +0 -12
- package/dist/elysia/enums/httpStatusCode.d.ts +0 -241
- package/dist/elysia/enums/index.d.ts +0 -2
- package/dist/elysia/enums/index.js +0 -2
- package/dist/elysia/error.d.ts +0 -46
- package/dist/elysia/index.d.ts +0 -7
- package/dist/elysia/index.js +0 -2
- package/dist/elysia/jwt.d.ts +0 -46
- package/dist/elysia/schemas/index.d.ts +0 -2
- package/dist/elysia/schemas/index.js +0 -2
- package/dist/elysia/types/crudOptions.d.ts +0 -126
- package/dist/elysia/types/crudRoutes.d.ts +0 -2
- package/dist/elysia/types/dynamicDatabaseSelectorPluginOptions.d.ts +0 -30
- package/dist/elysia/types/index.d.ts +0 -5
- package/dist/elysia/types/jwtOptions.d.ts +0 -92
- package/dist/error/coreError.d.ts +0 -89
- package/dist/error/index.d.ts +0 -1
- package/dist/error/index.js +0 -2
- package/dist/error/types/coreErrorOptions.d.ts +0 -21
- package/dist/error/types/index.d.ts +0 -1
- package/dist/index.d.ts +0 -68
- package/dist/index.js +0 -2
- package/dist/logger/enums/index.d.ts +0 -1
- package/dist/logger/enums/index.js +0 -2
- package/dist/logger/enums/loggerErrorKeys.d.ts +0 -6
- package/dist/logger/events/index.d.ts +0 -1
- package/dist/logger/events/loggerEvents.d.ts +0 -4
- package/dist/logger/index.d.ts +0 -1
- package/dist/logger/index.js +0 -2
- package/dist/logger/logger.d.ts +0 -173
- package/dist/logger/strategies/index.d.ts +0 -2
- package/dist/logger/strategies/index.js +0 -2
- package/dist/logger/types/index.d.ts +0 -6
- package/dist/mailer/enums/index.d.ts +0 -1
- package/dist/mailer/enums/index.js +0 -2
- package/dist/mailer/enums/mailerErrorKeys.d.ts +0 -8
- package/dist/mailer/index.d.ts +0 -1
- package/dist/mailer/index.js +0 -2
- package/dist/mailer/types/index.d.ts +0 -3
- package/dist/repository/index.d.ts +0 -1
- package/dist/repository/index.js +0 -2
- package/dist/repository/repository.d.ts +0 -378
- package/dist/repository/types/advancedSearch.d.ts +0 -47
- package/dist/repository/types/index.d.ts +0 -8
- package/dist/repository/types/orderBy.d.ts +0 -21
- package/dist/repository/types/queryOptions.d.ts +0 -33
- package/dist/repository/types/selectedFields.d.ts +0 -16
- package/dist/repository/types/whereClause.d.ts +0 -15
- package/dist/singletonManager/enums/index.d.ts +0 -1
- package/dist/singletonManager/enums/index.js +0 -2
- package/dist/singletonManager/enums/singletonManagerErrorKeys.d.ts +0 -7
- package/dist/singletonManager/index.d.ts +0 -1
- package/dist/singletonManager/index.js +0 -2
- package/dist/singletonManager/singletonManager.d.ts +0 -112
- package/dist/store/index.d.ts +0 -1
- package/dist/store/index.js +0 -2
- package/dist/store/redis.d.ts +0 -6
- package/dist/typedEventEmitter/index.d.ts +0 -1
- package/dist/typedEventEmitter/index.js +0 -2
- package/dist/typedEventEmitter/types/index.d.ts +0 -1
- package/dist/utils/enums/index.d.ts +0 -1
- package/dist/utils/enums/index.js +0 -2
- package/dist/utils/enums/utilErrorKeys.d.ts +0 -4
- package/dist/utils/isIsoDateString.d.ts +0 -1
- /package/dist/{data → errors}/types/index.js +0 -0
- /package/dist/{database/events → modules/data/types}/index.js +0 -0
- /package/dist/{database/types → modules/database/events}/index.js +0 -0
- /package/dist/{elysia → modules/database}/types/index.js +0 -0
- /package/dist/{error → modules/elysia/crud}/types/index.js +0 -0
- /package/dist/{logger/events → modules/elysia/crudSchema/types}/index.js +0 -0
- /package/dist/{logger → modules/elysia/dbResolver}/types/index.js +0 -0
- /package/dist/{mailer → modules/elysia/jwt}/types/index.js +0 -0
- /package/dist/{elysia → modules/elysia/microservice}/schemas/info.d.ts +0 -0
- /package/dist/{elysia → modules/elysia/microservice}/schemas/ping.d.ts +0 -0
- /package/dist/{repository → modules/elysia/ratelimit}/types/index.js +0 -0
- /package/dist/{typedEventEmitter/types → modules/logger/events}/index.js +0 -0
- /package/dist/{logger → modules/logger}/types/bodiesIntersection.d.ts +0 -0
- /package/dist/{logger → modules/logger}/types/logLevels.d.ts +0 -0
- /package/dist/{logger → modules/logger}/types/strategyBody.d.ts +0 -0
- /package/dist/{logger → modules/logger}/types/strategyMap.d.ts +0 -0
- /package/dist/{repository → modules/repository}/types/transaction.d.ts +0 -0
- /package/dist/{typedEventEmitter → modules/typedEventEmitter}/types/eventMap.d.ts +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
HttpError
|
|
4
|
+
} from "../../../chunk-84mqvfsk.js";
|
|
5
|
+
import {
|
|
6
|
+
BaseError
|
|
7
|
+
} from "../../../chunk-vknq69e0.js";
|
|
8
|
+
|
|
9
|
+
// source/modules/elysia/error/error.ts
|
|
10
|
+
import { Elysia } from "elysia";
|
|
11
|
+
var error = new Elysia({
|
|
12
|
+
name: "errorPlugin"
|
|
13
|
+
}).error({
|
|
14
|
+
BaseError,
|
|
15
|
+
HttpError
|
|
16
|
+
}).onError(({ code, error: error2, set }) => {
|
|
17
|
+
set.headers["content-type"] = "application/json; charset=utf-8";
|
|
18
|
+
switch (code) {
|
|
19
|
+
case "HttpError":
|
|
20
|
+
set.status = error2.httpStatusCode;
|
|
21
|
+
return {
|
|
22
|
+
message: error2.message,
|
|
23
|
+
cause: error2.cause
|
|
24
|
+
};
|
|
25
|
+
case "BaseError":
|
|
26
|
+
set.status = 500;
|
|
27
|
+
return {
|
|
28
|
+
message: error2.message,
|
|
29
|
+
cause: error2.cause
|
|
30
|
+
};
|
|
31
|
+
case "VALIDATION": {
|
|
32
|
+
set.status = 422;
|
|
33
|
+
return {
|
|
34
|
+
message: "core.error.validation",
|
|
35
|
+
cause: {
|
|
36
|
+
on: error2.type,
|
|
37
|
+
found: error2.value,
|
|
38
|
+
errors: error2.all
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
case "NOT_FOUND":
|
|
43
|
+
set.status = 404;
|
|
44
|
+
return {
|
|
45
|
+
message: "core.error.not_found"
|
|
46
|
+
};
|
|
47
|
+
case "INTERNAL_SERVER_ERROR":
|
|
48
|
+
case "UNKNOWN":
|
|
49
|
+
default:
|
|
50
|
+
set.status = 500;
|
|
51
|
+
return {
|
|
52
|
+
message: "core.error.internal_server_error"
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}).as("global");
|
|
56
|
+
export {
|
|
57
|
+
error
|
|
58
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { jwt } from './jwt';
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
HttpError
|
|
4
|
+
} from "../../../chunk-84mqvfsk.js";
|
|
5
|
+
import"../../../chunk-vknq69e0.js";
|
|
6
|
+
|
|
7
|
+
// source/modules/elysia/jwt/jwt.ts
|
|
8
|
+
import { Elysia } from "elysia";
|
|
9
|
+
import {
|
|
10
|
+
SignJWT,
|
|
11
|
+
jwtVerify
|
|
12
|
+
} from "jose";
|
|
13
|
+
|
|
14
|
+
// source/modules/elysia/jwt/enums/jwtErrorKeys.ts
|
|
15
|
+
var JWT_ERROR_KEYS = {
|
|
16
|
+
JWT_SIGN_ERROR: "elysia.jwt.error.sign_error",
|
|
17
|
+
JWT_SECRET_NOT_FOUND: "elysia.jwt.error.secret_not_found"
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// source/modules/elysia/jwt/jwt.ts
|
|
21
|
+
var jwt = (options) => {
|
|
22
|
+
if (!options.secret)
|
|
23
|
+
throw new HttpError({
|
|
24
|
+
message: JWT_ERROR_KEYS.JWT_SECRET_NOT_FOUND,
|
|
25
|
+
httpStatusCode: "INTERNAL_SERVER_ERROR"
|
|
26
|
+
});
|
|
27
|
+
const encodedKey = new TextEncoder().encode(options.secret);
|
|
28
|
+
const contextKeyName = options.jwtKeyName ?? "jwt";
|
|
29
|
+
const defaultAlgorithm = "HS256";
|
|
30
|
+
const defaultExpiration = "15m";
|
|
31
|
+
return new Elysia({
|
|
32
|
+
name: "jwt",
|
|
33
|
+
seed: options
|
|
34
|
+
}).decorate(contextKeyName, {
|
|
35
|
+
async sign(additionalPayload, expiration = options.exp ?? defaultExpiration) {
|
|
36
|
+
const jwtId = crypto.randomUUID();
|
|
37
|
+
const finalPayload = {
|
|
38
|
+
iss: "elysia-jwt-plugin",
|
|
39
|
+
aud: "elysia-application",
|
|
40
|
+
jti: jwtId,
|
|
41
|
+
iat: Math.floor(Date.now() / 1000),
|
|
42
|
+
...options.payload,
|
|
43
|
+
...additionalPayload
|
|
44
|
+
};
|
|
45
|
+
try {
|
|
46
|
+
const headerParams = {
|
|
47
|
+
alg: defaultAlgorithm,
|
|
48
|
+
typ: "JWT",
|
|
49
|
+
...options.header ? Object.fromEntries(Object.entries(options.header).filter(([key]) => key !== "b64")) : {}
|
|
50
|
+
};
|
|
51
|
+
const jwt2 = new SignJWT(finalPayload).setProtectedHeader(headerParams).setIssuedAt().setExpirationTime(expiration);
|
|
52
|
+
if (finalPayload.iss)
|
|
53
|
+
jwt2.setIssuer(finalPayload.iss);
|
|
54
|
+
if (finalPayload.aud)
|
|
55
|
+
jwt2.setAudience(Array.isArray(finalPayload.aud) ? finalPayload.aud : [finalPayload.aud]);
|
|
56
|
+
return await jwt2.sign(encodedKey);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new HttpError({
|
|
59
|
+
message: JWT_ERROR_KEYS.JWT_SIGN_ERROR,
|
|
60
|
+
httpStatusCode: "INTERNAL_SERVER_ERROR",
|
|
61
|
+
cause: error
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
async verify(token) {
|
|
66
|
+
if (!token || token.trim() === "")
|
|
67
|
+
return false;
|
|
68
|
+
try {
|
|
69
|
+
const result = await jwtVerify(token, encodedKey, {
|
|
70
|
+
algorithms: [defaultAlgorithm]
|
|
71
|
+
});
|
|
72
|
+
return result;
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}).as("scoped");
|
|
78
|
+
};
|
|
79
|
+
export {
|
|
80
|
+
jwt
|
|
81
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import { type JWTPayload, type JWTVerifyResult } from 'jose';
|
|
3
|
+
import type { JWTOptions } from './types/jwtOptions';
|
|
4
|
+
/**
|
|
5
|
+
* The `elysiaJwtPlugin` provides secure JSON Web Token (JWT) authentication capabilities for Elysia applications.
|
|
6
|
+
*
|
|
7
|
+
* This plugin leverages the industry-standard `jose` library to ensure robust JWT handling with modern cryptographic standards.
|
|
8
|
+
*
|
|
9
|
+
* @template TJWTKeyName - The name to use for JWT functionality in the Elysia context (defaults to 'jwt')
|
|
10
|
+
* @param options - Configuration options for the JWT plugin
|
|
11
|
+
*
|
|
12
|
+
* @returns An Elysia plugin that adds JWT functionality to the application context
|
|
13
|
+
*
|
|
14
|
+
* @throws ({@link HttpError}) - When the secret key is missing or invalid
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* Basic usage
|
|
18
|
+
* ```ts
|
|
19
|
+
* const app = new Elysia()
|
|
20
|
+
* .use(jwt({
|
|
21
|
+
* secret: process.env.JWT_SECRET!,
|
|
22
|
+
* exp: '1h'
|
|
23
|
+
* }))
|
|
24
|
+
* .post('/login', ({ jwt }) => {
|
|
25
|
+
* return jwt.sign({ userId: 123, role: 'user' });
|
|
26
|
+
* })
|
|
27
|
+
* .get('/protected', async ({ jwt, headers }) => {
|
|
28
|
+
* const token = headers.authorization?.replace('Bearer ', '');
|
|
29
|
+
* const payload = await jwt.verify(token);
|
|
30
|
+
* if (!payload) throw new Error('Invalid token');
|
|
31
|
+
* return { user: payload };
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
* @example
|
|
35
|
+
* Custom context key name
|
|
36
|
+
* ```ts
|
|
37
|
+
* const app2 = new Elysia()
|
|
38
|
+
* .use(jwt({
|
|
39
|
+
* jwtKeyName: 'auth',
|
|
40
|
+
* secret: 'my-secret'
|
|
41
|
+
* }))
|
|
42
|
+
* .post('/login', ({ auth }) => auth.sign({ id: 1 }));
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare const jwt: <const TJWTKeyName extends string = "jwt">(options: JWTOptions<TJWTKeyName>) => Elysia<"", {
|
|
46
|
+
decorator: { [name in TJWTKeyName]: {
|
|
47
|
+
/**
|
|
48
|
+
* Signs a JWT with the provided payload and optional expiration time.
|
|
49
|
+
*
|
|
50
|
+
* @param additionalPayload - Custom payload data to include in the JWT
|
|
51
|
+
* @param expiration - Token expiration time (overrides default if provided)
|
|
52
|
+
*
|
|
53
|
+
* @returns A Promise that resolves to the signed JWT string
|
|
54
|
+
*
|
|
55
|
+
* @throws ({@link HttpError}) - When JWT signing fails due to invalid payload or configuration
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* Sign with user data
|
|
59
|
+
* ```ts
|
|
60
|
+
* const token = await jwt.sign({ userId: 123, role: 'admin' });
|
|
61
|
+
* ```
|
|
62
|
+
* @example
|
|
63
|
+
* Sign with custom expiration
|
|
64
|
+
* ```ts
|
|
65
|
+
* const token = await jwt.sign({ userId: 123 }, '2h');
|
|
66
|
+
* ````
|
|
67
|
+
* @example
|
|
68
|
+
* Sign with Date expiration
|
|
69
|
+
* ```ts
|
|
70
|
+
* const token = await jwt.sign({ userId: 123 }, new Date('2024-12-31'));
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
sign(additionalPayload?: JWTPayload, expiration?: number | string | Date): Promise<string>;
|
|
74
|
+
/**
|
|
75
|
+
* Verifies and decodes a JWT token.
|
|
76
|
+
*
|
|
77
|
+
* @param token - The JWT string to verify and decode
|
|
78
|
+
*
|
|
79
|
+
* @returns A Promise that resolves to the decoded payload or false if invalid
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* Verify token from Authorization header
|
|
83
|
+
* ```ts
|
|
84
|
+
* const token = headers.authorization?.replace('Bearer ', '');
|
|
85
|
+
* const payload = await jwt.verify(token);
|
|
86
|
+
*
|
|
87
|
+
* if (payload) {
|
|
88
|
+
* console.log('User ID:', payload.userId);
|
|
89
|
+
* console.log('Token expires:', new Date(payload.exp! * 1000));
|
|
90
|
+
* } else {
|
|
91
|
+
* console.log('Invalid or expired token');
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
verify(token?: string): Promise<JWTVerifyResult | false>;
|
|
96
|
+
}; } extends infer T ? { [K in keyof T]: T[K]; } : never;
|
|
97
|
+
store: {};
|
|
98
|
+
derive: {};
|
|
99
|
+
resolve: {};
|
|
100
|
+
}, {
|
|
101
|
+
typebox: {};
|
|
102
|
+
error: {};
|
|
103
|
+
}, {
|
|
104
|
+
schema: {};
|
|
105
|
+
standaloneSchema: {};
|
|
106
|
+
macro: {};
|
|
107
|
+
macroFn: {};
|
|
108
|
+
parser: {};
|
|
109
|
+
}, {}, {
|
|
110
|
+
derive: {};
|
|
111
|
+
resolve: {};
|
|
112
|
+
schema: import("elysia").MergeSchema<{}, {}, "">;
|
|
113
|
+
standaloneSchema: import("elysia/types").PrettifySchema<{}>;
|
|
114
|
+
}, {
|
|
115
|
+
derive: {};
|
|
116
|
+
resolve: {};
|
|
117
|
+
schema: {};
|
|
118
|
+
standaloneSchema: {};
|
|
119
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { JWTOptions } from './jwtOptions';
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { JWSHeaderParameters, JWTPayload } from 'jose';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for the JWT plugin.
|
|
4
|
+
*
|
|
5
|
+
* @template TJWTKeyName - The name to be used for accessing the JWT functionality in the Elysia context
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const options: JWTOption = {
|
|
10
|
+
* name: 'auth',
|
|
11
|
+
* secret: process.env.JWT_SECRET || 'your-secret-key',
|
|
12
|
+
* exp: '1d',
|
|
13
|
+
* header: {
|
|
14
|
+
* alg: 'HS256',
|
|
15
|
+
* typ: 'JWT'
|
|
16
|
+
* },
|
|
17
|
+
* payload: {
|
|
18
|
+
* iss: 'my-api',
|
|
19
|
+
* aud: 'my-client'
|
|
20
|
+
* }
|
|
21
|
+
* };
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export interface JWTOptions<TJWTKeyName extends string = 'jwt'> {
|
|
25
|
+
/**
|
|
26
|
+
* JWT name to add in context with decorate.
|
|
27
|
+
*
|
|
28
|
+
* This allows you to customize how you access the JWT functionality in your
|
|
29
|
+
* route handlers. For example, if set to 'auth', you would use `auth.sign()`
|
|
30
|
+
* instead of the default `jwt.sign()`.
|
|
31
|
+
*
|
|
32
|
+
* @defaultValue 'jwt'
|
|
33
|
+
*/
|
|
34
|
+
readonly jwtKeyName?: TJWTKeyName;
|
|
35
|
+
/**
|
|
36
|
+
* Secret key used to sign and verify JWTs.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* Using a string secret
|
|
40
|
+
* ```ts
|
|
41
|
+
* secret: 'your-very-secret-key'
|
|
42
|
+
*```
|
|
43
|
+
* @example
|
|
44
|
+
* Using an environment variable (recommended for production)
|
|
45
|
+
* ```ts
|
|
46
|
+
* secret: process.env.JWT_SECRET
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
readonly secret: string;
|
|
50
|
+
/**
|
|
51
|
+
* JWT expiration setting. Applies as the default expiration for tokens.
|
|
52
|
+
*
|
|
53
|
+
* Controls how long tokens are valid before they expire. This setting provides
|
|
54
|
+
* a good balance between security (limiting the window of opportunity for token misuse)
|
|
55
|
+
* and user experience (not requiring frequent re-authentication).
|
|
56
|
+
*
|
|
57
|
+
* @defaultValue '15m' (15 minutes)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* Set tokens to expire after 1 hour
|
|
61
|
+
* ```ts
|
|
62
|
+
* exp: '1h'
|
|
63
|
+
* ```
|
|
64
|
+
* @example
|
|
65
|
+
* Set tokens to expire at a specific date
|
|
66
|
+
* ```ts
|
|
67
|
+
* exp: new Date('2023-12-31')
|
|
68
|
+
* ```
|
|
69
|
+
* @example
|
|
70
|
+
* Set tokens to expire after 3600 seconds (1 hour)
|
|
71
|
+
* ```ts
|
|
72
|
+
* exp: 3600
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
readonly exp?: number | string | Date;
|
|
76
|
+
/**
|
|
77
|
+
* Default JWT header parameters to include in every JWT.
|
|
78
|
+
*
|
|
79
|
+
* This allows you to specify additional metadata about the token.
|
|
80
|
+
*/
|
|
81
|
+
readonly header?: JWSHeaderParameters;
|
|
82
|
+
/**
|
|
83
|
+
* Default payload values to include in every JWT.
|
|
84
|
+
*
|
|
85
|
+
* These values are merged with any additional payload provided during signing,
|
|
86
|
+
* allowing you to set standard claims that should be included in all tokens
|
|
87
|
+
* generated by your application.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* payload: {
|
|
92
|
+
* iss: 'my-api', // Issuer
|
|
93
|
+
* aud: 'my-frontend', // Audience
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
readonly payload?: JWTPayload;
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { microservice } from './microservice';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// source/modules/elysia/microservice/microservice.ts
|
|
3
|
+
import { Elysia } from "elysia";
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
import { platform } from "os";
|
|
6
|
+
|
|
7
|
+
// source/modules/elysia/microservice/schemas/info.ts
|
|
8
|
+
import { t } from "elysia";
|
|
9
|
+
var infoResponse200Schema = t.Object({
|
|
10
|
+
message: t.String({
|
|
11
|
+
description: "Message",
|
|
12
|
+
example: "Microservice Information"
|
|
13
|
+
}),
|
|
14
|
+
content: t.Object({
|
|
15
|
+
author: t.String({
|
|
16
|
+
description: "Author",
|
|
17
|
+
example: "Ruby"
|
|
18
|
+
}),
|
|
19
|
+
name: t.String({
|
|
20
|
+
description: "Name",
|
|
21
|
+
example: "API"
|
|
22
|
+
}),
|
|
23
|
+
version: t.String({
|
|
24
|
+
description: "Version",
|
|
25
|
+
example: "1.0.0"
|
|
26
|
+
}),
|
|
27
|
+
description: t.String({
|
|
28
|
+
description: "Description",
|
|
29
|
+
example: "Is a microservice that provides a RESTful API for the application."
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// source/modules/elysia/microservice/schemas/ping.ts
|
|
35
|
+
import { t as t2 } from "elysia";
|
|
36
|
+
var pingResponse200Schema = t2.Object({
|
|
37
|
+
message: t2.String({
|
|
38
|
+
description: "Message",
|
|
39
|
+
example: "pong"
|
|
40
|
+
})
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// source/modules/elysia/microservice/microservice.ts
|
|
44
|
+
var findPackageJson = (path) => {
|
|
45
|
+
const isWin = platform() === "win32";
|
|
46
|
+
const separator = isWin ? "\\" : "/";
|
|
47
|
+
if (isWin && /^[A-Z]:\\$/i.test(path) || !isWin && path === "/")
|
|
48
|
+
return "";
|
|
49
|
+
const packageJsonPath = path + separator + "package.json";
|
|
50
|
+
if (existsSync(packageJsonPath))
|
|
51
|
+
return packageJsonPath;
|
|
52
|
+
const pathParts = path.split(separator);
|
|
53
|
+
if (pathParts.length <= 1)
|
|
54
|
+
return "";
|
|
55
|
+
const newPath = pathParts.slice(0, -1).join(separator);
|
|
56
|
+
if (newPath === "")
|
|
57
|
+
return "";
|
|
58
|
+
return findPackageJson(newPath);
|
|
59
|
+
};
|
|
60
|
+
var packageJson = await import(findPackageJson(Bun.main));
|
|
61
|
+
var microservice = new Elysia({
|
|
62
|
+
name: "microservicePlugin",
|
|
63
|
+
prefix: "/microservice",
|
|
64
|
+
detail: {
|
|
65
|
+
tags: ["Microservice"],
|
|
66
|
+
security: []
|
|
67
|
+
}
|
|
68
|
+
}).model({
|
|
69
|
+
infoResponse200: infoResponse200Schema,
|
|
70
|
+
pingResponse200: pingResponse200Schema
|
|
71
|
+
}).get("/ping", () => ({
|
|
72
|
+
message: "pong"
|
|
73
|
+
}), {
|
|
74
|
+
detail: {
|
|
75
|
+
summary: "Ping",
|
|
76
|
+
description: "Ping the microservice to check if it is alive"
|
|
77
|
+
},
|
|
78
|
+
response: "pingResponse200"
|
|
79
|
+
}).get("/info", () => ({
|
|
80
|
+
message: "Microservice Information",
|
|
81
|
+
content: {
|
|
82
|
+
name: packageJson.default.name,
|
|
83
|
+
version: packageJson.default.version,
|
|
84
|
+
description: packageJson.default.description,
|
|
85
|
+
author: packageJson.default.author
|
|
86
|
+
}
|
|
87
|
+
}), {
|
|
88
|
+
detail: {
|
|
89
|
+
summary: "Info",
|
|
90
|
+
description: "Get information about the microservice"
|
|
91
|
+
},
|
|
92
|
+
response: "infoResponse200"
|
|
93
|
+
}).as("scoped");
|
|
94
|
+
export {
|
|
95
|
+
microservice
|
|
96
|
+
};
|
|
@@ -6,7 +6,7 @@ import { Elysia } from 'elysia';
|
|
|
6
6
|
* - `/ping`: Checks if the microservice is alive.
|
|
7
7
|
* - `/info`: Provides information about the microservice.
|
|
8
8
|
*/
|
|
9
|
-
export declare const
|
|
9
|
+
export declare const microservice: Elysia<"/microservice", {
|
|
10
10
|
decorator: {};
|
|
11
11
|
store: {};
|
|
12
12
|
derive: {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { rateLimit } from './ratelimit';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
HttpError
|
|
4
|
+
} from "../../../chunk-84mqvfsk.js";
|
|
5
|
+
import"../../../chunk-vknq69e0.js";
|
|
6
|
+
|
|
7
|
+
// source/modules/elysia/ratelimit/ratelimit.ts
|
|
8
|
+
import { Elysia } from "elysia";
|
|
9
|
+
|
|
10
|
+
// source/modules/elysia/ratelimit/enums/ratelimitErrorKeys.ts
|
|
11
|
+
var RATELIMIT_ERROR_KEYS = {
|
|
12
|
+
RATELIMIT_EXCEEDED: "elysia.ratelimit.error.exceeded"
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// source/modules/elysia/ratelimit/ratelimit.ts
|
|
16
|
+
var rateLimit = ({ redis, limit, window }) => new Elysia({
|
|
17
|
+
name: "rateLimit",
|
|
18
|
+
seed: {
|
|
19
|
+
redis,
|
|
20
|
+
limit,
|
|
21
|
+
window
|
|
22
|
+
}
|
|
23
|
+
}).onRequest(async ({ set, request, server }) => {
|
|
24
|
+
const ip = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || server?.requestIP(request)?.address || "127.0.0.1";
|
|
25
|
+
const key = `ratelimit:${ip}`;
|
|
26
|
+
const current = await redis.get(key);
|
|
27
|
+
const count = current ? parseInt(current) : 0;
|
|
28
|
+
if (count === 0)
|
|
29
|
+
await redis.setex(key, window, "1");
|
|
30
|
+
else
|
|
31
|
+
await redis.incr(key);
|
|
32
|
+
const newCount = await redis.get(key);
|
|
33
|
+
const currentCount = newCount ? parseInt(newCount) : 0;
|
|
34
|
+
if (currentCount > limit) {
|
|
35
|
+
set.status = 429;
|
|
36
|
+
throw new HttpError({
|
|
37
|
+
message: RATELIMIT_ERROR_KEYS.RATELIMIT_EXCEEDED,
|
|
38
|
+
httpStatusCode: "TOO_MANY_REQUESTS",
|
|
39
|
+
cause: {
|
|
40
|
+
limit,
|
|
41
|
+
window,
|
|
42
|
+
remaining: 0,
|
|
43
|
+
reset: await redis.ttl(key)
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
set.headers = {
|
|
48
|
+
"X-RateLimit-Limit": limit.toString(),
|
|
49
|
+
"X-RateLimit-Remaining": Math.max(0, limit - currentCount).toString(),
|
|
50
|
+
"X-RateLimit-Reset": (await redis.ttl(key)).toString()
|
|
51
|
+
};
|
|
52
|
+
}).as("scoped");
|
|
53
|
+
export {
|
|
54
|
+
rateLimit
|
|
55
|
+
};
|
|
@@ -5,11 +5,6 @@ import type { RateLimitOptions } from './types/rateLimitOptions';
|
|
|
5
5
|
* protecting APIs from excessive use and potential abuse. It tracks request rates by client IP
|
|
6
6
|
* and enforces configurable limits based on a sliding time window.
|
|
7
7
|
*
|
|
8
|
-
* The plugin uses Redis for tracking request counts, making it suitable for distributed
|
|
9
|
-
* environments where multiple server instances may be handling requests from the same client.
|
|
10
|
-
* When a client exceeds the configured request limit, the plugin returns a 429 Too Many Requests
|
|
11
|
-
* response with appropriate headers indicating the limit and reset time.
|
|
12
|
-
*
|
|
13
8
|
* ### Rate Limit Headers:
|
|
14
9
|
* The plugin adds the following headers to all responses:
|
|
15
10
|
* - `X-RateLimit-Limit`: The maximum number of requests allowed in the window
|
|
@@ -21,11 +16,7 @@ import type { RateLimitOptions } from './types/rateLimitOptions';
|
|
|
21
16
|
* @returns An {@link Elysia} plugin that adds rate limiting functionality
|
|
22
17
|
*
|
|
23
18
|
* @example
|
|
24
|
-
* ```
|
|
25
|
-
* import { Elysia } from 'elysia';
|
|
26
|
-
* import { Redis } from '#/core/store/redis';
|
|
27
|
-
* import { rateLimitPlugin } from '#/core/elysia/plugin/ratelimit';
|
|
28
|
-
*
|
|
19
|
+
* ```ts
|
|
29
20
|
* // Create Redis instance
|
|
30
21
|
* const redis = new Redis({
|
|
31
22
|
* host: 'localhost',
|
|
@@ -35,11 +26,10 @@ import type { RateLimitOptions } from './types/rateLimitOptions';
|
|
|
35
26
|
*
|
|
36
27
|
* // Create and configure the application with rate limiting
|
|
37
28
|
* const app = new Elysia()
|
|
38
|
-
* .use(
|
|
29
|
+
* .use(rateLimit({
|
|
39
30
|
* redis,
|
|
40
31
|
* limit: 100, // 100 requests
|
|
41
32
|
* window: 60, // per minute
|
|
42
|
-
* message: 'Too many requests, please try again later.'
|
|
43
33
|
* }))
|
|
44
34
|
* .get('/public-api', () => {
|
|
45
35
|
* return { success: true, message: 'This endpoint is rate limited' };
|
|
@@ -49,7 +39,7 @@ import type { RateLimitOptions } from './types/rateLimitOptions';
|
|
|
49
39
|
* app.listen(3000);
|
|
50
40
|
* ```
|
|
51
41
|
*/
|
|
52
|
-
export declare const
|
|
42
|
+
export declare const rateLimit: ({ redis, limit, window }: RateLimitOptions) => Elysia<"", {
|
|
53
43
|
decorator: {};
|
|
54
44
|
store: {};
|
|
55
45
|
derive: {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { RateLimitOptions } from './rateLimitOptions';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Redis } from '
|
|
1
|
+
import type { Redis } from 'ioredis';
|
|
2
2
|
/**
|
|
3
3
|
* Options to configure the rate limit plugin.
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
|
-
* ```
|
|
6
|
+
* ```ts
|
|
7
7
|
* const options: RateLimitOptions = {
|
|
8
8
|
* redis: redisInstance, // Your Redis instance
|
|
9
9
|
* limit: 100, // Allow 100 requests
|
|
@@ -14,31 +14,21 @@ import type { Redis } from '../../store/redis';
|
|
|
14
14
|
*/
|
|
15
15
|
export interface RateLimitOptions {
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
* @see {@link Redis}
|
|
17
|
+
* Redis instance used for storing rate limit data.
|
|
19
18
|
*/
|
|
20
|
-
redis: Redis;
|
|
19
|
+
readonly redis: Redis;
|
|
21
20
|
/**
|
|
22
21
|
* Maximum number of requests allowed in the time window.
|
|
23
22
|
*
|
|
24
23
|
* This defines how many requests a client can make within the specified time window
|
|
25
24
|
* before rate limiting is applied.
|
|
26
25
|
*/
|
|
27
|
-
limit: number;
|
|
26
|
+
readonly limit: number;
|
|
28
27
|
/**
|
|
29
28
|
* Time window in seconds during which the request limit applies.
|
|
30
29
|
*
|
|
31
30
|
* This defines the duration of the rate limiting window. For example, a window of 60
|
|
32
31
|
* with a limit of 100 allows 100 requests per minute per client.
|
|
33
32
|
*/
|
|
34
|
-
window: number;
|
|
35
|
-
/**
|
|
36
|
-
* Custom error message when rate limit is exceeded.
|
|
37
|
-
*
|
|
38
|
-
* If provided, this message will be included in the error response when a client
|
|
39
|
-
* exceeds their rate limit. If not provided, a default message is used.
|
|
40
|
-
*
|
|
41
|
-
* @defaultValue 'Rate limit exceeded'
|
|
42
|
-
*/
|
|
43
|
-
message?: string;
|
|
33
|
+
readonly window: number;
|
|
44
34
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const LOGGER_ERROR_KEYS: {
|
|
2
|
+
readonly STRATEGY_ALREADY_ADDED: "logger.error.strategy_already_added";
|
|
3
|
+
readonly STRATEGY_NOT_FOUND: "logger.error.strategy_not_found";
|
|
4
|
+
readonly NO_STRATEGY_ADDED: "logger.error.no_strategy_added";
|
|
5
|
+
readonly STRATEGY_ERROR: "logger.error.strategy_error";
|
|
6
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { LoggerEvent } from './loggerEvents';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Logger } from './logger';
|