curl and Terminal Clients

curl, Wget, HTTPie and xh get a page's first frame as truecolor ANSI text. Configure its size or turn it off.

کلاینت‌های HTTP ترمینال، نخستین فریم صفحه را به‌صورت متن ANSI با رنگ واقعی به‌جای سند HTML دریافت می‌کنند. نیازی به پیکربندی ندارید.

curl https://my-app.example.com/about

درخواست‌های دریافت‌کنندهٔ فریم

درخواست زمانی فریم دریافت می‌کند که همهٔ این شرایط برقرار باشند:

  • متد GET یا HEAD باشد؛
  • مقدار User-Agent با curl/، Wget/، wget2/، HTTPie/ یا xh/ شروع شود؛
  • هدر Accept وجود نداشته باشد یا شامل text/html نباشد.

مرورگرها، خزنده‌ها و پیش‌نمایش‌های پیوند، صفحهٔ HTML دریافت می‌کنند. برای دریافت HTML با curl، آن را درخواست کنید:

curl -H 'Accept: text/html' https://my-app.example.com/about

فریم در نقطه‌ای انتخاب می‌شود که صفحه قرار است ارائه شود: پس از middleware، rewrites و کنترل‌گرهای مسیر، و هرگز برای فایل‌ها یا مسیرهایی که بخش پایانی آن‌ها نقطه دارد انتخاب نمی‌شود. تغییرمسیرهای middleware، پاسخ‌های 401، هدرها و بازنویسی‌ها همانند مرورگرها برای curl نیز اعمال می‌شوند. مسیر /api/health همچنان کنترل‌گر خود را اجرا می‌کند و مسیر /robots.txt همچنان فایل را ارائه می‌دهد.

محتوای فریم

فریم نخستین رندر صفحه است، همانند یک پوستهٔ پیش‌رندرشده: هر مرز <Suspense> که هنوز منتظر است، محتوای جایگزین خود را نشان می‌دهد. کامپوننت‌های ناهمگام سرور اجرا نمی‌شوند و فراخوانی fetch() هرگز به نتیجه نمی‌رسد، بنابراین داده‌هایی که در افکت‌ها بارگیری می‌شوند در حالت بارگیری باقی می‌مانند.

  • اندازه: ⁦80 × 24⁩ سلول. برنامه‌ای با ناحیهٔ دید ثابت (viewport.responsive: false) به‌جای آن از viewport.width × viewport.height استفاده می‌کند.
  • رنگ‌ها: کدهای گریز SGR با عمق 24 بیت در viewport.theme برنامه. هر ردیف با بازنشانی پایان می‌یابد و فریم با نویسهٔ خط جدید تمام می‌شود.
  • وضعیت: 200، یا 404 همراه با صفحهٔ یافت‌نشدن برنامه، هنگامی که هیچ صفحه‌ای مطابقت ندارد یا صفحه تابع notFound() را فراخوانی می‌کند. صفحه‌ای که هنگام رندر تابع redirect() را فراخوانی کند، HTML ارائه می‌دهد.

پاسخ‌ها از نوع text/plain; charset=utf-8 با هدرهای Vary: User-Agent, Accept و Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate هستند، بنابراین حافظه‌های نهان اشتراکی هرگز فریمی را ذخیره نمی‌کنند تا آن را به مرورگر ارائه دهند. صفحهٔ HTML در مسیری که curl از آن فریم دریافت می‌کند، همان هدر Vary را دارد.

محیط‌های پشتیبانی‌شده

میزبانصفحه‌های ایستاصفحه‌های پویا، مسیرهای ناشناخته
text devرندر هنگام درخواسترندر هنگام درخواست
text start، bunپیش‌رندر با text buildرندر هنگام درخواست
vercel، cloudflareپیش‌رندر با text buildصفحهٔ HTML
staticصفحهٔ HTMLصفحهٔ HTML

صفحه‌های رندرشده در سمت سرور به text start یا bun نیاز دارند (به استقرار مراجعه کنید).

میزبان‌های ایستا نمی‌توانند به یک کلاینت پاسخی متفاوت از کلاینت دیگر بدهند، بنابراین آداپتور static از فریم‌ها پشتیبانی نمی‌کند. در Vercel و Cloudflare، فریم‌های صفحه‌های ایستا همراه خروجی بیلد ارائه می‌شوند. صفحه‌های پویا ([id]، force-dynamic) در این محیط‌ها HTML ارائه می‌دهند، زیرا آداپتورهای vercel و cloudflare رندرکننده‌ای مستقر نمی‌کنند.

دستورهای text start و bun dist/server.js صفحه‌های باقی‌مانده را هنگام درخواست با .text/server/live.mjs رندر می‌کنند و 128 فریم آخر را به‌مدت 10 ثانیه نگه می‌دارند. هر سرور در هر 10 ثانیه حداکثر 20 صفحهٔ ذخیره‌نشده در حافظهٔ نهان را رندر می‌کند. پس از آن، curl تا زمان تجدید سهمیه صفحهٔ HTML دریافت می‌کند. اگر فایل live.mjs روی سرور بارگیری نشود، مثلاً به این دلیل که ماژول یک صفحه در سطح بالای خود مقدار window را می‌خواند، آن صفحه‌ها HTML ارائه می‌دهند.

دستور text build فریم‌های پیش‌رندرشده را گزارش می‌کند:

 ✓ Prerendering curl frames (5/5)

پیکربندی

اندازه را برای کل برنامه تغییر دهید یا فریم‌ها را غیرفعال کنید:

text.config.tsts
import { defineConfig } from "@textjs/app";export default defineConfig({  ansi: { cols: 100, rows: 30 },  // ansi: false,});

هر صفحه می‌تواند اندازهٔ خود را تغییر دهد یا به ترمینال‌ها نیز HTML ارائه کند:

app/dashboard/page.tsxtsx
export const ansi = { cols: 120, rows: 40 };// export const ansi = false;

اندازه‌ها به بازهٔ ⁦1–500⁩ سلول محدود می‌شوند. با تنظیم ansi: false در فایل text.config.ts، خروجی‌های صادرشدهٔ صفحه نادیده گرفته می‌شوند.

⁦HTTP⁩ ساده

⁦curl⁩ تغییرمسیرها را دنبال نمی‌کند، مگر اینکه گزینهٔ -L را بدهید. Vercel درخواست‌های http:// را به https:// هدایت می‌کند و Cloudflare نیز با فعال بودن همیشه از HTTPS استفاده شود همین کار را می‌کند، بنابراین دستور curl http://… به‌جای فریم، تغییرمسیر را چاپ می‌کند. نشانی‌های https:// را به اشتراک بگذارید.

سرورهای سفارشی

ماژول @textjs/app/ansi توابع کمکی تشخیص و پاسخ را برای سرورها و توابعی صادر می‌کند که دستور text start یا آداپتوری را اجرا نمی‌کنند:

import { ansiResponse, wantsAnsi } from "@textjs/app/ansi";import { frameToAnsi } from "@textjs/react";if (wantsAnsi(request)) return ansiResponse(frameToAnsi(buffer, { theme: "geistDark" }), request.method);

تابع wantsAnsi(request) همچنین ورودی (method, headers) را با Headers وب یا IncomingHttpHeaders در Node می‌پذیرد. تابع frameToAnsi(buffer, { theme }) یک CellBuffer رندرشده را به همان روش فریم‌ورک کدگذاری می‌کند.

ویرایش این صفحه در GitHub