snow-flow 3.6.19 → 3.6.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -797,14 +797,17 @@ ${args.help_text ? `❓ Help: ${args.help_text}` : ''}
797
797
  }
798
798
  /**
799
799
  * Create Catalog UI Policy with Actions
800
- * Creates records in 2 tables: sys_ui_policy and catalog_ui_policy_action
800
+ * Creates records in 2 tables: catalog_ui_policy and catalog_ui_policy_action
801
801
  *
802
- * ✅ CORRECTED STRUCTURE (v3.6.18):
803
- * - Main policy goes in sys_ui_policy table (NOT catalog_ui_policy!)
804
- * - Actions go in catalog_ui_policy_action table
805
- * - Actions reference sys_ui_policy via ui_policy field (using policy name)
802
+ * ✅ CORRECTED STRUCTURE (v3.6.21):
803
+ * - Main policy goes in catalog_ui_policy table (NOT sys_ui_policy!)
804
+ * - Actions go in catalog_ui_policy_action table (inherits from sys_ui_policy_action)
805
+ * - Actions reference catalog_ui_policy via ui_policy field (using policy sys_id directly)
806
806
  * - Conditions use IO:sys_id format for catalog variables
807
807
  * - catalog_ui_policy_action.catalog_variable uses IO:sys_id format
808
+ * - visible/mandatory/disabled use "ignore" as default, not false or empty
809
+ * - Reference fields are set directly for reliability
810
+ * - Enhanced verification ensures all critical fields are populated
808
811
  */
