To upgrade to the latest compatibility mode, you must understand what changed between modes, so that you can make the corresponding changes to your code.
Your site uses one of the following compatibility modes: 10.4, 10.6, 13.6, 15.5, 16.1, 16.2,17.7, 18.2, 18.10, 19.10, or 21.2.
The dw.system.System.getCompatibilityMode()
method returns the compatibility
mode of the custom code version that is currently active. The compatibility mode is returned
as a number, for example, compatibility mode 15.5 is returned as 1505.
class
, export
,
extends
, import
, super
,
await
, enum
implements
, interface
,
package
, private
, protected
,
public
, static
String
,
Number
, Array
, Math
, and
Object
. The new methods are designated as API
Versioned, From version 21.2 in B2C Commerce Script
documentation.for..of
loops.function *
syntax.)19.10 includes the following changes:
dw.svc.ServiceRegistry
,
dw.svc.ServiceDefinition
, and the subclasses of
dw.svc.ServiceDefinition
have been removed from the script API. These
classes had been previously deprecated and replaced with
dw.svc.LocalServiceRegistry
. You can’t register
ServiceDefinitions
using an init
script in
package.json
. The init
scripts are no longer
executed.guard.js
, change the type to string, as follows:Change this:
session.custom.TargetLocation = browsing.lastUrl();
To this:
session.custom.TargetLocation = ''+browsing.lastUrl();
The dw.util.StringUtils#formatNumber(number,format,locale)
API method now
respects the regional settings of the locale for grouping and decimal characters.
Before Compatibility Mode 18.10, this method ignored the defined regional settings and used the format setting from Java for the specified locale.
Exceptions from JavaScript functions called by script API classes were wrapped as a SystemError. This situation led to issues if the exception was an APIException, because the additional properties weren’t accessible.
A method where this situation occurred is dw.util.Transaction.wrap()
:
try {
dw.util.Transaction.wrap(function () {
throw new Error("my error");
});
} catch (e)
{
return {message: e.message, name: e.name};
}
Before Compatibility Mode 18.2, this example returned the unexpected result:
message: com.demandware.core.script.capi.ScriptingException: Error: test error (...) name: SystemError.
With 18.2 Compatibility Mode, the original exception object remains intact, which means the example returns the following message:
test error name: Error
APP-49849: Changed Argument Handling of ISML.RenderTemplate
The behavior of the dw.template.ISML.renderTemplate()
method has changed
slightly. The template execution is now scoped. All variables passed to the template are
only placed in the dictionary temporarily. After the template finishes, the original
pipeline dictionary is recovered. Previously, arguments passed into the template were placed
in the global pipeline dictionary. Having the arguments in the global pipeline dictionary
led to naming conflicts and changed values in the dictionary after the template
returned.
With Compatibility Mode 16.2 it, you can encrypt and decrypt a message with a salt of ‘0’, using the Cipher class in the Salesforce B2C Commerce API. When using a previous compatibility mode, a system-defined salt was used if the developer passed a salt that consisted solely of bytes with value 0x00 or other characters that are represented by ASCII codes less than or equal to 0x20.
Compatibility Mode 16.1 used the following salt values:
If you must reproduce the behavior of compatibility modes before Release 16.2 on an instance that has 16.2 enabled, use these salts as the salt parameters to encrypt or decrypt.
APP-33920: ECMAScript 5 compliant behavior of global function parseInt(String) in code compatibility version 16.1
Starting with B2C Commerce Script API (code compatibility) version 16.1, the parseInt(String) function is ECMAScript 5 compliant. In older versions, the function was only compliant with ECMAScript 3. The difference is that with ECMAScript 5, octal number support was dropped. Numbers starting with leading zeros are now parsed to radix 10 instead of radix 8, as previously. If the dynamic radix determination isn't needed explicitly, the use of parseInt(String, Number) is still recommended.
APP-34144: Map.Values() Returns a View to the Map in Code Compatibility Version 16.1
Starting with B2C Commerce Script API (code compatibility) version 16.1, the Map.values() method now returns a view to a map the same way the Map.keySet() and Map.entrySet() methods did in earlier versions. Previously, the Map.values() method returned an independent collection where modification didn’t change the map.
APP-32403: SiteGenesis Release 15.3 and 15.4 Developers Must Modify Their Code If Using the Release 15.5 B2C Commerce Script API
A recent change in the way the 15.5 B2C Commerce Script API handles global variables means
that customers who have adopted SiteGenesis Releases 15.3 or 15.4 must explicitly declare
the paths of global functions such as dw.system.Logger
and
dw.web.URLUtils
.
Who Does This Affect?
This change affects only customers using SiteGenesis Releases 15.3 and 15.4, and who have set the B2C Commerce Script API Compatibility Mode to 15.5. This change doesn't affect customers using B2C Commerce Script API Version 13.6 or using SiteGenesis 15.2 or earlier or SiteGenesis 15.5 or later.
How Does the Problem Appear?
If you’re using SiteGenesis Release 15.3 or 15.4 and you’re using B2C Commerce Script API 15.5, you can't access the Cart page in SiteGenesis. You get an error in your log file as follows:
org.mozilla.javascript.EcmaError: ReferenceError:
"Logger" isn't defined.
(app_storefront_core/cartridge/scripts/cart/calculate.js#271)
in line 271
What Should I Do If This Happens to Me?
calculate.js
, orcalculate.js
, replace all calls to Logger()
to the
fully qualified version, as follows:
dw.system.Logger()
.APP-23919: Global Scope of Caller Not Accessible by Called Modules with Compatibility Version 15.5
The require()
script now works properly within pipelines (Assign Node).
Previously, global variables were shared between modules, which limited isolation and
reusability. Global variables defined in a module script didn’t work, while they worked
properly when requiring the module in another script.
See the following example:
TopLevelScript.ds
importPackage( dw.system );
var globalVariable = PIPELET_ERROR;
function execute( args : PipelineDictionary ) :
Number
{
return require("myModule");
}
MyModule.ds
var globalVariable;
module.exports = globalVariable || PIPELET_NEXT;
With compatibility version 15.5, the PIPELET_NEXT
is returned, while
previous compatibility versions returned a PIPELET_ERROR
.
Activate the new behavior by selecting compatibility version 15.5.
Customer impact: Review your code for use of the require()
script that
relies on the leakage of variables from the caller scope into the module.
APP-30008: Cipher Methods Expect a Base64-Encoded Salt with Compatibility Version 15.5
Starting with API Version 15.5, all dw.crypto.Cipher
methods expect the
salt argument to be base64-encoded.
APP-30138: Module Lifetime Is Entire Request with Compatibility Version 15.5
With code compatibility version 15.5, modules are now loaded and instantiated only once
per request. If within script code a require()
call requests the module a
second time, then the same instance as the first call is returned. This return of the same
instance happens regardless of the location of the require call (pipeline, script files, or
ISML files).
Previously, the module cache that was held within the implementation of
require()
wasn’t global per request, but belonged to the JavaScript
context. For every new context, a new cache was created. Modules that were resolved in a
script were therefore not visible to script sections contained in templates (for example,
isscript
) because scripts had their scope, and templates had another
scope.
APP-30693: Log notification for changed methods in older API Versions
If a method behavior changes, but the method signature stays the same, and the method is still used with an old B2C Commerce Script API version active (also referred to as Compatibility Mode), B2C Commerce now writes notifications to the API log.
For example, if a fictitious class method apiClass.setMethod(String one) existed in the old B2C Commerce Script API Version 13.6 (which is the last active Compatibility Mode in 15.4) and the behavior changed with the new B2C Commerce Script API (a new Compatibility Mode) in Release 15.5, the usage of apiClass.setMethod in Release 15.5 executed on the old B2C Commerce Script API version 13.6 will log a message such as the following to the API log file:
API Method apiClass.setMethod(String) has been changed in a newer API Version.
Consider updating."
The same invocation on the newer B2C Commerce Script API (Compatibility Mode 15.5 after you activated this new API) will no longer log this type of message.
APP-31925: Strict JSON parsing enforced with code compatibility version 15.5
Starting with B2C Commerce Script API (code compatibility) version 15.5, strict parsing is enforced. Previously, versions of the JSON parsers in B2C Commerce accepted invalid JSON that contained extraneous commas before closing brackets.
APP-32088: ECMAScript compliance issue in B2C Commerce script parser fixed with compatibility version 15.5
When compatibility version 15.5 is selected, an error is thrown when code accesses undeclared properties, which is proper ECMAScript behavior. For compatibility reasons, this behavior is still allowed if you select a compatibility version earlier than 15.5.
APP-18307: SeekableIterator in Pipeline Dictionary
In B2C Commerce script files, you can call API methods that return a
dw.util.SeekableIterator
instance. A SeekableIterator
enables you to iterate over its elements a single time. However, if you put this iterator
into the Pipeline Dictionary and your API compatibility mode is earlier than 13.6, you can
use the iterator multiple times. Depending on the number of elements the iterator
represents, this approach can cause memory usage issues.
As of API compatibility mode 13.6, the elements in the SeekableIterator
can only be accessed one time. If you’re using an API compatibility mode that pre-dates
13.6, there are entries in the API log indicating that the SeekableIterator is being placed
into the Pipeline Dictionary. These log entries enable you to identify uses of
SeekableIterator where moving to 13.6 compatibility mode can cause a change in your Pipeline
behavior.
The log entries take the following form:
PipelineDictionary usage violation:
WARN: dw.util.SeekableIterator put in dictionary.
KEY: key_name, SCRIPT: script_name
where key_name
is the pipeline dictionary key, and
script_name
is the name of the script that is putting the
SeekableIterator
into the dictionary.
APP-46080: SeekableIterator.close()
now
ensures that the iterator is closed
As of Release 17.2, SeekableIterator.close() n
ow ensures that the
iterator is closed. Previously in some situations, it was possible to read elements from a
dw.util.SeekableIterator
even after close was explicitly called.
Customer impact: for compatibility modes 10.6 and greater, the iterator must always be
empty after a call to close()
.
APP-15882: API Behavior Change When Accessing SeekableIteratot via the Pipeline Dictionary
Instances of SeekableIterator
are returned in the API whenever a method
returns mass data. Starting with API version 10.6, these iterators can only be iterated one
time to avoid possible memory problems for large iterators. Putting them into the pipeline
dictionary and trying to loop them multiple times is no longer possible because this
approach would require buffering the iterated elements internally.
Previously, and for all customers still running API version 10.4 (compatibility mode),
SeekableIterator
instances stored in the pipeline dictionary could be
iterated multiple times (for example, by several loop nodes).
Customer Impact: Check your code for instances of SeekableIterator and adjust as required.
Product Attributes Set At Site Level (No Release Note)
With Compatibility Mode 10.6, the product attributes onlineFlag
,
searchableFlag
, searchPlacement
, and
searchRank
are set at the site level. Previously they were set at global
level.
APP-15381: Improved ProductAttributeModel Methods GetValue() and GetDisplayValue()
The getValue()
and getDisplayValue()
ProductAttributeModel
methods now return a MediaFile
instance if there’s a custom image attribute, or a MarkupText instance if there’s a custom
HTML attribute. Previously, both methods returned the image path or the HTML source as a
simple String.
APP-12148: Inventory levels are now adjusted on order cancellation and order Replacement
For instances configured (via API versioning) to use the B2C Commerce API version 10.6 or later, inventory levels are now adjusted to reflect items from canceled or replaced orders. Previously, when an order was canceled or replaced, no change was made to inventory levels.
Example 1: If an order has 5 units of product X, when the order is canceled, the availability of product X increases by five units.
Example 2: Assume the following:
If order A is replaced by order B, then the number of units available changes: -1 units of X, +2 units of Y, and -5 units of Z
When replacing order A with order B, the inventory levels now reflect that the items in order A are available.
This behavior is the original behavior. You have this version or greater.