@madgex/fert 5.0.4 → 5.0.5

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.
Files changed (126) hide show
  1. package/README.md +4 -5
  2. package/bin/cli.js +9 -30
  3. package/bin/commands/_service-command-bootstrap.js +6 -13
  4. package/bin/commands/build-tasks/build-tokens.js +8 -22
  5. package/bin/commands/build-tasks/bundle-entry.js +1 -4
  6. package/bin/commands/build.js +1 -0
  7. package/bin/commands/configs.js +17 -53
  8. package/bin/commands/dev-server.js +5 -14
  9. package/bin/commands/init.js +27 -117
  10. package/bin/commands/publish-tasks/asset-store-uploader.js +2 -5
  11. package/bin/commands/publish.js +10 -30
  12. package/bin/utils/configs.js +55 -95
  13. package/bin/utils/cpid-lookup.js +2 -2
  14. package/bin/utils/cpid-matches-git-remote.js +5 -10
  15. package/bin/utils/getSchemaMeta.js +1 -1
  16. package/bin/utils/index.js +14 -25
  17. package/bin/utils/lookup-cf-distribution-ids.js +2 -7
  18. package/bin/utils/resolve-external-assets.js +6 -15
  19. package/constants.js +3 -17
  20. package/package.json +17 -26
  21. package/repo-template/fert.config.js +3 -0
  22. package/repo-template/package.json +22 -0
  23. package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/brand.json +6 -3
  24. package/repo-template/services/jobseekers-frontend/fert.service.config.js +7 -0
  25. package/repo-template/services/jobseekers-frontend/public/icons/user.svg +4 -0
  26. package/repo-template/services/jobseekers-frontend/public/images/favicon.ico +0 -0
  27. package/repo-template/services/jobseekers-frontend/public/images/fred.jpeg +0 -0
  28. package/repo-template/services/jobseekers-frontend/src/css/styles.scss +1152 -0
  29. package/repo-template/services/jobseekers-frontend/src/index.js +9 -0
  30. package/repo-template/services/jobseekers-frontend/src/js/recruiter-link.js +25 -0
  31. package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/context/footer-nav.njk +26 -26
  32. package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/context/main-nav.njk +40 -31
  33. package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/context/user-nav.njk +16 -16
  34. package/repo-template/services/jobseekers-frontend/templates/footer.njk +20 -0
  35. package/repo-template/services/jobseekers-frontend/templates/header.njk +74 -0
  36. package/repo-template/services/jobseekers-frontend/templates/includes/footer-nav.njk +15 -0
  37. package/repo-template/services/jobseekers-frontend/templates/includes/main-nav.njk +19 -0
  38. package/repo-template/services/jobseekers-frontend/templates/includes/user-nav/authenticated.njk +34 -0
  39. package/repo-template/services/jobseekers-frontend/templates/includes/user-nav/unauthenticated.njk +9 -0
  40. package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/en.njk +1 -0
  41. package/server/index.js +2 -3
  42. package/server/plugins/hapi-vite.js +4 -2
  43. package/server/routes/views.js +1 -0
  44. package/server/view-manager.js +2 -5
  45. package/.prettierrc.js +0 -8
  46. package/bin/commands/configs.test.js +0 -182
  47. package/bin/utils/configs.test.js +0 -53
  48. package/bin/utils/persistent-cache-with-ttl.test.js +0 -42
  49. package/bin/utils/resolve-external-assets.test.js +0 -98
  50. package/eslint.config.mjs +0 -53
  51. package/repo-templates/globals/fert.config.js +0 -9
  52. package/repo-templates/template-basic/_gitignore +0 -6
  53. package/repo-templates/template-basic/package.json +0 -13
  54. package/repo-templates/template-basic/public/favicon.ico +0 -0
  55. package/repo-templates/template-basic/src/css/styles.scss +0 -11
  56. package/repo-templates/template-basic/src/index.js +0 -3
  57. package/repo-templates/template-basic/templates/footer.njk +0 -14
  58. package/repo-templates/template-basic/templates/header.njk +0 -14
  59. package/repo-templates/template-bigworkbag/_gitignore +0 -6
  60. package/repo-templates/template-bigworkbag/brand.json +0 -21
  61. package/repo-templates/template-bigworkbag/package.json +0 -13
  62. package/repo-templates/template-bigworkbag/public/favicon.ico +0 -0
  63. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.eot +0 -0
  64. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.svg +0 -71
  65. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.ttf +0 -0
  66. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.woff +0 -0
  67. package/repo-templates/template-bigworkbag/public/fonts/my-font.woff +0 -1
  68. package/repo-templates/template-bigworkbag/public/images/logo.png +0 -0
  69. package/repo-templates/template-bigworkbag/public/images/user-menu-pointer.svg +0 -4
  70. package/repo-templates/template-bigworkbag/src/css/breakpoints.scss +0 -17
  71. package/repo-templates/template-bigworkbag/src/css/clicky-menu.scss +0 -52
  72. package/repo-templates/template-bigworkbag/src/css/desktop-main-nav.scss +0 -25
  73. package/repo-templates/template-bigworkbag/src/css/desktop-user-nav.scss +0 -127
  74. package/repo-templates/template-bigworkbag/src/css/footer.scss +0 -77
  75. package/repo-templates/template-bigworkbag/src/css/header-top.scss +0 -29
  76. package/repo-templates/template-bigworkbag/src/css/leaderboard-ad.scss +0 -22
  77. package/repo-templates/template-bigworkbag/src/css/mobile-main-nav.scss +0 -68
  78. package/repo-templates/template-bigworkbag/src/css/mobile-user-nav.scss +0 -49
  79. package/repo-templates/template-bigworkbag/src/css/reset.scss +0 -91
  80. package/repo-templates/template-bigworkbag/src/css/styles.scss +0 -18
  81. package/repo-templates/template-bigworkbag/src/css/top-bar.scss +0 -13
  82. package/repo-templates/template-bigworkbag/src/css/typography.scss +0 -20
  83. package/repo-templates/template-bigworkbag/src/css/util.scss +0 -28
  84. package/repo-templates/template-bigworkbag/src/css/variables.scss +0 -9
  85. package/repo-templates/template-bigworkbag/src/index.js +0 -3
  86. package/repo-templates/template-bigworkbag/src/js/clicky-menus.js +0 -178
  87. package/repo-templates/template-bigworkbag/src/js/no-js.js +0 -10
  88. package/repo-templates/template-bigworkbag/templates/footer.njk +0 -68
  89. package/repo-templates/template-bigworkbag/templates/header.njk +0 -54
  90. package/repo-templates/template-bigworkbag/templates/includes/desktop-main-nav-items.njk +0 -18
  91. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/loggedin-items.njk +0 -28
  92. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/loggedout-items.njk +0 -9
  93. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/submenu-items.njk +0 -18
  94. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/user-nav.njk +0 -24
  95. package/repo-templates/template-bigworkbag/templates/includes/dev-console-context.njk +0 -7
  96. package/repo-templates/template-bigworkbag/templates/includes/mobile-main-nav-items.njk +0 -25
  97. package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/loggedin-items.njk +0 -33
  98. package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/loggedout-items.njk +0 -16
  99. package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/user-nav.njk +0 -24
  100. package/repo-templates/template-bigworkbag/templates/svgs/arrow-down.svg +0 -3
  101. package/repo-templates/template-bigworkbag/templates/svgs/arrow-left.svg +0 -3
  102. package/repo-templates/template-bigworkbag/templates/svgs/arrow-right.svg +0 -3
  103. package/repo-templates/template-bigworkbag/templates/svgs/arrow-up.svg +0 -3
  104. package/repo-templates/template-bigworkbag/templates/svgs/cart.svg +0 -3
  105. package/repo-templates/template-bigworkbag/templates/svgs/facebook.svg +0 -3
  106. package/repo-templates/template-bigworkbag/templates/svgs/linkedin.svg +0 -3
  107. package/repo-templates/template-bigworkbag/templates/svgs/profile.svg +0 -5
  108. package/repo-templates/template-bigworkbag/templates/svgs/star-filled.svg +0 -3
  109. package/repo-templates/template-bigworkbag/templates/svgs/star-outline.svg +0 -3
  110. package/repo-templates/template-bigworkbag/templates/svgs/twitter.svg +0 -3
  111. package/repo-templates/template-bigworkbag/templates/svgs/youtube.svg +0 -3
  112. /package/{repo-templates/globals → repo-template}/jenkinsfile +0 -0
  113. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.eot +0 -0
  114. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.svg +0 -0
  115. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.ttf +0 -0
  116. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.woff +0 -0
  117. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/my-font.woff +0 -0
  118. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/images/logo.png +0 -0
  119. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/da.njk +0 -0
  120. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/de.njk +0 -0
  121. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/es.njk +0 -0
  122. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/fr.njk +0 -0
  123. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/nb.njk +0 -0
  124. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/nl.njk +0 -0
  125. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/sv.njk +0 -0
  126. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/zh-cn.njk +0 -0
