@alwaysmeticulous/downloading-helpers 2.42.0 → 2.43.0
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.
|
@@ -15,6 +15,7 @@ export interface LoadOrDownloadJsonFileOptions<T> {
|
|
|
15
15
|
* Handles concurrent processes trying to download to the same file at the same time.
|
|
16
16
|
*/
|
|
17
17
|
export declare const getOrDownloadJsonFile: <T>({ filePath, downloadJson, dataDescription, }: LoadOrDownloadJsonFileOptions<T>) => Promise<T | null>;
|
|
18
|
+
export declare const waitToAcquireLockOnFile: (filePath: string) => Promise<ReleaseLock>;
|
|
18
19
|
export declare const fileExists: (filePath: string) => Promise<boolean>;
|
|
19
20
|
export declare const waitToAcquireLockOnDirectory: (directoryPath: string) => Promise<ReleaseLock>;
|
|
20
21
|
export {};
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.waitToAcquireLockOnDirectory = exports.fileExists = exports.getOrDownloadJsonFile = exports.sanitizeFilename = void 0;
|
|
6
|
+
exports.waitToAcquireLockOnDirectory = exports.fileExists = exports.waitToAcquireLockOnFile = exports.getOrDownloadJsonFile = exports.sanitizeFilename = void 0;
|
|
7
7
|
const promises_1 = require("fs/promises");
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const common_1 = require("@alwaysmeticulous/common");
|
|
@@ -27,7 +27,7 @@ const getOrDownloadJsonFile = async ({ filePath, downloadJson, dataDescription,
|
|
|
27
27
|
// time they don't interfere with each other. The second process to run will
|
|
28
28
|
// wait for the first process to complete, and then return straight away because
|
|
29
29
|
// it'll notice the file already exists.
|
|
30
|
-
const releaseLock = await waitToAcquireLockOnFile(filePath);
|
|
30
|
+
const releaseLock = await (0, exports.waitToAcquireLockOnFile)(filePath);
|
|
31
31
|
try {
|
|
32
32
|
const existingData = await (0, promises_1.readFile)(filePath)
|
|
33
33
|
.then((data) => JSON.parse(data.toString("utf-8")))
|
|
@@ -68,6 +68,7 @@ const waitToAcquireLockOnFile = async (filePath) => {
|
|
|
68
68
|
await releaseLock();
|
|
69
69
|
};
|
|
70
70
|
};
|
|
71
|
+
exports.waitToAcquireLockOnFile = waitToAcquireLockOnFile;
|
|
71
72
|
const fileExists = (filePath) => (0, promises_1.access)(filePath)
|
|
72
73
|
.then(() => true)
|
|
73
74
|
.catch(() => false);
|
|
@@ -10,32 +10,43 @@ const common_1 = require("@alwaysmeticulous/common");
|
|
|
10
10
|
const axios_1 = __importDefault(require("axios"));
|
|
11
11
|
const loglevel_1 = __importDefault(require("loglevel"));
|
|
12
12
|
const snippets_1 = require("../config/snippets");
|
|
13
|
+
const local_data_utils_1 = require("../file-downloads/local-data.utils");
|
|
13
14
|
const ASSETS_FOLDER_NAME = "assets";
|
|
14
15
|
const ASSET_METADATA_FILE_NAME = "assets.json";
|
|
15
16
|
const fetchAsset = async (path) => {
|
|
16
17
|
const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
|
|
17
18
|
const fetchUrl = new URL(path, (0, snippets_1.getSnippetsBaseUrl)()).href;
|
|
18
19
|
const assetFileName = `${(0, path_1.basename)(new URL(fetchUrl).pathname, ".js")}.cjs`;
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const releaseLock = await (0, local_data_utils_1.waitToAcquireLockOnFile)(await getAssetsFilePath());
|
|
21
|
+
try {
|
|
22
|
+
const assetMetadata = await loadAssetMetadata();
|
|
23
|
+
const etag = (await axios_1.default.head(fetchUrl)).headers["etag"] || "";
|
|
24
|
+
const entry = assetMetadata.assets.find((item) => item.fileName === assetFileName);
|
|
25
|
+
const filePath = (0, path_1.join)(await getOrCreateAssetsDir(), assetFileName);
|
|
26
|
+
if (entry && etag !== "" && etag === entry.etag) {
|
|
27
|
+
logger.debug(`${fetchUrl} already present`);
|
|
28
|
+
releaseLock();
|
|
29
|
+
return filePath;
|
|
30
|
+
}
|
|
31
|
+
const contents = (await axios_1.default.get(fetchUrl)).data;
|
|
32
|
+
await (0, promises_1.writeFile)(filePath, contents);
|
|
33
|
+
if (entry) {
|
|
34
|
+
logger.debug(`${fetchUrl} updated`);
|
|
35
|
+
entry.etag = etag;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
logger.debug(`${fetchUrl} downloaded`);
|
|
39
|
+
assetMetadata.assets.push({ fileName: assetFileName, etag, fetchUrl });
|
|
40
|
+
}
|
|
41
|
+
await saveAssetMetadata(assetMetadata);
|
|
42
|
+
releaseLock();
|
|
25
43
|
return filePath;
|
|
26
44
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
entry.etag = etag;
|
|
45
|
+
catch (err) {
|
|
46
|
+
releaseLock();
|
|
47
|
+
logger.error(`Error fetching asset from ${fetchUrl}`);
|
|
48
|
+
throw err;
|
|
32
49
|
}
|
|
33
|
-
else {
|
|
34
|
-
logger.debug(`${fetchUrl} downloaded`);
|
|
35
|
-
assetMetadata.assets.push({ fileName: assetFileName, etag, fetchUrl });
|
|
36
|
-
}
|
|
37
|
-
await saveAssetMetadata(assetMetadata);
|
|
38
|
-
return filePath;
|
|
39
50
|
};
|
|
40
51
|
exports.fetchAsset = fetchAsset;
|
|
41
52
|
const getOrCreateAssetsDir = async () => {
|
|
@@ -44,7 +55,7 @@ const getOrCreateAssetsDir = async () => {
|
|
|
44
55
|
return assetsDir;
|
|
45
56
|
};
|
|
46
57
|
const loadAssetMetadata = async () => {
|
|
47
|
-
const assetsFile =
|
|
58
|
+
const assetsFile = await getAssetsFilePath();
|
|
48
59
|
const existingMetadata = await (0, promises_1.readFile)(assetsFile)
|
|
49
60
|
.then((data) => JSON.parse(data.toString("utf-8")))
|
|
50
61
|
.catch(() => null);
|
|
@@ -57,3 +68,7 @@ const saveAssetMetadata = async (assetMetadata) => {
|
|
|
57
68
|
const assetsFile = (0, path_1.join)(await getOrCreateAssetsDir(), ASSET_METADATA_FILE_NAME);
|
|
58
69
|
await (0, promises_1.writeFile)(assetsFile, JSON.stringify(assetMetadata, null, 2));
|
|
59
70
|
};
|
|
71
|
+
const getAssetsFilePath = async () => {
|
|
72
|
+
const assetsDir = await getOrCreateAssetsDir();
|
|
73
|
+
return (0, path_1.join)(assetsDir, ASSET_METADATA_FILE_NAME);
|
|
74
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwaysmeticulous/downloading-helpers",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.43.0",
|
|
4
4
|
"description": "Helper utilities for downloading files & scripts required to execute replays",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"bugs": {
|
|
51
51
|
"url": "https://github.com/alwaysmeticulous/meticulous-sdk/issues"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "7664f4dfeed3b08e5523c0acb4d98d11eee4c9ff"
|
|
54
54
|
}
|