Digital Script checks run as you type in .ds files and server .js files, most with a quick fix. They're in Settings › Editor › Inspections › SFCC › Digital Script, all on except Rhino-only syntax that ES2015 replaces
importClass, a class passed to importPackage, a script path that is not a string literal. The first three have a fix that writes the right callThe syntax checks are free and work while the IDE indexes. The other checks need a license and wait until indexing ends
Import calls
| Inspection | Level | Message | Fix |
|---|---|---|---|
| importScript path that names no script | Error | Cannot find script 'cart/Missing.ds' | Create 'cart/Missing.ds' in app_core, with the folders it needs |
| Warning | B2C Commerce needs the file name with its extension: 'cart/CartUtils.ds' | Add '.ds', or Add '/index.js' | |
| Wrong argument to importClass, importPackage or importScript | Error | 'dw.util' is a package: importPackage imports it, 'dw.util.HashMap' is a class: importClass imports it | Use importPackage, Use importClass |
| Error | importPackage takes the package name itself, not a string | Remove quotes, for a dotted name | |
| Error | importScript takes the script path as a string literal, such as 'app_core:cart/CartUtils.ds', importClass takes one class name | None | |
| Unused or repeated import call | Warning, in gray | importPackage(dw.util) repeats an earlier import call, importPackage(dw.catalog) is not used | Remove the import call, see Optimize Imports |
| Class name two imported packages provide | Warning | 'AgentUserStatusCodes' is a class of both dw.customer and dw.system: Rhino stops with an ambiguous import | Use dw.customer.AgentUserStatusCodes, Add importClass(dw.customer.AgentUserStatusCodes), one of each per package |
| Warning | This file declares a function 'HashMap': importClass fails at runtime because the name is defined | Remove the import call | |
| Function an importScript brings that the script hides | Warning | This file declares 'getTotal' itself, which hides the function of the same name from cart/CartUtils.ds | Rename |
| Weak warning | A later importScript imports every function of cart/CartUtils.ds again | Remove the import call | |
| Name used before the import call that binds it | Warning | 'HashMap' is used before importPackage(dw.util) runs | Move the import call to the top of the file |
| B2C Commerce class the script does not import | Error | 'HashMap' is a class of dw.util that this script does not import | Add importPackage(dw.util), Add importClass(dw.util.HashMap), Use require('dw/util/HashMap') |
| Variable of an importScript target | Error | 'calcTax' is a variable of cart/CartUtils.ds: importScript brings only the script's functions | Declare 'calcTax' as a function in CartUtils.ds, when the variable holds a plain function expression |
| Map or Set after importPackage(dw.util) | Warning | importPackage(dw.util) makes 'Map' the class dw.util.Map, not the ECMAScript Map | Import the classes the script uses instead |
- importScript path that names no script and Wrong argument also run in
<isscript>, see Scripting in ISML - A path without a
cartridge:prefix is checked against the calling script's cartridge only, see Script paths - Name used before the import call checks top-level code outside functions, and only when every call that binds the name comes after the use
- Class name two imported packages provide stays quiet when an
importClasspicks the class or the file declares the name - Import the classes the script uses instead writes one
importClassperdw.utilclass the script uses, other thanMapandSet. With none, it removes the call. The check runs with no mode set or from mode 21.2 - Rename is offered as you type, not in Inspect Code
Syntax
Free, and they work while the IDE indexes:
| Inspection | Level | Message | Fix |
|---|---|---|---|
| Script syntax the compatibility mode does not support | Error | Compatibility mode 19.10 does not support arrow functions (21.2 or later), No B2C compatibility mode supports optional chaining | Convert to 'for each' loop, Convert to string concatenation, Convert to function expression |
| 'each' in a for (;;) loop | Warning | 'each' has no effect in a for (;;) loop | Remove 'each' |
| Rhino-only syntax that ES2015 replaces | Weak warning, off by default | 'for each' is a Rhino extension; ES2015 code uses for...of | None, use the Convert to 'for...of' loop intention |
for each (var x of items) is always an error, invalid for each loop, with Remove 'each' and Use 'in'. Templates have their own mode check, see Syntax & Compatibility Mode
let and const
B2C Commerce runs let and const on Rhino, which doesn't follow ES6: a let doesn't stay in its block, a const holds for its whole function and is set once per call, and the script debugger doesn't always show either. var runs the same in every compatibility mode
let can outlive its block and a const holds for its whole function. Each one is a weak warning whose fix writes var, and Fix all converts a file at once| Inspection | Level | Message | Fix |
|---|---|---|---|
| 'let' or 'const' in server code | Weak warning | Use 'var': Rhino's 'let' does not follow ES6 block scope, Use 'var': Rhino's 'const' is function scoped and set once per call | Replace 'let' with 'var', Replace 'const' with 'var' |
| Weak warning | 'limit' is assigned again, which Rhino ignores for a 'const': fix that, then use 'var' | None | |
| Weak warning | Rename 'count' first: as a 'var' it would merge with another 'count' this function uses | None | |
| 'const' in a loop that keeps its first value | Warning | 'item' keeps the value of the first pass: Rhino sets a const once per function call | Replace 'const' with 'var' |
- 'let' or 'const' in server code also runs in
<isscript>. Client scripts and server.tsfiles, which Babel compiles, aren't checked - Use Fix all in the quick-fix menu for a file, or Code › Analyze Code › Run Inspection by Name for a whole cartridge
- A
letwithout a value whose block runs again, in a loop or in an<isscript>inside<isloop>, becomesvar x = undefined, so it starts empty on each pass as theletdid - The fix is held back where
varwould change what the code does: aconstassigned again, or a name the function also gives to another variable. Rename the variable, then apply the fix - 'const' in a loop reports only a value that changes between passes, such as
items.next()or a name the loop assigns. Arequireor a site preference isn't reported - While 'let' or 'const' in server code is on, the IDE's Convert to let and Convert to const aren't offered in server code
A const declared in a block resolves for the whole function, see Block const
Names and host objects
| Inspection | Level | Message | Fix |
|---|---|---|---|
| Name that nothing declares | Error | Cannot find name 'unknownCall' | The IDE's create fixes |
| Type annotation that names no type | Error | Cannot find type 'Strin' | None |
| Host object B2C Commerce does not have | Warning | 'setTimeout' is not available on B2C Commerce | Use dw.system.Logger.debug on a console call |
| Weak warning | 'module' does not exist in templates, and the same for exports | None |
Name that nothing declares and Host object also run in templates. Which names they skip, and the full host object list, are in Scopes & Types
Pipelets
Pipelet script that breaks the pipeline contract is a warning on pipelet scripts. A missing execute is an error, and a pdict key the header doesn't declare is a weak warning
| Message | Fix |
|---|---|
A pipelet script needs an execute function: the pipeline calls it | Create the execute function |
The script never assigns @output 'Total' | None |
execute returns nothing: the pipeline expects PIPELET_NEXT or PIPELET_ERROR | Return PIPELET_NEXT |
The pipelet header does not declare 'Undeclared' | Add '@input Undeclared : Object' to the header |
Every message is in The pipeline contract
TypeScript sources
Two checks catch what breaks when a server .ts file deploys. .d.ts and client .ts files aren't checked
| Inspection | Message | Fix |
|---|---|---|
| importPackage, importClass or importScript in a server .ts file | importPackage does not bind names in TypeScript: import each class from its module | Import the classes of dw.util the file uses |
importClass does not bind names in TypeScript: import the class from its module | Import HashMap from 'dw/util/HashMap' | |
importScript does not bind names in TypeScript: move the functions into a module and import it | None | |
| Name that changes when a .ts source deploys | Price.js is in the same folder, and both deploy as Price.js | None |
The server has no .ts files: 'helpers/price' names the deployed module | Remove '.ts' | |
The Babel build cannot compile 'export =': assign module.exports | Assign module.exports | |
The Babel build cannot compile 'import = require()': use const | Use const |
Both are warnings. Name that changes when a .ts source deploys also checks .ds and server .js files, see .ds, .js and .ts together