eslint-plugin-sfmc 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,7 +49,8 @@ Add the following to your `.vscode/settings.json`:
49
49
  "markdown",
50
50
  "ampscript",
51
51
  "ssjs",
52
- "sfmc"
52
+ "sfmc",
53
+ "handlebars"
53
54
  ]
54
55
  }
55
56
  ```
@@ -72,15 +73,15 @@ Add the following to your `.vscode/settings.json`:
72
73
 
73
74
  ### Marketing Cloud Next
74
75
 
75
- Use the `-next` config variants when targeting **Marketing Cloud Next (MCN)**. MCN supports only a subset of AMPscript functions and does **not** support SSJS at all.
76
+ Use the `-next` config variants when targeting **Marketing Cloud Next (MCN)**. MCN supports only a subset of AMPscript functions and does **not** support SSJS at all. Handlebars is MCN's templating language, so the `embedded-next` and `strict-next` configs also lint the `{{...}}` helpers and `{!$...}` bindings extracted from HTML (see [Handlebars Rules](#handlebars-rules-hbs-)).
76
77
 
77
- | Config | Files | What it does |
78
- | ---------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------- |
79
- | `sfmc.configs['ampscript-next']` | `**/*.ampscript`, `**/*.amp` | AMPscript rules + flags functions unsupported in MCN (single config object) |
80
- | `sfmc.configs['ssjs-next']` | `**/*.ssjs` | Flags all SSJS API calls as MCN-unsupported; all other SSJS quality rules disabled |
81
- | `sfmc.configs['recommended-next']` | Both of the above | AMPscript MCN-aware + SSJS flagged for standalone files |
82
- | `sfmc.configs['embedded-next']` | `**/*.html` | AMPscript MCN-aware + SSJS flagged for HTML-embedded code |
83
- | `sfmc.configs['strict-next']` | All of the above + HTML | All AMPscript rules at `error` severity + MCN flag; SSJS fully flagged |
78
+ | Config | Files | What it does |
79
+ | ---------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------- |
80
+ | `sfmc.configs['ampscript-next']` | `**/*.ampscript`, `**/*.amp` | AMPscript rules + flags functions unsupported in MCN (single config object) |
81
+ | `sfmc.configs['ssjs-next']` | `**/*.ssjs` | Flags all SSJS API calls as MCN-unsupported; all other SSJS quality rules disabled |
82
+ | `sfmc.configs['recommended-next']` | Both of the above | AMPscript MCN-aware + SSJS flagged for standalone files |
83
+ | `sfmc.configs['embedded-next']` | `**/*.html` | AMPscript MCN-aware + SSJS flagged + Handlebars rules for HTML-embedded code |
84
+ | `sfmc.configs['strict-next']` | All of the above + HTML | All AMPscript rules at `error` severity + MCN flag; SSJS fully flagged; Handlebars rules on |
84
85
 
85
86
  `recommended-next`, `embedded-next`, and `strict-next` are arrays — spread them with `...`.
86
87
 
@@ -93,62 +94,64 @@ export default [...sfmc.configs['recommended-next'], ...sfmc.configs['embedded-n
93
94
 
94
95
  ## AMPscript Rules (`amp-*`)
95
96
 
96
- | Rule | Default | Description |
97
- | ------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------ |
98
- | [`sfmc/amp-no-unknown-function`](docs/rules/amp/no-unknown-function.md) | `error` | Disallow calls to unknown AMPscript functions |
99
- | [`sfmc/amp-function-arity`](docs/rules/amp/function-arity.md) | `error` | Enforce correct argument counts |
100
- | [`sfmc/amp-arg-types`](docs/rules/amp/arg-types.md) | `error` | Check that literal arguments match expected parameter types and allowed values |
101
- | [`sfmc/amp-set-requires-target`](docs/rules/amp/set-requires-target.md) | `error` | Require `set` to have a target variable |
102
- | [`sfmc/amp-no-smart-quotes`](docs/rules/amp/no-smart-quotes.md) | `error` | Disallow smart/curly quotes in strings |
103
- | [`sfmc/amp-no-var-redeclaration`](docs/rules/amp/no-var-redeclaration.md) | `warn` | Disallow re-declaring a variable with `var` |
104
- | [`sfmc/amp-no-empty-block`](docs/rules/amp/no-empty-block.md) | `warn` | Disallow empty `%%[ ]%%` blocks |
105
- | [`sfmc/amp-no-loop-counter-assign`](docs/rules/amp/no-loop-counter-assign.md) | `warn` | Disallow assigning to the `for` loop counter |
106
- | [`sfmc/amp-no-inline-statement`](docs/rules/amp/no-inline-statement.md) | `warn` | Disallow statements inside inline expressions |
107
- | [`sfmc/amp-no-deprecated-function`](docs/rules/amp/no-deprecated-function.md) | `warn` | Flag deprecated functions and suggest replacements |
108
- | [`sfmc/amp-naming-convention`](docs/rules/amp/naming-convention.md) | `warn` | Enforce variable naming convention |
109
- | [`sfmc/amp-no-empty-then`](docs/rules/amp/no-empty-then.md) | `warn` | Disallow IF with empty THEN branch |
110
- | [`sfmc/amp-require-rowcount-check`](docs/rules/amp/require-rowcount-check.md) | `warn` | Require RowCount check before FOR on LookupRows |
111
- | [`sfmc/amp-no-html-comment`](docs/rules/amp/no-html-comment.md) | `warn` | Disallow HTML comments inside AMPscript blocks |
112
- | [`sfmc/amp-no-js-line-comment`](docs/rules/amp/no-js-line-comment.md) | `warn` | Disallow JS-style `//` line comments in AMPscript |
113
- | [`sfmc/amp-no-nested-script-tag`](docs/rules/amp/no-nested-script-tag.md) | `error` | Disallow `<script>` tags nested inside AMPscript script tags |
114
- | [`sfmc/amp-no-nested-ampscript-delimiter`](docs/rules/amp/no-nested-ampscript-delimiter.md) | `error` | Disallow AMPscript delimiters nested inside AMPscript blocks |
115
- | [`sfmc/amp-prefer-attribute-value`](docs/rules/amp/prefer-attribute-value.md) | off | Prefer `AttributeValue()` over bare personalization |
116
- | [`sfmc/amp-require-variable-declaration`](docs/rules/amp/require-variable-declaration.md) | off | Require `var` before `set` |
117
- | [`sfmc/amp-no-email-excluded-function`](docs/rules/amp/no-email-excluded-function.md) | off | Flag functions unavailable in email context |
97
+ | Rule | Default | Description |
98
+ | ------------------------------------------------------------------------------------------- | ------------------------ | ----------------------------------------------------------------------------------- |
99
+ | [`sfmc/amp-no-unknown-function`](docs/rules/amp/no-unknown-function.md) | `error` | Disallow calls to unknown AMPscript functions |
100
+ | [`sfmc/amp-no-mcn-unsupported`](docs/rules/amp/no-mcn-unsupported.md) | off (`error` in `-next`) | Flag AMPscript functions unavailable in the targeted MCN API version (`apiVersion`) |
101
+ | [`sfmc/amp-function-arity`](docs/rules/amp/function-arity.md) | `error` | Enforce correct argument counts |
102
+ | [`sfmc/amp-arg-types`](docs/rules/amp/arg-types.md) | `error` | Check that literal arguments match expected parameter types and allowed values |
103
+ | [`sfmc/amp-set-requires-target`](docs/rules/amp/set-requires-target.md) | `error` | Require `set` to have a target variable |
104
+ | [`sfmc/amp-no-smart-quotes`](docs/rules/amp/no-smart-quotes.md) | `error` | Disallow smart/curly quotes in strings |
105
+ | [`sfmc/amp-no-var-redeclaration`](docs/rules/amp/no-var-redeclaration.md) | `warn` | Disallow re-declaring a variable with `var` |
106
+ | [`sfmc/amp-no-empty-block`](docs/rules/amp/no-empty-block.md) | `warn` | Disallow empty `%%[ ]%%` blocks |
107
+ | [`sfmc/amp-no-loop-counter-assign`](docs/rules/amp/no-loop-counter-assign.md) | `warn` | Disallow assigning to the `for` loop counter |
108
+ | [`sfmc/amp-no-inline-statement`](docs/rules/amp/no-inline-statement.md) | `warn` | Disallow statements inside inline expressions |
109
+ | [`sfmc/amp-no-deprecated-function`](docs/rules/amp/no-deprecated-function.md) | `warn` | Flag deprecated functions and suggest replacements |
110
+ | [`sfmc/amp-naming-convention`](docs/rules/amp/naming-convention.md) | `warn` | Enforce variable naming convention |
111
+ | [`sfmc/amp-no-empty-then`](docs/rules/amp/no-empty-then.md) | `warn` | Disallow IF with empty THEN branch |
112
+ | [`sfmc/amp-require-rowcount-check`](docs/rules/amp/require-rowcount-check.md) | `warn` | Require RowCount check before FOR on LookupRows |
113
+ | [`sfmc/amp-no-html-comment`](docs/rules/amp/no-html-comment.md) | `warn` | Disallow HTML comments inside AMPscript blocks |
114
+ | [`sfmc/amp-no-js-line-comment`](docs/rules/amp/no-js-line-comment.md) | `warn` | Disallow JS-style `//` line comments in AMPscript |
115
+ | [`sfmc/amp-no-nested-script-tag`](docs/rules/amp/no-nested-script-tag.md) | `error` | Disallow `<script>` tags nested inside AMPscript script tags |
116
+ | [`sfmc/amp-no-nested-ampscript-delimiter`](docs/rules/amp/no-nested-ampscript-delimiter.md) | `error` | Disallow AMPscript delimiters nested inside AMPscript blocks |
117
+ | [`sfmc/amp-prefer-attribute-value`](docs/rules/amp/prefer-attribute-value.md) | off | Prefer `AttributeValue()` over bare personalization |
118
+ | [`sfmc/amp-require-variable-declaration`](docs/rules/amp/require-variable-declaration.md) | off | Require `var` before `set` |
119
+ | [`sfmc/amp-no-email-excluded-function`](docs/rules/amp/no-email-excluded-function.md) | off | Flag functions unavailable in email context |
118
120
 
