@madgex/fert 7.0.13 → 7.0.14

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.
@@ -1,8 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import * as Hoek from '@hapi/hoek';
4
- import axios from 'axios';
5
- import FormData from 'form-data';
6
4
  import ora from 'ora';
7
5
  import chalk from 'chalk';
8
6
  import { log } from '../../utils/logging.js';
@@ -27,43 +25,52 @@ export class AssetStoreUploader {
27
25
  const label = absoluteUrl.pathname;
28
26
 
29
27
  log.debug('upload', { file, dest, absoluteUrl });
30
-
28
+ // `openAsBlob` returns a "File-backend" Blob, not in memory
29
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
30
+ const fileBackedBlob = await fs.openAsBlob(file);
31
31
  const form = new FormData();
32
- form.append('data', fs.createReadStream(file));
32
+ form.append('data', fileBackedBlob, path.basename(file));
33
33
  form.append('invalidateCache', 'false'); // opt out as will invalidate whole path (*) at end
34
34
  form.append('modifiedById', ASSET_STORE_USER_GUID);
35
35
 
36
36
  const spinner = ora(`${chalk.yellow('Uploading')}: ${label}`).start();
37
37
 
38
- return axios
39
- .put(absoluteUrl.href, form, {
38
+ try {
39
+ const res = await fetch(absoluteUrl.href, {
40
+ method: 'put',
40
41
  headers: {
41
42
  apikey: this.apiKey,
42
- ...form.getHeaders(),
43
43
  },
44
- })
45
- .then(() => {
46
- spinner.succeed(`${label}`);
47
- })
48
- .catch((err) => {
49
- spinner.fail(`Failed to upload '${label}':`, err.message);
50
-
51
- throw err;
44
+ body: form,
52
45
  });
46
+ if (!res.ok) {
47
+ const resText = await res.text();
48
+ throw new Error(`${res.status} - ${resText}`);
49
+ }
50
+
51
+ spinner.succeed(`${label}`);
52
+ } catch (err) {
53
+ spinner.fail(`Failed to upload '${label}':`, err.message);
54
+
55
+ throw err;
56
+ }
53
57
  }
54
58
 
55
- async uploadDir(dir, dest = false) {
59
+ async uploadDir(dir, dryRun = false) {
56
60
  Hoek.assert(dir, 'dir missing');
57
61
 
58
62
  const start = process.hrtime();
59
- const files = this._getFilesFromDir(dir);
63
+ const files = await this._getFilesFromDir(dir);
60
64
 
61
65
  // Send files consecutively to avoid straining the api
62
66
  for (const file of files) {
63
67
  const relativeName = path.posix.relative(dir, file);
64
- const remotePath = path.posix.dirname(dest || relativeName);
65
-
66
- await this.upload(file, remotePath);
68
+ const remotePath = path.posix.dirname(relativeName);
69
+ if (!dryRun) {
70
+ await this.upload(file, remotePath);
71
+ } else {
72
+ log.info('(Dry run) Uploading', file, 'to => ', remotePath);
73
+ }
67
74
  }
68
75
 
69
76
  const end = process.hrtime(start);
@@ -94,10 +101,13 @@ export class AssetStoreUploader {
94
101
  payload.distributionId = distributionId;
95
102
  }
96
103
 
97
- await axios.post(invalidateUrl.href, payload, {
104
+ await fetch(invalidateUrl.href, {
105
+ method: 'post',
98
106
  headers: {
99
107
  apikey: this.apiKey,
108
+ 'Content-Type': 'application/json',
100
109
  },
110
+ body: JSON.stringify(payload),
101
111
  });
102
112
 
103
113
  log.info(
@@ -106,18 +116,13 @@ export class AssetStoreUploader {
106
116
  }:\n${JSON.stringify(paths)}\n`,
107
117
  );
108
118
  }
109
- // Returns array of all files in provided directory (recursive)
110
- _getFilesFromDir = (dir, files = []) => {
111
- fs.readdirSync(dir).forEach((entry) => {
112
- const name = path.join(dir, entry);
113
-
114
- if (fs.statSync(name).isDirectory()) {
115
- this._getFilesFromDir(name, files);
116
- } else {
117
- files.push(name);
118
- }
119
- });
120
-
121
- return files;
122
- };
119
+ /**
120
+ * Returns array of all files in provided directory (recursive), as absolute paths including filename.
121
+ */
122
+ async _getFilesFromDir(dir) {
123
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
124
+ const all = await Array.fromAsync(fs.promises.glob('**/*', { cwd: dir, withFileTypes: true })); // withFileTypes return dirent instead of strings
125
+ // only files, make sure output is array of absolute file path strings
126
+ return all.filter((dirent) => dirent.isFile()).map((dirent) => path.resolve(dirent.parentPath, dirent.name));
127
+ }
123
128
  }
@@ -57,10 +57,10 @@ export async function publish(options) {
57
57
  const localDir = path.resolve(fertConfig.workingDir, UPLOAD_DIR);
58
58
  const apiKeyParamPath = Hoek.reachTemplate(templateCtx, AWS_PARAM_NAME);
59
59
 
60
- const apiKey = await getAwsParam(apiKeyParamPath);
61
-
62
- const assetsPath = await getAssetsPath(fertConfig, options.target);
63
- const clientCloudFrontDists = await getCloudFrontDistributionsForDomain(assetsPath.hostname, options);
60
+ const [apiKey, assetsPath] = await Promise.all([
61
+ getAwsParam(apiKeyParamPath),
62
+ getAssetsPath(fertConfig, options.target),
63
+ ]);
64
64
 
65
65
  log.info(
66
66
  `\nPublishing ${chalk.cyan(localDir)} to ${chalk.green.bold(
@@ -76,18 +76,17 @@ export async function publish(options) {
76
76
  basePath: remoteBasePath,
77
77
  });
78
78
 
79
- let uploadResult;
80
- if (!options.dryRun) {
81
- uploadResult = await assetStore.uploadDir(localDir);
82
- }
79
+ const uploadResult = await assetStore.uploadDir(localDir, options.dryRun);
83
80
 
84
81
  log.success(`Publish complete in ${((uploadResult?.duration || 1) / 1000).toFixed(0)}s\n`);
85
82
 
86
83
  // invalidate cloudfront cache
87
- await assetStore.invalidatePaths([assetStoreInvPath]);
88
-
89
- for (let dist of clientCloudFrontDists) {
90
- await assetStore.invalidatePaths([`${assetsPath.pathname}/*`], dist.id);
84
+ if (!options.dryRun) {
85
+ await assetStore.invalidatePaths([assetStoreInvPath]);
86
+ const clientCloudFrontDists = await getCloudFrontDistributionsForDomain(assetsPath.hostname, options);
87
+ for (let dist of clientCloudFrontDists) {
88
+ await assetStore.invalidatePaths([`${assetsPath.pathname}/*`], dist.id);
89
+ }
91
90
  }
92
91
 
93
92
  log.info(`\nNote cloudfront invalidations may take upto ${chalk.yellow('30 seconds')} to complete.\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madgex/fert",
3
- "version": "7.0.13",
3
+ "version": "7.0.14",
4
4
  "description": "Tool to help build the V6 branding",
5
5
  "bin": {
6
6
  "fert": "./bin/cli.js"
@@ -24,47 +24,45 @@
24
24
  "author": "Madgex",
25
25
  "license": "UNLICENSED",
26
26
  "dependencies": {
27
- "@aws-sdk/client-cloudfront": "3.982.0",
28
- "@aws-sdk/client-ssm": "3.982.0",
29
- "@hapi/hapi": "21.4.4",
27
+ "@aws-sdk/client-cloudfront": "3.1017.0",
28
+ "@aws-sdk/client-ssm": "3.1017.0",
29
+ "@hapi/hapi": "21.4.7",
30
30
  "@hapi/hoek": "11.0.7",
31
31
  "@hapi/inert": "7.1.0",
32
32
  "@hapi/vision": "7.0.3",
33
33
  "@hapipal/toys": "4.0.0",
34
- "@madgex/config-api-sdk": "1.13.1",
35
- "@madgex/design-system": "13.2.1",
34
+ "@madgex/config-api-sdk": "1.16.0",
35
+ "@madgex/design-system": "13.5.1",
36
36
  "@private/header-footer-podlet-server": "github:wiley/madgex-header-footer-podlet",
37
- "axios": "1.13.2",
38
37
  "cac": "6.7.14",
39
38
  "chalk": "5.6.2",
40
39
  "chokidar5": "npm:chokidar@5.0.0",
41
40
  "debug": "4.4.3",
42
41
  "dedent": "1.7.1",
43
42
  "find-up-simple": "1.0.1",
44
- "flat-cache": "6.1.20",
45
- "form-data": "4.0.5",
46
- "joi": "18.0.2",
43
+ "flat-cache": "6.1.21",
44
+ "joi": "18.1.1",
47
45
  "nunjucks": "3.2.4",
48
46
  "open": "11.0.0",
49
47
  "ora": "5.4.1",
50
48
  "prompts": "2.4.2",
51
49
  "rimraf": "6.1.2",
52
- "sass": "1.97.3",
53
- "simple-git": "3.30.0",
50
+ "sass": "1.98.0",
51
+ "simple-git": "3.33.0",
54
52
  "simple-update-notifier": "2.0.0",
55
53
  "uuid-validate": "0.0.3",
56
54
  "vite": "7.3.1",
57
55
  "vite-plugin-static-copy": "3.2.0"
58
56
  },
59
57
  "devDependencies": {
60
- "@commitlint/cli": "20.4.1",
61
- "@commitlint/config-conventional": "20.4.1",
62
- "@madgex/eslint-config-madgex": "2.3.0",
63
- "@madgex/prettier-config-madgex": "2.0.0",
64
- "eslint": "9.39.2",
58
+ "@commitlint/cli": "20.5.0",
59
+ "@commitlint/config-conventional": "20.5.0",
60
+ "@madgex/eslint-config-madgex": "3.0.0",
61
+ "@madgex/prettier-config-madgex": "2.0.1",
62
+ "eslint": "10.1.0",
65
63
  "husky": "9.1.7",
66
- "lint-staged": "16.2.7",
67
- "msw": "^2.12.8",
64
+ "lint-staged": "16.4.0",
65
+ "msw": "^2.12.14",
68
66
  "prettier": "3.8.1",
69
67
  "semantic-release": "25.0.3"
70
68
  },
@@ -1,4 +1,4 @@
1
- FROM node:22-alpine
1
+ FROM node:24-alpine
2
2
 
3
3
  ENV HOME=/app/
4
4