sliftutils 1.2.37 → 1.2.39
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/index.d.ts +28 -0
- package/misc/https/httpsCerts.d.ts +17 -0
- package/misc/https/httpsCerts.ts +4 -4
- package/package.json +1 -1
- package/storage/FileFolderAPI.d.ts +3 -0
- package/storage/FileFolderAPI.tsx +32 -2
- package/storage/IStorage.d.ts +4 -0
- package/storage/IStorage.ts +3 -0
- package/storage/IndexedDBFileFolderAPI.ts +6 -0
- package/storage/PrivateFileSystemStorage.d.ts +4 -0
- package/storage/PrivateFileSystemStorage.ts +11 -0
package/index.d.ts
CHANGED
|
@@ -156,6 +156,11 @@ declare module "sliftutils/misc/https/dns" {
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
declare module "sliftutils/misc/https/httpsCerts" {
|
|
159
|
+
/// <reference path="node-forge-ed25519.d.ts" />
|
|
160
|
+
/// <reference path="../../storage/storage.d.ts" />
|
|
161
|
+
/// <reference types="node" />
|
|
162
|
+
/// <reference types="node" />
|
|
163
|
+
import * as forge from "node-forge";
|
|
159
164
|
/** NOTE: We also generate the domain *.domain */
|
|
160
165
|
export declare const getHTTPSCert: {
|
|
161
166
|
(key: string): Promise<{
|
|
@@ -174,6 +179,18 @@ declare module "sliftutils/misc/https/httpsCerts" {
|
|
|
174
179
|
cert: string;
|
|
175
180
|
}> | undefined;
|
|
176
181
|
};
|
|
182
|
+
export declare const getAccountKey: (domain: string) => Promise<string>;
|
|
183
|
+
export declare function parseCert(PEMorDER: string | Buffer): forge.pki.Certificate;
|
|
184
|
+
export declare function normalizeCertToPEM(PEMorDER: string | Buffer): string;
|
|
185
|
+
export declare function generateCert(config: {
|
|
186
|
+
accountKey: string;
|
|
187
|
+
domain: string;
|
|
188
|
+
altDomains?: string[];
|
|
189
|
+
}): Promise<{
|
|
190
|
+
domains: string[];
|
|
191
|
+
key: string;
|
|
192
|
+
cert: string;
|
|
193
|
+
}>;
|
|
177
194
|
|
|
178
195
|
}
|
|
179
196
|
|
|
@@ -929,6 +946,9 @@ declare module "sliftutils/storage/FileFolderAPI" {
|
|
|
929
946
|
size: number;
|
|
930
947
|
lastModified: number;
|
|
931
948
|
arrayBuffer(): Promise<ArrayBuffer>;
|
|
949
|
+
slice(start: number, end: number): {
|
|
950
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
951
|
+
};
|
|
932
952
|
}>;
|
|
933
953
|
createWritable(config?: {
|
|
934
954
|
keepExistingData?: boolean;
|
|
@@ -1026,6 +1046,10 @@ declare module "sliftutils/storage/IStorage" {
|
|
|
1026
1046
|
};
|
|
1027
1047
|
export type IStorageRaw = {
|
|
1028
1048
|
get(key: string): Promise<Buffer | undefined>;
|
|
1049
|
+
getRange(key: string, config: {
|
|
1050
|
+
start: number;
|
|
1051
|
+
end: number;
|
|
1052
|
+
}): Promise<Buffer | undefined>;
|
|
1029
1053
|
append(key: string, value: Buffer): Promise<void>;
|
|
1030
1054
|
set(key: string, value: Buffer): Promise<void>;
|
|
1031
1055
|
remove(key: string): Promise<void>;
|
|
@@ -1117,6 +1141,10 @@ declare module "sliftutils/storage/PrivateFileSystemStorage" {
|
|
|
1117
1141
|
private getFileHandle;
|
|
1118
1142
|
private fileExists;
|
|
1119
1143
|
get(key: string): Promise<Buffer | undefined>;
|
|
1144
|
+
getRange(key: string, config: {
|
|
1145
|
+
start: number;
|
|
1146
|
+
end: number;
|
|
1147
|
+
}): Promise<Buffer | undefined>;
|
|
1120
1148
|
set(key: string, value: Buffer): Promise<void>;
|
|
1121
1149
|
append(key: string, value: Buffer): Promise<void>;
|
|
1122
1150
|
remove(key: string): Promise<void>;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/// <reference path="node-forge-ed25519.d.ts" />
|
|
2
|
+
/// <reference path="../../storage/storage.d.ts" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
5
|
+
import * as forge from "node-forge";
|
|
1
6
|
/** NOTE: We also generate the domain *.domain */
|
|
2
7
|
export declare const getHTTPSCert: {
|
|
3
8
|
(key: string): Promise<{
|
|
@@ -16,3 +21,15 @@ export declare const getHTTPSCert: {
|
|
|
16
21
|
cert: string;
|
|
17
22
|
}> | undefined;
|
|
18
23
|
};
|
|
24
|
+
export declare const getAccountKey: (domain: string) => Promise<string>;
|
|
25
|
+
export declare function parseCert(PEMorDER: string | Buffer): forge.pki.Certificate;
|
|
26
|
+
export declare function normalizeCertToPEM(PEMorDER: string | Buffer): string;
|
|
27
|
+
export declare function generateCert(config: {
|
|
28
|
+
accountKey: string;
|
|
29
|
+
domain: string;
|
|
30
|
+
altDomains?: string[];
|
|
31
|
+
}): Promise<{
|
|
32
|
+
domains: string[];
|
|
33
|
+
key: string;
|
|
34
|
+
cert: string;
|
|
35
|
+
}>;
|
package/misc/https/httpsCerts.ts
CHANGED
|
@@ -91,7 +91,7 @@ export const getHTTPSCert = cache(async (domain: string): Promise<{ key: string;
|
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
const getAccountKey = async function getAccountKey(domain: string) {
|
|
94
|
+
export const getAccountKey = async function getAccountKey(domain: string) {
|
|
95
95
|
let accountKey = getKeyStore<string>(domain, "letsEncryptAccountKey");
|
|
96
96
|
let secret = await accountKey.get();
|
|
97
97
|
if (!secret) {
|
|
@@ -105,11 +105,11 @@ const getAccountKey = async function getAccountKey(domain: string) {
|
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
function parseCert(PEMorDER: string | Buffer) {
|
|
108
|
+
export function parseCert(PEMorDER: string | Buffer) {
|
|
109
109
|
return forge.pki.certificateFromPem(normalizeCertToPEM(PEMorDER));
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
function normalizeCertToPEM(PEMorDER: string | Buffer): string {
|
|
112
|
+
export function normalizeCertToPEM(PEMorDER: string | Buffer): string {
|
|
113
113
|
if (PEMorDER.toString().startsWith("-----BEGIN CERTIFICATE-----")) {
|
|
114
114
|
return PEMorDER.toString();
|
|
115
115
|
}
|
|
@@ -118,7 +118,7 @@ function normalizeCertToPEM(PEMorDER: string | Buffer): string {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
|
|
121
|
-
async function generateCert(config: {
|
|
121
|
+
export async function generateCert(config: {
|
|
122
122
|
accountKey: string;
|
|
123
123
|
domain: string;
|
|
124
124
|
altDomains?: string[];
|
package/package.json
CHANGED
|
@@ -40,6 +40,9 @@ type FileWrapper = {
|
|
|
40
40
|
size: number;
|
|
41
41
|
lastModified: number;
|
|
42
42
|
arrayBuffer(): Promise<ArrayBuffer>;
|
|
43
|
+
// Matches Blob.slice (which the native File object provides), so the browser
|
|
44
|
+
// implementation works vanilla. End is exclusive, both clamped to the file size.
|
|
45
|
+
slice(start: number, end: number): { arrayBuffer(): Promise<ArrayBuffer> };
|
|
43
46
|
}>;
|
|
44
47
|
createWritable(config?: { keepExistingData?: boolean }): Promise<{
|
|
45
48
|
seek(offset: number): Promise<void>;
|
|
@@ -99,13 +102,29 @@ class NodeJSFileHandleWrapper implements FileWrapper {
|
|
|
99
102
|
|
|
100
103
|
async getFile() {
|
|
101
104
|
const stats = await fs.promises.stat(this.filePath);
|
|
105
|
+
const filePath = this.filePath;
|
|
102
106
|
return {
|
|
103
107
|
size: stats.size,
|
|
104
108
|
lastModified: stats.mtimeMs,
|
|
105
109
|
arrayBuffer: async () => {
|
|
106
|
-
const buffer = await fs.promises.readFile(
|
|
110
|
+
const buffer = await fs.promises.readFile(filePath);
|
|
107
111
|
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
108
|
-
}
|
|
112
|
+
},
|
|
113
|
+
slice: (start: number, end: number) => ({
|
|
114
|
+
arrayBuffer: async () => {
|
|
115
|
+
const clampedStart = Math.min(Math.max(start, 0), stats.size);
|
|
116
|
+
const clampedEnd = Math.min(Math.max(end, clampedStart), stats.size);
|
|
117
|
+
const length = clampedEnd - clampedStart;
|
|
118
|
+
const fileHandle = await fs.promises.open(filePath, "r");
|
|
119
|
+
try {
|
|
120
|
+
const buffer = Buffer.alloc(length);
|
|
121
|
+
await fileHandle.read(buffer, 0, length, clampedStart);
|
|
122
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
123
|
+
} finally {
|
|
124
|
+
await fileHandle.close();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
})
|
|
109
128
|
};
|
|
110
129
|
}
|
|
111
130
|
|
|
@@ -440,6 +459,17 @@ function wrapHandleFiles(handle: DirectoryWrapper): IStorageRaw {
|
|
|
440
459
|
}
|
|
441
460
|
},
|
|
442
461
|
|
|
462
|
+
async getRange(key: string, config: { start: number; end: number }): Promise<Buffer | undefined> {
|
|
463
|
+
try {
|
|
464
|
+
const file = await handle.getFileHandle(key);
|
|
465
|
+
const fileContent = await file.getFile();
|
|
466
|
+
const arrayBuffer = await fileContent.slice(config.start, config.end).arrayBuffer();
|
|
467
|
+
return Buffer.from(arrayBuffer);
|
|
468
|
+
} catch (error) {
|
|
469
|
+
return undefined;
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
|
|
443
473
|
async append(key: string, value: Buffer): Promise<void> {
|
|
444
474
|
await appendQueue(key)(async () => {
|
|
445
475
|
// NOTE: Interesting point. Chrome doesn't optimize this to be an append, and instead
|
package/storage/IStorage.d.ts
CHANGED
|
@@ -27,6 +27,10 @@ export type IStorage<T> = {
|
|
|
27
27
|
};
|
|
28
28
|
export type IStorageRaw = {
|
|
29
29
|
get(key: string): Promise<Buffer | undefined>;
|
|
30
|
+
getRange(key: string, config: {
|
|
31
|
+
start: number;
|
|
32
|
+
end: number;
|
|
33
|
+
}): Promise<Buffer | undefined>;
|
|
30
34
|
append(key: string, value: Buffer): Promise<void>;
|
|
31
35
|
set(key: string, value: Buffer): Promise<void>;
|
|
32
36
|
remove(key: string): Promise<void>;
|
package/storage/IStorage.ts
CHANGED
|
@@ -29,6 +29,9 @@ export type IStorage<T> = {
|
|
|
29
29
|
// (/ makes a folder). And there are even more rules, such as lengths per folder, etc, etc.
|
|
30
30
|
export type IStorageRaw = {
|
|
31
31
|
get(key: string): Promise<Buffer | undefined>;
|
|
32
|
+
// Reads bytes in the range [start, end) (end is exclusive, clamped to the file size).
|
|
33
|
+
// Returns undefined if the file doesn't exist.
|
|
34
|
+
getRange(key: string, config: { start: number; end: number }): Promise<Buffer | undefined>;
|
|
32
35
|
// May or may not be efficient in the underlying storage
|
|
33
36
|
append(key: string, value: Buffer): Promise<void>;
|
|
34
37
|
set(key: string, value: Buffer): Promise<void>;
|
|
@@ -44,6 +44,12 @@ class VirtualFileStorage implements FileStorage {
|
|
|
44
44
|
return badBuffer;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
async getRange(key: string, config: { start: number; end: number }): Promise<Buffer | undefined> {
|
|
48
|
+
const fullBuffer = await this.get(key);
|
|
49
|
+
if (!fullBuffer) return undefined;
|
|
50
|
+
return fullBuffer.subarray(config.start, config.end);
|
|
51
|
+
}
|
|
52
|
+
|
|
47
53
|
async append(key: string, value: Buffer): Promise<void> {
|
|
48
54
|
const store = this.getStore("readwrite");
|
|
49
55
|
const fullPath = this.id + key;
|
|
@@ -11,6 +11,10 @@ export declare class PrivateFileSystemStorage implements IStorageRaw {
|
|
|
11
11
|
private getFileHandle;
|
|
12
12
|
private fileExists;
|
|
13
13
|
get(key: string): Promise<Buffer | undefined>;
|
|
14
|
+
getRange(key: string, config: {
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
}): Promise<Buffer | undefined>;
|
|
14
18
|
set(key: string, value: Buffer): Promise<void>;
|
|
15
19
|
append(key: string, value: Buffer): Promise<void>;
|
|
16
20
|
remove(key: string): Promise<void>;
|
|
@@ -114,6 +114,17 @@ export class PrivateFileSystemStorage implements IStorageRaw {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
public async getRange(key: string, config: { start: number; end: number }): Promise<Buffer | undefined> {
|
|
118
|
+
const fileHandle = await this.getFileHandle(key, false);
|
|
119
|
+
if (!fileHandle) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const file = await fileHandle.getFile();
|
|
124
|
+
const arrayBuffer = await file.slice(config.start, config.end).arrayBuffer();
|
|
125
|
+
return Buffer.from(arrayBuffer);
|
|
126
|
+
}
|
|
127
|
+
|
|
117
128
|
public async set(key: string, value: Buffer): Promise<void> {
|
|
118
129
|
try {
|
|
119
130
|
const fileHandle = await this.getFileHandle(key, true);
|