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

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 +1002 -507
  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
  }));
@@ -10582,15 +10582,18 @@ Examples:
10582
10582
  $ sharedev object-dev scene pull --objectApiName AccountObj --sceneApiName demo_scene
10583
10583
  $ sharedev object-dev scene push --objectApiName AccountObj --sceneApiNames demo_scene,test_scene
10584
10584
  $ sharedev object-dev scene update --objectApiName AccountObj --data "{}"
10585
- $ sharedev object-dev object-mapping pull --objectApiNames AccountObj,LeadsObj
10586
- $ sharedev object-dev object-mapping create --objectApiName AccountObj --data "{}"
10587
- $ sharedev object-dev object-mapping update --objectApiName AccountObj --data "{}"
10588
- $ sharedev object-dev object-mapping push --objectApiName AccountObj --ruleApiNames rule_xsh2__c,rule_xxa1__c
10589
- $ sharedev object-dev convert-rule list --objectApiName AccountObj
10590
- $ sharedev object-dev convert-rule pull --objectApiNames AccountObj,LeadsObj
10591
- $ sharedev object-dev convert-rule create --objectApiName AccountObj --data "{}"
10592
- $ sharedev object-dev convert-rule update --objectApiName AccountObj --data "{}"
10593
- $ sharedev object-dev convert-rule push --objectApiName AccountObj --ruleApiNames rule_xsh2__c,rule_xxa1__c
10585
+ $ sharedev object-dev object-mapping pull
10586
+ $ sharedev object-dev object-mapping create --data "{}"
10587
+ $ sharedev object-dev object-mapping update --data "{}"
10588
+ $ sharedev object-dev object-mapping push --ruleApiNames rule_xsh2__c,rule_xxa1__c
10589
+ $ sharedev object-dev object-mapping push
10590
+ $ sharedev object-dev convert-rule list
10591
+ $ sharedev object-dev convert-rule pull
10592
+ $ sharedev object-dev convert-rule create --data "{}"
10593
+ $ sharedev object-dev convert-rule update --data "{}"
10594
+ $ sharedev object-dev convert-rule push --ruleApiNames rule_xsh2__c,rule_xxa1__c
10595
+ $ sharedev object-dev email-template list
10596
+ $ sharedev object-dev email-template list --objDescApiName AccountObj
10594
10597
  `);
10595
10598
  const objectCommand = objectDev.command('object').description('Object describe operations');
10596
10599
  objectCommand
@@ -11032,7 +11035,8 @@ Examples:
11032
11035
  objectMappingCommand
11033
11036
  .command('pull')
11034
11037
  .description('Pull object-mapping rules from remote and save locally')
11035
- .requiredOption('--objectApiNames <apiNames>', 'Object apiNames, comma separated')
11038
+ .option('--status <number>', 'Filter by status (1=enabled, 0=disabled)')
11039
+ .option('--ruleName <name>', 'Filter by rule name')
11036
11040
  .option('--force', 'Force overwrite local metadata files regardless of local status')
11037
11041
  .option('--yes', 'Skip the force confirmation prompt')
11038
11042
  .option('--skipOverwriteConfirm', 'Skip overwrite confirm for local metadata not in unchanged status and keep local file')
@@ -11043,7 +11047,7 @@ Examples:
11043
11047
  objectMappingCommand
11044
11048
  .command('create')
11045
11049
  .description('Create local object-mapping rule draft without remote API call')
11046
- .requiredOption('--objectApiName <apiName>', 'Target object apiName')
11050
+ .option('--objectApiName <apiName>', 'Target object apiName (can also be set via data.describe_api_name)')
11047
11051
  .requiredOption('--data <json>', 'Object-mapping rule data (JSON string)')
11048
11052
  .option('--force', 'Force overwrite local metadata file if it already exists')
11049
11053
  .action((0, command_ts_1.createCommandAction)('object-dev', 'object-mapping.create', runtimeContext, async ({ options, context }) => {
@@ -11053,7 +11057,6 @@ Examples:
11053
11057
  objectMappingCommand
11054
11058
  .command('update')
11055
11059
  .description('Update local object-mapping rule draft without remote API call')
11056
- .requiredOption('--objectApiName <apiName>', 'Target object apiName')
11057
11060
  .requiredOption('--data <json>', 'Object-mapping rule data (JSON string)')
11058
11061
  .action((0, command_ts_1.createCommandAction)('object-dev', 'object-mapping.update', runtimeContext, async ({ options, context }) => {
11059
11062
  void context;
@@ -11062,8 +11065,7 @@ Examples:
11062
11065
  objectMappingCommand
11063
11066
  .command('push')
11064
11067
  .description('Push object-mapping rules to remote via shareCli execute (auto create or update)')
11065
- .requiredOption('--objectApiName <apiName>', 'Target object apiName')
11066
- .requiredOption('--ruleApiNames <ruleApiNames>', 'Target rule apiNames, comma separated')
11068
+ .option('--ruleApiNames <ruleApiNames>', 'Target rule apiNames, comma separated (push all if omitted)')
11067
11069
  .option('--skipOverwriteConfirm', 'Skip overwrite confirm when pre/post pull encounters local metadata not in unchanged status')
11068
11070
  .action((0, command_ts_1.createCommandAction)('object-dev', 'object-mapping.push', runtimeContext, async ({ options, context }) => {
11069
11071
  void context;
@@ -11073,7 +11075,7 @@ Examples:
11073
11075
  convertRuleCommand
11074
11076
  .command('list')
11075
11077
  .description('List convert rules via shareCli execute')
11076
- .requiredOption('--objectApiName <apiName>', 'Target object apiName')
11078
+ .option('--ruleName <name>', 'Filter by rule name')
11077
11079
  .action((0, command_ts_1.createCommandAction)('object-dev', 'convert-rule.list', runtimeContext, async ({ options, context }) => {
11078
11080
  void context;
11079
11081
  await (0, index_ts_1.objectDevConvertRuleListCommand)(options);
@@ -11081,7 +11083,7 @@ Examples:
11081
11083
  convertRuleCommand
11082
11084
  .command('pull')
11083
11085
  .description('Pull convert rules from remote and save locally')
11084
- .requiredOption('--objectApiNames <apiNames>', 'Object apiNames, comma separated')
11086
+ .option('--ruleName <name>', 'Filter by rule name')
11085
11087
  .option('--force', 'Force overwrite local metadata files regardless of local status')
11086
11088
  .option('--yes', 'Skip the force confirmation prompt')
11087
11089
  .option('--skipOverwriteConfirm', 'Skip overwrite confirm for local metadata not in unchanged status and keep local file')
@@ -11092,7 +11094,6 @@ Examples:
11092
11094
  convertRuleCommand
11093
11095
  .command('create')
11094
11096
  .description('Create local convert-rule draft without remote API call')
11095
- .requiredOption('--objectApiName <apiName>', 'Target object apiName')
11096
11097
  .requiredOption('--data <json>', 'Convert-rule data (JSON string)')
11097
11098
  .option('--force', 'Force overwrite local metadata file if it already exists')
11098
11099
  .action((0, command_ts_1.createCommandAction)('object-dev', 'convert-rule.create', runtimeContext, async ({ options, context }) => {
@@ -11102,7 +11103,6 @@ Examples:
11102
11103
  convertRuleCommand
11103
11104
  .command('update')
11104
11105
  .description('Update local convert-rule draft without remote API call')
11105
- .requiredOption('--objectApiName <apiName>', 'Target object apiName')
11106
11106
  .requiredOption('--data <json>', 'Convert-rule data (JSON string)')
11107
11107
  .action((0, command_ts_1.createCommandAction)('object-dev', 'convert-rule.update', runtimeContext, async ({ options, context }) => {
11108
11108
  void context;
@@ -11111,13 +11111,23 @@ Examples:
11111
11111
  convertRuleCommand
11112
11112
  .command('push')
11113
11113
  .description('Push convert rules to remote via shareCli execute (auto create or update)')
11114
- .requiredOption('--objectApiName <apiName>', 'Target object apiName')
11115
11114
  .requiredOption('--ruleApiNames <ruleApiNames>', 'Target rule apiNames, comma separated')
11116
11115
  .option('--skipOverwriteConfirm', 'Skip overwrite confirm when pre/post pull encounters local metadata not in unchanged status')
11117
11116
  .action((0, command_ts_1.createCommandAction)('object-dev', 'convert-rule.push', runtimeContext, async ({ options, context }) => {
11118
11117
  void context;
11119
11118
  await (0, index_ts_1.objectDevConvertRulePushCommand)(options);
11120
11119
  }));
11120
+ const emailTemplateCommand = objectDev.command('email-template').description('Email template operations');
11121
+ emailTemplateCommand
11122
+ .command('list')
11123
+ .description('List email templates via shareCli execute')
11124
+ .option('--objDescApiName <apiName>', 'Filter by object describe api name')
11125
+ .option('--pageNumber <number>', 'Page number (default: 1)')
11126
+ .option('--pageSize <number>', 'Page size (default: 2000)')
11127
+ .action((0, command_ts_1.createCommandAction)('object-dev', 'email-template.list', runtimeContext, async ({ options, context }) => {
11128
+ void context;
11129
+ await (0, index_ts_1.objectDevEmailTemplateListCommand)(options);
11130
+ }));
11121
11131
  }
11122
11132
 
11123
11133
 
@@ -12763,6 +12773,9 @@ const SHARE_CLI_COMMAND_PATH_MAP = {
12763
12773
  'create-rule': ['object-dev', 'convert-rule', 'create-rule'],
12764
12774
  'update-rule': ['object-dev', 'convert-rule', 'update-rule'],
12765
12775
  },
12776
+ emailTemplate: {
12777
+ 'template-page': ['object-dev', 'email-template', 'template-page'],
12778
+ },
12766
12779
  dataAuth: {
12767
12780
  getCommonPrivilegeList: ['access', 'data-auth', 'get-common-privilege-list'],
12768
12781
  batchUpdateCommonPrivilege: ['access', 'data-auth', 'batch-update-common-privilege'],
@@ -13362,11 +13375,10 @@ const rules_ts_1 = __webpack_require__(5330);
13362
13375
  ;
13363
13376
  let instance = null;
13364
13377
  class XmlMetadataManager {
13365
- static getInstance() {
13366
- if (!instance) {
13367
- instance = new XmlMetadataManager();
13368
- }
13369
- return instance;
13378
+ constructor() {
13379
+ if (instance)
13380
+ return instance;
13381
+ instance = this;
13370
13382
  }
13371
13383
  async writeXml(headerName, apiName, content, options = {}) {
13372
13384
  const rule = (0, rules_ts_1.getXmlMetadataRule)(headerName);
@@ -13758,13 +13770,13 @@ exports.XML_METADATA_RULES = {
13758
13770
  defaultOpenTag: '<CommonPrivilege xmlns="http://sharecrm.com/metadata">',
13759
13771
  },
13760
13772
  ObjectMapping: {
13761
- dirPathTemplate: 'tenant-config/objects/{objectApiName}/object-mappings',
13773
+ dirPathTemplate: 'tenant-config/object-mappings',
13762
13774
  fileNameTemplate: '{apiName}.object-mapping-meta.xml',
13763
13775
  apiNameVariable: 'apiName',
13764
13776
  defaultOpenTag: '<ObjectMapping xmlns="http://sharecrm.com/metadata">',
13765
13777
  },
13766
13778
  ConvertRule: {
13767
- dirPathTemplate: 'tenant-config/objects/{objectApiName}/convert-rules',
13779
+ dirPathTemplate: 'tenant-config/convert-rules',
13768
13780
  fileNameTemplate: '{apiName}.convert-rule-meta.xml',
13769
13781
  apiNameVariable: 'apiName',
13770
13782
  defaultOpenTag: '<ConvertRule xmlns="http://sharecrm.com/metadata">',
@@ -19793,23 +19805,28 @@ function printErrorMessages(errorMessages) {
19793
19805
  return true;
19794
19806
  }
19795
19807
  async function objectDevConvertRuleListCommand(options) {
19796
- const checkedObjectApiName = normalize_ts_1.default.normalizeString(options.objectApiName);
19797
- if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
19798
- throw new Error('Invalid arguments: objectApiName is required.');
19799
- }
19800
- const rules = await (0, index_ts_1.fetchConvertRuleList)(checkedObjectApiName, null);
19801
- logger_ts_1.loggerService.printTable(['apiName', 'label', 'ruleType', 'isActive'], rules.map((item) => [
19802
- normalize_ts_1.default.normalizeString(item.api_name)
19803
- ?? normalize_ts_1.default.normalizeString(item.apiName) ?? '',
19804
- normalize_ts_1.default.normalizeText(item.label),
19805
- normalize_ts_1.default.normalizeText(item.rule_type)
19806
- ?? normalize_ts_1.default.normalizeText(item.ruleType)
19807
- ?? '',
19808
- normalize_ts_1.default.normalizeText(item.is_active)
19809
- ?? normalize_ts_1.default.normalizeText(item.isActive)
19810
- ?? '',
19808
+ const items = await (0, index_ts_1.fetchConvertRuleList)({
19809
+ ruleName: options.ruleName,
19810
+ });
19811
+ // 展开 items[].ruleList[] 为扁平规则列表
19812
+ const rules = [];
19813
+ for (const item of items) {
19814
+ const ruleList = item.ruleList;
19815
+ if (ruleList) {
19816
+ rules.push(...ruleList);
19817
+ }
19818
+ }
19819
+ logger_ts_1.loggerService.printTable(['apiName', 'ruleName', 'sourceApiName', 'targetApiName', 'defineType'], rules.map((item) => [
19820
+ normalize_ts_1.default.normalizeString(item.rule_api_name) ?? '',
19821
+ normalize_ts_1.default.normalizeText(item.rule_name),
19822
+ normalize_ts_1.default.normalizeText(item.source_api_name)
19823
+ ?? normalize_ts_1.default.normalizeText(item.sourceApiName) ?? '',
19824
+ normalize_ts_1.default.normalizeText(item.target_api_name)
19825
+ ?? normalize_ts_1.default.normalizeText(item.targetApiName) ?? '',
19826
+ normalize_ts_1.default.normalizeText(item.define_type)
19827
+ ?? normalize_ts_1.default.normalizeText(item.defineType) ?? '',
19811
19828
  ]));
19812
- logger_ts_1.loggerService.success(`Convert-rule list completed: object=${checkedObjectApiName}, found=${rules.length}`);
19829
+ logger_ts_1.loggerService.success(`Convert-rule list completed: found=${rules.length}`);
19813
19830
  }
19814
19831
  async function objectDevConvertRulePullCommand(options) {
19815
19832
  if (options.force && options.skipOverwriteConfirm) {
@@ -19824,13 +19841,17 @@ async function objectDevConvertRulePullCommand(options) {
19824
19841
  throw new Error('Command cancelled.');
19825
19842
  }
19826
19843
  }
19827
- const { objectApiNames, found, written, skipped, errorMessages } = await (0, index_ts_1.convertRulePullService)(options.objectApiNames, options.force === true, options.skipOverwriteConfirm === true);
19844
+ const { found, written, skipped, errorMessages } = await (0, index_ts_1.convertRulePullService)({
19845
+ ruleName: options.ruleName,
19846
+ force: options.force === true,
19847
+ skipOverwriteConfirm: options.skipOverwriteConfirm === true,
19848
+ });
19828
19849
  if (printErrorMessages(errorMessages))
19829
19850
  return;
19830
- logger_ts_1.loggerService.success(`Convert-rule pull completed: objects=${objectApiNames.length}, found=${found}, written=${written}, skipped=${skipped}`);
19851
+ logger_ts_1.loggerService.success(`Convert-rule pull completed: found=${found}, written=${written}, skipped=${skipped}`);
19831
19852
  }
19832
19853
  async function objectDevConvertRuleCreateCommand(options) {
19833
- const result = await (0, index_ts_1.convertRuleCreateService)(options.objectApiName, options.data, options.force === true);
19854
+ const result = await (0, index_ts_1.convertRuleCreateService)(options.data, options.force === true);
19834
19855
  if (printErrorMessages(result.errorMessages))
19835
19856
  return;
19836
19857
  if (!result.filePath) {
@@ -19840,7 +19861,7 @@ async function objectDevConvertRuleCreateCommand(options) {
19840
19861
  logger_ts_1.loggerService.info(`Convert-rule metadata created: ${result.filePath}`);
19841
19862
  }
19842
19863
  async function objectDevConvertRuleUpdateCommand(options) {
19843
- const result = await (0, index_ts_1.convertRuleUpdateService)(options.objectApiName, options.data);
19864
+ const result = await (0, index_ts_1.convertRuleUpdateService)(options.data);
19844
19865
  if (!result.filePath) {
19845
19866
  throw new Error('Convert-rule metadata not updated.');
19846
19867
  }
@@ -19850,10 +19871,41 @@ async function objectDevConvertRuleUpdateCommand(options) {
19850
19871
  logger_ts_1.loggerService.info(`Convert-rule metadata updated: ${result.filePath}`);
19851
19872
  }
19852
19873
  async function objectDevConvertRulePushCommand(options) {
19853
- const pushed = await (0, index_ts_1.convertRulePushService)(options.objectApiName, options.ruleApiNames, options.skipOverwriteConfirm === true);
19874
+ const pushed = await (0, index_ts_1.convertRulePushService)(options.ruleApiNames, options.skipOverwriteConfirm === true);
19854
19875
  if (printErrorMessages(pushed.errorMessages))
19855
19876
  return;
19856
- logger_ts_1.loggerService.success(`Push completed successfully: convert-rule (${pushed.objectApiName}.${pushed.apiName})`);
19877
+ logger_ts_1.loggerService.success(`Push completed successfully: convert-rule (${pushed.apiName})`);
19878
+ }
19879
+
19880
+
19881
+ /***/ },
19882
+
19883
+ /***/ 1026
19884
+ (__unused_webpack_module, exports, __webpack_require__) {
19885
+
19886
+
19887
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19888
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19889
+ };
19890
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
19891
+ exports.objectDevEmailTemplateListCommand = objectDevEmailTemplateListCommand;
19892
+ const index_ts_1 = __webpack_require__(285);
19893
+ const logger_ts_1 = __webpack_require__(3333);
19894
+ const normalize_ts_1 = __importDefault(__webpack_require__(9268));
19895
+ async function objectDevEmailTemplateListCommand(options) {
19896
+ const items = await (0, index_ts_1.fetchEmailTemplateList)({
19897
+ objDescApiName: options.objDescApiName,
19898
+ pageNumber: options.pageNumber ? Number(options.pageNumber) : undefined,
19899
+ pageSize: options.pageSize ? Number(options.pageSize) : undefined,
19900
+ });
19901
+ logger_ts_1.loggerService.printTable(['apiName', 'name', 'subject', 'objDescApiName', 'bindApl'], items.map((item) => [
19902
+ normalize_ts_1.default.normalizeString(item.apiName) ?? '',
19903
+ normalize_ts_1.default.normalizeText(item.name),
19904
+ normalize_ts_1.default.normalizeText(item.subject),
19905
+ normalize_ts_1.default.normalizeText(item.objDescApiName) ?? '',
19906
+ normalize_ts_1.default.normalizeText(item.bindAplApiname) ?? '',
19907
+ ]));
19908
+ logger_ts_1.loggerService.success(`Email-template list completed: found=${items.length}`);
19857
19909
  }
19858
19910
 
19859
19911
 
@@ -19929,7 +19981,7 @@ async function objectDevFieldPushCommand(options) {
19929
19981
 
19930
19982
  Object.defineProperty(exports, "__esModule", ({ value: true }));
19931
19983
  exports.objectDevConvertRuleListCommand = exports.objectDevObjectMappingPushCommand = exports.objectDevObjectMappingUpdateCommand = exports.objectDevObjectMappingCreateCommand = exports.objectDevObjectMappingPullCommand = exports.objectDevButtonPushCommand = exports.objectDevButtonUpdateCommand = exports.objectDevButtonCreateCommand = exports.objectDevButtonPullCommand = exports.objectDevButtonListCommand = exports.objectDevValidateRuleUpdateCommand = exports.objectDevValidateRulePushCommand = exports.objectDevValidateRulePullCommand = exports.objectDevValidateRuleListCommand = exports.objectDevValidateRuleCreateCommand = exports.objectDevLayoutRuleUpdateCommand = exports.objectDevLayoutRulePushCommand = exports.objectDevLayoutRulePullCommand = exports.objectDevLayoutRuleListCommand = exports.objectDevLayoutRuleCreateCommand = exports.objectDevLayoutUpdateCommand = exports.objectDevLayoutPushCommand = exports.objectDevLayoutPullCommand = exports.objectDevLayoutListCommand = exports.objectDevLayoutEnableEditCommand = exports.objectDevLayoutEditStatusCommand = exports.objectDevLayoutCreateCommand = exports.objectDevFieldPushCommand = exports.objectDevFieldUpdateCommand = exports.objectDevFieldCreateCommand = exports.objectDevFieldListCommand = exports.objectDevObjectPushCommand = exports.objectDevObjectUpdateCommand = exports.objectDevObjectCreateCommand = exports.objectDevSceneUpdateCommand = exports.objectDevScenePushCommand = exports.objectDevScenePullCommand = exports.objectDevSceneListCommand = exports.objectDevSceneCreateCommand = exports.objectDevOptionSetUpdateCommand = exports.objectDevOptionSetPushCommand = exports.objectDevOptionSetPullCommand = exports.objectDevOptionSetListCommand = exports.objectDevOptionSetDeleteCommand = exports.objectDevOptionSetCreateCommand = exports.objectDevObjectRelatedPullCommand = exports.ObjectDevObjectPullOptions = exports.ObjectDevObjectListOptions = exports.objectDevObjectPullCommand = exports.objectDevObjectListCommand = void 0;
19932
- exports.objectDevConvertRulePushCommand = exports.objectDevConvertRuleUpdateCommand = exports.objectDevConvertRuleCreateCommand = exports.objectDevConvertRulePullCommand = void 0;
19984
+ exports.objectDevEmailTemplateListCommand = exports.objectDevConvertRulePushCommand = exports.objectDevConvertRuleUpdateCommand = exports.objectDevConvertRuleCreateCommand = exports.objectDevConvertRulePullCommand = void 0;
19933
19985
  var object_ts_1 = __webpack_require__(1268);
19934
19986
  Object.defineProperty(exports, "objectDevObjectListCommand", ({ enumerable: true, get: function () { return object_ts_1.objectDevObjectListCommand; } }));
19935
19987
  Object.defineProperty(exports, "objectDevObjectPullCommand", ({ enumerable: true, get: function () { return object_ts_1.objectDevObjectPullCommand; } }));
@@ -19996,6 +20048,8 @@ Object.defineProperty(exports, "objectDevConvertRulePullCommand", ({ enumerable:
19996
20048
  Object.defineProperty(exports, "objectDevConvertRuleCreateCommand", ({ enumerable: true, get: function () { return convert_rule_ts_1.objectDevConvertRuleCreateCommand; } }));
19997
20049
  Object.defineProperty(exports, "objectDevConvertRuleUpdateCommand", ({ enumerable: true, get: function () { return convert_rule_ts_1.objectDevConvertRuleUpdateCommand; } }));
19998
20050
  Object.defineProperty(exports, "objectDevConvertRulePushCommand", ({ enumerable: true, get: function () { return convert_rule_ts_1.objectDevConvertRulePushCommand; } }));
20051
+ var email_template_ts_1 = __webpack_require__(1026);
20052
+ Object.defineProperty(exports, "objectDevEmailTemplateListCommand", ({ enumerable: true, get: function () { return email_template_ts_1.objectDevEmailTemplateListCommand; } }));
19999
20053
 
20000
20054
 
20001
20055
  /***/ },
@@ -20260,10 +20314,15 @@ async function objectDevObjectMappingPullCommand(options) {
20260
20314
  throw new Error('Command cancelled.');
20261
20315
  }
20262
20316
  }
20263
- const { objectApiNames, found, written, skipped, errorMessages } = await (0, index_ts_1.objectMappingPullService)(options.objectApiNames, options.force === true, options.skipOverwriteConfirm === true);
20317
+ const { found, written, skipped, errorMessages } = await (0, index_ts_1.objectMappingPullService)({
20318
+ status: options.status ? Number(options.status) : undefined,
20319
+ ruleName: options.ruleName,
20320
+ force: options.force === true,
20321
+ skipOverwriteConfirm: options.skipOverwriteConfirm === true,
20322
+ });
20264
20323
  if (printErrorMessages(errorMessages))
20265
20324
  return;
20266
- logger_ts_1.loggerService.success(`Object-mapping pull completed: objects=${objectApiNames.length}, found=${found}, written=${written}, skipped=${skipped}`);
20325
+ logger_ts_1.loggerService.success(`Object-mapping pull completed: found=${found}, written=${written}, skipped=${skipped}`);
20267
20326
  }
20268
20327
  async function objectDevObjectMappingCreateCommand(options) {
20269
20328
  const result = await (0, index_ts_1.objectMappingCreateService)(options.objectApiName, options.data, options.force === true);
@@ -20276,7 +20335,7 @@ async function objectDevObjectMappingCreateCommand(options) {
20276
20335
  logger_ts_1.loggerService.info(`Object-mapping metadata created: ${result.filePath}`);
20277
20336
  }
20278
20337
  async function objectDevObjectMappingUpdateCommand(options) {
20279
- const result = await (0, index_ts_1.objectMappingUpdateService)(options.objectApiName, options.data);
20338
+ const result = await (0, index_ts_1.objectMappingUpdateService)(options.data);
20280
20339
  if (!result.filePath) {
20281
20340
  throw new Error('Object-mapping metadata not updated.');
20282
20341
  }
@@ -20286,10 +20345,10 @@ async function objectDevObjectMappingUpdateCommand(options) {
20286
20345
  logger_ts_1.loggerService.info(`Object-mapping metadata updated: ${result.filePath}`);
20287
20346
  }
20288
20347
  async function objectDevObjectMappingPushCommand(options) {
20289
- const pushed = await (0, index_ts_1.objectMappingPushService)(options.objectApiName, options.ruleApiNames, options.skipOverwriteConfirm === true);
20348
+ const pushed = await (0, index_ts_1.objectMappingPushService)(options.ruleApiNames, options.skipOverwriteConfirm === true);
20290
20349
  if (printErrorMessages(pushed.errorMessages))
20291
20350
  return;
20292
- logger_ts_1.loggerService.success(`Push completed successfully: object-mapping (${pushed.objectApiName}.${pushed.apiName})`);
20351
+ logger_ts_1.loggerService.success(`Push completed successfully: object-mapping (${pushed.apiName})`);
20293
20352
  }
20294
20353
 
20295
20354
 
@@ -20695,6 +20754,7 @@ exports.buttonCreateService = void 0;
20695
20754
  const normalize_ts_1 = __importDefault(__webpack_require__(9268));
20696
20755
  const index_ts_1 = __webpack_require__(9985);
20697
20756
  const button_service_ts_1 = __webpack_require__(7580);
20757
+ const button_metadata_ts_1 = __webpack_require__(3506);
20698
20758
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
20699
20759
  const buttonCreateService = async (objectApiName, data, force) => {
20700
20760
  // Validate objectApiName
@@ -20707,18 +20767,11 @@ const buttonCreateService = async (objectApiName, data, force) => {
20707
20767
  if (!raw) {
20708
20768
  throw new Error('Invalid arguments: data is required.');
20709
20769
  }
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
- }
20770
+ const buttonContent = (0, button_metadata_ts_1.assertCompleteButtonMetaContent)(JSON.parse(raw), checkedObjectApiName);
20771
+ const buttonApiName = (0, button_metadata_ts_1.getButtonApiName)(buttonContent);
20719
20772
  // Check remote existence: error if button already exists remotely
20720
20773
  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)) {
20774
+ if (remoteButtons.some((item) => (0, button_metadata_ts_1.getButtonApiName)(item) === buttonApiName)) {
20722
20775
  throw new Error('Button already exists remotely: ' + checkedObjectApiName + '.' + buttonApiName);
20723
20776
  }
20724
20777
  // Check if local file already exists
@@ -20732,7 +20785,7 @@ const buttonCreateService = async (objectApiName, data, force) => {
20732
20785
  }
20733
20786
  }
20734
20787
  // Write local Button XML, mark as new
20735
- const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, buttonData, {
20788
+ const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, buttonContent, {
20736
20789
  objectApiName: checkedObjectApiName,
20737
20790
  status: 'new',
20738
20791
  });
@@ -20780,14 +20833,17 @@ const buttonListService = async (objectApiName, buttonApiNamesRaw) => {
20780
20833
  errorMessages.push(`${checkedObjectApiName}: ${error instanceof Error ? error.message : String(error)}`);
20781
20834
  return { objectApiName: checkedObjectApiName, buttons: [], found: 0, errorMessages };
20782
20835
  }
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);
20836
+ const buttonItems = buttons.map((item) => {
20837
+ const button = item.button;
20838
+ return {
20839
+ apiName: normalize_ts_1.default.normalizeText(button.api_name),
20840
+ label: normalize_ts_1.default.normalizeText(button.label),
20841
+ buttonType: normalize_ts_1.default.normalizeText(button.button_type),
20842
+ usePages: Array.isArray(button.use_pages) ? button.use_pages.join(', ') : normalize_ts_1.default.normalizeText(button.use_pages),
20843
+ isActive: normalize_ts_1.default.normalizeText(button.is_active),
20844
+ content: item,
20845
+ };
20846
+ }).filter((item) => item.apiName);
20791
20847
  return {
20792
20848
  objectApiName: checkedObjectApiName,
20793
20849
  buttons: buttonItems,
@@ -20798,6 +20854,222 @@ const buttonListService = async (objectApiName, buttonApiNamesRaw) => {
20798
20854
  exports.buttonListService = buttonListService;
20799
20855
 
20800
20856
 
20857
+ /***/ },
20858
+
20859
+ /***/ 3506
20860
+ (__unused_webpack_module, exports, __webpack_require__) {
20861
+
20862
+
20863
+ var __importDefault = (this && this.__importDefault) || function (mod) {
20864
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20865
+ };
20866
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20867
+ exports.normalizePulledButtonMetaContent = normalizePulledButtonMetaContent;
20868
+ exports.assertCompleteButtonMetaContent = assertCompleteButtonMetaContent;
20869
+ exports.getButtonApiName = getButtonApiName;
20870
+ exports.toButtonExecutePayload = toButtonExecutePayload;
20871
+ const normalize_ts_1 = __importDefault(__webpack_require__(9268));
20872
+ function normalizePulledButtonMetaContent(record, objectApiName) {
20873
+ const button = normalize_ts_1.default.isRecord(record.button) ? record.button : pickFlatButtonRecord(record);
20874
+ const content = {
20875
+ button: {
20876
+ ...button,
20877
+ describe_api_name: normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(button.describe_api_name)) ?? objectApiName,
20878
+ },
20879
+ post_actions: readRecordArray(record.post_actions, 'post_actions', true),
20880
+ roles: readArray(record.roles, 'roles', true),
20881
+ ignore_default_role: readBoolean(record.ignore_default_role, 'ignore_default_role', true) ?? false,
20882
+ i18nInfoList: readRecordArray(record.i18nInfoList, 'i18nInfoList', true),
20883
+ handler_list: readRecordArray(record.handler_list, 'handler_list', true),
20884
+ sourceInfo: normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(record.sourceInfo)),
20885
+ };
20886
+ assertButtonMetaContent(content, objectApiName, { requireComplete: false });
20887
+ return content;
20888
+ }
20889
+ function pickFlatButtonRecord(record) {
20890
+ const { post_actions: _postActions, roles: _roles, ignore_default_role: _ignoreDefaultRole, i18nInfoList: _i18nInfoList, handler_list: _handlerList, sourceInfo: _sourceInfo, button_config: _buttonConfig, ...button } = record;
20891
+ void _postActions;
20892
+ void _roles;
20893
+ void _ignoreDefaultRole;
20894
+ void _i18nInfoList;
20895
+ void _handlerList;
20896
+ void _sourceInfo;
20897
+ void _buttonConfig;
20898
+ return button;
20899
+ }
20900
+ function assertCompleteButtonMetaContent(input, objectApiName) {
20901
+ return assertButtonMetaContent(input, objectApiName, { requireComplete: true });
20902
+ }
20903
+ function getButtonApiName(content) {
20904
+ const buttonApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.api_name));
20905
+ if (!buttonApiName) {
20906
+ throw new Error('button.button.api_name is required.');
20907
+ }
20908
+ return buttonApiName;
20909
+ }
20910
+ function toButtonExecutePayload(content, options) {
20911
+ const buttonPayload = {
20912
+ ...content.button,
20913
+ api_name: options.buttonApiName,
20914
+ describe_api_name: options.objectApiName,
20915
+ };
20916
+ const payload = {
20917
+ button: JSON.stringify(buttonPayload),
20918
+ post_actions: content.post_actions,
20919
+ roles: content.roles,
20920
+ i18nInfoList: content.i18nInfoList,
20921
+ };
20922
+ if (options.isCreate) {
20923
+ payload.ignore_default_role = content.ignore_default_role;
20924
+ }
20925
+ else {
20926
+ payload.handler_list = content.handler_list ?? [];
20927
+ payload.sourceInfo = content.sourceInfo ?? 'object_management';
20928
+ }
20929
+ return payload;
20930
+ }
20931
+ function assertButtonMetaContent(input, objectApiName, options) {
20932
+ if (!normalize_ts_1.default.isRecord(input)) {
20933
+ throw new Error('button content must be a JSON object.');
20934
+ }
20935
+ if (!normalize_ts_1.default.isRecord(input.button)) {
20936
+ throw new Error('button content must include button object.');
20937
+ }
20938
+ const button = { ...input.button };
20939
+ const buttonApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(button.api_name));
20940
+ if (!buttonApiName) {
20941
+ throw new Error('button.button.api_name is required.');
20942
+ }
20943
+ const describeApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(button.describe_api_name));
20944
+ if (!describeApiName) {
20945
+ if (options.requireComplete) {
20946
+ throw new Error('button.button.describe_api_name is required.');
20947
+ }
20948
+ button.describe_api_name = objectApiName;
20949
+ }
20950
+ else if (describeApiName !== objectApiName) {
20951
+ throw new Error('button.button.describe_api_name must be ' + objectApiName + '.');
20952
+ }
20953
+ requireString(button.label, 'button.button.label', options.requireComplete);
20954
+ requireString(button.button_type, 'button.button_type', options.requireComplete);
20955
+ const usePages = readStringArray(button.use_pages, 'button.use_pages', !options.requireComplete);
20956
+ if (options.requireComplete && usePages.length === 0) {
20957
+ throw new Error('button.use_pages must be a non-empty string array.');
20958
+ }
20959
+ button.use_pages = usePages;
20960
+ button.wheres = readRecordArray(button.wheres, 'button.wheres', !options.requireComplete);
20961
+ button.param_form = readRecordArray(button.param_form, 'button.param_form', !options.requireComplete);
20962
+ button.actions = readStringArray(button.actions, 'button.actions', !options.requireComplete);
20963
+ const postActions = readRecordArray(input.post_actions, 'post_actions', !options.requireComplete);
20964
+ const roles = readArray(input.roles, 'roles', !options.requireComplete);
20965
+ const ignoreDefaultRole = readBoolean(input.ignore_default_role, 'ignore_default_role', !options.requireComplete);
20966
+ const i18nInfoList = readRecordArray(input.i18nInfoList, 'i18nInfoList', !options.requireComplete);
20967
+ const handlerList = readRecordArray(input.handler_list, 'handler_list', true);
20968
+ const sourceInfo = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(input.sourceInfo));
20969
+ if (options.requireComplete && i18nInfoList.length === 0) {
20970
+ throw new Error('i18nInfoList must be a non-empty array.');
20971
+ }
20972
+ const content = {
20973
+ button,
20974
+ post_actions: postActions,
20975
+ roles,
20976
+ ignore_default_role: ignoreDefaultRole ?? false,
20977
+ i18nInfoList,
20978
+ handler_list: handlerList,
20979
+ sourceInfo,
20980
+ };
20981
+ assertButtonTypeRules(content);
20982
+ return content;
20983
+ }
20984
+ function requireString(value, fieldName, required) {
20985
+ if (!required && value === undefined) {
20986
+ return;
20987
+ }
20988
+ if (!normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(value))) {
20989
+ throw new Error(fieldName + ' is required.');
20990
+ }
20991
+ }
20992
+ function readBoolean(value, fieldName, optional) {
20993
+ if (value === undefined || value === null) {
20994
+ if (optional) {
20995
+ return undefined;
20996
+ }
20997
+ throw new Error(fieldName + ' is required.');
20998
+ }
20999
+ if (typeof value !== 'boolean') {
21000
+ throw new Error(fieldName + ' must be a boolean.');
21001
+ }
21002
+ return value;
21003
+ }
21004
+ function readRecordArray(value, fieldName, optional) {
21005
+ if (value === undefined || value === null) {
21006
+ if (optional) {
21007
+ return [];
21008
+ }
21009
+ throw new Error(fieldName + ' is required.');
21010
+ }
21011
+ if (!Array.isArray(value)) {
21012
+ throw new Error(fieldName + ' must be an array.');
21013
+ }
21014
+ return value.map((item, index) => {
21015
+ if (!normalize_ts_1.default.isRecord(item)) {
21016
+ throw new Error(fieldName + '[' + index + '] must be an object.');
21017
+ }
21018
+ return item;
21019
+ });
21020
+ }
21021
+ function readArray(value, fieldName, optional) {
21022
+ if (value === undefined || value === null) {
21023
+ if (optional) {
21024
+ return [];
21025
+ }
21026
+ throw new Error(fieldName + ' is required.');
21027
+ }
21028
+ if (!Array.isArray(value)) {
21029
+ throw new Error(fieldName + ' must be an array.');
21030
+ }
21031
+ return value;
21032
+ }
21033
+ function readStringArray(value, fieldName, optional) {
21034
+ if (value === undefined || value === null) {
21035
+ if (optional) {
21036
+ return [];
21037
+ }
21038
+ throw new Error(fieldName + ' is required.');
21039
+ }
21040
+ if (!Array.isArray(value)) {
21041
+ throw new Error(fieldName + ' must be an array.');
21042
+ }
21043
+ return value.map((item, index) => {
21044
+ const text = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(item));
21045
+ if (!text) {
21046
+ throw new Error(fieldName + '[' + index + '] must be a non-empty string.');
21047
+ }
21048
+ return text;
21049
+ });
21050
+ }
21051
+ function assertButtonTypeRules(content) {
21052
+ const buttonType = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.button_type));
21053
+ const redirectType = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.redirect_type));
21054
+ const jumpUrl = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(content.button.jump_url));
21055
+ const paramForm = Array.isArray(content.button.param_form) ? content.button.param_form : [];
21056
+ const actions = Array.isArray(content.button.actions) ? content.button.actions : [];
21057
+ if (redirectType) {
21058
+ if (!jumpUrl) {
21059
+ throw new Error('button.jump_url is required when button.redirect_type is set.');
21060
+ }
21061
+ if (actions.length > 0 || content.post_actions.length > 0) {
21062
+ throw new Error('redirect button cannot include button.actions or post_actions.');
21063
+ }
21064
+ }
21065
+ if (buttonType === 'mapping') {
21066
+ if (paramForm.length > 0 || actions.length > 0 || content.post_actions.length > 0) {
21067
+ throw new Error('mapping button cannot include button.param_form, button.actions or post_actions.');
21068
+ }
21069
+ }
21070
+ }
21071
+
21072
+
20801
21073
  /***/ },
20802
21074
 
20803
21075
  /***/ 6884
@@ -20813,6 +21085,7 @@ const normalize_ts_1 = __importDefault(__webpack_require__(9268));
20813
21085
  const logger_ts_1 = __webpack_require__(3333);
20814
21086
  const index_ts_1 = __webpack_require__(9985);
20815
21087
  const button_service_ts_1 = __webpack_require__(7580);
21088
+ const button_metadata_ts_1 = __webpack_require__(3506);
20816
21089
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
20817
21090
  const buttonPullService = async (objectApiNamesRaw, force = false, skipOverwriteConfirm = false) => {
20818
21091
  const errorMessages = [];
@@ -20837,8 +21110,11 @@ const buttonPullService = async (objectApiNamesRaw, force = false, skipOverwrite
20837
21110
  // Write each button to local XML
20838
21111
  for (const buttonRecord of buttons) {
20839
21112
  // Extract button api_name
20840
- const buttonApiName = normalize_ts_1.default.normalizeString(buttonRecord.api_name);
20841
- if (!buttonApiName) {
21113
+ let buttonApiName;
21114
+ try {
21115
+ buttonApiName = (0, button_metadata_ts_1.getButtonApiName)(buttonRecord);
21116
+ }
21117
+ catch {
20842
21118
  skipped += 1;
20843
21119
  continue;
20844
21120
  }
@@ -20912,6 +21188,7 @@ const button_service_ts_1 = __webpack_require__(7580);
20912
21188
  const button_pull_ts_1 = __webpack_require__(6884);
20913
21189
  const request_ts_1 = __webpack_require__(3176);
20914
21190
  const logger_ts_1 = __webpack_require__(3333);
21191
+ const button_metadata_ts_1 = __webpack_require__(3506);
20915
21192
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
20916
21193
  const isRecord = normalize_ts_1.default.isRecord;
20917
21194
  /**
@@ -20953,7 +21230,7 @@ const buttonPushService = async (objectApiName, buttonApiName, skipOverwriteConf
20953
21230
  let existsRemotely = false;
20954
21231
  try {
20955
21232
  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);
21233
+ existsRemotely = remoteButtons.some((item) => (0, button_metadata_ts_1.getButtonApiName)(item) === checkedButtonApiName);
20957
21234
  }
20958
21235
  finally {
20959
21236
  logger_ts_1.loggerService.stopLoading();
@@ -20983,40 +21260,16 @@ const buttonPushService = async (objectApiName, buttonApiName, skipOverwriteConf
20983
21260
  objectApiName: checkedObjectApiName,
20984
21261
  });
20985
21262
  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);
21263
+ const buttonContent = (0, button_metadata_ts_1.assertCompleteButtonMetaContent)(correctedMeta.content && isRecord(correctedMeta.content)
21264
+ ? correctedMeta.content
21265
+ : buttonMeta.content, checkedObjectApiName);
20999
21266
  // Build payload and call create/update
21000
21267
  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
- ];
21268
+ const payload = (0, button_metadata_ts_1.toButtonExecutePayload)(buttonContent, {
21269
+ objectApiName: checkedObjectApiName,
21270
+ buttonApiName: checkedButtonApiName,
21271
+ isCreate,
21272
+ });
21020
21273
  const raw = await (0, request_ts_1.requestObjectDevExecute)(isCreate
21021
21274
  ? (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('button', 'create')
21022
21275
  : (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('button', 'update'), payload);
@@ -21072,8 +21325,9 @@ exports.fetchButtonList = void 0;
21072
21325
  const request_execute_command_paths_ts_1 = __webpack_require__(2351);
21073
21326
  const request_ts_1 = __webpack_require__(3176);
21074
21327
  const types_ts_1 = __webpack_require__(7480);
21328
+ const button_metadata_ts_1 = __webpack_require__(3506);
21075
21329
  /**
21076
- * 共享:调 list 接口获取单个对象下全部按钮(或指定按钮),返回解析后的 button 数组
21330
+ * 共享:调 list 接口获取单个对象下全部按钮(或指定按钮),返回本地 ObjectButton XML content 结构
21077
21331
  */
21078
21332
  const fetchButtonList = async (objectApiName, buttonApiNames) => {
21079
21333
  const response = await (0, request_ts_1.requestObjectDevExecute)((0, request_execute_command_paths_ts_1.getShareCliCommandPath)('button', 'list'), {
@@ -21091,14 +21345,11 @@ const fetchButtonList = async (objectApiName, buttonApiNames) => {
21091
21345
  throw new Error(result.errorMessage);
21092
21346
  }
21093
21347
  const buttons = result.data ?? [];
21094
- // 提取 item.button:响应结构为 [{ button: {...}, button_config: {...}, ... }, ...]
21348
+ // 响应结构为 [{ button, post_actions, roles, i18nInfoList, button_config, ... }]
21349
+ // 本地 XML 只保存完整 button metadata content,不把 button_config 混入 content.button。
21095
21350
  return buttons
21096
21351
  .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
- });
21352
+ .map((item) => (0, button_metadata_ts_1.normalizePulledButtonMetaContent)(item, objectApiName));
21102
21353
  };
21103
21354
  exports.fetchButtonList = fetchButtonList;
21104
21355
 
@@ -21116,6 +21367,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
21116
21367
  exports.buttonUpdateService = void 0;
21117
21368
  const normalize_ts_1 = __importDefault(__webpack_require__(9268));
21118
21369
  const index_ts_1 = __webpack_require__(9985);
21370
+ const button_metadata_ts_1 = __webpack_require__(3506);
21119
21371
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
21120
21372
  const buttonUpdateService = async (objectApiName, data) => {
21121
21373
  const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
@@ -21126,32 +21378,17 @@ const buttonUpdateService = async (objectApiName, data) => {
21126
21378
  if (!raw) {
21127
21379
  throw new Error('Invalid arguments: data is required.');
21128
21380
  }
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
21381
+ const buttonContent = (0, button_metadata_ts_1.assertCompleteButtonMetaContent)(JSON.parse(raw), checkedObjectApiName);
21382
+ const buttonApiName = (0, button_metadata_ts_1.getButtonApiName)(buttonContent);
21138
21383
  const existing = await xmlMetadataManager.readXml('ObjectButton', buttonApiName, {
21139
21384
  objectApiName: checkedObjectApiName,
21140
21385
  fields: ['content', 'status'],
21141
21386
  });
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];
21387
+ if (existing.content === null || existing.content === undefined) {
21388
+ throw new Error('Button does not exist locally: ' + checkedObjectApiName + '.' + buttonApiName);
21152
21389
  }
21153
21390
  const nextStatus = existing.status === 'new' ? 'new' : 'modified';
21154
- const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, mergedData, {
21391
+ const filePath = await xmlMetadataManager.writeXml('ObjectButton', buttonApiName, buttonContent, {
21155
21392
  objectApiName: checkedObjectApiName,
21156
21393
  status: nextStatus,
21157
21394
  });
@@ -21178,11 +21415,7 @@ const normalize_ts_1 = __importDefault(__webpack_require__(9268));
21178
21415
  const index_ts_1 = __webpack_require__(9985);
21179
21416
  const convert_rule_list_ts_1 = __webpack_require__(8031);
21180
21417
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
21181
- const convertRuleCreateService = async (objectApiName, data, force) => {
21182
- const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
21183
- if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
21184
- throw new Error('Invalid arguments: objectApiName is required.');
21185
- }
21418
+ const convertRuleCreateService = async (data, force) => {
21186
21419
  const raw = normalize_ts_1.default.normalizeString(data);
21187
21420
  if (!raw) {
21188
21421
  throw new Error('Invalid arguments: data is required.');
@@ -21191,35 +21424,52 @@ const convertRuleCreateService = async (objectApiName, data, force) => {
21191
21424
  if (!ruleData || typeof ruleData !== 'object' || Array.isArray(ruleData)) {
21192
21425
  throw new Error('data must be a JSON object.');
21193
21426
  }
21194
- const ruleApiName = normalize_ts_1.default.normalizeString(ruleData.api_name) ?? normalize_ts_1.default.normalizeString(ruleData.apiName);
21427
+ // 提取 ruleList
21428
+ const ruleList = ruleData.ruleList;
21429
+ if (!ruleList?.length) {
21430
+ throw new Error('data.ruleList is required and must be a non-empty array.');
21431
+ }
21432
+ // 从 ruleList 中找主规则 (master_rule_api_name 为空) 的 rule_api_name 作为文件名
21433
+ const mainRule = ruleList.find((r) => {
21434
+ const master = r.master_rule_api_name;
21435
+ return !master || master === '';
21436
+ }) ?? ruleList[0];
21437
+ const ruleApiName = normalize_ts_1.default.normalizeString(mainRule.rule_api_name)
21438
+ ?? normalize_ts_1.default.normalizeString(mainRule.ruleApiName);
21195
21439
  if (!ruleApiName) {
21196
- throw new Error('data.api_name or data.apiName is required.');
21440
+ throw new Error('Cannot determine rule_api_name from data.ruleList.');
21441
+ }
21442
+ // 远端查重
21443
+ const remoteItems = await (0, convert_rule_list_ts_1.fetchConvertRuleList)();
21444
+ const remoteNameSet = new Set();
21445
+ for (const item of remoteItems) {
21446
+ const ruleList = item.ruleList;
21447
+ if (ruleList) {
21448
+ for (const rule of ruleList) {
21449
+ const name = normalize_ts_1.default.normalizeString(rule.rule_api_name);
21450
+ if (name)
21451
+ remoteNameSet.add(name);
21452
+ }
21453
+ }
21197
21454
  }
21198
- const remoteRules = await (0, convert_rule_list_ts_1.fetchConvertRuleList)(checkedObjectApiName, null);
21199
- if (remoteRules.some((item) => {
21200
- const remoteName = normalize_ts_1.default.normalizeString(item.api_name)
21201
- ?? normalize_ts_1.default.normalizeString(item.apiName);
21202
- return remoteName === ruleApiName;
21203
- })) {
21204
- throw new Error('Convert-rule already exists remotely: ' + checkedObjectApiName + '.' + ruleApiName);
21455
+ if (remoteNameSet.has(ruleApiName)) {
21456
+ throw new Error('Convert-rule already exists remotely: ' + ruleApiName);
21205
21457
  }
21458
+ // 本地查重
21206
21459
  const existing = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21207
- objectApiName: checkedObjectApiName,
21208
21460
  fields: ['content'],
21209
21461
  });
21210
21462
  if (existing.content !== null && existing.content !== undefined) {
21211
21463
  if (!force) {
21212
- throw new Error('Convert-rule already exists locally: ' + checkedObjectApiName + '.' + ruleApiName + '. Use --force to overwrite.');
21464
+ throw new Error('Convert-rule already exists locally: ' + ruleApiName + '. Use --force to overwrite.');
21213
21465
  }
21214
21466
  }
21215
- const filePath = await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, ruleData, {
21216
- objectApiName: checkedObjectApiName,
21217
- status: 'new',
21218
- });
21219
- return {
21220
- filePath,
21221
- errorMessages: [],
21467
+ // 组装内容(对齐 create-rule API 格式)
21468
+ const fullContent = {
21469
+ ruleList: ruleList,
21222
21470
  };
21471
+ const filePath = await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, fullContent, { status: 'new' });
21472
+ return { filePath, errorMessages: [] };
21223
21473
  };
21224
21474
  exports.convertRuleCreateService = convertRuleCreateService;
21225
21475
 
@@ -21235,61 +21485,52 @@ exports.fetchConvertRuleDetailList = exports.fetchConvertRuleList = void 0;
21235
21485
  const request_execute_command_paths_ts_1 = __webpack_require__(2351);
21236
21486
  const request_ts_1 = __webpack_require__(3176);
21237
21487
  const types_ts_1 = __webpack_require__(7480);
21488
+ const SEARCH_QUERY_INFO = JSON.stringify({ offset: 0, limit: 2000 });
21238
21489
  /**
21239
21490
  * 调 list 接口获取转换规则轻量列表
21491
+ * 实际返回结构: { data: { items: [{ ...rule fields... }, ...] } } 或 { data: { ruleList: [...] } }
21240
21492
  */
21241
- const fetchConvertRuleList = async (objectApiName, ruleApiNames) => {
21493
+ const fetchConvertRuleList = async (options = {}) => {
21242
21494
  const response = await (0, request_ts_1.requestObjectDevExecute)((0, request_execute_command_paths_ts_1.getShareCliCommandPath)('convertRule', 'rule-list'), {
21243
- describeApiName: objectApiName,
21244
- ruleApiNames,
21245
- });
21246
- const result = await (0, request_ts_1.extractObjectDevServiceResult)(response, (res) => {
21247
- const data = (0, types_ts_1.narrowObjectDevResponse)(res.data);
21248
- if (!data)
21249
- throw new Error(`Invalid response data for object ${objectApiName}`);
21250
- const list = (0, types_ts_1.narrowObjectDevResponse)(data.convertRuleList)
21251
- ?? (0, types_ts_1.narrowObjectDevResponse)(data.ruleInfoList)
21252
- ?? (0, types_ts_1.narrowObjectDevResponse)(data.list);
21253
- return list ?? [];
21495
+ ruleName: options.ruleName ?? '',
21496
+ searchQueryInfo: SEARCH_QUERY_INFO,
21254
21497
  });
21498
+ const result = await (0, request_ts_1.extractObjectDevServiceResult)(response, (res) => parseContentToArray(res));
21255
21499
  if (!result.success) {
21256
21500
  throw new Error(result.errorMessage);
21257
21501
  }
21258
- return (result.data ?? []).filter((item) => Boolean(item) && typeof item === 'object').map((item) => {
21259
- const record = item;
21260
- const rule = record.rule;
21261
- return (rule && typeof rule === 'object' ? rule : record);
21262
- });
21502
+ return (result.data ?? []);
21263
21503
  };
21264
21504
  exports.fetchConvertRuleList = fetchConvertRuleList;
21265
21505
  /**
21266
21506
  * 调详情列表接口获取转换规则完整详情
21267
21507
  */
21268
- const fetchConvertRuleDetailList = async (objectApiName, ruleApiNames) => {
21508
+ const fetchConvertRuleDetailList = async (options = {}) => {
21269
21509
  const response = await (0, request_ts_1.requestObjectDevExecute)((0, request_execute_command_paths_ts_1.getShareCliCommandPath)('convertRule', 'rule-detail-list'), {
21270
- describeApiName: objectApiName,
21271
- ruleApiNames,
21272
- });
21273
- const result = await (0, request_ts_1.extractObjectDevServiceResult)(response, (res) => {
21274
- const data = (0, types_ts_1.narrowObjectDevResponse)(res.data);
21275
- if (!data)
21276
- throw new Error(`Invalid response data for object ${objectApiName}`);
21277
- const list = (0, types_ts_1.narrowObjectDevResponse)(data.convertRuleList)
21278
- ?? (0, types_ts_1.narrowObjectDevResponse)(data.ruleInfoList)
21279
- ?? (0, types_ts_1.narrowObjectDevResponse)(data.ruleDetailList)
21280
- ?? (0, types_ts_1.narrowObjectDevResponse)(data.list);
21281
- return list ?? [];
21510
+ ruleName: options.ruleName ?? '',
21511
+ searchQueryInfo: SEARCH_QUERY_INFO,
21282
21512
  });
21513
+ const result = await (0, request_ts_1.extractObjectDevServiceResult)(response, (res) => parseContentToArray(res));
21283
21514
  if (!result.success) {
21284
21515
  throw new Error(result.errorMessage);
21285
21516
  }
21286
- return (result.data ?? []).filter((item) => Boolean(item) && typeof item === 'object').map((item) => {
21287
- const record = item;
21288
- const rule = record.rule;
21289
- return (rule && typeof rule === 'object' ? rule : record);
21290
- });
21517
+ return (result.data ?? []);
21291
21518
  };
21292
21519
  exports.fetchConvertRuleDetailList = fetchConvertRuleDetailList;
21520
+ function parseContentToArray(res) {
21521
+ const data = (0, types_ts_1.narrowObjectDevResponse)(res.data);
21522
+ if (!data)
21523
+ throw new Error('Invalid response data');
21524
+ const items = data.items;
21525
+ if (Array.isArray(items)) {
21526
+ return items;
21527
+ }
21528
+ const ruleList = data.ruleList;
21529
+ if (Array.isArray(ruleList)) {
21530
+ return ruleList;
21531
+ }
21532
+ return [];
21533
+ }
21293
21534
 
21294
21535
 
21295
21536
  /***/ },
@@ -21303,74 +21544,77 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
21303
21544
  };
21304
21545
  Object.defineProperty(exports, "__esModule", ({ value: true }));
21305
21546
  exports.convertRulePullService = void 0;
21547
+ const normalize_ts_1 = __importDefault(__webpack_require__(9268));
21306
21548
  const logger_ts_1 = __webpack_require__(3333);
21307
21549
  const index_ts_1 = __webpack_require__(9985);
21308
21550
  const convert_rule_list_ts_1 = __webpack_require__(8031);
21309
- const normalize_ts_1 = __importDefault(__webpack_require__(9268));
21310
21551
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
21311
- const convertRulePullService = async (objectApiNamesRaw, force = false, skipOverwriteConfirm = false) => {
21312
- const errorMessages = [];
21313
- const objectApiNames = (normalize_ts_1.default.normalizeString(objectApiNamesRaw) ?? '')
21314
- .split(',')
21315
- .map((item) => item.trim())
21316
- .filter(Boolean);
21317
- if (!objectApiNames.length) {
21318
- throw new Error('Invalid arguments: objectApiNames is required.');
21552
+ /**
21553
+ * item.ruleList 中找到主规则的 rule_api_name 作为文件名
21554
+ * 主规则: master_rule_api_name 为空字符串或 null/undefined
21555
+ */
21556
+ function resolveItemApiName(item) {
21557
+ const ruleList = item.ruleList;
21558
+ if (ruleList?.length) {
21559
+ const mainRule = ruleList.find((r) => {
21560
+ const master = r.master_rule_api_name;
21561
+ return !master || master === '';
21562
+ });
21563
+ if (mainRule) {
21564
+ return normalize_ts_1.default.normalizeString(mainRule.rule_api_name);
21565
+ }
21566
+ return normalize_ts_1.default.normalizeString(ruleList[0].rule_api_name);
21319
21567
  }
21568
+ return undefined;
21569
+ }
21570
+ const convertRulePullService = async (options = {}) => {
21571
+ const errorMessages = [];
21572
+ const force = options.force === true;
21573
+ const skipOverwriteConfirm = options.skipOverwriteConfirm === true;
21574
+ const items = await (0, convert_rule_list_ts_1.fetchConvertRuleDetailList)({
21575
+ ruleName: options.ruleName,
21576
+ });
21320
21577
  let written = 0;
21321
21578
  let skipped = 0;
21322
- let found = 0;
21323
- for (const objectApiName of objectApiNames) {
21579
+ const found = items.length;
21580
+ for (const item of items) {
21581
+ const ruleApiName = resolveItemApiName(item);
21582
+ if (!ruleApiName) {
21583
+ skipped += 1;
21584
+ continue;
21585
+ }
21324
21586
  try {
21325
- const rules = await (0, convert_rule_list_ts_1.fetchConvertRuleDetailList)(objectApiName, null);
21326
- found += rules.length;
21327
- for (const ruleRecord of rules) {
21328
- const ruleApiName = normalize_ts_1.default.normalizeString(ruleRecord.api_name)
21329
- ?? normalize_ts_1.default.normalizeString(ruleRecord.apiName);
21330
- if (!ruleApiName) {
21331
- skipped += 1;
21332
- continue;
21333
- }
21334
- try {
21335
- if (force) {
21336
- await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, ruleRecord, {
21337
- objectApiName,
21338
- status: 'unchanged',
21339
- });
21340
- written += 1;
21341
- continue;
21342
- }
21343
- const localStatus = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21344
- objectApiName,
21345
- fields: ['status'],
21346
- });
21347
- if (localStatus.status !== 'unchanged') {
21348
- if (skipOverwriteConfirm) {
21349
- logger_ts_1.loggerService.info(`Skipped ${objectApiName}.${ruleApiName}: local status is ${localStatus.status}. Use --force to overwrite local metadata.`);
21350
- }
21351
- else {
21352
- logger_ts_1.loggerService.info(`Convert-rule local status ${localStatus.status}, skip overwrite: ${objectApiName}.${ruleApiName}. Use --force to overwrite local metadata.`);
21353
- }
21354
- skipped += 1;
21355
- continue;
21356
- }
21357
- await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, ruleRecord, {
21358
- objectApiName,
21359
- status: 'unchanged',
21360
- });
21361
- written += 1;
21587
+ if (force) {
21588
+ await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, item, {
21589
+ status: 'unchanged',
21590
+ });
21591
+ written += 1;
21592
+ continue;
21593
+ }
21594
+ const localStatus = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21595
+ fields: ['status'],
21596
+ });
21597
+ if (localStatus.status !== 'unchanged') {
21598
+ if (skipOverwriteConfirm) {
21599
+ logger_ts_1.loggerService.info(`Skipped ${ruleApiName}: local status is ${localStatus.status}. Use --force to overwrite local metadata.`);
21362
21600
  }
21363
- catch (error) {
21364
- errorMessages.push(objectApiName + ' convert-rule ' + ruleApiName + ': ' + (error instanceof Error ? error.message : String(error)));
21601
+ else {
21602
+ logger_ts_1.loggerService.info(`Convert-rule local status ${localStatus.status}, skip overwrite: ${ruleApiName}. Use --force to overwrite local metadata.`);
21365
21603
  }
21604
+ skipped += 1;
21605
+ continue;
21366
21606
  }
21607
+ await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, item, {
21608
+ status: 'unchanged',
21609
+ });
21610
+ written += 1;
21367
21611
  }
21368
21612
  catch (error) {
21369
- errorMessages.push(objectApiName + ': ' + (error instanceof Error ? error.message : String(error)));
21613
+ errorMessages.push('convert-rule ' + ruleApiName + ': ' + (error instanceof Error ? error.message : String(error)));
21370
21614
  }
21371
21615
  }
21372
21616
  return {
21373
- objectApiNames,
21617
+ objectApiNames: [],
21374
21618
  found,
21375
21619
  written,
21376
21620
  skipped,
@@ -21400,12 +21644,8 @@ const request_ts_1 = __webpack_require__(3176);
21400
21644
  const logger_ts_1 = __webpack_require__(3333);
21401
21645
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
21402
21646
  const isRecord = normalize_ts_1.default.isRecord;
21403
- const convertRulePushService = async (objectApiName, ruleApiNames, skipOverwriteConfirm = false) => {
21647
+ const convertRulePushService = async (ruleApiNames, skipOverwriteConfirm = false) => {
21404
21648
  const errorMessages = [];
21405
- const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
21406
- if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
21407
- throw new Error('Invalid arguments: objectApiName is required.');
21408
- }
21409
21649
  const targetRuleApiNames = (ruleApiNames ?? '')
21410
21650
  .split(',')
21411
21651
  .map((item) => normalize_ts_1.default.normalizeString(item))
@@ -21415,109 +21655,99 @@ const convertRulePushService = async (objectApiName, ruleApiNames, skipOverwrite
21415
21655
  }
21416
21656
  for (const ruleApiName of targetRuleApiNames) {
21417
21657
  try {
21418
- let ruleMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21419
- objectApiName: checkedObjectApiName,
21420
- });
21658
+ let ruleMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName);
21421
21659
  if (!ruleMeta.content || !isRecord(ruleMeta.content)) {
21422
- throw new Error(`Invalid convert-rule content: ${checkedObjectApiName}.${ruleApiName}`);
21660
+ throw new Error(`Invalid convert-rule content: ${ruleApiName}`);
21423
21661
  }
21662
+ const content = ruleMeta.content;
21424
21663
  // pre-pull for non-new rules
21425
21664
  if (ruleMeta.status !== 'new') {
21426
- logger_ts_1.loggerService.startLoading('convert-rule push pre-pull: ' + checkedObjectApiName + '.' + ruleApiName);
21665
+ logger_ts_1.loggerService.startLoading('convert-rule push pre-pull: ' + ruleApiName);
21427
21666
  try {
21428
- const prePullResult = await (0, convert_rule_pull_ts_1.convertRulePullService)(checkedObjectApiName, false, skipOverwriteConfirm);
21667
+ const prePullResult = await (0, convert_rule_pull_ts_1.convertRulePullService)({
21668
+ skipOverwriteConfirm,
21669
+ });
21429
21670
  errorMessages.push(...prePullResult.errorMessages);
21430
21671
  }
21431
21672
  finally {
21432
21673
  logger_ts_1.loggerService.stopLoading();
21433
21674
  }
21434
21675
  }
21435
- // Check remote existence via rule-detail-list
21436
- logger_ts_1.loggerService.startLoading('convert-rule push check remote: ' + checkedObjectApiName + '.' + ruleApiName);
21676
+ // 远端存在性检查
21677
+ logger_ts_1.loggerService.startLoading('convert-rule push check remote: ' + ruleApiName);
21437
21678
  let existsRemotely = false;
21438
21679
  try {
21439
- const remoteRules = await (0, convert_rule_list_ts_1.fetchConvertRuleDetailList)(checkedObjectApiName, null);
21680
+ const remoteRules = await (0, convert_rule_list_ts_1.fetchConvertRuleDetailList)();
21440
21681
  existsRemotely = remoteRules.some((item) => {
21441
- const remoteName = normalize_ts_1.default.normalizeString(item.api_name)
21442
- ?? normalize_ts_1.default.normalizeString(item.apiName);
21443
- return remoteName === ruleApiName;
21682
+ const ruleList = item.ruleList;
21683
+ return ruleList?.some((rule) => {
21684
+ const remoteName = normalize_ts_1.default.normalizeString(rule.rule_api_name);
21685
+ return remoteName === ruleApiName;
21686
+ }) ?? false;
21444
21687
  });
21445
21688
  }
21446
21689
  finally {
21447
21690
  logger_ts_1.loggerService.stopLoading();
21448
21691
  }
21449
- // Fix local status based on remote
21692
+ // 状态修正
21450
21693
  if (ruleMeta.status === 'new' && existsRemotely) {
21451
- await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, ruleMeta.content, {
21452
- objectApiName: checkedObjectApiName,
21694
+ await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, content, {
21453
21695
  status: 'modified',
21454
21696
  features: ruleMeta.features,
21455
21697
  extra: ruleMeta.extra,
21456
21698
  });
21457
- logger_ts_1.loggerService.warn('Convert-rule exists remotely, local status changed from new to modified: ' + checkedObjectApiName + '.' + ruleApiName);
21458
- ruleMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21459
- objectApiName: checkedObjectApiName,
21460
- });
21699
+ logger_ts_1.loggerService.warn('Convert-rule exists remotely, local status changed from new to modified: ' + ruleApiName);
21700
+ ruleMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName);
21461
21701
  }
21462
21702
  if (ruleMeta.status !== 'new' && !existsRemotely) {
21463
- await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, ruleMeta.content, {
21464
- objectApiName: checkedObjectApiName,
21703
+ await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, content, {
21465
21704
  status: 'new',
21466
21705
  features: ruleMeta.features,
21467
21706
  extra: ruleMeta.extra,
21468
21707
  });
21469
- logger_ts_1.loggerService.warn('Convert-rule does not exist remotely, local status changed from ' + ruleMeta.status + ' to new: ' + checkedObjectApiName + '.' + ruleApiName);
21470
- ruleMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21471
- objectApiName: checkedObjectApiName,
21472
- });
21708
+ logger_ts_1.loggerService.warn('Convert-rule does not exist remotely, local status changed from ' + ruleMeta.status + ' to new: ' + ruleApiName);
21709
+ ruleMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName);
21473
21710
  }
21474
21711
  const isCreate = ruleMeta.status === 'new';
21475
- const ruleContent = { ...(ruleMeta.content && isRecord(ruleMeta.content)
21712
+ const updatedContent = { ...(ruleMeta.content && isRecord(ruleMeta.content)
21476
21713
  ? ruleMeta.content
21477
- : {}) };
21478
- if (!ruleContent.describe_api_name) {
21479
- ruleContent.describe_api_name = checkedObjectApiName;
21480
- }
21481
- if (!ruleContent.api_name) {
21482
- ruleContent.api_name = ruleApiName;
21483
- }
21484
- logger_ts_1.loggerService.startLoading('convert-rule push request: ' + checkedObjectApiName + '.' + ruleApiName + ' (' + (isCreate ? 'create' : 'update') + ')');
21714
+ : content) };
21715
+ logger_ts_1.loggerService.startLoading('convert-rule push request: ' + ruleApiName + ' (' + (isCreate ? 'create' : 'update') + ')');
21485
21716
  const raw = await (0, request_ts_1.requestObjectDevExecute)(isCreate
21486
21717
  ? (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('convertRule', 'create-rule')
21487
- : (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('convertRule', 'update-rule'), ruleContent);
21718
+ : (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('convertRule', 'update-rule'), updatedContent);
21488
21719
  const response = raw;
21489
21720
  if (response.success !== true || normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(response.code)) !== 'OK') {
21490
21721
  logger_ts_1.loggerService.stopLoading();
21491
21722
  throw new Error('convert-rule push failed: ' + (normalize_ts_1.default.normalizeText(response.message) || 'Unknown error'));
21492
21723
  }
21493
21724
  logger_ts_1.loggerService.stopLoading();
21494
- // Write back status
21495
- const latestMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21496
- objectApiName: checkedObjectApiName,
21497
- });
21725
+ // 回写状态
21726
+ const latestMeta = await xmlMetadataManager.readXml('ConvertRule', ruleApiName);
21498
21727
  await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, latestMeta.content, {
21499
- objectApiName: checkedObjectApiName,
21500
21728
  status: 'unchanged',
21501
21729
  features: latestMeta.features,
21502
21730
  extra: latestMeta.extra,
21503
21731
  });
21504
21732
  // post-pull
21505
- logger_ts_1.loggerService.startLoading('convert-rule push post-pull: ' + checkedObjectApiName);
21733
+ logger_ts_1.loggerService.startLoading('convert-rule push post-pull');
21506
21734
  try {
21507
- const postPullResult = await (0, convert_rule_pull_ts_1.convertRulePullService)(checkedObjectApiName, false, skipOverwriteConfirm);
21735
+ const postPullResult = await (0, convert_rule_pull_ts_1.convertRulePullService)({
21736
+ skipOverwriteConfirm,
21737
+ });
21508
21738
  errorMessages.push(...postPullResult.errorMessages);
21509
21739
  }
21510
21740
  finally {
21511
21741
  logger_ts_1.loggerService.stopLoading();
21512
21742
  }
21513
- logger_ts_1.loggerService.info(`Convert-rule pushed: ${checkedObjectApiName}.${ruleApiName}`);
21743
+ logger_ts_1.loggerService.info(`Convert-rule pushed: ${ruleApiName}`);
21514
21744
  }
21515
21745
  catch (error) {
21516
- errorMessages.push(`Convert-rule push failed: ${checkedObjectApiName}.${ruleApiName}: ${error}`);
21746
+ errorMessages.push(`Convert-rule push failed: ${ruleApiName}: ${error}`);
21517
21747
  }
21518
21748
  }
21519
21749
  return {
21520
- objectApiName: checkedObjectApiName,
21750
+ objectApiName: '',
21521
21751
  apiName: targetRuleApiNames.join(','),
21522
21752
  errorMessages,
21523
21753
  };
@@ -21539,11 +21769,7 @@ exports.convertRuleUpdateService = void 0;
21539
21769
  const normalize_ts_1 = __importDefault(__webpack_require__(9268));
21540
21770
  const index_ts_1 = __webpack_require__(9985);
21541
21771
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
21542
- const convertRuleUpdateService = async (objectApiName, data) => {
21543
- const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
21544
- if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
21545
- throw new Error('Invalid arguments: objectApiName is required.');
21546
- }
21772
+ const convertRuleUpdateService = async (data) => {
21547
21773
  const raw = normalize_ts_1.default.normalizeString(data);
21548
21774
  if (!raw) {
21549
21775
  throw new Error('Invalid arguments: data is required.');
@@ -21552,30 +21778,76 @@ const convertRuleUpdateService = async (objectApiName, data) => {
21552
21778
  if (!ruleData || typeof ruleData !== 'object' || Array.isArray(ruleData)) {
21553
21779
  throw new Error('data must be a JSON object.');
21554
21780
  }
21555
- const ruleApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(ruleData.api_name))
21556
- ?? normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(ruleData.apiName));
21781
+ // ruleList 中找主规则的 rule_api_name 定位文件
21782
+ const ruleList = ruleData.ruleList;
21783
+ if (!ruleList?.length) {
21784
+ throw new Error('data.ruleList is required and must be a non-empty array.');
21785
+ }
21786
+ const mainRule = ruleList.find((r) => {
21787
+ const master = r.master_rule_api_name;
21788
+ return !master || master === '';
21789
+ }) ?? ruleList[0];
21790
+ const ruleApiName = normalize_ts_1.default.normalizeString(mainRule.rule_api_name)
21791
+ ?? normalize_ts_1.default.normalizeString(mainRule.ruleApiName)
21792
+ ?? '';
21557
21793
  if (!ruleApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(ruleApiName)) {
21558
- throw new Error('Invalid arguments: api_name or apiName is required in data.');
21794
+ throw new Error('Invalid arguments: cannot determine rule_api_name from data.ruleList.');
21559
21795
  }
21560
21796
  const current = await xmlMetadataManager.readXml('ConvertRule', ruleApiName, {
21561
- objectApiName: checkedObjectApiName,
21562
21797
  fields: ['content', 'status']
21563
21798
  });
21564
21799
  if (current.content === null || current.content === undefined) {
21565
- throw new Error(`Convert-rule metadata not found: ${checkedObjectApiName}.${ruleApiName}`);
21800
+ throw new Error(`Convert-rule metadata not found: ${ruleApiName}`);
21566
21801
  }
21567
21802
  const filePath = await xmlMetadataManager.writeXml('ConvertRule', ruleApiName, ruleData, {
21568
- objectApiName: checkedObjectApiName,
21569
21803
  status: current.status === 'new' ? 'new' : 'modified'
21570
21804
  });
21571
- return {
21572
- filePath,
21573
- errorMessages: []
21574
- };
21805
+ return { filePath, errorMessages: [] };
21575
21806
  };
21576
21807
  exports.convertRuleUpdateService = convertRuleUpdateService;
21577
21808
 
21578
21809
 
21810
+ /***/ },
21811
+
21812
+ /***/ 236
21813
+ (__unused_webpack_module, exports, __webpack_require__) {
21814
+
21815
+
21816
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
21817
+ exports.fetchEmailTemplateList = void 0;
21818
+ const request_execute_command_paths_ts_1 = __webpack_require__(2351);
21819
+ const request_ts_1 = __webpack_require__(3176);
21820
+ const types_ts_1 = __webpack_require__(7480);
21821
+ /**
21822
+ * 查询邮件模板列表
21823
+ */
21824
+ const fetchEmailTemplateList = async (options = {}) => {
21825
+ const response = await (0, request_ts_1.requestObjectDevExecute)((0, request_execute_command_paths_ts_1.getShareCliCommandPath)('emailTemplate', 'template-page'), {
21826
+ objDescApiName: options.objDescApiName ?? '',
21827
+ pageNumber: options.pageNumber ?? 1,
21828
+ pageSize: options.pageSize ?? 2000,
21829
+ SortField: options.sortField ?? '',
21830
+ SortType: options.sortType ?? '',
21831
+ QueryInfo: {},
21832
+ });
21833
+ const result = await (0, request_ts_1.extractObjectDevServiceResult)(response, (res) => {
21834
+ const data = (0, types_ts_1.narrowObjectDevResponse)(res.data);
21835
+ if (!data)
21836
+ throw new Error('Invalid response data');
21837
+ const list = data.list ?? data.items ?? data.records;
21838
+ if (Array.isArray(list)) {
21839
+ return list;
21840
+ }
21841
+ return [];
21842
+ });
21843
+ if (!result.success) {
21844
+ throw new Error(result.errorMessage);
21845
+ }
21846
+ return (result.data ?? []);
21847
+ };
21848
+ exports.fetchEmailTemplateList = fetchEmailTemplateList;
21849
+
21850
+
21579
21851
  /***/ },
21580
21852
 
21581
21853
  /***/ 3163
@@ -21926,7 +22198,7 @@ exports.fieldUpdateService = fieldUpdateService;
21926
22198
 
21927
22199
  Object.defineProperty(exports, "__esModule", ({ value: true }));
21928
22200
  exports.fetchConvertRuleList = exports.objectMappingPushService = exports.objectMappingUpdateService = exports.objectMappingCreateService = exports.objectMappingListService = exports.fetchObjectMappingList = exports.objectMappingPullService = exports.buttonPushService = exports.buttonUpdateService = exports.buttonCreateService = exports.buttonListService = exports.buttonPullService = exports.validateRulePushService = exports.validateRuleUpdateService = exports.validateRuleCreateService = exports.validateRulePullService = exports.validateRuleListService = exports.layoutRulePushService = exports.layoutRulePullService = exports.layoutRuleUpdateService = exports.layoutRuleListService = exports.layoutRuleCreateService = exports.layoutPushService = exports.layoutPullService = exports.layoutUpdateService = exports.layoutListService = exports.layoutEnableEditService = exports.layoutEditStatusService = exports.layoutCreateService = exports.sceneUpdateService = exports.scenePushService = exports.scenePullService = exports.sceneListService = exports.sceneCreateService = exports.optionSetUpdateService = exports.optionSetPushService = exports.optionSetPullService = exports.optionSetListService = exports.optionSetDeleteService = exports.optionSetCreateService = exports.fieldPushService = exports.fieldUpdateService = exports.fieldListService = exports.fieldCreateService = exports.objectPushService = exports.objectUpdateService = exports.objectCreateService = exports.objectListService = exports.objectRelatedPullService = exports.objectPullService = void 0;
21929
- exports.extractObjectDevServiceResult = exports.requestObjectDevExecute = exports.convertRulePushService = exports.convertRuleUpdateService = exports.convertRuleCreateService = exports.convertRulePullService = exports.convertRuleListService = void 0;
22201
+ exports.extractObjectDevServiceResult = exports.requestObjectDevExecute = exports.emailTemplateListService = exports.fetchEmailTemplateList = exports.convertRulePushService = exports.convertRuleUpdateService = exports.convertRuleCreateService = exports.convertRulePullService = exports.convertRuleListService = void 0;
21930
22202
  var object_pull_ts_1 = __webpack_require__(9365);
21931
22203
  Object.defineProperty(exports, "objectPullService", ({ enumerable: true, get: function () { return object_pull_ts_1.objectPullService; } }));
21932
22204
  var object_related_pull_ts_1 = __webpack_require__(9711);
@@ -22035,6 +22307,9 @@ var convert_rule_update_ts_1 = __webpack_require__(8346);
22035
22307
  Object.defineProperty(exports, "convertRuleUpdateService", ({ enumerable: true, get: function () { return convert_rule_update_ts_1.convertRuleUpdateService; } }));
22036
22308
  var convert_rule_push_ts_1 = __webpack_require__(2771);
22037
22309
  Object.defineProperty(exports, "convertRulePushService", ({ enumerable: true, get: function () { return convert_rule_push_ts_1.convertRulePushService; } }));
22310
+ var email_template_list_ts_1 = __webpack_require__(236);
22311
+ Object.defineProperty(exports, "fetchEmailTemplateList", ({ enumerable: true, get: function () { return email_template_list_ts_1.fetchEmailTemplateList; } }));
22312
+ Object.defineProperty(exports, "emailTemplateListService", ({ enumerable: true, get: function () { return email_template_list_ts_1.fetchEmailTemplateList; } }));
22038
22313
  var request_ts_1 = __webpack_require__(3176);
22039
22314
  Object.defineProperty(exports, "requestObjectDevExecute", ({ enumerable: true, get: function () { return request_ts_1.requestObjectDevExecute; } }));
22040
22315
  Object.defineProperty(exports, "extractObjectDevServiceResult", ({ enumerable: true, get: function () { return request_ts_1.extractObjectDevServiceResult; } }));
@@ -23007,10 +23282,6 @@ const index_ts_1 = __webpack_require__(9985);
23007
23282
  const object_mapping_list_ts_1 = __webpack_require__(7244);
23008
23283
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
23009
23284
  const objectMappingCreateService = async (objectApiName, data, force) => {
23010
- const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
23011
- if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
23012
- throw new Error('Invalid arguments: objectApiName is required.');
23013
- }
23014
23285
  const raw = normalize_ts_1.default.normalizeString(data);
23015
23286
  if (!raw) {
23016
23287
  throw new Error('Invalid arguments: data is required.');
@@ -23019,35 +23290,54 @@ const objectMappingCreateService = async (objectApiName, data, force) => {
23019
23290
  if (!mappingData || typeof mappingData !== 'object' || Array.isArray(mappingData)) {
23020
23291
  throw new Error('data must be a JSON object.');
23021
23292
  }
23022
- const mappingApiName = normalize_ts_1.default.normalizeString(mappingData.api_name) ?? normalize_ts_1.default.normalizeString(mappingData.apiName);
23023
- if (!mappingApiName) {
23024
- throw new Error('data.api_name or data.apiName is required.');
23293
+ // describe_api_name: 优先从 data 取,其次 --objectApiName
23294
+ const checkedObjectApiName = normalize_ts_1.default.normalizeString(mappingData.describe_api_name) ?? normalize_ts_1.default.normalizeString(objectApiName);
23295
+ if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
23296
+ throw new Error('Invalid arguments: describe_api_name is required (via --objectApiName or data.describe_api_name).');
23297
+ }
23298
+ // 从 rule_list 中提取主规则的 rule_api_name 作为文件名
23299
+ const ruleList = mappingData.rule_list;
23300
+ const mainRule = ruleList?.find((r) => {
23301
+ const master = r.master_rule_api_name;
23302
+ return !master || master === '';
23303
+ });
23304
+ const mappingApiName = mainRule
23305
+ ? (normalize_ts_1.default.normalizeString(mainRule.rule_api_name) ?? checkedObjectApiName)
23306
+ : checkedObjectApiName;
23307
+ // 远端查重
23308
+ const remoteItems = await (0, object_mapping_list_ts_1.fetchObjectMappingList)();
23309
+ const remoteNameSet = new Set();
23310
+ for (const item of remoteItems) {
23311
+ const ruleList = item.ruleList;
23312
+ if (ruleList) {
23313
+ for (const rule of ruleList) {
23314
+ const name = normalize_ts_1.default.normalizeString(rule.rule_api_name);
23315
+ if (name)
23316
+ remoteNameSet.add(name);
23317
+ }
23318
+ }
23025
23319
  }
23026
- const remoteMappings = await (0, object_mapping_list_ts_1.fetchObjectMappingList)(checkedObjectApiName, null);
23027
- if (remoteMappings.some((item) => {
23028
- const remoteName = normalize_ts_1.default.normalizeString(item.api_name)
23029
- ?? normalize_ts_1.default.normalizeString(item.apiName);
23030
- return remoteName === mappingApiName;
23031
- })) {
23032
- throw new Error('Object-mapping already exists remotely: ' + checkedObjectApiName + '.' + mappingApiName);
23320
+ if (remoteNameSet.has(mappingApiName)) {
23321
+ throw new Error('Object-mapping already exists remotely: ' + mappingApiName);
23033
23322
  }
23323
+ // 本地查重
23034
23324
  const existing = await xmlMetadataManager.readXml('ObjectMapping', mappingApiName, {
23035
- objectApiName: checkedObjectApiName,
23036
23325
  fields: ['content'],
23037
23326
  });
23038
23327
  if (existing.content !== null && existing.content !== undefined) {
23039
23328
  if (!force) {
23040
- throw new Error('Object-mapping already exists locally: ' + checkedObjectApiName + '.' + mappingApiName + '. Use --force to overwrite.');
23329
+ throw new Error('Object-mapping already exists locally: ' + mappingApiName + '. Use --force to overwrite.');
23041
23330
  }
23042
23331
  }
23043
- const filePath = await xmlMetadataManager.writeXml('ObjectMapping', mappingApiName, mappingData, {
23044
- objectApiName: checkedObjectApiName,
23045
- status: 'new',
23046
- });
23047
- return {
23048
- filePath,
23049
- errorMessages: [],
23332
+ // 组装完整内容(匹配 create-rule API 格式)
23333
+ const fullContent = {
23334
+ rule_list: ruleList ?? [],
23335
+ button: mappingData.button ?? {},
23336
+ describe_api_name: checkedObjectApiName,
23337
+ roles: mappingData.roles ?? [],
23050
23338
  };
23339
+ const filePath = await xmlMetadataManager.writeXml('ObjectMapping', mappingApiName, fullContent, { status: 'new' });
23340
+ return { filePath, errorMessages: [] };
23051
23341
  };
23052
23342
  exports.objectMappingCreateService = objectMappingCreateService;
23053
23343
 
@@ -23064,30 +23354,29 @@ const request_execute_command_paths_ts_1 = __webpack_require__(2351);
23064
23354
  const request_ts_1 = __webpack_require__(3176);
23065
23355
  const types_ts_1 = __webpack_require__(7480);
23066
23356
  /**
23067
- * 调 list 接口获取指定对象下的对象映射规则列表
23357
+ * 调详情列表接口获取对象映射规则列表
23358
+ * 实际返回结构: { data: { items: [{ button, ruleList, roles }, ...] } }
23068
23359
  */
23069
- const fetchObjectMappingList = async (objectApiName, ruleApiNames) => {
23070
- const response = await (0, request_ts_1.requestObjectDevExecute)((0, request_execute_command_paths_ts_1.getShareCliCommandPath)('objectMapping', 'rule-detail-list'), {
23071
- describeApiName: objectApiName,
23072
- ruleApiNames,
23073
- });
23360
+ const fetchObjectMappingList = async (options = {}) => {
23361
+ const data = {
23362
+ status: options.status ?? 0,
23363
+ rule_name: options.ruleName ?? '',
23364
+ };
23365
+ const response = await (0, request_ts_1.requestObjectDevExecute)((0, request_execute_command_paths_ts_1.getShareCliCommandPath)('objectMapping', 'rule-detail-list'), data);
23074
23366
  const result = await (0, request_ts_1.extractObjectDevServiceResult)(response, (res) => {
23075
23367
  const data = (0, types_ts_1.narrowObjectDevResponse)(res.data);
23076
23368
  if (!data)
23077
- throw new Error(`Invalid response data for object ${objectApiName}`);
23078
- const list = (0, types_ts_1.narrowObjectDevResponse)(data.ruleInfoList)
23079
- ?? (0, types_ts_1.narrowObjectDevResponse)(data.objectMappingList)
23080
- ?? (0, types_ts_1.narrowObjectDevResponse)(data.list);
23081
- return list ?? [];
23369
+ throw new Error('Invalid response data');
23370
+ const items = data.items;
23371
+ if (Array.isArray(items)) {
23372
+ return items;
23373
+ }
23374
+ return [];
23082
23375
  });
23083
23376
  if (!result.success) {
23084
23377
  throw new Error(result.errorMessage);
23085
23378
  }
23086
- return (result.data ?? []).filter((item) => Boolean(item) && typeof item === 'object').map((item) => {
23087
- const record = item;
23088
- const rule = record.rule;
23089
- return (rule && typeof rule === 'object' ? rule : record);
23090
- });
23379
+ return (result.data ?? []);
23091
23380
  };
23092
23381
  exports.fetchObjectMappingList = fetchObjectMappingList;
23093
23382
 
@@ -23108,69 +23397,77 @@ const logger_ts_1 = __webpack_require__(3333);
23108
23397
  const index_ts_1 = __webpack_require__(9985);
23109
23398
  const object_mapping_list_ts_1 = __webpack_require__(7244);
23110
23399
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
23111
- const objectMappingPullService = async (objectApiNamesRaw, force = false, skipOverwriteConfirm = false) => {
23112
- const errorMessages = [];
23113
- const objectApiNames = (normalize_ts_1.default.normalizeString(objectApiNamesRaw) ?? '')
23114
- .split(',')
23115
- .map((item) => item.trim())
23116
- .filter(Boolean);
23117
- if (!objectApiNames.length) {
23118
- throw new Error('Invalid arguments: objectApiNames is required.');
23400
+ /**
23401
+ * item.ruleList 中找到主规则的 rule_api_name 作为文件名
23402
+ * 主规则: master_rule_api_name 为空字符串或 null/undefined
23403
+ * 没有主规则时回退到 button.api_name
23404
+ */
23405
+ function resolveItemApiName(item) {
23406
+ const ruleList = item.ruleList;
23407
+ if (ruleList?.length) {
23408
+ const mainRule = ruleList.find((r) => {
23409
+ const master = r.master_rule_api_name;
23410
+ return !master || master === '';
23411
+ });
23412
+ if (mainRule) {
23413
+ return normalize_ts_1.default.normalizeString(mainRule.rule_api_name);
23414
+ }
23415
+ // 没有主规则时用第一条的 rule_api_name
23416
+ return normalize_ts_1.default.normalizeString(ruleList[0].rule_api_name);
23119
23417
  }
23120
- let found = 0;
23418
+ // 回退到 button.api_name
23419
+ const button = item.button;
23420
+ return normalize_ts_1.default.normalizeString(button?.api_name);
23421
+ }
23422
+ const objectMappingPullService = async (options = {}) => {
23423
+ const errorMessages = [];
23424
+ const force = options.force === true;
23425
+ const skipOverwriteConfirm = options.skipOverwriteConfirm === true;
23426
+ const items = await (0, object_mapping_list_ts_1.fetchObjectMappingList)({
23427
+ status: options.status,
23428
+ ruleName: options.ruleName,
23429
+ });
23121
23430
  let written = 0;
23122
23431
  let skipped = 0;
23123
- for (const objectApiName of objectApiNames) {
23432
+ const found = items.length;
23433
+ for (const item of items) {
23434
+ const mappingApiName = resolveItemApiName(item);
23435
+ if (!mappingApiName) {
23436
+ skipped += 1;
23437
+ continue;
23438
+ }
23124
23439
  try {
23125
- const mappings = await (0, object_mapping_list_ts_1.fetchObjectMappingList)(objectApiName, null);
23126
- found += mappings.length;
23127
- for (const mappingRecord of mappings) {
23128
- const mappingApiName = normalize_ts_1.default.normalizeString(mappingRecord.api_name)
23129
- ?? normalize_ts_1.default.normalizeString(mappingRecord.apiName);
23130
- if (!mappingApiName) {
23131
- skipped += 1;
23132
- continue;
23133
- }
23134
- try {
23135
- if (force) {
23136
- await xmlMetadataManager.writeXml('ObjectMapping', mappingApiName, mappingRecord, {
23137
- objectApiName,
23138
- status: 'unchanged',
23139
- });
23140
- written += 1;
23141
- continue;
23142
- }
23143
- const localStatus = await xmlMetadataManager.readXml('ObjectMapping', mappingApiName, {
23144
- objectApiName,
23145
- fields: ['status'],
23146
- });
23147
- if (localStatus.status !== 'unchanged') {
23148
- if (skipOverwriteConfirm) {
23149
- logger_ts_1.loggerService.info(`Skipped ${objectApiName}.${mappingApiName}: local status is ${localStatus.status}. Use --force to overwrite local metadata.`);
23150
- }
23151
- else {
23152
- logger_ts_1.loggerService.info(`Object-mapping local status ${localStatus.status}, skip overwrite: ${objectApiName}.${mappingApiName}. Use --force to overwrite local metadata.`);
23153
- }
23154
- skipped += 1;
23155
- continue;
23156
- }
23157
- await xmlMetadataManager.writeXml('ObjectMapping', mappingApiName, mappingRecord, {
23158
- objectApiName,
23159
- status: 'unchanged',
23160
- });
23161
- written += 1;
23440
+ if (force) {
23441
+ await xmlMetadataManager.writeXml('ObjectMapping', mappingApiName, item, {
23442
+ status: 'unchanged',
23443
+ });
23444
+ written += 1;
23445
+ continue;
23446
+ }
23447
+ const localStatus = await xmlMetadataManager.readXml('ObjectMapping', mappingApiName, {
23448
+ fields: ['status'],
23449
+ });
23450
+ if (localStatus.status !== 'unchanged') {
23451
+ if (skipOverwriteConfirm) {
23452
+ logger_ts_1.loggerService.info(`Skipped ${mappingApiName}: local status is ${localStatus.status}. Use --force to overwrite local metadata.`);
23162
23453
  }
23163
- catch (error) {
23164
- errorMessages.push(objectApiName + ' object-mapping ' + mappingApiName + ': ' + (error instanceof Error ? error.message : String(error)));
23454
+ else {
23455
+ logger_ts_1.loggerService.info(`Object-mapping local status ${localStatus.status}, skip overwrite: ${mappingApiName}. Use --force to overwrite local metadata.`);
23165
23456
  }
23457
+ skipped += 1;
23458
+ continue;
23166
23459
  }
23460
+ await xmlMetadataManager.writeXml('ObjectMapping', mappingApiName, item, {
23461
+ status: 'unchanged',
23462
+ });
23463
+ written += 1;
23167
23464
  }
23168
23465
  catch (error) {
23169
- errorMessages.push(objectApiName + ': ' + (error instanceof Error ? error.message : String(error)));
23466
+ errorMessages.push('object-mapping ' + mappingApiName + ': ' + (error instanceof Error ? error.message : String(error)));
23170
23467
  }
23171
23468
  }
23172
23469
  return {
23173
- objectApiNames,
23470
+ objectApiNames: [],
23174
23471
  found,
23175
23472
  written,
23176
23473
  skipped,
@@ -23200,124 +23497,135 @@ const request_ts_1 = __webpack_require__(3176);
23200
23497
  const logger_ts_1 = __webpack_require__(3333);
23201
23498
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
23202
23499
  const isRecord = normalize_ts_1.default.isRecord;
23203
- const objectMappingPushService = async (objectApiName, ruleApiNames, skipOverwriteConfirm = false) => {
23500
+ const objectMappingPushService = async (ruleApiNames, skipOverwriteConfirm = false) => {
23204
23501
  const errorMessages = [];
23205
- const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
23206
- if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
23207
- throw new Error('Invalid arguments: objectApiName is required.');
23502
+ const targetRuleApiNames = [];
23503
+ if (ruleApiNames) {
23504
+ targetRuleApiNames.push(...(ruleApiNames
23505
+ .split(',')
23506
+ .map((item) => normalize_ts_1.default.normalizeString(item))
23507
+ .filter((item) => Boolean(item))));
23208
23508
  }
23209
- const targetRuleApiNames = (ruleApiNames ?? '')
23210
- .split(',')
23211
- .map((item) => normalize_ts_1.default.normalizeString(item))
23212
- .filter((item) => Boolean(item));
23213
23509
  if (!targetRuleApiNames.length) {
23214
- throw new Error('Invalid arguments: ruleApiNames is required.');
23510
+ // 未指定 ruleApiNames 扫描本地所有 object-mapping 文件
23511
+ const localIndex = await xmlMetadataManager.listLocalXmlApiName(undefined, ['ObjectMapping']);
23512
+ const mappingIndex = localIndex[''];
23513
+ if (mappingIndex?.ObjectMapping?.length) {
23514
+ targetRuleApiNames.push(...mappingIndex.ObjectMapping);
23515
+ }
23516
+ }
23517
+ if (!targetRuleApiNames.length) {
23518
+ throw new Error('No object-mapping metadata found. Use --ruleApiNames <apiNames> or create local object-mapping metadata first.');
23215
23519
  }
23216
23520
  for (const ruleApiName of targetRuleApiNames) {
23217
23521
  try {
23218
- let mappingMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName, {
23219
- objectApiName: checkedObjectApiName,
23220
- });
23522
+ let mappingMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName);
23221
23523
  if (!mappingMeta.content || !isRecord(mappingMeta.content)) {
23222
- throw new Error(`Invalid object-mapping content: ${checkedObjectApiName}.${ruleApiName}`);
23524
+ throw new Error(`Invalid object-mapping content: ${ruleApiName}`);
23223
23525
  }
23526
+ const content = mappingMeta.content;
23527
+ const button = content.button;
23528
+ const describeApiName = normalize_ts_1.default.normalizeString(content.describe_api_name)
23529
+ ?? normalize_ts_1.default.normalizeString(content.describeApiName)
23530
+ ?? normalize_ts_1.default.normalizeString(button?.describe_api_name)
23531
+ ?? '';
23224
23532
  // pre-pull for non-new rules
23225
23533
  if (mappingMeta.status !== 'new') {
23226
- logger_ts_1.loggerService.startLoading('object-mapping push pre-pull: ' + checkedObjectApiName + '.' + ruleApiName);
23534
+ logger_ts_1.loggerService.startLoading('object-mapping push pre-pull: ' + ruleApiName);
23227
23535
  try {
23228
- const prePullResult = await (0, object_mapping_pull_ts_1.objectMappingPullService)(checkedObjectApiName, false, skipOverwriteConfirm);
23536
+ const prePullResult = await (0, object_mapping_pull_ts_1.objectMappingPullService)({
23537
+ skipOverwriteConfirm,
23538
+ });
23229
23539
  errorMessages.push(...prePullResult.errorMessages);
23230
23540
  }
23231
23541
  finally {
23232
23542
  logger_ts_1.loggerService.stopLoading();
23233
23543
  }
23234
23544
  }
23235
- // Check remote existence
23236
- logger_ts_1.loggerService.startLoading('object-mapping push check remote: ' + checkedObjectApiName + '.' + ruleApiName);
23545
+ // 远端存在性检查
23546
+ logger_ts_1.loggerService.startLoading('object-mapping push check remote: ' + ruleApiName);
23237
23547
  let existsRemotely = false;
23238
23548
  try {
23239
- const remoteMappings = await (0, object_mapping_list_ts_1.fetchObjectMappingList)(checkedObjectApiName, null);
23240
- existsRemotely = remoteMappings.some((item) => {
23241
- const remoteName = normalize_ts_1.default.normalizeString(item.api_name)
23242
- ?? normalize_ts_1.default.normalizeString(item.apiName);
23243
- return remoteName === ruleApiName;
23549
+ const remoteItems = await (0, object_mapping_list_ts_1.fetchObjectMappingList)();
23550
+ existsRemotely = remoteItems.some((item) => {
23551
+ const ruleList = item.ruleList;
23552
+ return ruleList?.some((rule) => {
23553
+ const remoteName = normalize_ts_1.default.normalizeString(rule.rule_api_name);
23554
+ return remoteName === ruleApiName;
23555
+ }) ?? false;
23244
23556
  });
23245
23557
  }
23246
23558
  finally {
23247
23559
  logger_ts_1.loggerService.stopLoading();
23248
23560
  }
23249
- // Fix local status based on remote
23561
+ // 状态修正
23250
23562
  if (mappingMeta.status === 'new' && existsRemotely) {
23251
- await xmlMetadataManager.writeXml('ObjectMapping', ruleApiName, mappingMeta.content, {
23252
- objectApiName: checkedObjectApiName,
23563
+ await xmlMetadataManager.writeXml('ObjectMapping', ruleApiName, content, {
23253
23564
  status: 'modified',
23254
23565
  features: mappingMeta.features,
23255
23566
  extra: mappingMeta.extra,
23256
23567
  });
23257
- logger_ts_1.loggerService.warn('Object-mapping exists remotely, local status changed from new to modified: ' + checkedObjectApiName + '.' + ruleApiName);
23258
- mappingMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName, {
23259
- objectApiName: checkedObjectApiName,
23260
- });
23568
+ logger_ts_1.loggerService.warn('Object-mapping exists remotely, local status changed from new to modified: ' + ruleApiName);
23569
+ mappingMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName);
23261
23570
  }
23262
23571
  if (mappingMeta.status !== 'new' && !existsRemotely) {
23263
- await xmlMetadataManager.writeXml('ObjectMapping', ruleApiName, mappingMeta.content, {
23264
- objectApiName: checkedObjectApiName,
23572
+ await xmlMetadataManager.writeXml('ObjectMapping', ruleApiName, content, {
23265
23573
  status: 'new',
23266
23574
  features: mappingMeta.features,
23267
23575
  extra: mappingMeta.extra,
23268
23576
  });
23269
- logger_ts_1.loggerService.warn('Object-mapping does not exist remotely, local status changed from ' + mappingMeta.status + ' to new: ' + checkedObjectApiName + '.' + ruleApiName);
23270
- mappingMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName, {
23271
- objectApiName: checkedObjectApiName,
23272
- });
23577
+ logger_ts_1.loggerService.warn('Object-mapping does not exist remotely, local status changed from ' + mappingMeta.status + ' to new: ' + ruleApiName);
23578
+ mappingMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName);
23273
23579
  }
23274
23580
  const isCreate = mappingMeta.status === 'new';
23275
- const mappingContent = { ...(mappingMeta.content && isRecord(mappingMeta.content)
23581
+ // 组装 push payload(对齐 create-rule/update-rule API 格式)
23582
+ const updatedContent = { ...(mappingMeta.content && isRecord(mappingMeta.content)
23276
23583
  ? mappingMeta.content
23277
- : {}) };
23278
- if (!mappingContent.describe_api_name) {
23279
- mappingContent.describe_api_name = checkedObjectApiName;
23584
+ : content) };
23585
+ if (!updatedContent.describe_api_name) {
23586
+ updatedContent.describe_api_name = describeApiName;
23280
23587
  }
23281
- if (!mappingContent.api_name) {
23282
- mappingContent.api_name = ruleApiName;
23588
+ // ruleList(camelCase,pull 返回)→ rule_list(snake_case,create-rule/update-rule API 要求)
23589
+ if (updatedContent.ruleList && !updatedContent.rule_list) {
23590
+ updatedContent.rule_list = updatedContent.ruleList;
23591
+ delete updatedContent.ruleList;
23283
23592
  }
23284
- logger_ts_1.loggerService.startLoading('object-mapping push request: ' + checkedObjectApiName + '.' + ruleApiName + ' (' + (isCreate ? 'create' : 'update') + ')');
23593
+ logger_ts_1.loggerService.startLoading('object-mapping push request: ' + ruleApiName + ' (' + (isCreate ? 'create' : 'update') + ')');
23285
23594
  const raw = await (0, request_ts_1.requestObjectDevExecute)(isCreate
23286
23595
  ? (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('objectMapping', 'create-rule')
23287
- : (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('objectMapping', 'update-rule'), mappingContent);
23596
+ : (0, request_execute_command_paths_ts_1.getShareCliCommandPath)('objectMapping', 'update-rule'), updatedContent);
23288
23597
  const response = raw;
23289
23598
  if (response.success !== true || normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(response.code)) !== 'OK') {
23290
23599
  logger_ts_1.loggerService.stopLoading();
23291
23600
  throw new Error('object-mapping push failed: ' + (normalize_ts_1.default.normalizeText(response.message) || 'Unknown error'));
23292
23601
  }
23293
23602
  logger_ts_1.loggerService.stopLoading();
23294
- // Write back status
23295
- const latestMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName, {
23296
- objectApiName: checkedObjectApiName,
23297
- });
23603
+ // 回写状态
23604
+ const latestMeta = await xmlMetadataManager.readXml('ObjectMapping', ruleApiName);
23298
23605
  await xmlMetadataManager.writeXml('ObjectMapping', ruleApiName, latestMeta.content, {
23299
- objectApiName: checkedObjectApiName,
23300
23606
  status: 'unchanged',
23301
23607
  features: latestMeta.features,
23302
23608
  extra: latestMeta.extra,
23303
23609
  });
23304
23610
  // post-pull
23305
- logger_ts_1.loggerService.startLoading('object-mapping push post-pull: ' + checkedObjectApiName);
23611
+ logger_ts_1.loggerService.startLoading('object-mapping push post-pull');
23306
23612
  try {
23307
- const postPullResult = await (0, object_mapping_pull_ts_1.objectMappingPullService)(checkedObjectApiName, false, skipOverwriteConfirm);
23613
+ const postPullResult = await (0, object_mapping_pull_ts_1.objectMappingPullService)({
23614
+ skipOverwriteConfirm,
23615
+ });
23308
23616
  errorMessages.push(...postPullResult.errorMessages);
23309
23617
  }
23310
23618
  finally {
23311
23619
  logger_ts_1.loggerService.stopLoading();
23312
23620
  }
23313
- logger_ts_1.loggerService.info(`Object-mapping pushed: ${checkedObjectApiName}.${ruleApiName}`);
23621
+ logger_ts_1.loggerService.info(`Object-mapping pushed: ${ruleApiName}`);
23314
23622
  }
23315
23623
  catch (error) {
23316
- errorMessages.push(`Object-mapping push failed: ${checkedObjectApiName}.${ruleApiName}: ${error}`);
23624
+ errorMessages.push(`Object-mapping push failed: ${ruleApiName}: ${error}`);
23317
23625
  }
23318
23626
  }
23319
23627
  return {
23320
- objectApiName: checkedObjectApiName,
23628
+ objectApiName: '',
23321
23629
  apiName: targetRuleApiNames.join(','),
23322
23630
  errorMessages,
23323
23631
  };
@@ -23339,11 +23647,7 @@ exports.objectMappingUpdateService = void 0;
23339
23647
  const normalize_ts_1 = __importDefault(__webpack_require__(9268));
23340
23648
  const index_ts_1 = __webpack_require__(9985);
23341
23649
  const xmlMetadataManager = new index_ts_1.XmlMetadataManager();
23342
- const objectMappingUpdateService = async (objectApiName, data) => {
23343
- const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
23344
- if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
23345
- throw new Error('Invalid arguments: objectApiName is required.');
23346
- }
23650
+ const objectMappingUpdateService = async (data) => {
23347
23651
  const raw = normalize_ts_1.default.normalizeString(data);
23348
23652
  if (!raw) {
23349
23653
  throw new Error('Invalid arguments: data is required.');
@@ -23352,26 +23656,30 @@ const objectMappingUpdateService = async (objectApiName, data) => {
23352
23656
  if (!mappingData || typeof mappingData !== 'object' || Array.isArray(mappingData)) {
23353
23657
  throw new Error('data must be a JSON object.');
23354
23658
  }
23355
- const mappingApiName = normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(mappingData.api_name))
23356
- ?? normalize_ts_1.default.normalizeString(normalize_ts_1.default.asString(mappingData.apiName));
23659
+ // rule_list 中提取主规则的 rule_api_name 作为文件名
23660
+ const ruleList = mappingData.rule_list;
23661
+ const mainRule = ruleList?.find((r) => {
23662
+ const master = r.master_rule_api_name;
23663
+ return !master || master === '';
23664
+ });
23665
+ const mappingApiName = mainRule
23666
+ ? (normalize_ts_1.default.normalizeString(mainRule.rule_api_name) ?? '')
23667
+ : normalize_ts_1.default.normalizeString(mappingData.api_name)
23668
+ ?? normalize_ts_1.default.normalizeString(mappingData.apiName)
23669
+ ?? '';
23357
23670
  if (!mappingApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(mappingApiName)) {
23358
- throw new Error('Invalid arguments: api_name or apiName is required in data.');
23671
+ throw new Error('Invalid arguments: cannot determine apiName from data (need rule_list with main rule or api_name/apiName).');
23359
23672
  }
23360
23673
  const current = await xmlMetadataManager.readXml('ObjectMapping', mappingApiName, {
23361
- objectApiName: checkedObjectApiName,
23362
23674
  fields: ['content', 'status']
23363
23675
  });
23364
23676
  if (current.content === null || current.content === undefined) {
23365
- throw new Error(`Object-mapping metadata not found: ${checkedObjectApiName}.${mappingApiName}`);
23677
+ throw new Error(`Object-mapping metadata not found: ${mappingApiName}`);
23366
23678
  }
23367
23679
  const filePath = await xmlMetadataManager.writeXml('ObjectMapping', mappingApiName, mappingData, {
23368
- objectApiName: checkedObjectApiName,
23369
23680
  status: current.status === 'new' ? 'new' : 'modified'
23370
23681
  });
23371
- return {
23372
- filePath,
23373
- errorMessages: []
23374
- };
23682
+ return { filePath, errorMessages: [] };
23375
23683
  };
23376
23684
  exports.objectMappingUpdateService = objectMappingUpdateService;
23377
23685
 
@@ -24906,7 +25214,7 @@ const validateRuleCreateService = async (apiName, data, force = false) => {
24906
25214
  // 1) 校验 validate-rule apiName 参数
24907
25215
  const checkedValidateRuleApiName = normalize_ts_1.default.normalizeString(apiName);
24908
25216
  if (!checkedValidateRuleApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedValidateRuleApiName)) {
24909
- throw new Error('Invalid arguments: apiName is required.');
25217
+ throw new Error('Invalid arguments: validateRuleApiName is required.');
24910
25218
  }
24911
25219
  // 2) 解析创建数据并提取所属 objectApiName
24912
25220
  const raw = normalize_ts_1.default.normalizeString(data);
@@ -24972,7 +25280,7 @@ const validateRuleListService = async (objectApiName) => {
24972
25280
  // 1) 校验参数并查询 validate-rule 列表
24973
25281
  const checkedObjectApiName = normalize_ts_1.default.normalizeString(objectApiName);
24974
25282
  if (!checkedObjectApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedObjectApiName)) {
24975
- throw new Error('Invalid arguments: apiName is required.');
25283
+ throw new Error('Invalid arguments: objectApiName is required.');
24976
25284
  }
24977
25285
  const errorMessages = [];
24978
25286
  const validateRules = [];
@@ -25115,7 +25423,7 @@ const validateRulePushService = async (objectApiName, validateRuleApiName) => {
25115
25423
  throw new Error('Invalid arguments: objectApiName is required.');
25116
25424
  }
25117
25425
  if (!checkedValidateRuleApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedValidateRuleApiName)) {
25118
- throw new Error('Invalid arguments: apiName is required.');
25426
+ throw new Error('Invalid arguments: validateRuleApiName is required.');
25119
25427
  }
25120
25428
  let validateRuleMeta = await xmlMetadataManager.readXml('ObjectValidateRule', checkedValidateRuleApiName, {
25121
25429
  objectApiName: checkedObjectApiName
@@ -25232,7 +25540,7 @@ const validateRuleUpdateService = async (apiName, data) => {
25232
25540
  // 1) 校验 validate-rule apiName 参数
25233
25541
  const checkedValidateRuleApiName = normalize_ts_1.default.normalizeString(apiName);
25234
25542
  if (!checkedValidateRuleApiName || !/^[A-Za-z][A-Za-z0-9_]*$/.test(checkedValidateRuleApiName)) {
25235
- throw new Error('Invalid arguments: apiName is required.');
25543
+ throw new Error('Invalid arguments: validateRuleApiName is required.');
25236
25544
  }
25237
25545
  // 2) 解析更新数据并提取所属 objectApiName
25238
25546
  const raw = normalize_ts_1.default.normalizeString(data);
@@ -25435,18 +25743,9 @@ const file_ts_1 = __webpack_require__(5409);
25435
25743
  const logger_ts_1 = __webpack_require__(3333);
25436
25744
  const pwc_service_ts_1 = __webpack_require__(2317);
25437
25745
  const pwc_types_ts_1 = __webpack_require__(1851);
25746
+ const pwc_mateXml_ts_1 = __webpack_require__(240);
25438
25747
  const pwc_workspace_ts_1 = __webpack_require__(3047);
25439
25748
  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
25749
  const COMPONENT_DEFAULT_INDEX_VUE = `<template>
