@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
package/README.md CHANGED
@@ -149,10 +149,9 @@ When faced with an empty branding repo, this will help the user get started with
149
149
 
150
150
  **Options**
151
151
 
152
- | Option | |
153
- | ----------------------- | ------------------------------------------------------ |
154
- | `--template <template>` | Specify the template you wish to use when scaffolding |
155
- | `--cpid <cpid>` | Specify the clientPropertyId to use in the new project |
152
+ | Option | |
153
+ | --------------- | ------------------------------------------------------ |
154
+ | `--cpid <cpid>` | Specify the clientPropertyId to use in the new project |
156
155
 
157
156
  **Outline of implementation**
158
157
 
@@ -327,7 +326,7 @@ Each change that's pushed to a branch will trigger:
327
326
  2. The [jenkinsfile](https://github.com/wiley/madgex-jenkins-shared-library/blob/master/vars/clientRepoDeploymentPipeline.groovy) pipeline will run `fert publish` to send all built assets to the Asset Store API.
328
327
  3. The [jenkinsfile](https://github.com/wiley/madgex-jenkins-shared-library/blob/master/vars/clientRepoDeploymentPipeline.groovy) pipeline will run `fert configs --publish`, Uploading the branding repo's client `/configs` to the configuration-api.
329
328
 
330
- > [!NOTE]
329
+ > [!NOTE] > `master` branch will go to `production`. All other branches will go to `jb dev`.
331
330
  > `master` branch will go to `production`. All other branches will go to `jb dev`.
332
331
 
333
332
  ## `npm scripts`
package/bin/cli.js CHANGED
@@ -6,18 +6,13 @@ const cli = require('cac')('fert');
6
6
  const { VERSION } = require('../constants');
7
7
  const { printBanner } = require('./utils/index.js');
8
8
 
9
- const {
10
- serivceCommandBootstrap,
11
- } = require('./commands/_service-command-bootstrap.js');
9
+ const { serivceCommandBootstrap } = require('./commands/_service-command-bootstrap.js');
12
10
 
13
11
  const run = () => {
14
12
  printBanner();
15
13
 
16
14
  cli
17
- .command(
18
- '',
19
- 'Start layout server. Can supply a branding directory if running FERT standalone'
20
- )
15
+ .command('', 'Start layout server. Can supply a branding directory if running FERT standalone')
21
16
  .alias('dev')
22
17
  .option('--open', 'Automatically open the dev server in your browser')
23
18
  .option('--host [host]', '[string] specify hostname')
@@ -26,10 +21,7 @@ const run = () => {
26
21
  .action((...args) => serivceCommandBootstrap('dev', ...args));
27
22
 
28
23
  cli
29
- .command(
30
- 'build',
31
- 'Build project. Can supply a branding directory if running FERT standalone'
32
- )
24
+ .command('build', 'Build project. Can supply a branding directory if running FERT standalone')
33
25
  .option('--only <task>', `Only run part of the build [ 'assets', 'tokens']`)
34
26
  .option('--config [dir]', 'Use custom rollup config file')
35
27
  .option('--service-name <serviceName>', '[string] run a single service')
@@ -37,37 +29,24 @@ const run = () => {
37
29
 
38
30
  cli
39
31
  .command('publish', 'Publish the project')
40
- .option(
41
- '--target <env>',
42
- 'Environment to publish to, "dev" or "production"'
43
- )
32
+ .option('--target <env>', 'Environment to publish to, "dev" or "production"')
44
33
  .option('--service-name <serviceName>', '[string] run a single service')
45
34
  .option('--dry-run', 'Dry run, dont actually upload anything')
46
35
  .action((...args) => serivceCommandBootstrap('publish', ...args));
47
36
 
48
37
  cli
49
38
  .command('configs', 'Query/Publish project configs')
50
- .option(
51
- '--publish <env>',
52
- 'Publish configs to Configuration API environment "dev" or "production"'
53
- )
39
+ .option('--publish <env>', 'Publish configs to Configuration API environment "dev" or "production"')
54
40
  .option(
55
41
  '--download <env>',
56
- 'Download known configs from the Configuration API for environment "dev" or "production"'
57
- )
58
- .option(
59
- '--query [configName]',
60
- 'Describe known keys for a config, omit to list all known configs'
42
+ 'Download known configs from the Configuration API for environment "dev" or "production"',
61
43
  )
44
+ .option('--query [configName]', 'Describe known keys for a config, omit to list all known configs')
62
45
  .action((...args) => require('./commands/configs')(...args));
63
46
 
64
47
  cli
65
48
  .command('init [root]', 'Create a new branding project')
66
- .option('--template <template>', 'Template to use when scaffolding project')
67
- .option(
68
- '--cpid <cpid>',
69
- 'Specify the clientPropertyId to use in the new project'
70
- )
49
+ .option('--cpid <cpid>', 'Specify the clientPropertyId to use in the new project')
71
50
  .action((...args) => require('./commands/init')(...args));
72
51
 
73
52
  cli.option('--no-cache', 'Do not use cache');
@@ -92,6 +71,6 @@ try {
92
71
  } else {
93
72
  console.error(error);
94
73
  }
95
-
74
+ // eslint-disable-next-line n/no-process-exit
96
75
  process.exit(1);
97
76
  }
@@ -1,9 +1,6 @@
1
1
  const chalk = require('chalk');
2
2
 
3
- const {
4
- loadServiceConfigFiles,
5
- loadConfigFromFile,
6
- } = require('../utils/index.js');
3
+ const { loadServiceConfigFiles, loadConfigFromFile } = require('../utils/index.js');
7
4
 
8
5
  const commandDevSever = require('./dev-server.js');
9
6
  const commandBuild = require('./build.js');
@@ -21,10 +18,7 @@ const commandMap = {
21
18
  * determine if we are running a single service, otherwise search for all services
22
19
  * Then run command
23
20
  */
24
- module.exports.serivceCommandBootstrap = async function serivceCommandBootstrap(
25
- command,
26
- options
27
- ) {
21
+ module.exports.serivceCommandBootstrap = async function serivceCommandBootstrap(command, options) {
28
22
  // explicitly run a single service - via CLI option
29
23
  if (options.serviceName) {
30
24
  console.log(`🔦 ${chalk.green('Running single service mode')}`);
@@ -62,7 +56,7 @@ module.exports.serivceCommandBootstrap = async function serivceCommandBootstrap(
62
56
  }
63
57
 
64
58
  console.log(
65
- `🔦 ${chalk.green('Running multi service mode')}, calling ${chalk.cyan(command)} on ${chalk.cyan(serviceConfigs.length)} ${serviceConfigs.length === 1 ? 'service' : 'services'} [${serviceConfigs.map((i) => chalk.cyanBright(i?.serviceConfig?.serviceName || 'Unknown')).join(', ')}]`
59
+ `🔦 ${chalk.green('Running multi service mode')}, calling ${chalk.cyan(command)} on ${chalk.cyan(serviceConfigs.length)} ${serviceConfigs.length === 1 ? 'service' : 'services'} [${serviceConfigs.map((i) => chalk.cyanBright(i?.serviceConfig?.serviceName || 'Unknown')).join(', ')}]`,
66
60
  );
67
61
 
68
62
  for (const { serviceConfig } of serviceConfigs) {
@@ -72,10 +66,9 @@ module.exports.serivceCommandBootstrap = async function serivceCommandBootstrap(
72
66
  serviceName: serviceConfig.serviceName,
73
67
  });
74
68
  } catch (err) {
75
- throw new Error(
76
- `Failed to run command ${command} on service ${serviceConfig.serviceName}: ${err.message}`,
77
- { cause: err }
78
- );
69
+ throw new Error(`Failed to run command ${command} on service ${serviceConfig.serviceName}: ${err.message}`, {
70
+ cause: err,
71
+ });
79
72
  }
80
73
  }
81
74
  };
@@ -1,17 +1,13 @@
1
1
  const Path = require('node:path');
2
2
  const fs = require('node:fs/promises');
3
3
  const StyleDictionaryPackage = require('style-dictionary');
4
- const {
5
- registerTransforms,
6
- } = require('@madgex/design-system/tasks/registerTransforms');
4
+ const { registerTransforms } = require('@madgex/design-system/tasks/registerTransforms');
7
5
  const colorTransforms = require('@madgex/design-system/tasks/colorTransforms');
8
6
  const { ensureTrailingSlash, exists } = require('../../utils');
9
7
  const { log } = require('../../utils/logging');
10
8
  const { TMP_DIR } = require('../../../constants');
11
9
 
12
- const dsTokensPath = Path.dirname(
13
- require.resolve('@madgex/design-system/src/tokens/_config.js')
14
- );
10
+ const dsTokensPath = Path.dirname(require.resolve('@madgex/design-system/src/tokens/_config.js'));
15
11
 
16
12
  // eslint-disable-next-line no-unused-vars
17
13
  const createTempBrandFile = async (dir = './') => {
@@ -35,9 +31,9 @@ async function runSilently(fn) {
35
31
  console.log = originalLog;
36
32
  }
37
33
 
38
- module.exports = async function buildCssFromTokens(srcTokensPath, buildPath) {
39
- srcTokensPath = ensureTrailingSlash(Path.resolve(srcTokensPath));
40
- buildPath = ensureTrailingSlash(Path.resolve(buildPath));
34
+ module.exports = async function buildCssFromTokens(_srcTokensPath, _buildPath) {
35
+ const srcTokensPath = ensureTrailingSlash(Path.resolve(_srcTokensPath));
36
+ const buildPath = ensureTrailingSlash(Path.resolve(_buildPath));
41
37
 
42
38
  const brandFile = Path.join(srcTokensPath, 'brand.json');
43
39
 
@@ -46,24 +42,14 @@ module.exports = async function buildCssFromTokens(srcTokensPath, buildPath) {
46
42
  }
47
43
 
48
44
  // Fetch the file so we can transform the colours in style dictionary
49
- const brandObj = JSON.parse(
50
- await fs.readFile(brandFile, { encoding: 'utf8' })
51
- );
45
+ const brandObj = JSON.parse(await fs.readFile(brandFile, { encoding: 'utf8' }));
52
46
  const tmpBrandFile = await createTempBrandFile(srcTokensPath);
53
47
 
54
- await fs.writeFile(
55
- Path.join(tmpBrandFile),
56
- JSON.stringify(colorTransforms(brandObj))
57
- );
48
+ await fs.writeFile(Path.join(tmpBrandFile), JSON.stringify(colorTransforms(brandObj)));
58
49
 
59
50
  // TODO - Investigate whether we can retrieve from DS instead of redefining
60
51
  // e.g. const { registerTransforms } = require('@madgex/design-system/tasks/registerTransforms');
61
- const transforms = [
62
- 'attribute/cti',
63
- 'name/cti/kebab',
64
- 'color/css',
65
- 'css/rawData',
66
- ];
52
+ const transforms = ['attribute/cti', 'name/cti/kebab', 'color/css', 'css/rawData'];
67
53
  const prefix = 'mds';
68
54
 
69
55
  // TODO - Investigate whether we can retrieve from DS instead of redefining
@@ -21,10 +21,7 @@ module.exports = async (fertConfig, options = {}) => {
21
21
  cssCodeSplit: false, // important: to get a single, style.css file output
22
22
  outDir: path.resolve(fertConfig.workingDir, 'dist'),
23
23
  rollupOptions: {
24
- input: path.resolve(
25
- fertConfig.workingDir,
26
- fertConfig.entry || './src/index.js'
27
- ),
24
+ input: path.resolve(fertConfig.workingDir, fertConfig.entry || './src/index.js'),
28
25
  },
29
26
  },
30
27
  };
@@ -34,6 +34,7 @@ module.exports = async (options = {}) => {
34
34
  }
35
35
  };
36
36
 
37
+ // eslint-disable-next-line n/no-exports-assign
37
38
  exports = module.exports; // allow default export & { named } exports
38
39
 
39
40
  // eslint-disable-next-line no-unused-vars
@@ -12,9 +12,7 @@ const handleDownload = async ({ workingDir }, api, options) => {
12
12
  const validTargets = ['dev', 'production'];
13
13
 
14
14
  if (!validTargets.includes(options.download)) {
15
- throw new Error(
16
- `Missing or invalid --download option. Choose from [${validTargets}]`
17
- );
15
+ throw new Error(`Missing or invalid --download option. Choose from [${validTargets}]`);
18
16
  }
19
17
 
20
18
  const spinner = ora('Downloading v6 configs...').start();
@@ -53,7 +51,7 @@ const handleDownload = async ({ workingDir }, api, options) => {
53
51
  } catch (error) {
54
52
  log.debug(
55
53
  `Unable to retrieve ${chalk.cyan(error.url || schemaName + '/' + configKey)}`,
56
- error.message || error.statusText || error
54
+ error.message || error.statusText || error,
57
55
  );
58
56
  }
59
57
  }
@@ -61,9 +59,7 @@ const handleDownload = async ({ workingDir }, api, options) => {
61
59
 
62
60
  spinner.succeed();
63
61
  } catch (error) {
64
- spinner.fail(
65
- `Error ${error.code ? `[${error.code}]` : ''}: ${error.message}`
66
- );
62
+ spinner.fail(`Error ${error.code ? `[${error.code}]` : ''}: ${error.message}`);
67
63
  throw error;
68
64
  }
69
65
 
@@ -83,17 +79,11 @@ const handleDownload = async ({ workingDir }, api, options) => {
83
79
  }
84
80
  };
85
81
 
86
- const handlePublish = async (
87
- { workingDir, clientPropertyId },
88
- api,
89
- options
90
- ) => {
82
+ const handlePublish = async ({ workingDir, clientPropertyId }, api, options) => {
91
83
  const validTargets = ['dev', 'production'];
92
84
 
93
85
  if (!validTargets.includes(options.publish)) {
94
- throw new Error(
95
- `Missing or invalid --publish option. Choose from [${validTargets}]`
96
- );
86
+ throw new Error(`Missing or invalid --publish option. Choose from [${validTargets}]`);
97
87
  }
98
88
 
99
89
  try {
@@ -104,34 +94,23 @@ const handlePublish = async (
104
94
  });
105
95
  } catch (err) {
106
96
  log.debug(err);
97
+ // eslint-disable-next-line n/no-process-exit
107
98
  process.exit(1);
108
99
  }
109
100
  };
110
101
 
111
- const handleQuery = async (
112
- /* { workingDir, clientPropertyId } */ _,
113
- api,
114
- options
115
- ) => {
102
+ const handleQuery = async (/* { workingDir, clientPropertyId } */ _, api, options) => {
116
103
  try {
117
104
  if (options.query !== true) {
118
- console.log(
119
- chalk.cyan(
120
- `\nGetting schema description for config: ${chalk.bold(options.query)}...`
121
- )
122
- );
105
+ console.log(chalk.cyan(`\nGetting schema description for config: ${chalk.bold(options.query)}...`));
123
106
  const schema = api.schemas[options.query];
124
107
  if (!schema) {
125
- console.error(
126
- chalk.red(`Schema not found for ${chalk.bold(options.query)}`)
127
- );
108
+ console.error(chalk.red(`Schema not found for ${chalk.bold(options.query)}`));
128
109
  return;
129
110
  }
130
111
 
131
112
  console.log(JSON.stringify(schema.describe().keys, null, 2));
132
- console.log(
133
- `\n${chalk.cyan('Configs default values')}:\n${JSON.stringify(schema.validate({}).value, null, 2)}`
134
- );
113
+ console.log(`\n${chalk.cyan('Configs default values')}:\n${JSON.stringify(schema.validate({}).value, null, 2)}`);
135
114
  return;
136
115
  }
137
116
 
@@ -141,14 +120,13 @@ const handleQuery = async (
141
120
  .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
142
121
  .map((key) => ` * ${key}`)
143
122
  .join('\n'),
144
- '\n'
123
+ '\n',
145
124
  );
146
125
 
147
- console.log(
148
- 'Use `fert configs <configName>` to get a specific schema description'
149
- );
126
+ console.log('Use `fert configs <configName>` to get a specific schema description');
150
127
  } catch (err) {
151
128
  log.debug(err);
129
+ // eslint-disable-next-line n/no-process-exit
152
130
  process.exit(1);
153
131
  }
154
132
  };
@@ -165,30 +143,16 @@ module.exports = async (options) => {
165
143
  });
166
144
 
167
145
  if (!options.publish && !options.query && !options.download) {
168
- console.log(
169
- chalk.red(`Missing required --publish, --query or --download option`)
170
- );
146
+ console.log(chalk.red(`Missing required --publish, --query or --download option`));
171
147
  return;
172
148
  }
173
149
 
174
150
  if (options.download) {
175
- await handleDownload(
176
- { clientPropertyId, workingDir: fertConfigDir },
177
- api,
178
- options
179
- );
151
+ await handleDownload({ clientPropertyId, workingDir: fertConfigDir }, api, options);
180
152
  } else if (options.publish) {
181
- await handlePublish(
182
- { clientPropertyId, workingDir: fertConfigDir },
183
- api,
184
- options
185
- );
153
+ await handlePublish({ clientPropertyId, workingDir: fertConfigDir }, api, options);
186
154
  } else if (options.query) {
187
- await handleQuery(
188
- { clientPropertyId, workingDir: fertConfigDir },
189
- api,
190
- options
191
- );
155
+ await handleQuery({ clientPropertyId, workingDir: fertConfigDir }, api, options);
192
156
  }
193
157
  };
194
158
 
@@ -7,21 +7,15 @@ const { log } = require('../utils/logging.js');
7
7
  const { validateLocalConfigs } = require('../utils/configs.js');
8
8
  const { devServer } = require('../../server');
9
9
  const { buildTokens, buildExternalAssets } = require('./build.js');
10
- const {
11
- BRAND_JSON_FILENAME,
12
- FERT_CONFIG_FILENAME,
13
- FERT_SERVICE_CONFIG_FILENAME,
14
- } = require('../../constants.js');
10
+ const { BRAND_JSON_FILENAME, FERT_CONFIG_FILENAME, FERT_SERVICE_CONFIG_FILENAME } = require('../../constants.js');
15
11
 
16
12
  module.exports = async (options = {}) => {
17
13
  let fertConfig = await resolveConfig(options);
18
14
 
19
15
  console.log(
20
- `Starting branding server for ${chalk.green(
21
- fertConfig.client.brandName
22
- )} [${fertConfig.serviceName}] ${chalk.dim(
23
- `(${fertConfig.clientPropertyId})`
24
- )}\n`
16
+ `Starting branding server for ${chalk.green(fertConfig.client.brandName)} [${fertConfig.serviceName}] ${chalk.dim(
17
+ `(${fertConfig.clientPropertyId})`,
18
+ )}\n`,
25
19
  );
26
20
 
27
21
  await validateLocalConfigs({
@@ -50,10 +44,7 @@ module.exports = async (options = {}) => {
50
44
  });
51
45
 
52
46
  const configPath = path.resolve(fertConfigDir, FERT_CONFIG_FILENAME);
53
- const serviceConfigPath = path.resolve(
54
- fertConfig.workingDir,
55
- FERT_SERVICE_CONFIG_FILENAME
56
- );
47
+ const serviceConfigPath = path.resolve(fertConfig.workingDir, FERT_SERVICE_CONFIG_FILENAME);
57
48
  chokidar.watch([configPath, serviceConfigPath]).on('change', async () => {
58
49
  console.log('Config changed, reloading…');
59
50
  fertConfig = await resolveConfig(options);
@@ -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)