@steedos-labs/content-compliance 0.8.36 → 1.0.1

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 (177) hide show
  1. package/dist/index.js +1 -1
  2. package/lib/actions/contentHubMaterialGroups.d.ts +19 -0
  3. package/lib/actions/contentHubMaterialGroups.js +70 -0
  4. package/lib/actions/contentHubMaterialGroups.js.map +1 -0
  5. package/lib/actions/contentHubSyncPreview.d.ts +21 -0
  6. package/lib/actions/contentHubSyncPreview.js +51 -0
  7. package/lib/actions/contentHubSyncPreview.js.map +1 -0
  8. package/lib/actions/contentHubTagValues.d.ts +12 -0
  9. package/lib/actions/contentHubTagValues.js +70 -0
  10. package/lib/actions/contentHubTagValues.js.map +1 -0
  11. package/lib/actions/index.d.ts +3 -0
  12. package/lib/actions/index.js +3 -0
  13. package/lib/actions/index.js.map +1 -1
  14. package/lib/actions/sendToContentHub.js +1 -1
  15. package/lib/actions/sendToContentHub.js.map +1 -1
  16. package/lib/actions/spotCheckMaterial.js +2 -1
  17. package/lib/actions/spotCheckMaterial.js.map +1 -1
  18. package/lib/index.js +173 -30
  19. package/lib/index.js.map +1 -1
  20. package/lib/methods/__tests__/contentHubMaterialGroup.test.d.ts +1 -0
  21. package/lib/methods/__tests__/contentHubMaterialGroup.test.js +97 -0
  22. package/lib/methods/__tests__/contentHubMaterialGroup.test.js.map +1 -0
  23. package/lib/methods/__tests__/contentHubMaterialGroupRule.test.d.ts +1 -0
  24. package/lib/methods/__tests__/contentHubMaterialGroupRule.test.js +168 -0
  25. package/lib/methods/__tests__/contentHubMaterialGroupRule.test.js.map +1 -0
  26. package/lib/methods/__tests__/contentHubPush.test.d.ts +1 -0
  27. package/lib/methods/__tests__/contentHubPush.test.js +568 -0
  28. package/lib/methods/__tests__/contentHubPush.test.js.map +1 -0
  29. package/lib/methods/__tests__/contentHubSyncRule.test.d.ts +1 -0
  30. package/lib/methods/__tests__/contentHubSyncRule.test.js +130 -0
  31. package/lib/methods/__tests__/contentHubSyncRule.test.js.map +1 -0
  32. package/lib/methods/__tests__/contentHubTagSync.test.d.ts +1 -0
  33. package/lib/methods/__tests__/contentHubTagSync.test.js +743 -0
  34. package/lib/methods/__tests__/contentHubTagSync.test.js.map +1 -0
  35. package/lib/methods/__tests__/tagLabel.test.d.ts +1 -0
  36. package/lib/methods/__tests__/tagLabel.test.js +136 -0
  37. package/lib/methods/__tests__/tagLabel.test.js.map +1 -0
  38. package/lib/methods/approval_engine.js +10 -7
  39. package/lib/methods/approval_engine.js.map +1 -1
  40. package/lib/methods/consts.d.ts +4 -0
  41. package/lib/methods/consts.js.map +1 -1
  42. package/lib/methods/content_hub.d.ts +8 -1
  43. package/lib/methods/content_hub.js +278 -27
  44. package/lib/methods/content_hub.js.map +1 -1
  45. package/lib/methods/content_hub_copyright.d.ts +15 -0
  46. package/lib/methods/content_hub_copyright.js +223 -0
  47. package/lib/methods/content_hub_copyright.js.map +1 -0
  48. package/lib/methods/content_hub_material_group.d.ts +29 -0
  49. package/lib/methods/content_hub_material_group.js +268 -0
  50. package/lib/methods/content_hub_material_group.js.map +1 -0
  51. package/lib/methods/content_hub_material_group_rule.d.ts +23 -0
  52. package/lib/methods/content_hub_material_group_rule.js +58 -0
  53. package/lib/methods/content_hub_material_group_rule.js.map +1 -0
  54. package/lib/methods/content_hub_sync_rule.d.ts +51 -0
  55. package/lib/methods/content_hub_sync_rule.js +122 -0
  56. package/lib/methods/content_hub_sync_rule.js.map +1 -0
  57. package/lib/methods/content_hub_tag.d.ts +57 -0
  58. package/lib/methods/content_hub_tag.js +830 -0
  59. package/lib/methods/content_hub_tag.js.map +1 -0
  60. package/lib/methods/pls.d.ts +4 -1
  61. package/lib/methods/pls.js +60 -51
  62. package/lib/methods/pls.js.map +1 -1
  63. package/lib/methods/tag_label.d.ts +19 -0
  64. package/lib/methods/tag_label.js +192 -0
  65. package/lib/methods/tag_label.js.map +1 -0
  66. package/main/default/applications/pepsico_content_setting.app.yml +8 -0
  67. package/main/default/objects/pepesio_ch__c/fields/media_type.field.yml +2 -0
  68. package/main/default/objects/pepesio_ch__c/fields/pepsico_material_approval.field.yml +6 -0
  69. package/main/default/objects/pepesio_ch__c/fields/push_status.field.yml +11 -0
  70. package/main/default/objects/pepesio_ch__c/fields/type.field.yml +48 -8
  71. package/main/default/objects/pepesio_ch__c/listviews/all.listview.yml +2 -0
  72. package/main/default/objects/pepsico_ch_material_group_rule/fields/active.field.yml +6 -0
  73. package/main/default/objects/pepsico_ch_material_group_rule/fields/classification.field.yml +73 -0
  74. package/main/default/objects/pepsico_ch_material_group_rule/fields/name.field.yml +9 -0
  75. package/main/default/objects/pepsico_ch_material_group_rule/fields/orgs.field.yml +10 -0
  76. package/main/default/objects/pepsico_ch_material_group_rule/fields/priority.field.yml +10 -0
  77. package/main/default/objects/pepsico_ch_material_group_rule/fields/query_mode.field.yml +12 -0
  78. package/main/default/objects/pepsico_ch_material_group_rule/fields/remark.field.yml +7 -0
  79. package/main/default/objects/pepsico_ch_material_group_rule/listviews/all.listview.yml +20 -0
  80. package/main/default/objects/pepsico_ch_material_group_rule/pepsico_ch_material_group_rule.object.yml +19 -0
  81. package/main/default/objects/pepsico_ch_material_group_rule/permissions/admin.permission.yml +15 -0
  82. package/main/default/objects/pepsico_ch_material_group_rule/permissions/user.permission.yml +14 -0
  83. package/main/default/objects/pepsico_ch_sync_rule/fields/active.field.yml +6 -0
  84. package/main/default/objects/pepsico_ch_sync_rule/fields/classification.field.yml +73 -0
  85. package/main/default/objects/pepsico_ch_sync_rule/fields/kol_classification.field.yml +67 -0
  86. package/main/default/objects/pepsico_ch_sync_rule/fields/name.field.yml +9 -0
  87. package/main/default/objects/pepsico_ch_sync_rule/fields/need_sync.field.yml +11 -0
  88. package/main/default/objects/pepsico_ch_sync_rule/fields/orgs.field.yml +10 -0
  89. package/main/default/objects/pepsico_ch_sync_rule/fields/priority.field.yml +10 -0
  90. package/main/default/objects/pepsico_ch_sync_rule/fields/product.field.yml +65 -0
  91. package/main/default/objects/pepsico_ch_sync_rule/fields/remark.field.yml +7 -0
  92. package/main/default/objects/pepsico_ch_sync_rule/fields/spot_check.field.yml +12 -0
  93. package/main/default/objects/pepsico_ch_sync_rule/listviews/all.listview.yml +24 -0
  94. package/main/default/objects/pepsico_ch_sync_rule/pepsico_ch_sync_rule.object.yml +19 -0
  95. package/main/default/objects/pepsico_ch_sync_rule/permissions/admin.permission.yml +15 -0
  96. package/main/default/objects/pepsico_ch_sync_rule/permissions/user.permission.yml +14 -0
  97. package/main/default/objects/pepsico_ch_tag_sync_log/fields/action.field.yml +6 -0
  98. package/main/default/objects/pepsico_ch_tag_sync_log/fields/changed_at.field.yml +6 -0
  99. package/main/default/objects/pepsico_ch_tag_sync_log/fields/duration.field.yml +6 -0
  100. package/main/default/objects/pepsico_ch_tag_sync_log/fields/error_code.field.yml +6 -0
  101. package/main/default/objects/pepsico_ch_tag_sync_log/fields/error_msg.field.yml +6 -0
  102. package/main/default/objects/pepsico_ch_tag_sync_log/fields/expired_date.field.yml +6 -0
  103. package/main/default/objects/pepsico_ch_tag_sync_log/fields/name.field.yml +7 -0
  104. package/main/default/objects/pepsico_ch_tag_sync_log/fields/parent_tag_val_id.field.yml +6 -0
  105. package/main/default/objects/pepsico_ch_tag_sync_log/fields/request_id.field.yml +7 -0
  106. package/main/default/objects/pepsico_ch_tag_sync_log/fields/result.field.yml +6 -0
  107. package/main/default/objects/pepsico_ch_tag_sync_log/fields/source_ip.field.yml +6 -0
  108. package/main/default/objects/pepsico_ch_tag_sync_log/fields/space.field.yml +6 -0
  109. package/main/default/objects/pepsico_ch_tag_sync_log/fields/tag_id.field.yml +6 -0
  110. package/main/default/objects/pepsico_ch_tag_sync_log/fields/tag_val_id.field.yml +7 -0
  111. package/main/default/objects/pepsico_ch_tag_sync_log/fields/tag_val_name.field.yml +6 -0
  112. package/main/default/objects/pepsico_ch_tag_sync_log/listviews/all.listview.yml +21 -0
  113. package/main/default/objects/pepsico_ch_tag_sync_log/pepsico_ch_tag_sync_log.object.yml +16 -0
  114. package/main/default/objects/pepsico_ch_tag_sync_log/permissions/admin.permission.yml +15 -0
  115. package/main/default/objects/pepsico_ch_tag_sync_log/permissions/user.permission.yml +14 -0
  116. package/main/default/objects/pepsico_ch_tag_sync_request/fields/changed_at.field.yml +6 -0
  117. package/main/default/objects/pepsico_ch_tag_sync_request/fields/duration.field.yml +6 -0
  118. package/main/default/objects/pepsico_ch_tag_sync_request/fields/expired_date.field.yml +6 -0
  119. package/main/default/objects/pepsico_ch_tag_sync_request/fields/item_count.field.yml +6 -0
  120. package/main/default/objects/pepsico_ch_tag_sync_request/fields/name.field.yml +7 -0
  121. package/main/default/objects/pepsico_ch_tag_sync_request/fields/request_id.field.yml +7 -0
  122. package/main/default/objects/pepsico_ch_tag_sync_request/fields/response.field.yml +9 -0
  123. package/main/default/objects/pepsico_ch_tag_sync_request/fields/result_code.field.yml +6 -0
  124. package/main/default/objects/pepsico_ch_tag_sync_request/fields/source_ip.field.yml +6 -0
  125. package/main/default/objects/pepsico_ch_tag_sync_request/fields/space.field.yml +6 -0
  126. package/main/default/objects/pepsico_ch_tag_sync_request/fields/tag_id.field.yml +6 -0
  127. package/main/default/objects/pepsico_ch_tag_sync_request/fields/tag_label.field.yml +6 -0
  128. package/main/default/objects/pepsico_ch_tag_sync_request/listviews/all.listview.yml +19 -0
  129. package/main/default/objects/pepsico_ch_tag_sync_request/pepsico_ch_tag_sync_request.object.yml +16 -0
  130. package/main/default/objects/pepsico_ch_tag_sync_request/permissions/admin.permission.yml +15 -0
  131. package/main/default/objects/pepsico_ch_tag_sync_request/permissions/user.permission.yml +14 -0
  132. package/main/default/objects/pepsico_material/fields/material_type_label.field.yml +10 -0
  133. package/main/default/objects/pepsico_material_approval/buttons/pepsico_confirm_online.button.yml +78 -1
  134. package/main/default/objects/pepsico_material_approval/buttons/pepsico_modify_pls.button.yml +1 -1
  135. package/main/default/objects/pepsico_material_approval/fields/available_channels.field.yml +2 -0
  136. package/main/default/objects/pepsico_material_approval/fields/available_channels_label.field.yml +10 -0
  137. package/main/default/objects/pepsico_material_approval/fields/ch_material_group.field.yml +56 -0
  138. package/main/default/objects/pepsico_material_approval/fields/ch_material_group_path.field.yml +14 -0
  139. package/main/default/objects/pepsico_material_approval/fields/ch_sync_enabled.field.yml +11 -0
  140. package/main/default/objects/pepsico_material_approval/fields/ch_sync_rule_check.field.yml +55 -0
  141. package/main/default/objects/pepsico_material_approval/fields/content_rule.field.yml +2 -0
  142. package/main/default/objects/pepsico_material_approval/fields/content_rule_label.field.yml +10 -0
  143. package/main/default/objects/pepsico_material_approval/fields/ec_check_food_name.field.yml +2 -2
  144. package/main/default/objects/pepsico_material_approval/fields/ec_check_ingredients.field.yml +2 -2
  145. package/main/default/objects/pepsico_material_approval/fields/ec_check_net_content.field.yml +2 -2
  146. package/main/default/objects/pepsico_material_approval/fields/ec_check_producer_address.field.yml +2 -2
  147. package/main/default/objects/pepsico_material_approval/fields/ec_check_producer_name.field.yml +2 -2
  148. package/main/default/objects/pepsico_material_approval/fields/ec_check_shelf_life.field.yml +2 -2
  149. package/main/default/objects/pepsico_material_approval/fields/ec_check_standard_code.field.yml +2 -2
  150. package/main/default/objects/pepsico_material_approval/fields/ec_check_storage_condition.field.yml +2 -2
  151. package/main/default/objects/pepsico_material_approval/fields/ec_has_detail_page.field.yml +1 -1
  152. package/main/default/objects/pepsico_material_approval/fields/ec_producers.field.yml +1 -1
  153. package/main/default/objects/pepsico_material_approval/fields/ec_qc_production_email.field.yml +2 -2
  154. package/main/default/objects/pepsico_material_approval/fields/ec_related_approval.field.yml +1 -1
  155. package/main/default/objects/pepsico_material_approval/fields/effective_date.field.yml +2 -0
  156. package/main/default/objects/pepsico_material_approval/fields/expiry_date.field.yml +2 -0
  157. package/main/default/objects/pepsico_material_approval/fields/form_version.field.yml +6 -2
  158. package/main/default/objects/pepsico_material_approval/fields/has_nutrition_table.field.yml +1 -1
  159. package/main/default/objects/pepsico_material_approval/fields/material_editable.field.yml +78 -0
  160. package/main/default/objects/pepsico_material_approval/fields/material_type.field.yml +2 -0
  161. package/main/default/objects/pepsico_material_approval/fields/material_type_label.field.yml +10 -0
  162. package/main/default/objects/pepsico_material_approval/fields/pls_file.field.yml +1 -1
  163. package/main/default/objects/pepsico_material_approval/fields/pls_km_files.field.yml +2 -5
  164. package/main/default/objects/pepsico_material_approval/fields/pls_upload_files.field.yml +1 -1
  165. package/main/default/objects/pepsico_material_approval/fields/product_label.field.yml +10 -0
  166. package/main/default/objects/pepsico_material_approval_data/fields/guding_pass.field.yml +9 -1
  167. package/main/default/objects/pepsico_material_data/fields/guding_pass.field.yml +9 -1
  168. package/main/default/objects/picklist_options/fields/ch_changed_at.field.yml +8 -0
  169. package/main/default/objects/picklist_options/picklist_options.object.yml +7 -0
  170. package/main/default/tabs/object_pepsico_ch_material_group_rule.tab.yml +8 -0
  171. package/main/default/tabs/object_pepsico_ch_sync_rule.tab.yml +8 -0
  172. package/main/default/triggers/pepsico_material_approval_tag_label.trigger.yml +80 -0
  173. package/main/default/triggers/pepsico_material_tag_label.trigger.yml +77 -0
  174. package/package.json +1 -1
  175. package/scripts/audit-legacy-tags.js +246 -0
  176. package/scripts/probe-content-hub-tags.js +134 -0
  177. package/main/default/objects/pepsico_material_approval/fields/has_detail_page.field.yml +0 -18
