snow-flow 3.6.23 → 3.6.24
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.
package/dist/dynamic-version.js
CHANGED
|
@@ -36,7 +36,7 @@ function getDynamicVersion() {
|
|
|
36
36
|
console.warn('Warning: Could not read version from package.json:', error);
|
|
37
37
|
}
|
|
38
38
|
// Fallback to hardcoded version
|
|
39
|
-
return '3.6.
|
|
39
|
+
return '3.6.24';
|
|
40
40
|
}
|
|
41
41
|
// Export a constant that uses the dynamic version
|
|
42
42
|
exports.VERSION = getDynamicVersion();
|
|
@@ -319,7 +319,7 @@ class ServiceNowDeploymentMCP {
|
|
|
319
319
|
enum: [
|
|
320
320
|
'widget', 'portal_page', 'application', 'script', 'business_rule', 'table',
|
|
321
321
|
'script_include', 'ui_page', 'client_script', 'ui_action', 'ui_policy',
|
|
322
|
-
'acl', 'field', 'workflow', 'flow', 'notification', 'scheduled_job'
|
|
322
|
+
'catalog_ui_policy', 'acl', 'field', 'workflow', 'flow', 'notification', 'scheduled_job'
|
|
323
323
|
],
|
|
324
324
|
description: 'Type of artifact to deploy'
|
|
325
325
|
},
|
|
@@ -7448,6 +7448,8 @@ Use individual deployment tools like \`snow_deploy_${args.type}\` with manual co
|
|
|
7448
7448
|
return await this.deployApplication(scopedConfig);
|
|
7449
7449
|
case 'xml_update_set':
|
|
7450
7450
|
return await this.deployXMLUpdateSet(scopedConfig);
|
|
7451
|
+
case 'catalog_ui_policy':
|
|
7452
|
+
return await this.deployCatalogUIPolicy(scopedConfig);
|
|
7451
7453
|
default:
|
|
7452
7454
|
throw new Error(`Unsupported artifact type for unified deployment: ${type}`);
|
|
7453
7455
|
}
|
|
@@ -7585,6 +7587,176 @@ Use individual deployment tools like \`snow_deploy_${args.type}\` with manual co
|
|
|
7585
7587
|
throw new Error(`XML deployment failed: ${errorMsg}`);
|
|
7586
7588
|
}
|
|
7587
7589
|
}
|
|
7590
|
+
/**
|
|
7591
|
+
* Deploy Catalog UI Policy to ServiceNow
|
|
7592
|
+
*/
|
|
7593
|
+
async deployCatalogUIPolicy(config) {
|
|
7594
|
+
const { catalog_item, cat_item, catalog_conditions, short_description, applies_to = 'all', active = true, on_load = true, reverse_if_false = true, conditions = [], actions = [] } = config;
|
|
7595
|
+
const catalogItemId = catalog_item || cat_item;
|
|
7596
|
+
if (!catalogItemId) {
|
|
7597
|
+
throw new Error('catalog_item or cat_item is required for catalog UI policy deployment');
|
|
7598
|
+
}
|
|
7599
|
+
if (!short_description) {
|
|
7600
|
+
throw new Error('short_description is required for catalog UI policy deployment');
|
|
7601
|
+
}
|
|
7602
|
+
this.logger.info('🚀 Deploying Catalog UI Policy', {
|
|
7603
|
+
catalogItem: catalogItemId,
|
|
7604
|
+
description: short_description,
|
|
7605
|
+
conditions: conditions.length,
|
|
7606
|
+
actions: actions.length
|
|
7607
|
+
});
|
|
7608
|
+
try {
|
|
7609
|
+
// If catalog_conditions is provided, convert it to conditions array
|
|
7610
|
+
let policyConditions = conditions;
|
|
7611
|
+
if (catalog_conditions && policyConditions.length === 0) {
|
|
7612
|
+
// Parse catalog_conditions string like "employee_type=contractor"
|
|
7613
|
+
const conditionParts = catalog_conditions.split('=');
|
|
7614
|
+
if (conditionParts.length === 2) {
|
|
7615
|
+
policyConditions = [{
|
|
7616
|
+
catalog_variable: conditionParts[0].trim(),
|
|
7617
|
+
operation: 'is',
|
|
7618
|
+
value: conditionParts[1].trim(),
|
|
7619
|
+
and_or: 'AND'
|
|
7620
|
+
}];
|
|
7621
|
+
this.logger.info('📝 Converted catalog_conditions to conditions array:', policyConditions);
|
|
7622
|
+
}
|
|
7623
|
+
}
|
|
7624
|
+
// Build policy data for catalog_ui_policy table
|
|
7625
|
+
const policyData = {
|
|
7626
|
+
cat_item: catalogItemId,
|
|
7627
|
+
short_description: short_description,
|
|
7628
|
+
applies_to: applies_to,
|
|
7629
|
+
active: active,
|
|
7630
|
+
on_load: on_load,
|
|
7631
|
+
reverse_if_false: reverse_if_false,
|
|
7632
|
+
order: 100
|
|
7633
|
+
};
|
|
7634
|
+
this.logger.info('🎯 Creating main policy in catalog_ui_policy table with data:', policyData);
|
|
7635
|
+
const policyResponse = await this.client.createRecord('catalog_ui_policy', policyData);
|
|
7636
|
+
if (!policyResponse.success) {
|
|
7637
|
+
throw new Error(`Failed to create catalog UI policy: ${policyResponse.error}`);
|
|
7638
|
+
}
|
|
7639
|
+
const policyId = policyResponse.data.sys_id;
|
|
7640
|
+
this.logger.info(`✅ Created policy with sys_id: ${policyId}`);
|
|
7641
|
+
// Create conditions if provided
|
|
7642
|
+
const createdConditions = [];
|
|
7643
|
+
for (let i = 0; i < policyConditions.length; i++) {
|
|
7644
|
+
const condition = policyConditions[i];
|
|
7645
|
+
// Resolve variable name to sys_id if needed
|
|
7646
|
+
let variableSysId = condition.catalog_variable;
|
|
7647
|
+
if (condition.catalog_variable && !condition.catalog_variable.match(/^[a-f0-9]{32}$/)) {
|
|
7648
|
+
// Search for variable by name
|
|
7649
|
+
const variableSearch = await this.client.searchRecords('item_option_new', `cat_item=${catalogItemId}^name=${condition.catalog_variable}`, 1);
|
|
7650
|
+
if (variableSearch.success && variableSearch.data.result.length > 0) {
|
|
7651
|
+
variableSysId = variableSearch.data.result[0].sys_id;
|
|
7652
|
+
this.logger.info(`✅ Resolved variable '${condition.catalog_variable}' to sys_id: ${variableSysId}`);
|
|
7653
|
+
}
|
|
7654
|
+
else {
|
|
7655
|
+
this.logger.warn(`⚠️ Could not resolve variable '${condition.catalog_variable}', using as-is`);
|
|
7656
|
+
}
|
|
7657
|
+
}
|
|
7658
|
+
const conditionData = {
|
|
7659
|
+
ui_policy: policyId,
|
|
7660
|
+
catalog_variable: `IO:${variableSysId}`, // IO: prefix required
|
|
7661
|
+
operation: condition.operation || 'is',
|
|
7662
|
+
value: condition.value || '',
|
|
7663
|
+
and_or: condition.and_or || 'AND',
|
|
7664
|
+
order: (i + 1) * 100,
|
|
7665
|
+
active: true
|
|
7666
|
+
};
|
|
7667
|
+
this.logger.info(`🔗 Creating condition ${i + 1}:`, conditionData);
|
|
7668
|
+
const conditionResponse = await this.client.createRecord('catalog_ui_policy_condition', conditionData);
|
|
7669
|
+
if (conditionResponse.success) {
|
|
7670
|
+
createdConditions.push(conditionResponse.data.sys_id);
|
|
7671
|
+
this.logger.info(`✅ Created condition ${i + 1} with sys_id: ${conditionResponse.data.sys_id}`);
|
|
7672
|
+
}
|
|
7673
|
+
else {
|
|
7674
|
+
this.logger.error(`❌ Failed to create condition ${i + 1}:`, conditionResponse.error);
|
|
7675
|
+
}
|
|
7676
|
+
}
|
|
7677
|
+
// Create actions if provided
|
|
7678
|
+
const createdActions = [];
|
|
7679
|
+
for (let i = 0; i < actions.length; i++) {
|
|
7680
|
+
const action = actions[i];
|
|
7681
|
+
// Resolve variable name to sys_id if needed
|
|
7682
|
+
let actionVariableSysId = action.catalog_variable;
|
|
7683
|
+
if (action.catalog_variable && !action.catalog_variable.match(/^[a-f0-9]{32}$/)) {
|
|
7684
|
+
const actionVariableSearch = await this.client.searchRecords('item_option_new', `cat_item=${catalogItemId}^name=${action.catalog_variable}`, 1);
|
|
7685
|
+
if (actionVariableSearch.success && actionVariableSearch.data.result.length > 0) {
|
|
7686
|
+
actionVariableSysId = actionVariableSearch.data.result[0].sys_id;
|
|
7687
|
+
this.logger.info(`✅ Resolved action variable '${action.catalog_variable}' to sys_id: ${actionVariableSysId}`);
|
|
7688
|
+
}
|
|
7689
|
+
else {
|
|
7690
|
+
this.logger.warn(`⚠️ Could not resolve action variable '${action.catalog_variable}', using as-is`);
|
|
7691
|
+
}
|
|
7692
|
+
}
|
|
7693
|
+
const actionData = {
|
|
7694
|
+
ui_policy: policyId,
|
|
7695
|
+
catalog_item: catalogItemId,
|
|
7696
|
+
catalog_variable: `IO:${actionVariableSysId}`, // IO: prefix required
|
|
7697
|
+
order: (i + 1) * 100,
|
|
7698
|
+
active: true
|
|
7699
|
+
};
|
|
7700
|
+
// Set action type fields based on action.type or individual properties
|
|
7701
|
+
if (action.type === 'set_mandatory' || action.mandatory !== undefined) {
|
|
7702
|
+
actionData.mandatory = action.mandatory === true ? 'true' :
|
|
7703
|
+
action.mandatory === false ? 'false' : 'ignore';
|
|
7704
|
+
}
|
|
7705
|
+
else {
|
|
7706
|
+
actionData.mandatory = 'ignore';
|
|
7707
|
+
}
|
|
7708
|
+
if (action.type === 'set_visible' || action.visible !== undefined) {
|
|
7709
|
+
actionData.visible = action.visible === true ? 'true' :
|
|
7710
|
+
action.visible === false ? 'false' : 'ignore';
|
|
7711
|
+
}
|
|
7712
|
+
else {
|
|
7713
|
+
actionData.visible = 'ignore';
|
|
7714
|
+
}
|
|
7715
|
+
if (action.type === 'set_readonly' || action.readonly !== undefined) {
|
|
7716
|
+
actionData.disabled = action.readonly === true ? 'true' :
|
|
7717
|
+
action.readonly === false ? 'false' : 'ignore';
|
|
7718
|
+
}
|
|
7719
|
+
else {
|
|
7720
|
+
actionData.disabled = 'ignore';
|
|
7721
|
+
}
|
|
7722
|
+
if (action.value !== undefined && action.value !== null && action.value !== '') {
|
|
7723
|
+
actionData.value = String(action.value);
|
|
7724
|
+
}
|
|
7725
|
+
this.logger.info(`🎬 Creating action ${i + 1}:`, actionData);
|
|
7726
|
+
const actionResponse = await this.client.createRecord('catalog_ui_policy_action', actionData);
|
|
7727
|
+
if (actionResponse.success) {
|
|
7728
|
+
createdActions.push(actionResponse.data.sys_id);
|
|
7729
|
+
this.logger.info(`✅ Created action ${i + 1} with sys_id: ${actionResponse.data.sys_id}`);
|
|
7730
|
+
}
|
|
7731
|
+
else {
|
|
7732
|
+
this.logger.error(`❌ Failed to create action ${i + 1}:`, actionResponse.error);
|
|
7733
|
+
}
|
|
7734
|
+
}
|
|
7735
|
+
return {
|
|
7736
|
+
success: true,
|
|
7737
|
+
policy_id: policyId,
|
|
7738
|
+
conditions_created: createdConditions.length,
|
|
7739
|
+
actions_created: createdActions.length,
|
|
7740
|
+
message: `✅ Catalog UI Policy '${short_description}' deployed successfully`,
|
|
7741
|
+
details: {
|
|
7742
|
+
policy_sys_id: policyId,
|
|
7743
|
+
catalog_item: catalogItemId,
|
|
7744
|
+
conditions: createdConditions,
|
|
7745
|
+
actions: createdActions,
|
|
7746
|
+
next_steps: [
|
|
7747
|
+
'1. Test the catalog item form to verify policy behavior',
|
|
7748
|
+
'2. Check that conditions trigger actions correctly',
|
|
7749
|
+
'3. Verify variable visibility/mandatory/readonly changes'
|
|
7750
|
+
]
|
|
7751
|
+
}
|
|
7752
|
+
};
|
|
7753
|
+
}
|
|
7754
|
+
catch (error) {
|
|
7755
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
7756
|
+
this.logger.error('Catalog UI Policy deployment failed', { error: errorMsg, config });
|
|
7757
|
+
throw new Error(`Catalog UI Policy deployment failed: ${errorMsg}`);
|
|
7758
|
+
}
|
|
7759
|
+
}
|
|
7588
7760
|
/**
|
|
7589
7761
|
* Check if error is permission-related
|
|
7590
7762
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snow-flow",
|
|
3
|
-
"version": "3.6.
|
|
4
|
-
"description": "CATALOG
|
|
3
|
+
"version": "3.6.24",
|
|
4
|
+
"description": "CATALOG UI POLICY DEPLOYMENT SUPPORT - v3.6.24 adds catalog_ui_policy support to snow_deploy tool. You can now deploy catalog UI policies via unified deployment with automatic variable resolution, condition/action creation, and comprehensive error handling.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"bin": {
|