Skip to content

Commit e2005ac

Browse files
Merge pull request #80 from SalesforceFoundation/feature/dependabot-alerts-site
W-10048303: [OFM-Site] Resolve all known dependabot alerts
2 parents 62ed292 + 0701d85 commit e2005ac

8 files changed

Lines changed: 3135 additions & 2970 deletions

File tree

.eslintrc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ globals:
1212
parserOptions:
1313
ecmaVersion: 2018
1414
sourceType: module
15-
parser: babel-eslint
15+
parser: "@babel/eslint-parser"
1616
plugins:
1717
- prettier
1818
- "@lwc/eslint-plugin-lwc"

cumulusci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ project:
99
package:
1010
name: Outbound Funds Community
1111
namespace: outfunds_comm
12-
api_version: "50.0"
12+
api_version: "52.0"
1313
dependencies:
1414
- namespace: sfdobase
1515
version: 1.0

dev/tasks/communities.py

Lines changed: 111 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,67 @@
1-
# * Copyright (c) 2021, salesforce.com, inc.
2-
# * All rights reserved.
3-
# * SPDX-License-Identifier: BSD-3-Clause
4-
# * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
5-
# *
6-
7-
""""
8-
Steps:
9-
10-
1) Retrieve Network, extract picassoSite (is the API Name of ExpBundle)
11-
2) Retrieve ExperienceBundle
12-
3) Update themes: loop over all *.json files in themes directory
13-
- navigationMenuEditorRefresh
14-
15-
"""
161
import os
2+
from pathlib import Path
173
import re
18-
from tempfile import mkstemp
19-
from shutil import move
204
import xml.etree.ElementTree as ET
215
from cumulusci.core.exceptions import CumulusCIException
22-
from os import path, fdopen, remove
236
from dev.tasks.debugger import log_title
247
from dev.tasks.sfdx import SfdxEtlWithNamespaceInjectionTask
258

269

27-
class ReplaceThemeLayoutNavigationMenuTask(SfdxEtlWithNamespaceInjectionTask):
28-
10+
class ExperienceBundleTask(SfdxEtlWithNamespaceInjectionTask):
2911
task_options = {
3012
"network_name": {"description": ("Name of Network"), "required": True},
31-
"navigation_menu": {
32-
"description": "NavigationMenu API name that will replace the default Navigation Menus in the community theme layout.",
33-
"required": True,
34-
},
3513
**SfdxEtlWithNamespaceInjectionTask.task_options,
3614
}
3715

16+
def _sfdx_extract(self):
17+
# Create default package directory in temporary directory
18+
self._temporary_package_directory = os.path.join(
19+
self._temporary_directory, self._default_package_directory
20+
)
21+
22+
self._network_name = self.options.get("network_name")
23+
24+
# Retrieve the Network metadata.
25+
self._retrieve_network()
26+
27+
# Extract the ExperienceBundle API Name from the Network metadata.
28+
self._set_experience_bundle_name()
29+
30+
# Retrieve the ExperienceBundle metadata.
31+
self._retrieve_experience_bundle()
32+
33+
def _sfdx_transform(self):
34+
pass
35+
36+
def _sfdx_load(self):
37+
self._deploy_experience_bundle()
38+
self._publish_network()
39+
3840
def _retrieve_network(self):
41+
self._log_title("Retrieving Network metadata")
3942
result = self._sfdx(
40-
[
41-
"force:source:retrieve",
42-
'--metadata="Network:{}"'.format(self.options.get("network_name")),
43-
],
43+
["force:source:retrieve", f'--metadata="Network:{self._network_name}"'],
4444
addTargetUsername=True,
4545
)
4646

47-
self.retrieved_file_paths = set()
48-
for inbound_file in result["inboundFiles"]:
49-
self.retrieved_file_paths.add(inbound_file["filePath"])
50-
51-
# raise CumulusCIException is no results found.
52-
if not result["inboundFiles"]:
53-
raise CumulusCIException(
54-
'Metadata not found: "Network:{}"'.format(
55-
self.options.get("network_name")
56-
)
57-
)
47+
# Check if there were any errors retrieveing metadata
48+
self._assert_sfdx_retrieved_successfully(result)
5849

5950
def _set_experience_bundle_name(self):
6051
"""
6152
1) Open Network file
6253
2) Extract picassoSite with regex.
6354
3) set self._experience_bundle_name = picassoSite
6455
"""
65-
basepath = path.dirname(self._temporary_package_directory)
66-
filepath = path.abspath(path.join(basepath, self.retrieved_file_paths.pop()))
56+
network_path = os.path.join(
57+
self._temporary_package_directory,
58+
"main",
59+
"default",
60+
"networks",
61+
f"{self._network_name}.network-meta.xml",
62+
)
6763

68-
tree = ET.parse(filepath)
64+
tree = ET.parse(network_path)
6965
root = tree.getroot()
7066

