@share-crm/sharedev-cli 0.0.4-rc.20 → 0.0.4-rc.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/sharedev.js +488 -124
  2. package/package.json +1 -1
package/dist/sharedev.js CHANGED
@@ -10098,7 +10098,7 @@ function registerFlowNamespace(program, runtimeContext) {
10098
10098
  flowDef
10099
10099
  .command('get-link-app')
10100
10100
  .description('查询互联应用')
10101
- .option('--linkAppId <linkAppId>', '关联应用ID')
10101
+ .option('--flowType <flowType>', '流程类型')
10102
10102
  .action((0, command_ts_1.createCommandAction)('flow def', 'get-link-app', runtimeContext, async ({ options, context }) => {
10103
10103
  await (0, flow_def_command_ts_1.flowDefGetLinkAppCommand)(context, options);
10104
10104
  }));
@@ -13362,11 +13362,10 @@ const rules_ts_1 = __webpack_require__(5330);
13362
13362
  ;
13363
13363
  let instance = null;
13364
13364
  class XmlMetadataManager {
13365
- static getInstance() {
13366
- if (!instance) {
13367
- instance = new XmlMetadataManager();
13368
- }
13369
- return instance;
13365
+ constructor() {
13366
+ if (instance)
13367
+ return instance;
13368
+ instance = this;
13370
13369
  }
13371
13370
  async writeXml(headerName, apiName, content, options = {}) {
13372
13371
  const rule = (0, rules_ts_1.getXmlMetadataRule)(headerName);
@@ -20695,6 +20694,7 @@ exports.buttonCreateService = void 0;
20695
20694
  const normalize_ts_1 = __importDefault(__webpack_require__(9268));
20696
20695
  const index_ts_1 = __webpack_require__(9985);
20697
20696
  const button_service_ts_1 = __webpack_require__(7580);
20697
+ const button_metadata_ts_1 = __webpack_require__(3506);
20698
20698
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
20699
20699
  const buttonCreateService = async (objectApiName, data, force) => {
20700
20700
  // Validate objectApiName
@@ -20707,18 +20707,11 @@ const buttonCreateService = async (objectApiName, data, force) => {
20707
20707
  if (!raw) {
20708
20708
  throw new Error('Invalid arguments: data is required.');
20709
20709
  }
20710
- const buttonData = JSON.parse(raw);
20711
- if (!buttonData || typeof buttonData !== 'object' || Array.isArray(buttonData)) {
20712
- throw new Error('data must be a JSON object.');
20713
- }
20714
- // Extract buttonApiName from data
20715
- const buttonApiName = normalize_ts_1.default.normalizeString(buttonData.api_name);
20716
- if (!buttonApiName) {
20717
- throw new Error('data.api_name is required.');
20718
- }
20710
+ const buttonContent = (0, button_metadata_ts_1.assertCompleteButtonMetaContent)(JSON.parse(raw), checkedObjectApiName);
20711
+ const buttonApiName = (0, button_metadata_ts_1.getButtonApiName)(buttonContent);
20719
20712
  // Check remote existence: error if button already exists remotely
20720
20713
  const remoteButtons = await (0, button_service_ts_1.fetchButtonList)(checkedObjectApiName, null);
20721
- if (remoteButtons.some((item) => normalize_ts_1.default.normalizeString(item.api_name) === buttonApiName)) {
20714
+ if (remoteButtons.some((item) => (0, button_metadata_ts_1.getButtonApiName)(item) === buttonApiName)) {
20722
20715
  throw new Error('Button already exists remotely: ' + checkedObjectApiName + '.' + buttonApiName);
20723
20716
  }
20724
20717
  // Check if local file already exists
@@ -20732,7 +20725,7 @@ const buttonCreateService = async (objectApiName, data, force) => {
20732
20725
  }
20733
20726
  }
20734
20727
  // Write local Button XML, mark as new
20735
- const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, buttonData, {
20728
+ const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, buttonContent, {
20736
20729
  objectApiName: checkedObjectApiName,
20737
20730
  status: 'new',
20738
20731
  });
@@ -20780,14 +20773,17 @@ const buttonListService = async (objectApiName, buttonApiNamesRaw) => {
20780
20773
  errorMessages.push(`${checkedObjectApiName}: ${error instanceof Error ? error.message : String(error)}`);
20781
20774
  return { objectApiName: checkedObjectApiName, buttons: [], found: 0, errorMessages };
20782
20775
  }
20783
- const buttonItems = buttons.map((item) => ({
20784
- apiName: normalize_ts_1.default.normalizeText(item.api_name),
20785
- label: normalize_ts_1.default.normalizeText(item.label),
20786
- buttonType: normalize_ts_1.default.normalizeText(item.button_type),
20787
- usePages: Array.isArray(item.use_pages) ? item.use_pages.join(', ') : normalize_ts_1.default.normalizeText(item.use_pages),
20788
- isActive: normalize_ts_1.default.normalizeText(item.is_active),
20789
- content: item,
20790
- })).filter((item) => item.apiName);
20776
+ const buttonItems = buttons.map((item) => {
20777
+ const button = item.button;
20778
+ return {
20779
+ apiName: normalize_ts_1.default.normalizeText(button.api_name),
20780
+ label: normalize_ts_1.default.normalizeText(button.label),
20781
+ buttonType: normalize_ts_1.default.normalizeText(button.button_type),
20782
+ usePages: Array.isArray(button.use_pages) ? button.use_pages.join(', ') : normalize_ts_1.default.normalizeText(button.use_pages),
20783
+ isActive: normalize_ts_1.default.normalizeText(button.is_active),
20784
+ content: item,
20785
+ };
20786
+ }).filter((item) => item.apiName);
20791
20787
  return {
20792
20788
  objectApiName: checkedObjectApiName,
20793
20789
  buttons: buttonItems,
@@ -20798,6 +20794,222 @@ const buttonListService = async (objectApiName, buttonApiNamesRaw) => {
20798
20794
  exports.buttonListService = buttonListService;
20799
20795
 
20800
20796
 
20797
+ /***/ },
20798
+
20799
+ /***/ 3506
20800
+ (__unused_webpack_module, exports, __webpack_require__) {
20801
+
20802
+
20803
+ var __importDefault = (this && this.__importDefault) || function (mod) {
20804
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20805
+ };
20806
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20807
+ exports.normalizePulledButtonMetaContent = normalizePulledButtonMetaContent;
20808
+ exports.assertCompleteButtonMetaContent = assertCompleteButtonMetaContent;
20809
+ exports.getButtonApiName = getButtonApiName;
20810
+ exports.toButtonExecutePayload = toButtonExecutePayload;
20811
+ const normalize_ts_1 = __importDefault(__webpack_require__(9268));
20812
+ function normalizePulledButtonMetaContent(record, objectApiName) {
20813
+ const button = normalize_ts_1.default.isRecord(record.button) ? record.button : pickFlatButtonRecord(record);
20814
+ const content = {
20815
+ button: {
20816
+ ...button,
20817
+ describe_api_name: normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(button.describe_api_name)) ?? objectApiName,
20818
+ },
20819
+ post_actions: readRecordArray(record.post_actions, 'post_actions', true),
20820
+ roles: readArray(record.roles, 'roles', true),
20821
+ ignore_default_role: readBoolean(record.ignore_default_role, 'ignore_default_role', true) ?? false,
20822
+ i18nInfoList: readRecordArray(record.i18nInfoList, 'i18nInfoList', true),
20823
+ handler_list: readRecordArray(record.handler_list, 'handler_list', true),
20824
+ sourceInfo: normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(record.sourceInfo)),
20825
+ };
20826
+ assertButtonMetaContent(content, objectApiName, { requireComplete: false });
20827
+ return content;
20828
+ }
20829
+ function pickFlatButtonRecord(record) {
20830
+ const { post_actions: _postActions, roles: _roles, ignore_default_role: _ignoreDefaultRole, i18nInfoList: _i18nInfoList, handler_list: _handlerList, sourceInfo: _sourceInfo, button_config: _buttonConfig, ...button } = record;
20831
+ void _postActions;
20832
+ void _roles;
20833
+ void _ignoreDefaultRole;
20834
+ void _i18nInfoList;
20835
+ void _handlerList;
20836
+ void _sourceInfo;
20837
+ void _buttonConfig;
20838
+ return button;
20839
+ }
20840
+ function assertCompleteButtonMetaContent(input, objectApiName) {
20841
+ return assertButtonMetaContent(input, objectApiName, { requireComplete: true });
20842
+ }
20843
+ function getButtonApiName(content) {
20844
+ const buttonApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.api_name));
20845
+ if (!buttonApiName) {
20846
+ throw new Error('button.button.api_name is required.');
20847
+ }
20848
+ return buttonApiName;
20849
+ }
20850
+ function toButtonExecutePayload(content, options) {
20851
+ const buttonPayload = {
20852
+ ...content.button,
20853
+ api_name: options.buttonApiName,
20854
+ describe_api_name: options.objectApiName,
20855
+ };
20856
+ const payload = {
20857
+ button: JSON.stringify(buttonPayload),
20858
+ post_actions: content.post_actions,
20859
+ roles: content.roles,
20860
+ i18nInfoList: content.i18nInfoList,
20861
+ };
20862
+ if (options.isCreate) {
20863
+ payload.ignore_default_role = content.ignore_default_role;
20864
+ }
20865
+ else {
20866
+ payload.handler_list = content.handler_list ?? [];
20867
+ payload.sourceInfo = content.sourceInfo ?? 'object_management';
20868
+ }
20869
+ return payload;
20870
+ }
20871
+ function assertButtonMetaContent(input, objectApiName, options) {
20872
+ if (!normalize_ts_1.default.isRecord(input)) {
20873
+ throw new Error('button content must be a JSON object.');
20874
+ }
20875
+ if (!normalize_ts_1.default.isRecord(input.button)) {
20876
+ throw new Error('button content must include button object.');
20877
+ }
20878
+ const button = { ...input.button };
20879
+ const buttonApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(button.api_name));
20880
+ if (!buttonApiName) {
20881
+ throw new Error('button.button.api_name is required.');
20882
+ }
20883
+ const describeApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(button.describe_api_name));
20884
+ if (!describeApiName) {
20885
+ if (options.requireComplete) {
20886
+ throw new Error('button.button.describe_api_name is required.');
20887
+ }
20888
+ button.describe_api_name = objectApiName;
20889
+ }
20890
+ else if (describeApiName !== objectApiName) {
20891
+ throw new Error('button.button.describe_api_name must be ' + objectApiName + '.');
20892
+ }
20893
+ requireString(button.label, 'button.button.label', options.requireComplete);
20894
+ requireString(button.button_type, 'button.button_type', options.requireComplete);
20895
+ const usePages = readStringArray(button.use_pages, 'button.use_pages', !options.requireComplete);
20896
+ if (options.requireComplete && usePages.length === 0) {
20897
+ throw new Error('button.use_pages must be a non-empty string array.');
20898
+ }
20899
+ button.use_pages = usePages;
20900
+ button.wheres = readRecordArray(button.wheres, 'button.wheres', !options.requireComplete);
20901
+ button.param_form = readRecordArray(button.param_form, 'button.param_form', !options.requireComplete);
20902
+ button.actions = readStringArray(button.actions, 'button.actions', !options.requireComplete);
20903
+ const postActions = readRecordArray(input.post_actions, 'post_actions', !options.requireComplete);
20904
+ const roles = readArray(input.roles, 'roles', !options.requireComplete);
20905
+ const ignoreDefaultRole = readBoolean(input.ignore_default_role, 'ignore_default_role', !options.requireComplete);
20906
+ const i18nInfoList = readRecordArray(input.i18nInfoList, 'i18nInfoList', !options.requireComplete);
20907
+ const handlerList = readRecordArray(input.handler_list, 'handler_list', true);
20908
+ const sourceInfo = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(input.sourceInfo));
20909
+ if (options.requireComplete && i18nInfoList.length === 0) {
20910
+ throw new Error('i18nInfoList must be a non-empty array.');
20911
+ }
20912
+ const content = {
20913
+ button,
20914
+ post_actions: postActions,
20915
+ roles,
20916
+ ignore_default_role: ignoreDefaultRole ?? false,
20917
+ i18nInfoList,
20918
+ handler_list: handlerList,
20919
+ sourceInfo,
20920
+ };
20921
+ assertButtonTypeRules(content);
20922
+ return content;
20923
+ }
20924
+ function requireString(value, fieldName, required) {
20925
+ if (!required && value === undefined) {
20926
+ return;
20927
+ }
20928
+ if (!normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(value))) {
20929
+ throw new Error(fieldName + ' is required.');
20930
+ }
20931
+ }
20932
+ function readBoolean(value, fieldName, optional) {
20933
+ if (value === undefined || value === null) {
20934
+ if (optional) {
20935
+ return undefined;
20936
+ }
20937
+ throw new Error(fieldName + ' is required.');
20938
+ }
20939
+ if (typeof value !== 'boolean') {
20940
+ throw new Error(fieldName + ' must be a boolean.');
20941
+ }
20942
+ return value;
20943
+ }
20944
+ function readRecordArray(value, fieldName, optional) {
20945
+ if (value === undefined || value === null) {
20946
+ if (optional) {
20947
+ return [];
20948
+ }
20949
+ throw new Error(fieldName + ' is required.');
20950
+ }
20951
+ if (!Array.isArray(value)) {
20952
+ throw new Error(fieldName + ' must be an array.');
20953
+ }
20954
+ return value.map((item, index) => {
20955
+ if (!normalize_ts_1.default.isRecord(item)) {
20956
+ throw new Error(fieldName + '[' + index + '] must be an object.');
20957
+ }
20958
+ return item;
20959
+ });
20960
+ }
20961
+ function readArray(value, fieldName, optional) {
20962
+ if (value === undefined || value === null) {
20963
+ if (optional) {
20964
+ return [];
20965
+ }
20966
+ throw new Error(fieldName + ' is required.');
20967
+ }
20968
+ if (!Array.isArray(value)) {
20969
+ throw new Error(fieldName + ' must be an array.');
20970
+ }
20971
+ return value;
20972
+ }
20973
+ function readStringArray(value, fieldName, optional) {
20974
+ if (value === undefined || value === null) {
20975
+ if (optional) {
20976
+ return [];
20977
+ }
20978
+ throw new Error(fieldName + ' is required.');
20979
+ }
20980
+ if (!Array.isArray(value)) {
20981
+ throw new Error(fieldName + ' must be an array.');
20982
+ }
20983
+ return value.map((item, index) => {
20984
+ const text = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(item));
20985
+ if (!text) {
20986
+ throw new Error(fieldName + '[' + index + '] must be a non-empty string.');
20987
+ }
20988
+ return text;
20989
+ });
20990
+ }
20991
+ function assertButtonTypeRules(content) {
20992
+ const buttonType = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.button_type));
20993
+ const redirectType = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.redirect_type));
20994
+ const jumpUrl = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.jump_url));
20995
+ const paramForm = Array.isArray(content.button.param_form) ? content.button.param_form : [];
20996
+ const actions = Array.isArray(content.button.actions) ? content.button.actions : [];
20997
+ if (redirectType) {
20998
+ if (!jumpUrl) {
20999
+ throw new Error('button.jump_url is required when button.redirect_type is set.');
21000
+ }
21001
+ if (actions.length > 0 || content.post_actions.length > 0) {
21002
+ throw new Error('redirect button cannot include button.actions or post_actions.');
21003
+ }
21004
+ }
21005
+ if (buttonType === 'mapping') {
21006
+ if (paramForm.length > 0 || actions.length > 0 || content.post_actions.length > 0) {
21007
+ throw new Error('mapping button cannot include button.param_form, button.actions or post_actions.');
21008
+ }
21009
+ }
21010
+ }
21011
+
21012
+
20801
21013
  /***/ },
