@madgex/fert 5.0.3 → 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 (127) hide show
  1. package/README.md +21 -12
  2. package/bin/cli.js +9 -27
  3. package/bin/commands/_service-command-bootstrap.js +12 -52
  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/delivery/jenkinsfile +0 -93
  51. package/eslint.config.mjs +0 -53
  52. package/repo-templates/globals/fert.config.js +0 -9
  53. package/repo-templates/template-basic/_gitignore +0 -6
  54. package/repo-templates/template-basic/package.json +0 -13
  55. package/repo-templates/template-basic/public/favicon.ico +0 -0
  56. package/repo-templates/template-basic/src/css/styles.scss +0 -11
  57. package/repo-templates/template-basic/src/index.js +0 -3
  58. package/repo-templates/template-basic/templates/footer.njk +0 -14
  59. package/repo-templates/template-basic/templates/header.njk +0 -14
  60. package/repo-templates/template-bigworkbag/_gitignore +0 -6
  61. package/repo-templates/template-bigworkbag/brand.json +0 -21
  62. package/repo-templates/template-bigworkbag/package.json +0 -13
  63. package/repo-templates/template-bigworkbag/public/favicon.ico +0 -0
  64. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.eot +0 -0
  65. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.svg +0 -71
  66. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.ttf +0 -0
  67. package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.woff +0 -0
  68. package/repo-templates/template-bigworkbag/public/fonts/my-font.woff +0 -1
  69. package/repo-templates/template-bigworkbag/public/images/logo.png +0 -0
  70. package/repo-templates/template-bigworkbag/public/images/user-menu-pointer.svg +0 -4
  71. package/repo-templates/template-bigworkbag/src/css/breakpoints.scss +0 -17
  72. package/repo-templates/template-bigworkbag/src/css/clicky-menu.scss +0 -52
  73. package/repo-templates/template-bigworkbag/src/css/desktop-main-nav.scss +0 -25
  74. package/repo-templates/template-bigworkbag/src/css/desktop-user-nav.scss +0 -127
  75. package/repo-templates/template-bigworkbag/src/css/footer.scss +0 -77
  76. package/repo-templates/template-bigworkbag/src/css/header-top.scss +0 -29
  77. package/repo-templates/template-bigworkbag/src/css/leaderboard-ad.scss +0 -22
  78. package/repo-templates/template-bigworkbag/src/css/mobile-main-nav.scss +0 -68
  79. package/repo-templates/template-bigworkbag/src/css/mobile-user-nav.scss +0 -49
  80. package/repo-templates/template-bigworkbag/src/css/reset.scss +0 -91
  81. package/repo-templates/template-bigworkbag/src/css/styles.scss +0 -18
  82. package/repo-templates/template-bigworkbag/src/css/top-bar.scss +0 -13
  83. package/repo-templates/template-bigworkbag/src/css/typography.scss +0 -20
  84. package/repo-templates/template-bigworkbag/src/css/util.scss +0 -28
  85. package/repo-templates/template-bigworkbag/src/css/variables.scss +0 -9
  86. package/repo-templates/template-bigworkbag/src/index.js +0 -3
  87. package/repo-templates/template-bigworkbag/src/js/clicky-menus.js +0 -178
  88. package/repo-templates/template-bigworkbag/src/js/no-js.js +0 -10
  89. package/repo-templates/template-bigworkbag/templates/footer.njk +0 -68
  90. package/repo-templates/template-bigworkbag/templates/header.njk +0 -54
  91. package/repo-templates/template-bigworkbag/templates/includes/desktop-main-nav-items.njk +0 -18
  92. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/loggedin-items.njk +0 -28
  93. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/loggedout-items.njk +0 -9
  94. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/submenu-items.njk +0 -18
  95. package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/user-nav.njk +0 -24
  96. package/repo-templates/template-bigworkbag/templates/includes/dev-console-context.njk +0 -7
  97. package/repo-templates/template-bigworkbag/templates/includes/mobile-main-nav-items.njk +0 -25
  98. package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/loggedin-items.njk +0 -33
  99. package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/loggedout-items.njk +0 -16
  100. package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/user-nav.njk +0 -24
  101. package/repo-templates/template-bigworkbag/templates/svgs/arrow-down.svg +0 -3
  102. package/repo-templates/template-bigworkbag/templates/svgs/arrow-left.svg +0 -3
  103. package/repo-templates/template-bigworkbag/templates/svgs/arrow-right.svg +0 -3
  104. package/repo-templates/template-bigworkbag/templates/svgs/arrow-up.svg +0 -3
  105. package/repo-templates/template-bigworkbag/templates/svgs/cart.svg +0 -3
  106. package/repo-templates/template-bigworkbag/templates/svgs/facebook.svg +0 -3
  107. package/repo-templates/template-bigworkbag/templates/svgs/linkedin.svg +0 -3
  108. package/repo-templates/template-bigworkbag/templates/svgs/profile.svg +0 -5
  109. package/repo-templates/template-bigworkbag/templates/svgs/star-filled.svg +0 -3
  110. package/repo-templates/template-bigworkbag/templates/svgs/star-outline.svg +0 -3
  111. package/repo-templates/template-bigworkbag/templates/svgs/twitter.svg +0 -3
  112. package/repo-templates/template-bigworkbag/templates/svgs/youtube.svg +0 -3
  113. /package/{repo-templates/globals → repo-template}/jenkinsfile +0 -0
  114. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.eot +0 -0
  115. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.svg +0 -0
  116. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.ttf +0 -0
  117. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/mdgx-icons.woff +0 -0
  118. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/fonts/my-font.woff +0 -0
  119. /package/{repo-templates/template-basic → repo-template/services/jobseekers-frontend}/public/images/logo.png +0 -0
  120. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/da.njk +0 -0
  121. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/de.njk +0 -0
  122. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/es.njk +0 -0
  123. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/fr.njk +0 -0
  124. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/nb.njk +0 -0
  125. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/nl.njk +0 -0
  126. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/sv.njk +0 -0
  127. /package/{repo-templates/template-bigworkbag → repo-template/services/jobseekers-frontend}/templates/translations/zh-cn.njk +0 -0
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-unreachable */
2
1
  const path = require('node:path');
