{"id":21532226,"url":"https://github.com/modscleo4/midori","last_synced_at":"2025-04-10T00:30:34.180Z","repository":{"id":115746813,"uuid":"520375710","full_name":"modscleo4/midori","owner":"modscleo4","description":"A Node.js Web API Framework WITHOUT Express","archived":false,"fork":false,"pushed_at":"2025-02-09T15:23:04.000Z","size":405,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T02:12:59.075Z","etag":null,"topics":["cron","http","http-server","javascript","json","jwt","multipart","problem-details","typescript","uuid","zlib"],"latest_commit_sha":null,"homepage":"http://modscleo4.dev.br/midori/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/modscleo4.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-02T06:17:53.000Z","updated_at":"2025-02-09T15:23:07.000Z","dependencies_parsed_at":"2024-03-17T19:34:34.085Z","dependency_job_id":"45be5e40-e7da-4c43-8bbe-5a7adad98693","html_url":"https://github.com/modscleo4/midori","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modscleo4%2Fmidori","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modscleo4%2Fmidori/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modscleo4%2Fmidori/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modscleo4%2Fmidori/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/modscleo4","download_url":"https://codeload.github.com/modscleo4/midori/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248134807,"owners_count":21053537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","http","http-server","javascript","json","jwt","multipart","problem-details","typescript","uuid","zlib"],"created_at":"2024-11-24T02:19:10.847Z","updated_at":"2025-04-10T00:30:34.167Z","avatar_url":"https://github.com/modscleo4.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Midori\nA Node.js Web API Framework WITHOUT Express.\n\nMidori is an opinionated Web API Framework designed for Node.js, using Node.js's native HTTP module as basis, built with TypeScript and being inspired from PSR standards.\n\n## Features\n- [x] Router\n- [x] Basic Middlewares\n- [x] Request and Response\n- [x] Error Handling\n- [x] Service Providers\n- [x] Config Providers\n- [x] Logger\n    - [x] Console\n    - [x] File\n    - [x] GELF\n- [x] Task Scheduler\n    - [x] Cron\n- [x] JWT\n    - [x] JWS\n    - [x] JWE\n    - [x] JWK\n- [x] CORS\n- [x] Content Security Policy\n- [x] Static Files\n- [x] Implicit HEAD and OPTIONS\n- [x] Response Compression using `node:zlib` module\n    - [x] Gzip\n    - [x] Deflate\n    - [x] Brotli\n- [x] Extensible Body Parser and Response Serializer\n    - [x] JSON+BigInt\n    - [x] Form\n    - [x] Multipart\n    - [x] Streams\n    - [x] RSS\n    - [x] XML\n- [x] Hashing using native Node.js `node:crypto` module\n    - [x] PBKDF2\n    - [x] Scrypt\n    - [x] SHA-256\n    - [x] SHA-512\n- [x] Problem Details\n- [x] Request Validation\n- [x] Auth\n    - [x] Basic\n    - [x] Bearer\n\n## Roadmap\n- [ ] Tests\n    - [x] JWE\n    - [x] JWS\n    - [x] ASN.1\n    - [x] Cron\n    - [x] RSS\n    - [x] XML\n- [x] Documentation\n- [ ] Rate Limiting\n\n## Installation\n```bash\nnpm install modscleo4/midori\n```\n\n## Usage\nSee [HTTP Bin](https://github.com/modscleo4/httpbin) for an example project.\n\n### Basic\n```ts\n// Import the node:http wrapper\nimport { Server } from 'midori/app';\n// Import the HTTP utilities\nimport { Request, Response } from 'midori/http';\n\n// Create the Server\nconst server = new Server();\n\n// Install a basic Middleware\nserver.pipe(async (req: Request, next: (req: Request) =\u003e Promise\u003cResponse\u003e): Promise\u003cResponse\u003e =\u003e {\n    // Return a response for all requests\n    return Response.json({\n        message: 'Hello World!'\n    });\n});\n\n// Start the server\nserver.listen(8080);\n```\n\n### Using the included Router\n```ts\n// Import the node:http wrapper\nimport { Server } from 'midori/app';\n// Import the HTTP utilities\nimport { Handler, Request, Response } from 'midori/http';\n// Import the Route creator utility\nimport { Router } from 'midori/router';\n// Import the required middlewares to support Router in the pipeline\nimport { RouterMiddleware, DispatchMiddleware, NotFoundMiddleware } from 'midori/middlewares';\n// Import the Router Service Provider factory\nimport { RouterServiceProviderFactory } from 'midori/providers';\n\n// Create a Router instance\nconst router = new Router();\n\n// Create a GET route\nrouter.get('/', async (req: Request): Promise\u003cResponse\u003e =\u003e {\n    // Return a response\n    return Response.json({\n        message: 'Hello World!'\n    });\n});\n\n// Create the Server\nconst server = new Server();\n\n// Install the Router Service Provider with the Router instance\nserver.install(RouterServiceProviderFactory(router));\n\n// Install the middlewares\nserver.pipe(RouterMiddleware);\nserver.pipe(DispatchMiddleware);\nserver.pipe(NotFoundMiddleware);\n\n// Start the server\nserver.listen(8080);\n```\n\n## Structure\nThe framework is designed to be as simple as possible, while still being powerful and flexible. As such, it is distributed in the following modules:\n\n### midori/app\nThe App module is the main module of the framework. It is responsible for bootstrapping the application, loading service providers, config providers, middlewares, routes and starting the server.\n- `ConfigProvider` - Abstract class designed for config providers. Install on the app using `app.configure(DerivedConfigProvider)` and retrieve using `app.config.get(DerivedConfigProvider)`.\n- `ServiceProvider` - Abstract class designed for service providers. Install on the app using `app.install(DerivedServiceProvider)` and retrieve using `app.service.get(DerivedServiceProvider)`.\n- `Server` - Midori's implementation of HTTP server using Node.js's native HTTP module. It is responsible for listening to requests and sending responses, as well as being the container for Configurations and Services installed on the app using `app.configure` and `app.install` respectively.\n\n### midori/auth\nThe Auth module is responsible for handling authentication and authorization.\n- `Auth` - Base Auth Service class using UserService to authenticate and authorize users, storing the user in the request Container.\n- `User` - Base User class used by Auth Service.\n- `UserService` - Abstract User Service class used by Auth Service responsible for fetching users from the source.\n\n### midori/errors\nThe Errors module is responsible for handling errors.\n- `AuthError` - Base class for authentication/authorization errors.\n- `HTTPError` - Base class for HTTP errors (any 4xx or 5xx response). It is designed to be caught and treated by `HTTPErrorMiddleware`.\n- `JWTError` - Base class for JWT errors, thrown by `JWT`.\n- `UnknownServiceError` - Error thrown when a service is not found in the Service Container.\n\n### midori/hash\nThe Hash module is responsible for generating secure hashes and verifying them.\n- `Hash` - Abstract Hash Service class responsible for generating and verifying hashes. Use `Hash.hash` to generate a hash and `Hash.verify` to verify a hash.\n```ts\nimport { Scrypt } from 'midori/hash'; // Or any other Hash Service you want to use\n\nconst hash = await Scrypt.hash('password'); // Can also pass a Buffer\nconst isTheSame = await Scrypt.verify(hash, 'password');\n```\n- `PBKDF2` - Hash Service class using PBKDF2 algorithm.\n- `Scrypt` - Hash Service class using Scrypt algorithm.\n- `SHA256` - Hash Service class using SHA-256 algorithm.\n- `SHA512` - Hash Service class using SHA-512 algorithm.\n\n### midori/http\nThe HTTP module is responsible for handling HTTP requests and responses.\n- `EStatusCode` - Enum for all HTTP status codes.\n- `Handler` - Abstract class for all handlers. You can also implement a handler as a function.\n```ts\nimport { Application } from 'midori/app';\nimport { Request, Response } from 'midori/http';\n\nconst handler = async (\n    req: Request,\n    app: Application\n): Promise\u003cResponse\u003e {\n    // ...\n}\n```\n- `Middleware` - Abstract class for all middlewares. You can also implement a middleware as a function.\n```ts\nimport { Application } from 'midori/app';\nimport { Request, Response } from 'midori/http';\n\nconst middleware = async (\n    req: Request,\n    next: (req: Request) =\u003e Promise\u003cResponse\u003e,\n    app: Application\n): Promise\u003cResponse\u003e {\n    // ...\n}\n```\n- `Request` - Class representing an HTTP request, extending Node.js's `IncomingMessage`.\n- `Response` - Class representing an HTTP response. It does NOT extend Node.js's `ServerResponse`, as it is designed to be sent only at the end of the pipeline.\n\n### midori/jwt\nThe JWT module is responsible for handling JSON Web Tokens.\n- `JWT` - Class responsible for signing and verifying (JWS), encrypting and decrypting (JWE).\n\n### midori/log\nThe Log module is responsible for logging.\n- `Logger` - Abstract class for all loggers.\n- `ConsoleLogger` - Logger class using `console.log` and `console.error`.\n- `FileLogger` - Logger class using Node.js's native `node:fs/promises` module.\n\n### midori/middlewares\nThe Middlewares module is responsible for providing basic middlewares to be used by the application.\n- `AuthMiddleware` - Middleware to check if the user is authenticated. It uses the `Auth` service installed on the app.\n- `AuthBasicMiddleware` - Middleware for Basic Authentication.\n- `AuthBearerMiddleware` - Middleware for Bearer Authentication.\n- `ContentLengthMiddleware` - Middleware to send the Content-Length header to the client. It is automatically installed on the app as the first middleware.\n- `ContentSecurityPolicyMiddleware` - Middleware for Content Security Policy. Can be configured using `app.configure(ContentSecurityPolicyConfigProviderFactory({ ... }))`.\n- `CORSMiddleware` - Middleware for Cross-Origin Resource Sharing. Can be configured using `app.configure(CORSConfigProviderFactory({ ... }))`.\n- `DispatchMiddleware` - Middleware to dispatch the request to the handler. It uses the `Router` to find the handler for the request.\n- `ErrorLoggerMiddleware` - Middleware to log errors thrown anywhere in the pipeline using the `Logger` installed on the app.\n- `ErrorMiddleware` - Middleware to handle any errors thrown anywhere in the pipeline. It should be one of the first middlewares installed on the app. Can be configured using `app.configure(ErrorConfigProviderFactory({ ... }))`.\n- `HTTPErrorMiddleware` - Middleware to handle `HTTPError`s thrown anywhere in the pipeline.\n- `ImplicitHeadMiddleware` - Middleware to handle implicit HEAD requests, returning the same response as the corresponding GET request but without the body.\n- `ImplicitOptionsMiddleware` - Middleware to handle implicit OPTIONS requests, returning the allowed methods for the requested path using the `Router`.\n- `MethodNotAllowedMiddleware` - Middleware to handle requests with matching path but not matching method, returning a `405 Method Not Allowed` response.\n- `NotFoundMiddleware` - Middleware intended to be the last middleware in the pipeline, returning a `404 Not Found` response.\n- `ParseBodyMiddleware` - Middleware to parse the request body based on the `Content-Type` header.\n- `PublicPathMiddleware` - Middleware to serve static files from a public path. Can be configured using `app.configure(PublicPathConfigProviderFactory({ ... }))`.\n- `RequestLoggerMiddleware` - Middleware to log requests using the `Logger` installed on the app.\n- `ResponseCompressionMiddleware` - Middleware to compress responses using `node:zlib` module. Can be configured using `app.configure(ResponseConfigProviderFactory({ compression: { ... } }))`.\n- `RouterMiddleware` - Middleware to find the handler for the request using the `Router`.\n- `ValidationMiddleware` - Abstract class for validation middlewares. The `validate` method is internally used to validate an object against a `ValidationRules` object. Define your `ValidationRules` object by extending the `ValidationMiddleware.rules` property.\n```ts\nimport { ValidationMiddleware } from 'midori/middlewares';\nimport { ValidationRules } from 'midori/util/validation.js';\n\nclass MyValidationMiddleware extends ValidationMiddleware {\n    override get rules(): ValidationRules {\n        return {\n            fieldA: {\n                type: 'string',\n                required: true\n            },\n            fieldB: {\n                type: 'number',\n                required: false,\n                min: 15,\n            },\n            fieldC: {\n                type: 'boolean',\n                required: false,\n            },\n            fieldD: {\n                type: 'array',\n                required: false,\n                all: {\n                    type: 'string',\n                }\n            },\n            fieldE: {\n                type: 'object',\n                required: false,\n                properties: {\n                    fieldA: {\n                        type: 'string',\n                        required: true\n                    },\n                }\n            }\n        };\n    }\n}\n```\n\n### midori/providers\nThe Providers module is responsible for providing basic providers to be used by the application.\n- `AuthServiceProvider` - Service Provider for `Auth` service.\n- `ContentSecurityPolicyConfigProvider` - Config Provider for `ContentSecurityPolicyMiddleware`.\n- `CORSConfigProvider` - Config Provider for `CORSMiddleware`.\n- `ErrorConfigProvider` - Config Provider for `ErrorMiddleware`.\n- `HashServiceProvider` - Service Provider for `Hash` service.\n- `JWTConfigProvider` - Config Provider for `JWT`.\n- `JWTServiceProvider` - Service Provider for `JWT`.\n- `LoggerServiceProvider` - Service Provider for `Logger` service.\n- `PublicPathConfigProvider` - Config Provider for `PublicPathMiddleware`.\n- `RequestConfigProvider` - Config Provider for `Request` related services.\n- `ResponseConfigProvider` - Config Provider for `Response` related services.\n- `RouterServiceProvider` - Service Provider for `Router` service.\n- `UserServiceProvider` - Service Provider for `UserService` service.\n\n### midori/router\nThe Router module is responsible for routing requests to handlers.\n- `Route` - Class representing a route, containing the path, method, handler and middlewares.\n- `Router` - Class responsible for storing routes and finding the correct handler for a request.\n\n### midori/scheduler\nThe Scheduler module is responsible for scheduling tasks.\n- `Task` - Abstract class for all tasks. You can also implement a task as a function.\n```ts\nimport { Application } from 'midori/app';\n\nconst task = async (app: Application): Promise\u003cvoid\u003e {\n    // ...\n}\n```\nInstall on the app using `app.schedule(cronString, DerivedTask)`. `cronString` is a string representing the schedule of the task using the cron format WITH seconds. For example, `* * * * * *` will run the task every second.\n\n### midori/util\nThe Util module is responsible for providing utility functions used by the framework.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmodscleo4%2Fmidori","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmodscleo4%2Fmidori","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmodscleo4%2Fmidori/lists"}