119
121
  ## SSJS Rules (`ssjs-*`)
120
122
 
121
- | Rule | Default | Description |
122
- | ------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------ |
123
- | [`sfmc/ssjs-require-platform-load`](docs/rules/ssjs/require-platform-load.md) | `error` | Require `Platform.Load("core")` before Core or requiresCoreLoad globals |
124
- | [`sfmc/ssjs-no-unsupported-syntax`](docs/rules/ssjs/no-unsupported-syntax.md) | `error` | Flag ES6+ syntax not supported by SFMC |
125
- | [`sfmc/ssjs-no-unknown-function`](docs/rules/ssjs/no-unknown-function.md) | `error` | Disallow unknown methods on Platform.\*, HTTP, Core Library, and WSProxy |
126
- | [`sfmc/ssjs-no-deprecated-function`](docs/rules/ssjs/no-deprecated-function.md) | `error` | Flag use of deprecated SFMC SSJS APIs (e.g. ContentArea, ContentAreaObj) |
127
- | [`sfmc/ssjs-no-property-call`](docs/rules/ssjs/no-property-call.md) | `error` | Disallow calling Platform.Request/Response properties as functions |
128
- | [`sfmc/ssjs-platform-function-arity`](docs/rules/ssjs/platform-function-arity.md) | `error` | Enforce correct arity for `Platform.Function.*` |
129
- | [`sfmc/ssjs-require-platform-load-order`](docs/rules/ssjs/require-platform-load-order.md) | `error` | Require `Platform.Load()` before Core usage in order |
130
- | [`sfmc/ssjs-no-hardcoded-credentials`](docs/rules/ssjs/no-hardcoded-credentials.md) | `error` | Flag hardcoded keys in encryption calls |
131
- | [`sfmc/ssjs-cache-loop-length`](docs/rules/ssjs/cache-loop-length.md) | `warn` | Require caching `.length` in for-loops |
132
- | [`sfmc/ssjs-require-hasownproperty`](docs/rules/ssjs/require-hasownproperty.md) | `warn` | Require `hasOwnProperty` guard in for-in loops |
133
- | [`sfmc/ssjs-prefer-platform-load-version`](docs/rules/ssjs/prefer-platform-load-version.md) | `warn` | Enforce a minimum `Platform.Load` version string |
134
- | [`sfmc/ssjs-no-unavailable-method`](docs/rules/ssjs/no-unavailable-method.md) | `warn` | Flag Array/String methods unavailable or broken in SFMC's ES3 engine |
135
- | [`sfmc/ssjs-prefer-parsejson-safe-arg`](docs/rules/ssjs/prefer-parsejson-safe-arg.md) | `warn` | Require string coercion on `ParseJSON` argument |
136
- | [`sfmc/ssjs-no-switch-default`](docs/rules/ssjs/no-switch-default.md) | `warn` | Disallow `default` clause in `switch` statements |
137
- | [`sfmc/ssjs-no-treatascontent-injection`](docs/rules/ssjs/no-treatascontent-injection.md) | `warn` | Flag dynamic string concatenation in `TreatAsContent` calls |
138
- | [`sfmc/ssjs-core-method-arity`](docs/rules/ssjs/core-method-arity.md) | `warn` | Enforce correct argument counts for Core Library object methods |
139
- | [`sfmc/ssjs-arg-types`](docs/rules/ssjs/arg-types.md) | `warn` | Check that literal arguments match expected parameter types |
123
+ | Rule | Default | Description |
124
+ | ------------------------------------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------ |
125
+ | [`sfmc/ssjs-require-platform-load`](docs/rules/ssjs/require-platform-load.md) | `error` | Require `Platform.Load("core")` before Core or requiresCoreLoad globals |
126
+ | [`sfmc/ssjs-no-unsupported-syntax`](docs/rules/ssjs/no-unsupported-syntax.md) | `error` | Flag ES6+ syntax not supported by SFMC |
127
+ | [`sfmc/ssjs-no-unknown-function`](docs/rules/ssjs/no-unknown-function.md) | `error` | Disallow unknown methods on Platform.\*, HTTP, Core Library, and WSProxy |
128
+ | [`sfmc/ssjs-no-mcn-unsupported`](docs/rules/ssjs/no-mcn-unsupported.md) | off (`error` in `-next`) | Flag all SSJS API usage as unsupported in Marketing Cloud Next |
129
+ | [`sfmc/ssjs-no-deprecated-function`](docs/rules/ssjs/no-deprecated-function.md) | `error` | Flag use of deprecated SFMC SSJS APIs (e.g. ContentArea, ContentAreaObj) |
130
+ | [`sfmc/ssjs-no-property-call`](docs/rules/ssjs/no-property-call.md) | `error` | Disallow calling Platform.Request/Response properties as functions |
131
+ | [`sfmc/ssjs-platform-function-arity`](docs/rules/ssjs/platform-function-arity.md) | `error` | Enforce correct arity for `Platform.Function.*` |
132
+ | [`sfmc/ssjs-require-platform-load-order`](docs/rules/ssjs/require-platform-load-order.md) | `error` | Require `Platform.Load()` before Core usage in order |
133
+ | [`sfmc/ssjs-no-hardcoded-credentials`](docs/rules/ssjs/no-hardcoded-credentials.md) | `error` | Flag hardcoded keys in encryption calls |
134
+ | [`sfmc/ssjs-cache-loop-length`](docs/rules/ssjs/cache-loop-length.md) | `warn` | Require caching `.length` in for-loops |
135
+ | [`sfmc/ssjs-require-hasownproperty`](docs/rules/ssjs/require-hasownproperty.md) | `warn` | Require `hasOwnProperty` guard in for-in loops |
136
+ | [`sfmc/ssjs-prefer-platform-load-version`](docs/rules/ssjs/prefer-platform-load-version.md) | `warn` | Enforce a minimum `Platform.Load` version string |
137
+ | [`sfmc/ssjs-no-unavailable-method`](docs/rules/ssjs/no-unavailable-method.md) | `warn` | Flag Array/String methods unavailable or broken in SFMC's ES3 engine |
138
+ | [`sfmc/ssjs-prefer-parsejson-safe-arg`](docs/rules/ssjs/prefer-parsejson-safe-arg.md) | `warn` | Require string coercion on `ParseJSON` argument |
139
+ | [`sfmc/ssjs-no-switch-default`](docs/rules/ssjs/no-switch-default.md) | `warn` | Disallow `default` clause in `switch` statements |
140
+ | [`sfmc/ssjs-no-treatascontent-injection`](docs/rules/ssjs/no-treatascontent-injection.md) | `warn` | Flag dynamic string concatenation in `TreatAsContent` calls |
141
+ | [`sfmc/ssjs-core-method-arity`](docs/rules/ssjs/core-method-arity.md) | `warn` | Enforce correct argument counts for Core Library object methods |
142
+ | [`sfmc/ssjs-arg-types`](docs/rules/ssjs/arg-types.md) | `warn` | Check that literal arguments match expected parameter types |
140
143
 
