@lark-project/cli
Version:
飞书项目插件开发工具
63 lines (62 loc) • 4.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ensurePluginMetadataReady = void 0;
const list_categories_1 = require("../../../api/tools/list-categories");
const update_plugin_description_1 = require("../../../api/tools/update-plugin-description");
const logger_1 = require("../../../utils/logger");
const app_type_guard_1 = require("../publish/app-type-guard");
const collect_missing_base_info_1 = require("./collect-missing-base-info");
/**
* 后端是否存在可选分类(status===1 的启用分类)。仅普通插件(type=0)会调到——AI 本就跳过 category。
* 私有化等无分类标签的环境分类列表为空,返回 false —— 据此放行 category 必填。
* 拉取失败时回退为 true(按"有分类"处理),保持「分类必填」的既有保守行为,不因分类接口抖动而误放行。
*/
async function hasPublishableCategories(siteDomain) {
var _a, _b;
try {
const res = await (0, list_categories_1.listCategories)({ siteDomain, type: 0 });
return ((_b = (_a = res.list) === null || _a === void 0 ? void 0 : _a.filter(i => i.status === 1).length) !== null && _b !== void 0 ? _b : 0) > 0;
}
catch (error) {
logger_1.logger.debug('listCategories failed while probing category availability, assuming available:', error);
return true;
}
}
/**
* 发布前置闸门(PC0):拉后端插件元信息,校验 name / short / detail-description / icon /
* category 完整(缺失项判定与逐字段指引见 collectMissingBaseInfo),并顺带用后端真实
* app_type / point_types 对账本地 app_type。
*
* 仅供 `publishProject` 调用:publish 链路本就要求登录态,元信息闸门走 description/info
* (经 getToolAuthHeaders / Bearer)放在这里才合理。
*
* ⚠️ 不要再把它加进 `releaseProject`:release 是零登录态命令(只做本地 build + zip +
* uploadZipFile,靠 X-MEEGO-TOKEN 插件 secret 鉴权),调它会请求需要登录态的 description/info,
* 破坏 release 的零鉴权不变量。曾在 commit fa088ef 为 fail-fast 加进 release,已回退。
*
* 元信息缺失或 app_type 不符时抛错(由调用方 catch → process.exit(1))。
*
* 校验通过后返回拉到的 descInfo(草稿态元信息)与 categoriesAvailable(后端是否有可选分类),
* 供调用方复用——publishAIPlugin 用 descInfo 打印「即将随全量发布上线的 base info」,普通插件
* 把 categoriesAvailable 透传给 commit 前的 Layer 2 复查,无需二次拉取。
*/
async function ensurePluginMetadataReady({ siteDomain, appKey, localAppType, }) {
var _a;
logger_1.logger.info('Checking plugin metadata...');
const descInfo = await (0, update_plugin_description_1.getPluginDescriptionInfo)({ siteDomain, appKey });
// 串链路强校验:descInfo 自带后端真实 app_type / point_types,先比对再查元信息完整性——
// 形态不符时直接抛错,比"缺 name/icon"这类下游报错更贴近根因。
(0, app_type_guard_1.assertAppTypeMatchesBackend)(localAppType, descInfo);
// 私有化等环境没有分类标签:空列表 → 跳过 category 必填,否则发布会被「无任何合法分类 id 可填」死锁。
// 仅在"普通插件 + 尚未填分类"时才探测——AI 本就跳过 category,已填分类时 collectMissingBaseInfo
// 根本不看该值,省掉这次对发布热路径的多余请求。
const needCategoryProbe = descInfo.app_type !== 1 && !((_a = descInfo.category_ids) === null || _a === void 0 ? void 0 : _a.length);
const categoriesAvailable = needCategoryProbe ? await hasPublishableCategories(siteDomain) : true;
const missing = (0, collect_missing_base_info_1.collectMissingBaseInfo)(descInfo, { categoriesAvailable });
if (missing.length > 0) {
throw new Error((0, collect_missing_base_info_1.formatMissingBaseInfoError)(missing));
}
logger_1.logger.success('Plugin metadata check passed.');
return { descInfo, categoriesAvailable };
}
exports.ensurePluginMetadataReady = ensurePluginMetadataReady;