@@ -5,9 +5,7 @@ const { resolveConfig } = require('../utils');
5
5
  const { log } = require('../utils/logging');
6
6
  const getAwsParam = require('./publish-tasks/get-aws-parameter');
7
7
  const AssetStoreUploader = require('./publish-tasks/asset-store-uploader');
8
- const {
9
- getCloudFrontDistributionsForDomain,
10
- } = require('../utils/lookup-cf-distribution-ids');
8
+ const { getCloudFrontDistributionsForDomain } = require('../utils/lookup-cf-distribution-ids');
11
9
  const {
12
10
  ASSET_STORE_API,
13
11
  AWS_PARAM_NAME,
@@ -23,13 +21,12 @@ module.exports = async (options) => {
23
21
 
24
22
  // handle legacy options
25
23
  if (options.target === 'prod') {
24
+ // eslint-disable-next-line no-param-reassign
26
25
  options.target = 'production';
27
26
  }
28
27
 
29
28
  if (!validTargets.includes(options.target)) {
30
- throw Error(
31
- `Missing or invalid --target option. Choose from [${validTargets}]`
32
- );
29
+ throw Error(`Missing or invalid --target option. Choose from [${validTargets}]`);
33
30
  }
34
31
 
35
32
  if (options.dryRun) {
@@ -46,29 +43,18 @@ module.exports = async (options) => {
46
43
  const apiUrl = Hoek.reachTemplate(templateCtx, ASSET_STORE_API);
47
44
  const remoteBasePath = Hoek.reachTemplate(templateCtx, REMOTE_UPLOAD_BASE);
48
45
  const apiKeyParamPath = Hoek.reachTemplate(templateCtx, AWS_PARAM_NAME);
49
- const assetStoreInvPath = Hoek.reachTemplate(
50
- templateCtx,
51
- ASSET_STORE_INVALIDATION_PATH
52
- );
53
- const brandedSiteInvPath = Hoek.reachTemplate(
54
- templateCtx,
55
- BRANDED_SITE_INVALIDATION_PATH
56
- );
46
+ const assetStoreInvPath = Hoek.reachTemplate(templateCtx, ASSET_STORE_INVALIDATION_PATH);
47
+ const brandedSiteInvPath = Hoek.reachTemplate(templateCtx, BRANDED_SITE_INVALIDATION_PATH);
57
48
 
58
49
  const apiKey = await getAwsParam(apiKeyParamPath);
59
50
 
60
51
  const siteUrl = new URL(fertConfig.config.JobseekerSiteWebSitePath);
61
- const clientCloudFrontDists = await getCloudFrontDistributionsForDomain(
62
- siteUrl.hostname,
63
- options
64
- );
52
+ const clientCloudFrontDists = await getCloudFrontDistributionsForDomain(siteUrl.hostname, options);
65
53
 
66
54
  log.info(
67
55
  `\nPublishing ${chalk.cyan(localDir)} to ${chalk.green.bold(
68
- options.target
69
- )} for ${chalk.green(fertConfig.client.brandName)} ${chalk.dim(
70
- `(${fertConfig.clientPropertyId})`
71
- )}\n`
56
+ options.target,
57
+ )} for ${chalk.green(fertConfig.client.brandName)} ${chalk.dim(`(${fertConfig.clientPropertyId})`)}\n`,
72
58
  );
73
59
 
74
60
  try {
@@ -84,9 +70,7 @@ module.exports = async (options) => {
84
70
  uploadResult = await assetStore.uploadDir(localDir);
85
71
  }
86
72
 
87
- log.success(
88
- `Publish complete in ${((uploadResult?.duration || 1) / 1000).toFixed(0)}s\n`
89
- );
73
+ log.success(`Publish complete in ${((uploadResult?.duration || 1) / 1000).toFixed(0)}s\n`);
90
74
 
91
75
  // invalidate cloudfront cache
92
76
  await assetStore.invalidatePaths([assetStoreInvPath]);
@@ -95,11 +79,7 @@ module.exports = async (options) => {
95
79
  await assetStore.invalidatePaths([brandedSiteInvPath], dist.id);
96
80
  }
97
81
 
98
- log.info(
99
- `\nNote cloudfront invalidations may take upto ${chalk.yellow(
100
- '30 seconds'
101
- )} to complete.\n`
102
- );
82
+ log.info(`\nNote cloudfront invalidations may take upto ${chalk.yellow('30 seconds')} to complete.\n`);
103
83
  } catch (error) {
104
84
  log.error('An error occurred during the publish process', error);
105
85
  }
@@ -16,11 +16,7 @@ const { CONFIG_DIR } = require('../../constants');
16
16
  * @returns {Promise<void>} - Returns a promise that resolves if all configurations are valid.
17
17
  * @throws {Error} - Throws an error if any configuration is invalid.
18
18
  */
19
- const validateLocalConfigs = async ({
20
- workingDir,
21
- clientPropertyId,
22
- throwable = true,
23
- }) => {
19
+ const validateLocalConfigs = async ({ workingDir, clientPropertyId, throwable = true }) => {
24
20
  Hoek.assert(clientPropertyId, 'clientPropertyId is required');
25
21
  Hoek.assert(workingDir, 'workingDir is required');
26
22
 
@@ -36,55 +32,44 @@ const validateLocalConfigs = async ({
36
32
  });
37
33
  const localConfigs = loadLocalConfigs(workingDir);
38
34
 
39
- const validationPromises = Object.keys(localConfigs).map(
40
- async (configName) => {
41
- try {
42
- const schema = api.getSchema(configName);
43
- const isSchemaReadOnly = api._isSchemaReadOnly(schema);
35
+ const validationPromises = Object.keys(localConfigs).map(async (configName) => {
36
+ try {
37
+ const schema = api.getSchema(configName);
38
+ const isSchemaReadOnly = api._isSchemaReadOnly(schema);
44
39
 
45
- if (isSchemaReadOnly) {
46
- throw Error(
47
- `You're trying to set values on a read-only (usually V5) config schema: ${configName}`
48
- );
49
- }
40
+ if (isSchemaReadOnly) {
41
+ throw Error(`You're trying to set values on a read-only (usually V5) config schema: ${configName}`);
42
+ }
50
43
 
51
- // check the entire config against the config validation
52
- const { error } = schema.validate(localConfigs[configName].data);
53
- if (error) {
54
- throw new Error(
55
- `Config invalid: ${chalk.bold(localConfigs[configName].path)} - ${error.message}`
56
- );
57
- }
44
+ // check the entire config against the config validation
45
+ const { error } = schema.validate(localConfigs[configName].data);
46
+ if (error) {
47
+ throw new Error(`Config invalid: ${chalk.bold(localConfigs[configName].path)} - ${error.message}`);
48
+ }
58
49
 
59
- // validate all keys individually against the schema keys to ensure we're not trying to set any read-only keys
60
- const config = localConfigs[configName].data;
61
- for (const key in config) {
62
- const keySchema = schema.extract(key);
63
- if (api._isSchemaReadOnly(keySchema)) {
64
- throw new Error(
65
- `You're trying to set a read-only key on a config schema: ${configName}/${key}`
66
- );
67
- }
50
+ // validate all keys individually against the schema keys to ensure we're not trying to set any read-only keys
51
+ const config = localConfigs[configName].data;
52
+ for (const key in config) {
53
+ const keySchema = schema.extract(key);
54
+ if (api._isSchemaReadOnly(keySchema)) {
55
+ throw new Error(`You're trying to set a read-only key on a config schema: ${configName}/${key}`);
68
56
  }
57
+ }
69
58
 
70
- log.success(`Config validated:`, chalk.bold(configName));
71
- } catch (err) {
72
- log.error(err.message);
59
+ log.success(`Config validated:`, chalk.bold(configName));
60
+ } catch (err) {
61
+ log.error(err.message);
73
62
 
74
- if (throwable) {
75
- throw err;
76
- }
63
+ if (throwable) {
64
+ throw err;
77
65
  }
78
66
  }
79
- );
67
+ });
80
68
 