20802
21014
 
20803
21015
  /***/ 6884
@@ -20813,6 +21025,7 @@ const normalize_ts_1 = __importDefault(__webpack_require__(9268));
20813
21025
  const logger_ts_1 = __webpack_require__(3333);
20814
21026
  const index_ts_1 = __webpack_require__(9985);
20815
21027
  const button_service_ts_1 = __webpack_require__(7580);
21028
+ const button_metadata_ts_1 = __webpack_require__(3506);
20816
21029
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
20817
21030
  const buttonPullService = async (objectApiNamesRaw, force = false, skipOverwriteConfirm = false) => {
20818
21031
  const errorMessages = [];
@@ -20837,8 +21050,11 @@ const buttonPullService = async (objectApiNamesRaw, force = false, skipOverwrite
20837
21050
  // Write each button to local XML
20838
21051
  for (const buttonRecord of buttons) {
20839
21052
  // Extract button api_name
20840
- const buttonApiName = normalize_ts_1.default.normalizeString(buttonRecord.api_name);
20841
- if (!buttonApiName) {
21053
+ let buttonApiName;
21054
+ try {
21055
+ buttonApiName = (0, button_metadata_ts_1.getButtonApiName)(buttonRecord);
21056
+ }
21057
+ catch {
20842
21058
  skipped += 1;
20843
21059
  continue;
20844
21060
  }
@@ -20912,6 +21128,7 @@ const button_service_ts_1 = __webpack_require__(7580);
20912
21128
  const button_pull_ts_1 = __webpack_require__(6884);
20913
21129
  const request_ts_1 = __webpack_require__(3176);
20914
21130
  const logger_ts_1 = __webpack_require__(3333);
21131
+ const button_metadata_ts_1 = __webpack_require__(3506);
20915
21132
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
20916
21133
  const isRecord = normalize_ts_1.default.isRecord;
20917
21134
  /**
@@ -20953,7 +21170,7 @@ const buttonPushService = async (objectApiName, buttonApiName, skipOverwriteConf
20953
21170
  let existsRemotely = false;
20954
21171
  try {
20955
21172
  const remoteButtons = await (0, button_service_ts_1.fetchButtonList)(checkedObjectApiName, null);
20956
- existsRemotely = remoteButtons.some((item) => normalize_ts_1.default.normalizeString(item.api_name) === checkedButtonApiName);
21173
+ existsRemotely = remoteButtons.some((item) => (0, button_metadata_ts_1.getButtonApiName)(item) === checkedButtonApiName);
20957
21174
  }
20958
21175
  finally {
20959
21176
  logger_ts_1.loggerService.stopLoading();
@@ -20983,40 +21200,16 @@ const buttonPushService = async (objectApiName, buttonApiName, skipOverwriteConf
20983
21200
  objectApiName: checkedObjectApiName,
20984
21201
  });
20985
21202
  const isCreate = correctedMeta.status === 'new';
20986
- // Build push payload
20987
- const buttonContent = { ...(correctedMeta.content && isRecord(correctedMeta.content)
20988
- ? correctedMeta.content
20989
- : buttonMeta.content) };
20990
- if (!buttonContent.describe_api_name) {
20991
- buttonContent.describe_api_name = checkedObjectApiName;
20992
- }
20993
- if (!buttonContent.api_name) {
20994
- buttonContent.api_name = checkedButtonApiName;
20995
- }
20996
- const buttonPayloadContent = { ...buttonContent };
20997
- delete buttonPayloadContent.button_config;
20998
- const buttonJsonString = JSON.stringify(buttonPayloadContent);
21203
+ const buttonContent = (0, button_metadata_ts_1.assertCompleteButtonMetaContent)(correctedMeta.content && isRecord(correctedMeta.content)
21204
+ ? correctedMeta.content
21205
+ : buttonMeta.content, checkedObjectApiName);
20999
21206
  // Build payload and call create/update
21000
21207
  logger_ts_1.loggerService.startLoading('button push request: ' + checkedObjectApiName + '.' + checkedButtonApiName + ' (' + (isCreate ? 'create' : 'update') + ')');
21001
- const payload = {
21002
- button: buttonJsonString,
21003
- post_actions: [],
21004
- roles: [],
21005
- };
21006
- if (!isCreate) {
21007
- payload.handler_list = [];
21008
- }
21009
- const i18nInfoList = buttonContent.i18nInfoList;
21010
- payload.i18nInfoList = i18nInfoList ?? [
21011
- {
21012
- apiName: checkedButtonApiName,
21013
- defaultValue: buttonContent.label ?? checkedButtonApiName,
21014
- type: 'buttonName',
21015
- languageInfo: {
21016
- 'zh-CN': buttonContent.label ?? checkedButtonApiName,
21017
- },
21018
- },
21019
- ];
21208
+ const payload = (0, button_metadata_ts_1.toButtonExecutePayload)(buttonContent, {
21209
+ objectApiName: checkedObjectApiName,
21210
+ buttonApiName: checkedButtonApiName,
21211
+ isCreate,
21212
+ });
21020
21213
  const raw = await (0, request_ts_1.requestObjectDevExecute)(isCreate
21021
21214
  ? (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('button', 'create')
21022
21215
  : (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('button', 'update'), payload);
@@ -21072,8 +21265,9 @@ exports.fetchButtonList = void 0;
21072
21265
  const request_execute_command_paths_ts_1 = __webpack_require__(2351);
21073
21266
  const request_ts_1 = __webpack_require__(3176);
21074
21267
  const types_ts_1 = __webpack_require__(7480);
21268
+ const button_metadata_ts_1 = __webpack_require__(3506);
21075
21269
  /**
21076
- * 共享:调 list 接口获取单个对象下全部按钮(或指定按钮),返回解析后的 button 数组
21270
+ * 共享:调 list 接口获取单个对象下全部按钮(或指定按钮),返回本地 ObjectButton XML content 结构
21077
21271
  */
21078
21272
  const fetchButtonList = async (objectApiName, buttonApiNames) => {
21079
21273
  const response = await (0, request_ts_1.requestObjectDevExecute)((0, request_execute_command_paths_ts_1.getShareCliCommandPath)('button', 'list'), {
@@ -21091,14 +21285,11 @@ const fetchButtonList = async (objectApiName, buttonApiNames) => {
21091
21285
  throw new Error(result.errorMessage);
21092
21286
  }
21093
21287
  const buttons = result.data ?? [];
21094
- // 提取 item.button:响应结构为 [{ button: {...}, button_config: {...}, ... }, ...]
21288
+ // 响应结构为 [{ button, post_actions, roles, i18nInfoList, button_config, ... }]
21289
+ // 本地 XML 只保存完整 button metadata content,不把 button_config 混入 content.button。
21095
21290
  return buttons
21096
21291
  .filter((item) => Boolean(item) && typeof item === 'object')
21097
- .map((item) => {
21098
- const record = item;
21099
- const button = record.button;
21100
- return (button && typeof button === 'object' ? button : record);
21101
- });
21292
+ .map((item) => (0, button_metadata_ts_1.normalizePulledButtonMetaContent)(item, objectApiName));
21102
21293
  };
21103
21294
  exports.fetchButtonList = fetchButtonList;
21104
21295
 
@@ -21116,6 +21307,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
21116
21307
  exports.buttonUpdateService = void 0;
21117
21308
  const normalize_ts_1 = __importDefault(__webpack_require__(9268));
21118
21309
  const index_ts_1 = __webpack_require__(9985);
21310
+ const button_metadata_ts_1 = __webpack_require__(3506);
21119
21311
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
21120
21312
  const buttonUpdateService = async (objectApiName, data) => {
21121
21313
  const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
@@ -21126,32 +21318,17 @@ const buttonUpdateService = async (objectApiName, data) => {
21126
21318
  if (!raw) {
21127
21319
  throw new Error('Invalid arguments: data is required.');
21128
21320
  }
21129
- const buttonData = JSON.parse(raw);
21130
- if (!buttonData || typeof buttonData !== 'object' || Array.isArray(buttonData)) {
21131
- throw new Error('data must be a JSON object.');
21132
- }
21133
- const buttonApiName = normalize_ts_1.default.normalizeString(buttonData.api_name);
21134
- if (!buttonApiName) {
21135
- throw new Error('data.api_name is required.');
21136
- }
21137
- // Read existing data and merge with input
21321
+ const buttonContent = (0, button_metadata_ts_1.assertCompleteButtonMetaContent)(JSON.parse(raw), checkedObjectApiName);
21322
+ const buttonApiName = (0, button_metadata_ts_1.getButtonApiName)(buttonContent);
21138
21323
  const existing = await xmlMetadataManager.readXml('ObjectButton', buttonApiName, {
21139
21324
  objectApiName: checkedObjectApiName,
21140
21325
  fields: ['content', 'status'],
21141
21326
  });
21142
- const existingContent = (existing.content && normalize_ts_1.default.isRecord(existing.content)
21143
- ? existing.content
21144
- : {});
21145
- const inputData = buttonData;
21146
- const mergedData = {};
21147
- for (const key of Object.keys(existingContent)) {
21148
- mergedData[key] = existingContent[key];
21149
- }
21150
- for (const key of Object.keys(inputData)) {
21151
- mergedData[key] = inputData[key];
21327
+ if (existing.content === null || existing.content === undefined) {
21328
+ throw new Error('Button does not exist locally: ' + checkedObjectApiName + '.' + buttonApiName);
21152
21329
  }
21153
21330
  const nextStatus = existing.status === 'new' ? 'new' : 'modified';
21154
- const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, mergedData, {
21331
+ const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, buttonContent, {
21155
21332
  objectApiName: checkedObjectApiName,
21156
21333
  status: nextStatus,
21157
21334
  });
@@ -24906,7 +25083,7 @@ const validateRuleCreateService = async (apiName, data, force = false) => {
24906
25083
  // 1) 校验 validate-rule apiName 参数
24907
25084
  const checkedValidateRuleApiName = normalize_ts_1.default.normalizeString(apiName);
24908
25085
  if (!checkedValidateRuleApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedValidateRuleApiName)) {
24909
- throw new Error('Invalid arguments: apiName is required.');
25086
+ throw new Error('Invalid arguments: validateRuleApiName is required.');
24910
25087
  }
24911
25088
  // 2) 解析创建数据并提取所属 objectApiName
24912
25089
  const raw = normalize_ts_1.default.normalizeString(data);
@@ -24972,7 +25149,7 @@ const validateRuleListService = async (objectApiName) => {
24972
25149
  // 1) 校验参数并查询 validate-rule 列表
24973
25150
  const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
24974
25151
  if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
24975
- throw new Error('Invalid arguments: apiName is required.');
25152
+ throw new Error('Invalid arguments: objectApiName is required.');
24976
25153
  }
24977
25154
  const errorMessages = [];
24978
25155
  const validateRules = [];
@@ -25115,7 +25292,7 @@ const validateRulePushService = async (objectApiName, validateRuleApiName) => {
25115
25292
  throw new Error('Invalid arguments: objectApiName is required.');
25116
25293
  }
25117
25294
  if (!checkedValidateRuleApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedValidateRuleApiName)) {
25118
- throw new Error('Invalid arguments: apiName is required.');
25295
+ throw new Error('Invalid arguments: validateRuleApiName is required.');
25119
25296
  }
25120
25297
  let validateRuleMeta = await xmlMetadataManager.readXml('ObjectValidateRule', checkedValidateRuleApiName, {
25121
25298
  objectApiName: checkedObjectApiName
@@ -25232,7 +25409,7 @@ const validateRuleUpdateService = async (apiName, data) => {
25232
25409
  // 1) 校验 validate-rule apiName 参数
25233
25410
  const checkedValidateRuleApiName = normalize_ts_1.default.normalizeString(apiName);
25234
25411
  if (!checkedValidateRuleApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedValidateRuleApiName)) {
25235
- throw new Error('Invalid arguments: apiName is required.');
25412
+ throw new Error('Invalid arguments: validateRuleApiName is required.');
25236
25413
  }
25237
25414
  // 2) 解析更新数据并提取所属 objectApiName
25238
25415
  const raw = normalize_ts_1.default.normalizeString(data);
@@ -25435,18 +25612,9 @@ const file_ts_1 = __webpack_require__(5409);
25435
25612
  const logger_ts_1 = __webpack_require__(3333);
25436
25613
  const pwc_service_ts_1 = __webpack_require__(2317);
25437
25614
  const pwc_types_ts_1 = __webpack_require__(1851);
25615
+ const pwc_mateXml_ts_1 = __webpack_require__(240);
25438
25616
  const pwc_workspace_ts_1 = __webpack_require__(3047);
25439
25617
  const API_NAME_PATTERN = /^[a-zA-Z](?!.*__.*__c$)\w{0,46}__c$/u;
25440
- async function assertPluginTypeValid(pluginType) {
25441
- const config = await (0, pwc_service_ts_1.getPwcConfig)();
25442
- const validValues = new Set(Object.values(config.plugins ?? {}).flatMap((items) => items.map((item) => item.value)));
25443
- if (!pluginType) {
25444
- throw new Error(`mateXml.xml is missing required <type> for plugin. Valid values: ${[...validValues].join(', ')}`);
25445
- }
25446
- if (!validValues.has(pluginType)) {
25447
- throw new Error(`mateXml.xml <type> value "${pluginType}" is not valid. Valid values: ${[...validValues].join(', ')}`);
25448
- }
25449
- }
25450
25618
  const COMPONENT_DEFAULT_INDEX_VUE = `<template>
25451
25619
  <div>
25452
25620
 
@@ -25587,11 +25755,8 @@ async function pwcDeployCommand(apiNameOrPath, options, context) {
25587
25755
  try {
25588
25756
  const target = resolveDeployTarget(apiNameOrPath, options.type, context);
25589
25757
  logger_ts_1.loggerService.updateLoading(`Preparing local files for ${target.apiName}`);
25590
- const bundle = await (0, pwc_workspace_ts_1.readLocalPwcUploadBundle)(context, target.type, target.apiName);
25591
- if (target.type === pwc_types_ts_1.PWCType.Plugin) {
25592
- logger_ts_1.loggerService.updateLoading('Validating plugin type from mateXml.xml');
25593
- await assertPluginTypeValid(bundle.pluginType);
25594
- }
25758
+ const constraints = (0, pwc_mateXml_ts_1.buildPwcTypeConstraints)(await (0, pwc_service_ts_1.getPwcConfig)());
25759
+ const bundle = await (0, pwc_workspace_ts_1.readLocalPwcUploadBundle)(context, target.type, target.apiName, constraints);
25595
25760
  logger_ts_1.loggerService.updateLoading(`Uploading ${bundle.uploadFiles.length} files`);
25596
25761
  const uploaded = await (0, pwc_service_ts_1.uploadFileList)(bundle.uploadFiles.map((item) => ({
25597
25762
  fileName: item.fileName,
@@ -25657,11 +25822,8 @@ async function pwcPushCommand(apiNameOrPath, options, context) {
25657
25822
  try {
25658
25823
  const target = resolveDeployTarget(apiNameOrPath, options.type, context);
25659
25824
  logger_ts_1.loggerService.updateLoading(`Preparing local files for ${target.apiName}`);
25660
- const bundle = await (0, pwc_workspace_ts_1.readLocalPwcUploadBundle)(context, target.type, target.apiName);
25661
- if (target.type === pwc_types_ts_1.PWCType.Plugin) {
25662
- logger_ts_1.loggerService.updateLoading('Validating plugin type from mateXml.xml');
25663
- await assertPluginTypeValid(bundle.pluginType);
25664
- }
25825
+ const constraints = (0, pwc_mateXml_ts_1.buildPwcTypeConstraints)(await (0, pwc_service_ts_1.getPwcConfig)());
25826
+ const bundle = await (0, pwc_workspace_ts_1.readLocalPwcUploadBundle)(context, target.type, target.apiName, constraints);
25665
25827
  logger_ts_1.loggerService.updateLoading(`Uploading ${bundle.uploadFiles.length} files`);
25666
25828
  const uploaded = await (0, pwc_service_ts_1.uploadFileList)(bundle.uploadFiles.map((item) => ({
25667
25829
  fileName: item.fileName,
@@ -26370,6 +26532,192 @@ async function sleep(ms) {
26370
26532
  }
26371
26533
 
26372
26534
 
26535
+ /***/ },
26536
+
26537
+ /***/ 240
26538
+ (__unused_webpack_module, exports, __webpack_require__) {
26539
+
26540
+
26541
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
26542
+ exports.buildPwcTypeConstraints = buildPwcTypeConstraints;
26543
+ exports.validatePwcLocalStructure = validatePwcLocalStructure;
26544
+ exports.validatePwcMateXmlContent = validatePwcMateXmlContent;
26545
+ const fast_xml_parser_1 = __webpack_require__(4603);
26546
+ const file_ts_1 = __webpack_require__(5409);
26547
+ function buildPwcTypeConstraints(config) {
26548
+ const componentTypes = new Set(Object.keys(config.components ?? {}).filter(Boolean));
26549
+ const pluginTypes = new Set(Object.values(config.plugins ?? {})
26550
+ .flatMap((items) => items.map((item) => item.value))
26551
+ .filter(Boolean));
26552
+ return {
26553
+ componentTypes,
26554
+ pluginTypes
26555
+ };
26556
+ }
26557
+ async function validatePwcLocalStructure(input) {
26558
+ const { type, apiName, mateXmlPath, metaPath, sourceDir, fileTreeDir } = input;
26559
+ if (!(await (0, file_ts_1.pathExists)(mateXmlPath))) {
26560
+ throw new Error(`PWC ${type} ${apiName}: required file not found: ${mateXmlPath}`);
26561
+ }
26562
+ const mateXmlStat = await (0, file_ts_1.statPath)(mateXmlPath);
26563
+ if (!mateXmlStat.isFile()) {
26564
+ throw new Error(`PWC ${type} ${apiName}: required file is not a file: ${mateXmlPath}`);
26565
+ }
26566
+ if (!(await (0, file_ts_1.pathExists)(metaPath))) {
26567
+ throw new Error(`PWC ${type} ${apiName}: required file not found: ${metaPath}`);
26568
+ }
26569
+ const metaStat = await (0, file_ts_1.statPath)(metaPath);
26570
+ if (!metaStat.isFile()) {
26571
+ throw new Error(`PWC ${type} ${apiName}: required file is not a file: ${metaPath}`);
26572
+ }
26573
+ const sourceStat = (await (0, file_ts_1.pathExists)(sourceDir)) ? await (0, file_ts_1.statPath)(sourceDir) : undefined;
26574
+ const fileTreeStat = (await (0, file_ts_1.pathExists)(fileTreeDir)) ? await (0, file_ts_1.statPath)(fileTreeDir) : undefined;
26575
+ const hasSourceDir = sourceStat?.isDirectory() === true;
26576
+ const hasFileTreeDir = fileTreeStat?.isDirectory() === true;
26577
+ if (!hasSourceDir && !hasFileTreeDir) {
26578
+ throw new Error(`PWC ${type} ${apiName}: both source and fileTree are missing.`);
26579
+ }
26580
+ }
26581
+ function parseXmlDocument(content, filePath) {
26582
+ try {
26583
+ return new fast_xml_parser_1.XMLParser({
26584
+ ignoreAttributes: false,
26585
+ attributeNamePrefix: '',
26586
+ trimValues: false
26587
+ }).parse(content);
26588
+ }
26589
+ catch (error) {
26590
+ const message = error instanceof Error ? error.message : String(error);
26591
+ throw new Error(`Invalid XML format in ${filePath}: ${message}`);
26592
+ }
26593
+ }
26594
+ function toArray(value) {
26595
+ if (value == null) {
26596
+ return [];
26597
+ }
26598
+ return Array.isArray(value) ? value : [value];
26599
+ }
26600
+ function readTextNode(value) {
26601
+ if (typeof value === 'string') {
26602
+ return value;
26603
+ }
26604
+ if (typeof value === 'number') {
26605
+ return String(value);
26606
+ }
26607
+ return '';
26608
+ }
26609
+ function hasOwn(obj, key) {
26610
+ return typeof obj === 'object' && obj !== null && Object.prototype.hasOwnProperty.call(obj, key);
26611
+ }
26612
+ function assertNonEmpty(value, message) {
26613
+ if (!value.trim()) {
26614
+ throw new Error(message);
26615
+ }
26616
+ }
26617
+ function assertClientValue(value, message) {
26618
+ if (value !== 'web' && value !== 'app') {
26619
+ throw new Error(message);
26620
+ }
26621
+ }
26622
+ function validateComponentMateXml(doc, input) {
26623
+ const { apiName, constraints } = input;
26624
+ const bundle = doc.ComponentBundle;
26625
+ if (typeof bundle !== 'object' || bundle === null) {
26626
+ throw new Error(`PWC component ${apiName}: mateXml.xml root node must be <ComponentBundle>.`);
26627
+ }
26628
+ if (!hasOwn(bundle, 'description')) {
26629
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <description>.`);
26630
+ }
26631
+ const type = readTextNode(bundle.type);
26632
+ assertNonEmpty(type, `PWC component ${apiName}: mateXml.xml is missing <type>.`);
26633
+ if (!constraints.componentTypes.has(type)) {
26634
+ throw new Error(`PWC component ${apiName}: mateXml.xml <type> value "${type}" is not valid.`);
26635
+ }
26636
+ const clientsNode = bundle.clients;
26637
+ if (typeof clientsNode !== 'object' || clientsNode === null) {
26638
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <clients>.`);
26639
+ }
26640
+ const clients = toArray(clientsNode.client).map(readTextNode);
26641
+ if (!clients.length) {
26642
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <clients><client>.`);
26643
+ }
26644
+ for (const client of clients) {
26645
+ assertNonEmpty(client, `PWC component ${apiName}: mateXml.xml <clients><client> must have a value.`);
26646
+ assertClientValue(client, `PWC component ${apiName}: mateXml.xml <clients><client> must be web or app.`);
26647
+ }
26648
+ const scopesNode = bundle.scopes;
26649
+ if (typeof scopesNode !== 'object' || scopesNode === null) {
26650
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <scopes>.`);
26651
+ }
26652
+ const scopes = toArray(scopesNode.scope);
26653
+ if (!scopes.length) {
26654
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <scopes><scope>.`);
26655
+ }
26656
+ for (const scope of scopes) {
26657
+ if (typeof scope !== 'object' || scope === null) {
26658
+ throw new Error(`PWC component ${apiName}: mateXml.xml <scopes><scope> must contain target attribute and valid content.`);
26659
+ }
26660
+ const scopeObj = scope;
26661
+ const target = readTextNode(scopeObj.target);
26662
+ assertNonEmpty(target, `PWC component ${apiName}: mateXml.xml <scopes><scope> must contain target attribute.`);
26663
+ const wildcardText = readTextNode(scopeObj['#text']);
26664
+ const objectsNode = scopeObj.objects;
26665
+ const hasWildcard = wildcardText.trim() === '*';
26666
+ const hasObjects = typeof objectsNode === 'object' && objectsNode !== null;
26667
+ if (hasWildcard) {
26668
+ continue;
26669
+ }
26670
+ if (hasObjects) {
26671
+ const objects = toArray(objectsNode.object).map(readTextNode).filter((item) => item.trim());
26672
+ if (!objects.length) {
26673
+ throw new Error(`PWC component ${apiName}: mateXml.xml historical <objects><object> structure is empty.`);
26674
+ }
26675
+ continue;
26676
+ }
26677
+ throw new Error(`PWC component ${apiName}: mateXml.xml <scopes><scope> must be "*" or nested <objects><object>...</object></objects>.`);
26678
+ }
26679
+ }
26680
+ function validatePluginMateXml(doc, input) {
26681
+ const { apiName, constraints } = input;
26682
+ const bundle = doc.PluginBundle;
26683
+ if (typeof bundle !== 'object' || bundle === null) {
26684
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml root node must be <PluginBundle>.`);
26685
+ }
26686
+ if (!hasOwn(bundle, 'description')) {
26687
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml is missing <description>.`);
26688
+ }
26689
+ const type = readTextNode(bundle.type);
26690
+ assertNonEmpty(type, `PWC plugin ${apiName}: mateXml.xml is missing <type>.`);
26691
+ if (!constraints.pluginTypes.has(type)) {
26692
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml <type> value "${type}" is not valid.`);
26693
+ }
26694
+ const client = readTextNode(bundle.client);
26695
+ assertNonEmpty(client, `PWC plugin ${apiName}: mateXml.xml is missing <client>.`);
26696
+ assertClientValue(client, `PWC plugin ${apiName}: mateXml.xml <client> must be web or app.`);
26697
+ const entryFileName = readTextNode(bundle.entryFileName);
26698
+ const requiresEntryFileName = client === 'web';
26699
+ if (requiresEntryFileName) {
26700
+ assertNonEmpty(entryFileName, `PWC plugin ${apiName}: mateXml.xml is missing <entryFileName>.`);
26701
+ }
26702
+ const scopeObjectsNode = bundle.scopeObjects;
26703
+ if (typeof scopeObjectsNode !== 'object' || scopeObjectsNode === null) {
26704
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml is missing <scopeObjects>.`);
26705
+ }
26706
+ const objects = toArray(scopeObjectsNode.object).map(readTextNode).filter((item) => item.trim());
26707
+ if (!objects.length) {
26708
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml is missing <scopeObjects><object>.`);
26709
+ }
26710
+ }
26711
+ function validatePwcMateXmlContent(input) {
26712
+ const doc = parseXmlDocument(input.content, input.filePath);
26713
+ if (input.type === 'component') {
26714
+ validateComponentMateXml(doc, input);
26715
+ return;
26716
+ }
26717
+ validatePluginMateXml(doc, input);
26718
+ }
26719
+
26720
+
26373
26721
  /***/ },
26374
26722
 
26375
26723
  /***/ 2317
@@ -26611,6 +26959,7 @@ const node_path_1 = __importDefault(__webpack_require__(6760));
26611
26959
  const fast_xml_parser_1 = __webpack_require__(4603);
26612
26960
  const file_ts_1 = __webpack_require__(5409);
26613
26961
  const pwc_types_ts_1 = __webpack_require__(1851);
26962
+ const pwc_mateXml_ts_1 = __webpack_require__(240);
26614
26963
  async function writeFiles(baseDir, files) {
26615
26964
  if (!files?.length) {
26616
26965
  return;
@@ -26700,7 +27049,7 @@ function resolveMateXmlInfo(type, mateXmlContent) {
26700
27049
  pluginType: typeof pluginType === 'string' ? pluginType : 'edit_plugin'
26701
27050
  };
26702
27051
  }
26703
- async function readLocalPwcUploadBundle(context, type, apiName) {
27052
+ async function readLocalPwcUploadBundle(context, type, apiName, constraints) {
26704
27053
  const componentRoot = resolvePwcComponentRoot(context, type, apiName);
26705
27054
  if (!(await (0, file_ts_1.pathExists)(componentRoot))) {
26706
27055
  throw new Error(`Local PWC resource directory not found: ${componentRoot}`);
@@ -26709,6 +27058,16 @@ async function readLocalPwcUploadBundle(context, type, apiName) {
26709
27058
  const staticDir = node_path_1.default.join(componentRoot, 'static');
26710
27059
  const fileTreeDir = node_path_1.default.join(componentRoot, 'fileTree');
26711
27060
  const mateXmlPath = node_path_1.default.join(componentRoot, 'mateXml.xml');
27061
+ const metaPath = node_path_1.default.join(componentRoot, '.sharedev-meta.json');
27062
+ await (0, pwc_mateXml_ts_1.validatePwcLocalStructure)({
27063
+ type,
27064
+ apiName,
27065
+ componentRoot,
27066
+ mateXmlPath,
27067
+ metaPath,
27068
+ sourceDir,
27069
+ fileTreeDir
27070
+ });
26712
27071
  const sourceFiles = await collectFilesRecursively(sourceDir);
26713
27072
  const staticFiles = await collectFilesRecursively(staticDir);
26714
27073
  const fileTreeFiles = await collectFilesRecursively(fileTreeDir);
@@ -26731,13 +27090,18 @@ async function readLocalPwcUploadBundle(context, type, apiName) {
26731
27090
  let entryFileName = '';
26732
27091
  let client = 'web';
26733
27092
  let pluginType = '';
26734
- if (await (0, file_ts_1.pathExists)(mateXmlPath)) {
26735
- const mateXmlContent = await (0, file_ts_1.readTextFile)(mateXmlPath);
26736
- const mateInfo = resolveMateXmlInfo(type, mateXmlContent);
26737
- entryFileName = mateInfo.entryFileName;
26738
- client = mateInfo.client;
26739
- pluginType = mateInfo.pluginType;
26740
- }
27093
+ const mateXmlContent = await (0, file_ts_1.readTextFile)(mateXmlPath);
27094
+ (0, pwc_mateXml_ts_1.validatePwcMateXmlContent)({
27095
+ type,
27096
+ apiName,
27097
+ filePath: mateXmlPath,
27098
+ content: mateXmlContent,
27099
+ constraints
27100
+ });
27101
+ const mateInfo = resolveMateXmlInfo(type, mateXmlContent);
27102
+ entryFileName = mateInfo.entryFileName;
27103
+ client = mateInfo.client;
27104
+ pluginType = mateInfo.pluginType;
26741
27105
  return {
26742
27106
  entryFileName,
26743
27107
  client,
@@ -26753,17 +27117,17 @@ function resolveFileTreeRelativePath(fileTreeBaseDir, absoluteFilePath) {
26753
27117
  return normalizeFileTreePath(fileTreeBaseDir, absoluteFilePath);
26754
27118
  }
26755
27119
  async function writePwcComponent(context, component) {
26756
- const componentRoot = resolvePwcComponentRoot(context, component.type, component.apiName);
27120
+ const type = component.type;
27121
+ const componentRoot = resolvePwcComponentRoot(context, type, component.apiName);
26757
27122
  const sourceDir = node_path_1.default.join(componentRoot, 'source');
26758
27123
  const staticDir = node_path_1.default.join(componentRoot, 'static');
26759
27124
  const fileTreeDir = node_path_1.default.join(componentRoot, 'fileTree');
27125
+ const mateXmlPath = node_path_1.default.join(componentRoot, 'mateXml.xml');
26760
27126
  await (0, file_ts_1.ensureDir)(componentRoot);
26761
27127
  await (0, file_ts_1.ensureDir)(sourceDir);
26762
27128
  await (0, file_ts_1.ensureDir)(staticDir);
26763
27129
  await (0, file_ts_1.ensureDir)(fileTreeDir);
26764
- if (component.mateXml) {
26765
- await (0, file_ts_1.writeTextFile)(node_path_1.default.join(componentRoot, 'mateXml.xml'), component.mateXml);
26766
- }
27130
+ await (0, file_ts_1.writeTextFile)(mateXmlPath, component.mateXml);
26767
27131
  await writeFiles(sourceDir, component.sourceFiles);
26768
27132
  await writeFiles(staticDir, component.images);
26769
27133
  await writeFileTree(fileTreeDir, component.fileTree);
@@ -42627,7 +42991,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"application/1d-interleaved-parityfec
42627
42991
  /***/ 8330
42628
42992
  (module) {
42629
42993
 
42630
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@share-crm/sharedev-cli","version":"0.0.4-rc.20","private":false,"description":"sharedev command line tool","type":"module","main":"dist/sharedev.js","bin":{"sharedev":"./bin/cli.mjs"},"author":{"name":"sharecrm-npm"},"files":["dist","bin","README.md"],"scripts":{"build":"tsc --noEmit && webpack --config build/webpack/webpack.prod.cjs","build:debug":"tsc --noEmit && webpack --config build/webpack/webpack.debug.cjs","build:bin":"bun build --compile --target=bun-darwin-x64 src/cli.ts --outfile scripts/sharedev-darwin-x64 && bun build --compile --target=bun-darwin-arm64 src/cli.ts --outfile scripts/sharedev-darwin-arm64 && bun build --compile --target=bun-windows-x64 src/cli.ts --outfile scripts/sharedev-windows-x64.exe","build:all":"npm run build && npm run build:bin","dev":"tsc --noEmit --watch & webpack --config build/webpack/webpack.dev.cjs --watch","dev2":"node src/cli.ts","typecheck":"tsc --noEmit","prettier":"prettier --write ./src/**/*.ts","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},"dependencies":{"@clack/prompts":"^1.1.0","@mariozechner/pi-coding-agent":"^0.62.0","axios":"~1.13.0","chalk":"^5.6.2","commander":"^14.0.1","extract-zip":"^2.0.1","fast-xml-parser":"^5.2.5","fs-extra":"^11.3.2","lodash-es":"^4.18.1","ora":"^9.3.0"},"devDependencies":{"@types/extract-zip":"^2.0.3","@types/fs-extra":"^11.0.4","@types/lodash-es":"^4.17.12","@types/node":"^24.3.0","@vitest/coverage-v8":"^4.1.8","ts-loader":"^9.5.4","typescript":"^5.9.2","vitest":"^3.2.6","webpack":"^5.101.3","webpack-cli":"^6.0.1","webpack-merge":"^6.0.1"},"packageManager":"pnpm@10.17.0"}');
42994
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@share-crm/sharedev-cli","version":"0.0.4-rc.21","private":false,"description":"sharedev command line tool","type":"module","main":"dist/sharedev.js","bin":{"sharedev":"./bin/cli.mjs"},"author":{"name":"sharecrm-npm"},"files":["dist","bin","README.md"],"scripts":{"build":"tsc --noEmit && webpack --config build/webpack/webpack.prod.cjs","build:debug":"tsc --noEmit && webpack --config build/webpack/webpack.debug.cjs","build:bin":"bun build --compile --target=bun-darwin-x64 src/cli.ts --outfile scripts/sharedev-darwin-x64 && bun build --compile --target=bun-darwin-arm64 src/cli.ts --outfile scripts/sharedev-darwin-arm64 && bun build --compile --target=bun-windows-x64 src/cli.ts --outfile scripts/sharedev-windows-x64.exe","build:all":"npm run build && npm run build:bin","dev":"tsc --noEmit --watch & webpack --config build/webpack/webpack.dev.cjs --watch","dev2":"node src/cli.ts","typecheck":"tsc --noEmit","prettier":"prettier --write ./src/**/*.ts","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},"dependencies":{"@clack/prompts":"^1.1.0","@mariozechner/pi-coding-agent":"^0.62.0","axios":"~1.13.0","chalk":"^5.6.2","commander":"^14.0.1","extract-zip":"^2.0.1","fast-xml-parser":"^5.2.5","fs-extra":"^11.3.2","lodash-es":"^4.18.1","ora":"^9.3.0"},"devDependencies":{"@types/extract-zip":"^2.0.3","@types/fs-extra":"^11.0.4","@types/lodash-es":"^4.17.12","@types/node":"^24.3.0","@vitest/coverage-v8":"^4.1.8","ts-loader":"^9.5.4","typescript":"^5.9.2","vitest":"^3.2.6","webpack":"^5.101.3","webpack-cli":"^6.0.1","webpack-merge":"^6.0.1"},"packageManager":"pnpm@10.17.0"}');
42631
42995
 
42632
42996
  /***/ }
42633
42997
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@share-crm/sharedev-cli",
3
- "version": "0.0.4-rc.20",
3
+ "version": "0.0.4-rc.21",
4
4
  "private": false,
5
5
  "description": "sharedev command line tool",
6
6
  "type": "module",