-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
file_resolver.ts
113 lines (100 loc) 路 2.41 KB
/
file_resolver.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
/**
* 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 type { Fn } from "./types.ts";
/**
* match multiple cases
*/
export function Match<T extends any>(data: T) {
const cases: Array<{ condition: T | any; action?: Fn }> = [];
let once = true;
return {
case(condition: T, action: Fn) {
cases.push({ condition, action });
return this;
},
default(action?: Fn) {
if (once) {
cases.push({ condition: "DEFAULT", action });
once = false;
}
return {
Value() {
const value = cases
.map(({ action, condition }) => {
if (condition === data) {
return action?.();
}
})
.filter((val) => val);
const none = cases.filter(({ condition }) => condition === "DEFAULT");
return value.length
? value.shift()
: none.shift()?.action?.() ?? null;
},
};
},
};
}
/**
* resolve main download file
*/
export async function getMainFile(name: string, version?: string) {
// * filter a array promises
async function filter<T extends any>(
arr: Array<T>,
callback: (item: T) => Promise<boolean>,
) {
const fail = Symbol();
return (
await Promise.all(
arr.map(async (item) => ((await callback(item)) ? item : fail)),
)
).filter((item) => item !== fail);
}
const files = [
"mod.ts",
"mod.js",
"index.js",
"index.ts",
"%name%.js",
"%name%.ts",
"dist/index.esm.js",
"dist/index.esm.min.js",
"dist/%name%.esm.js",
"dist/%name%.esm.min.js",
"dist/mod.ts",
"dist/mod.js",
"dist/index.js",
"dist/%name%.js",
"dist/%name%.min.js",
"lib/index.ts",
"lib/index.js",
"lib/%name%.ts",
"lib/%name%.js",
"deno/index.ts",
"deno/index.js",
].map(async (target) => {
const file = target.includes("%name%")
? target.replace("%name%", name?.trim())
: target;
const response = await fetch(
`https://deno.land/x/${name}${version ? `@${version}` : ""}/${file}`,
);
const { ok, status } = response;
return {
file,
ok,
status,
};
});
return (
await filter(
files,
async (file) => (await file).ok && (await file).status < 300,
)
).shift();
}