querysub 0.436.0 → 0.438.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.
- package/.eslintrc.js +50 -50
- package/bin/deploy.js +0 -0
- package/bin/function.js +0 -0
- package/bin/server.js +0 -0
- package/costsBenefits.txt +115 -115
- package/deploy.ts +2 -2
- package/package.json +1 -1
- package/spec.txt +1192 -1192
- package/src/-a-archives/archives.ts +202 -202
- package/src/-a-archives/archivesBackBlaze.ts +0 -1
- package/src/-a-archives/archivesDisk.ts +454 -454
- package/src/-a-auth/certs.ts +540 -540
- package/src/-a-auth/node-forge-ed25519.d.ts +16 -16
- package/src/-b-authorities/dnsAuthority.ts +138 -138
- package/src/-c-identity/IdentityController.ts +258 -258
- package/src/-d-trust/NetworkTrust2.ts +180 -180
- package/src/-e-certs/EdgeCertController.ts +252 -252
- package/src/-e-certs/certAuthority.ts +201 -201
- package/src/-f-node-discovery/NodeDiscovery.ts +640 -640
- package/src/-g-core-values/NodeCapabilities.ts +200 -200
- package/src/-h-path-value-serialize/stringSerializer.ts +175 -175
- package/src/0-path-value-core/PathValueCommitter.ts +468 -468
- package/src/0-path-value-core/PathValueController.ts +0 -2
- package/src/2-proxy/PathValueProxyWatcher.ts +2542 -2542
- package/src/2-proxy/TransactionDelayer.ts +94 -94
- package/src/2-proxy/pathDatabaseProxyBase.ts +36 -36
- package/src/2-proxy/pathValueProxy.ts +159 -159
- package/src/3-path-functions/PathFunctionRunnerMain.ts +87 -87
- package/src/3-path-functions/pathFunctionLoader.ts +516 -516
- package/src/3-path-functions/tests/rejectTest.ts +76 -76
- package/src/4-deploy/deployCheck.ts +6 -6
- package/src/4-dom/css.tsx +29 -29
- package/src/4-dom/cssTypes.d.ts +211 -211
- package/src/4-dom/qreact.tsx +2799 -2799
- package/src/4-dom/qreactTest.tsx +410 -410
- package/src/4-querysub/permissions.ts +335 -335
- package/src/4-querysub/querysubPrediction.ts +483 -483
- package/src/5-diagnostics/qreactDebug.tsx +377 -346
- package/src/TestController.ts +34 -34
- package/src/bits.ts +104 -104
- package/src/buffers.ts +69 -69
- package/src/diagnostics/ActionsHistory.ts +57 -57
- package/src/diagnostics/listenOnDebugger.ts +71 -71
- package/src/diagnostics/periodic.ts +111 -111
- package/src/diagnostics/trackResources.ts +91 -91
- package/src/diagnostics/watchdog.ts +120 -120
- package/src/errors.ts +133 -133
- package/src/forceProduction.ts +2 -2
- package/src/fs.ts +80 -80
- package/src/functional/diff.ts +857 -857
- package/src/functional/promiseCache.ts +78 -78
- package/src/functional/random.ts +8 -8
- package/src/functional/stats.ts +60 -60
- package/src/heapDumps.ts +665 -665
- package/src/https.ts +1 -1
- package/src/library-components/AspectSizedComponent.tsx +87 -87
- package/src/library-components/ButtonSelector.tsx +64 -64
- package/src/library-components/DropdownCustom.tsx +150 -150
- package/src/library-components/DropdownSelector.tsx +31 -31
- package/src/library-components/InlinePopup.tsx +66 -66
- package/src/misc/color.ts +29 -29
- package/src/misc/hash.ts +83 -83
- package/src/misc/ipPong.js +13 -13
- package/src/misc/networking.ts +1 -1
- package/src/misc/random.ts +44 -44
- package/src/misc.ts +196 -196
- package/src/path.ts +255 -255
- package/src/persistentLocalStore.ts +41 -41
- package/src/promise.ts +14 -14
- package/src/storage/fileSystemPointer.ts +71 -71
- package/src/test/heapProcess.ts +35 -35
- package/src/zip.ts +15 -15
- package/tsconfig.json +26 -26
- package/yarnSpec.txt +56 -56
|
@@ -1,203 +1,203 @@
|
|
|
1
|
-
import { isNode } from "socket-function/src/misc";
|
|
2
|
-
import { getDomain, isNoNetwork } from "../config";
|
|
3
|
-
import { getStorageDir, getSubFolder } from "../fs";
|
|
4
|
-
import { getArchivesBackblaze, hasBackblazePermissions } from "./archivesBackBlaze";
|
|
5
|
-
import { getArchivesLocal } from "./archivesDisk";
|
|
6
|
-
import { magenta } from "socket-function/src/formatting/logColors";
|
|
7
|
-
import debugbreak from "debugbreak";
|
|
8
|
-
import { isClient } from "../config2";
|
|
9
|
-
import { wrapArchivesWithCache } from "./archiveCache";
|
|
10
|
-
import { Args } from "socket-function/src/types";
|
|
11
|
-
|
|
12
|
-
export interface Archives {
|
|
13
|
-
getDebugName(): string;
|
|
14
|
-
|
|
15
|
-
get(path: string, config?: {
|
|
16
|
-
range?: { start: number; end: number; };
|
|
17
|
-
retryCount?: number;
|
|
18
|
-
// Skips checking if the file exists on the remote. Only appropriate when the file name is fresh (recently obtained from find).
|
|
19
|
-
fastRead?: boolean;
|
|
20
|
-
}): Promise<Buffer | undefined>;
|
|
21
|
-
set(path: string, data: Buffer): Promise<void>;
|
|
22
|
-
del(path: string): Promise<void>;
|
|
23
|
-
|
|
24
|
-
append(path: string, data: Buffer): Promise<void>;
|
|
25
|
-
|
|
26
|
-
getInfo(path: string): Promise<{ writeTime: number; size: number; } | undefined>;
|
|
27
|
-
|
|
28
|
-
setLargeFile(config: { path: string; getNextData(): Promise<Buffer | undefined>; }): Promise<void>;
|
|
29
|
-
|
|
30
|
-
// For example findFileNames("ips/")
|
|
31
|
-
/** Returns to full paths. Returns paths WILL NOT end with / */
|
|
32
|
-
find(
|
|
33
|
-
prefix: string,
|
|
34
|
-
config?: {
|
|
35
|
-
shallow?: boolean;
|
|
36
|
-
// Defaults to files
|
|
37
|
-
type: "files" | "folders";
|
|
38
|
-
}
|
|
39
|
-
): Promise<string[]>;
|
|
40
|
-
findInfo(
|
|
41
|
-
prefix: string,
|
|
42
|
-
config?: {
|
|
43
|
-
shallow?: boolean;
|
|
44
|
-
// Defaults to files
|
|
45
|
-
type: "files" | "folders";
|
|
46
|
-
}
|
|
47
|
-
): Promise<{ path: string; createTime: number; size: number; }[]>;
|
|
48
|
-
|
|
49
|
-
move(config: {
|
|
50
|
-
path: string;
|
|
51
|
-
target: Archives;
|
|
52
|
-
targetPath: string;
|
|
53
|
-
}): Promise<void>;
|
|
54
|
-
copy(config: {
|
|
55
|
-
path: string;
|
|
56
|
-
target: Archives;
|
|
57
|
-
targetPath: string;
|
|
58
|
-
}): Promise<void>;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
enableLogging(): void;
|
|
62
|
-
|
|
63
|
-
/** Might throw due to too long of a length. Should never throw due to characters, as we can always encode special characters. */
|
|
64
|
-
assertPathValid(path: string): Promise<void>;
|
|
65
|
-
|
|
66
|
-
getBaseArchives?: () => { parentPath: string; archives: Archives; } | undefined;
|
|
67
|
-
|
|
68
|
-
/** Get a download URL for a file. Only implemented for some archive types (like Backblaze). */
|
|
69
|
-
getURL?: (path: string) => Promise<string>;
|
|
70
|
-
|
|
71
|
-
// NOTE: This isn't part of getURL, as it is much more efficient to call it once and reuse the authorization. This is only for backblaze as of right now.
|
|
72
|
-
// NOTE: This also gives authorization for ALL files, so... ONLY use it for internal download links. If we need external links, we should use a public folder with hash links, or... make a new endpoint.
|
|
73
|
-
getDownloadAuthorization?: (config: {
|
|
74
|
-
validDurationInSeconds: number;
|
|
75
|
-
}) => Promise<{
|
|
76
|
-
bucketId: string;
|
|
77
|
-
fileNamePrefix: string;
|
|
78
|
-
authorizationToken: string;
|
|
79
|
-
}>;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function createArchivesOverride<T extends Partial<Archives>>(
|
|
83
|
-
baseArchives: Archives,
|
|
84
|
-
overrideArchives: T
|
|
85
|
-
): T & Archives {
|
|
86
|
-
return {
|
|
87
|
-
getDebugName: () => baseArchives.getDebugName(),
|
|
88
|
-
get: (fileName: string, config) => baseArchives.get(fileName, config),
|
|
89
|
-
set: (fileName: string, data: Buffer) => baseArchives.set(fileName, data),
|
|
90
|
-
append: (fileName: string, data: Buffer) => baseArchives.append(fileName, data),
|
|
91
|
-
del: (fileName: string) => baseArchives.del(fileName),
|
|
92
|
-
getInfo: (fileName: string) => baseArchives.getInfo(fileName),
|
|
93
|
-
setLargeFile: (config) => baseArchives.setLargeFile(config),
|
|
94
|
-
find: async (prefix: string, config) => baseArchives.find(prefix, config),
|
|
95
|
-
findInfo: async (prefix: string, config) => baseArchives.findInfo(prefix, config),
|
|
96
|
-
enableLogging: () => baseArchives.enableLogging(),
|
|
97
|
-
move: (config) => baseArchives.move(config),
|
|
98
|
-
copy: (config) => baseArchives.copy(config),
|
|
99
|
-
assertPathValid: (path: string) => baseArchives.assertPathValid(path),
|
|
100
|
-
getBaseArchives: () => baseArchives.getBaseArchives?.() ?? ({ archives: baseArchives, parentPath: "" }),
|
|
101
|
-
getURL: baseArchives.getURL ? (filePath: string) => baseArchives.getURL!(filePath) : undefined,
|
|
102
|
-
getDownloadAuthorization: baseArchives.getDownloadAuthorization ? (config: { validDurationInSeconds: number }) => baseArchives.getDownloadAuthorization!(config) : undefined,
|
|
103
|
-
...overrideArchives,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function nestArchives(path: string, archives: Archives): Archives {
|
|
108
|
-
if (!path) return archives;
|
|
109
|
-
if (!path.endsWith("/")) {
|
|
110
|
-
path = path + "/";
|
|
111
|
-
}
|
|
112
|
-
function stripFilePrefix(file: string) {
|
|
113
|
-
if (file.startsWith("/")) {
|
|
114
|
-
return file.slice(1);
|
|
115
|
-
}
|
|
116
|
-
return file;
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
getDebugName: () => archives.getDebugName() + "/" + path,
|
|
120
|
-
get: (fileName: string, config) => archives.get(path + stripFilePrefix(fileName), config),
|
|
121
|
-
setLargeFile: (config) => archives.setLargeFile({ ...config, path: path + stripFilePrefix(config.path) }),
|
|
122
|
-
set: (fileName: string, data: Buffer) => archives.set(path + stripFilePrefix(fileName), data),
|
|
123
|
-
append: (fileName: string, data: Buffer) => archives.append(path + stripFilePrefix(fileName), data),
|
|
124
|
-
del: (fileName: string) => archives.del(path + stripFilePrefix(fileName)),
|
|
125
|
-
getInfo: (fileName: string) => archives.getInfo(path + stripFilePrefix(fileName)),
|
|
126
|
-
find: async (prefix: string, config) => archives.find(path + prefix, config).then(x => x.map(x => x.slice(path.length))),
|
|
127
|
-
findInfo: async (prefix: string, config) => archives.findInfo(path + prefix, config).then(x => x.map(x => ({ path: x.path.slice(path.length), createTime: x.createTime, size: x.size }))),
|
|
128
|
-
enableLogging: () => archives.enableLogging(),
|
|
129
|
-
move: (config) => archives.move({
|
|
130
|
-
path: path + config.path,
|
|
131
|
-
target: config.target,
|
|
132
|
-
targetPath: config.targetPath,
|
|
133
|
-
}),
|
|
134
|
-
copy: (config) => archives.copy({
|
|
135
|
-
path: path + config.path,
|
|
136
|
-
target: config.target,
|
|
137
|
-
targetPath: config.targetPath,
|
|
138
|
-
}),
|
|
139
|
-
assertPathValid: (path: string) => archives.assertPathValid(path),
|
|
140
|
-
getBaseArchives: () => {
|
|
141
|
-
let result = { parentPath: path, archives };
|
|
142
|
-
let base = archives.getBaseArchives?.();
|
|
143
|
-
if (base) {
|
|
144
|
-
result.parentPath = base.parentPath + path;
|
|
145
|
-
result.archives = base.archives;
|
|
146
|
-
}
|
|
147
|
-
return result;
|
|
148
|
-
},
|
|
149
|
-
getURL: archives.getURL ? (filePath: string) => archives.getURL!(path + stripFilePrefix(filePath)) : undefined,
|
|
150
|
-
getDownloadAuthorization: archives.getDownloadAuthorization && ((...args: Args<typeof archives.getDownloadAuthorization>) => archives.getDownloadAuthorization!(...args)),
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
let archivesLogging = false;
|
|
155
|
-
export function enableArchivesLogging() {
|
|
156
|
-
archivesLogging = true;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
let cached = new Map<string, Archives>();
|
|
160
|
-
export function getArchives(rootPath = ""): Archives {
|
|
161
|
-
let value = cached.get(rootPath);
|
|
162
|
-
if (!value) {
|
|
163
|
-
value = getArchivesBase(rootPath);
|
|
164
|
-
cached.set(rootPath, value);
|
|
165
|
-
}
|
|
166
|
-
return value;
|
|
167
|
-
}
|
|
168
|
-
export function getArchivesBase(rootPath = ""): Archives {
|
|
169
|
-
let archives: Archives;
|
|
170
|
-
let domain = getDomain();
|
|
171
|
-
if (isNoNetwork()) {
|
|
172
|
-
archives = getArchivesLocal(domain);
|
|
173
|
-
archives = nestArchives(rootPath, archives);
|
|
174
|
-
} else {
|
|
175
|
-
archives = getArchivesBackblaze(domain);
|
|
176
|
-
archives = nestArchives(rootPath, archives);
|
|
177
|
-
// Why did we think we should always cache? We absolutely should not. Even if we were checking
|
|
178
|
-
// file hashes on every read (which we do not), it would still potentially fill the cache up
|
|
179
|
-
// with large temporary files we have no intention of using (which might evict entries we
|
|
180
|
-
// intend to use).
|
|
181
|
-
//archives = wrapArchivesWithCache(archives);
|
|
182
|
-
}
|
|
183
|
-
if (archivesLogging) {
|
|
184
|
-
archives.enableLogging();
|
|
185
|
-
}
|
|
186
|
-
return archives;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function hasArchivesPermissions() {
|
|
190
|
-
if (isNoNetwork()) {
|
|
191
|
-
return true;
|
|
192
|
-
}
|
|
193
|
-
return hasBackblazePermissions();
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (isNode()) {
|
|
197
|
-
if (isNoNetwork()) {
|
|
198
|
-
console.log("Primary data storage: " + magenta(getStorageDir()));
|
|
199
|
-
} else {
|
|
200
|
-
console.log("Config storage path: " + magenta(getStorageDir()));
|
|
201
|
-
console.log("Primary data storage: " + magenta(`backblaze:${getDomain()}`));
|
|
202
|
-
}
|
|
1
|
+
import { isNode } from "socket-function/src/misc";
|
|
2
|
+
import { getDomain, isNoNetwork } from "../config";
|
|
3
|
+
import { getStorageDir, getSubFolder } from "../fs";
|
|
4
|
+
import { getArchivesBackblaze, hasBackblazePermissions } from "./archivesBackBlaze";
|
|
5
|
+
import { getArchivesLocal } from "./archivesDisk";
|
|
6
|
+
import { magenta } from "socket-function/src/formatting/logColors";
|
|
7
|
+
import debugbreak from "debugbreak";
|
|
8
|
+
import { isClient } from "../config2";
|
|
9
|
+
import { wrapArchivesWithCache } from "./archiveCache";
|
|
10
|
+
import { Args } from "socket-function/src/types";
|
|
11
|
+
|
|
12
|
+
export interface Archives {
|
|
13
|
+
getDebugName(): string;
|
|
14
|
+
|
|
15
|
+
get(path: string, config?: {
|
|
16
|
+
range?: { start: number; end: number; };
|
|
17
|
+
retryCount?: number;
|
|
18
|
+
// Skips checking if the file exists on the remote. Only appropriate when the file name is fresh (recently obtained from find).
|
|
19
|
+
fastRead?: boolean;
|
|
20
|
+
}): Promise<Buffer | undefined>;
|
|
21
|
+
set(path: string, data: Buffer): Promise<void>;
|
|
22
|
+
del(path: string): Promise<void>;
|
|
23
|
+
|
|
24
|
+
append(path: string, data: Buffer): Promise<void>;
|
|
25
|
+
|
|
26
|
+
getInfo(path: string): Promise<{ writeTime: number; size: number; } | undefined>;
|
|
27
|
+
|
|
28
|
+
setLargeFile(config: { path: string; getNextData(): Promise<Buffer | undefined>; }): Promise<void>;
|
|
29
|
+
|
|
30
|
+
// For example findFileNames("ips/")
|
|
31
|
+
/** Returns to full paths. Returns paths WILL NOT end with / */
|
|
32
|
+
find(
|
|
33
|
+
prefix: string,
|
|
34
|
+
config?: {
|
|
35
|
+
shallow?: boolean;
|
|
36
|
+
// Defaults to files
|
|
37
|
+
type: "files" | "folders";
|
|
38
|
+
}
|
|
39
|
+
): Promise<string[]>;
|
|
40
|
+
findInfo(
|
|
41
|
+
prefix: string,
|
|
42
|
+
config?: {
|
|
43
|
+
shallow?: boolean;
|
|
44
|
+
// Defaults to files
|
|
45
|
+
type: "files" | "folders";
|
|
46
|
+
}
|
|
47
|
+
): Promise<{ path: string; createTime: number; size: number; }[]>;
|
|
48
|
+
|
|
49
|
+
move(config: {
|
|
50
|
+
path: string;
|
|
51
|
+
target: Archives;
|
|
52
|
+
targetPath: string;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
copy(config: {
|
|
55
|
+
path: string;
|
|
56
|
+
target: Archives;
|
|
57
|
+
targetPath: string;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
enableLogging(): void;
|
|
62
|
+
|
|
63
|
+
/** Might throw due to too long of a length. Should never throw due to characters, as we can always encode special characters. */
|
|
64
|
+
assertPathValid(path: string): Promise<void>;
|
|
65
|
+
|
|
66
|
+
getBaseArchives?: () => { parentPath: string; archives: Archives; } | undefined;
|
|
67
|
+
|
|
68
|
+
/** Get a download URL for a file. Only implemented for some archive types (like Backblaze). */
|
|
69
|
+
getURL?: (path: string) => Promise<string>;
|
|
70
|
+
|
|
71
|
+
// NOTE: This isn't part of getURL, as it is much more efficient to call it once and reuse the authorization. This is only for backblaze as of right now.
|
|
72
|
+
// NOTE: This also gives authorization for ALL files, so... ONLY use it for internal download links. If we need external links, we should use a public folder with hash links, or... make a new endpoint.
|
|
73
|
+
getDownloadAuthorization?: (config: {
|
|
74
|
+
validDurationInSeconds: number;
|
|
75
|
+
}) => Promise<{
|
|
76
|
+
bucketId: string;
|
|
77
|
+
fileNamePrefix: string;
|
|
78
|
+
authorizationToken: string;
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function createArchivesOverride<T extends Partial<Archives>>(
|
|
83
|
+
baseArchives: Archives,
|
|
84
|
+
overrideArchives: T
|
|
85
|
+
): T & Archives {
|
|
86
|
+
return {
|
|
87
|
+
getDebugName: () => baseArchives.getDebugName(),
|
|
88
|
+
get: (fileName: string, config) => baseArchives.get(fileName, config),
|
|
89
|
+
set: (fileName: string, data: Buffer) => baseArchives.set(fileName, data),
|
|
90
|
+
append: (fileName: string, data: Buffer) => baseArchives.append(fileName, data),
|
|
91
|
+
del: (fileName: string) => baseArchives.del(fileName),
|
|
92
|
+
getInfo: (fileName: string) => baseArchives.getInfo(fileName),
|
|
93
|
+
setLargeFile: (config) => baseArchives.setLargeFile(config),
|
|
94
|
+
find: async (prefix: string, config) => baseArchives.find(prefix, config),
|
|
95
|
+
findInfo: async (prefix: string, config) => baseArchives.findInfo(prefix, config),
|
|
96
|
+
enableLogging: () => baseArchives.enableLogging(),
|
|
97
|
+
move: (config) => baseArchives.move(config),
|
|
98
|
+
copy: (config) => baseArchives.copy(config),
|
|
99
|
+
assertPathValid: (path: string) => baseArchives.assertPathValid(path),
|
|
100
|
+
getBaseArchives: () => baseArchives.getBaseArchives?.() ?? ({ archives: baseArchives, parentPath: "" }),
|
|
101
|
+
getURL: baseArchives.getURL ? (filePath: string) => baseArchives.getURL!(filePath) : undefined,
|
|
102
|
+
getDownloadAuthorization: baseArchives.getDownloadAuthorization ? (config: { validDurationInSeconds: number }) => baseArchives.getDownloadAuthorization!(config) : undefined,
|
|
103
|
+
...overrideArchives,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function nestArchives(path: string, archives: Archives): Archives {
|
|
108
|
+
if (!path) return archives;
|
|
109
|
+
if (!path.endsWith("/")) {
|
|
110
|
+
path = path + "/";
|
|
111
|
+
}
|
|
112
|
+
function stripFilePrefix(file: string) {
|
|
113
|
+
if (file.startsWith("/")) {
|
|
114
|
+
return file.slice(1);
|
|
115
|
+
}
|
|
116
|
+
return file;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
getDebugName: () => archives.getDebugName() + "/" + path,
|
|
120
|
+
get: (fileName: string, config) => archives.get(path + stripFilePrefix(fileName), config),
|
|
121
|
+
setLargeFile: (config) => archives.setLargeFile({ ...config, path: path + stripFilePrefix(config.path) }),
|
|
122
|
+
set: (fileName: string, data: Buffer) => archives.set(path + stripFilePrefix(fileName), data),
|
|
123
|
+
append: (fileName: string, data: Buffer) => archives.append(path + stripFilePrefix(fileName), data),
|
|
124
|
+
del: (fileName: string) => archives.del(path + stripFilePrefix(fileName)),
|
|
125
|
+
getInfo: (fileName: string) => archives.getInfo(path + stripFilePrefix(fileName)),
|
|
126
|
+
find: async (prefix: string, config) => archives.find(path + prefix, config).then(x => x.map(x => x.slice(path.length))),
|
|
127
|
+
findInfo: async (prefix: string, config) => archives.findInfo(path + prefix, config).then(x => x.map(x => ({ path: x.path.slice(path.length), createTime: x.createTime, size: x.size }))),
|
|
128
|
+
enableLogging: () => archives.enableLogging(),
|
|
129
|
+
move: (config) => archives.move({
|
|
130
|
+
path: path + config.path,
|
|
131
|
+
target: config.target,
|
|
132
|
+
targetPath: config.targetPath,
|
|
133
|
+
}),
|
|
134
|
+
copy: (config) => archives.copy({
|
|
135
|
+
path: path + config.path,
|
|
136
|
+
target: config.target,
|
|
137
|
+
targetPath: config.targetPath,
|
|
138
|
+
}),
|
|
139
|
+
assertPathValid: (path: string) => archives.assertPathValid(path),
|
|
140
|
+
getBaseArchives: () => {
|
|
141
|
+
let result = { parentPath: path, archives };
|
|
142
|
+
let base = archives.getBaseArchives?.();
|
|
143
|
+
if (base) {
|
|
144
|
+
result.parentPath = base.parentPath + path;
|
|
145
|
+
result.archives = base.archives;
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
},
|
|
149
|
+
getURL: archives.getURL ? (filePath: string) => archives.getURL!(path + stripFilePrefix(filePath)) : undefined,
|
|
150
|
+
getDownloadAuthorization: archives.getDownloadAuthorization && ((...args: Args<typeof archives.getDownloadAuthorization>) => archives.getDownloadAuthorization!(...args)),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let archivesLogging = false;
|
|
155
|
+
export function enableArchivesLogging() {
|
|
156
|
+
archivesLogging = true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let cached = new Map<string, Archives>();
|
|
160
|
+
export function getArchives(rootPath = ""): Archives {
|
|
161
|
+
let value = cached.get(rootPath);
|
|
162
|
+
if (!value) {
|
|
163
|
+
value = getArchivesBase(rootPath);
|
|
164
|
+
cached.set(rootPath, value);
|
|
165
|
+
}
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
export function getArchivesBase(rootPath = ""): Archives {
|
|
169
|
+
let archives: Archives;
|
|
170
|
+
let domain = getDomain();
|
|
171
|
+
if (isNoNetwork()) {
|
|
172
|
+
archives = getArchivesLocal(domain);
|
|
173
|
+
archives = nestArchives(rootPath, archives);
|
|
174
|
+
} else {
|
|
175
|
+
archives = getArchivesBackblaze(domain);
|
|
176
|
+
archives = nestArchives(rootPath, archives);
|
|
177
|
+
// Why did we think we should always cache? We absolutely should not. Even if we were checking
|
|
178
|
+
// file hashes on every read (which we do not), it would still potentially fill the cache up
|
|
179
|
+
// with large temporary files we have no intention of using (which might evict entries we
|
|
180
|
+
// intend to use).
|
|
181
|
+
//archives = wrapArchivesWithCache(archives);
|
|
182
|
+
}
|
|
183
|
+
if (archivesLogging) {
|
|
184
|
+
archives.enableLogging();
|
|
185
|
+
}
|
|
186
|
+
return archives;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function hasArchivesPermissions() {
|
|
190
|
+
if (isNoNetwork()) {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
return hasBackblazePermissions();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (isNode()) {
|
|
197
|
+
if (isNoNetwork()) {
|
|
198
|
+
console.log("Primary data storage: " + magenta(getStorageDir()));
|
|
199
|
+
} else {
|
|
200
|
+
console.log("Config storage path: " + magenta(getStorageDir()));
|
|
201
|
+
console.log("Primary data storage: " + magenta(`backblaze:${getDomain()}`));
|
|
202
|
+
}
|
|
203
203
|
}
|