141
144
  ## Handlebars Rules (`hbs-*`)
142
145
 
143
146
  Handlebars is the templating language for **Marketing Cloud Next (MCN)** only. These rules are enabled at `error` severity in the `-next` configs and are `off` in the classic (Engagement) configs — in classic SFMC, `{{...}}` is plain content and must not be flagged.
144
147
 
145
- | Rule | Default (`-next`) | Description |
146
- | ----------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------- |
147
- | [`sfmc/hbs-no-unknown-helper`](docs/rules/hbs/no-unknown-helper.md) | `error` | Disallow helper invocations that are not part of the MCN catalog |
148
- | [`sfmc/hbs-no-unknown-binding`](docs/rules/hbs/no-unknown-binding.md) | `error` | Disallow unknown `{!$...}` built-in data bindings |
149
- | [`sfmc/hbs-helper-arity`](docs/rules/hbs/helper-arity.md) | `error` | Enforce correct positional-argument counts for known helpers |
150
- | [`sfmc/hbs-no-unsupported-construct`](docs/rules/hbs/no-unsupported-construct.md) | `error` | Disallow constructs unsupported by the MCN engine (partials, decorators, `log`) |
151
- | [`sfmc/hbs-helper-too-new-for-target`](docs/rules/hbs/helper-too-new-for-target.md) | off | Flag helpers newer than the targeted MCN API version (opt-in via `apiVersion`) |
148
+ | Rule | Default (`-next`) | Description |
149
+ | --------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------ |
150
+ | [`sfmc/hbs-no-unknown-helper`](docs/rules/hbs/no-unknown-helper.md) | `error` | Disallow helper invocations that are not part of the MCN catalog |
151
+ | [`sfmc/hbs-no-unknown-binding`](docs/rules/hbs/no-unknown-binding.md) | `error` | Disallow unknown `{!$...}` built-in data bindings |
152
+ | [`sfmc/hbs-helper-arity`](docs/rules/hbs/helper-arity.md) | `error` | Enforce correct positional-argument counts for known helpers |
153
+ | [`sfmc/hbs-no-unsupported-construct`](docs/rules/hbs/no-unsupported-construct.md) | `error` | Disallow constructs unsupported by the MCN engine (partials, decorators, `log`) |
154
+ | [`sfmc/hbs-no-mcn-unsupported`](docs/rules/hbs/no-mcn-unsupported.md) | `error` | Flag helpers and bindings unavailable in the targeted MCN API version (`apiVersion`) |
152
155
 