@@ -0,0 +1,830 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncTagValues = exports.purgeExpiredTagSyncLogs = exports.orderItemsByParent = exports.normalizeRequest = exports.isValidTagValId = exports.parseChangedAt = exports.httpStatusOf = exports.isTagSyncError = exports.TagSyncError = exports.ITEM_LOG_RETENTION_DAYS = exports.MAX_TAG_DEPTH = exports.REQUEST_LOG_RETENTION_DAYS = exports.MAX_REQUEST_ID_LENGTH = exports.MAX_TAG_VAL_ID_LENGTH = exports.MAX_NAME_LENGTH = exports.MAX_ITEMS_PER_BATCH = exports.TAG_SYNC_ACTIONS = exports.TagSyncAction = exports.TagSyncCode = exports.CONTENT_HUB_TAG_WHITELIST = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var _ = require("lodash");
6
+ exports.CONTENT_HUB_TAG_WHITELIST = {
7
+ '223321001114213': '品牌/产品',
8
+ '223321001114222': '素材类型',
9
+ '223321001114944': '可使用渠道',
10
+ '223321022150011': '素材授权规则'
11
+ };
12
+ exports.TagSyncCode = {
13
+ OK: 0,
14
+ PARTIAL: 1001,
15
+ BAD_REQUEST: 40001,
16
+ TAG_NOT_ALLOWED: 40002,
17
+ INVALID_TAG_VAL_ID: 40003,
18
+ PARENT_NOT_FOUND: 40004,
19
+ PARENT_IMMUTABLE: 40005,
20
+ TOO_MANY_ITEMS: 40006,
21
+ TAG_VAL_NOT_FOUND: 40007,
22
+ UNAUTHORIZED: 40101,
23
+ SERVER_ERROR: 50000
24
+ };
25
+ exports.TagSyncAction = {
26
+ upsert: 'upsert',
27
+ disable: 'disable',
28
+ enable: 'enable'
29
+ };
30
+ exports.TAG_SYNC_ACTIONS = [exports.TagSyncAction.upsert, exports.TagSyncAction.disable, exports.TagSyncAction.enable];
31
+ exports.MAX_ITEMS_PER_BATCH = 100;
32
+ exports.MAX_NAME_LENGTH = 100;
33
+ exports.MAX_TAG_VAL_ID_LENGTH = 64;
34
+ exports.MAX_REQUEST_ID_LENGTH = 128;
35
+ exports.REQUEST_LOG_RETENTION_DAYS = 7;
36
+ exports.MAX_TAG_DEPTH = 3;
37
+ exports.ITEM_LOG_RETENTION_DAYS = 90;
38
+ var LOG_OBJECT_NAME = 'pepsico_ch_tag_sync_log';
39
+ var REQUEST_OBJECT_NAME = 'pepsico_ch_tag_sync_request';
40
+ var CHANGED_AT_FIELD = 'ch_changed_at';
41
+ var TagSyncError = (function (_super) {
42
+ tslib_1.__extends(TagSyncError, _super);
43
+ function TagSyncError(code, message) {
44
+ var _this = _super.call(this, message) || this;
45
+ _this.isTagSyncError = true;
46
+ _this.code = code;
47
+ return _this;
48
+ }
49
+ return TagSyncError;
50
+ }(Error));
51
+ exports.TagSyncError = TagSyncError;
52
+ var isTagSyncError = function (error) { return !!(error && error.isTagSyncError); };
53
+ exports.isTagSyncError = isTagSyncError;
54
+ var httpStatusOf = function (code) {
55
+ if (code === exports.TagSyncCode.OK || code === exports.TagSyncCode.PARTIAL) {
56
+ return 200;
57
+ }
58
+ if (code === exports.TagSyncCode.UNAUTHORIZED) {
59
+ return 401;
60
+ }
61
+ if (code === exports.TagSyncCode.SERVER_ERROR) {
62
+ return 500;
63
+ }
64
+ return 400;
65
+ };
66
+ exports.httpStatusOf = httpStatusOf;
67
+ var ISO_WITH_OFFSET = /^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|z|[+-]\d{2}:?\d{2})$/;
68
+ var parseChangedAt = function (value) {
69
+ if (!_.isString(value)) {
70
+ return null;
71
+ }
72
+ var text = value.trim();
73
+ if (!ISO_WITH_OFFSET.test(text)) {
74
+ return null;
75
+ }
76
+ var date = new Date(text);
77
+ return isNaN(date.getTime()) ? null : date;
78
+ };
79
+ exports.parseChangedAt = parseChangedAt;
80
+ var TAG_VAL_ID_PATTERN = /^[A-Za-z0-9_]+$/;
81
+ var isValidTagValId = function (value) {
82
+ if (!_.isString(value)) {
83
+ return false;
84
+ }
85
+ var text = value.trim();
86
+ return !!text && TAG_VAL_ID_PATTERN.test(text) && text.length <= exports.MAX_TAG_VAL_ID_LENGTH;
87
+ };
88
+ exports.isValidTagValId = isValidTagValId;
89
+ var normalizeRequest = function (params) {
90
+ if (!_.isPlainObject(params)) {
91
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, '请求体格式错误');
92
+ }
93
+ if (_.every(['requestId', 'changedAt', 'tagId', 'items'], function (field) { return _.isNil(params[field]); })) {
94
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, '请求体为空或未被解析, 请确认已带上 Content-Type: application/json');
95
+ }
96
+ var requestId = _.isString(params.requestId) ? params.requestId.trim() : '';
97
+ if (!requestId || requestId.length > exports.MAX_REQUEST_ID_LENGTH) {
98
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, 'requestId 缺失或格式错误');
99
+ }
100
+ var batchChangedAt = (0, exports.parseChangedAt)(params.changedAt);
101
+ if (!batchChangedAt) {
102
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, 'changedAt 缺失或格式错误, 需为带时区偏移的 ISO 8601 时间');
103
+ }
104
+ var tagId = _.isString(params.tagId) ? params.tagId.trim() : '';
105
+ if (!tagId) {
106
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, 'tagId 缺失或格式错误');
107
+ }
108
+ if (!exports.CONTENT_HUB_TAG_WHITELIST[tagId]) {
109
+ throw new TagSyncError(exports.TagSyncCode.TAG_NOT_ALLOWED, "tagId \u4E0D\u5728\u6258\u7BA1\u767D\u540D\u5355: ".concat(tagId));
110
+ }
111
+ var rawItems = params.items;
112
+ if (!_.isArray(rawItems) || rawItems.length < 1) {
113
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, 'items 缺失或为空');
114
+ }
115
+ if (rawItems.length > exports.MAX_ITEMS_PER_BATCH) {
116
+ throw new TagSyncError(exports.TagSyncCode.TOO_MANY_ITEMS, "\u5355\u6279\u6761\u6570\u8D85\u8FC7 ".concat(exports.MAX_ITEMS_PER_BATCH, " \u6761"));
117
+ }
118
+ var seen = {};
119
+ var items = rawItems.map(function (raw, index) {
120
+ if (!_.isPlainObject(raw)) {
121
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "items[".concat(index, "] \u683C\u5F0F\u9519\u8BEF"));
122
+ }
123
+ var action = _.isNil(raw.action) || raw.action === '' ? exports.TagSyncAction.upsert : raw.action;
124
+ if (!_.includes(exports.TAG_SYNC_ACTIONS, action)) {
125
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "items[".concat(index, "].action \u975E\u6CD5: ").concat(raw.action));
126
+ }
127
+ if (!(0, exports.isValidTagValId)(raw.tagValId)) {
128
+ throw new TagSyncError(exports.TagSyncCode.INVALID_TAG_VAL_ID, "items[".concat(index, "].tagValId \u975E\u6CD5"));
129
+ }
130
+ var tagValId = raw.tagValId.trim();
131
+ if (seen[tagValId]) {
132
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "\u540C\u4E00\u6279\u6B21\u5185 tagValId \u91CD\u590D: ".concat(tagValId));
133
+ }
134
+ seen[tagValId] = true;
135
+ var name = null;
136
+ if (action === exports.TagSyncAction.upsert) {
137
+ if (!_.isString(raw.name) || !raw.name.trim()) {
138
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "items[".concat(index, "].name \u7F3A\u5931, upsert \u5FC5\u586B"));
139
+ }
140
+ name = raw.name.trim();
141
+ if (name.length > exports.MAX_NAME_LENGTH) {
142
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "items[".concat(index, "].name \u8D85\u8FC7 ").concat(exports.MAX_NAME_LENGTH, " \u4E2A\u5B57\u7B26"));
143
+ }
144
+ }
145
+ var parentTagValId = null;
146
+ if (!_.isNil(raw.parentTagValId) && raw.parentTagValId !== '') {
147
+ if (!(0, exports.isValidTagValId)(raw.parentTagValId)) {
148
+ throw new TagSyncError(exports.TagSyncCode.INVALID_TAG_VAL_ID, "items[".concat(index, "].parentTagValId \u975E\u6CD5"));
149
+ }
150
+ parentTagValId = raw.parentTagValId.trim();
151
+ if (parentTagValId === tagValId) {
152
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "items[".concat(index, "].parentTagValId \u4E0D\u80FD\u6307\u5411\u81EA\u8EAB"));
153
+ }
154
+ }
155
+ var changedAt = batchChangedAt;
156
+ if (!_.isNil(raw.changedAt) && raw.changedAt !== '') {
157
+ changedAt = (0, exports.parseChangedAt)(raw.changedAt);
158
+ if (!changedAt) {
159
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "items[".concat(index, "].changedAt \u683C\u5F0F\u9519\u8BEF, \u9700\u4E3A\u5E26\u65F6\u533A\u504F\u79FB\u7684 ISO 8601 \u65F6\u95F4"));
160
+ }
161
+ }
162
+ return { index: index, action: action, tagValId: tagValId, name: name, parentTagValId: parentTagValId, changedAt: changedAt };
163
+ });
164
+ return { requestId: requestId, tagId: tagId, changedAt: batchChangedAt, items: items };
165
+ };
166
+ exports.normalizeRequest = normalizeRequest;
167
+ var orderItemsByParent = function (items) {
168
+ var upsertByValue = {};
169
+ items.forEach(function (item) {
170
+ if (item.action === exports.TagSyncAction.upsert) {
171
+ upsertByValue[item.tagValId] = item;
172
+ }
173
+ });
174
+ var ordered = [];
175
+ var state = {};
176
+ var visit = function (item) {
177
+ if (state[item.tagValId]) {
178
+ return;
179
+ }
180
+ state[item.tagValId] = 1;
181
+ var parent = item.parentTagValId && upsertByValue[item.parentTagValId];
182
+ if (parent && state[parent.tagValId] !== 1) {
183
+ visit(parent);
184
+ }
185
+ state[item.tagValId] = 2;
186
+ ordered.push(item);
187
+ };
188
+ items.forEach(visit);
189
+ return ordered;
190
+ };
191
+ exports.orderItemsByParent = orderItemsByParent;
192
+ var buildDepthResolver = function (ctx, picklistId, items, optionByValue) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
193
+ var parentValueOf, byId, fetchById, storedDepthCache, storedDepth, resolved, items_1, items_1_1, item, depth, cursor, parentValue, stored, _a, e_1_1;
194
+ var e_1, _b;
195
+ return tslib_1.__generator(this, function (_c) {
196
+ switch (_c.label) {
197
+ case 0:
198
+ parentValueOf = {};
199
+ items.forEach(function (item) {
200
+ if (item.action === exports.TagSyncAction.upsert) {
201
+ parentValueOf[item.tagValId] = item.parentTagValId || null;
202
+ }
203
+ });
204
+ byId = _.keyBy(_.values(optionByValue), '_id');
205
+ fetchById = function (id) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
206
+ var found;
207
+ return tslib_1.__generator(this, function (_a) {
208
+ switch (_a.label) {
209
+ case 0:
210
+ if (!!(id in byId)) return [3, 2];
211
+ return [4, ctx.getObject('picklist_options').directFind({
212
+ filters: [['picklist', '=', picklistId], ['_id', '=', id]],
213
+ fields: ['_id', 'value', 'parent'],
214
+ top: 1
215
+ })];
216
+ case 1:
217
+ found = _a.sent();
218
+ byId[id] = (found && found[0]) || null;
219
+ _a.label = 2;
220
+ case 2: return [2, byId[id]];
221
+ }
222
+ });
223
+ }); };
224
+ storedDepthCache = {};
225
+ storedDepth = function (option) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
226
+ var depth, cursor, step;
227
+ return tslib_1.__generator(this, function (_a) {
228
+ switch (_a.label) {
229
+ case 0:
230
+ if (!option) {
231
+ return [2, 0];
232
+ }
233
+ if (storedDepthCache[option._id]) {
234
+ return [2, storedDepthCache[option._id]];
235
+ }
236
+ depth = 1;
237
+ cursor = option;
238
+ step = 0;
239
+ _a.label = 1;
240
+ case 1:
241
+ if (!(step < exports.MAX_TAG_DEPTH + 5 && cursor && cursor.parent)) return [3, 4];
242
+ return [4, fetchById(cursor.parent)];
243
+ case 2:
244
+ cursor = _a.sent();
245
+ if (!cursor) {
246
+ return [3, 4];
247
+ }
248
+ depth += 1;
249
+ _a.label = 3;
250
+ case 3:
251
+ step++;
252
+ return [3, 1];
253
+ case 4:
254
+ storedDepthCache[option._id] = depth;
255
+ return [2, depth];
256
+ }
257
+ });
258
+ }); };
259
+ resolved = {};
260
+ _c.label = 1;
261
+ case 1:
262
+ _c.trys.push([1, 9, 10, 11]);
263
+ items_1 = tslib_1.__values(items), items_1_1 = items_1.next();
264
+ _c.label = 2;
265
+ case 2:
266
+ if (!!items_1_1.done) return [3, 8];
267
+ item = items_1_1.value;
268
+ if (item.action !== exports.TagSyncAction.upsert || optionByValue[item.tagValId]) {
269
+ return [3, 7];
270
+ }
271
+ depth = 1;
272
+ cursor = item.tagValId;
273
+ _c.label = 3;
274
+ case 3:
275
+ if (!(depth <= exports.MAX_TAG_DEPTH + 2)) return [3, 6];
276
+ parentValue = parentValueOf[cursor];
277
+ if (!parentValue) {
278
+ return [3, 6];
279
+ }
280
+ stored = optionByValue[parentValue];
281
+ if (!stored) return [3, 5];
282
+ _a = depth;
283
+ return [4, storedDepth(stored)];
284
+ case 4:
285
+ depth = _a + _c.sent();
286
+ return [3, 6];
287
+ case 5:
288
+ if (!(parentValue in parentValueOf)) {
289
+ return [3, 6];
290
+ }
291
+ cursor = parentValue;
292
+ depth += 1;
293
+ return [3, 3];
294
+ case 6:
295
+ resolved[item.tagValId] = depth;
296
+ _c.label = 7;
297
+ case 7:
298
+ items_1_1 = items_1.next();
299
+ return [3, 2];
300
+ case 8: return [3, 11];
301
+ case 9:
302
+ e_1_1 = _c.sent();
303
+ e_1 = { error: e_1_1 };
304
+ return [3, 11];
305
+ case 10:
306
+ try {
307
+ if (items_1_1 && !items_1_1.done && (_b = items_1.return)) _b.call(items_1);
308
+ }
309
+ finally { if (e_1) throw e_1.error; }
310
+ return [7];
311
+ case 11: return [2, function (tagValId) { return resolved[tagValId] || 1; }];
312
+ }
313
+ });
314
+ }); };
315
+ var optionFields = ['_id', 'value', 'name', 'parent', 'enable', 'space', CHANGED_AT_FIELD];
316
+ var findProcessedRequest = function (ctx, requestId) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
317
+ var records, record;
318
+ return tslib_1.__generator(this, function (_a) {
319
+ switch (_a.label) {
320
+ case 0: return [4, ctx.getObject(REQUEST_OBJECT_NAME).directFind({
321
+ filters: [['request_id', '=', requestId]],
322
+ fields: ['_id', 'request_id', 'response'],
323
+ top: 1
324
+ })];
325
+ case 1:
326
+ records = _a.sent();
327
+ record = records && records[0];
328
+ if (!record || !record.response) {
329
+ return [2, null];
330
+ }
331
+ try {
332
+ return [2, JSON.parse(record.response)];
333
+ }
334
+ catch (e) {
335
+ return [2, null];
336
+ }
337
+ return [2];
338
+ }
339
+ });
340
+ }); };
341
+ var writeRequestSnapshot = function (ctx, _a) {
342
+ var requestId = _a.requestId, tagId = _a.tagId, changedAt = _a.changedAt, items = _a.items, code = _a.code, data = _a.data, space = _a.space, userId = _a.userId, sourceIp = _a.sourceIp, duration = _a.duration;
343
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
344
+ var now, expiredDate;
345
+ return tslib_1.__generator(this, function (_b) {
346
+ switch (_b.label) {
347
+ case 0:
348
+ now = new Date();
349
+ expiredDate = new Date(now.getTime() + exports.REQUEST_LOG_RETENTION_DAYS * 24 * 60 * 60 * 1000);
350
+ return [4, ctx.getObject(REQUEST_OBJECT_NAME).directInsert({
351
+ name: requestId,
352
+ request_id: requestId,
353
+ tag_id: tagId,
354
+ tag_label: exports.CONTENT_HUB_TAG_WHITELIST[tagId],
355
+ changed_at: changedAt,
356
+ item_count: items.length,
357
+ result_code: code,
358
+ response: JSON.stringify(data),
359
+ source_ip: sourceIp,
360
+ duration: duration,
361
+ expired_date: expiredDate,
362
+ space: space,
363
+ owner: userId,
364
+ created: now,
365
+ created_by: userId,
366
+ modified: now,
367
+ modified_by: userId
368
+ })];
369
+ case 1:
370
+ _b.sent();
371
+ return [2];
372
+ }
373
+ });
374
+ });
375
+ };
376
+ var writeItemLogs = function (ctx, _a) {
377
+ var requestId = _a.requestId, tagId = _a.tagId, items = _a.items, results = _a.results, space = _a.space, userId = _a.userId, sourceIp = _a.sourceIp, duration = _a.duration;
378
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
379
+ var now, expiredDate, logObj, items_2, items_2_1, item, result, e_2_1;
380
+ var e_2, _b;
381
+ return tslib_1.__generator(this, function (_c) {
382
+ switch (_c.label) {
383
+ case 0:
384
+ now = new Date();
385
+ expiredDate = new Date(now.getTime() + exports.ITEM_LOG_RETENTION_DAYS * 24 * 60 * 60 * 1000);
386
+ logObj = ctx.getObject(LOG_OBJECT_NAME);
387
+ _c.label = 1;
388
+ case 1:
389
+ _c.trys.push([1, 6, 7, 8]);
390
+ items_2 = tslib_1.__values(items), items_2_1 = items_2.next();
391
+ _c.label = 2;
392
+ case 2:
393
+ if (!!items_2_1.done) return [3, 5];
394
+ item = items_2_1.value;
395
+ result = results[item.index] || {};
396
+ return [4, logObj.directInsert({
397
+ name: "".concat(requestId, "-").concat(item.tagValId),
398
+ request_id: requestId,
399
+ changed_at: item.changedAt,
400
+ tag_id: tagId,
401
+ tag_val_id: item.tagValId,
402
+ tag_val_name: item.name,
403
+ parent_tag_val_id: item.parentTagValId,
404
+ action: item.action,
405
+ result: result.result,
406
+ error_code: result.code,
407
+ error_msg: result.msg,
408
+ source_ip: sourceIp,
409
+ duration: duration,
410
+ expired_date: expiredDate,
411
+ space: space,
412
+ owner: userId,
413
+ created: now,
414
+ created_by: userId,
415
+ modified: now,
416
+ modified_by: userId
417
+ })];
418
+ case 3:
419
+ _c.sent();
420
+ _c.label = 4;
421
+ case 4:
422
+ items_2_1 = items_2.next();
423
+ return [3, 2];
424
+ case 5: return [3, 8];
425
+ case 6:
426
+ e_2_1 = _c.sent();
427
+ e_2 = { error: e_2_1 };
428
+ return [3, 8];
429
+ case 7:
430
+ try {
431
+ if (items_2_1 && !items_2_1.done && (_b = items_2.return)) _b.call(items_2);
432
+ }
433
+ finally { if (e_2) throw e_2.error; }
434
+ return [7];
435
+ case 8: return [2];
436
+ }
437
+ });
438
+ });
439
+ };
440
+ var purgeExpiredRequests = function (ctx) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
441
+ var requestObj, expired, _a, _b, record, e_3_1, e_4;
442
+ var e_3, _c;
443
+ var _d;
444
+ return tslib_1.__generator(this, function (_e) {
445
+ switch (_e.label) {
446
+ case 0:
447
+ _e.trys.push([0, 10, , 12]);
448
+ requestObj = ctx.getObject(REQUEST_OBJECT_NAME);
449
+ return [4, requestObj.directFind({
450
+ filters: [['expired_date', '<', new Date()]],
451
+ fields: ['_id'],
452
+ top: exports.MAX_ITEMS_PER_BATCH
453
+ })];
454
+ case 1:
455
+ expired = _e.sent();
456
+ _e.label = 2;
457
+ case 2:
458
+ _e.trys.push([2, 7, 8, 9]);
459
+ _a = tslib_1.__values(expired || []), _b = _a.next();
460
+ _e.label = 3;
461
+ case 3:
462
+ if (!!_b.done) return [3, 6];
463
+ record = _b.value;
464
+ return [4, requestObj.directDelete(record._id)];
465
+ case 4:
466
+ _e.sent();
467
+ _e.label = 5;
468
+ case 5:
469
+ _b = _a.next();
470
+ return [3, 3];
471
+ case 6: return [3, 9];
472
+ case 7:
473
+ e_3_1 = _e.sent();
474
+ e_3 = { error: e_3_1 };
475
+ return [3, 9];
476
+ case 8:
477
+ try {
478
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
479
+ }
480
+ finally { if (e_3) throw e_3.error; }
481
+ return [7];
482
+ case 9: return [3, 12];
483
+ case 10:
484
+ e_4 = _e.sent();
485
+ return [4, ((_d = ctx.logger) === null || _d === void 0 ? void 0 : _d.warn('[Content Hub 标签同步]清理过期留存记录失败', { error: e_4.message }))];
486
+ case 11:
487
+ _e.sent();
488
+ return [3, 12];
489
+ case 12: return [2];
490
+ }
491
+ });
492
+ }); };
493
+ var purgeExpiredTagSyncLogs = function (ctx, batchSize) {
494
+ if (batchSize === void 0) { batchSize = 500; }
495
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
496
+ var logObj, expired, _a, _b, log, e_5_1, deleted;
497
+ var e_5, _c;
498
+ var _d;
499
+ return tslib_1.__generator(this, function (_e) {
500
+ switch (_e.label) {
501
+ case 0:
502
+ logObj = ctx.getObject(LOG_OBJECT_NAME);
503
+ return [4, logObj.directFind({
504
+ filters: [['expired_date', '<', new Date()]],
505
+ fields: ['_id'],
506
+ top: batchSize
507
+ })];
508
+ case 1:
509
+ expired = _e.sent();
510
+ _e.label = 2;
511
+ case 2:
512
+ _e.trys.push([2, 7, 8, 9]);
513
+ _a = tslib_1.__values(expired || []), _b = _a.next();
514
+ _e.label = 3;
515
+ case 3:
516
+ if (!!_b.done) return [3, 6];
517
+ log = _b.value;
518
+ return [4, logObj.directDelete(log._id)];
519
+ case 4:
520
+ _e.sent();
521
+ _e.label = 5;
522
+ case 5:
523
+ _b = _a.next();
524
+ return [3, 3];
525
+ case 6: return [3, 9];
526
+ case 7:
527
+ e_5_1 = _e.sent();
528
+ e_5 = { error: e_5_1 };
529
+ return [3, 9];
530
+ case 8:
531
+ try {
532
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
533
+ }
534
+ finally { if (e_5) throw e_5.error; }
535
+ return [7];
536
+ case 9:
537
+ deleted = (expired || []).length;
538
+ return [4, ((_d = ctx.logger) === null || _d === void 0 ? void 0 : _d.info('[Content Hub 标签同步]清理明细日志', { deleted: deleted }))];
539
+ case 10:
540
+ _e.sent();
541
+ return [2, { deleted: deleted, hasMore: deleted >= batchSize }];
542
+ }
543
+ });
544
+ });
545
+ };
546
+ exports.purgeExpiredTagSyncLogs = purgeExpiredTagSyncLogs;
547
+ var tagQueues = {};
548
+ var runSerialByTag = function (tagId, task) {
549
+ var previous = tagQueues[tagId] || Promise.resolve();
550
+ var current = previous.then(task, task);
551
+ tagQueues[tagId] = current.then(function () { return undefined; }, function () { return undefined; });
552
+ return current;
553
+ };
554
+ var syncTagValues = function (ctx, params) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
555
+ var normalized;
556
+ return tslib_1.__generator(this, function (_a) {
557
+ normalized = (0, exports.normalizeRequest)(params);
558
+ return [2, runSerialByTag(normalized.tagId, function () { return syncNormalizedTagValues(ctx, normalized); })];
559
+ });
560
+ }); };
561
+ exports.syncTagValues = syncTagValues;
562
+ var syncNormalizedTagValues = function (ctx, normalized) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
563
+ var startedAt, requestId, tagId, changedAt, items, sourceIp, processed, picklists, picklist, referenced, options, optionByValue, upsertValues, items_3, items_3_1, item, existing, parent, depthOf, items_4, items_4_1, item, depth, user, userId, space, results, optionsObj, _a, _b, item, _c, _d, e_6_1, data, code, duration;
564
+ var e_7, _e, e_8, _f, e_6, _g;
565
+ var _h, _j;
566
+ return tslib_1.__generator(this, function (_k) {
567
+ switch (_k.label) {
568
+ case 0:
569
+ startedAt = Date.now();
570
+ requestId = normalized.requestId, tagId = normalized.tagId, changedAt = normalized.changedAt, items = normalized.items;
571
+ sourceIp = (ctx.meta && ctx.meta.clientIp) || null;
572
+ return [4, findProcessedRequest(ctx, requestId)];
573
+ case 1:
574
+ processed = _k.sent();
575
+ if (!processed) return [3, 3];
576
+ return [4, ((_h = ctx.logger) === null || _h === void 0 ? void 0 : _h.info("[Content Hub \u6807\u7B7E\u540C\u6B65]\u547D\u4E2D\u5E42\u7B49-".concat(requestId), {
577
+ objectName: LOG_OBJECT_NAME,
578
+ request_id: requestId,
579
+ tag_id: tagId
580
+ }))];
581
+ case 2:
582
+ _k.sent();
583
+ return [2, {
584
+ code: processed.results && _.some(processed.results, { result: 'failed' }) ? exports.TagSyncCode.PARTIAL : exports.TagSyncCode.OK,
585
+ msg: '',
586
+ data: _.assign({}, processed, { idempotent: true })
587
+ }];
588
+ case 3: return [4, ctx.getObject('picklists').directFind({
589
+ filters: [['code', '=', tagId]],
590
+ fields: ['_id', 'name', 'space'],
591
+ top: 1
592
+ })];
593
+ case 4:
594
+ picklists = _k.sent();
595
+ picklist = picklists && picklists[0];
596
+ if (!picklist) {
597
+ throw new TagSyncError(exports.TagSyncCode.SERVER_ERROR, "\u6807\u7B7E\u7C7B\u76EE\u672A\u5728 Compliance \u4FA7\u5EFA\u6863: ".concat(tagId));
598
+ }
599
+ referenced = _.uniq(_.compact(_.flatten(items.map(function (item) { return [item.tagValId, item.parentTagValId]; }))));
600
+ return [4, ctx.getObject('picklist_options').directFind({
601
+ filters: [['picklist', '=', picklist._id], ['value', 'in', referenced]],
602
+ fields: optionFields
603
+ })];
604
+ case 5:
605
+ options = _k.sent();
606
+ optionByValue = _.keyBy(options, 'value');
607
+ upsertValues = {};
608
+ items.forEach(function (item) {
609
+ if (item.action === exports.TagSyncAction.upsert) {
610
+ upsertValues[item.tagValId] = true;
611
+ }
612
+ });
613
+ try {
614
+ for (items_3 = tslib_1.__values(items), items_3_1 = items_3.next(); !items_3_1.done; items_3_1 = items_3.next()) {
615
+ item = items_3_1.value;
616
+ existing = optionByValue[item.tagValId];
617
+ if (!item.parentTagValId) {
618
+ continue;
619
+ }
620
+ parent = optionByValue[item.parentTagValId];
621
+ if (!parent && !upsertValues[item.parentTagValId]) {
622
+ throw new TagSyncError(exports.TagSyncCode.PARENT_NOT_FOUND, "parentTagValId \u4E0D\u5B58\u5728: ".concat(item.parentTagValId));
623
+ }
624
+ if (existing && (!parent || existing.parent !== parent._id)) {
625
+ throw new TagSyncError(exports.TagSyncCode.PARENT_IMMUTABLE, "\u4E0D\u652F\u6301\u4FEE\u6539\u5DF2\u5B58\u5728\u8BB0\u5F55\u7684 parentTagValId: ".concat(item.tagValId));
626
+ }
627
+ }
628
+ }
629
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
630
+ finally {
631
+ try {
632
+ if (items_3_1 && !items_3_1.done && (_e = items_3.return)) _e.call(items_3);
633
+ }
634
+ finally { if (e_7) throw e_7.error; }
635
+ }
636
+ return [4, buildDepthResolver(ctx, picklist._id, items, optionByValue)];
637
+ case 6:
638
+ depthOf = _k.sent();
639
+ try {
640
+ for (items_4 = tslib_1.__values(items), items_4_1 = items_4.next(); !items_4_1.done; items_4_1 = items_4.next()) {
641
+ item = items_4_1.value;
642
+ if (item.action !== exports.TagSyncAction.upsert || optionByValue[item.tagValId]) {
643
+ continue;
644
+ }
645
+ depth = depthOf(item.tagValId);
646
+ if (depth > exports.MAX_TAG_DEPTH) {
647
+ throw new TagSyncError(exports.TagSyncCode.BAD_REQUEST, "\u6807\u7B7E\u5C42\u7EA7\u8D85\u8FC7 ".concat(exports.MAX_TAG_DEPTH, " \u5C42: ").concat(item.tagValId, "(\u7B2C ").concat(depth, " \u5C42)"));
648
+ }
649
+ }
650
+ }
651
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
652
+ finally {
653
+ try {
654
+ if (items_4_1 && !items_4_1.done && (_f = items_4.return)) _f.call(items_4);
655
+ }
656
+ finally { if (e_8) throw e_8.error; }
657
+ }
658
+ user = (ctx.meta && ctx.meta.user) || {};
659
+ userId = user.userId;
660
+ space = picklist.space || user.spaceId;
661
+ results = [];
662
+ optionsObj = ctx.getObject('picklist_options');
663
+ _k.label = 7;
664
+ case 7:
665
+ _k.trys.push([7, 12, 13, 14]);
666
+ _a = tslib_1.__values((0, exports.orderItemsByParent)(items)), _b = _a.next();
667
+ _k.label = 8;
668
+ case 8:
669
+ if (!!_b.done) return [3, 11];
670
+ item = _b.value;
671
+ _c = results;
672
+ _d = item.index;
673
+ return [4, applyItem(ctx, {
674
+ item: item,
675
+ picklist: picklist,
676
+ optionByValue: optionByValue,
677
+ optionsObj: optionsObj,
678
+ space: space,
679
+ userId: userId
680
+ })];
681
+ case 9:
682
+ _c[_d] = _k.sent();
683
+ _k.label = 10;
684
+ case 10:
685
+ _b = _a.next();
686
+ return [3, 8];
687
+ case 11: return [3, 14];
688
+ case 12:
689
+ e_6_1 = _k.sent();
690
+ e_6 = { error: e_6_1 };
691
+ return [3, 14];
692
+ case 13:
693
+ try {
694
+ if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
695
+ }
696
+ finally { if (e_6) throw e_6.error; }
697
+ return [7];
698
+ case 14:
699
+ data = {
700
+ requestId: requestId,
701
+ idempotent: false,
702
+ results: results
703
+ };
704
+ code = _.some(results, { result: 'failed' }) ? exports.TagSyncCode.PARTIAL : exports.TagSyncCode.OK;
705
+ duration = Date.now() - startedAt;
706
+ return [4, writeRequestSnapshot(ctx, { requestId: requestId, tagId: tagId, changedAt: changedAt, items: items, code: code, data: data, space: space, userId: userId, sourceIp: sourceIp, duration: duration })];
707
+ case 15:
708
+ _k.sent();
709
+ return [4, writeItemLogs(ctx, { requestId: requestId, tagId: tagId, items: items, results: results, space: space, userId: userId, sourceIp: sourceIp, duration: duration })];
710
+ case 16:
711
+ _k.sent();
712
+ return [4, purgeExpiredRequests(ctx)];
713
+ case 17:
714
+ _k.sent();
715
+ return [4, ((_j = ctx.logger) === null || _j === void 0 ? void 0 : _j.info("[Content Hub \u6807\u7B7E\u540C\u6B65]-".concat(requestId), {
716
+ objectName: 'picklist_options',
717
+ request_id: requestId,
718
+ tag_id: tagId,
719
+ code: code,
720
+ results: results
721
+ }))];
722
+ case 18:
723
+ _k.sent();
724
+ return [2, { code: code, msg: '', data: data }];
725
+ }
726
+ });
727
+ }); };
728
+ var applyItem = function (ctx, _a) {
729
+ var item = _a.item, picklist = _a.picklist, optionByValue = _a.optionByValue, optionsObj = _a.optionsObj, space = _a.space, userId = _a.userId;
730
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
731
+ var action, tagValId, name, parentTagValId, changedAt, existing, applied, now, parent, created, changedField, resultName, target, current, updates, error_1;
732
+ var _b, _c, _d, _e;
733
+ var _f;
734
+ return tslib_1.__generator(this, function (_g) {
735
+ switch (_g.label) {
736
+ case 0:
737
+ action = item.action, tagValId = item.tagValId, name = item.name, parentTagValId = item.parentTagValId, changedAt = item.changedAt;
738
+ _g.label = 1;
739
+ case 1:
740
+ _g.trys.push([1, 5, , 7]);
741
+ existing = optionByValue[tagValId];
742
+ if (action !== exports.TagSyncAction.upsert && !existing) {
743
+ return [2, { tagValId: tagValId, result: 'failed', code: exports.TagSyncCode.TAG_VAL_NOT_FOUND, msg: 'tagValId 不存在' }];
744
+ }
745
+ if (existing && existing[CHANGED_AT_FIELD]) {
746
+ applied = new Date(existing[CHANGED_AT_FIELD]);
747
+ if (!isNaN(applied.getTime()) && changedAt.getTime() < applied.getTime()) {
748
+ return [2, { tagValId: tagValId, result: 'stale' }];
749
+ }
750
+ }
751
+ now = new Date();
752
+ if (!!existing) return [3, 3];
753
+ parent = parentTagValId ? optionByValue[parentTagValId] : null;
754
+ if (parentTagValId && !parent) {
755
+ return [2, { tagValId: tagValId, result: 'failed', code: exports.TagSyncCode.PARENT_NOT_FOUND, msg: 'parentTagValId 不存在' }];
756
+ }
757
+ return [4, optionsObj.directInsert((_b = {
758
+ picklist: picklist._id,
759
+ value: tagValId,
760
+ name: name,
761
+ parent: parent ? parent._id : null,
762
+ enable: true
763
+ },
764
+ _b[CHANGED_AT_FIELD] = changedAt,
765
+ _b.space = space,
766
+ _b.owner = userId,
767
+ _b.created = now,
768
+ _b.created_by = userId,
769
+ _b.modified = now,
770
+ _b.modified_by = userId,
771
+ _b))];
772
+ case 2:
773
+ created = _g.sent();
774
+ optionByValue[tagValId] = _.assign({}, created, (_c = {
775
+ _id: created._id,
776
+ value: tagValId,
777
+ name: name,
778
+ parent: parent ? parent._id : null,
779
+ enable: true
780
+ },
781
+ _c[CHANGED_AT_FIELD] = changedAt,
782
+ _c));
783
+ return [2, { tagValId: tagValId, result: 'created' }];
784
+ case 3:
785
+ changedField = null;
786
+ resultName = 'unchanged';
787
+ if (action === exports.TagSyncAction.upsert) {
788
+ if (existing.name !== name) {
789
+ changedField = { name: name };
790
+ resultName = 'updated';
791
+ }
792
+ }
793
+ else {
794
+ target = action === exports.TagSyncAction.enable;
795
+ current = existing.enable !== false;
796
+ if (current !== target) {
797
+ changedField = { enable: target };
798
+ resultName = target ? 'enabled' : 'disabled';
799
+ }
800
+ else if (existing.enable !== target) {
801
+ changedField = { enable: target };
802
+ }
803
+ }
804
+ updates = _.assign({}, changedField, (_d = {},
805
+ _d[CHANGED_AT_FIELD] = changedAt,
806
+ _d.modified = now,
807
+ _d.modified_by = userId,
808
+ _d));
809
+ return [4, optionsObj.directUpdate(existing._id, updates)];
810
+ case 4:
811
+ _g.sent();
812
+ optionByValue[tagValId] = _.assign({}, existing, changedField, (_e = {}, _e[CHANGED_AT_FIELD] = changedAt, _e));
813
+ return [2, { tagValId: tagValId, result: resultName }];
814
+ case 5:
815
+ error_1 = _g.sent();
816
+ return [4, ((_f = ctx.logger) === null || _f === void 0 ? void 0 : _f.error("[Content Hub \u6807\u7B7E\u540C\u6B65]\u5355\u6761\u5904\u7406\u5931\u8D25-".concat(tagValId), {
817
+ objectName: 'picklist_options',
818
+ tag_val_id: tagValId,
819
+ action: action,
820
+ error: error_1.message
821
+ }))];
822
+ case 6:
823
+ _g.sent();
824
+ return [2, { tagValId: tagValId, result: 'failed', code: exports.TagSyncCode.SERVER_ERROR, msg: error_1.message }];
825
+ case 7: return [2];
826
+ }
827
+ });
828
+ });
829
+ };
830
+ //# sourceMappingURL=content_hub_tag.js.map