@lark-project/cli
Version:
飞书项目插件开发工具
152 lines (151 loc) • 6.96 kB
JavaScript
;
/**
* 表格列展示态布局 DSL 的格式归一化工具。
*
* 后端存储的始终是完整的 { definitions, template } 对象;本地 yaml 允许两种简写:
* 1. 裸 template:用户只写根节点(含顶层 `type`),CLI 自动包装成 { definitions, template };
* 2. 完整对象:缺失的 definitions.data / $i18n / $colorTokens 会被补成空对象。
*
* 老 yaml 中 control.table_cell 是 JSON 字符串,这里同时做兼容:自动 JSON.parse 一次。
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.denormalizeDslForLocal = exports.normalizeLocalConfigDsl = exports.normalizeDslInPlace = exports.normalizeDslForBackend = void 0;
const EMPTY_DEFS = { data: {}, $i18n: {}, $colorTokens: {} };
function isPlainObject(v) {
return !!v && typeof v === 'object' && !Array.isArray(v);
}
function isBareTemplate(v) {
return typeof v.type === 'string' && !('template' in v);
}
/** 本地 yaml 形态 → 发往后端的完整 { definitions, template } 对象 */
function normalizeDslForBackend(input) {
if (input == null || input === '')
return undefined;
let value = input;
if (typeof value === 'string') {
try {
value = JSON.parse(value);
}
catch (_a) {
return undefined;
}
}
if (!isPlainObject(value))
return undefined;
if (isBareTemplate(value)) {
return { definitions: Object.assign({}, EMPTY_DEFS), template: value };
}
const defs = isPlainObject(value.definitions) ? value.definitions : {};
return Object.assign(Object.assign({}, value), { definitions: {
data: isPlainObject(defs.data) ? defs.data : {},
$i18n: isPlainObject(defs.$i18n) ? defs.$i18n : {},
$colorTokens: isPlainObject(defs.$colorTokens) ? defs.$colorTokens : {},
}, template: value.template });
}
exports.normalizeDslForBackend = normalizeDslForBackend;
/**
* 就地归一化本地 yaml 形态的 DSL:
* - 裸 template → 保持裸(本地仍以裸形态可读)
* - 完整对象 → 补齐 definitions.data / $i18n / $colorTokens 为 {}
* - JSON 字符串(老 yaml)→ 解析并升级为对象形态(单向迁移)
* 与 normalizeDslForBackend 的区别:此函数产出**仍然是本地 yaml 形态**,不强制包成
* { definitions, template }。裸 template 的简写特性得以保留,避免 set 落盘时破坏语义。
*/
function normalizeDslInPlace(input) {
if (input == null || input === '')
return input;
let value = input;
if (typeof value === 'string') {
try {
value = JSON.parse(value);
}
catch (_a) {
// 非法 JSON 字符串,保留原值让 schema 校验报错
return input;
}
}
if (!isPlainObject(value))
return input;
// 裸 template(顶层含 `type`):保持裸形态,不主动包 definitions
if (isBareTemplate(value))
return value;
// 完整对象:补齐三键空对象
const defs = isPlainObject(value.definitions) ? value.definitions : {};
const data = isPlainObject(defs.data) ? defs.data : {};
const i18n = isPlainObject(defs.$i18n) ? defs.$i18n : {};
const tokens = isPlainObject(defs.$colorTokens) ? defs.$colorTokens : {};
// 与 denormalizeDslForLocal 保持对称:若三键全空且有 template,折成裸形态。
// 避免 set(normalize) 和 pull(denormalize) 在同一份数据上产出不同形态。
const allDefsEmpty = Object.keys(data).length === 0 &&
Object.keys(i18n).length === 0 &&
Object.keys(tokens).length === 0;
if (allDefsEmpty && isPlainObject(value.template)) {
return value.template;
}
return Object.assign(Object.assign({}, value), { definitions: { data, $i18n: i18n, $colorTokens: tokens }, template: value.template });
}
exports.normalizeDslInPlace = normalizeDslInPlace;
/**
* 对整个本地配置(QueryLocalConfigInput 形态)就地跑 DSL 归一化。
* 影响 control[].platform.web.table_cell 和 field_template[].platform.web.table_layout 两处。
* 其他字段完全保留,不搬成 extension。
*/
function normalizeLocalConfigDsl(config) {
if (!isPlainObject(config))
return config;
const out = Object.assign({}, config);
const controls = Array.isArray(out.control) ? out.control : null;
if (controls) {
out.control = controls.map((pt) => {
var _a, _b;
const cell = (_b = (_a = pt === null || pt === void 0 ? void 0 : pt.platform) === null || _a === void 0 ? void 0 : _a.web) === null || _b === void 0 ? void 0 : _b.table_cell;
if (cell === undefined)
return pt;
return Object.assign(Object.assign({}, pt), { platform: Object.assign(Object.assign({}, pt.platform), { web: Object.assign(Object.assign({}, pt.platform.web), { table_cell: normalizeDslInPlace(cell) }) }) });
});
}
const fieldTemplates = Array.isArray(out.field_template) ? out.field_template : null;
if (fieldTemplates) {
out.field_template = fieldTemplates.map((pt) => {
var _a, _b;
const layout = (_b = (_a = pt === null || pt === void 0 ? void 0 : pt.platform) === null || _a === void 0 ? void 0 : _a.web) === null || _b === void 0 ? void 0 : _b.table_layout;
if (layout === undefined)
return pt;
return Object.assign(Object.assign({}, pt), { platform: Object.assign(Object.assign({}, pt.platform), { web: Object.assign(Object.assign({}, pt.platform.web), { table_layout: normalizeDslInPlace(layout) }) }) });
});
}
return out;
}
exports.normalizeLocalConfigDsl = normalizeLocalConfigDsl;
/** 后端完整对象 → 本地 yaml 形态:当 definitions 三键全为空时,回写为裸 template */
function denormalizeDslForLocal(input) {
if (input == null)
return undefined;
let value = input;
if (typeof value === 'string') {
try {
value = JSON.parse(value);
}
catch (_a) {
return undefined;
}
}
if (!isPlainObject(value))
return undefined;
const template = isPlainObject(value.template) ? value.template : undefined;
const defs = isPlainObject(value.definitions) ? value.definitions : {};
const data = isPlainObject(defs.data) ? defs.data : {};
const i18n = isPlainObject(defs.$i18n) ? defs.$i18n : {};
const tokens = isPlainObject(defs.$colorTokens) ? defs.$colorTokens : {};
const allDefsEmpty = Object.keys(data).length === 0 &&
Object.keys(i18n).length === 0 &&
Object.keys(tokens).length === 0;
if (allDefsEmpty && template) {
return template;
}
return {
definitions: { data, $i18n: i18n, $colorTokens: tokens },
template,
};
}
exports.denormalizeDslForLocal = denormalizeDslForLocal;