3
2
  const fs = require('node:fs');
4
3
  const chalk = require('chalk');
@@ -6,20 +5,17 @@ const prompts = require('prompts');
6
5
  const uuidValidator = require('uuid-validate');
7
6
  const ora = require('ora');
8
7
  const { cpidLookup } = require('../utils/cpid-lookup');
8
+ const fertPackageJSON = require('../../package.json');
9
9
 
10
10
  const { isEmptyDir, formatTargetDir, emptyDir } = require('../utils/index');
11
- const { TEMPLATES, FERT_CONFIG_FILENAME } = require('../../constants');
11
+ const { FERT_CONFIG_FILENAME } = require('../../constants');
12
12
 
13
13
  const cwd = process.cwd();
14
- const templateList = TEMPLATES.map((i) => i.name);
15
14
 
16
15
  module.exports = async (root, options = {}) => {
17
- throw new Error('TODO: init new monorepo template');
18
16
  const defaultProjectName = 'madgex-{cpid}';
19
17
  const argTargetDir = root ? formatTargetDir(root) : null;
20
- const argTemplate = options.template;
21
- const argClientPropertyId =
22
- options.cpid && uuidValidator(options.cpid) ? options.cpid : false;
18
+ const argClientPropertyId = options.cpid && uuidValidator(options.cpid) ? options.cpid : false;
23
19
 
24
20
  let targetDir = argTargetDir || path.join(cwd, defaultProjectName);
25
21
  let result;
@@ -32,47 +28,22 @@ module.exports = async (root, options = {}) => {
32
28
  name: 'cpid',
33
29
  message: 'clientPropertyId:',
34
30
  validate: (cpid) =>
35
- uuidValidator(cpid)
36
- ? true
37
- : `Invalid UUID, ensure the correct clientPropertyId is entered`,
31
+ uuidValidator(cpid) ? true : `Invalid UUID, ensure the correct clientPropertyId is entered`,
38
32
  },
39
33
  {
40
34
  type: argTargetDir ? null : 'text',
41
35
  name: 'projectName',
42
36
  message: 'Project name:',
43
- initial: (prev) =>
44
- defaultProjectName.replace('{cpid}', prev || argClientPropertyId),
37
+ initial: (prev) => defaultProjectName.replace('{cpid}', prev || argClientPropertyId),
45
38
  onState: (state) => {
46
39
  targetDir = formatTargetDir(state.value) || defaultProjectName;
47
40
  },
48
41
  },
49
42
  {
50
- type:
51
- argTemplate && templateList.includes(argTemplate) ? null : 'select',
52
- name: 'template',
53
- message:
54
- typeof argTemplate === 'string' &&
55
- !templateList.includes(argTemplate)
56
- ? `"${argTemplate}" isn't a valid template. Please choose from below: `
57
- : 'Select a template:',
58
- initial: 0,
59
- choices: TEMPLATES.map((i) => {
60
- return {
61
- title: i.display,
62
- value: i.name,
63
- };
64
- }),
65
- },
66
- {
67
- type: () =>
68
- !fs.existsSync(targetDir) || isEmptyDir(targetDir)
69
- ? null
70
- : 'confirm',
43
+ type: () => (!fs.existsSync(targetDir) || isEmptyDir(targetDir) ? null : 'confirm'),
71
44
  name: 'overwrite',
72
45
  message: () =>
73
- (targetDir === '.'
74
- ? 'Current directory'
75
- : `Target directory "${targetDir}"`) +
46
+ (targetDir === '.' ? 'Current directory' : `Target directory "${targetDir}"`) +
76
47
  ` is not empty. Remove existing files and continue?`,
77
48
  },
78
49
  {
@@ -89,32 +60,24 @@ module.exports = async (root, options = {}) => {
89
60
  onCancel: () => {
90
61
  throw new Error(chalk.red('✖') + ' Operation cancelled');
91
62
  },
92
- }
63
+ },
93
64
  );
