Available on npm at @servicenow/sdk
What's New in v4.2
Version 4.2 introduces powerful new Fluent APIs, enhanced type safety for server-side development, and improved developer tooling. This release focuses on making ServiceNow application development more intuitive and type-safe.
🚀 New Features
ImportSet Fluent API
The ImportSet API provides a fluent interface for creating Transform Maps with their associated field mappings (sys_transform_entry) and transform scripts (sys_transform_script).
Note: Data Sources (sys_data_source) should be configured through the Record API, as they contain structurally flat, independent metadata.
Basic Configuration
ImportSet({
$id: Now.ID['user-import-set'],
name: 'User Data Import',
targetTable: 'sys_user',
sourceTable: 'u_user_import_staging',
active: true,
runBusinessRules: true,
enforceMandatoryFields: 'onlyMappedFields',
fields: {
first_name: 'name',
last_name: 'last_name',
email: {
sourceField: 'email',
coalesce: true,
coalesceCaseSensitive: false
}
}
})Advanced Configuration with Field Transforms
ImportSet({
$id: Now.ID['advanced-import-set'],
name: 'Advanced User Import',
targetTable: 'sys_user',
sourceTable: 'u_user_import_staging',
active: true,
runScript: true,
script: transformUserData, // Imported function
fields: {
email: {
sourceField: 'email_address',
coalesce: true,
useSourceScript: true,
sourceScript: `answer = (function transformEntry(source) {
return source.email_address.toLowerCase().trim();
})(source);`
},
department: {
sourceField: 'dept_code',
choiceAction: 'create'
}
},
scripts: [
{
active: true,
order: 100,
when: 'onBefore',
script: `(function runTransformScript(source, map, log, target) {
if (!source.email_address || source.email_address.indexOf('@') === -1) {
log.error('Invalid email address: ' + source.email_address);
return;
}
})(source, map, log, target);`
}
]
})UiPolicy Fluent API
Configure UI Policy records (sys_ui_policy) with their associated UI Policy Actions (sys_ui_policy_action) and Related List Actions (sys_ui_policy_rl_action) to control field visibility, mandatory status, read-only behavior, and related list visibility on forms.
Basic UI Policy
UiPolicy({
$id: Now.ID['incident_related_list_control'],
table: 'incident',
shortDescription: 'Control related lists for high priority incidents',
onLoad: true,
conditions: 'priority=1',
actions: [
{
field: 'urgency',
mandatory: true
}
],
relatedListActions: [
{
$id: Now.ID['rl_action_1'],
list: 'b9edf0ca0a0a0b010035de2d6b579a03', // System relationship (GUID)
visible: false
},
{
$id: Now.ID['rl_action_2'],
list: 'incident.caller_id', // table.field format (reference field)
visible: true
},
{
$id: Now.ID['rl_action_3'],
list: 'change_request.change_task', // Parent-child relationship
visible: 'ignore'
}
]
})UI Policy with Scripts
UiPolicy({
$id: Now.ID['task_assignment_policy'],
table: 'task',
shortDescription: 'Task assignment validation with scripts',
onLoad: true,
conditions: 'assigned_to=',
runScripts: true,
scriptTrue: `function onCondition() {
g_form.addInfoMessage('Please assign this task to a user.');
g_form.setMandatory('assigned_to', true);
}`,
scriptFalse: `function onCondition() {
g_form.clearMessages();
}`,
uiType: 'desktop',
isolateScript: true,
actions: [
{
field: 'assigned_to',
mandatory: true
}
]
})Now.attach API for Image Fields
Attach images to Image field type columns.
import { Record } from '@servicenow/sdk/core'
Record({
$id: Now.ID['test'],
table: 'sp_portal',
data: {
title: 'Test Portal',
url_suffix: 'test',
icon: Now.attach('../../assets/servicenow.jpg')
}
})Additional Column Types
The Table API now supports additional database column types:
Password2ColumnGuidColumnJsonColumnNameValuePairsColumnUrlColumnEmailColumnHTMLColumnFloatColumnMultiLineTextColumnDurationColumnTimeColumnFieldListColumnSlushBucketColumnTemplateValueColumnApprovalRulesColumn
Utility Helper Functions
The SDK now includes helper functions for complex ServiceNow data types, providing strong typing support and simplified syntax.
Duration()
Works with the DurationColumn type for specifying duration values in days, hours, minutes, and seconds.
Record({
table: 'u_my_table',
data: {
duration_field: Duration({ days: 1, hours: 6, minutes: 30, seconds: 15 })
}
})Time()
Works with the TimeColumn type for specifying times in hours, minutes, and seconds.
Record({
table: 'u_my_table',
data: {
time_field: Time({ hours: 6, minutes: 30, seconds: 15 }), // Basic example
time_tz_field: Time({ hours: 6, minutes: 30, seconds: 15 }, 'America/New_York') // With timezone
}
})FieldList()
Works with the FieldListColumn type for specifying a list of field names that are type-checked to a specified table, with dot-walking support.
Record({
table: 'u_my_table',
data: {
field_list_field: FieldList<'sys_user'>(['name', 'company', 'active', 'manager.name'])
}
})TemplateValue()
Works with the TemplateValueColumn type for specifying objects with field-value pairs.
Example TemplateValue in encoded format: cost=100^description=Catalog Item Description^category=Hardware^active=true^EQ
Record({
table: 'u_my_table',
data: {
template_field: TemplateValue({
cost: 100,
description: 'Catalog Item Description',
category: 'Hardware',
active: true,
})
}
})Enhanced dependencies Command
When developing ServiceNow applications, having complete type information for instance dependencies outside your app scope is essential for type safety and better developer experience. The dependencies command now provides enhanced support for pulling down type definitions for tables and roles.
Configuration
Configure dependencies through the now.config.json file:
{
"dependencies": {
"global": {
"tables": [
"cmdb_ci_server"
],
"roles": [
"admin",
"itil"
]
}
}
}Fluent API Type Imports
Fluent code dependencies are now stored in the local @types folder at @types/servicenow/fluent and can be referenced using the #now:{scope}/{category} import alias pattern that is configured through package.json.
For existing projects: Manually add the following imports configuration to your package.json (this is automatically configured for new projects):
{
"imports": {
"#now:*": "./@types/servicenow/fluent/*/index.js"
}
}Usage example:
import { Acl } from "@servicenow/sdk/core";
import { role as globalRole } from "#now:global/security";
Acl({
$id: Now.ID["my_acl"],
type: "record",
table: "incident",
operation: "read",
roles: [globalRole.admin, globalRole.itil],
});Server Script Type Definition Enhancements
Version 4.2 significantly improves type safety for server-side module development. The @servicenow/glide package (v27.0.3+) now includes generic support for GlideRecord, GlideElement, and GlideRecordSecure, enabling proper table-aware type checking.
Migration for Existing Projects
To take advantage of enhanced type definitions:
- Update the
@servicenow/glidepackage:
{
"dependencies": {
"@servicenow/glide": "27.0.3"
}
}- Run the dependencies command:
now-sdk dependencies- Update
src/server/tsconfig.json:
{
"include": [
"../../@types/**/*.modules.d.ts"
]
}Result
Module files now provide rich type information for GlideRecord calls for any table on your instance:
Type Definitions for Server Scripts Using Now.include
Enhanced type support for server scripts such as script includes, business rules, and other non-module scripts is now available when using Now.include and can take advantage of the type definitions if the @types folder as well. To connect these Typescript definitions to your code, we suggest using a .server.js type file extension pattern for any server side code, and .client.js for client side javascript.
Example:
ScriptInclude({
$id: Now.ID['my-script-include'],
name: 'MyScriptInclude',
script: Now.include('./MyScriptInclude.server.js')
})src/fluent/tsconfig.json
{
"files": [],
"references": [
{
"path": "./tsconfig.server.json"
},
{
"path": "./tsconfig.client.json"
}
]
}src/fluent/tsconfig.server.json
{
"compilerOptions": {
"lib": [
"ES2021"
],
"noEmit": true,
"checkJs": false,
"allowJs": true,
"noEmitHelpers": true,
"esModuleInterop": false,
"module": "None",
"types": []
},
"include": [
"./**/*.server.js",
"../../@types/servicenow/*.server.d.ts",
]
}src/fluent/tsconfig.client.json
{
"compilerOptions": {
"target": "ES6",
"lib": [
"DOM",
"ES6"
],
"checkJs": false,
"allowJs": true,
"noEmit": true,
"noEmitHelpers": true,
"esModuleInterop": false,
"module": "None",
"types": []
},
"include": [
"./**/*.client.js",
"../../@types/servicenow/*.client.d.ts",
]
}To get further type checking you can experiment with turning checkJs on in your tsconfig.server.json file to get more diagnostic errors. Script includes that are using older Class.create() style construction with prototypes will likely produce many errors though, and it is recommended to use ES6 style classes instead to resolve that.
🐛 Bug Fixes
- Fixed escape sequence not being preserved when transforming from XML with embedded JSON (PRB1973926)
- Fixed empty choice values during transform
- Fixed transform issues with
ListAPI - Fixed
JSON.stringifyto allow JSON arrays - Fixed
ListColumnto allow choices - Changed
referenceTablefield to required forReferenceColumnandListColumn - Fixed
DocumentIdColumnnot populating values for dependent fields - Fixed 'priority' not being captured while transforming
BusinessRule - Fixed missing diagnostic error when duplicate
Now.IDvalues are used - Fixed missing
sys_scopeforsys_atf_steprecords fromATFAPI - Fixed "undefined" replacement on
processglobals for BYOF builds
Feedback
For any issues or feedback, please use the SDK discussions: https://github.com/ServiceNow/sdk/discussions