eslint-plugin-sfmc 0.2.0 → 1.0.1

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.
@@ -1,43 +0,0 @@
1
- # `sfmc/ssjs-no-unknown-platform-response`
2
-
3
- > Disallow unknown `Platform.Response.*` method calls.
4
-
5
- | | |
6
- |---|---|
7
- | **Type** | `problem` |
8
- | **Default severity** | `error` in `recommended` and `strict` |
9
- | **Fixable** | — |
10
-
11
- ## Why This Rule Exists
12
-
13
- `Platform.Response` exposes a fixed set of methods for controlling HTTP responses from CloudPages and landing pages (e.g. `Platform.Response.Write`, `Platform.Response.Redirect`). Calling an unknown method causes a runtime error. This rule validates every `Platform.Response.*` call against the known list.
14
-
15
- ## Settings
16
-
17
- | Setting | Values | Default |
18
- |---------|--------|---------|
19
- | severity | `"error"` \| `"warn"` \| `"off"` | `"error"` |
20
-
21
- This rule has no configuration options.
22
-
23
- ### Examples
24
-
25
- **Not allowed:**
26
-
27
- ```js
28
- Platform.Response.Send("text/html", "<p>Hello</p>");
29
- ```
30
-
31
- **Allowed:**
32
-
33
- ```js
34
- Platform.Response.Write("<p>Hello</p>");
35
- Platform.Response.Redirect("https://example.com");
36
- ```
37
-
38
- ## When to Disable
39
-
40
- ```js
41
- // eslint.config.js
42
- rules: { 'sfmc/ssjs-no-unknown-platform-response': 'off' }
43
- ```
@@ -1,43 +0,0 @@
1
- # `sfmc/ssjs-no-unknown-platform-variable`
2
-
3
- > Disallow unknown `Platform.Variable.*` method calls.
4
-
5
- | | |
6
- |---|---|
7
- | **Type** | `problem` |
8
- | **Default severity** | `error` in `recommended` and `strict` |
9
- | **Fixable** | — |
10
-
11
- ## Why This Rule Exists
12
-
13
- `Platform.Variable` exposes a fixed set of methods for interacting with AMPscript variables from SSJS (e.g. `Platform.Variable.GetValue`, `Platform.Variable.SetValue`). Calling an unknown method causes a runtime error. This rule validates every `Platform.Variable.*` call against the known list.
14
-
15
- ## Settings
16
-
17
- | Setting | Values | Default |
18
- |---------|--------|---------|
19
- | severity | `"error"` \| `"warn"` \| `"off"` | `"error"` |
20
-
21
- This rule has no configuration options.
22
-
23
- ### Examples
24
-
25
- **Not allowed:**
26
-
27
- ```js
28
- var val = Platform.Variable.ReadValue("@myVar");
29
- ```
30
-
31
- **Allowed:**
32
-
33
- ```js
34
- var val = Platform.Variable.GetValue("@myVar");
35
- Platform.Variable.SetValue("@myVar", "Hello");
36
- ```
37
-
38
- ## When to Disable
39
-
40
- ```js
41
- // eslint.config.js
42
- rules: { 'sfmc/ssjs-no-unknown-platform-variable': 'off' }
43
- ```
@@ -1,46 +0,0 @@
1
- # `sfmc/ssjs-no-unknown-wsproxy-method`
2
-
3
- > Disallow unknown method calls on a `WSProxy` instance.
4
-
5
- | | |
6
- |---|---|
7
- | **Type** | `problem` |
8
- | **Default severity** | `warn` in `recommended`; `error` in `strict` |
9
- | **Fixable** | — |
10
-
11
- ## Why This Rule Exists
12
-
13
- `WSProxy` is SFMC's SSJS wrapper around the SOAP API. It exposes a specific set of methods (`retrieve`, `retrieveAll`, `create`, `update`, `delete`, `execute`, `perform`). Calling an unknown method on a `WSProxy` instance causes a runtime error. This rule infers `WSProxy` variable usage and validates method calls against the known list.
14
-
15
- ## Settings
16
-
17
- | Setting | Values | Default |
18
- |---------|--------|---------|
19
- | severity | `"error"` \| `"warn"` \| `"off"` | `"warn"` |
20
-
21
- This rule has no configuration options.
22
-
23
- ### Examples
24
-
25
- **Not allowed:**
26
-
27
- ```js
28
- Platform.Load("core", "1.1.5");
29
- var proxy = new Script.Util.WSProxy();
30
- var result = proxy.query({ ObjectType: "Subscriber" });
31
- ```
32
-
33
- **Allowed:**
34
-
35
- ```js
36
- Platform.Load("core", "1.1.5");
37
- var proxy = new Script.Util.WSProxy();
38
- var result = proxy.retrieve({ ObjectType: "Subscriber", Properties: ["SubscriberKey"] }, []);
39
- ```
40
-
41
- ## When to Disable
42
-
43
- ```js
44
- // eslint.config.js
45
- rules: { 'sfmc/ssjs-no-unknown-wsproxy-method': 'off' }
46
- ```
@@ -1,121 +0,0 @@
1
- /**
2
- * Rule: no-unknown-core-method
3
- *
4
- * Flags calls to Core library object methods that don't exist on that
5
- * object type, when the object type can be inferred from an Init call.
6
- *
7
- * Example:
8
- * var de = DataExtension.Init("MyDE");
9
- * de.Foo(); // error: 'Foo' is not a method of DataExtension
10
- */
11
-
12
- import { coreObjectLookup, coreObjectNames } from 'ssjs-data';
13
-
14
- export default {
15
- meta: {
16
- type: 'problem',
17
- docs: {
18
- description: "Disallow calls to methods that don't exist on a Core library object",
19
- },
20
- messages: {
21
- unknownMethod:
22
- "'{{method}}' is not a known method of {{objectType}}. Available methods: {{available}}.",
23
- },
24
- schema: [],
25
- },
26
-
27
- create(context) {
28
- const variableTypes = new Map();
29
-
30
- return {
31
- VariableDeclaration(node) {
32
- for (const decl of node.declarations) {
33
- if (!decl.init || !decl.id || decl.id.type !== 'Identifier') {
34
- continue;
35
- }
36
- const coreType = getCoreInitType(decl.init);
37
- if (coreType) {
38
- variableTypes.set(decl.id.name, coreType);
39
- }
40
- }
41
- },
42
-
43
- AssignmentExpression(node) {
44
- if (node.left.type !== 'Identifier') {
45
- return;
46
- }
47
- const coreType = getCoreInitType(node.right);
48
- if (coreType) {
49
- variableTypes.set(node.left.name, coreType);
50
- }
51
- },
52
-
53
- CallExpression(node) {
54
- const callee = node.callee;
55
- if (callee.type !== 'MemberExpression') {
56
- return;
57
- }
58
- if (callee.object.type !== 'Identifier') {
59
- return;
60
- }
61
- if (callee.property.type !== 'Identifier') {
62
- return;
63
- }
64
-
65
- const objectName = callee.object.name;
66
- const method = callee.property.name;
67
-
68
- const coreType = variableTypes.get(objectName);
69
- if (!coreType) {
70
- return;
71
- }
72
-
73
- const objectDef = coreObjectLookup.get(coreType);
74
- if (!objectDef) {
75
- return;
76
- }
77
-
78
- const knownMethods = new Set(objectDef.methods.map((m) => m.toLowerCase()));
79
- if (!knownMethods.has(method.toLowerCase())) {
80
- context.report({
81
- node: callee.property,
82
- messageId: 'unknownMethod',
83
- data: {
84
- method,
85
- objectType: coreType,
86
- available: objectDef.methods.join(', '),
87
- },
88
- });
89
- }
90
- },
91
- };
92
- },
93
- };
94
-
95
- function getCoreInitType(node) {
96
- if (!node || node.type !== 'CallExpression') {
97
- return null;
98
- }
99
- const callee = node.callee;
100
- if (callee.type !== 'MemberExpression') {
101
- return null;
102
- }
103
-
104
- if (callee.property.type === 'Identifier' && callee.property.name === 'Init') {
105
- if (callee.object.type === 'Identifier' && coreObjectNames.has(callee.object.name)) {
106
- return callee.object.name;
107
- }
108
- if (
109
- callee.object.type === 'MemberExpression' &&
110
- callee.object.object.type === 'Identifier' &&
111
- callee.object.property.type === 'Identifier'
112
- ) {
113
- const fullName = `${callee.object.object.name}.${callee.object.property.name}`;
114
- if (coreObjectNames.has(fullName)) {
115
- return fullName;
116
- }
117
- }
118
- }
119
-
120
- return null;
121
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * Rule: no-unknown-http-method
3
- *
4
- * Flags calls to HTTP.* where the method name does not exist
5
- * in the known SFMC HTTP method catalog.
6
- */
7
-
8
- import { httpMethodNames } from 'ssjs-data';
9
-
10
- export default {
11
- meta: {
12
- type: 'problem',
13
- docs: {
14
- description: 'Disallow calls to unknown HTTP object methods',
15
- },
16
- messages: {
17
- unknownMethod: "'HTTP.{{name}}' is not a recognized SFMC HTTP method.",
18
- },
19
- schema: [],
20
- },
21
-
22
- create(context) {
23
- return {
24
- CallExpression(node) {
25
- const callee = node.callee;
26
- if (callee.type !== 'MemberExpression') {
27
- return;
28
- }
29
- if (callee.object.type !== 'Identifier' || callee.object.name !== 'HTTP') {
30
- return;
31
- }
32
- if (callee.property.type !== 'Identifier') {
33
- return;
34
- }
35
-
36
- const methodName = callee.property.name;
37
- if (!httpMethodNames.has(methodName.toLowerCase())) {
38
- context.report({
39
- node: callee.property,
40
- messageId: 'unknownMethod',
41
- data: { name: methodName },
42
- });
43
- }
44
- },
45
- };
46
- },
47
- };
@@ -1,53 +0,0 @@
1
- /**
2
- * Rule: no-unknown-platform-client-browser
3
- *
4
- * Flags calls to Platform.ClientBrowser.* — this namespace is deprecated.
5
- * The methods previously under Platform.ClientBrowser.* are now available
6
- * under Platform.Response.* (e.g. Platform.Response.Redirect,
7
- * Platform.Response.SetCookie, Platform.Response.RemoveCookie).
8
- * All Platform.ClientBrowser.* calls are flagged as unknown.
9
- */
10
-
11
- const knownMethods = new Set();
12
-
13
- export default {
14
- meta: {
15
- type: 'problem',
16
- docs: {
17
- description: 'Disallow calls to unknown Platform.ClientBrowser methods',
18
- },
19
- messages: {
20
- unknownMethod: "'Platform.ClientBrowser.{{name}}' is not a recognized method.",
21
- },
22
- schema: [],
23
- },
24
-
25
- create(context) {
26
- return {
27
- CallExpression(node) {
28
- const callee = node.callee;
29
- if (callee.type !== 'MemberExpression') {
30
- return;
31
- }
32
-
33
- if (
34
- callee.object.type === 'MemberExpression' &&
35
- callee.object.object.type === 'Identifier' &&
36
- callee.object.object.name === 'Platform' &&
37
- callee.object.property.type === 'Identifier' &&
38
- callee.object.property.name === 'ClientBrowser' &&
39
- callee.property.type === 'Identifier'
40
- ) {
41
- const methodName = callee.property.name;
42
- if (!knownMethods.has(methodName.toLowerCase())) {
43
- context.report({
44
- node: callee.property,
45
- messageId: 'unknownMethod',
46
- data: { name: methodName },
47
- });
48
- }
49
- }
50
- },
51
- };
52
- },
53
- };
@@ -1,51 +0,0 @@
1
- /**
2
- * Rule: no-unknown-platform-function
3
- *
4
- * Flags calls to Platform.Function.* where the method name does not
5
- * exist in the known SFMC Platform.Function catalog.
6
- */
7
-
8
- import { platformFunctionNames } from 'ssjs-data';
9
-
10
- export default {
11
- meta: {
12
- type: 'problem',
13
- docs: {
14
- description: 'Disallow calls to unknown Platform.Function methods',
15
- },
16
- messages: {
17
- unknownFunction:
18
- "'Platform.Function.{{name}}' is not a recognized SFMC Platform function.",
19
- },
20
- schema: [],
21
- },
22
-
23
- create(context) {
24
- return {
25
- CallExpression(node) {
26
- const callee = node.callee;
27
- if (callee.type !== 'MemberExpression') {
28
- return;
29
- }
30
-
31
- if (
32
- callee.object.type === 'MemberExpression' &&
33
- callee.object.object.type === 'Identifier' &&
34
- callee.object.object.name === 'Platform' &&
35
- callee.object.property.type === 'Identifier' &&
36
- callee.object.property.name === 'Function' &&
37
- callee.property.type === 'Identifier'
38
- ) {
39
- const methodName = callee.property.name;
40
- if (!platformFunctionNames.has(methodName.toLowerCase())) {
41
- context.report({
42
- node: callee.property,
43
- messageId: 'unknownFunction',
44
- data: { name: methodName },
45
- });
46
- }
47
- }
48
- },
49
- };
50
- },
51
- };
@@ -1,52 +0,0 @@
1
- /**
2
- * Rule: no-unknown-platform-request
3
- *
4
- * Flags calls to Platform.Request.* where the method name does not
5
- * exist in the known SFMC Platform.Request catalog.
6
- */
7
-
8
- import { PLATFORM_REQUEST_METHODS } from 'ssjs-data';
9
-
10
- const knownMethods = new Set(PLATFORM_REQUEST_METHODS.map((m) => m.name.toLowerCase()));
11
-
12
- export default {
13
- meta: {
14
- type: 'problem',
15
- docs: {
16
- description: 'Disallow calls to unknown Platform.Request methods',
17
- },
18
- messages: {
19
- unknownMethod: "'Platform.Request.{{name}}' is not a recognized method.",
20
- },
21
- schema: [],
22
- },
23
-
24
- create(context) {
25
- return {
26
- CallExpression(node) {
27
- const callee = node.callee;
28
- if (callee.type !== 'MemberExpression') {
29
- return;
30
- }
31
-
32
- if (
33
- callee.object.type === 'MemberExpression' &&
34
- callee.object.object.type === 'Identifier' &&
35
- callee.object.object.name === 'Platform' &&
36
- callee.object.property.type === 'Identifier' &&
37
- callee.object.property.name === 'Request' &&
38
- callee.property.type === 'Identifier'
39
- ) {
40
- const methodName = callee.property.name;
41
- if (!knownMethods.has(methodName.toLowerCase())) {
42
- context.report({
43
- node: callee.property,
44
- messageId: 'unknownMethod',
45
- data: { name: methodName },
46
- });
47
- }
48
- }
49
- },
50
- };
51
- },
52
- };
@@ -1,52 +0,0 @@
1
- /**
2
- * Rule: no-unknown-platform-response
3
- *
4
- * Flags calls to Platform.Response.* where the method name does not
5
- * exist in the known SFMC Platform.Response catalog.
6
- */
7
-
8
- import { PLATFORM_RESPONSE_METHODS } from 'ssjs-data';
9
-
10
- const knownMethods = new Set(PLATFORM_RESPONSE_METHODS.map((m) => m.name.toLowerCase()));
11
-
12
- export default {
13
- meta: {
14
- type: 'problem',
15
- docs: {
16
- description: 'Disallow calls to unknown Platform.Response methods',
17
- },
18
- messages: {
19
- unknownMethod: "'Platform.Response.{{name}}' is not a recognized method.",
20
- },
21
- schema: [],
22
- },
23
-
24
- create(context) {
25
- return {
26
- CallExpression(node) {
27
- const callee = node.callee;
28
- if (callee.type !== 'MemberExpression') {
29
- return;
30
- }
31
-
32
- if (
33
- callee.object.type === 'MemberExpression' &&
34
- callee.object.object.type === 'Identifier' &&
35
- callee.object.object.name === 'Platform' &&
36
- callee.object.property.type === 'Identifier' &&
37
- callee.object.property.name === 'Response' &&
38
- callee.property.type === 'Identifier'
39
- ) {
40
- const methodName = callee.property.name;
41
- if (!knownMethods.has(methodName.toLowerCase())) {
42
- context.report({
43
- node: callee.property,
44
- messageId: 'unknownMethod',
45
- data: { name: methodName },
46
- });
47
- }
48
- }
49
- },
50
- };
51
- },
52
- };
@@ -1,52 +0,0 @@
1
- /**
2
- * Rule: no-unknown-platform-variable
3
- *
4
- * Flags calls to Platform.Variable.* where the method name does not
5
- * exist in the known SFMC Platform.Variable catalog.
6
- */
7
-
8
- import { PLATFORM_VARIABLE_METHODS } from 'ssjs-data';
9
-
10
- const knownMethods = new Set(PLATFORM_VARIABLE_METHODS.map((m) => m.name.toLowerCase()));
11
-
12
- export default {
13
- meta: {
14
- type: 'problem',
15
- docs: {
16
- description: 'Disallow calls to unknown Platform.Variable methods',
17
- },
18
- messages: {
19
- unknownMethod: "'Platform.Variable.{{name}}' is not a recognized method.",
20
- },
21
- schema: [],
22
- },
23
-
24
- create(context) {
25
- return {
26
- CallExpression(node) {
27
- const callee = node.callee;
28
- if (callee.type !== 'MemberExpression') {
29
- return;
30
- }
31
-
32
- if (
33
- callee.object.type === 'MemberExpression' &&
34
- callee.object.object.type === 'Identifier' &&
35
- callee.object.object.name === 'Platform' &&
36
- callee.object.property.type === 'Identifier' &&
37
- callee.object.property.name === 'Variable' &&
38
- callee.property.type === 'Identifier'
39
- ) {
40
- const methodName = callee.property.name;
41
- if (!knownMethods.has(methodName.toLowerCase())) {
42
- context.report({
43
- node: callee.property,
44
- messageId: 'unknownMethod',
45
- data: { name: methodName },
46
- });
47
- }
48
- }
49
- },
50
- };
51
- },
52
- };
@@ -1,88 +0,0 @@
1
- /**
2
- * Rule: no-unknown-wsproxy-method
3
- *
4
- * Flags calls to WSProxy instances where the method name does not
5
- * exist in the known SFMC WSProxy method catalog.
6
- */
7
-
8
- import { wsproxyMethodNames } from 'ssjs-data';
9
-
10
- export default {
11
- meta: {
12
- type: 'problem',
13
- docs: {
14
- description: 'Disallow calls to unknown WSProxy methods',
15
- },
16
- messages: {
17
- unknownMethod: "'{{name}}' is not a recognized WSProxy method.",
18
- },
19
- schema: [],
20
- },
21
-
22
- create(context) {
23
- const wsproxyVariables = new Set();
24
-
25
- return {
26
- VariableDeclaration(node) {
27
- for (const decl of node.declarations) {
28
- if (
29
- decl.id &&
30
- decl.id.type === 'Identifier' &&
31
- decl.init &&
32
- isWSProxyConstructor(decl.init)
33
- ) {
34
- wsproxyVariables.add(decl.id.name);
35
- }
36
- }
37
- },
38
-
39
- AssignmentExpression(node) {
40
- if (node.left.type === 'Identifier' && isWSProxyConstructor(node.right)) {
41
- wsproxyVariables.add(node.left.name);
42
- }
43
- },
44
-
45
- CallExpression(node) {
46
- const callee = node.callee;
47
- if (callee.type !== 'MemberExpression') {
48
- return;
49
- }
50
- if (callee.object.type !== 'Identifier') {
51
- return;
52
- }
53
- if (callee.property.type !== 'Identifier') {
54
- return;
55
- }
56
-
57
- if (!wsproxyVariables.has(callee.object.name)) {
58
- return;
59
- }
60
-
61
- const methodName = callee.property.name;
62
- if (!wsproxyMethodNames.has(methodName.toLowerCase())) {
63
- context.report({
64
- node: callee.property,
65
- messageId: 'unknownMethod',
66
- data: { name: methodName },
67
- });
68
- }
69
- },
70
- };
71
- },
72
- };
73
- function isWSProxyConstructor(node) {
74
- if (!node || node.type !== 'NewExpression') {
75
- return false;
76
- }
77
- const c = node.callee;
78
- return (
79
- c.type === 'MemberExpression' &&
80
- c.property.type === 'Identifier' &&
81
- c.property.name === 'WSProxy' &&
82
- c.object.type === 'MemberExpression' &&
83
- c.object.property.type === 'Identifier' &&
84
- c.object.property.name === 'Util' &&
85
- c.object.object.type === 'Identifier' &&
86
- c.object.object.name === 'Script'
87
- );
88
- }