script-include-patterns

安装量: 50
排名: #14819

安装

npx skills add https://github.com/groeimetai/snow-flow --skill script-include-patterns

Script Include Patterns for ServiceNow Script Includes are reusable server-side JavaScript libraries that can be called from any server-side script. Script Include Types Type Use Case Client Callable Standard Server-side utilities No Client Callable GlideAjax from client Yes On-Demand Lazy loading No AbstractAjaxProcessor Client-server communication Yes Standard Script Include (ES5) // Basic utility class var IncidentUtils = Class . create ( ) IncidentUtils . prototype = { initialize : function ( ) { this . LOG_PREFIX = "[IncidentUtils] " } , / * Get incident by number * @param { string } number - Incident number (INC0010001) * @returns { GlideRecord | null } - Incident record or null */ getByNumber : function ( number ) { var gr = new GlideRecord ( "incident" ) gr . addQuery ( "number" , number ) gr . query ( ) if ( gr . next ( ) ) { return gr } return null } , / * Calculate priority based on impact and urgency * @param { number } impact - Impact value (1-3) * @param { number } urgency - Urgency value (1-3) * @returns { number } - Calculated priority (1-5) / calculatePriority : function ( impact , urgency ) { var matrix = { "1-1" : 1 , "1-2" : 2 , "1-3" : 3 , "2-1" : 2 , "2-2" : 3 , "2-3" : 4 , "3-1" : 3 , "3-2" : 4 , "3-3" : 5 , } var key = impact + "-" + urgency return matrix [ key ] || 4 } , / * Get open incidents for user * @param { string } userSysId - User sys_id * @returns { Array } - Array of incident objects / getOpenIncidentsForUser : function ( userSysId ) { var incidents = [ ] var gr = new GlideRecord ( "incident" ) gr . addQuery ( "caller_id" , userSysId ) gr . addQuery ( "active" , true ) gr . orderByDesc ( "opened_at" ) gr . query ( ) while ( gr . next ( ) ) { incidents . push ( { sys_id : gr . getUniqueValue ( ) , number : gr . getValue ( "number" ) , short_description : gr . getValue ( "short_description" ) , state : gr . state . getDisplayValue ( ) , priority : gr . priority . getDisplayValue ( ) , } ) } return incidents } , type : "IncidentUtils" , } Client Callable Script Include (ES5) // Extends AbstractAjaxProcessor for GlideAjax calls var IncidentAjax = Class . create ( ) IncidentAjax . prototype = Object . extendsObject ( AbstractAjaxProcessor , { / * Get incident details - callable from client * Client calls: new GlideAjax('IncidentAjax').addParam('sysparm_name', 'getIncidentDetails') */ getIncidentDetails : function ( ) { var incidentId = this . getParameter ( "sysparm_incident_id" ) var result = { } var gr = new GlideRecord ( "incident" ) if ( gr . get ( incidentId ) ) { result . success = true result . number = gr . getValue ( "number" ) result . short_description = gr . getValue ( "short_description" ) result . state = gr . state . getDisplayValue ( ) result . priority = gr . priority . getDisplayValue ( ) result . assigned_to = gr . assigned_to . getDisplayValue ( ) result . assignment_group = gr . assignment_group . getDisplayValue ( ) } else { result . success = false result . message = "Incident not found" } return JSON . stringify ( result ) } , / * Search incidents by keyword / searchIncidents : function ( ) { var keyword = this . getParameter ( "sysparm_keyword" ) var limit = parseInt ( this . getParameter ( "sysparm_limit" ) , 10 ) || 10 var incidents = [ ] var gr = new GlideRecord ( "incident" ) gr . addQuery ( "short_description" , "CONTAINS" , keyword ) gr . addOrCondition ( "description" , "CONTAINS" , keyword ) gr . addQuery ( "active" , true ) gr . setLimit ( limit ) gr . orderByDesc ( "opened_at" ) gr . query ( ) while ( gr . next ( ) ) { incidents . push ( { sys_id : gr . getUniqueValue ( ) , number : gr . getValue ( "number" ) , short_description : gr . getValue ( "short_description" ) , } ) } return JSON . stringify ( incidents ) } , / * Check if user can update incident / canUserUpdate : function ( ) { var incidentId = this . getParameter ( "sysparm_incident_id" ) var userId = gs . getUserID ( ) var gr = new GlideRecord ( "incident" ) if ( gr . get ( incidentId ) ) { // Check if user is assigned or in assignment group var canUpdate = gr . getValue ( "assigned_to" ) === userId || this . _isUserInGroup ( userId , gr . getValue ( "assignment_group" ) ) return JSON . stringify ( { canUpdate : canUpdate } ) } return JSON . stringify ( { canUpdate : false } ) } , _isUserInGroup : function ( userId , groupId ) { var member = new GlideRecord ( "sys_user_grmember" ) member . addQuery ( "user" , userId ) member . addQuery ( "group" , groupId ) member . query ( ) return member . hasNext ( ) } , type : "IncidentAjax" , } ) Client-Side GlideAjax Call (ES5) // Client script calling Script Include function getIncidentDetails ( incidentSysId , callback ) { var ga = new GlideAjax ( "IncidentAjax" ) ga . addParam ( "sysparm_name" , "getIncidentDetails" ) ga . addParam ( "sysparm_incident_id" , incidentSysId ) ga . getXMLAnswer ( function ( answer ) { var result = JSON . parse ( answer ) callback ( result ) } ) } // Usage in client script getIncidentDetails ( g_form . getUniqueValue ( ) , function ( incident ) { if ( incident . success ) { g_form . addInfoMessage ( "Incident: " + incident . number ) } else { g_form . addErrorMessage ( incident . message ) } } ) Inheritance Pattern (ES5) // Base class var TaskUtils = Class . create ( ) TaskUtils . prototype = { initialize : function ( tableName ) { this . tableName = tableName || "task" } , getByState : function ( state ) { var records = [ ] var gr = new GlideRecord ( this . tableName ) gr . addQuery ( "state" , state ) gr . query ( ) while ( gr . next ( ) ) { records . push ( this . _toObject ( gr ) ) } return records } , _toObject : function ( gr ) { return { sys_id : gr . getUniqueValue ( ) , number : gr . getValue ( "number" ) , short_description : gr . getValue ( "short_description" ) , state : gr . getValue ( "state" ) , } } , type : "TaskUtils" , } // Derived class var IncidentUtilsExtended = Class . create ( ) IncidentUtilsExtended . prototype = Object . extendsObject ( TaskUtils , { initialize : function ( ) { TaskUtils . prototype . initialize . call ( this , "incident" ) } , getP1Incidents : function ( ) { var incidents = [ ] var gr = new GlideRecord ( "incident" ) gr . addQuery ( "priority" , 1 ) gr . addQuery ( "active" , true ) gr . query ( ) while ( gr . next ( ) ) { var obj = this . _toObject ( gr ) obj . caller = gr . caller_id . getDisplayValue ( ) incidents . push ( obj ) } return incidents } , type : "IncidentUtilsExtended" , } ) Scoped Script Include (ES5) // In scoped application: x_myapp var MyAppUtils = Class . create ( ) MyAppUtils . prototype = { initialize : function ( ) { this . APP_SCOPE = "x_myapp" } , / * Get application property * @param { string } name - Property name (without scope prefix) */ getAppProperty : function ( name ) { return gs . getProperty ( this . APP_SCOPE + "." + name ) } , / * Log with application prefix / log : function ( message , source ) { gs . info ( "[" + this . APP_SCOPE + "][" + ( source || "MyAppUtils" ) + "] " + message ) } , / * Access cross-scope table safely / getGlobalUser : function ( userId ) { var gr = new GlideRecord ( "sys_user" ) if ( gr . get ( userId ) ) { return { name : gr . getValue ( "name" ) , email : gr . getValue ( "email" ) , } } return null } , type : "MyAppUtils" , } MCP Tool Integration Available Script Include Tools Tool Purpose snow_create_script_include Create new Script Include snow_find_artifact Find existing Script Includes snow_edit_artifact Modify Script Include code snow_execute_script_with_output Test Script Include Example Workflow // 1. Create Script Include await snow_create_script_include ( { name : "IncidentUtils" , script : "/ Script Include code /" , client_callable : false , description : "Incident utility functions" , } ) // 2. Test the Script Include await snow_execute_script_with_output ( { script : var utils = new IncidentUtils(); var incident = utils.getByNumber('INC0010001'); gs.info('Found: ' + (incident ? incident.number : 'null')); , } ) Best Practices Single Responsibility - One class, one purpose Meaningful Names - IncidentUtils not Utils Document Methods - JSDoc comments Error Handling - Try-catch with logging Private Methods - Prefix with underscore No Side Effects - Initialization should not modify data Testable - Write methods that can be unit tested ES5 Only - No const, let, arrow functions, template literals

返回排行榜