94
65
  } catch (cancelled) {
95
66
  console.log(cancelled.message);
96
67
  return;
97
68
  }
98
69
 
99
- const { overwrite, template, cpid } = result;
100
- const templateName = template || argTemplate;
70
+ const { overwrite, cpid } = result;
101
71
  const clientPropertyId = cpid || argClientPropertyId;
102
72
  const outDir = targetDir;
103
73
 
104
- const spinner = ora(
105
- `Looking up clientPropertyId: ${chalk.yellow(clientPropertyId)}`
106
- ).start();
74
+ const spinner = ora(`Looking up clientPropertyId: ${chalk.yellow(clientPropertyId)}`).start();
107
75
  let clientProperties;
108
76
  try {
109
77
  clientProperties = await cpidLookup(clientPropertyId, options);
110
- spinner.succeed(
111
- `Looking up clientPropertyId: ${chalk.green(clientPropertyId)}`
112
- );
78
+ spinner.succeed(`Looking up clientPropertyId: ${chalk.green(clientPropertyId)}`);
113
79
  } catch (err) {
114
- spinner.fail(
115
- `Unable to find client details for '${chalk.red(clientPropertyId)}':`,
116
- err.message
117
- );
80
+ spinner.fail(`Unable to find client details for '${chalk.red(clientPropertyId)}':`, err.message);
118
81
 
119
82
  return;
120
83
  }
