namirasoft-core 1.4.12 → 1.4.13
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.
- package/dist/EncryptionOperation.js +17 -7
- package/dist/EncryptionOperation.js.map +1 -1
- package/dist/HashOperation.js +17 -7
- package/dist/HashOperation.js.map +1 -1
- package/dist/PhoneOperation.js +17 -7
- package/dist/PhoneOperation.js.map +1 -1
- package/dist/SortItem.d.ts +24 -0
- package/dist/SortItem.js +75 -0
- package/dist/SortItem.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/BaseDatabaseRow.ts +6 -6
- package/src/BaseMetaColumn.ts +13 -13
- package/src/BaseMetaTable.ts +24 -24
- package/src/BaseServer.ts +107 -107
- package/src/CacheService.ts +57 -57
- package/src/ConsoleOperation.ts +68 -68
- package/src/ConvertService.ts +100 -100
- package/src/CookieService.ts +33 -33
- package/src/Countries.ts +486 -486
- package/src/Country.ts +21 -21
- package/src/CountryOperation.ts +98 -98
- package/src/EncodingOperation.ts +12 -12
- package/src/EncryptionOperation.ts +40 -40
- package/src/EnvService.ts +22 -22
- package/src/ErrorOperation.ts +13 -13
- package/src/FileOperation.ts +57 -57
- package/src/FilterItem.ts +128 -128
- package/src/FilterItemColumnType.ts +6 -6
- package/src/FilterItemOperator.ts +51 -51
- package/src/GeoOperation.ts +18 -18
- package/src/HTTPError.ts +8 -8
- package/src/HTTPMethod.ts +6 -6
- package/src/HashOperation.ts +24 -24
- package/src/IStorage.ts +5 -5
- package/src/IStorageCookie.ts +52 -52
- package/src/IStorageJsonFile.ts +45 -45
- package/src/IStorageLocal.ts +16 -16
- package/src/IStorageMemory.ts +17 -17
- package/src/NamingConvention.ts +107 -107
- package/src/ObjectService.ts +27 -27
- package/src/PackageService.ts +76 -76
- package/src/PhoneOperation.ts +8 -8
- package/src/PriceOperation.ts +18 -18
- package/src/RegexTemplate.ts +7 -7
- package/src/SearchOperation.ts +29 -29
- package/src/SortItem.ts +89 -0
- package/src/StringOperation.ts +18 -18
- package/src/TimeOperation.ts +262 -262
- package/src/URLOperation.ts +54 -54
- package/src/VersionOperation.ts +46 -46
- package/src/index.ts +40 -39
package/src/Country.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
export class Country
|
|
2
|
-
{
|
|
3
|
-
continent: string = "";
|
|
4
|
-
name: string = "";
|
|
5
|
-
iso2: string = "";
|
|
6
|
-
iso3: string = "";
|
|
7
|
-
code: string = "";
|
|
8
|
-
european_union: boolean = false;
|
|
9
|
-
coeff: number;
|
|
10
|
-
other: string[] = [];
|
|
11
|
-
constructor(continent: string, name: string, iso2: string, iso3: string, code: string, european_union: boolean, coeff: number, other: string[] = [])
|
|
12
|
-
{
|
|
13
|
-
this.continent = continent;
|
|
14
|
-
this.name = name;
|
|
15
|
-
this.iso2 = iso2;
|
|
16
|
-
this.iso3 = iso3;
|
|
17
|
-
this.code = code;
|
|
18
|
-
this.european_union = european_union;
|
|
19
|
-
this.coeff = coeff;
|
|
20
|
-
this.other = other;
|
|
21
|
-
}
|
|
1
|
+
export class Country
|
|
2
|
+
{
|
|
3
|
+
continent: string = "";
|
|
4
|
+
name: string = "";
|
|
5
|
+
iso2: string = "";
|
|
6
|
+
iso3: string = "";
|
|
7
|
+
code: string = "";
|
|
8
|
+
european_union: boolean = false;
|
|
9
|
+
coeff: number;
|
|
10
|
+
other: string[] = [];
|
|
11
|
+
constructor(continent: string, name: string, iso2: string, iso3: string, code: string, european_union: boolean, coeff: number, other: string[] = [])
|
|
12
|
+
{
|
|
13
|
+
this.continent = continent;
|
|
14
|
+
this.name = name;
|
|
15
|
+
this.iso2 = iso2;
|
|
16
|
+
this.iso3 = iso3;
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.european_union = european_union;
|
|
19
|
+
this.coeff = coeff;
|
|
20
|
+
this.other = other;
|
|
21
|
+
}
|
|
22
22
|
}
|
package/src/CountryOperation.ts
CHANGED
|
@@ -1,99 +1,99 @@
|
|
|
1
|
-
import { Country } from "./Country";
|
|
2
|
-
import { Countries } from "./Countries";
|
|
3
|
-
|
|
4
|
-
export class CountryOperation
|
|
5
|
-
{
|
|
6
|
-
private static simplify(input: string): string
|
|
7
|
-
{
|
|
8
|
-
if (!input)
|
|
9
|
-
input = "";
|
|
10
|
-
let arr = [" ", ".", "/", "'", "\"", "?", "!", "-", "+", "_", '\$', "@", "%", " of ", " the ", " a ", " an "];
|
|
11
|
-
arr.map(pattern => input = input.split(pattern).join(""));
|
|
12
|
-
input = input.split("é").join("e");
|
|
13
|
-
return input.trim().toLowerCase();
|
|
14
|
-
}
|
|
15
|
-
static find(input: string): Country | null
|
|
16
|
-
{
|
|
17
|
-
if (!input)
|
|
18
|
-
input = "";
|
|
19
|
-
input = this.simplify(input);
|
|
20
|
-
if (input)
|
|
21
|
-
for (let country of Countries.getAll())
|
|
22
|
-
{
|
|
23
|
-
let values = [country.iso2, country.iso3, country.name];
|
|
24
|
-
if (input.startsWith(country.code))
|
|
25
|
-
return country;
|
|
26
|
-
if (country.other)
|
|
27
|
-
for (let i = 0; i < country.other.length; i++)
|
|
28
|
-
values.push(country.other[i]);
|
|
29
|
-
for (let i = 0; i < values.length; i++)
|
|
30
|
-
if (this.simplify(values[i]) === input)
|
|
31
|
-
return country;
|
|
32
|
-
}
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
static findPhone(input: string): Country[]
|
|
36
|
-
{
|
|
37
|
-
if (!input)
|
|
38
|
-
input = "";
|
|
39
|
-
input = this.simplify(input);
|
|
40
|
-
let ans = [];
|
|
41
|
-
let max = 0;
|
|
42
|
-
if (input)
|
|
43
|
-
for (let country of Countries.getAll())
|
|
44
|
-
if (input.startsWith(country.code))
|
|
45
|
-
{
|
|
46
|
-
ans.push(country);
|
|
47
|
-
max = Math.max(country.code.length, max);
|
|
48
|
-
}
|
|
49
|
-
let res = [];
|
|
50
|
-
for (let i = 0; i < ans.length; i++)
|
|
51
|
-
{
|
|
52
|
-
if (ans[i].code.length == max)
|
|
53
|
-
res.push(ans[i]);
|
|
54
|
-
}
|
|
55
|
-
return res;
|
|
56
|
-
}
|
|
57
|
-
static isPhoneFromCountry(input: string, country: Country | string | null)
|
|
58
|
-
{
|
|
59
|
-
if (country instanceof String)
|
|
60
|
-
country = this.find(country as string);
|
|
61
|
-
let countries = this.findPhone(input);
|
|
62
|
-
if (country)
|
|
63
|
-
for (let i = 0; i < countries.length; i++)
|
|
64
|
-
if (this.areEqual([countries[i], country]))
|
|
65
|
-
return true;
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
static areEqual(countries: (Country | string)[]): boolean
|
|
69
|
-
{
|
|
70
|
-
countries = countries.map(country =>
|
|
71
|
-
{
|
|
72
|
-
let c: Country | null = null;
|
|
73
|
-
if (country instanceof Country)
|
|
74
|
-
c = country;
|
|
75
|
-
else
|
|
76
|
-
c = this.find(country as string);
|
|
77
|
-
if (c)
|
|
78
|
-
return c.name;
|
|
79
|
-
throw new Error("Couldn't find country: " + country);
|
|
80
|
-
});
|
|
81
|
-
countries = countries.filter(v => v);
|
|
82
|
-
countries = countries.filter((v, i, a) => a.indexOf(v) === i);
|
|
83
|
-
return countries.length === 1;
|
|
84
|
-
}
|
|
85
|
-
static getCoeff(code: string, amount: number, times: number = 1): number
|
|
86
|
-
{
|
|
87
|
-
if (!times)
|
|
88
|
-
times = 1;
|
|
89
|
-
let country: Country | null = this.find(code);
|
|
90
|
-
let ans: number = country?.coeff ?? 0;
|
|
91
|
-
if (isNaN(ans))
|
|
92
|
-
ans = 0.1;
|
|
93
|
-
ans += Math.min(Math.max(1 - ans, 0), 1) * (times - 1) / times;
|
|
94
|
-
ans = Math.min(Math.max(ans, 0), 1);
|
|
95
|
-
if (amount)
|
|
96
|
-
ans = amount * ans;
|
|
97
|
-
return ans;
|
|
98
|
-
}
|
|
1
|
+
import { Country } from "./Country";
|
|
2
|
+
import { Countries } from "./Countries";
|
|
3
|
+
|
|
4
|
+
export class CountryOperation
|
|
5
|
+
{
|
|
6
|
+
private static simplify(input: string): string
|
|
7
|
+
{
|
|
8
|
+
if (!input)
|
|
9
|
+
input = "";
|
|
10
|
+
let arr = [" ", ".", "/", "'", "\"", "?", "!", "-", "+", "_", '\$', "@", "%", " of ", " the ", " a ", " an "];
|
|
11
|
+
arr.map(pattern => input = input.split(pattern).join(""));
|
|
12
|
+
input = input.split("é").join("e");
|
|
13
|
+
return input.trim().toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
static find(input: string): Country | null
|
|
16
|
+
{
|
|
17
|
+
if (!input)
|
|
18
|
+
input = "";
|
|
19
|
+
input = this.simplify(input);
|
|
20
|
+
if (input)
|
|
21
|
+
for (let country of Countries.getAll())
|
|
22
|
+
{
|
|
23
|
+
let values = [country.iso2, country.iso3, country.name];
|
|
24
|
+
if (input.startsWith(country.code))
|
|
25
|
+
return country;
|
|
26
|
+
if (country.other)
|
|
27
|
+
for (let i = 0; i < country.other.length; i++)
|
|
28
|
+
values.push(country.other[i]);
|
|
29
|
+
for (let i = 0; i < values.length; i++)
|
|
30
|
+
if (this.simplify(values[i]) === input)
|
|
31
|
+
return country;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
static findPhone(input: string): Country[]
|
|
36
|
+
{
|
|
37
|
+
if (!input)
|
|
38
|
+
input = "";
|
|
39
|
+
input = this.simplify(input);
|
|
40
|
+
let ans = [];
|
|
41
|
+
let max = 0;
|
|
42
|
+
if (input)
|
|
43
|
+
for (let country of Countries.getAll())
|
|
44
|
+
if (input.startsWith(country.code))
|
|
45
|
+
{
|
|
46
|
+
ans.push(country);
|
|
47
|
+
max = Math.max(country.code.length, max);
|
|
48
|
+
}
|
|
49
|
+
let res = [];
|
|
50
|
+
for (let i = 0; i < ans.length; i++)
|
|
51
|
+
{
|
|
52
|
+
if (ans[i].code.length == max)
|
|
53
|
+
res.push(ans[i]);
|
|
54
|
+
}
|
|
55
|
+
return res;
|
|
56
|
+
}
|
|
57
|
+
static isPhoneFromCountry(input: string, country: Country | string | null)
|
|
58
|
+
{
|
|
59
|
+
if (country instanceof String)
|
|
60
|
+
country = this.find(country as string);
|
|
61
|
+
let countries = this.findPhone(input);
|
|
62
|
+
if (country)
|
|
63
|
+
for (let i = 0; i < countries.length; i++)
|
|
64
|
+
if (this.areEqual([countries[i], country]))
|
|
65
|
+
return true;
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
static areEqual(countries: (Country | string)[]): boolean
|
|
69
|
+
{
|
|
70
|
+
countries = countries.map(country =>
|
|
71
|
+
{
|
|
72
|
+
let c: Country | null = null;
|
|
73
|
+
if (country instanceof Country)
|
|
74
|
+
c = country;
|
|
75
|
+
else
|
|
76
|
+
c = this.find(country as string);
|
|
77
|
+
if (c)
|
|
78
|
+
return c.name;
|
|
79
|
+
throw new Error("Couldn't find country: " + country);
|
|
80
|
+
});
|
|
81
|
+
countries = countries.filter(v => v);
|
|
82
|
+
countries = countries.filter((v, i, a) => a.indexOf(v) === i);
|
|
83
|
+
return countries.length === 1;
|
|
84
|
+
}
|
|
85
|
+
static getCoeff(code: string, amount: number, times: number = 1): number
|
|
86
|
+
{
|
|
87
|
+
if (!times)
|
|
88
|
+
times = 1;
|
|
89
|
+
let country: Country | null = this.find(code);
|
|
90
|
+
let ans: number = country?.coeff ?? 0;
|
|
91
|
+
if (isNaN(ans))
|
|
92
|
+
ans = 0.1;
|
|
93
|
+
ans += Math.min(Math.max(1 - ans, 0), 1) * (times - 1) / times;
|
|
94
|
+
ans = Math.min(Math.max(ans, 0), 1);
|
|
95
|
+
if (amount)
|
|
96
|
+
ans = amount * ans;
|
|
97
|
+
return ans;
|
|
98
|
+
}
|
|
99
99
|
}
|
package/src/EncodingOperation.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Buffer } from 'buffer';
|
|
2
|
-
|
|
3
|
-
export class EncodingOperation
|
|
4
|
-
{
|
|
5
|
-
static Base64Encode(message: string): string
|
|
6
|
-
{
|
|
7
|
-
return Buffer.from(message).toString("base64");
|
|
8
|
-
}
|
|
9
|
-
static Base64Decode(message: string): string
|
|
10
|
-
{
|
|
11
|
-
return atob(message);
|
|
12
|
-
}
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
|
|
3
|
+
export class EncodingOperation
|
|
4
|
+
{
|
|
5
|
+
static Base64Encode(message: string): string
|
|
6
|
+
{
|
|
7
|
+
return Buffer.from(message).toString("base64");
|
|
8
|
+
}
|
|
9
|
+
static Base64Decode(message: string): string
|
|
10
|
+
{
|
|
11
|
+
return atob(message);
|
|
12
|
+
}
|
|
13
13
|
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import * as crypto from 'node:crypto';
|
|
2
|
-
|
|
3
|
-
export class EncryptionOperation
|
|
4
|
-
{
|
|
5
|
-
private static encrypt<T>(algorithm: string, secret: string, message: T): string
|
|
6
|
-
{
|
|
7
|
-
if (secret.length != 32)
|
|
8
|
-
throw new Error("Secret length must be exactly 32");
|
|
9
|
-
const secretBytes = Buffer.from(secret);
|
|
10
|
-
const iv = crypto.randomBytes(16);
|
|
11
|
-
const cipher = crypto.createCipheriv(algorithm, secretBytes, iv);
|
|
12
|
-
const encrypted = Buffer.concat([cipher.update(JSON.stringify(message), 'utf8'), cipher.final()]);
|
|
13
|
-
const authTag = (cipher as any).getAuthTag();
|
|
14
|
-
const ivHex = iv.toString('hex');
|
|
15
|
-
const authTagHex = authTag.toString('hex');
|
|
16
|
-
const encryptedHex = encrypted.toString('hex');
|
|
17
|
-
return [ivHex, authTagHex, encryptedHex].join(";");
|
|
18
|
-
}
|
|
19
|
-
private static decrypt<T>(algorithm: string, secret: string, message: string): T
|
|
20
|
-
{
|
|
21
|
-
const [ivHex, authTagHex, encryptedHex] = message.split(';');
|
|
22
|
-
const iv = Buffer.from(ivHex, 'hex');
|
|
23
|
-
const authTag = Buffer.from(authTagHex, 'hex');
|
|
24
|
-
const encrypte = Buffer.from(encryptedHex, 'hex');
|
|
25
|
-
|
|
26
|
-
const decipher = crypto.createDecipheriv(algorithm, secret, iv);
|
|
27
|
-
(decipher as any).setAuthTag(authTag);
|
|
28
|
-
|
|
29
|
-
let decrypted = decipher.update(encrypte);
|
|
30
|
-
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
31
|
-
return JSON.parse(decrypted.toString());
|
|
32
|
-
}
|
|
33
|
-
static AES256GCMEncrypt<T>(secret: string, message: T): string
|
|
34
|
-
{
|
|
35
|
-
return EncryptionOperation.encrypt("aes-256-gcm", secret, message);
|
|
36
|
-
}
|
|
37
|
-
static AES256GCMDecrypt<T>(secret: string, message: string): T
|
|
38
|
-
{
|
|
39
|
-
return EncryptionOperation.decrypt("aes-256-gcm", secret, message);
|
|
40
|
-
}
|
|
1
|
+
import * as crypto from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
export class EncryptionOperation
|
|
4
|
+
{
|
|
5
|
+
private static encrypt<T>(algorithm: string, secret: string, message: T): string
|
|
6
|
+
{
|
|
7
|
+
if (secret.length != 32)
|
|
8
|
+
throw new Error("Secret length must be exactly 32");
|
|
9
|
+
const secretBytes = Buffer.from(secret);
|
|
10
|
+
const iv = crypto.randomBytes(16);
|
|
11
|
+
const cipher = crypto.createCipheriv(algorithm, secretBytes, iv);
|
|
12
|
+
const encrypted = Buffer.concat([cipher.update(JSON.stringify(message), 'utf8'), cipher.final()]);
|
|
13
|
+
const authTag = (cipher as any).getAuthTag();
|
|
14
|
+
const ivHex = iv.toString('hex');
|
|
15
|
+
const authTagHex = authTag.toString('hex');
|
|
16
|
+
const encryptedHex = encrypted.toString('hex');
|
|
17
|
+
return [ivHex, authTagHex, encryptedHex].join(";");
|
|
18
|
+
}
|
|
19
|
+
private static decrypt<T>(algorithm: string, secret: string, message: string): T
|
|
20
|
+
{
|
|
21
|
+
const [ivHex, authTagHex, encryptedHex] = message.split(';');
|
|
22
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
23
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
24
|
+
const encrypte = Buffer.from(encryptedHex, 'hex');
|
|
25
|
+
|
|
26
|
+
const decipher = crypto.createDecipheriv(algorithm, secret, iv);
|
|
27
|
+
(decipher as any).setAuthTag(authTag);
|
|
28
|
+
|
|
29
|
+
let decrypted = decipher.update(encrypte);
|
|
30
|
+
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
31
|
+
return JSON.parse(decrypted.toString());
|
|
32
|
+
}
|
|
33
|
+
static AES256GCMEncrypt<T>(secret: string, message: T): string
|
|
34
|
+
{
|
|
35
|
+
return EncryptionOperation.encrypt("aes-256-gcm", secret, message);
|
|
36
|
+
}
|
|
37
|
+
static AES256GCMDecrypt<T>(secret: string, message: string): T
|
|
38
|
+
{
|
|
39
|
+
return EncryptionOperation.decrypt("aes-256-gcm", secret, message);
|
|
40
|
+
}
|
|
41
41
|
}
|
package/src/EnvService.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { ConvertService } from "./ConvertService";
|
|
2
|
-
|
|
3
|
-
export class EnvService extends ConvertService
|
|
4
|
-
{
|
|
5
|
-
name: string;
|
|
6
|
-
constructor(name: string, mandatory: boolean = false)
|
|
7
|
-
{
|
|
8
|
-
super(mandatory);
|
|
9
|
-
this.name = name;
|
|
10
|
-
}
|
|
11
|
-
override getNullString()
|
|
12
|
-
{
|
|
13
|
-
let ans = process.env[this.name];
|
|
14
|
-
if (ans)
|
|
15
|
-
return ans;
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
protected override onMandatoryError(): void
|
|
19
|
-
{
|
|
20
|
-
if (!process.env.NAMIRASOFT_MUTE)
|
|
21
|
-
throw new Error(`Env value was not provided: ${this.name}`);
|
|
22
|
-
}
|
|
1
|
+
import { ConvertService } from "./ConvertService";
|
|
2
|
+
|
|
3
|
+
export class EnvService extends ConvertService
|
|
4
|
+
{
|
|
5
|
+
name: string;
|
|
6
|
+
constructor(name: string, mandatory: boolean = false)
|
|
7
|
+
{
|
|
8
|
+
super(mandatory);
|
|
9
|
+
this.name = name;
|
|
10
|
+
}
|
|
11
|
+
override getNullString()
|
|
12
|
+
{
|
|
13
|
+
let ans = process.env[this.name];
|
|
14
|
+
if (ans)
|
|
15
|
+
return ans;
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
protected override onMandatoryError(): void
|
|
19
|
+
{
|
|
20
|
+
if (!process.env.NAMIRASOFT_MUTE)
|
|
21
|
+
throw new Error(`Env value was not provided: ${this.name}`);
|
|
22
|
+
}
|
|
23
23
|
}
|
package/src/ErrorOperation.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { HTTPError } from "./HTTPError";
|
|
2
|
-
import { StringOperation } from "./StringOperation";
|
|
3
|
-
|
|
4
|
-
export class ErrorOperation
|
|
5
|
-
{
|
|
6
|
-
static throwHTTP(code: number, message: string, ...args: string[])
|
|
7
|
-
{
|
|
8
|
-
throw this.getHTTP(code, message, ...args);
|
|
9
|
-
}
|
|
10
|
-
static getHTTP(code: number, message: string, ...args: string[])
|
|
11
|
-
{
|
|
12
|
-
return new HTTPError(code, StringOperation.format(message, ...args));
|
|
13
|
-
}
|
|
1
|
+
import { HTTPError } from "./HTTPError";
|
|
2
|
+
import { StringOperation } from "./StringOperation";
|
|
3
|
+
|
|
4
|
+
export class ErrorOperation
|
|
5
|
+
{
|
|
6
|
+
static throwHTTP(code: number, message: string, ...args: string[])
|
|
7
|
+
{
|
|
8
|
+
throw this.getHTTP(code, message, ...args);
|
|
9
|
+
}
|
|
10
|
+
static getHTTP(code: number, message: string, ...args: string[])
|
|
11
|
+
{
|
|
12
|
+
return new HTTPError(code, StringOperation.format(message, ...args));
|
|
13
|
+
}
|
|
14
14
|
}
|
package/src/FileOperation.ts
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
let fs: any;
|
|
2
|
-
let path: any;
|
|
3
|
-
if (typeof window === 'undefined')
|
|
4
|
-
{
|
|
5
|
-
fs = require('fs');
|
|
6
|
-
path = require('path');
|
|
7
|
-
}
|
|
8
|
-
export class FileOperation
|
|
9
|
-
{
|
|
10
|
-
static findUp(fileName: string): string[]
|
|
11
|
-
{
|
|
12
|
-
let currentDir: string = __dirname;
|
|
13
|
-
const rootDir: string = process.cwd();
|
|
14
|
-
const foundFilePaths: string[] = [];
|
|
15
|
-
function searchRecursively(dir: string)
|
|
16
|
-
{
|
|
17
|
-
const files: string[] = fs.readdirSync(dir);
|
|
18
|
-
if (files.includes(fileName))
|
|
19
|
-
foundFilePaths.push(path.join(dir, fileName));
|
|
20
|
-
if (rootDir === dir)
|
|
21
|
-
return;
|
|
22
|
-
let new_dir = path.dirname(dir);
|
|
23
|
-
if (new_dir == dir)
|
|
24
|
-
return;
|
|
25
|
-
searchRecursively(new_dir);
|
|
26
|
-
}
|
|
27
|
-
searchRecursively(currentDir);
|
|
28
|
-
return foundFilePaths;
|
|
29
|
-
}
|
|
30
|
-
static async foreach(base: string, handler: (base: string, sub: string, name: string, full: string, isFolder: boolean) => Promise<boolean>, folders: boolean = true, files: boolean = true)
|
|
31
|
-
{
|
|
32
|
-
async function recursive(base: string, sub: string)
|
|
33
|
-
{
|
|
34
|
-
let names = fs.readdirSync(path.join(base, sub));
|
|
35
|
-
for (let name of names)
|
|
36
|
-
{
|
|
37
|
-
let newSub = path.join(sub, name)
|
|
38
|
-
let full = path.join(base, newSub);
|
|
39
|
-
if (fs.statSync(full).isDirectory())
|
|
40
|
-
{
|
|
41
|
-
if (folders)
|
|
42
|
-
{
|
|
43
|
-
let moveon = await handler(base, sub, name, full, true);
|
|
44
|
-
if (!moveon)
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
await recursive(base, newSub);
|
|
48
|
-
}
|
|
49
|
-
else
|
|
50
|
-
{
|
|
51
|
-
if (files)
|
|
52
|
-
await handler(base, sub, name, full, false);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
await recursive(base, "");
|
|
57
|
-
}
|
|
1
|
+
let fs: any;
|
|
2
|
+
let path: any;
|
|
3
|
+
if (typeof window === 'undefined')
|
|
4
|
+
{
|
|
5
|
+
fs = require('fs');
|
|
6
|
+
path = require('path');
|
|
7
|
+
}
|
|
8
|
+
export class FileOperation
|
|
9
|
+
{
|
|
10
|
+
static findUp(fileName: string): string[]
|
|
11
|
+
{
|
|
12
|
+
let currentDir: string = __dirname;
|
|
13
|
+
const rootDir: string = process.cwd();
|
|
14
|
+
const foundFilePaths: string[] = [];
|
|
15
|
+
function searchRecursively(dir: string)
|
|
16
|
+
{
|
|
17
|
+
const files: string[] = fs.readdirSync(dir);
|
|
18
|
+
if (files.includes(fileName))
|
|
19
|
+
foundFilePaths.push(path.join(dir, fileName));
|
|
20
|
+
if (rootDir === dir)
|
|
21
|
+
return;
|
|
22
|
+
let new_dir = path.dirname(dir);
|
|
23
|
+
if (new_dir == dir)
|
|
24
|
+
return;
|
|
25
|
+
searchRecursively(new_dir);
|
|
26
|
+
}
|
|
27
|
+
searchRecursively(currentDir);
|
|
28
|
+
return foundFilePaths;
|
|
29
|
+
}
|
|
30
|
+
static async foreach(base: string, handler: (base: string, sub: string, name: string, full: string, isFolder: boolean) => Promise<boolean>, folders: boolean = true, files: boolean = true)
|
|
31
|
+
{
|
|
32
|
+
async function recursive(base: string, sub: string)
|
|
33
|
+
{
|
|
34
|
+
let names = fs.readdirSync(path.join(base, sub));
|
|
35
|
+
for (let name of names)
|
|
36
|
+
{
|
|
37
|
+
let newSub = path.join(sub, name)
|
|
38
|
+
let full = path.join(base, newSub);
|
|
39
|
+
if (fs.statSync(full).isDirectory())
|
|
40
|
+
{
|
|
41
|
+
if (folders)
|
|
42
|
+
{
|
|
43
|
+
let moveon = await handler(base, sub, name, full, true);
|
|
44
|
+
if (!moveon)
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
await recursive(base, newSub);
|
|
48
|
+
}
|
|
49
|
+
else
|
|
50
|
+
{
|
|
51
|
+
if (files)
|
|
52
|
+
await handler(base, sub, name, full, false);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
await recursive(base, "");
|
|
57
|
+
}
|
|
58
58
|
}
|