prettier-plugin-sfmc 0.4.0 → 0.4.3

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
@@ -52,13 +52,15 @@ All options use the `ampscript` prefix — they control AMPscript formatting beh
52
52
 
53
53
  ## Supported File Types
54
54
 
55
- | Extension | Parser | What happens |
56
- | ------------ | ------------------ | ----------------------------------------------- |
57
- | `.ampscript` | `ampscript-parse` | Full AMPscript formatting |
58
- | `.amp` | `ampscript-parse` | Full AMPscript formatting |
59
- | `.html` | `ampscript-parse` | AMPscript formatted; HTML delegated to Prettier |
60
- | `.ssjs` | `babel` (built-in) | Standard JavaScript formatting |
61
- | `.sql` | `sql` | SQL via composed `prettier-plugin-sql` |
55
+ | Extension | VS Code language ID | Parser | What happens |
56
+ | ------------ | ------------------- | ------------------ | ------------------------------------------------------------------------------- |
57
+ | `.ampscript` | `ampscript` | `ampscript-parse` | Full AMPscript formatting |
58
+ | `.amp` | `ampscript` | `ampscript-parse` | Full AMPscript formatting |
59
+ | `.html` | `sfmc` | `ampscript-parse` | AMPscript formatted; HTML and `<script runat="server">` delegated to Prettier's built-in HTML formatter |
60
+ | `.ssjs` | `ssjs` | `babel` (built-in) | Standard JavaScript formatting |
61
+ | `.sql` | — | `sql` | SQL via composed `prettier-plugin-sql` |
62
+
63
+ `.html` files are auto-detected as `sfmc` by the `vscode-sfmc-language` extension (v1.6.0+) when they contain AMPscript or SSJS content. Plain HTML files (language ID `html`) are out of scope and handled by Prettier's built-in HTML formatter directly.
62
64
 
63
65
  ## Core Prettier defaults (AMPscript, HTML, SQL, JavaScript / SSJS)
64
66
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "prettier-plugin-sfmc",
3
- "version": "0.4.0",
4
- "description": "Prettier plugin for Salesforce Marketing Cloud AMPscript, SSJS, and SQL formatting",
3
+ "version": "0.4.3",
4
+ "description": "Prettier plugin for Salesforce Marketing Cloud — AMPscript, SSJS, and SQL formatting",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
7
7
  "exports": {
@@ -47,13 +47,13 @@
47
47
  "license": "MIT",
48
48
  "dependencies": {
49
49
  "ampscript-data": "^0.1.3",
50
- "ampscript-parser": "^0.1.1",
50
+ "ampscript-parser": "^0.1.2",
51
51
  "prettier-plugin-sql": "^0.20.0",
52
52
  "ssjs-data": "^0.2.2"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@eslint/js": "^10.0.1",
56
- "@jest/globals": "^29.0.0",
56
+ "@jest/globals": "^30.3.0",
57
57
  "eslint": "^10.1.0",
58
58
  "eslint-config-prettier": "^10.1.8",
59
59
  "eslint-plugin-jsdoc": "^62.0.0",
@@ -61,7 +61,8 @@
61
61
  "eslint-plugin-unicorn": "^64.0.0",
62
62
  "globals": "^17.4.0",
63
63
  "husky": "^9.1.7",
64
- "jest": "^29.0.0",
64
+ "jest": "^30.3.0",
65
+ "lint-staged": "^17.0.5",
65
66
  "prettier": "^3.8.1"
66
67
  },
67
68
  "peerDependencies": {
@@ -69,5 +70,10 @@
69
70
  },
70
71
  "engines": {
71
72
  "node": ">=18.0.0"
73
+ },
74
+ "lint-staged": {
75
+ "*.{js,mjs,cjs}": [
76
+ "eslint --fix"
77
+ ]
72
78
  }
73
79
  }
package/src/index.js CHANGED
@@ -49,9 +49,15 @@ export const languages = [
49
49
  {
50
50
  name: 'AMPscript',
51
51
  parsers: ['ampscript-parse'],
52
- extensions: ['.ampscript', '.amp', '.html'],
52
+ extensions: ['.ampscript', '.amp'],
53
53
  vscodeLanguageIds: ['ampscript'],
54
54
  },
55
+ {
56
+ name: 'SFMC (AMPscript / SSJS)',
57
+ parsers: ['ampscript-parse'],
58
+ extensions: ['.html'],
59
+ vscodeLanguageIds: ['sfmc'],
60
+ },
55
61
  {
56
62
  name: 'SSJS',
57
63
  parsers: ['babel'],
package/src/printer.js CHANGED
@@ -370,7 +370,11 @@ function printAmpscriptNode(path, options, print) {
370
370
  for (const altDocument of altDocs) {
371
371
  parts.push(altDocument);
372
372
  }
373
- parts.push([hardline, kw('endif', okw.endif)]);
373
+ // Only emit endif when the parser saw it in this block (cross-block
374
+ // IF/ENDIF spans multiple %%[ ]%% segments; missing endif is intentional).
375
+ if ('endif' in okw) {
376
+ parts.push([hardline, kw('endif', okw.endif)]);
377
+ }
374
378
  return parts;
375
379
  }
376
380
 
@@ -426,7 +430,11 @@ function printAmpscriptNode(path, options, print) {
426
430
  if (node.body.length > 0) {
427
431
  parts.push(indent([hardline, join(hardline, path.map(print, 'body'))]));
428
432
  }
429
- parts.push([hardline, kw('next', okw.next), ' ', counterDocument]);
433
+ // Only emit next when the parser saw it in this block (cross-block
434
+ // FOR/NEXT spans multiple %%[ ]%% segments; missing next is intentional).
435
+ if ('next' in okw) {
436
+ parts.push([hardline, kw('next', okw.next), ' ', counterDocument]);
437
+ }
430
438
  return parts;
431
439
  }
432
440
 
@@ -492,7 +500,15 @@ function printAmpscriptNode(path, options, print) {
492
500
  }
493
501
 
494
502
  case 'RawStatement': {
495
- return kw(node.value.toLowerCase(), node.keyword);
503
+ const doc = kw(node.value.toLowerCase(), node.keyword);
504
+ const extra = node.crossBlockIndentDepth || 0;
505
+ if (extra === 0) {
506
+ return doc;
507
+ }
508
+ // Nested `indent()` does not stack visible spaces on single-line string
509
+ // leaves; prefix each line so cross-block ENDIF aligns with its opening IF.
510
+ const oneLevel = options.useTabs ? '\t' : ' '.repeat(options.tabWidth || 4);
511
+ return [oneLevel.repeat(extra), doc];
496
512
  }
497
513
 
498
514
  case 'Raw': {