Skip to content

SDK 4.2.0

Latest

Choose a tag to compare

@bryce-godfrey bryce-godfrey released this 21 Jan 06:15

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:

  • Password2Column
  • GuidColumn
  • JsonColumn
  • NameValuePairsColumn
  • UrlColumn
  • EmailColumn
  • HTMLColumn
  • FloatColumn
  • MultiLineTextColumn
  • DurationColumn
  • TimeColumn
  • FieldListColumn
  • SlushBucketColumn
  • TemplateValueColumn
  • ApprovalRulesColumn

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:

  1. Update the @servicenow/glide package:
   {
     "dependencies": {
       "@servicenow/glide": "27.0.3"
     }
   }
  1. Run the dependencies command:
   now-sdk dependencies
  1. 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-aware GlideRecord autocomplete

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 List API
  • Fixed JSON.stringify to allow JSON arrays
  • Fixed ListColumn to allow choices
  • Changed referenceTable field to required for ReferenceColumn and ListColumn
  • Fixed DocumentIdColumn not populating values for dependent fields
  • Fixed 'priority' not being captured while transforming BusinessRule
  • Fixed missing diagnostic error when duplicate Now.ID values are used
  • Fixed missing sys_scope for sys_atf_step records from ATF API
  • Fixed "undefined" replacement on process globals for BYOF builds

Feedback

For any issues or feedback, please use the SDK discussions: https://github.com/ServiceNow/sdk/discussions