81
69
  await Promise.all(validationPromises);
82
70
  };
83
71
 
84
- const getConfigAPI = async ({
85
- clientPropertyId,
86
- environment = 'production',
87
- } = {}) => {
72
+ const getConfigAPI = async ({ clientPropertyId, environment = 'production' } = {}) => {
88
73
  const { ConfigAPI } = await import('@madgex/config-api-sdk');
89
74
 
90
75
  const api = new ConfigAPI({
@@ -143,11 +128,7 @@ const loadLocalConfigs = (workingDir) => {
143
128
  *
144
129
  * @returns {Promise<boolean>} - Returns a promise that resolves to true if the update is successful.
145
130
  */
146
- const updateProjectConfigs = async ({
147
- clientPropertyId,
148
- workingDir,
149
- environment = 'production',
150
- } = {}) => {
131
+ const updateProjectConfigs = async ({ clientPropertyId, workingDir, environment = 'production' } = {}) => {
151
132
  Hoek.assert(clientPropertyId, 'clientPropertyId is required');
152
133
  Hoek.assert(workingDir, 'workingDir is required');
153
134
 
@@ -174,7 +155,7 @@ const updateProjectConfigs = async ({
174
155
  const { host } = new URL(api.options.apiUrl);
175
156
  log.info(``);
176
157
  log.info(`Project configs applied to ${chalk.bold(host)}`);
177
- return true;
158
+ return;
178
159
  } catch (error) {
179
160
  log.info(``);
180
161
  log.error('Failed to apply project configs', error);
@@ -186,48 +167,37 @@ const collateConfigs = (api, localConfigs) => {
186
167
  const toRemove = {};
187
168
  const toSet = {};
188
169
 
189
- Object.entries(localConfigs).forEach(
190
- ([configName, { data: config = {} } = {}]) => {
191
- const schema = api.getSchema(configName);
192
- const isSchemaReadOnly = api._isSchemaReadOnly(schema);
170
+ Object.entries(localConfigs).forEach(([configName, { data: config = {} } = {}]) => {
171
+ const schema = api.getSchema(configName);
172
+ const isSchemaReadOnly = api._isSchemaReadOnly(schema);
193
173
 
194
- if (isSchemaReadOnly) {
195
- log.warn(`Skipping read-only schema: ${configName}`);
196
- return;
197
- }
174
+ if (isSchemaReadOnly) {
175
+ log.warn(`Skipping read-only schema: ${configName}`);
176
+ return;
177
+ }
198
178
 
199
- const configDefault = api._getDefaultConfig(configName);
179
+ const configDefault = api._getDefaultConfig(configName);
200
180
 
201
- const unsetKeysWithDefaults = getUnsetKeysWithDefaults(
202
- configDefault,
203
- config
204
- );
181
+ const unsetKeysWithDefaults = getUnsetKeysWithDefaults(configDefault, config);
205
182
 
206
- // remove any keys that are read-only from the unset keys collection
207
- // we don't want to be deleting those!
208
- for (const key in unsetKeysWithDefaults) {
209
- if (api._isSchemaReadOnly(schema.extract(key))) {
210
- delete unsetKeysWithDefaults[key];
211
- }
183
+ // remove any keys that are read-only from the unset keys collection
184
+ // we don't want to be deleting those!
185
+ for (const key in unsetKeysWithDefaults) {
186
+ if (api._isSchemaReadOnly(schema.extract(key))) {
187
+ delete unsetKeysWithDefaults[key];
212
188
  }
213
-
214
- toRemove[configName] = Object.keys(unsetKeysWithDefaults);
215
- toSet[configName] = config;
216
189
  }
217
- );
190
+
191
+ toRemove[configName] = Object.keys(unsetKeysWithDefaults);
192
+ toSet[configName] = config;
193
+ });
218
194
 
219
195
  return { toRemove, toSet };
220
196
  };
221
197
 
222
198
  const getUnsetKeysWithDefaults = (defaults = {}, config = {}) => {
223
- Hoek.assert(
224
- typeof defaults === 'object' && defaults !== null,
225
- 'defaults must be an object'
226
- );
227
- Hoek.assert(
228
- typeof config === 'object' && config !== null,
229
- 'config must be an object'
230
- );
199
+ Hoek.assert(typeof defaults === 'object' && defaults !== null, 'defaults must be an object');
200
+ Hoek.assert(typeof config === 'object' && config !== null, 'config must be an object');
231
201
 
232
202
  const diff = {};
233
203
  for (const key in defaults) {
@@ -243,17 +213,12 @@ const removeConfigs = async (api, toRemove) => {
243
213
  keys.map(async (key) => {
244
214
  try {
245
215
  await api.deleteConfig(configName, key);
246
- log.success(
247
- `Successfully removed ${chalk.bold(key)} from ${chalk.bold(configName)}`
248
- );
216
+ log.success(`Successfully removed ${chalk.bold(key)} from ${chalk.bold(configName)}`);
249
217
  } catch (error) {
250
- log.error(
251
- `Failed to remove ${chalk.bold(key)} from ${chalk.bold(configName)}:`,
252
- error
253
- );
218
+ log.error(`Failed to remove ${chalk.bold(key)} from ${chalk.bold(configName)}:`, error);
254
219
  throw error;
255
220
  }
256
- })
221
+ }),
257
222
  );
258
223
 
259
224
  return Promise.all(operations);
@@ -264,17 +229,12 @@ const setConfigs = async (api, toSet) => {
264
229
  Object.entries(config).map(async ([key, value]) => {
265
230
  try {
266
231
  await api.setConfig(configName, key, value);
267
- log.success(
268
- `Successfully set ${chalk.bold(key)} in ${chalk.bold(configName)}`
269
- );
232
+ log.success(`Successfully set ${chalk.bold(key)} in ${chalk.bold(configName)}`);
270
233
  } catch (error) {
271
- log.error(
272
- `Failed to set ${chalk.bold(key)} in ${chalk.bold(configName)}:`,
273
- error
274
- );
234
+ log.error(`Failed to set ${chalk.bold(key)} in ${chalk.bold(configName)}:`, error);
275
235
  throw error;
276
236
  }
277
- })
237
+ }),
278
238
  );
279
239
 
280
240
  return Promise.all(operations);
@@ -19,8 +19,8 @@ exports.doCpidLookup = async (clientPropertyId) => {
19
19
  .catch((error) => {
20
20
  log.error(
21
21
  `Unable to lookup CPID [${chalk.yellow(
22
- clientPropertyId
23
- )}] from ${chalk.cyan(API_URL)}: ${chalk.redBright(error.message)}\n`
22
+ clientPropertyId,
23
+ )}] from ${chalk.cyan(API_URL)}: ${chalk.redBright(error.message)}\n`,
24
24
  );
25
25
 
26
26
  throw Error(error.message);
@@ -26,10 +26,7 @@ exports.cpIdMatchesGitRemote = async (fertConfig) => {
26
26
  baseDir: fertConfig.workingDir,
27
27
  };
28
28
  const git = simpleGit(simpleGitOptions);
29
- Hoek.assert(
30
- await git.checkIsRepo(),
31
- `detected fert config in${fertConfigDir}, but it is not a git repository`
32
- );
29
+ Hoek.assert(await git.checkIsRepo(), `detected fert config in${fertConfigDir}, but it is not a git repository`);
33
30
 
34
31
  // Validate that the CPID in the fert config matches the CPID in the git remote URL
35
32
  try {
@@ -38,22 +35,20 @@ exports.cpIdMatchesGitRemote = async (fertConfig) => {
38
35
  const repo = parts[parts.length - 1].trim();
39
36
  const remoteUrlCpid = repo.split('madgex-')[1].trim().replace('.git', '');
40
37
 
41
- if (remoteUrlCpid == fertConfig.clientPropertyId) {
38
+ if (remoteUrlCpid === fertConfig.clientPropertyId) {
42
39
  return true;
43
40
  }
44
41
 
45
42
  // Big ugly console message for high visibility.
46
43
  console.log(
47
44
  dedent`
48
- ${chalk.bgRed.bold(
49
- '💀 💀 💀 Client Property IDs do not match! 💀 💀 💀 '
50
- )}
45
+ ${chalk.bgRed.bold('💀 💀 💀 Client Property IDs do not match! 💀 💀 💀 ')}
51
46
  ${chalk.red('CPID from fert.config.js:')} ${fertConfig.clientPropertyId}
52
47
  ${chalk.red('CPID from Git remote URL:')} ${remoteUrlCpid}
53
48
  ${chalk.bgYellow.bold(
54
- '🤓 Please ensure that the Client Property Id from the fert.config.js and the git remote match 🧐 '
49
+ '🤓 Please ensure that the Client Property Id from the fert.config.js and the git remote match 🧐 ',
55
50
  )}\n
56
- `
51
+ `,
57
52
  );
58
53
  } catch (error) {
59
54
  console.log(error);
@@ -1,4 +1,4 @@
1
- const getSchemaMeta = function (schema, key = null) {
1
+ const getSchemaMeta = function getSchemaMeta(schema, key = null) {
2
2
  if (!schema || typeof schema.describe !== 'function') {
3
3
  throw new Error('Schema is required');
4
4
  }
@@ -1,11 +1,8 @@
1
1
  const path = require('node:path');
2
2
  const fs = require('node:fs');
3
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
3
4
  const { glob } = require('node:fs/promises');
4
- const {
5
- VERSION,
6
- FERT_CONFIG_FILENAME,
7
- FERT_SERVICE_CONFIG_FILENAME,
8
- } = require('../../constants');
5
+ const { VERSION, FERT_CONFIG_FILENAME, FERT_SERVICE_CONFIG_FILENAME } = require('../../constants');
9
6
  const chalk = require('chalk');
10
7
  const uuidValidator = require('uuid-validate');
11
8
  const Hoek = require('@hapi/hoek');
@@ -56,7 +53,7 @@ exports.resolveConfig = async (options = {}) => {
56
53
 
57
54
  // workingDir based on service folder
58
55
  const { dir: workingDir, serviceConfig } = serviceConfigs.find(
59
- (item) => item.serviceConfig.serviceName === options.serviceName
56
+ (item) => item.serviceConfig.serviceName === options.serviceName,
60
57
  );
61
58
  const fertConfig = Hoek.applyToDefaults(
62
59
  defaults,
@@ -64,20 +61,17 @@ exports.resolveConfig = async (options = {}) => {
64
61
  {
65
62
  ...this.loadConfigFromFile({ dir: rootDir }),
66
63
  ...serviceConfig,
67
- }
64
+ },
68
65
  );
69
66
 
70
67
  // Check Fert cpid is valid
71
68
  Hoek.assert(
72
69
  uuidValidator(fertConfig.clientPropertyId),
73
- `Invalid clientPropertyId specified in fert.config.js: ${fertConfig.clientPropertyId}`
70
+ `Invalid clientPropertyId specified in fert.config.js: ${fertConfig.clientPropertyId}`,
74
71
  );
75
72
 
76
73
  // Check Fert serviceName is valid
77
- Hoek.assert(
78
- typeof fertConfig.serviceName === 'string',
79
- `serviceName required: ${fertConfig.serviceName}`
80
- );
74
+ Hoek.assert(typeof fertConfig.serviceName === 'string', `serviceName required: ${fertConfig.serviceName}`);
81
75
  // get & store the current git branch
82
76
  fertConfig.currBranch = (await git.branch()).current;
83
77
 
@@ -86,7 +80,7 @@ exports.resolveConfig = async (options = {}) => {
86
80
 
87
81
  Hoek.assert(
88
82
  fertCpidMatchesGitRemote,
89
- `CPID mismatch, please correct before retrying: ${fertConfig.clientPropertyId}`
83
+ `CPID mismatch, please correct before retrying: ${fertConfig.clientPropertyId}`,
90
84
  );
91
85
 
92
86
  const client = await cpidLookup(fertConfig.clientPropertyId);
@@ -145,11 +139,7 @@ exports.loadServiceConfigFiles = async () => {
145
139
  return serviceConfigs;
146
140
  };
147
141
 
148
- exports.loadConfigFromFile = ({
149
- dir = process.cwd(),
150
- filename = FERT_CONFIG_FILENAME,
151
- silent = false,
152
- }) => {
142
+ exports.loadConfigFromFile = ({ dir = process.cwd(), filename = FERT_CONFIG_FILENAME, silent = false }) => {
153
143
  const configPath = path.resolve(dir, filename);
154
144
  try {
155
145
  // always return fresh config
@@ -162,14 +152,13 @@ exports.loadConfigFromFile = ({
162
152
  return fertConfig;
163
153
  } catch (err) {
164
154
  if (!silent) {
165
- log.error(
166
- `Failed to load ${filename} - ensure you're running fert on a branding repo & config exists.\n`
167
- );
155
+ log.error(`Failed to load ${filename} - ensure you're running fert on a branding repo & config exists.\n`);
168
156
 
169
157
  console.error(err);
170
158
  throw err;
171
159
  }
172
160
  }
161
+ return null;
173
162
  };
174
163
 
175
164
  exports.ensureTrailingSlash = (str) => {
@@ -178,17 +167,17 @@ exports.ensureTrailingSlash = (str) => {
178
167
  return lastChar === '/' ? str : `${str}/`;
179
168
  };
180
169
 
181
- exports.exists = async (path) => {
170
+ exports.exists = async (_path) => {
182
171
  try {
183
- fs.access(path);
172
+ fs.access(_path);
184
173
  return true;
185
174
  } catch {
186
175
  return false;
187
176
  }
188
177
  };
189
178
 
190
- exports.isEmptyDir = function isEmptyDir(path) {
191
- const files = fs.readdirSync(path);
179
+ exports.isEmptyDir = function isEmptyDir(_path) {
180
+ const files = fs.readdirSync(_path);
192
181
  return files.length === 0 || (files.length === 1 && files[0] === '.git');
193
182
  };
194
183
 
@@ -1,7 +1,4 @@
1
- const {
2
- CloudFrontClient,
3
- ListDistributionsCommand,
4
- } = require('@aws-sdk/client-cloudfront');
1
+ const { CloudFrontClient, ListDistributionsCommand } = require('@aws-sdk/client-cloudfront');
5
2
  const { persistentCacheWithTtl } = require('./persistent-cache-with-ttl');
6
3
  const assert = require('node:assert');
7
4
  const { ONE_WEEK, AWS_REGION } = require('../../constants');
@@ -19,9 +16,7 @@ exports.doGetAllCloudFrontDistributions = async () => {
19
16
  let isTruncated = false;
20
17
 
21
18
  do {
22
- const list = await cloudfront.send(
23
- new ListDistributionsCommand({ Marker })
24
- );
19
+ const list = await cloudfront.send(new ListDistributionsCommand({ Marker }));
25
20
 
26
21
  Marker = list.DistributionList.NextMarker;
27
22
  isTruncated = list.DistributionList.IsTruncated;
@@ -6,18 +6,14 @@ class LinkAsset {
6
6
  this.href = arg;
7
7
  } else if (typeof arg === 'object') {
8
8
  if (!arg.href) {
9
- throw new Error(
10
- 'External assets - the link is missing the href property'
11
- );
9
+ throw new Error('External assets - the link is missing the href property');
12
10
  }
13
11
 
14
12
  for (const [key, value] of Object.entries(arg)) {
15
13
  this[key] = value;
16
14
  }
17
15
  } else {
18
- throw new Error(
19
- 'External assets - the value should be a string or an object'
20
- );
16
+ throw new Error('External assets - the value should be a string or an object');
21
17
  }
22
18
  }
23
19
  }
@@ -29,13 +25,12 @@ class ScriptAsset {
29
25
  this.src = arg;
30
26
  } else if (typeof arg === 'object') {
31
27
  if (!arg.src) {
32
- throw new Error(
33
- 'External assets - the script is missing the src property'
34
- );
28
+ throw new Error('External assets - the script is missing the src property');
35
29
  }
36
30
 
37
31
  // in case defer has been set to false in the config, we remove it so it's not added to the object
38
32
  if (arg.defer === false) {
33
+ // eslint-disable-next-line no-param-reassign
39
34
  delete arg.defer;
40
35
  }
41
36
 
@@ -48,9 +43,7 @@ class ScriptAsset {
48
43
  delete this.async;
49
44
  }
50
45
  } else {
51
- throw new Error(
52
- 'External assets - the value should be a string or an object'
53
- );
46
+ throw new Error('External assets - the value should be a string or an object');
54
47
  }
55
48
  }
56
49
  }
@@ -70,9 +63,7 @@ function resolveExternalAssets(assets = {}) {
70
63
  }
71
64
 
72
65
  if (assets.scripts) {
73
- const scriptArr = Array.isArray(assets.scripts)
74
- ? assets.scripts
75
- : [assets.scripts];
66
+ const scriptArr = Array.isArray(assets.scripts) ? assets.scripts : [assets.scripts];
76
67
 
77
68
  scriptArr.forEach((item) => {
78
69
  result.scripts.push(new ScriptAsset(item));
package/constants.js CHANGED
@@ -2,9 +2,7 @@ const fs = require('node:fs');
2
2
  const path = require('node:path');
3
3
  const os = require('node:os');
4
4
 
5
- const { version: VERSION } = JSON.parse(
6
- fs.readFileSync(path.resolve(__dirname, './package.json')).toString()
7
- );
5
+ const { version: VERSION } = JSON.parse(fs.readFileSync(path.resolve(__dirname, './package.json')).toString());
8
6
 
9
7
  const ONE_MINUTE = 60000;
10
8
  const ONE_HOUR = ONE_MINUTE * 60;
@@ -16,8 +14,7 @@ module.exports = {
16
14
  TMP_DIR: fs.realpathSync(os.tmpdir()),
17
15
  FERT_PACKAGE_DIR: path.resolve('./'),
18
16
  AWS_REGION: 'eu-west-1',
19
- PROPERTY_ID_API:
20
- 'https://property-identification-api.cs.madgexhosting.net/properties/',
17
+ PROPERTY_ID_API: 'https://property-identification-api.cs.madgexhosting.net/properties/',
21
18
  ASSETS_API_URL: 'https://asset-store.job.madgexhosting.net',
22
19
  BRAND_JSON_FILENAME: 'brand.json',
23
20
  FERT_CONFIG_FILENAME: 'fert.config.js',
@@ -34,8 +31,7 @@ module.exports = {
34
31
  /**
35
32
  * important to have the correct service name and cpid so assets are uploaded to the correct unique place per-service.
36
33
  */
37
- REMOTE_UPLOAD_BASE:
38
- '/api/assets/{fertConfig.serviceName}/{fertConfig.clientPropertyId}',
34
+ REMOTE_UPLOAD_BASE: '/api/assets/{fertConfig.serviceName}/{fertConfig.clientPropertyId}',
39
35
  /**
40
36
  * invalidates the real asset store key path, which is related to `REMOTE_UPLOAD_BASE`
41
37
  * asset-store puts things in `rootClientPropertyId` based on the AWS_PARAM_NAME used, and the rest of the path relates to `REMOTE_UPLOAD_BASE`
@@ -50,16 +46,6 @@ module.exports = {
50
46
  */
51
47
  BRANDED_SITE_INVALIDATION_PATH: `/_/{fertConfig.serviceName}/assets/*`,
52
48
  ASSET_STORE_USER_GUID: 'a386d4b6-f2df-4b80-ad1f-0349e23f530b',
53
- TEMPLATES: [
54
- {
55
- name: 'basic',
56
- display: 'Basic - blank canvas',
57
- },
58
- {
59
- name: 'bigworkbag',
60
- display: 'BigWorkBag - populated, example project',
61
- },
62
- ],
63
49
  ONE_MINUTE,
64
50
  ONE_HOUR,
65
51
  ONE_DAY,