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:
|
|
800
|
+
* Creates records in 2 tables: catalog_ui_policy and catalog_ui_policy_action
|
|
801
801
|
*
|
|
802
|
-
* ✅ CORRECTED STRUCTURE (v3.6.
|
|
803
|
-
* - Main policy goes in
|
|
804
|
-
* - Actions go in catalog_ui_policy_action table
|
|
805
|
-
* - Actions reference
|
|
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
|
|
982
|
-
// The actions reference
|
|
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
|
-
//
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
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
|
-
|
|
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
|
|
998
|
-
const policyResponse = await this.client.createRecord('
|
|
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
|
|
1038
|
-
//
|
|
1039
|
-
//
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
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' :
|
|
1061
|
+
actionData.mandatory = action.mandatory === true ? 'true' :
|
|
1062
|
+
action.mandatory === false ? 'false' : 'ignore';
|
|
1056
1063
|
}
|
|
1057
|
-
|
|
1058
|
-
actionData.
|
|
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' :
|
|
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
|
-
|
|
1064
|
-
|
|
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
|
-
//
|
|
1078
|
+
// STEP 5: Set other metadata
|
|
1067
1079
|
actionData.order = (i + 1) * 100;
|
|
1068
1080
|
actionData.active = true;
|
|
1069
|
-
this.logger.info(
|
|
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
|
-
|
|
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
|
-
|
|
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 (!
|
|
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
|
|
1127
|
-
this.logger.info('🔍 Final verification: Checking policy in
|
|
1128
|
-
const policyVerification = await this.client.searchRecords('
|
|
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
|
|
1131
|
-
throw new Error(`Policy creation verification failed - policy not found in
|
|
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
|
|
1175
|
+
this.logger.info('✅ Policy verified in catalog_ui_policy table');
|
|
1134
1176
|
// Build comprehensive response
|
|
1135
|
-
let responseText = `✅ UI Policy created successfully
|
|
1177
|
+
let responseText = `✅ Catalog UI Policy created successfully!
|
|
1136
1178
|
|
|
1137
1179
|
📋 **${args.short_description}**
|
|
1138
1180
|
🆔 Policy sys_id: ${policyId}
|
|
1139
|
-
📊 Table:
|
|
1140
|
-
🎯
|
|
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
|
|
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
|
|
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.
|
|
4
|
-
"description": "CRITICAL
|
|
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": {
|