153
156
  ## Processors
154
157
 
@@ -0,0 +1,76 @@
1
+ # `sfmc/amp-no-mcn-unsupported`
2
+
3
+ > Disallow AMPscript functions that are not available in the targeted Marketing Cloud Next API version.
4
+
5
+ | | |
6
+ |---|---|
7
+ | **Type** | `problem` |
8
+ | **Default severity** | `error` in all `-next` configs; `off` otherwise |
9
+ | **Fixable** | — |
10
+
11
+ ## Why This Rule Exists
12
+
13
+ Only a subset of AMPscript functions are available in Marketing Cloud Next (MCN), and support has been added gradually across MCN releases. This rule flags AMPscript functions that will not work in the MCN release you target:
14
+
15
+ - Functions that **Marketing Cloud Next never supported** — they only work in classic Marketing Cloud Engagement.
16
+ - Functions that were **added in a later MCN release** than the one you target (see the `apiVersion` option below).
17
+ - Functions that work in MCN AMPscript but have **no Handlebars equivalent**, so they cannot be carried over if you later migrate the content to Handlebars.
18
+
19
+ Unknown function names are handled separately by [`sfmc/amp-no-unknown-function`](no-unknown-function.md); this rule only checks functions that actually exist in AMPscript.
20
+
21
+ ## Settings
22
+
23
+ | Setting | Values | Default |
24
+ |---------|--------|---------|
25
+ | severity | `"error"` \| `"warn"` \| `"off"` | `"error"` in `-next` configs |
26
+
27
+ ### Options
28
+
29
+ | Option | Type | Default | Description |
30
+ |--------|------|---------|-------------|
31
+ | `apiVersion` | `number` | — | The targeted Marketing Cloud Next API version (e.g. `65` = Winter '26, `67` = Summer '26). |
32
+
33
+ **What `apiVersion` does** (shared with the SSJS and Handlebars MCN rules):
34
+
35
+ - **Leave it unset** to check against _any_ MCN release: a function is flagged only if it is never supported in Marketing Cloud Next. Anything that works in some MCN release is allowed.
36
+ - **Set it to your target release** (for example `65`) to also flag functions that were added in a _later_ MCN release than the one you run. A function is allowed only when it is available in your target release or an earlier one.
37
+
38
+ ## Examples
39
+
40
+ ```js
41
+ // eslint.config.js
42
+ rules: {
43
+ 'sfmc/amp-no-mcn-unsupported': ['error', { apiVersion: 65 }]
44
+ }
45
+ ```
46
+
47
+ Or use the built-in `recommended-next` / `strict-next` / `embedded-next` configs, which apply this rule automatically (without an `apiVersion`, flagging only never-supported functions).
48
+
49
+ **Not allowed (with `apiVersion: 65`):**
50
+
51
+ ```ampscript
52
+ %%[
53
+ /* InsertDE is never available in Marketing Cloud Next */
54
+ InsertDE("MyDE", "Col", "Value")
55
+ /* Concat was added in a later MCN release than the one targeted (65) */
56
+ set @x = Concat("a", "b")
57
+ ]%%
58
+ ```
59
+
60
+ **Allowed (with `apiVersion: 67`):**
61
+
62
+ ```ampscript
63
+ %%[
64
+ /* Concat is available in this MCN release */
65
+ set @x = Concat("a", "b")
66
+ ]%%
67
+ ```
68
+
69
+ ## When to Disable
70
+
71
+ Disable this rule when you are not targeting Marketing Cloud Next (the default `engagement` configs already leave it `off`).
72
+
73
+ ```js
74
+ // eslint.config.js
75
+ rules: { 'sfmc/amp-no-mcn-unsupported': 'off' }
76
+ ```
@@ -12,7 +12,7 @@
12
12
 
