UNPKG

@lark-project/cli

Version:

飞书项目插件开发工具

145 lines (144 loc) 6.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.updatePluginDescription = exports.getPluginDescriptionInfo = void 0; const request_1 = require("../request"); const get_tool_auth_headers_1 = require("../get-tool-auth-headers"); const list_categories_1 = require("./list-categories"); /** * 将纯文本转为富文本编辑器所需的完整 RichText 结构(doc + doc_html + doc_text + is_empty) * doc 格式为飞书编辑器的 Delta JSON,doc_html 为对应的 HTML */ function plainTextToRichText(text) { if (!text) { return { doc: '', doc_html: '', doc_text: '', is_empty: true }; } const lines = text.split('\n'); // 构造 doc (Delta JSON 格式) const ops = []; lines.forEach(line => { if (line) { ops.push({ insert: line }); } ops.push({ insert: '\n' }); }); const doc = JSON.stringify({ '0': { ops, zoneId: '0', zoneType: 'Z' }, }); // 构造 doc_html const htmlLines = lines.map(line => `<div class="ace-line" data-node="true" dir="auto"><span data-string="true" data-leaf="true">${escapeHtml(line)}</span><span data-string="true" data-enter="true" data-leaf="true"></span></div>`); const doc_html = htmlLines.join(''); return { doc, doc_html, doc_text: text, is_empty: false }; } function escapeHtml(str) { return str .replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;'); } /** * 获取插件描述信息(草稿态)。 * IDL: api_app_development.GetAppDescriptionInfoRequest / Response * GET /goapi/v5/app/development/tool/description/info?app_key=XXX&data_status=draft */ async function getPluginDescriptionInfo({ siteDomain, appKey, dataStatus = 'draft', }) { return (0, request_1.request)(`${siteDomain}/goapi/v5/app/development/tool/description/info`, { method: 'GET', params: { app_key: appKey, data_status: dataStatus, }, headers: await (0, get_tool_auth_headers_1.getToolAuthHeaders)(siteDomain), timeout: 15000, }); } exports.getPluginDescriptionInfo = getPluginDescriptionInfo; /** * 对齐前端 BaseInfoForm handleChange 的 update_type 分类: * ICON = 1 — icon 单独更新,顶层字段 * I18N = 2 — name/short/description/document/carousel_list 走 i18n_info[lang] * CATEGORY = 3 — category_ids 单独更新,顶层字段 * PROTOCOL = 4 — protocol 单独更新,顶层字段 */ var PluginDescUpdateType; (function (PluginDescUpdateType) { PluginDescUpdateType[PluginDescUpdateType["ICON"] = 1] = "ICON"; PluginDescUpdateType[PluginDescUpdateType["I18N"] = 2] = "I18N"; PluginDescUpdateType[PluginDescUpdateType["CATEGORY"] = 3] = "CATEGORY"; PluginDescUpdateType[PluginDescUpdateType["PROTOCOL"] = 4] = "PROTOCOL"; })(PluginDescUpdateType || (PluginDescUpdateType = {})); function inferUpdateType(req) { if (req.updateType) return req.updateType; if (req.icon) return PluginDescUpdateType.ICON; if (req.categoryIds) return PluginDescUpdateType.CATEGORY; if (req.protocol) return PluginDescUpdateType.PROTOCOL; return PluginDescUpdateType.I18N; } async function updatePluginDescription(req) { var _a, _b; const { siteDomain, appKey, name, short, detailDescription, document, carouselList, icon, protocol, categoryIds, i18nLang, lang = 'zh-cn', } = req; const updateType = inferUpdateType(req); const langs = (i18nLang === null || i18nLang === void 0 ? void 0 : i18nLang.length) ? i18nLang : ['zh-cn']; // 按 update_type 组装不同的请求体,对齐前端 BaseInfoTabs handleBaseInfoChange 逻辑 const data = { app_key: appKey, update_type: updateType, i18n_lang: langs, }; switch (updateType) { case PluginDescUpdateType.ICON: // icon 是顶层字段(isOutter=true) data.icon = icon; break; case PluginDescUpdateType.CATEGORY: { // category_ids 是顶层字段(isOutter=true) const categoriesRes = await (0, list_categories_1.listCategories)({ siteDomain }); const validIds = new Set((_a = categoriesRes.list) === null || _a === void 0 ? void 0 : _a.filter(i => i.status === 1).map(i => i.id)); let ids = categoryIds || []; if (ids.length === 0) { const fallback = (_b = categoriesRes.list) === null || _b === void 0 ? void 0 : _b.find(i => { var _a; return i.status === 1 && ((_a = i.name) === null || _a === void 0 ? void 0 : _a['zh-CN']) === '其他'; }); if (fallback === null || fallback === void 0 ? void 0 : fallback.id) { ids = [fallback.id]; } } const invalidIds = ids.filter(id => !validIds.has(id)); if (invalidIds.length > 0) { throw new Error(`Invalid category ids: ${invalidIds.join(', ')}. Valid ids: ${[...validIds].join(', ')}`); } data.category_ids = ids; break; } case PluginDescUpdateType.PROTOCOL: // protocol 是顶层字段(isOutter=true) data.protocol = protocol; break; case PluginDescUpdateType.I18N: default: { // I18N 类字段包在 i18n_info[lang] 里(isOutter=false) const i18nEntry = {}; if (name !== undefined) i18nEntry.name = name; if (short !== undefined) i18nEntry.short = short; if (detailDescription) { i18nEntry.description = plainTextToRichText(detailDescription.trim()); } if (document !== undefined) i18nEntry.document = document; if (carouselList !== undefined) i18nEntry.carousel_list = carouselList; data.i18n_info = { [lang]: i18nEntry }; break; } } return (0, request_1.request)(`${siteDomain}/goapi/v5/app/development/tool/description/info`, { method: 'POST', data, headers: await (0, get_tool_auth_headers_1.getToolAuthHeaders)(siteDomain), }); } exports.updatePluginDescription = updatePluginDescription;