snow-flow 3.6.15 → 3.6.17

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.
@@ -807,23 +807,102 @@ ${args.help_text ? `❓ Help: ${args.help_text}` : ''}
807
807
  async createCatalogUIPolicy(args) {
808
808
  try {
809
809
  this.logger.info('Creating comprehensive catalog UI policy...');
810
- // Helper function to resolve variable names to sys_ids
810
+ // First, let's fetch ALL variables for this catalog item for debugging
811
+ this.logger.info(`📋 Fetching all variables for catalog item ${args.cat_item} for debugging...`);
812
+ try {
813
+ const allVarsResponse = await this.client.searchRecords('sc_cat_item_option', `cat_item=${args.cat_item}`, 100);
814
+ if (allVarsResponse.success && allVarsResponse.data.result.length > 0) {
815
+ this.logger.info(`📊 Found ${allVarsResponse.data.result.length} variables for this catalog item:`);
816
+ allVarsResponse.data.result.forEach((v) => {
817
+ this.logger.info(` - Variable: name='${v.name}', sys_id='${v.sys_id}', question='${v.question_text}'`);
818
+ });
819
+ }
820
+ else {
821
+ this.logger.warn(`⚠️ No variables found for catalog item ${args.cat_item} - this might be a problem!`);
822
+ }
823
+ }
824
+ catch (error) {
825
+ this.logger.error(`❌ Failed to fetch variables for debugging:`, error);
826
+ }
827
+ // Helper function to resolve variable names to sys_ids with MULTIPLE FALLBACKS
811
828
  const resolveVariableId = async (variableName, catalogItem) => {
812
829
  // If already a sys_id, return as-is
813
830
  if (variableName && variableName.match(/^[a-f0-9]{32}$/)) {
814
831
  this.logger.info(`✅ Using sys_id directly: ${variableName}`);
815
832
  return variableName;
816
833
  }
817
- // Search for variable by name in this catalog item
818
- this.logger.info(`🔍 Resolving variable name '${variableName}' to sys_id...`);
819
- const varResponse = await this.client.searchRecords('sc_cat_item_option', `cat_item=${catalogItem}^name=${variableName}`, 1);
820
- if (varResponse.success && varResponse.data.result.length > 0) {
821
- const sysId = varResponse.data.result[0].sys_id;
822
- this.logger.info(`✅ Resolved '${variableName}' to sys_id: ${sysId}`);
823
- return sysId;
834
+ this.logger.info(`🔍 Resolving variable name '${variableName}' to sys_id for catalog item ${catalogItem}...`);
835
+ // Try multiple search strategies for maximum compatibility
836
+ const searchStrategies = [
837
+ // Strategy 1: Search by name field
838
+ {
839
+ query: `cat_item=${catalogItem}^name=${variableName}`,
840
+ description: 'by name field'
841
+ },
842
+ // Strategy 2: Search by name with LIKE operator
843
+ {
844
+ query: `cat_item=${catalogItem}^nameLIKE${variableName}`,
845
+ description: 'by name with LIKE'
846
+ },
847
+ // Strategy 3: Search by question_text
848
+ {
849
+ query: `cat_item=${catalogItem}^question_text=${variableName}`,
850
+ description: 'by question_text field'
851
+ },
852
+ // Strategy 4: Search all variables for this item and match manually
853
+ {
854
+ query: `cat_item=${catalogItem}`,
855
+ description: 'all variables for manual matching'
856
+ }
857
+ ];
858
+ for (const strategy of searchStrategies) {
859
+ this.logger.info(`🔍 Trying strategy: ${strategy.description}`);
860
+ try {
861
+ const varResponse = await this.client.searchRecords('sc_cat_item_option', strategy.query, 50 // Get more results for manual matching
862
+ );
863
+ if (varResponse.success && varResponse.data.result.length > 0) {
864
+ // For the "all variables" strategy, try to match manually
865
+ if (strategy.description === 'all variables for manual matching') {
866
+ const match = varResponse.data.result.find((v) => v.name === variableName ||
867
+ v.question_text === variableName ||
868
+ v.name?.toLowerCase() === variableName.toLowerCase());
869
+ if (match) {
870
+ this.logger.info(`✅ Found variable through manual matching: ${match.sys_id}`);
871
+ return match.sys_id;
872
+ }
873
+ }
874
+ else {
875
+ // Direct match found
876
+ const sysId = varResponse.data.result[0].sys_id;
877
+ this.logger.info(`✅ Resolved '${variableName}' to sys_id: ${sysId} (${strategy.description})`);
878
+ return sysId;
879
+ }
880
+ }
881
+ }
882
+ catch (error) {
883
+ this.logger.warn(`⚠️ Strategy failed: ${strategy.description}`, error);
884
+ }
885
+ }
886
+ // If all strategies fail, try alternate table names (just in case)
887
+ const alternateTables = ['item_option_new', 'io_set_item_option'];
888
+ for (const table of alternateTables) {
889
+ this.logger.info(`🔍 Trying alternate table: ${table}`);
890
+ try {
891
+ const varResponse = await this.client.searchRecords(table, `cat_item=${catalogItem}^name=${variableName}`, 1);
892
+ if (varResponse.success && varResponse.data.result.length > 0) {
893
+ const sysId = varResponse.data.result[0].sys_id;
894
+ this.logger.info(`✅ Found in alternate table ${table}: ${sysId}`);
895
+ return sysId;
896
+ }
897
+ }
898
+ catch (error) {
899
+ this.logger.warn(`⚠️ Alternate table ${table} failed:`, error);
900
+ }
824
901
  }
825
- this.logger.warn(`⚠️ Variable '${variableName}' not found for catalog item ${catalogItem}, using name as fallback`);
826
- return variableName; // Return original if not found
902
+ this.logger.error(`❌ CRITICAL: Variable '${variableName}' not found in any table for catalog item ${catalogItem}`);
903
+ this.logger.error(`❌ This will cause the action to fail! Please use the sys_id directly instead of the name.`);
904
+ // Return the name but log a warning that this will fail
905
+ return variableName;
827
906
  };
828
907
  // Helper function to map operations to correct ServiceNow format
829
908
  const mapOperatorToServiceNow = (operator) => {
@@ -926,23 +1005,37 @@ ${args.help_text ? `❓ Help: ${args.help_text}` : ''}
926
1005
  // Resolve variable name to sys_id
927
1006
  this.logger.info(`🔍 Resolving variable: ${action.catalog_variable} for catalog item: ${args.cat_item}`);
928
1007
  const variableId = await resolveVariableId(action.catalog_variable, args.cat_item);
929
- this.logger.info(`✅ Resolved to variable ID: ${variableId}`);
1008
+ // Check if resolution actually worked (should be a sys_id now)
1009
+ const isValidSysId = variableId && variableId.match(/^[a-f0-9]{32}$/);
1010
+ if (!isValidSysId) {
1011
+ this.logger.error(`❌ CRITICAL: Failed to resolve variable '${action.catalog_variable}' to sys_id!`);
1012
+ this.logger.error(`❌ Got: ${variableId} (this is not a valid sys_id)`);
1013
+ // Continue anyway but it will likely fail
1014
+ }
1015
+ else {
1016
+ this.logger.info(`✅ Resolved to variable sys_id: ${variableId}`);
1017
+ }
930
1018
  // ✅ CRITICAL FIX: Add "IO:" prefix as required by ServiceNow
931
- const catalogVariableWithPrefix = `IO:${variableId}`;
932
- this.logger.info(`🎯 Using catalog_variable with IO: prefix: ${catalogVariableWithPrefix}`);
1019
+ // BUT ONLY if we have a valid sys_id!
1020
+ const catalogVariableWithPrefix = isValidSysId ? `IO:${variableId}` : variableId;
1021
+ this.logger.info(`🎯 Using catalog_variable value: ${catalogVariableWithPrefix}`);
933
1022
  // Actions structure in ServiceNow:
934
1023
  // - catalog_ui_policy_action.catalog_variable -> "IO:" + variable_sys_id (required format)
935
- // - item_option_new.cat_item -> sc_cat_item (catalog item)
936
- // - catalog_ui_policy.catalog_item -> sc_cat_item (catalog item)
1024
+ // - catalog_ui_policy_action.ui_policy -> catalog_ui_policy.sys_id
937
1025
  const actionData = {
938
- // ✅ Main connection: to the variable with required IO: prefix
1026
+ // ✅ Main connection: to the variable with required IO: prefix (if valid sys_id)
939
1027
  catalog_variable: catalogVariableWithPrefix
940
1028
  };
941
- // NIET: catalog_ui_policy - deze veld bestaat NIET (volgens error log)
942
- // Probeer alleen ui_policy en policy als alternatief
943
- if (policyId) {
944
- // Probeer ui_policy (dit is waarschijnlijk correct)
945
- actionData.ui_policy = policyId;
1029
+ // ✅ CRITICAL FIX: ui_policy field expects the NAME (short_description), NOT the sys_id!
1030
+ // ServiceNow uses the policy name as the reference value
1031
+ if (args.short_description) {
1032
+ actionData.ui_policy = args.short_description; // Use the policy NAME, not sys_id!
1033
+ this.logger.info(`🔗 Linking action to policy by NAME: "${args.short_description}"`);
1034
+ }
1035
+ else {
1036
+ // Fallback if somehow we don't have the name
1037
+ this.logger.error(`❌ CRITICAL: No policy name (short_description) available for linking!`);
1038
+ actionData.ui_policy = policyId; // Use sys_id as last resort
946
1039
  }
947
1040
  // Voeg alleen GEDEFINIEERDE action properties toe
948
1041
  if (action.mandatory !== undefined) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "3.6.15",
4
- "description": "CRITICAL CATALOG UI POLICY FIXES - v3.6.15 fixes ALL catalog UI policy issues based on detailed user feedback. Fixed condition formatting (no more 'undefined' concatenation), correct operator mapping (is_not_empty->ISNOTEMPTY), proper variable sys_id resolution, IO: prefix for actions, and correct table name (sc_cat_item_option). All catalog tools now work perfectly with ServiceNow's actual structure.",
3
+ "version": "3.6.17",
4
+ "description": "UI POLICY NAME FIX - v3.6.17 fixes critical issue where ui_policy field in catalog_ui_policy_action table expects the policy NAME (short_description) instead of sys_id. Actions will now properly link to policies using the policy name as the reference value, which is what ServiceNow actually expects.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",
7
7
  "bin": {