13
13
  AMPscript does not support user-defined functions. Every function call must match a name in Salesforce's published catalog. Calling an unknown name causes a runtime error (or is silently ignored depending on the execution context), making the code unreliable. This rule catches typos and invented names before deployment.
14
14
 
15
- When targeting **Marketing Cloud Next**, only a subset of AMPscript functions are supported. Use the `target: 'next'` option to flag functions that cannot run in MCN.
15
+ This rule only reports **unknown** function names. Functions that exist in the catalog but are unavailable when targeting Marketing Cloud Next are handled by [`sfmc/amp-no-mcn-unsupported`](no-mcn-unsupported.md).
16
16
 
17
17
  ## Settings
18
18
 
@@ -20,16 +20,10 @@ When targeting **Marketing Cloud Next**, only a subset of AMPscript functions ar
20
20
  |---------|--------|---------|
21
21
  | severity | `"error"` \| `"warn"` \| `"off"` | `"error"` |
22
22
 
23
- ### Options
24
-
25
- | Option | Type | Default | Description |
26
- |--------|------|---------|-------------|
27
- | `target` | `'engagement'` \| `'next'` | — | Target platform. Set to `'next'` to additionally flag AMPscript functions not available in Marketing Cloud Next (API v67.0+). |
23
+ This rule takes no options.
28
24
 
