Digital Script Inspections

Digital Script inspections in JetBrains IDEs for import calls, Rhino syntax, unresolved names, host objects, pipelet contracts and .ts sources, with fixes

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

An import call with the wrong argument is an error: a quoted name, a package passed to 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 call

The syntax checks are free and work while the IDE indexes. The other checks need a license and wait until indexing ends

Import calls

InspectionLevelMessageFix
importScript path that names no scriptErrorCannot find script 'cart/Missing.ds'Create 'cart/Missing.ds' in app_core, with the folders it needs
WarningB2C Commerce needs the file name with its extension: 'cart/CartUtils.ds'Add '.ds', or Add '/index.js'
Wrong argument to importClass, importPackage or importScriptError'dw.util' is a package: importPackage imports it, 'dw.util.HashMap' is a class: importClass imports itUse importPackage, Use importClass
ErrorimportPackage takes the package name itself, not a stringRemove quotes, for a dotted name
ErrorimportScript takes the script path as a string literal, such as 'app_core:cart/CartUtils.ds', importClass takes one class nameNone
Unused or repeated import callWarning, in grayimportPackage(dw.util) repeats an earlier import call, importPackage(dw.catalog) is not usedRemove the import call, see Optimize Imports
Class name two imported packages provideWarning'AgentUserStatusCodes' is a class of both dw.customer and dw.system: Rhino stops with an ambiguous importUse dw.customer.AgentUserStatusCodes, Add importClass(dw.customer.AgentUserStatusCodes), one of each per package
WarningThis file declares a function 'HashMap': importClass fails at runtime because the name is definedRemove the import call
Function an importScript brings that the script hidesWarningThis file declares 'getTotal' itself, which hides the function of the same name from cart/CartUtils.dsRename
Weak warningA later importScript imports every function of cart/CartUtils.ds againRemove the import call
Name used before the import call that binds itWarning'HashMap' is used before importPackage(dw.util) runsMove the import call to the top of the file
B2C Commerce class the script does not importError'HashMap' is a class of dw.util that this script does not importAdd importPackage(dw.util), Add importClass(dw.util.HashMap), Use require('dw/util/HashMap')
Variable of an importScript targetError'calcTax' is a variable of cart/CartUtils.ds: importScript brings only the script's functionsDeclare 'calcTax' as a function in CartUtils.ds, when the variable holds a plain function expression
Map or Set after importPackage(dw.util)WarningimportPackage(dw.util) makes 'Map' the class dw.util.Map, not the ECMAScript MapImport 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 importClass picks the class or the file declares the name
  • Import the classes the script uses instead writes one importClass per dw.util class the script uses, other than Map and Set. 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:

InspectionLevelMessageFix
Script syntax the compatibility mode does not supportErrorCompatibility mode 19.10 does not support arrow functions (21.2 or later), No B2C compatibility mode supports optional chainingConvert to 'for each' loop, Convert to string concatenation, Convert to function expression
'each' in a for (;;) loopWarning'each' has no effect in a for (;;) loopRemove 'each'
Rhino-only syntax that ES2015 replacesWeak warning, off by default'for each' is a Rhino extension; ES2015 code uses for...ofNone, 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

B2C Commerce runs server scripts on Rhino, where a 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
InspectionLevelMessageFix
'let' or 'const' in server codeWeak warningUse 'var': Rhino's 'let' does not follow ES6 block scope, Use 'var': Rhino's 'const' is function scoped and set once per callReplace '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 warningRename 'count' first: as a 'var' it would merge with another 'count' this function usesNone
'const' in a loop that keeps its first valueWarning'item' keeps the value of the first pass: Rhino sets a const once per function callReplace 'const' with 'var'
  • 'let' or 'const' in server code also runs in <isscript>. Client scripts and server .ts files, 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 let without a value whose block runs again, in a loop or in an <isscript> inside <isloop>, becomes var x = undefined, so it starts empty on each pass as the let did
  • The fix is held back where var would change what the code does: a const assigned 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. A require or 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

InspectionLevelMessageFix
Name that nothing declaresErrorCannot find name 'unknownCall'The IDE's create fixes
Type annotation that names no typeErrorCannot find type 'Strin'None
Host object B2C Commerce does not haveWarning'setTimeout' is not available on B2C CommerceUse dw.system.Logger.debug on a console call
Weak warning'module' does not exist in templates, and the same for exportsNone

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

MessageFix
A pipelet script needs an execute function: the pipeline calls itCreate the execute function
The script never assigns @output 'Total'None
execute returns nothing: the pipeline expects PIPELET_NEXT or PIPELET_ERRORReturn 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

InspectionMessageFix
importPackage, importClass or importScript in a server .ts fileimportPackage does not bind names in TypeScript: import each class from its moduleImport the classes of dw.util the file uses
importClass does not bind names in TypeScript: import the class from its moduleImport HashMap from 'dw/util/HashMap'
importScript does not bind names in TypeScript: move the functions into a module and import itNone
Name that changes when a .ts source deploysPrice.js is in the same folder, and both deploy as Price.jsNone
The server has no .ts files: 'helpers/price' names the deployed moduleRemove '.ts'
The Babel build cannot compile 'export =': assign module.exportsAssign module.exports
The Babel build cannot compile 'import = require()': use constUse 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

On this page