خط فرمان
This content is not available in your language yet.
npx darzsaz <فرمان> [پروژه.json] [پرچمها] # از npm (بستهٔ darzsaz)pnpm -r build && node apps/cli/dist/darzsaz.mjs <فرمان> # از خودِ مخزنبدون مسیر پروژه، آشپزخانهٔ نمونه (myKitchen) به کار میرود. پرونده — .darz ِ برنامه یا JSON ِ
خام — از راه unpackDarzWithAssets هسته خوانده میشود (src/project.ts؛ تصویرهای assets/ ِ .darz برای
جلدِ export و pdf، imageOf): همان سقفهای اندازه، اعتبارسنجی و مهاجرت رابط؛ اندازه پیش از خواندن
سنجیده میشود. فرمانها با همان هستهٔ رابط حساب میکنند (derive، یا تابعهای هستهای که derive از آنها
ساخته شده) و --json روی همه یک معنا دارد: فقط یک شیء JSON روی خروجی
استاندارد، عدد عدد (نه رشتهٔ فارسی) و بیجدول — برای اسکریپت و اتوماسیون. prices --update هم (تا پیگیریِ
موجِ ۶ تأییدِ متنی چاپ میکرد): { usdToman, note, noteId, noteValues, capturedAt, baseCapturedAt, factor, written }
— نرخ و تاریخِ مرجعِ نوشتهشده، تاریخِ مرجعی که جلو برده شد، و noteId که cli.prices.rate-failed یعنی
نرخ زنده نرسید و ضریب ۱ است. خروجیِ موفقِ هیچ فرمانی ok ندارد؛ فقط خطا ok: false است. darzsaz --help و
darzsaz <فرمان> --help راهنمای citty را میدهند، به زبانِ --lang.
| فرمان | چه میکند | پرچمها |
|---|---|---|
parts |
لیست برش؛ ابعاد، اندازهٔ برش است | --raw بدون ادغام؛ --material <id> |
nest |
ورق مصرفی و بازده هر جنس | --cuts ترتیب برش؛ --seed <n> |
check |
بررسی طرح با قواعد دستیار؛ با خطا کد خروج ۱ | — |
bom |
لیست خرید و هزینه به واحدِ پروژه، با تاریخِ برداشتِ مرجع | — |
units |
یونیتهای هر ردیف و موانع دیوار | — |
export |
بستهٔ کاغذی: darzsaz.html، cutlist.csv، bom.csv |
--out <پوشه>؛ --dxf برای CNC (با لایهٔ سوراخ و شیار)؛ --xlsx سه برگهٔ اکسل |
assemble |
راهنمای مونتاژ assembly.html |
--out <پوشه> |
pdf |
PDF از همان HTML با کروم بیسر | --out <پوشه>؛ --chrome <مسیر> |
prices |
قیمت مرجع با نشان اطمینان | --live نرخ روز؛ --from <مرجع.json>؛ --update --out <پرونده> مرجع تازه (تقریب)؛ --write <پروژه.json> |
demo |
پروژهٔ نمونه را مینویسد | <مسیر> |
bench |
بنچمارک پیکرهٔ ده آشپزخانهٔ واقعی: زمان، ورق، بازده، خطا | --iterations <n> |
render |
عکس رندر بیسر از اپ ساختهشده (جایگزینِ اسکریپتِ عکسِ قدیمی) | --out، --view، --quality، --width، --dof، --no-ao، --gpu، --url یا --app <پوشهٔ dist>، --chrome |
همه --json و --lang میگیرند.
prices هر ورق را با ابعادش میآورد — قیمت مالِ جنس و ابعاد است (sheetPriceKey، ۹.۶) — و
--write دفتر را به واحدِ خودش (تومان) و با capturedAt در پروژه مینویسد، حتی در پروژهٔ ریالی؛
تبدیل فقط در نمایش است (catalog.md).
زبان: --lang و DARZSAZ_LANG
Section titled “زبان: --lang و DARZSAZ_LANG”npx darzsaz bom --lang en-US # خروجی و راهنما انگلیسیDARZSAZ_LANG=en-US npx darzsaz check # برای کسی که همیشه انگلیسی میخواهدnpx darzsaz --lang en-US --helpیک جا تصمیم میگیرد (src/lang.ts، langOf): پرچم ← متغیرِ محیطی ← fa-IR. متغیرِ خالی یعنی
نگذاشتهای؛ پرچم هم پیش از نامِ فرمان (darzsaz --lang en-US parts) کار میکند هم پس از آن، با همان
تجزیهگرِ citty (پرچمِ آخر برنده؛ پس از -- آرگومان است). هر چه به زبان میگوید با setLang با هم عوض
میشود: say (پیام)، cliFmt() (عددِ جدول و نقشهٔ ورق)، cliI18n (برگه، CSV، اکسل)، و Say ِ
آشپزخانهٔ نمونه (demo، bench و هر فرمانِ بیپرونده) — نامِ پروژهٔ نمونه داده است و به زبانِ همان
اجرا ساخته میشود.
LANGِ سیستم خوانده نمیشود — همان تصمیمِ رابط کهnavigator.languagesرا نمیخواند (i18n.md): ترمینالِ انگلیسی در ایران نشانهٔ زبانِ کاربر نیست.- زبانِ ناشناخته خطاست، نه فارسیِ بیصدا.
--lang enیاDARZSAZ_LANG=englishپیش از هر کاری با کدِ ۲ بیرون میرود و پیام را به همهٔ زبانها میگوید — زبانِ کاربر درست همان است که نمیدانیم:✖ Unknown language “en” from --lang. Languages: fa-IR (فارسی) and en-US (English). - راهنما پیش از citty. citty
--helpرا پیش از هرsetupچاپ میکند (فرمانِ ناشناخته ازsetupِ ریشه میگذرد و بعد راهنما میگیرد)، پسmain.tsزبان را پیش ازrunMainمینشاند (startLang)؛setupِ ریشه همان تصمیم را برای هر راهِ دیگرِ درخت (runCommandِ آزمون) میگیرد. توضیحِ فرمانها و آرگومانها تابعاند (meta: () => …،args: () => …) که citty هنگامِ راهنما حل میکند؛ ثابتِ سطحِ ماژول با زبانِ پیش از--langقفل میشد. سرتیترهای خودِ citty (USAGE،OPTIONS،(Default: …)) انگلیسیاند، در فارسی هم مثل همیشه. --langروی هر فرمان اعلام شده (langArgدرcli.ts): citty پرچمِ ناشناخته را بولی و مقدارش را آرگومانِ جایگاهی میگیرد —darzsaz parts --lang en-USبی آن پروندهٔ «en-US» را میخواند.test/lang.test.tsهر دوازده فرمان را میسنجد.- اکسل جهتِ زبان را دارد:
xlsx(sheets, dir)برگهٔen-USرا چپبهراست مینویسد؛ تا ۳.۶ هر برگهrightToLeftبود.
آزمونها: test/lang.test.ts (ترتیبِ تصمیم، خطای زبان، یکجا عوض شدن، درختِ citty، --help ِ هر فرمان)،
test/english.test.ts (خروجیِ متنیِ check، parts، bom، nest، units، prices، bench، demo و
export در en-US بی هیچ حرفِ فارسی، با کاتالوگی که نامِ هر قلمش شناسه است — نامِ محصول ترجمه
نمیشود)، test/smoke.test.ts (راهنما و کدِ ۲ روی بستهٔ ساختهشده).
--json و پیام
Section titled “--json و پیام”darzsaz روی npm است و اسکریپتِ کسی کلیدهای دیروز را میخواند (۳.۶). هر جا خروجی پیامِ هسته دارد،
کلیدِ دیروز همان متن را به زبانِ خط فرمان (--lang، پیشفرض فارسی) نگه میدارد و شناسه و مقدارِ پیام کنارش
میآیند:
| شکل | کلیدِ دیروز | کلیدهای تازه |
|---|---|---|
شیء با message |
message |
messageId، values |
میدانِ پیامدارِ دیگر: bom ← lines[].name/unit/note، prices ← note |
name، unit، … |
nameId، nameValues، unitId، unitValues، … |
فهرستِ رشته: nest ← problems |
problems |
problemMessages: { code, message, messageId, values } به همان ترتیب |
برچسبِ قطعه: parts ← rows[].label، nest ← layouts[].placements[].label |
label |
labelId (part.label یا part.label.merged)، labelValues |
نامِ آشپزخانه: bench ← rows[].name |
name |
nameId (sample.kitchen.*)، nameValues |
برچسبِ یونیت: units ← walls[].runs[].units[].label |
label |
— (فقط متنِ رندرشدهٔ unitLabel، بی labelId/labelValues) |
values همان مقدارِ تیپدارِ هسته است ({ "kind": "count", "value": 105 })، پس اسکریپتِ تازه به زبانِ
خروجی وابسته نمیشود. واحدِ سطرِ صورتحساب در هسته کلید است (sheet) و unitId شناسهٔ واژهاش
(bom.unit.sheet). سطری که یادداشت ندارد، مثل دیروز کلیدِ یادداشت هم ندارد. کمکیها jsonField و
jsonMessage در src/lang.ts؛ عکسِ کلیدهای پیش و پس در test/json-messages.test.ts و
test/commands.test.ts.
--lang متن را عوض میکند، قرارداد را نه: در en-US همان کلیدها با همان شناسهها میآیند و فقط متنِ
کلیدِ دیروز انگلیسی است (test/json-messages.test.ts برای check، parts، nest، bom، units،
prices و bench مسیرِ هر کلید و هر …Id را در دو زبان برابر میخواهد). پیشفرض همچنان فارسی است.
check --json
Section titled “check --json”قراردادِ عمومی: { project, errors, issues[] } و هر مسئله
{ ruleId, severity, category, message, messageId, values, unitIds, fixes }. message و هر
fixes متنِ رندرشده به زبانِ خط فرماناند (پیشفرض فارسی، بی نویسهٔ جداسازِ جهت) — همان کلیدها با
همان معنای نسل چهارم. messageId و values تازهاند: شناسهٔ پیامِ هسته و مقدارِ تیپدارش
({ kind: 'mm', value: 43 }؛ یونیتِ بی نامِ کاربر
{ kind: 'ref', value: { ref: { id: 'unit.preset.base-hob' }, values: {} } } و نامِ کاربر text)، تا اسکریپتِ زبانِ دیگر پیام را
بی تجزیهٔ متنِ فارسی بسازد (i18n.md). آزمون: test/check-json.test.ts.
کد خروج
Section titled “کد خروج”0موفق؛checkهم با هشدار صفر میدهد — هشدار جلوی کار را نمیگیرد.1خطای دامنه (DarzError، پیام به زبانِ خط فرمان با کد) یاcheckبا دستکم یک خطا — تا در اسکریپت بشود جلوی خرید ورق را گرفت. پروندهٔ ناموجود (cli/file-not-found) یا ناخوانا (cli/file-unreadable)، گزینهٔ نادرستِrender(render/bad-view،render/bad-quality، وrender/bad-widthکه صفحه میسنجد)، رندری که در صفحه نشد یا به مهلت نرسید (render/failed،render/timeout)، نبودنِ بستهٔ وب (render/no-app) و کروم (cli/no-chromeازpdf،render/no-chromeازrender— یک پیام برای هر دو)، نقشهٔ مشکلدار درexport/pdf(export/problems،pdf/problems) و مرجعِprices --fromهم خطای دامنهاند: ناموجود، ناخوانا یا JSON ِ خراب همان خطای هر پروندهٔ کاربر (cli/file-not-found،cli/file-unreadable،cli/bad-jsonازreadJsonFile؛ تا پیگیریِ موجِ ۶ خطای خامِ Node بود) و JSON ِ ناهمشکلprices/bad-reference. تا نسل چهارم پروندهٔ ناموجود پشتهٔ خامِENOENTبود و چهار فرمان خودشانconsole.errorوprocess.exitمیزدند.2خطای کاربرد: زبانِ ناشناخته (--lang،DARZSAZ_LANG)،demoبی مسیر (cli/no-out) و پرچمِ عددیِ بدشکل (cli/bad-number:--seed،--iterations،--widthباintFlag؛ citty ۰٫۲ تیپِ عددی ندارد و--seed abcپیشتر بیصدا بذرِ پیشفرض میگرفت).- فرمان ناشناخته: citty راهنما را چاپ میکند و غیرصفر میدهد.
خطا در --json
Section titled “خطا در --json”هر خطای دامنه از guarded (src/cli.ts) میگذرد و با --json یک شیء روی خروجیِ استاندارد میدهد —
همان جایی که خروجیِ موفق است — و stderr خالی میماند. زبانِ ناشناخته به guarded نمیرسد: startLang پیش
از citty آن را به همهٔ زبانها روی stderr میگوید، با --json یا بی آن.
{ "ok": false, "code": "cli/file-not-found", "message": "…", "messageId": "cli.file.not-found", "values": { "path": { "kind": "text", "value": "x.json" } }}detail فقط وقتی هست که خطا جزئیات دارد: export/problems و pdf/problems همان problems و
problemMessages ِ nest --json را دارند. بی --json همان متن روی stderr با پنج مشکلِ اول و «… و N مورد
دیگر». آزمون: test/json-errors.test.ts (همهٔ فرمانهای پروژهخوان، مرجعِ prices --from، خطای کاربرد، متن).
PDF و رندر
Section titled “PDF و رندر”src/find-chrome.ts کروم را از DARZSAZ_CHROME، PUPPETEER_EXECUTABLE_PATH یا CHROME_PATH
میگیرد، وگرنه مسیرهای رایج macOS، Linux و Windows را میگردد (findChrome، از src/chrome.ts دوباره صادر) — یک
یابنده برای pdf، render و اسکریپتهای مخزن (scripts/lib/chrome.mjs همین پرونده را با زدودنِ تیپِ Node وارد
میکند؛ بستهٔ npm همان dist/darzsaz.mjs میماند) و یک پیامِ «کروم پیدا نشد» (noChromeMsg) برای pdf و
render؛ پیشتر دو متنِ جدا بود و هر اسکریپت فهرستِ کوتاهترِ خودش را داشت. --gpu پشتیبانِ ANGLE ِ همان
سکو را میگیرد (gpuAngle: metal روی مک، d3d11 روی ویندوز، gl روی لینوکس)؛ تا نسل چهارم همیشه
metal بود. src/pdf.ts (htmlToPdf) مسیرِ کروم را
اجباری میگیرد: گفتنِ «کروم پیدا نشد» کارِ فرمان است، به زبانِ خودش؛ نسخهٔ دومِ آن پیام به فارسیِ
ثابت در htmlToPdf بود و هیچ فراخوانی به آن نمیرسید. قلم در خودِ HTML
جاسازی شده، پس PDF روی هر دستگاهی یک شکل است. render (commands/render.ts، رانندهٔ کروم در
src/render.ts) بستهٔ وب را از --app با سرور ایستای کوچک (src/serve.ts) از زیرمسیر /darzsaz/ بالا
میآورد یا به --url وصل میشود، پروژه را از خانه با قلاب window.__darzsazOpen
(apps/web/src/app/automation.ts) باز میکند و با window.__darzsazRender({ view, quality, width, dof, ao })
رندر میگیرد؛ PNG را مینویسد، بیسر با SwiftShader یا با --gpu. تا نسل چهارم منتظرِ window.__darzsazLoad
ِ ویرایشگر بود که خانه ندارد، و هر رندر پس از شصت ثانیه میافتاد.
روی API، نه برچسب (۳.۷): تا نسل چهارم پنلِ رندر را مثلِ کاربر میراند — دکمه با
title="رندر با کیفیت بالا"، زبانه با متنِ «سهرخ»، <select id="q"> — و در رابطِ انگلیسی (و از
وقتی پهنا و کیفیت Select ِ سیستم طراحی شدند، در فارسی هم) رندر نمیشد. قلاب همان نگاشتِ پنل
(components/render/presets.ts) را میخواند و پاسخِ بیزبان میدهد: { ok: true, dataUrl } یا
کدِ خطا (bad-view، bad-quality، bad-width با فهرستِ مجاز، failed)؛ متن را خط فرمان به زبانِ
خودش میسازد. اسکریپتِ صفحه کوتاه است و نتیجه را روی window.__darzsazJob میگذارد تا Node هر نیم
ثانیه نظر کند (ارزیابیِ طولانی از مهلتِ پروتکل رد میشود). قلاب تا صحنهٔ سهبعدی بالا نیامده نیست.
بستهٔ npm
Section titled “بستهٔ npm”apps/cli با نام darzsaz منتشر میشود: tsdown یک پروندهٔ dist/darzsaz.mjs
میسازد که بستههای ورکاسپیس (هسته، زبان، گزارش، هندسه) داخلشاند و وابستگیهای بیرونی
(@lingui/core، citty، fflate، puppeteer-core، zod) بیرون. پس بستههای ورکاسپیس در
devDependencies اند، نه dependencies: pnpm pack آنها را 0.0.0 مینوشت و
npm i darzsaz با 404 میافتاد. node scripts/release-check.mjs بسته را میسازد و
میسنجد (نصبشدنی، فقط وزیرمتن)؛ انتشار با release.yml (deploy.md).
ساختار کد
Section titled “ساختار کد”src/main.ts ورود و src/cli-main.ts درخت فرمان citty با نسخه؛ نسخه را src/version.ts از
define ِ tsdown (و در آزمون، vitest) میگیرد که package.json ِ همین بسته را میخواند — نسخهٔ
محصول یک منبع دارد (deploy.md). هر فرمان commands/<نام>.ts با یک تابع
run<نام>(opts, cat) خالص (آزمونپذیر) و یک defineCommand برای راهنما و آرگومان — آزمونها run<نام>
را مستقیم صدا میزنند، جز pdf و render که خصوصیاش دارند (pdf از راهِ درختِ citty با htmlToPdf ِ
ساختگی، render با renderJobOf ِ صادرشده)؛
cli.ts مشترکات (help، projectArg، jsonArg، langArg، outArg، emit، guarded، loadFor،
readUserFile، readJsonFile، intFlag، shown)؛ find-chrome.ts یابندهٔ کروم و chrome.ts پیامِ نبودنش و
gpuAngle؛ lang.ts زبان
(langOf، setLang، say، cliFmt، cliI18n، jsonField)؛ words.ts واژههای مشترکِ چند فرمان
(سرستون، گروهِ هزینه، «نوشته شد») — یک شناسه برای یک معنا؛ table.ts جدولِ ترمینال (عدد را فرمان با
cliFmt() رشته میکند)؛ sheet-art.ts نقشهٔ ورق متنی؛ xlsx.ts نویسندهٔ اکسل و workbook.ts سه برگهٔ آن؛ render-page.ts پروتکلِ
صفحهٔ رندر (kickoffScript، failureOf)؛ usd.ts نرخِ دلارِ زنده؛ commands/prices-text.ts خروجیِ متنیِ
prices. هر رشتهٔ کاربرپسند پیام
است و در کاتالوگِ جدای خط فرمان (cli.<زبان>.po، i18n.md). آزمونها، پانزده
پرونده در test/: واحدِ فرمانها (commands.test.ts)، درختِ citty (cli-tree.test.ts)، زبان و --json
(بالا)، جدول، اکسل، prices --from، رندرِ بیسر و سرورش، و برگهها؛ و دو آزمون روی بستهٔ ساختهشده (smoke.test.ts،
darz-open.test.ts) که بسته را test/global-setup.ts از سورس میسازد — بی بیلدِ پیشین، و بی آن آزمون
میافتد، کنار نمیرود.