29
25
  ## Examples
30
26
 
31
- ### Standard usage (Marketing Cloud Engagement)
32
-
33
27
  **Not allowed:**
34
28
 
35
29
  ```ampscript
@@ -48,37 +42,6 @@ When targeting **Marketing Cloud Next**, only a subset of AMPscript functions ar
48
42
  ]%%
49
43
  ```
50
44
 
51
- ### MCN target
52
-
53
- Configure the rule with `target: 'next'` to flag functions unsupported in Marketing Cloud Next:
54
-
55
- ```js
56
- // eslint.config.js
57
- rules: {
58
- 'sfmc/amp-no-unknown-function': ['error', { target: 'next' }]
59
- }
60
- ```
61
-
62
- Or use the built-in `recommended-next` / `strict-next` / `embedded-next` configs which apply this automatically.
63
-
64
- **Not allowed (with `target: 'next'`):**
65
-
66
- ```ampscript
67
- %%[
68
- /* InsertDE is not supported in Marketing Cloud Next */
69
- InsertDE("MyDE", "Col", "Value")
70
- ]%%
71
- ```
72
-
73
- **Allowed (with `target: 'next'`):**
74
-
75
- ```ampscript
76
- %%[
77
- /* UpsertDE is supported in Marketing Cloud Next */
78
- UpsertDE("MyDE", 1, "Key", @key, "Col", "Value")
79
- ]%%
80
- ```
81
-
82
45
  ## When to Disable
83
46
 
84
47
  Only disable this rule if you are intentionally using a proprietary or undocumented SFMC extension that is not in the public catalog.
