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
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 keysFile 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
| Region | Folded |
|---|---|
| Two or more import calls in a row, blank lines and comments between them included | importPackage(...) ×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(...) call | The 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 on | Shows |
|---|---|
| An import call | What it binds and, for importScript, the script and its functions, see Quick documentation |
pdict.Basket, or the key in the header | Basket: dw.order.Basket, its description, its role in the pipeline and the header line |
| An E4X expression | XML 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 loop | The 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
| Abbreviation | Expands to |
|---|---|
foreach | for each (var item in collection) { }, with the variable named after the collection |
forit | var it = collection.iterator(); and a while (it.hasNext()) loop |
imp | importPackage(dw.); |
impc | importClass(dw.); |
imps | importScript(''); |
pipelet | A pipelet header with @input and @output, importPackage(dw.system); and an execute that returns PIPELET_NEXT |
trycatchif | try { } 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
| Kind | File | Content |
|---|---|---|
| Module | .ds | 'use strict'; and module.exports = {}; |
| Pipelet script | .ds | A header with @input Input and @output Output, and an execute that returns PIPELET_NEXT |
| Job step module | .js | exports.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:
| Intention | What it does |
|---|---|
| Convert to 'for...of' loop | for 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 JSDoc | function total(basket : Basket, rate : Number) : String gets @param {dw.order.Basket} basket, @param {number} rate and @returns {string} |
| Convert JSDoc types to annotations | The way back, in .ds files only. Union and generic types stay in JSDoc |
| Replace the import call with require | importClass(dw.util.HashMap); becomes var HashMap = require('dw/util/HashMap');, see Replace with require |
| Extract template script to a server module | In <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:
| Color | Paints |
|---|---|
| Rhino keyword (for each, default xml namespace) | each, and xml namespace in default xml namespace |
| Type annotation | The type after :, and the type on a pipelet header line |
| Unresolved name, type or script path | Classes 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 path | See Colors |
| E4X › Attribute | @id and @* |
| E4X › Operator | .., ::, .( and .* |
| Pipelet › Header tag | @input and @output |
| Pipelet › Dictionary key | The 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
.dsfiles. Stopped in a.dsfile, a server.jsfile or a template, Evaluate Expression and watches parse Digital Script, sofor each (var item in items)andvar total : Numberwork 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