-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
handle_files.ts
126 lines (106 loc) · 3.5 KB
/
handle_files.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* Copyright (c) Crew Dev.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { isLocalFile, newVersion } from "../tools/logs.ts";
import { KillProcess } from "../tools/kill_process.ts";
import type { objectGen } from "../utils/types.ts";
import { createHash } from "../utils/storage.ts";
import { LogPackages } from "../utils/logs.ts";
import { exists, writeJson } from "tools-fs";
import { Config } from "./global_configs.ts";
import Store from "./handler_storage.ts";
/**
* takes the import map file and returns its information.
* @return {string} string.
*/
export async function getImportMap<T extends any>(): Promise<T | undefined> {
if (await exists(`./${Config.getConfig("importMap")}`)) {
const decoder = new TextDecoder("utf-8");
// * get data from import_map and return data
const Package = await Deno.readFile(`./${Config.getConfig("importMap")}`);
return JSON.parse(decoder.decode(Package)) as T;
}
}
/**
* sort the packages in the import map file in alphabetical order.
* @param {object} map - object that contains all the packages.
* @return {object} the ordered object.
*/
function sortedPackage(map: any): objectGen {
return Object.keys(map)
.sort()
.reduce((result: objectGen, key) => {
result[key] = map[key];
return result;
}, {});
}
/**
* if the import map file does not exist create it and add the packages.
* @param {object} map - the object with all the packages.
* @param {boolean} log - parameter to display a message after installation.
* @return void
*/
export async function createPackage(map: objectGen, log?: boolean) {
// add virtual lock hash
for (const [pkg, url] of Object.entries(map)) {
if (url.startsWith("npm:")) continue;
await Store.setItem(`internal__trex__hash:${pkg}`, await generateHash(url));
}
// * create import_map.json
const create = await Deno.create(`./${Config.getConfig("importMap")}`);
create.close();
// * write import config inside import_map.json
await writeJson(
`./${Config.getConfig("importMap")}`,
{ imports: sortedPackage(map) },
{ spaces: 2 },
);
if (log) {
LogPackages(map);
// kill opened process
KillProcess(Deno.resources());
// show notification if exist a new version avaliable
await newVersion();
}
}
/**
* reads the content of a path either local or remote and returns it in string format
* @param path string
*/
async function readURLContent(path: string) {
if (new RegExp("^https?://[a-z.]").test(path)) {
const data = await fetch(path);
const text = await data.text();
return text;
} else {
// ignore no external deps
if (isLocalFile(path)) return "DEFAULT";
const decoder = new TextDecoder("utf-8");
const buffer = await Deno.readFile(path);
return decoder.decode(buffer);
}
}
/**
* generates a hash fingerprint based on url and file content
* @param url string
*/
export async function generateHash(url: string) {
const hash = await createHash("SHA-256", (await readURLContent(url)) + url);
return hash;
}
/**
* verifies that a hash fingerprint is valid
* @param url string
* @param hash string
*/
export async function validateHash(url: string, hash: string) {
const isNew = Object.keys(await Store.getStorage()).some((key) =>
key.startsWith("internal__trex__hash:")
);
if (!isNew) return true;
const _hash = await createHash("SHA-256", (await readURLContent(url)) + url);
return _hash.toString() === hash;
}