@@ -0,0 +1,69 @@
1
+ # `sfmc/hbs-no-mcn-unsupported`
2
+
3
+ > Disallow Handlebars helpers and bindings not available in the targeted Marketing Cloud Next API version.
4
+
5
+ | | |
6
+ |---|---|
7
+ | **Type** | `problem` |
8
+ | **Default severity** | `error` in all `-next` configs; `off` otherwise |
9
+ | **Fixable** | — |
10
+
11
+ ## Why This Rule Exists
12
+
13
+ Marketing Cloud Next (MCN) adds new Handlebars helpers and `{!$...}` data bindings across its releases. This rule flags helpers and bindings that will not work in the MCN release you target:
14
+
15
+ - Helpers/bindings that **Marketing Cloud Next never supported**.
16
+ - Helpers/bindings that were **added in a later MCN release** than the one you target (see the `apiVersion` option below).
17
+
18
+ Unknown helpers and bindings — ones that are not part of Marketing Cloud Next at all — are handled separately by [`sfmc/hbs-no-unknown-helper`](no-unknown-helper.md) and [`sfmc/hbs-no-unknown-binding`](no-unknown-binding.md); this rule only checks the release availability of helpers and bindings that MCN does provide. Handlebars constructs that MCN never supports (partials, decorators, `{{log}}`, etc.) are handled by [`sfmc/hbs-no-unsupported-construct`](no-unsupported-construct.md).
19
+
20
+ ## Settings
21
+
22
+ | Setting | Values | Default |
23
+ |---------|--------|---------|
24
+ | severity | `"error"` \| `"warn"` \| `"off"` | `"error"` in `-next` configs |
25
+
26
+ ### Options
27
+
28
+ | Option | Type | Default | Description |
29
+ |--------|------|---------|-------------|
30
+ | `apiVersion` | `number` | — | The targeted Marketing Cloud Next API version (e.g. `65` = Winter '26, `67` = Summer '26). |
31
+
32
+ **What `apiVersion` does** (shared with the AMPscript and SSJS MCN rules):
33
+
34
+ - **Leave it unset** to check against _any_ MCN release: a helper or binding is flagged only if it is never supported in Marketing Cloud Next. Anything that works in some MCN release is allowed.
35
+ - **Set it to your target release** (for example `65`) to also flag helpers and bindings that were added in a _later_ MCN release than the one you run. An item is allowed only when it is available in your target release or an earlier one.
36
+
37
+ Every Handlebars helper and binding is available in some MCN release, so with no `apiVersion` set nothing is flagged. Setting `apiVersion` to an earlier release flags the helpers and bindings added after it — for example, `apiVersion: 65` flags the helpers introduced in release 67.
38
+
39
+ ## Examples
40
+
41
+ ```js
42
+ // eslint.config.js
43
+ rules: {
44
+ 'sfmc/hbs-no-mcn-unsupported': ['error', { apiVersion: 65 }]
45
+ }
46
+ ```
47
+
48
+ **Not allowed (with `apiVersion: 65`):**
49
+
50
+ ```handlebars
51
+ {{! dateAdd was added in a later MCN release than the one targeted (65) }}
52
+ {{dateAdd order.createdAt 7 "days"}}
53
+ ```
54
+
55
+ **Allowed (with `apiVersion: 65`):**
56
+
57
+ ```handlebars
58
+ {{! add is available in this MCN release }}
59
+ {{add price tax}}
60
+ ```
61
+
62
+ ## When to Disable
63
+
64
+ Disable this rule when you are not targeting Marketing Cloud Next (the default `engagement` configs already leave it `off`).
65
+
66
+ ```js
67
+ // eslint.config.js
68
+ rules: { 'sfmc/hbs-no-mcn-unsupported': 'off' }
69
+ ```
@@ -0,0 +1,68 @@
1
+ # `sfmc/ssjs-no-mcn-unsupported`
2
+
3
+ > Disallow all Server-Side JavaScript API usage, which is unavailable in Marketing Cloud Next.
4
+
5
+ | | |
6
+ |---|---|
7
+ | **Type** | `problem` |
8
+ | **Default severity** | `error` in all `-next` configs; `off` otherwise |
9
+ | **Fixable** | — |
10
+
11
+ ## Why This Rule Exists
12
+
13
+ Server-Side JavaScript is not available in Marketing Cloud Next (MCN) at all. When targeting MCN, every SSJS API usage must be rewritten in AMPscript or Handlebars. This rule flags all SSJS API surface usage:
14
+
15
+ | Construct | Example |
16
+ |---|---|
17
+ | Any `Platform.*` call (incl. `Platform.Load`) | `Platform.Function.LookupRows(…)` |
18
+ | Any `HTTP.*` call | `HTTP.Get(…)` |
19
+ | Core Library instance calls | `de.Rows.Retrieve()` (tracked from `DataExtension.Init(…)`) |
20
+ | WSProxy instance calls | `api.retrieve(…)` |
21
+ | WSProxy construction | `new Script.Util.WSProxy()` |
22
+
23
+ Unlike [`sfmc/ssjs-no-unknown-function`](no-unknown-function.md), which only flags method names not in the catalog, this rule flags **every** SFMC API call — the whole SSJS block must be migrated.
24
+
25
+ ## Settings
26
+
27
+ | Setting | Values | Default |
28
+ |---------|--------|---------|
29
+ | severity | `"error"` \| `"warn"` \| `"off"` | `"error"` in `-next` configs |
30
+
31
+ ### Options
32
+
33
+ | Option | Type | Default | Description |
34
+ |--------|------|---------|-------------|
35
+ | `apiVersion` | `number` | — | Accepted for parity with the AMPscript and Handlebars MCN rules; currently has **no effect** because no MCN API version supports SSJS. |
36
+
37
+ ## Examples
38
+
39
+ ```js
40
+ // eslint.config.js
41
+ rules: {
42
+ 'sfmc/ssjs-no-mcn-unsupported': 'error'
43
+ }
44
+ ```
45
+
46
+ Or use the built-in `recommended-next` / `strict-next` / `embedded-next` configs, which apply this rule automatically (and disable the other SSJS quality rules, since the entire block must be migrated).
47
+
48
+ **Flagged (every API call):**
49
+
50
+ ```js
51
+ Platform.Load('Core', '1.1.1');
52
+ Platform.Function.LookupRows('MyDE', 'Status', 'Active');
53
+
54
+ var de = DataExtension.Init('CustomerData');
55
+ de.Rows.Retrieve();
56
+
57
+ var api = new Script.Util.WSProxy();
58
+ api.retrieve({ ObjectType: 'DataExtension' }, ['CustomerKey'], {});
59
+ ```
60
+
61
+ ## When to Disable
62
+
63
+ Disable this rule when you are not targeting Marketing Cloud Next (the default `engagement` configs already leave it `off`).
64
+
65
+ ```js
66
+ // eslint.config.js
67
+ rules: { 'sfmc/ssjs-no-mcn-unsupported': 'off' }
68
+ ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  Flags calls to SFMC API methods that do not exist in the catalog. This single rule replaces the seven narrow `no-unknown-*` rules from earlier versions of the plugin.
4
4
 
5
- When targeting **Marketing Cloud Next**, SSJS is not supported at all. Set `target: 'next'` to flag every SSJS API call as an error, signalling that the SSJS block must be removed or rewritten in AMPscript.
5
+ This rule only reports **unknown** method names. When targeting Marketing Cloud Next, SSJS is not supported at all every SSJS API call is flagged by the dedicated [`sfmc/ssjs-no-mcn-unsupported`](no-mcn-unsupported.md) rule instead.
6
6
 
7
7
  ## Covered namespaces
8
8
 
@@ -19,14 +19,10 @@ When targeting **Marketing Cloud Next**, SSJS is not supported at all. Set `targ
19
19
 
