ranuts/node — چارچوب کوچک HTTP
جعبهابزار کوچک و بیوابستگی HTTP برای Node.js: یک کارساز HTTP، یک مسیریاب، یک کارساز وبسوکت، میانافزار بدنه و فایلهای ایستا، بههمراه مشتی یاریرسان خط فرمان و سامانهٔ فایل.
⚠️ فقط Node. این نقطهٔ ورود
node:http،node:fs،node:child_processو مانند آن را میآورد. آن را ازranuts/nodeوارد کن، هرگز از کد مرورگر.
وارد کردن
import { Server, Router, staticMiddleware, body } from 'ranuts/node';میانافزاری که بدنه را میخواند با نام
bodyصادر میشود (نام درونیاشbodyMiddlewareاست). صادراتی به نامbodyMiddlewareوجود ندارد.
آغاز سریع
import { Server, Router, staticMiddleware, body } from 'ranuts/node';
const app = new Server();
const router = new Router();
// مسیرها با تطابق دقیق مسیر جور میشوند. دستگیره، Context درخواست را میگیرد.
router.get('/hello', (ctx) => {
ctx.res.setHeader('Content-Type', 'application/json');
ctx.res.end(JSON.stringify({ message: 'hello world' }));
});
// POST با بدنهٔ JSON؛ body() آن را میخواند و در ctx.request.body میگذارد
router.post('/echo', (ctx) => {
ctx.res.end(JSON.stringify({ youSent: ctx.request.body }));
});
// body() هم بدنهٔ درخواست را میخواند و هم ctx.request را پر میکند (method / path / url / query)
// که مسیریاب از آن میخواند؛ پس آن را پیش از router.routes() ثبت کن.
app.use(body());
app.use(router.routes());
app.use(router.allowedMethods());
// سرو کردن فایلهای ایستا (برای `/` به ./public/index.html برمیگردد)
app.use(staticMiddleware({ pathname: './public' }));
const server = app.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
// `server` همان نمونهٔ Server از node:http است که زیر کار نشسته.ترتیب میانافزارها مهم است: Router از ctx.request.path و ctx.request.method میخواند و پرکنندهٔ آنها body() است. نخست body() را ثبت کن. body() همراهشده در حال حاضر بدنههای application/json و multipart/form-data را میخواند.
API
Server
صادرات پیشفرض. کارسازی کمینه به سبک Koa که روی node:http سوار شده است.
| عضو | توضیح | نوع |
|---|---|---|
new Server() | یک کارساز میسازد. هیچ آرگومانی نمیگیرد. | () => Server |
use(middleware) | میانافزاری را به انتهای زنجیره میافزاید. void برمیگرداند، پس زنجیرهپذیر نیست. | (fn: MiddlewareFunction) => void |
listen(...args) | شنیدن را آغاز میکند. آرگومانها همانطور به http.Server.listen سپرده میشوند و http.Server زیرین برگردانده میشود. | (...args) => http.Server |
middleware | آرایهٔ میانافزارهای ثبتشده. | MiddlewareFunction[] |
ctx | Context مشترکِ درخواست (که req و res آن در هر درخواست عوض میشود). | Context |
امضای میانافزار
type Next = () => Promise<void> | Promise<never>;
type MiddlewareFunction = (ctx: Context, next: Next) => void | Promise<void>;برای سپردن کنترل به میانافزار بعدی next() را صدا بزن. میانافزارها به ترتیب ثبت اجرا میشوند؛ صدا زدن دوبارهٔ next() خطا میاندازد.
شکل Context
| میدان | توضیح | نوع |
|---|---|---|
req | درخواستی که میرسد. | http.IncomingMessage |
res | پاسخ کارساز. با res.setHeader، res.writeHead و res.end روی آن مینویسی. | http.ServerResponse |
ipv4() | نخستین نشانی IPv4 غیرداخلی این ماشین را برمیگرداند (وگرنه undefined). | () => string | undefined |
request | که body() میافزاید: { method, path, url, query, body }؛ و query یک URLSearchParams است. | object (dynamic) |
[key] | Context کیسهای باز است: هر میانافزاری میتواند فیلد دلخواه به آن بچسباند. | any |
Router
صادرات پیشفرض. برای هر روش HTTP و هر مسیر دقیق، دستگیره ثبت میکند و سپس آنها را با routes() به شکل میانافزار عرضه میکند.
| متد | توضیح | نوع |
|---|---|---|
new Router() | یک مسیریاب میسازد. | () => Router |
get(url, handler) | مسیری از نوع GET ثبت میکند. | (url: string, h: Handler) => void |
post(url, handler) | مسیری از نوع POST ثبت میکند. | (url: string, h: Handler) => void |
put(url, handler) | مسیری از نوع PUT ثبت میکند. | (url: string, h: Handler) => void |
patch(url, handler) | مسیری از نوع PATCH ثبت میکند. | (url: string, h: Handler) => void |
del(url, handler) | مسیری از نوع DELETE ثبت میکند. | (url: string, h: Handler) => void |
head(url, handler) | مسیری از نوع HEAD ثبت میکند. | (url: string, h: Handler) => void |
options(url, handler) | مسیری از نوع OPTIONS ثبت میکند. | (url: string, h: Handler) => void |
routes() | میانافزاری برمیگرداند که کار را به دستگیرهٔ جورشده میسپارد. | () => MiddlewareFunction |
allowedMethods() | میانافزاری برمیگرداند که وقتی مسیر یا روش جور نشود با 404، 405 یا 501 پاسخ میدهد. | () => MiddlewareFunction |
امضای دستگیره
type Handler = (ctx: Context, next: Next) => void;دادهٔ درخواست را از ctx.request بخوان (method، path، url، query، body) و پاسخ را از راه ctx.res بفرست. مسیرها دقیقاً جور میشوند: از پارههای :param پشتیبانی نمیشود؛ برای پارامترهای پرسوجو از ctx.request.query استفاده کن.
میانافزار
| نماد | توضیح | نوع |
|---|---|---|
body(options?) | میانافزار خواندن بدنه. ctx.request را پر میکند و application/json و multipart/form-data را میخواند. یک میانافزار برمیگرداند. | (o?: Partial<ServerBody>) => MiddlewareFunction |
staticMiddleware(opt?) | فایلهای ایستا را از opt.pathname (پیشفرض process.cwd()) سرو میکند و برای / همان index.html را میدهد. | (o?: Partial<Option>) => MiddlewareFunction |
connect(fn) | میانافزار به سبک Connect یا Express، یعنی (req, res, next)، را با میانافزار این چارچوب سازگار میکند. | (fn) => MiddlewareFunction |
گزینههای body(options)
| گزینه | توضیح | نوع | پیشفرض |
|---|---|---|---|
uploadDir | پوشهای برای فایلهای بارگذاریشده با multipart/form-data. | string | '.' |
encoding | رمزگذاری جریان درخواستی که میرسد. | BufferEncoding | 'utf-8'/'binary' |
json | بدنههای JSON را میخواند (با false رشتهٔ خام سر جایش میماند). | boolean | true |
urlencoded | برای بدنههای urlencoded کنار گذاشته شده است. | boolean | true |
گزینههای staticMiddleware(option)
| گزینه | توضیح | نوع | پیشفرض |
|---|---|---|---|
pathname | پوشهٔ ریشه که فایلها از آن سرو میشوند. | string | process.cwd() |
fileTypes | نگاشتهای افزوده از پسوند به نوع MIME که ثبت میشوند. | Record<string, string> | {} |
WebSocket
| نماد | توضیح | نوع |
|---|---|---|
new WSS(httpServer) | یک کارساز وبسوکت را به کارساز node:http میچسباند (دستدادن upgrade و قاببندی را خودش انجام میدهد). | (server: http.Server) => WSS |
import { Server, WSS } from 'ranuts/node';
const app = new Server();
const server = app.listen(3000);
const wss = new WSS(server);
wss.on('connect', (client) => {
client.on('message', (data) => client.send('echo: ' + data));
});
// wss.broadcast(data) به همهٔ کارخواههای متصل میفرستد؛ wss.clients همان فهرست است.هر client اینها را در اختیار میگذارد: send(data, options?)، ping()، pong()، close() و socket، و رویدادهای message، close و error.
ابزارهای کمکی
| نماد | توضیح | امضا |
|---|---|---|
connect(fn) | میانافزار (req, res, next) از Connect یا Express را با میانافزار این چارچوب سازگار میکند. | (fn) => MiddlewareFunction |
get({ url }) | یک نقطهٔ پایانی JSON را با GET روی HTTPS میگیرد و با { success, data, message } برآورده میشود. | ({ url: string }) => Promise<Response> |
getIPAdress() | نخستین نشانی IPv4 غیرداخلی این ماشین، یا undefined. | () => string | undefined |
paresUrl(req) | req.url را به { search, query, pathname, path, href } میشکند (به املای نام دقت کن). | (req: IncomingMessage) => ParseUrl | undefined |
prompt({ message }) | در پایانه پرسشی بله/خیر میپرسد؛ در برابر y یا yes با true برآورده میشود. | ({ message, stream?, defaultResponse? }) => Promise<boolean> |
runCommand(cmd, args) | فرایندی فرزند به راه میاندازد (stdio را به ارث میبرد) و با کد خروج 0 برآورده میشود. | (cmd: string, args: string[]) => Promise<void> |
readStream({ path }) | برای path یک fs.ReadStream میسازد. | (o: { path: string, ... }) => ReadStream |
writeStream({ path }) | برای path یک fs.WriteStream میسازد. | (o: { path: string, ... }) => WriteStream |
startTask() | زمانسنجی با دقت بالا آغاز میکند و یک symbol مبهم برمیگرداند. | () => symbol |
taskEnd(symbol) | زمان سپریشده از startTask() متناظر (در Node، نانوثانیه به شکل bigint). | (s: symbol) => number | bigint |
traverse(dir, cb, pre?) | dir را بازگشتی میپیماید و برای هر فایل cb(relPath, absPath, stats) را صدا میزند (ناهمگام). | (dir, cb, pre?) => Promise<any> |
traverseSync(dir, cb, pre?) | گونهٔ همگام traverse. | (dir, cb, pre?) => void |
isColorSupported | مقدار بولی: اینکه پایانهٔ کنونی رنگهای ANSI را پشتیبانی میکند یا نه. | boolean |
colors | یاریرسانهای رنگ ANSI، مثلاً colors.red('text')، بههمراه reset، bold و dim. | Record<string, (s: string) => string> |
بیشتر ببینید
همین نقطهٔ ورود ranuts/node یاریرسانهای سامانهٔ فایل را هم دارد که جداگانه مستند شدهاند: