Skip to content

widget.zip formati ​

Reliz — bu bitta ZIP arxiv. Uni relizga yuklaysiz, Bito hali birorta baytni ochmasdan turib arxivni tekshiradi va faqat tekshiruv muvaffaqiyatli o'tgandagina saqlaydi. Hisobot darhol sizga qaytadi — har bir xato o'zi buzgan qoidani nomma-nom aytadi.

Kataloglar tuzilishi ​

text
widget.zip
├── manifest.json        majburiy, arxiv ildizida
├── script.js            majburiy, arxiv ildizida
├── style.css            ixtiyoriy
├── i18n/
│   ├── uz.json          manifestdagi har bir til uchun bitta fayl
│   ├── ru.json
│   └── en.json
├── templates/           ixtiyoriy, nomlar erkin
│   └── card.twig
└── images/              ixtiyoriy
    ├── logo.png
    └── menu.png         ixtiyoriy, chap menyu ikonkasi

manifest.json va script.js papka ichida emas, ildizda yotishi shart. Papkaning o'zini, ichidagilar o'rniga, arxivlash — yuklashdagi eng ko'p uchraydigan xato.

manifest.json ​

json
{
    "widget": { "interface_version": 2 },
    "bito": {
        "schema_version": 1,
        "locations": {
            "surfaces": ["customer_profile", "card_phone", "list:customers"],
            "persistent": false
        },
        "network": {
            "connect_origins": ["https://api.example.com", "wss://events.example.com"]
        },
        "pipeline_endpoint": "https://api.example.com/bito/pipeline",
        "left_menu": {
            "widget_page": {
                "title_key": "app_title",
                "icon": "images/menu.png",
                "submenu": {
                    "deals": { "title_key": "deals" },
                    "reports": { "title_key": "reports" }
                }
            },
            "saleMain": {
                "submenu": { "order_sync": { "title_key": "order_sync" } }
            }
        }
    },
    "languages": ["uz", "ru", "en"],
    "default_language": "uz"
}
MaydonMajburiyQoidalar
widget.interface_versionHaSon bo'lishi kerak. 2 — joriy sahifa ichidagi runtime.
bito.schema_versionHaSon bo'lishi kerak. Joriy qiymat — 1.
languagesHaTil kodlari massivi. Har biri uchun arxivda i18n/<lang>.json bo'lishi shart.
default_languageHaSatr. Foydalanuvchi tili languages ichida bo'lmasa ishlatiladi.
bito.locations.surfacesYo'qJoylashuv nuqtalari massivi. Har bir band — nomlangan nuqta, list:<page_name> yoki global. Takrorlar rad etiladi.
bito.locations.persistentYo'qMantiqiy qiymat. true doimiy, hamisha ulangan slotni yoqadi. surfaces ichida globalni ko'rsatish ham uni yoqadi — ikkala shakl ham hisobga olinadi.
bito.network.connect_originsYo'qAniq originlar massivi. Faqat oshkor qilish — pastga qarang.
bito.pipeline_endpointYo'qAniq https:// URL. Buyurtmalar voronkasi widget_action'ni shu yerga yuboradi.
bito.left_menuYo'qAdmin panelning chap menyusidagi sahifalar: vidjetning o'z bo'limi va/yoki mavjud modullardagi submenyu sahifalari. Ilovada vidjet kodi bo'lishi shart; chap menyuga qarang.

JSON sifatida o'qilmaydigan yoki bu shaklga mos kelmaydigan hamma narsa server xatosi emas, xabarli tekshiruv xatosi hisoblanadi.

connect_origins — oshkor qilish, cheklov emas ​

DANGER

bito.network.connect_origins kompaniyaga rozilik ekranida ko'rsatiladi va hech qachon texnik jihatdan qo'llanmaydi. Vidjetingizni — yoki uning buzib kirilgan versiyasini — bu ro'yxatda yo'q manzilga murojaat qilishdan hech narsa to'smaydi.

Uni qo'llashning iloji ham yo'q: sahifa darajasidagi CSP butun hujjatga tegishli bo'ladi va bitta skriptga toraytirilmaydi, kodingiz esa host sahifasida ishlaydi. Bu maydonni Bito sizga qo'yayotgan cheklov emas, balki siz kompaniyaga beryotgan deklaratsiya deb biling. Foydalanuvchilaringizga uni "sandbox" deb tasvirlamang.

Yuklashda shakli tekshiriladi, toki rozilik ekranida toza ro'yxat chiqsin:

  • faqat aniq https:// yoki wss:// origin;
  • hech qayerda joker belgi bo'lmasin — satrdagi * darhol rad etishga olib keladi;
  • "yalang'och" sxema bo'lmasin (https:);
  • yo'l, so'rov va fragment bo'lmasin, oxirida slash ham bo'lmasin — satr o'zining origini bo'lib qaytishi kerak.

pipeline_endpoint ​

Agar kompaniya buyurtmalar voronkasining bosqichiga sizning ilovangiz uchun widget_action turidagi amalni sozlasa, Bito manzilni rozilik berilgan relizingizning manifestidan oladi — kompaniya URL'ni qo'lda kiritmaydi. POST yuboriladi:

json
{
    "event": "pipeline_action",
    "db_name": "tenant_db",
    "sale_order_id": "6712f0a9c4d1e87b3a0f1122",
    "organization_id": "6712f0a9c4d1e87b3a0f1130",
    "state_id": "6712f0a9c4d1e87b3a0f1140",
    "client_id": "69c50a2d50f7b939923a469b"
}

Yuklash paytida faqat shakl tekshiriladi: bu aniq https:// URL bo'lishi kerak. Yuborish paytida manzil qaytadan tekshiriladi — HTTPS bo'lmagan, loopback, xususiy va link-local manzillar rad etiladi, so'rovda esa qattiq taymaut bor.

Chap menyu ​

bito.left_menu o'rnatilgan vidjetga admin panelning chap menyusida o'z sahifalarini beradi. U amoCRM'ning left_menu va initMenuPage callback'i namunasida qurilgan. Menyu bandlari va sahifa sarlavhasini Bito chizadi; sahifa mazmuni esa vidjetingiz chizgan narsa. Bunday har bir sahifa widget_page nuqtasida ulanadi.

bito.left_menu avvalgi bito.settings_page va bito.menu maydonlari o'rnini egallaydi. Ikkalasi ham olib tashlangan: ulardan birortasini hali ham e'lon qilgan manifest left_menuga ishora qiluvchi xabar bilan rad etiladi.

left_menuning har bir kaliti — blok: widget_page yoki modul kaliti.

BlokMaydonlarQoidalar
widget_pagetitle_key (majburiy), icon, submenuVidjetning o'z yuqori darajali bo'limi. submenu bo'lmasa bitta sahifa; submenuda ko'pi bilan 10 ta band.
modul kalitisubmenu (majburiy)O'sha modulning Kengaytmalar guruhiga qo'shiladigan 1 tadan 3 tagacha sahifa. title_key va icon rad etiladi — modul o'z nomi va ikonkasini saqlaydi.

Modul kaliti quyidagilardan biri bo'lishi shart, boshqa har qanday kalit rad etiladi. Prefiks — sahifa URL'ining boshi.

Modul kalitiURL prefiksi
saleMain/sale
customerMain/customer
distributionMain/distribution
logisticsOrder/logistics
supplyMain/supply
warehouseMain/warehouse
financeMain/finance
hrMain/hr
integrationMain/integration
manufacturingMain/manufacturing
referenceMain/reference
toolsMain/tools

submenu — obyekt: kalit subband kodi, qiymat esa { "title_key": "..." }. Subband kodi ^[a-z][a-z0-9_]{1,31}$ga mos bo'lishi kerak — kichik lotin harfi, keyin 1 dan 31 tagacha kichik harf, raqam yoki pastki chiziq. Bandlar siz e'lon qilgan tartibda ko'rsatiladi.

Sarlavhalar ​

Har bir title_key i18n/<default_language>.jsonda bo'lishi shart, aks holda yuklash rad etiladi. Sarlavhalar yuklash paytida arxivdan olinadi, shuning uchun menyu matni ko'rib chiqilgan paketdan chetga chiqmaydi. Ko'rsatishda har bir sarlavha foydalanuvchi tilidagi bundle'dan olinadi; u yerda kalit bo'lmasa default_language qiymati ishlatiladi.

Ikonka ​

icon ixtiyoriy va faqat widget_pageda ruxsat etiladi. Quyidagi shartlar bajarilmasa, yuklash rad etiladi:

  • arxivdagi images/ ichidagi, .png bilan tugaydigan faylga yo'l;
  • hajmi ko'pi bilan 16 KB (16 384 bayt) bo'lgan PNG fayl;
  • kvadrat, har bir tomoni 48 dan 128 px gacha;
  • alfa-kanalli (PNG rang turi 4 — kulrang + alfa, yoki 6 — RGBA).

Bito ikonkaning faqat shaklidan foydalanadi. PNG'ning alfa-kanali niqob sifatida qo'llanadi va menyuning joriy mavzu rangi bilan bo'yaladi, shuning uchun ikonka yorug' va qorong'i rejimga, hover va faol holatga moslashadi; o'z ranglaringiz hech qachon ko'rinmaydi. Shaffof fonda bitta glif chizing. Ikonka bo'lmasa, bandda Bitoning standart kengaytma glifi ko'rsatiladi.

Vidjet kodi va URL'lar ​

Menyu URL'laridagi {widget_code} — ilovaning vidjet kodi, ya'ni Mening ilovalarimda tanlab band qilinadigan system_id (FAQga qarang). Ilovada kod bo'lmasa (masalan, shaxsiy vidjetda) uning o'rniga client_id ishlatiladi: /widget/{client_id}/{subitem}.

SahifaURLlocation
Submenyusiz widget_page/widget/{widget_code}widget_page
widget_page submenyu bandi/widget/{widget_code}/{subitem}widget_page
Modul submenyu bandi{prefix}/widget/{widget_code}/{subitem}, masalan /sale/widget/acme_crm/order_syncmodul kaliti, masalan saleMain

Manifestda e'lon qilinmagan blok yoki subband URL'i vidjet o'rniga "mavjud emas" xabarini ko'rsatadi. Modul sahifasiga doim subband kodi kerak. Qaysi sahifa ochilganini vidjet initMenuPage va bito.context.menudan biladi.

Ko'rinish va ruxsatlar ​

  • Menyu ko'pi bilan beshta vidjetning widget_page bo'limini ko'rsatadi; qolgan vidjetlarning bo'limlari ko'rinmaydi. Modul bandlariga bu cheklov ta'sir qilmaydi.
  • Menyu bandlari va sahifalar kompaniyaning har bir foydalanuvchisiga ko'rsatiladi; Bito ularni rol bo'yicha filtrlamaydi. Har bir foydalanuvchi nimani ko'rishi va qilishi mumkinligini vidjetingiz o'zi hal qiladi.
  • Har bir bito.ajax chaqiruviga Bito RBAC baribir qo'llanadi, shuning uchun sahifa tizimga kirgan foydalanuvchining o'z huquqlaridan tashqaridagi narsani o'qiy yoki o'zgartira olmaydi.
  • Bandlar ilova o'rnatilgach paydo bo'ladi. Kodingiz sahifada faqat kompaniya relizga rozilik bergandan keyin ishlaydi — boshqa har qanday joylashuv nuqtasidagi kabi.

amoCRM'dan farqlari ​

  • Sarlavha maydoni — title_key (i18n kaliti).
  • sort yo'q: e'lon qilish tartibi — ko'rsatish tartibi.
  • is_hidden yo'q.
  • Ikonka — chizilganicha ko'rsatiladigan SVG emas, shakl sifatida ishlatiladigan va Bito mavzu ranglarida bo'yaladigan PNG.
  • Modul kalitlari Bitoning o'ziniki, ular yuqorida keltirilgan.

Til lug'atlari ​