20
20
  ## Options
21
21
 
22
- | Option | Type | Default | Description |
23
- |--------|------|---------|-------------|
24
- | `target` | `'engagement'` \| `'next'` | — | Target platform. Set to `'next'` to flag every SSJS API call (all of `Platform.*`, `HTTP.*`, Core Library, and WSProxy) as unsupported in Marketing Cloud Next. |
22
+ This rule takes no options.
25
23
 
26
24
  ## Examples
27
25
 
28
- ### Standard usage (Marketing Cloud Engagement)
29
-
30
26
  #### ❌ Incorrect
31
27
 
32
28
  ```js
@@ -54,32 +50,9 @@ var de = DataExtension.Init('CustomerData');
54
50
  de.Rows.Retrieve();
55
51
  ```
56
52
 
57
- ### MCN target (`target: 'next'`)
58
-
59
- SSJS is not supported in Marketing Cloud Next. Configuring `target: 'next'` flags every SFMC API call within SSJS files, indicating they must be rewritten or removed.
60
-
61
- ```js
62
- // eslint.config.js
63
- rules: {
64
- 'sfmc/ssjs-no-unknown-function': ['error', { target: 'next' }]
65
- }
66
- ```
67
-
68
- Or use the built-in `recommended-next` / `strict-next` / `embedded-next` configs which apply this automatically (and disable all other SSJS quality rules, since the entire SSJS block must be migrated).
69
-
70
- #### ❌ Flagged (with `target: 'next'`)
71
-
72
- ```js
73
- // All SFMC API calls are flagged — SSJS is not available in MCN
74
- Platform.Function.LookupRows('MyDE', 'Status', 'Active');
75
-
76
- var de = DataExtension.Init('CustomerData');
77
- de.Rows.Retrieve();
78
- ```
79
-
80
53
  ## When to use
81
54
 
82
- Enable this rule to catch typos, outdated method names, and unsupported API calls before they cause runtime failures. Use `target: 'next'` when migrating content to Marketing Cloud Next.
55
+ Enable this rule to catch typos and outdated method names before they cause runtime failures. When migrating content to Marketing Cloud Next, use [`sfmc/ssjs-no-mcn-unsupported`](no-mcn-unsupported.md) (applied automatically by the `recommended-next` / `strict-next` / `embedded-next` configs).
83
56
 
84
57
  ## Rule details
85
58
 
@@ -87,4 +60,4 @@ Enable this rule to catch typos, outdated method names, and unsupported API call
87
60
  - **Fixable:** No
88
61
  - **Recommended:** Yes (`engagement` mode)
89
62
  - **Strict:** Yes (`engagement` mode)
90
- - **`recommended-next` / `strict-next` / `embedded-next`:** Yes (`next` mode — all other SSJS rules disabled)
63
+ - **`recommended-next` / `strict-next` / `embedded-next`:** Off (superseded by `ssjs-no-mcn-unsupported`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-sfmc",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "ESLint plugin for Salesforce Marketing Cloud — AMPscript and Server-Side JavaScript (SSJS)",
5
5
  "type": "module",
6
6
  "main": "src/index.js",