7167
for elem in root.findall(
@@ -75,103 +71,112 @@ def _set_experience_bundle_name(self):
7571

7672
self._experience_bundle_name = picasso_site
7773

74+
self._log_title("Extracting ExperienceBundle API Name from Network metadata")
75+
self.logger.info(f"ExperienceBundle: {self._experience_bundle_name}")
76+
7877
def _retrieve_experience_bundle(self):
78+
self._log_title("Retrieving ExperienceBundle metadata")
7979
result = self._sfdx(
8080
[
8181
"force:source:retrieve",
82-
'--metadata="ExperienceBundle:{}"'.format(self._experience_bundle_name),
82+
f'--metadata="ExperienceBundle:{self._experience_bundle_name}"',
8383
],
8484
addTargetUsername=True,
8585
)
8686

87-
self.theme_file_paths = set()
88-
89-
for item in result["inboundFiles"]:
90-
full_name = item["fullName"]
91-
match = self._experience_bundle_name + "/themes" in full_name
92-
if match:
93-
self.theme_file_paths.add(item["filePath"])
94-
95-
# raise CumulusCIException is no results found.
96-
if not result["inboundFiles"]:
97-
raise CumulusCIException(
98-
'Metadata not found: "ExperienceBundle:{}"'.format(
99-
self.options.get(self._experience_bundle_name)
100-
)
101-
)
87+
# Check if there were any errors retrieveing metadata
88+
self._assert_sfdx_retrieved_successfully(result)
10289

10390
def _deploy_experience_bundle(self):
91+
self._log_title("Deploying ExperienceBundle metadata")
92+
10493
result = self._sfdx(
10594
[
10695
"force:source:deploy",
107-
'--metadata="ExperienceBundle:{}"'.format(self._experience_bundle_name),
96+
f'--metadata="ExperienceBundle:{self._experience_bundle_name}"',
10897
],
10998
addTargetUsername=True,
11099
)
111100

112101
# raise CumulusCIException is no results found.
113102
if not result["deployedSource"]:
114103
raise CumulusCIException(
115-
'Metadata not found: "ExperienceBundle:{}"'.format(
116-
self.options.get(self._experience_bundle_name)
117-
)
104+
f'Metadata not found: "ExperienceBundle:{self._experience_bundle_name}"'
118105
)
119106

120-
def _replace_theme_navigation_menus(self):
121-
"""
122-
Replaces default navigation with navigation menu specified in the option navigation_menu
123-
"""
124-
basepath = path.dirname(self._temporary_package_directory)
125-
filepath = path.abspath(path.join(basepath, self.theme_file_paths.pop()))
126-
127-
fh, abs_path = mkstemp()
128-
log_title(
129-
"Adding navigation menu: {} to community pages".format(
130-
self.options["navigation_menu"]
131-
),
132-
self.logger.info,
107+
def _publish_network(self):
108+
self._log_title("Publishing Network")
109+
self._sfdx(
110+
["force:community:publish", f'--name="{self._network_name}"'],
111+
addTargetUsername=True,
133112
)
134-
page_count = 0
135-
with fdopen(fh, "w") as new_file:
136-
with open(filepath) as old_file:
137-
substitution = '"navigationMenuEditorRefresh" : "{}"'.format(
138-
self.options["navigation_menu"]
139-
)
140-
for line in old_file:
141-
updated_line = re.sub(
142-
r'("navigationMenuEditorRefresh" ?: ?.*$)',
143-
substitution,
144-
line,
145-
)
146-
new_file.write(updated_line)
147-
if updated_line != line:
148-
page_count += 1
149113

150-
self.logger.info("Number of Community Pages updated: {}".format(page_count))
114+
def _assert_sfdx_retrieved_successfully(self, sfdx_result):
115+
errors = []
116+
for inbound_file in sfdx_result["inboundFiles"]:
117+
if inbound_file.get("error"):
118+
errors.append(inbound_file.get("error"))
151119

152-
# Remove original file
153-
remove(filepath)
154-
# Move new file
155-
move(abs_path, filepath)
120+
if errors:
121+
raise CumulusCIException("; ".join(errors))
122+
123+
def _log_title(self, title):
124+
self.logger.info("")
125+
log_title(title, self.logger.info)
156126

157127
def _debug_temporary_directory(self):
158128
self.logger.warn("debugging temporary package directory")
159129
self.logger.warn("")
160130
self.logger.warn(f"temporary directory: {self._temporary_directory}")
161131
self.list_files(self._default_package_directory)
162132

163-
def _sfdx_extract(self):
164-
# Create default package directory in temporary directory
165-
self._temporary_package_directory = os.path.join(
166-
self._temporary_directory, self._default_package_directory
167-
)
168-
self._retrieve_network()
169-
self._set_experience_bundle_name()
170133

171-
self._retrieve_experience_bundle()
134+
class ReplaceThemeLayoutNavigationMenuTask(ExperienceBundleTask):
135+
136+
task_options = {
137+
"navigation_menu": {
138+
"description": "NavigationMenu API name to set for all theme layouts.",
139+
"required": True,
140+
},
141+
**ExperienceBundleTask.task_options,
142+
}
172143

173144
def _sfdx_transform(self):
174-
self._replace_theme_navigation_menus()
145+
self._set_navigation_menu()
146+
147+
def _set_navigation_menu(self):
148+
self._log_title("Set navigation menu")
149+
self.logger.info(
150+
'Setting the navigation menu as "{}" for all "{}" ExperienceBundle themes:'.format(
151+
self.options["navigation_menu"],
152+
self._experience_bundle_name,
153+
)
154+
)
175155

176-
def _sfdx_load(self):
177-
self._deploy_experience_bundle()
156+
themes_path = os.path.join(
157+
self._temporary_package_directory,
158+
"main",
159+
"default",
160+
"experiences",
161+
self._experience_bundle_name,
162+
"themes",
163+
)
164+
165+
for theme_file_dir_entry in os.scandir(themes_path):
166+
if theme_file_dir_entry.is_file():
167+
self.logger.info(f" {theme_file_dir_entry.name}")
168+
169+
theme_file = Path(theme_file_dir_entry.path)
170+
171+
# Replace all "navigationMenuEditorRefresh" values with the navigation_menu option.
172+
# This should be safe since it seems only the forceCommunity:themeNav component has a navigationMenuEditorRefresh attribute.
173+
theme_file.write_text(
174+
re.sub(
175+
r'("navigationMenuEditorRefresh" ?: ?"\w*")',
176+
'"navigationMenuEditorRefresh" : "{}"'.format(
177+
self.options.get("navigation_menu")
178+
),
179+
theme_file.read_text(),
180+
flags=re.M,
181+
)
182+
)

force-app/main/default/lwc/flowNavigateToRecord/__tests__/flowNavigationToRecord.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe("c-flow-navigate-to-records", () => {
2222
component.recordId = "recordId";
2323
document.body.appendChild(component);
2424

25-
return global.flushPromises().then(async () => {
25+
return Promise.resolve().then(async () => {
2626
const { pageReference } = getNavigateCalledWith();
2727
expect(pageReference.type).toBe("standard__recordPage");
2828
expect(pageReference.attributes.recordId).toBe(component.recordId);

force-app/main/default/lwc/util/__tests__/util.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ describe("formatLabel", () => {
6363
);
6464
});
6565

66-
it("should inject values for keys referenced in the label if keys and label references case-insensitively match ", () => {
66+
it("should inject values for keys referenced in the label if keys and label references case-insensitively match", () => {
6767
let label = "Hello, {firstname} {lastname}! Welcome to the {communityName}!";
6868
let replacements = {
6969
firstName: "Aileen",

package.json

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,31 @@
33
"license": "UNLICENSED",
44
"author": "Salesforce.org Impact Engineering",
55
"devDependencies": {
6-
"@lwc/eslint-plugin-lwc": "^0.11.0",
7-
"@lwc/jest-preset": "^7.0.0",
8-
"@sa11y/jest": "^0.2.1",
9-
"@salesforce/eslint-config-lwc": "^0.9.0",
10-
"@salesforce/sfdx-lwc-jest": "^0.11.0",
11-
"babel-eslint": "^10.1.0",
12-
"cspell": "^5.2.4",
13-
"eslint": "^7.18.0",
14-
"eslint-config-prettier": "^7.2.0",
15-
"eslint-plugin-prettier": "^3.3.1",
6+
"@babel/core": "^7.16.0",
7+
"@babel/eslint-parser": "^7",
8+
"@lwc/eslint-plugin-lwc": "^1.0.0",
9+
"@sa11y/jest": "^3.1.0",
10+
"@salesforce/eslint-config-lwc": "^3.2.0",
11+
"@salesforce/eslint-plugin-lightning": "^1.0.0",
12+
"@salesforce/sfdx-lwc-jest": "^0.12.6",
13+
"cspell": "^5.13.0",
14+
"eslint": "^8.3.0",
15+
"eslint-config-prettier": "^8.3.0",
16+
"eslint-plugin-import": "^2.25.3",
17+
"eslint-plugin-jest": "^25.3.0",
18+
"eslint-plugin-prettier": "^4.0.0",
1619
"hasha-cli": "^4.1.0",
17-
"husky": "^4.3.8",
18-
"jest": "^26.6.3",
19-
"lint-staged": "^10.5.3",
20-
"lockfile-lint": "^4.3.7",
21-
"prettier": "^2.2.1",
22-
"prettier-plugin-apex": "^1.8.0"
20+
"husky": "^4",
21+
"jest": "^27.3.1",
22+
"lint-staged": "^12.1.2",
23+
"lockfile-lint": "^4.6.2",
24+
"prettier": "^2.4.1",
25+
"prettier-plugin-apex": "^1.10.0",
26+
"typescript": "^4.5.2"
2327
},
2428
"resolutions": {
25-
"js-yaml": "^3.13.1",
26-
"axios": "^0.21.1",
27-
"node-notifier": "^8.0.1"
29+
"nth-check": "^2.0.1",
30+
"trim-newlines": "^3.0.1"
2831
},
2932
"scripts": {
3033
"test:unit": "lwc-jest",

sfdx-project.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"packageDirectories": [{ "path": "force-app", "default": true }],
33
"namespace": "outfunds_comm",
4-
"sourceApiVersion": "50.0"
4+
"sourceApiVersion": "52.0"
55
}

0 commit comments

Comments
 (0)