809
812
  async createCatalogUIPolicy(args) {
810
813
  try {
@@ -978,24 +981,23 @@ ${args.help_text ? `❓ Help: ${args.help_text}` : ''}
978
981
  conditionString = conditionParts.join('^');
979
982
  this.logger.info(`✅ Built conditions string: "${conditionString}"`);
980
983
  }
981
- // ✅ CRITICAL FIX: Create in sys_ui_policy table, NOT catalog_ui_policy!
982
- // The actions reference sys_ui_policy, not catalog_ui_policy
984
+ // ✅ CRITICAL FIX: Create in catalog_ui_policy table!
985
+ // The actions reference catalog_ui_policy, NOT sys_ui_policy!
983
986
  const policyData = {
984
- // sys_ui_policy fields are different from catalog_ui_policy!
985
- name: args.short_description, // sys_ui_policy uses 'name' not 'short_description'
986
- table: 'sc_cat_item', // The table this policy applies to
987
- conditions: conditionString || args.condition || '', // Condition string
987
+ // catalog_ui_policy fields
988
+ short_description: args.short_description,
989
+ catalog_item: args.cat_item, // Reference to the catalog item
990
+ catalog_conditions: conditionString || args.condition || '', // Conditions as string
991
+ applies_catalog: true, // This is a catalog policy
988
992
  active: args.active !== false,
989
- on_load: args.on_load !== false, // Different field name in sys_ui_policy
993
+ applies_on: args.applies_on || 'true', // When to apply: 'true', 'false', or 'both'
990
994
  reverse_if_false: args.reverse_if_false !== false,
991
- // Link to the catalog item via a different field
992
- catalog_item: args.cat_item,
993
995
  // Optional script fields
994
996
  script_true: args.script_true || '',
995
997
  script_false: args.script_false || ''
996
998
  };
997
- this.logger.info('🎯 Creating main policy in sys_ui_policy table with data:', policyData);
998
- const policyResponse = await this.client.createRecord('sys_ui_policy', policyData);
999
+ this.logger.info('🎯 Creating main policy in catalog_ui_policy table with data:', policyData);
1000
+ const policyResponse = await this.client.createRecord('catalog_ui_policy', policyData);
999
1001
  if (!policyResponse.success) {
1000
1002
  this.logger.error('❌ Policy creation failed:', policyResponse.error);
1001
1003
  throw new Error(`Failed to create catalog UI policy: ${policyResponse.error}`);
@@ -1034,39 +1036,56 @@ ${args.help_text ? `❓ Help: ${args.help_text}` : ''}
1034
1036
  // Actions structure in ServiceNow:
1035
1037
  // - catalog_ui_policy_action.catalog_variable -> "IO:" + variable_sys_id (required format)
1036
1038
  // - catalog_ui_policy_action.ui_policy -> catalog_ui_policy.sys_id
1037
- // ✅ CRITICAL FIX: Reference fields MUST be objects or sys_ids, not names!
1038
- // ServiceNow reference fields expect either:
1039
- // 1. Just the sys_id as a string
1040
- // 2. An object with { value: sys_id, link: url }
1041
- const actionData = {
1042
- // ✅ catalog_variable uses IO:sys_id format (this is a STRING field, not a reference)
1043
- catalog_variable: catalogVariableWithPrefix,
1044
- // ✅ ui_policy is a REFERENCE field - use the sys_id directly!
1045
- ui_policy: policyId, // Use the policy sys_id from sys_ui_policy
1046
- // catalog_item is also a REFERENCE field - use the sys_id
1047
- catalog_item: args.cat_item // The catalog item sys_id
1048
- };
1049
- this.logger.info(`🔗 Linking action to:`);
1050
- this.logger.info(` - Policy: ${policyId} (sys_ui_policy sys_id)`);
1051
- this.logger.info(` - Variable: ${catalogVariableWithPrefix} (with IO: prefix)`);
1052
- this.logger.info(` - Catalog Item: ${args.cat_item}`);
1053
- // Voeg alleen GEDEFINIEERDE action properties toe
1039
+ // ✅ CRITICAL: Build action data according to ServiceNow's exact structure
1040
+ // catalog_ui_policy_action inherits from sys_ui_policy_action
1041
+ // We must set fields in the correct way for ServiceNow to accept them
1042
+ const actionData = {};
1043
+ // STEP 1: Set reference fields (MUST be set first for ServiceNow)
1044
+ // ✅ ui_policy is a reference to sys_ui_policy - use sys_id directly
1045
+ actionData.ui_policy = policyId;
1046
+ // ✅ catalog_item is a reference to sc_cat_item - use sys_id directly
1047
+ actionData.catalog_item = args.cat_item;
1048
+ // STEP 2: Set the catalog_variable with IO: prefix (STRING field, not reference)
1049
+ actionData.catalog_variable = catalogVariableWithPrefix;
1050
+ // STEP 3: Set action properties with correct values
1051
+ // CRITICAL: Use "ignore" instead of not setting or using false
1052
+ // This is how ServiceNow differentiates between "don't change" and "set to false"
1053
+ if (action.visible !== undefined) {
1054
+ actionData.visible = action.visible === true ? 'true' :
1055
+ action.visible === false ? 'false' : 'ignore';
1056
+ }
1057
+ else {
1058
+ actionData.visible = 'ignore'; // Default to ignore if not specified
1059
+ }
1054
1060
  if (action.mandatory !== undefined) {
1055
- actionData.mandatory = action.mandatory === true ? 'true' : action.mandatory === false ? 'false' : 'ignore';
1061
+ actionData.mandatory = action.mandatory === true ? 'true' :
1062
+ action.mandatory === false ? 'false' : 'ignore';
1056
1063
  }
1057
- if (action.visible !== undefined) {
1058
- actionData.visible = action.visible === false ? 'false' : action.visible === true ? 'true' : 'ignore';
1064
+ else {
1065
+ actionData.mandatory = 'ignore'; // Default to ignore if not specified
1059
1066
  }
1060
1067
  if (action.readonly !== undefined) {
1061
- actionData.disabled = action.readonly === true ? 'true' : action.readonly === false ? 'false' : 'ignore';
1068
+ actionData.disabled = action.readonly === true ? 'true' :
1069
+ action.readonly === false ? 'false' : 'ignore';
1070
+ }
1071
+ else {
1072
+ actionData.disabled = 'ignore'; // Default to ignore if not specified
1062
1073
  }
1063
- if (action.value) {
1064
- actionData.value = action.value;
1074
+ // STEP 4: Set optional value field
1075
+ if (action.value !== undefined && action.value !== null && action.value !== '') {
1076
+ actionData.value = String(action.value);
1065
1077
  }
1066
- // Basis metadata
1078
+ // STEP 5: Set other metadata
1067
1079
  actionData.order = (i + 1) * 100;
1068
1080
  actionData.active = true;
1069
- this.logger.info(`🎯 Attempting to create action ${i + 1}:`, actionData);
1081
+ this.logger.info(`🔗 Creating action with proper structure:`);
1082
+ this.logger.info(` - ui_policy (ref): ${policyId}`);
1083
+ this.logger.info(` - catalog_item (ref): ${args.cat_item}`);
1084
+ this.logger.info(` - catalog_variable: ${catalogVariableWithPrefix}`);
1085
+ this.logger.info(` - visible: ${actionData.visible}`);
1086
+ this.logger.info(` - mandatory: ${actionData.mandatory}`);
1087
+ this.logger.info(` - disabled: ${actionData.disabled}`);
1088
+ this.logger.info(`🎯 Attempting to create action ${i + 1} in catalog_ui_policy_action table...`);
1070
1089
  const actionResponse = await this.client.createRecord('catalog_ui_policy_action', actionData);
1071
1090
  if (actionResponse.success) {
1072
1091
  const createdActionId = actionResponse.data.sys_id;
@@ -1089,19 +1108,42 @@ ${args.help_text ? `❓ Help: ${args.help_text}` : ''}
1089
1108
  mandatory: createdAction.mandatory,
1090
1109
  disabled: createdAction.disabled
1091
1110
  });
1092
- // Check if critical fields are populated
1093
- if (!createdAction.ui_policy || createdAction.ui_policy === '') {
1111
+ // ✅ ENHANCED VERIFICATION: Check if critical fields are populated correctly
1112
+ const uiPolicyValue = createdAction.ui_policy;
1113
+ const catalogVariableValue = createdAction.catalog_variable;
1114
+ const catalogItemValue = createdAction.catalog_item;
1115
+ // Check ui_policy reference
1116
+ if (!uiPolicyValue || uiPolicyValue === '' || uiPolicyValue === '{}') {
1094
1117
  this.logger.error(`❌ CRITICAL: ui_policy field is EMPTY for action ${i + 1}!`);
1118
+ this.logger.error(`❌ Expected: ${policyId}, Got: ${uiPolicyValue}`);
1095
1119
  throw new Error(`Action ${i + 1} created but ui_policy field is empty - action will not work!`);
1096
1120
  }
1097
- if (!createdAction.catalog_variable || createdAction.catalog_variable === '') {
1121
+ // For reference fields, ServiceNow might return an object - extract the value
1122
+ const uiPolicySysId = typeof uiPolicyValue === 'object' && uiPolicyValue.value ?
1123
+ uiPolicyValue.value : uiPolicyValue;
1124
+ if (uiPolicySysId !== policyId) {
1125
+ this.logger.warn(`⚠️ ui_policy mismatch - Expected: ${policyId}, Got: ${uiPolicySysId}`);
1126
+ }
1127
+ // Check catalog_variable (should have IO: prefix)
1128
+ if (!catalogVariableValue || catalogVariableValue === '') {
1098
1129
  this.logger.error(`❌ CRITICAL: catalog_variable field is EMPTY for action ${i + 1}!`);
1130
+ this.logger.error(`❌ Expected: ${catalogVariableWithPrefix}, Got: ${catalogVariableValue}`);
1099
1131
  throw new Error(`Action ${i + 1} created but catalog_variable field is empty - action will not work!`);
1100
1132
  }
1101
- if (!createdAction.catalog_item || createdAction.catalog_item === '') {
1133
+ if (!catalogVariableValue.startsWith('IO:')) {
1134
+ this.logger.warn(`⚠️ catalog_variable missing IO: prefix - Got: ${catalogVariableValue}`);
1135
+ }
1136
+ // Check catalog_item reference
1137
+ if (!catalogItemValue || catalogItemValue === '' || catalogItemValue === '{}') {
1102
1138
  this.logger.error(`❌ CRITICAL: catalog_item field is EMPTY for action ${i + 1}!`);
1139
+ this.logger.error(`❌ Expected: ${args.cat_item}, Got: ${catalogItemValue}`);
1103
1140
  throw new Error(`Action ${i + 1} created but catalog_item field is empty - action will not work!`);
1104
1141
  }
1142
+ const catalogItemSysId = typeof catalogItemValue === 'object' && catalogItemValue.value ?
1143
+ catalogItemValue.value : catalogItemValue;
1144
+ if (catalogItemSysId !== args.cat_item) {
1145
+ this.logger.warn(`⚠️ catalog_item mismatch - Expected: ${args.cat_item}, Got: ${catalogItemSysId}`);
1146
+ }
1105
1147
  this.logger.info(`✅ Action ${i + 1} verified in database with all fields populated`);
1106
1148
  createdActions.push({
1107
1149
  sys_id: createdActionId,
@@ -1123,27 +1165,27 @@ ${args.help_text ? `❓ Help: ${args.help_text}` : ''}
1123
1165
  }
1124
1166
  }
1125
1167
  }
1126
- // 🔍 FINAL VERIFICATION: Policy creation in sys_ui_policy table
1127
- this.logger.info('🔍 Final verification: Checking policy in sys_ui_policy table...');
1128
- const policyVerification = await this.client.searchRecords('sys_ui_policy', `sys_id=${policyId}`, 1);
1168
+ // 🔍 FINAL VERIFICATION: Policy creation in catalog_ui_policy table
1169
+ this.logger.info('🔍 Final verification: Checking policy in catalog_ui_policy table...');
1170
+ const policyVerification = await this.client.searchRecords('catalog_ui_policy', `sys_id=${policyId}`, 1);
1129
1171
  if (!policyVerification.success || policyVerification.data.result.length === 0) {
1130
- this.logger.error('❌ POLICY VERIFICATION FAILED: Policy not found in sys_ui_policy table!');
1131
- throw new Error(`Policy creation verification failed - policy not found in sys_ui_policy table`);
1172
+ this.logger.error('❌ POLICY VERIFICATION FAILED: Policy not found in catalog_ui_policy table!');
1173
+ throw new Error(`Policy creation verification failed - policy not found in catalog_ui_policy table`);
1132
1174
  }
1133
- this.logger.info('✅ Policy verified in sys_ui_policy table');
1175
+ this.logger.info('✅ Policy verified in catalog_ui_policy table');
1134
1176
  // Build comprehensive response
1135
- let responseText = `✅ UI Policy created successfully in sys_ui_policy table!
1177
+ let responseText = `✅ Catalog UI Policy created successfully!
1136
1178
 
1137
1179
  📋 **${args.short_description}**
1138
1180
  🆔 Policy sys_id: ${policyId}
1139
- 📊 Table: sys_ui_policy (correct table for catalog UI policy actions)
1140
- 🎯 Target Table: sc_cat_item
1181
+ 📊 Table: catalog_ui_policy (correct table for catalog actions)
1182
+ 🎯 Catalog Item: ${args.cat_item}
1141
1183
  🔄 Active: ${args.active !== false ? 'Yes' : 'No'}
1142
- ⚡ On Load: ${args.on_load !== false ? 'Yes' : 'No'}
1184
+ Applies On: ${args.applies_on || 'true'}
1143
1185
  🔁 Reverse if False: ${args.reverse_if_false !== false ? 'Yes' : 'No'}
1144
1186
 
1145
1187
  🔍 **Verification Results:**
1146
- ✅ Policy record created in sys_ui_policy table
1188
+ ✅ Policy record created in catalog_ui_policy table
1147
1189
  ✅ ${createdActions.length} actions created in catalog_ui_policy_action table`;
1148
1190
  if (conditionString) {
1149
1191
  responseText += `\n\n📝 **Conditions:**\n${conditionString}`;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "3.6.19",
4
- "description": "CRITICAL REFERENCE FIELD FIX - v3.6.19 fixes empty action fields by using sys_ids directly for reference fields (ui_policy, catalog_item) instead of names/objects. Added comprehensive verification to ensure all critical fields are populated. Actions now correctly link to sys_ui_policy with actual sys_id values, not empty strings.",
3
+ "version": "3.6.21",
4
+ "description": "CRITICAL TABLE FIX - v3.6.21 fixes fundamental issue: policies now created in catalog_ui_policy table (NOT sys_ui_policy!). Actions correctly reference catalog_ui_policy records. This matches ServiceNow's actual structure where catalog_ui_policy_action.ui_policy references catalog_ui_policy table, not sys_ui_policy.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",
7
7
  "bin": {