25451
25750
  <div>
25452
25751
 
@@ -25587,11 +25886,8 @@ async function pwcDeployCommand(apiNameOrPath, options, context) {
25587
25886
  try {
25588
25887
  const target = resolveDeployTarget(apiNameOrPath, options.type, context);
25589
25888
  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
- }
25889
+ const constraints = (0, pwc_mateXml_ts_1.buildPwcTypeConstraints)(await (0, pwc_service_ts_1.getPwcConfig)());
25890
+ const bundle = await (0, pwc_workspace_ts_1.readLocalPwcUploadBundle)(context, target.type, target.apiName, constraints);
25595
25891
  logger_ts_1.loggerService.updateLoading(`Uploading ${bundle.uploadFiles.length} files`);
25596
25892
  const uploaded = await (0, pwc_service_ts_1.uploadFileList)(bundle.uploadFiles.map((item) => ({
25597
25893
  fileName: item.fileName,
@@ -25657,11 +25953,8 @@ async function pwcPushCommand(apiNameOrPath, options, context) {
25657
25953
  try {
25658
25954
  const target = resolveDeployTarget(apiNameOrPath, options.type, context);
25659
25955
  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
- }
25956
+ const constraints = (0, pwc_mateXml_ts_1.buildPwcTypeConstraints)(await (0, pwc_service_ts_1.getPwcConfig)());
25957
+ const bundle = await (0, pwc_workspace_ts_1.readLocalPwcUploadBundle)(context, target.type, target.apiName, constraints);
25665
25958
  logger_ts_1.loggerService.updateLoading(`Uploading ${bundle.uploadFiles.length} files`);
25666
25959
  const uploaded = await (0, pwc_service_ts_1.uploadFileList)(bundle.uploadFiles.map((item) => ({
25667
25960
  fileName: item.fileName,
@@ -26370,6 +26663,192 @@ async function sleep(ms) {
26370
26663
  }
26371
26664
 
26372
26665
 
26666
+ /***/ },
26667
+
26668
+ /***/ 240
26669
+ (__unused_webpack_module, exports, __webpack_require__) {
26670
+
26671
+
26672
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
26673
+ exports.buildPwcTypeConstraints = buildPwcTypeConstraints;
26674
+ exports.validatePwcLocalStructure = validatePwcLocalStructure;
26675
+ exports.validatePwcMateXmlContent = validatePwcMateXmlContent;
26676
+ const fast_xml_parser_1 = __webpack_require__(4603);
26677
+ const file_ts_1 = __webpack_require__(5409);
26678
+ function buildPwcTypeConstraints(config) {
26679
+ const componentTypes = new Set(Object.keys(config.components ?? {}).filter(Boolean));
26680
+ const pluginTypes = new Set(Object.values(config.plugins ?? {})
26681
+ .flatMap((items) => items.map((item) => item.value))
26682
+ .filter(Boolean));
26683
+ return {
26684
+ componentTypes,
26685
+ pluginTypes
26686
+ };
26687
+ }
26688
+ async function validatePwcLocalStructure(input) {
26689
+ const { type, apiName, mateXmlPath, metaPath, sourceDir, fileTreeDir } = input;
26690
+ if (!(await (0, file_ts_1.pathExists)(mateXmlPath))) {
26691
+ throw new Error(`PWC ${type} ${apiName}: required file not found: ${mateXmlPath}`);
26692
+ }
26693
+ const mateXmlStat = await (0, file_ts_1.statPath)(mateXmlPath);
26694
+ if (!mateXmlStat.isFile()) {
26695
+ throw new Error(`PWC ${type} ${apiName}: required file is not a file: ${mateXmlPath}`);
26696
+ }
26697
+ if (!(await (0, file_ts_1.pathExists)(metaPath))) {
26698
+ throw new Error(`PWC ${type} ${apiName}: required file not found: ${metaPath}`);
26699
+ }
26700
+ const metaStat = await (0, file_ts_1.statPath)(metaPath);
26701
+ if (!metaStat.isFile()) {
26702
+ throw new Error(`PWC ${type} ${apiName}: required file is not a file: ${metaPath}`);
26703
+ }
26704
+ const sourceStat = (await (0, file_ts_1.pathExists)(sourceDir)) ? await (0, file_ts_1.statPath)(sourceDir) : undefined;
26705
+ const fileTreeStat = (await (0, file_ts_1.pathExists)(fileTreeDir)) ? await (0, file_ts_1.statPath)(fileTreeDir) : undefined;
26706
+ const hasSourceDir = sourceStat?.isDirectory() === true;
26707
+ const hasFileTreeDir = fileTreeStat?.isDirectory() === true;
26708
+ if (!hasSourceDir && !hasFileTreeDir) {
26709
+ throw new Error(`PWC ${type} ${apiName}: both source and fileTree are missing.`);
26710
+ }
26711
+ }
26712
+ function parseXmlDocument(content, filePath) {
26713
+ try {
26714
+ return new fast_xml_parser_1.XMLParser({
26715
+ ignoreAttributes: false,
26716
+ attributeNamePrefix: '',
26717
+ trimValues: false
26718
+ }).parse(content);
26719
+ }
26720
+ catch (error) {
26721
+ const message = error instanceof Error ? error.message : String(error);
26722
+ throw new Error(`Invalid XML format in ${filePath}: ${message}`);
26723
+ }
26724
+ }
26725
+ function toArray(value) {
26726
+ if (value == null) {
26727
+ return [];
26728
+ }
26729
+ return Array.isArray(value) ? value : [value];
26730
+ }
26731
+ function readTextNode(value) {
26732
+ if (typeof value === 'string') {
26733
+ return value;
26734
+ }
26735
+ if (typeof value === 'number') {
26736
+ return String(value);
26737
+ }
26738
+ return '';
26739
+ }
26740
+ function hasOwn(obj, key) {
26741
+ return typeof obj === 'object' && obj !== null && Object.prototype.hasOwnProperty.call(obj, key);
26742
+ }
26743
+ function assertNonEmpty(value, message) {
26744
+ if (!value.trim()) {
26745
+ throw new Error(message);
26746
+ }
26747
+ }
26748
+ function assertClientValue(value, message) {
26749
+ if (value !== 'web' && value !== 'app') {
26750
+ throw new Error(message);
26751
+ }
26752
+ }
26753
+ function validateComponentMateXml(doc, input) {
26754
+ const { apiName, constraints } = input;
26755
+ const bundle = doc.ComponentBundle;
26756
+ if (typeof bundle !== 'object' || bundle === null) {
26757
+ throw new Error(`PWC component ${apiName}: mateXml.xml root node must be <ComponentBundle>.`);
26758
+ }
26759
+ if (!hasOwn(bundle, 'description')) {
26760
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <description>.`);
26761
+ }
26762
+ const type = readTextNode(bundle.type);
26763
+ assertNonEmpty(type, `PWC component ${apiName}: mateXml.xml is missing <type>.`);
26764
+ if (!constraints.componentTypes.has(type)) {
26765
+ throw new Error(`PWC component ${apiName}: mateXml.xml <type> value "${type}" is not valid.`);
26766
+ }
26767
+ const clientsNode = bundle.clients;
26768
+ if (typeof clientsNode !== 'object' || clientsNode === null) {
26769
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <clients>.`);
26770
+ }
26771
+ const clients = toArray(clientsNode.client).map(readTextNode);
26772
+ if (!clients.length) {
26773
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <clients><client>.`);
26774
+ }
26775
+ for (const client of clients) {
26776
+ assertNonEmpty(client, `PWC component ${apiName}: mateXml.xml <clients><client> must have a value.`);
26777
+ assertClientValue(client, `PWC component ${apiName}: mateXml.xml <clients><client> must be web or app.`);
26778
+ }
26779
+ const scopesNode = bundle.scopes;
26780
+ if (typeof scopesNode !== 'object' || scopesNode === null) {
26781
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <scopes>.`);
26782
+ }
26783
+ const scopes = toArray(scopesNode.scope);
26784
+ if (!scopes.length) {
26785
+ throw new Error(`PWC component ${apiName}: mateXml.xml is missing <scopes><scope>.`);
26786
+ }
26787
+ for (const scope of scopes) {
26788
+ if (typeof scope !== 'object' || scope === null) {
26789
+ throw new Error(`PWC component ${apiName}: mateXml.xml <scopes><scope> must contain target attribute and valid content.`);
26790
+ }
26791
+ const scopeObj = scope;
26792
+ const target = readTextNode(scopeObj.target);
26793
+ assertNonEmpty(target, `PWC component ${apiName}: mateXml.xml <scopes><scope> must contain target attribute.`);
26794
+ const wildcardText = readTextNode(scopeObj['#text']);
26795
+ const objectsNode = scopeObj.objects;
26796
+ const hasWildcard = wildcardText.trim() === '*';
26797
+ const hasObjects = typeof objectsNode === 'object' && objectsNode !== null;
26798
+ if (hasWildcard) {
26799
+ continue;
26800
+ }
26801
+ if (hasObjects) {
26802
+ const objects = toArray(objectsNode.object).map(readTextNode).filter((item) => item.trim());
26803
+ if (!objects.length) {
26804
+ throw new Error(`PWC component ${apiName}: mateXml.xml historical <objects><object> structure is empty.`);
26805
+ }
26806
+ continue;
26807
+ }
26808
+ throw new Error(`PWC component ${apiName}: mateXml.xml <scopes><scope> must be "*" or nested <objects><object>...</object></objects>.`);
26809
+ }
26810
+ }
26811
+ function validatePluginMateXml(doc, input) {
26812
+ const { apiName, constraints } = input;
26813
+ const bundle = doc.PluginBundle;
26814
+ if (typeof bundle !== 'object' || bundle === null) {
26815
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml root node must be <PluginBundle>.`);
26816
+ }
26817
+ if (!hasOwn(bundle, 'description')) {
26818
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml is missing <description>.`);
26819
+ }
26820
+ const type = readTextNode(bundle.type);
26821
+ assertNonEmpty(type, `PWC plugin ${apiName}: mateXml.xml is missing <type>.`);
26822
+ if (!constraints.pluginTypes.has(type)) {
26823
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml <type> value "${type}" is not valid.`);
26824
+ }
26825
+ const client = readTextNode(bundle.client);
26826
+ assertNonEmpty(client, `PWC plugin ${apiName}: mateXml.xml is missing <client>.`);
26827
+ assertClientValue(client, `PWC plugin ${apiName}: mateXml.xml <client> must be web or app.`);
26828
+ const entryFileName = readTextNode(bundle.entryFileName);
26829
+ const requiresEntryFileName = client === 'web';
26830
+ if (requiresEntryFileName) {
26831
+ assertNonEmpty(entryFileName, `PWC plugin ${apiName}: mateXml.xml is missing <entryFileName>.`);
26832
+ }
26833
+ const scopeObjectsNode = bundle.scopeObjects;
26834
+ if (typeof scopeObjectsNode !== 'object' || scopeObjectsNode === null) {
26835
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml is missing <scopeObjects>.`);
26836
+ }
26837
+ const objects = toArray(scopeObjectsNode.object).map(readTextNode).filter((item) => item.trim());
26838
+ if (!objects.length) {
26839
+ throw new Error(`PWC plugin ${apiName}: mateXml.xml is missing <scopeObjects><object>.`);
26840
+ }
26841
+ }
26842
+ function validatePwcMateXmlContent(input) {
26843
+ const doc = parseXmlDocument(input.content, input.filePath);
26844
+ if (input.type === 'component') {
26845
+ validateComponentMateXml(doc, input);
26846
+ return;
26847
+ }
26848
+ validatePluginMateXml(doc, input);
26849
+ }
26850
+
26851
+
26373
26852
  /***/ },
26374
26853
 
26375
26854
  /***/ 2317
@@ -26611,6 +27090,7 @@ const node_path_1 = __importDefault(__webpack_require__(6760));
26611
27090
  const fast_xml_parser_1 = __webpack_require__(4603);
26612
27091
  const file_ts_1 = __webpack_require__(5409);
26613
27092
  const pwc_types_ts_1 = __webpack_require__(1851);
27093
+ const pwc_mateXml_ts_1 = __webpack_require__(240);
26614
27094
  async function writeFiles(baseDir, files) {
26615
27095
  if (!files?.length) {
26616
27096
  return;
@@ -26700,7 +27180,7 @@ function resolveMateXmlInfo(type, mateXmlContent) {
26700
27180
  pluginType: typeof pluginType === 'string' ? pluginType : 'edit_plugin'
26701
27181
  };
26702
27182
  }
26703
- async function readLocalPwcUploadBundle(context, type, apiName) {
27183
+ async function readLocalPwcUploadBundle(context, type, apiName, constraints) {
26704
27184
  const componentRoot = resolvePwcComponentRoot(context, type, apiName);
26705
27185
  if (!(await (0, file_ts_1.pathExists)(componentRoot))) {
26706
27186
  throw new Error(`Local PWC resource directory not found: ${componentRoot}`);
@@ -26709,6 +27189,16 @@ async function readLocalPwcUploadBundle(context, type, apiName) {
26709
27189
  const staticDir = node_path_1.default.join(componentRoot, 'static');
26710
27190
  const fileTreeDir = node_path_1.default.join(componentRoot, 'fileTree');
26711
27191
  const mateXmlPath = node_path_1.default.join(componentRoot, 'mateXml.xml');
27192
+ const metaPath = node_path_1.default.join(componentRoot, '.sharedev-meta.json');
27193
+ await (0, pwc_mateXml_ts_1.validatePwcLocalStructure)({
27194
+ type,
27195
+ apiName,
27196
+ componentRoot,
27197
+ mateXmlPath,
27198
+ metaPath,
27199
+ sourceDir,
27200
+ fileTreeDir
27201
+ });
26712
27202
  const sourceFiles = await collectFilesRecursively(sourceDir);
26713
27203
  const staticFiles = await collectFilesRecursively(staticDir);
26714
27204
  const fileTreeFiles = await collectFilesRecursively(fileTreeDir);
@@ -26731,13 +27221,18 @@ async function readLocalPwcUploadBundle(context, type, apiName) {
26731
27221
  let entryFileName = '';
26732
27222
  let client = 'web';
26733
27223
  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
- }
27224
+ const mateXmlContent = await (0, file_ts_1.readTextFile)(mateXmlPath);
27225
+ (0, pwc_mateXml_ts_1.validatePwcMateXmlContent)({
27226
+ type,
27227
+ apiName,
27228
+ filePath: mateXmlPath,
27229
+ content: mateXmlContent,
27230
+ constraints
27231
+ });
27232
+ const mateInfo = resolveMateXmlInfo(type, mateXmlContent);
27233
+ entryFileName = mateInfo.entryFileName;
27234
+ client = mateInfo.client;
27235
+ pluginType = mateInfo.pluginType;
26741
27236
  return {
26742
27237
  entryFileName,
26743
27238
  client,
@@ -26753,17 +27248,17 @@ function resolveFileTreeRelativePath(fileTreeBaseDir, absoluteFilePath) {
26753
27248
  return normalizeFileTreePath(fileTreeBaseDir, absoluteFilePath);
26754
27249
  }
26755
27250
  async function writePwcComponent(context, component) {
26756
- const componentRoot = resolvePwcComponentRoot(context, component.type, component.apiName);
27251
+ const type = component.type;
27252
+ const componentRoot = resolvePwcComponentRoot(context, type, component.apiName);
26757
27253
  const sourceDir = node_path_1.default.join(componentRoot, 'source');
26758
27254
  const staticDir = node_path_1.default.join(componentRoot, 'static');
26759
27255
  const fileTreeDir = node_path_1.default.join(componentRoot, 'fileTree');
27256
+ const mateXmlPath = node_path_1.default.join(componentRoot, 'mateXml.xml');
26760
27257
  await (0, file_ts_1.ensureDir)(componentRoot);
26761
27258
  await (0, file_ts_1.ensureDir)(sourceDir);
26762
27259
  await (0, file_ts_1.ensureDir)(staticDir);
26763
27260
  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
- }
27261
+ await (0, file_ts_1.writeTextFile)(mateXmlPath, component.mateXml);
26767
27262
  await writeFiles(sourceDir, component.sourceFiles);
26768
27263
  await writeFiles(staticDir, component.images);
26769
27264
  await writeFileTree(fileTreeDir, component.fileTree);
@@ -42627,7 +43122,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"application/1d-interleaved-parityfec
42627
43122
  /***/ 8330
42628
43123
  (module) {
42629
43124
 
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"}');
43125
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@share-crm/sharedev-cli","version":"0.0.4-rc.22","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
43126
 
42632
43127
  /***/ }
42633
43128