@@ -127,83 +90,30 @@ module.exports = async (root, options = {}) => {
127
90
 
128
91
  console.log(`\nScaffolding project in ${chalk.bold(outDir)}…`);
129
92
 
130
- const templateGlobalsDir = path.resolve(
131
- __dirname,
132
- '../../repo-templates',
133
- `globals`
134
- );
135
- const templateDir = path.resolve(
136
- __dirname,
137
- '../../repo-templates',
138
- `template-${templateName}`
139
- );
140
-
141
- const renameFiles = {
142
- _gitignore: '.gitignore',
143
- };
144
-
145
- function copy(src, dest) {
146
- const stat = fs.statSync(src);
147
- if (stat.isDirectory()) {
148
- copyDir(src, dest);
149
- } else {
150
- fs.copyFileSync(src, dest);
151
- }
152
- }
153
-
154
- function copyDir(srcDir, destDir) {
155
- fs.mkdirSync(destDir, { recursive: true });
156
- for (const file of fs.readdirSync(srcDir)) {
157
- const srcFile = path.resolve(srcDir, file);
158
- const destFile = path.resolve(destDir, file);
159
- copy(srcFile, destFile);
160
- }
161
- }
93
+ // copy boilerplate to output dir
94
+ const templateDir = path.resolve(__dirname, '../../repo-template');
95
+ fs.cpSync(templateDir, outDir, { recursive: true });
162
96
 
163
- const write = (file, content) => {
164
- const targetPath = path.join(outDir, renameFiles[file] ?? file);
165
- if (content) {
166
- fs.writeFileSync(targetPath, content);
167
- } else {
168
- copy(path.join(templateDir, file), targetPath);
169
- }
170
- };
171
-
172
- copy(templateGlobalsDir, outDir);
173
-
174
- const files = fs.readdirSync(templateDir);
175
- for (const file of files.filter((f) => f !== 'package.json')) {
176
- write(file);
177
- }
178
-
179
- // create package.json
180
- const pkg = JSON.parse(
181
- fs.readFileSync(path.join(templateDir, 'package.json'), 'utf-8')
182
- );
97
+ // Update new package.json
98
+ const pkg = JSON.parse(fs.readFileSync(path.join(outDir, 'package.json'), 'utf-8'));
183
99
  pkg.name = `madgex-${clientPropertyId}`;
100
+ pkg.devDependencies['@madgex/fert'] = `^${fertPackageJSON.version}`;
184
101
  pkg.description = `Branding repo for ${clientProperties.brandName}`;
185
- write('package.json', JSON.stringify(pkg, null, 2) + '\n');
186
-
187
- // create fert.config.js
188
- const fertConfigJs = fs.readFileSync(
189
- path.join(outDir, FERT_CONFIG_FILENAME),
190
- 'utf-8'
191
- );
192
- write(
193
- FERT_CONFIG_FILENAME,
194
- fertConfigJs.replace(/{CPID}/gi, clientPropertyId)
195
- );
102
+ pkg.repository.url = `git+https://github.com/wiley/madgex-${clientPropertyId}.git`;
103
+ pkg.homepage = `https://github.com/wiley/madgex-${clientPropertyId}#readme`;
104
+ fs.writeFileSync(path.join(outDir, 'package.json'), JSON.stringify(pkg, null, 2) + '\n');
105
+
106
+ // Update fert.config.js
107
+ const fertConfigPath = path.join(outDir, FERT_CONFIG_FILENAME);
108
+ const fertConfigJs = fs.readFileSync(fertConfigPath, 'utf-8');
109
+ fs.writeFileSync(fertConfigPath, fertConfigJs.replace(/{CPID}/gi, clientPropertyId));
196
110
 
197
111
  const cdProjectName = path.relative(cwd, outDir);
198
112
 
199
113
  console.log(`\nDone. Now run:\n`);
200
114
 
201
115
  if (cdProjectName && root !== cwd) {
202
- console.log(
203
- ` cd ${
204
- cdProjectName.includes(' ') ? `"${cdProjectName}"` : cdProjectName
205
- }`
206
- );
116
+ console.log(` cd ${cdProjectName.includes(' ') ? `"${cdProjectName}"` : cdProjectName}`);
207
117
  }
208
118
 
209
119
  console.log(` npm install`);
@@ -19,10 +19,7 @@ module.exports = class AssetStoreUploader {
19
19
  }
20
20
 
21
21
  buildAbsolutePath(relativePath, ...parts) {
22
- return new URL(
23
- path.posix.join(this.basePath, relativePath, ...parts),
24
- this.apiUrl
25
- );
22
+ return new URL(path.posix.join(this.basePath, relativePath, ...parts), this.apiUrl);
26
23
  }
27
24
 
28
25
  async upload(file, dest) {
@@ -106,7 +103,7 @@ module.exports = class AssetStoreUploader {
106
103
  log.info(
107
104
  `CloudFront cache invalidation sent for the following paths${
108
105
  distributionId ? ` (distribution id: ${distributionId})` : ''
109
- }:\n${JSON.stringify(paths)}\n`
106
+ }:\n${JSON.stringify(paths)}\n`,
110
107
  );
111
108
  }
112
109
  // Returns array of all files in provided directory (recursive)
@@ -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
  }