Tekis JSON obyekt: kalit → satr. Bito ulanish paytida serverda bitta lug'atni tanlaydi: agar manifestda e'lon qilingan bo'lsa foydalanuvchi tilini, aks holda default_language'ni. Vidjet faqat o'shani oladi — bito.i18n() orqali.

json
{
    "title": "Qo'ng'iroqlar tarixi",
    "empty": "Hozircha hech nima yo'q",
    "greeting": "Assalomu alaykum, {{name}}"
}

JSON sifatida noto'g'ri lug'at logga yoziladi va bo'sh deb hisoblanadi — vidjet baribir ulanadi, har bir kalit esa o'zini qaytaradi.

templates/ ​

templates/ ichidagi har bir fayl mount javobiga qo'shiladi va templates/ prefiksidan keyingi yo'li bo'yicha nomlanadi: templates/card.twig — bu card.twig. Render — ikki jingalak qavs ichidagi oddiy almashtirish, boshqa hech nima: na sikl, na shart, na filtr. .twig kengaytmasi tanishlik uchun ruxsat etilgan; bu Twig dvigateli emas.

style.css ​

Fayl bo'lsa, vidjet ishlab turgan vaqtda host hujjatiga <link> sifatida ulanadi va uzilganda olib tashlanadi. U hech qanday doiraga cheklanmagan: yalang'och .card { ... } qoidasi admin panelni ham qayta bo'yaydi. Har bir selektorga o'z prefiksingizni qo'ying.

script.js ​

AMD modul. Qarang: CustomWidget hayotiy sikli.

Cheklovlar ​

Bularning barchasi ZIP markaziy katalogi bo'yicha, hech narsa ochilmasdan oldin tekshiriladi, shu sababli zip-bomba ochilmasdan turib rad etiladi.

CheklovQiymat
Siqilgan arxiv10 MiB (10 485 760 bayt)
Umumiy siqilmagan hajm50 MiB (52 428 800 bayt)
Bitta fayl, siqilmagan holda5 MiB (5 242 880 bayt)
Yozuvlar soni1000
Ochilish nisbati, har bir yozuv uchun100:1

Yozuv nima uchun rad etiladi ​

QoidaTafsilot
Mutlaq yo'llarBoshidagi / yoki har qanday mutlaq yo'l
Chegaradan chiqishYo'lning .. bo'lagi
Teskari slashYozuv nomida \ uchrashi
SymlinklarArxiv qaysi OS'ni da'vo qilishidan qat'i nazar, shartsiz rad etiladi
Shifrlangan yozuvlarParol bilan himoyalangan yozuvlar qabul qilinmaydi
Ichma-ich arxivlar.zip .rar .7z .tar .gz .tgz .bz2
Bajarish bitiUnix 0o111 rejim bitlaridan biri qo'yilgan bo'lsa
Takroriy yo'llarBir xil yozuv nomi ikki marta
Noma'lum kengaytmaQuyidagi ro'yxatda yo'q hamma narsa
Noto'g'ri matn kodlashUTF-8 bo'lmagan matn fayli
Rasm bo'lmagan rasmPNG, JPEG va WebP sehrli baytlar bo'yicha tekshiriladi; kengaytmaga ishonilmaydi

Ruxsat etilgan kengaytmalar: .js .json .css .html .twig .txt .png .jpg .jpeg .webp .woff2

Kontent turlari serverda aynan shu kengaytmadan belgilanadi, arxiv yoki yuklash so'rovi da'vo qilgan narsadan emas.

Tekshiruv hisoboti ​

upload hisobot bilan javob beradi va u tekshiruv o'tgan-o'tmaganidan qat'i nazar relizda saqlanadi:

json
{
    "ok": false,
    "errors": [
        "Extension not allowed: vendor/lib.map",
        "Missing i18n/ru.json declared in manifest.json"
    ],
    "entries": 14,
    "uncompressed_bytes": 189342
}

ok qiymati true bo'lganda hisobot o'qilgan manifestni ham olib keladi. Saqlangan hisobot ok demaguncha relizni tekshiruvga yuborib bo'lmaydi.

Bito 2.0 Integration API