Editing Digital Script

Edit Digital Script in JetBrains IDEs with File Structure, folding, quick documentation, live templates, new script files, intentions and E4X completion

Beyond the IDE's JavaScript editing, Digital Script gets its own structure, folding, documentation, templates and intentions for import calls, pipelet headers, E4X and Rhino loops

File Structure (Cmd+F12) adds an Imports node with every import call and a Pipelet node with the header keys. A run of import calls folds to importPackage(...) ×4 and the pipelet header to its keys

File Structure

File Structure (Cmd+F12, Ctrl+F12) and the Structure tool window add two nodes to the functions and variables of the script:

Imports
  dw.util (package)
  BasketMgr (dw.order)
  app_core:cart/CartUtils.ds (script)
Pipelet
  Basket (@input dw.order.Basket)
  Total (@output Number)

Imports lists the valid import calls and follows the caret onto them. Pipelet lists the header keys and opens each one in the header. A file without import calls or a header shows neither node

Folding

RegionFolded
Two or more import calls in a row, blank lines and comments between them includedimportPackage(...) ×4
A pipelet header over several lines/** @input Basket, @output Total */, up to 4 keys and then ...
An XML literal over several lines<feed>...</feed>
A static Resource.msg(...) or Resource.msgf(...) callThe message, such as "Loyalty rewards"

Nothing is folded when a file opens, except Resource.msg calls. Folding works while the IDE indexes, but Resource.msg calls fold once it ends and need a license. Click a folded message to open the call, and click the marker in the gutter to fold it back. Resource.msg() messages in Settings › Editor › General › Code Folding turns them off, see Resource bundles

Quick documentation

Quick documentation (F1, Ctrl+Q) answers for Digital Script forms, and leaves everything else to the IDE's JavaScript pages:

Caret onShows
An import callWhat it binds and, for importScript, the script and its functions, see Quick documentation
pdict.Basket, or the key in the headerBasket: dw.order.Basket, its description, its role in the pipeline and the header line
An E4X expressionXML or XMLList and the rule, such as "A descendant access x..name is the XMLList of all matching descendants."
The each of a for each loopThe iterated type, the variable type and what the loop yields, such as "Iterates the elements of the collection or iterator, in the order its iterator() gives them."

Lists stop after 12 items with "+N more". Quick documentation needs a license

Live templates

AbbreviationExpands to
foreachfor each (var item in collection) { }, with the variable named after the collection
foritvar it = collection.iterator(); and a while (it.hasNext()) loop
impimportPackage(dw.);
impcimportClass(dw.);
impsimportScript('');
pipeletA pipelet header with @input and @output, importPackage(dw.system); and an execute that returns PIPELET_NEXT
trycatchiftry { } catch (e if e instanceof Error) { }

They expand with Tab where a statement can start, in .ds files, server .js files and <isscript>, but not in comments, strings or expressions. foreach over basket.productLineItems names its variable productLineItem. Edit them in Settings › Editor › Live Templates › Digital Script

New script files

Open the New menu

Right-click a cartridge folder and pick New › Digital Script File

Name the script

A name can be a path, such as checkout/Calculate. Folders that don't exist are created

Pick the kind

KindFileContent
Module.ds'use strict'; and module.exports = {};
Pipelet script.dsA header with @input Input and @output Output, and an execute that returns PIPELET_NEXT
Job step module.jsexports.execute = function (parameters, stepExecution) with JSDoc types, returning new Status(Status.OK)

Typed on a cartridge folder, the file goes under cartridge/scripts, and on the cartridge folder under scripts. Anywhere else, the name is used as typed. The dialog refuses an empty name, an empty, . or .. path segment, and the characters < > : " | ? *

The three templates are in Settings › Editor › File and Code Templates, in the Digital Script group

Intentions

Alt+Enter intentions in the SFCC/Digital Script group of Settings › Editor › Intentions. They need a license:

IntentionWhat it does
Convert to 'for...of' loopfor each (var item in basket.getProductLineItems()) becomes for (var item of basket.getProductLineItems().toArray()). Offered from mode 21.2 or with no mode set, over arrays and Script API collections, iterators and maps
Convert type annotations to JSDocfunction total(basket : Basket, rate : Number) : String gets @param {dw.order.Basket} basket, @param {number} rate and @returns {string}
Convert JSDoc types to annotationsThe way back, in .ds files only. Union and generic types stay in JSDoc
Replace the import call with requireimportClass(dw.util.HashMap); becomes var HashMap = require('dw/util/HashMap');, see Replace with require
Extract template script to a server moduleIn <isscript>, moves the block or the selected statements into cartridge/scripts/templates/<template path>.js as prepare, and calls require('~/cartridge/scripts/templates/cart/total').prepare(pdict, currency) in its place

Convert to 'for...of' loop keeps the values the same. A Script API list goes through toArray(), a map through values().toArray() and an iterator through asList().toArray(). It isn't offered over objects, XML or unknown types

Extract template script to a server module passes the names the code reads as arguments and returns what it sets. Several results come back as one object, such as var result = require(...).prepare(pdict, total);. It isn't offered for a selection that cuts a statement, for code with return, this or arguments outside a function, or for code that calls an importScript function

E4X completion

After feed. or feed.., completion offers the element names of the file's XML literals, then the XML methods. After @ it offers only the attribute names, and inside a filter such as feed.item.(...) the element names come with the Script API globals. E4X completion needs a license

Colors

Settings › Editor › Color Scheme › Digital Script:

ColorPaints
Rhino keyword (for each, default xml namespace)each, and xml namespace in default xml namespace
Type annotationThe type after :, and the type on a pipelet header line
Unresolved name, type or script pathClasses the script doesn't import, unknown types, undeclared names and importScript paths that name no script, red with a wave in every bundled scheme
Imports › Import call, Imported name, importScript pathSee Colors
E4X › Attribute@id and @*
E4X › Operator.., ::, .( and .*
Pipelet › Header tag@input and @output
Pipelet › Dictionary keyThe key in the header and in pdict.Basket
Clickable path, route or key (underline)A thin grey underline on strings a click opens: require and importScript paths, static files and other targets, only while they resolve

Default, Darcula, High contrast and Islands Dark have their own Unresolved name, type or script path color. Imported names and pdict keys are colored once indexing ends and need a license. let is colored as a keyword, like var and const

Debugging and call hierarchy

  • Line breakpoints work in .ds files. Stopped in a .ds file, a server .js file or a template, Evaluate Expression and watches parse Digital Script, so for each (var item in items) and var total : Number work there, see Script Debugger
  • Call Hierarchy lists callers across importScript, in importing scripts and template functions. Top-level calls in template code aren't listed
  • Analyze Data Flow isn't available for JavaScript or Digital Script

On this page