@filefreak.io/sdk 0.1.0 → 0.3.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/README.md +43 -3
- package/dist/client.d.ts +3 -1
- package/dist/client.js +15 -11
- package/dist/generated.d.ts +134 -23
- package/dist/generated.js +43 -21
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/links.d.ts +72 -0
- package/dist/links.js +355 -0
- package/dist/node.d.ts +20 -0
- package/dist/node.js +79 -6
- package/dist/reader.d.ts +76 -0
- package/dist/reader.js +510 -0
- package/dist/shards.d.ts +3 -3
- package/dist/uploads.d.ts +2 -1
- package/dist/uploads.js +153 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,8 +6,10 @@ later and in browsers. No dependencies.
|
|
|
6
6
|
Every endpoint is a function, typed from the same table the API is built
|
|
7
7
|
from. Around them: uploads sent straight to storage in parts and carried on
|
|
8
8
|
after an interruption, downloads fetched in ranges, listings and changes read
|
|
9
|
-
to the end,
|
|
10
|
-
|
|
9
|
+
to the end, files under Shard Protection sealed as they are sent and read
|
|
10
|
+
through their maps, what a share link holds saved with no key, and requests sent again only when that
|
|
11
|
+
cannot make anything twice. The reference is at
|
|
12
|
+
https://filefreak.io/developers/reference.
|
|
11
13
|
|
|
12
14
|
## On a server
|
|
13
15
|
|
|
@@ -30,6 +32,12 @@ const bytes = await ff.bytes(file.id); // for a file small enough to hold in mem
|
|
|
30
32
|
`fromPath` reads the file a part at a time as it is sent, so a file larger
|
|
31
33
|
than memory is fine. `toPath` writes beside the file and gives it its name
|
|
32
34
|
only once every byte is there: a download that fails leaves nothing behind.
|
|
35
|
+
A file under Shard Protection has no address, and `download` and `bytes`
|
|
36
|
+
read it through its map instead, each fragment checked as it arrives.
|
|
37
|
+
Into a folder under Shard Protection, `upload` seals each part with the
|
|
38
|
+
file's own key before it is sent, so none of the file is ever plain in
|
|
39
|
+
storage. The key is asked of the API for the upload and kept nowhere, and
|
|
40
|
+
an upload carried on asks which fragments storage has before it sends any.
|
|
33
41
|
|
|
34
42
|
Keep keys on a server. A key sent from a web page is refused.
|
|
35
43
|
|
|
@@ -66,12 +74,44 @@ folder asked for, for a minute to an hour. It is checked against its key on
|
|
|
66
74
|
every request, so revoking the key stops its tokens at once. A token cannot
|
|
67
75
|
make another.
|
|
68
76
|
|
|
77
|
+
## Saving from a link
|
|
78
|
+
|
|
79
|
+
`get` saves what a share link or a public page holds. It needs no key, and
|
|
80
|
+
sends nothing that says who is asking: no key, and from a browser no
|
|
81
|
+
cookies. A file goes into one sink; a folder needs somewhere for each of its
|
|
82
|
+
files, which `toFolder` makes on disk.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { get } from "@filefreak.io/sdk";
|
|
86
|
+
import { toFolder, toPath } from "@filefreak.io/sdk/node";
|
|
87
|
+
|
|
88
|
+
await get("https://filefreak.link/share/...", await toPath("report.pdf"));
|
|
89
|
+
|
|
90
|
+
const got = await get("https://filefreak.link/share/...", toFolder("downloads"), {
|
|
91
|
+
password: "open sesame", // for a link that has one
|
|
92
|
+
onProgress: (written, total) => console.log(`${written} of ${total} bytes`),
|
|
93
|
+
});
|
|
94
|
+
console.log(`${got.files.length} files, ${got.sizeBytes} bytes`);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
It takes a share link, a public file's or folder's page, and a file's direct
|
|
98
|
+
address. A folder comes whole: each file goes to the sink the function makes
|
|
99
|
+
for it, given its name and the folders it is in. Each file saved is one of
|
|
100
|
+
the link's downloads, as on its page, and a link with fewer left than there
|
|
101
|
+
are files saves nothing (`not_enough_downloads`). A file under Shard
|
|
102
|
+
Protection is read through the link's map, and counted once.
|
|
103
|
+
|
|
104
|
+
Every name a link gives is its sharer's, and can be anything: `../../.bashrc`,
|
|
105
|
+
or one that reads backwards. `toFolder` makes each one safe with `safeName`
|
|
106
|
+
before writing, and never writes outside the folder it is given. A program
|
|
107
|
+
that names files from a link itself should use `safeName` too.
|
|
108
|
+
|
|
69
109
|
## Every endpoint
|
|
70
110
|
|
|
71
111
|
The functions are grouped as the reference groups the endpoints:
|
|
72
112
|
`ff.files`, `ff.folders`, `ff.tree`, `ff.changes`, `ff.uploads`, `ff.usage`,
|
|
73
113
|
`ff.me`, `ff.tokens` and `ff.shares` (share links, which only a device signed
|
|
74
|
-
in with `
|
|
114
|
+
in with `filefreak login` may make). Ids in the address come first, then the body or
|
|
75
115
|
the query, then options:
|
|
76
116
|
|
|
77
117
|
```ts
|
package/dist/client.d.ts
CHANGED
|
@@ -66,7 +66,9 @@ export declare class FileFreak {
|
|
|
66
66
|
/**
|
|
67
67
|
* Fetch a file straight from storage into `sink`: as up to six ranges at
|
|
68
68
|
* once for a large one. One download address is asked for, so the file is
|
|
69
|
-
* counted toward the month's downloads once.
|
|
69
|
+
* counted toward the month's downloads once. A file under Shard Protection
|
|
70
|
+
* has no address, and is read through its map instead (files.shards), each
|
|
71
|
+
* fragment checked as it arrives. Resolves to the file.
|
|
70
72
|
*/
|
|
71
73
|
download(id: string, sink: Sink, options?: DownloadOptions): Promise<Item>;
|
|
72
74
|
/** A file's bytes, in memory: for a file small enough to hold. */
|
package/dist/client.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// ranges, and reading a listing or the changes to the end.
|
|
5
5
|
import { bind, OPERATIONS, } from "./generated.js";
|
|
6
6
|
import { fetchRanges } from "./ranges.js";
|
|
7
|
+
import { asItIsKept, readProtected } from "./reader.js";
|
|
7
8
|
import { FileFreakError, sleep, Transport } from "./transport.js";
|
|
8
9
|
import { upload } from "./uploads.js";
|
|
9
10
|
/** How long a follow of the changes waits for one before asking again, unless told. */
|
|
@@ -90,7 +91,9 @@ export class FileFreak {
|
|
|
90
91
|
/**
|
|
91
92
|
* Fetch a file straight from storage into `sink`: as up to six ranges at
|
|
92
93
|
* once for a large one. One download address is asked for, so the file is
|
|
93
|
-
* counted toward the month's downloads once.
|
|
94
|
+
* counted toward the month's downloads once. A file under Shard Protection
|
|
95
|
+
* has no address, and is read through its map instead (files.shards), each
|
|
96
|
+
* fragment checked as it arrives. Resolves to the file.
|
|
94
97
|
*/
|
|
95
98
|
async download(id, sink, options = {}) {
|
|
96
99
|
try {
|
|
@@ -117,18 +120,19 @@ export class FileFreak {
|
|
|
117
120
|
// Nothing to fetch, and an address would count a download of nothing.
|
|
118
121
|
if (item.sizeBytes === 0)
|
|
119
122
|
return;
|
|
120
|
-
const {
|
|
121
|
-
const progress =
|
|
122
|
-
await
|
|
123
|
-
url,
|
|
124
|
-
sizeBytes: item.sizeBytes,
|
|
123
|
+
const { signal, onProgress } = options;
|
|
124
|
+
const progress = onProgress && ((written) => onProgress(written, item.sizeBytes));
|
|
125
|
+
await asItIsKept(item.protected, async () => {
|
|
126
|
+
const { url } = await this.files.downloadUrl(item.id, {}, { signal });
|
|
127
|
+
await fetchRanges({ url, sizeBytes: item.sizeBytes, sink, signal, progress, ranges: options.ranges, fetch: this.transport.fetch, sleep: (ms) => sleep(ms, signal) });
|
|
128
|
+
}, () => readProtected({
|
|
129
|
+
pages: (from, pageSignal) => this.files.shards(item.id, { from }, { signal: pageSignal }),
|
|
125
130
|
sink,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
sizeBytes: item.sizeBytes,
|
|
132
|
+
signal,
|
|
133
|
+
progress,
|
|
129
134
|
fetch: this.transport.fetch,
|
|
130
|
-
|
|
131
|
-
});
|
|
135
|
+
}));
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
/** Every item in a listing, a page at a time. */
|
package/dist/generated.d.ts
CHANGED
|
@@ -23,6 +23,10 @@ export interface Item {
|
|
|
23
23
|
revision: number;
|
|
24
24
|
/** The SHA-256 the uploader gave when it completed the upload of this content, in lower-case hex, or null. The uploader's word: this service never sees a file's bytes and does not check it. */
|
|
25
25
|
clientSha256: string | null;
|
|
26
|
+
/** Whether the file is under Shard Protection: kept as sealed fragments, and read through its map (files.shards) rather than from an address. */
|
|
27
|
+
protected: boolean;
|
|
28
|
+
/** Its own Shard Protection setting. inherit follows the nearest folder above it that has one, and with none the drive's default: the app's, which its owner turns on from the app's page, or for a device the account's. The nearest setting wins. A file is converted within a few minutes of a change, and protected says when it has been. */
|
|
29
|
+
protection: "on" | "off" | "inherit";
|
|
26
30
|
createdAt: string;
|
|
27
31
|
updatedAt: string;
|
|
28
32
|
}
|
|
@@ -122,7 +126,7 @@ export interface SiteDeploy {
|
|
|
122
126
|
number: number;
|
|
123
127
|
/** uploading: files are being declared and sent. ready: every file is stored, and it can be made live. cancelled or expired: given up on, and it holds nothing. */
|
|
124
128
|
state: "uploading" | "ready" | "cancelled" | "expired";
|
|
125
|
-
/** upload: sent by
|
|
129
|
+
/** upload: sent from a computer, by the CLI or a program. folder: copied from a folder in the drive, on the website. */
|
|
126
130
|
source: "upload" | "folder";
|
|
127
131
|
fileCount: number;
|
|
128
132
|
/** What its files add up to. */
|
|
@@ -147,6 +151,36 @@ export interface SendTo {
|
|
|
147
151
|
/** When the address stops working. sites.sendAgain gives fresh ones. */
|
|
148
152
|
expiresAt: string;
|
|
149
153
|
}
|
|
154
|
+
/** A page of a protected file's map: its key, and where each fragment is. */
|
|
155
|
+
export interface ShardMap {
|
|
156
|
+
/** The content's own id, which each fragment's check is bound to with its place and the count. */
|
|
157
|
+
contentId: string;
|
|
158
|
+
/** The file's size. */
|
|
159
|
+
sizeBytes: number;
|
|
160
|
+
/** How many bytes of the file each fragment holds, except the last, which holds what remains. */
|
|
161
|
+
fragmentBytes: number;
|
|
162
|
+
/** How many fragments the file is. */
|
|
163
|
+
count: number;
|
|
164
|
+
/** The file's own key, in base64: 32 bytes, which open its fragments. In this answer and nowhere else. */
|
|
165
|
+
key: string;
|
|
166
|
+
name: string;
|
|
167
|
+
contentType: string | null;
|
|
168
|
+
/** The file's revision whose content this is. Its fragments never change, however late they are read. */
|
|
169
|
+
revision: number;
|
|
170
|
+
/** The first place on this page. */
|
|
171
|
+
from: number;
|
|
172
|
+
/** Up to 1000, in order of place. */
|
|
173
|
+
fragments: Array<{
|
|
174
|
+
/** Counted from zero. Its bytes of the file begin at place times fragmentBytes. */
|
|
175
|
+
place: number;
|
|
176
|
+
/** Where to fetch the stored fragment, with a plain GET and no key: the address is the permission. */
|
|
177
|
+
url: string;
|
|
178
|
+
}>;
|
|
179
|
+
/** The from of the next page, or null when this page reaches the last fragment. */
|
|
180
|
+
next: number | null;
|
|
181
|
+
/** When this page's addresses stop working. Ask for the page again before then, from the first fragment not yet fetched. */
|
|
182
|
+
expiresAt: string;
|
|
183
|
+
}
|
|
150
184
|
/** What GET /v1/files takes in its query. */
|
|
151
185
|
export type FilesListQuery = {
|
|
152
186
|
/** The folder to list. Left out, the top of the app (or of the folder the key is confined to). */
|
|
@@ -182,6 +216,8 @@ export type FilesUpdateBody = {
|
|
|
182
216
|
parentId?: string | null;
|
|
183
217
|
/** public, private, or inherit to follow the folder it is in. */
|
|
184
218
|
visibility?: "private" | "public" | "inherit";
|
|
219
|
+
/** on, off, or inherit to follow the folder it is in. */
|
|
220
|
+
protection?: "on" | "off" | "inherit";
|
|
185
221
|
};
|
|
186
222
|
/** What PATCH /v1/files/:id answers with. */
|
|
187
223
|
export type FilesUpdateAnswer = {
|
|
@@ -272,6 +308,8 @@ export type UploadsBeginBody = {
|
|
|
272
308
|
/** The block's SHA-256 in hex. */
|
|
273
309
|
sha256: string;
|
|
274
310
|
}>;
|
|
311
|
+
/** true when this program can seal fragments as it sends them, as the SDK and the CLI do. Into a protected place the answer's shards is then set, and each part is a fragment. */
|
|
312
|
+
protectable?: boolean;
|
|
275
313
|
};
|
|
276
314
|
/** What POST /v1/uploads answers with. */
|
|
277
315
|
export type UploadsBeginAnswer = {
|
|
@@ -280,6 +318,15 @@ export type UploadsBeginAnswer = {
|
|
|
280
318
|
parts: Array<Part>;
|
|
281
319
|
/** For an upload begun with blocks: the parts not to send, because storage has them already, from the file this replaces, or because they repeat a block an earlier part sends. Empty otherwise. Nothing is taken from the file this replaces when the key may not read it, when the file has not been opened or changed in 90 days, or when copying it would take the account past 1000 GB copied this way in an hour: every block is sent then. */
|
|
282
320
|
reused: Array<number>;
|
|
321
|
+
/** Set when the upload is sealed as it is sent: how the file is cut into fragments. The key to seal them with is given by uploads.get. Null for an upload sent as it is. */
|
|
322
|
+
shards: {
|
|
323
|
+
/** The content's own id, which each fragment's seal is bound to with its place and the count. */
|
|
324
|
+
contentId: string;
|
|
325
|
+
/** How many bytes of the file each fragment holds, except the last, which holds what remains. */
|
|
326
|
+
fragmentBytes: number;
|
|
327
|
+
/** How many fragments, one to each part. */
|
|
328
|
+
count: number;
|
|
329
|
+
} | null;
|
|
283
330
|
};
|
|
284
331
|
/** What GET /v1/uploads/:id answers with. */
|
|
285
332
|
export type UploadsGetAnswer = {
|
|
@@ -293,6 +340,17 @@ export type UploadsGetAnswer = {
|
|
|
293
340
|
}> | null;
|
|
294
341
|
/** As in the answer that began the upload: the parts not to send. */
|
|
295
342
|
reused: Array<number>;
|
|
343
|
+
/** For an upload sealed as it is sent: how the file is cut, and the key to seal each fragment with. Null for an upload sent as it is, and for one that has ended. */
|
|
344
|
+
shards: {
|
|
345
|
+
/** The content's own id, which each fragment's seal is bound to with its place and the count. */
|
|
346
|
+
contentId: string;
|
|
347
|
+
/** The file's own key, in base64: 32 bytes, which open its fragments. In this answer and nowhere else. */
|
|
348
|
+
key: string;
|
|
349
|
+
/** How many bytes of the file each fragment holds, except the last, which holds what remains. */
|
|
350
|
+
fragmentBytes: number;
|
|
351
|
+
/** How many fragments, one to each part. */
|
|
352
|
+
count: number;
|
|
353
|
+
} | null;
|
|
296
354
|
};
|
|
297
355
|
/** What GET /v1/uploads/:id/parts takes in its query. */
|
|
298
356
|
export type UploadsPartsQuery = {
|
|
@@ -304,6 +362,20 @@ export type UploadsPartsQuery = {
|
|
|
304
362
|
export type UploadsPartsAnswer = {
|
|
305
363
|
parts: Array<Part>;
|
|
306
364
|
};
|
|
365
|
+
/** What POST /v1/uploads/:id/fragments takes as its body. */
|
|
366
|
+
export type UploadsFragmentsBody = {
|
|
367
|
+
/** The places of fragments that have been sent: up to 100 at a time. */
|
|
368
|
+
places: Array<number>;
|
|
369
|
+
};
|
|
370
|
+
/** What POST /v1/uploads/:id/fragments answers with. */
|
|
371
|
+
export type UploadsFragmentsAnswer = {
|
|
372
|
+
/** At their own names, the size their places hold, and recorded. Never send them again. */
|
|
373
|
+
recorded: Array<number>;
|
|
374
|
+
/** Still being copied, or being confirmed by another request. Ask again shortly. */
|
|
375
|
+
pending: Array<number>;
|
|
376
|
+
/** Not in storage, or not their size and removed. Seal each again, under a new nonce, and send and confirm it. */
|
|
377
|
+
resend: Array<number>;
|
|
378
|
+
};
|
|
307
379
|
/** What POST /v1/uploads/:id/complete takes as its body. */
|
|
308
380
|
export type UploadsCompleteBody = {
|
|
309
381
|
/** The file's SHA-256 in hex, as you worked it out. Kept with the file as your word, since this service never sees the bytes, and given back as clientSha256, so a copy can be checked later without reading the file again. */
|
|
@@ -328,6 +400,13 @@ export type FilesDownloadUrlAnswer = {
|
|
|
328
400
|
inline: boolean;
|
|
329
401
|
contentType: string | null;
|
|
330
402
|
};
|
|
403
|
+
/** What GET /v1/files/:id/shards takes in its query. */
|
|
404
|
+
export type FilesShardsQuery = {
|
|
405
|
+
/** The first fragment wanted, counted from zero: 0, or the `next` of the page before. */
|
|
406
|
+
from?: number;
|
|
407
|
+
};
|
|
408
|
+
/** What GET /v1/files/:id/shards answers with. */
|
|
409
|
+
export type FilesShardsAnswer = ShardMap;
|
|
331
410
|
/** What GET /v1/files/:id/image takes in its query. */
|
|
332
411
|
export type FilesImageQuery = {
|
|
333
412
|
/** One of 64, 128, 256, 512, 1024. */
|
|
@@ -367,7 +446,7 @@ export type UsageGetAnswer = {
|
|
|
367
446
|
};
|
|
368
447
|
/** What GET /v1/me answers with. */
|
|
369
448
|
export type MeGetAnswer = {
|
|
370
|
-
/** key: an app's key, on a server. token: a token a key made for a web page. device: a person, signed in with
|
|
449
|
+
/** key: an app's key, on a server. token: a token a key made for a web page. device: a person, signed in with filefreak login. */
|
|
371
450
|
via: "key" | "token" | "device";
|
|
372
451
|
account: {
|
|
373
452
|
username: string;
|
|
@@ -603,6 +682,12 @@ export declare const OPERATIONS: {
|
|
|
603
682
|
readonly idempotent: false;
|
|
604
683
|
readonly repeatable: false;
|
|
605
684
|
};
|
|
685
|
+
readonly "uploads.fragments": {
|
|
686
|
+
readonly method: "POST";
|
|
687
|
+
readonly path: "/v1/uploads/:id/fragments";
|
|
688
|
+
readonly idempotent: false;
|
|
689
|
+
readonly repeatable: true;
|
|
690
|
+
};
|
|
606
691
|
readonly "uploads.complete": {
|
|
607
692
|
readonly method: "POST";
|
|
608
693
|
readonly path: "/v1/uploads/:id/complete";
|
|
@@ -621,6 +706,12 @@ export declare const OPERATIONS: {
|
|
|
621
706
|
readonly idempotent: false;
|
|
622
707
|
readonly repeatable: false;
|
|
623
708
|
};
|
|
709
|
+
readonly "files.shards": {
|
|
710
|
+
readonly method: "GET";
|
|
711
|
+
readonly path: "/v1/files/:id/shards";
|
|
712
|
+
readonly idempotent: false;
|
|
713
|
+
readonly repeatable: false;
|
|
714
|
+
};
|
|
624
715
|
readonly "files.image": {
|
|
625
716
|
readonly method: "GET";
|
|
626
717
|
readonly path: "/v1/files/:id/image";
|
|
@@ -758,6 +849,8 @@ export declare function bind(call: Call): {
|
|
|
758
849
|
*
|
|
759
850
|
* Any of the three, in one request. They are applied in that order, each as its own change: if the second is refused the first has still happened, and the answer says which was refused. Moving a folder moves everything in it and is one change however much that is. Making a folder public makes everything in it public, except what has a setting of its own.
|
|
760
851
|
*
|
|
852
|
+
* protection is a fourth, applied last: on puts the file or folder under Shard Protection, off takes it out, and inherit has it follow the folder it is in. A folder's setting reaches everything in it that has none of its own. Turning it on is refused while the account's plan does not include it (402 shard_protection_needs_pro); turning it off never is. Nothing is converted in this request: the service converts each file within a few minutes, and its protected says when. A key confined to a folder decides about what is in it, and not about the folder.
|
|
853
|
+
*
|
|
761
854
|
* PATCH /v1/files/:id. Needs the scope files:write.
|
|
762
855
|
*/
|
|
763
856
|
update: (id: string, body: FilesUpdateBody, options?: CallOptions) => Promise<FilesUpdateAnswer>;
|
|
@@ -780,11 +873,19 @@ export declare function bind(call: Call): {
|
|
|
780
873
|
/**
|
|
781
874
|
* An address to download a file from.
|
|
782
875
|
*
|
|
783
|
-
* A short-lived address on storage itself. Anybody holding it can fetch the file until it expires, with no key, so it can be handed to a browser. Each one issued counts the file's size toward the month's downloads. For an address that does not expire, make the file public and use its publicUrl. A file under Shard Protection is answered with 409 shard_protected
|
|
876
|
+
* A short-lived address on storage itself. Anybody holding it can fetch the file until it expires, with no key, so it can be handed to a browser. Each one issued counts the file's size toward the month's downloads. For an address that does not expire, make the file public and use its publicUrl. A file under Shard Protection has no address: it is answered with 409 shard_protected, and read through its map with files.shards.
|
|
784
877
|
*
|
|
785
878
|
* GET /v1/files/:id/download. Needs the scope files:read.
|
|
786
879
|
*/
|
|
787
880
|
downloadUrl: (id: string, query?: FilesDownloadUrlQuery, options?: CallOptions) => Promise<FilesDownloadUrlAnswer>;
|
|
881
|
+
/**
|
|
882
|
+
* A protected file's map.
|
|
883
|
+
*
|
|
884
|
+
* A file under Shard Protection is kept as fragments, each sealed with the file's own key and stored across several storage accounts. Its map says where each fragment is, up to 1,000 at a time, with the key. Fetch each fragment from its address (no key: the address is the permission), check and open it as the SDK's openFragment does, and write it at its place. The first page counts the file's size toward the month's downloads; later pages count nothing. Addresses work for four hours: before then, ask for the page again from the first fragment not yet fetched. The key is in this answer and nowhere else. This API never keeps it, and neither should a program, beyond the read.
|
|
885
|
+
*
|
|
886
|
+
* GET /v1/files/:id/shards. Needs the scope files:read.
|
|
887
|
+
*/
|
|
888
|
+
shards: (id: string, query?: FilesShardsQuery, options?: CallOptions) => Promise<FilesShardsAnswer>;
|
|
788
889
|
/**
|
|
789
890
|
* An image at a smaller size.
|
|
790
891
|
*
|
|
@@ -836,13 +937,15 @@ export declare function bind(call: Call): {
|
|
|
836
937
|
*
|
|
837
938
|
* The room is set aside now, so an upload that would not fit is refused before a byte is sent. The parts can be sent by anything that can make a PUT request, including a browser that has never seen the API key: hand it the addresses.
|
|
838
939
|
*
|
|
940
|
+
* Into a place under Shard Protection, an upload begun with protectable true is sealed as it is sent. A place is protected by the setting nearest it (files.update's protection), or with none by the drive's default: an app's, which its owner turns on from the app's page, or for a device the account's. The answer's shards then says how the file is cut, and uploads.get gives its key. Each part is a fragment: the file's bytes from its number times fragmentBytes, sealed with that key as the SDK's sealFragment does, under a nonce of its own, and sent to the part's address. uploads.fragments confirms them, and completing makes the file, protected from its first byte, with a null clientSha256. A sealed upload sets blocks aside: none is kept, and none reused. Begun without protectable, a file lands as an ordinary file and the service protects it within a few minutes; from then on it is read through its map (files.shards).
|
|
941
|
+
*
|
|
839
942
|
* POST /v1/uploads. Needs the scope files:write. Honours an Idempotency-Key.
|
|
840
943
|
*/
|
|
841
944
|
begin: (body: UploadsBeginBody, options?: CallOptions) => Promise<UploadsBeginAnswer>;
|
|
842
945
|
/**
|
|
843
946
|
* An upload, and which parts have arrived.
|
|
844
947
|
*
|
|
845
|
-
* For carrying on after an interruption: storage itself says which parts it has, so nothing the client remembered is needed.
|
|
948
|
+
* For carrying on after an interruption: storage itself says which parts it has, so nothing the client remembered is needed. For an upload sealed as it is sent, uploadedParts are the fragments confirmed and recorded, and shards gives the key, which this API keeps nowhere else. Confirm any fragment that may have been sent before sending it again. This answer is never kept, by this API or anything between it and the caller.
|
|
846
949
|
*
|
|
847
950
|
* GET /v1/uploads/:id. Needs the scope files:write.
|
|
848
951
|
*/
|
|
@@ -850,11 +953,19 @@ export declare function bind(call: Call): {
|
|
|
850
953
|
/**
|
|
851
954
|
* Addresses for more parts.
|
|
852
955
|
*
|
|
853
|
-
* Addresses are given out a window at a time and each lasts half an hour. Ask again for any that have run out.
|
|
956
|
+
* Addresses are given out a window at a time and each lasts half an hour. Ask again for any that have run out. For an upload sealed as it is sent, each number is a fragment's place, and its address takes the sealed fragment, with its Content-MD5. Confirm fragments with uploads.fragments once they are sent.
|
|
854
957
|
*
|
|
855
958
|
* GET /v1/uploads/:id/parts. Needs the scope files:write.
|
|
856
959
|
*/
|
|
857
960
|
parts: (id: string, query?: UploadsPartsQuery, options?: CallOptions) => Promise<UploadsPartsAnswer>;
|
|
961
|
+
/**
|
|
962
|
+
* Confirm sealed fragments.
|
|
963
|
+
*
|
|
964
|
+
* Confirms fragments of a sealed upload that have been sent. Each is copied inside storage to its own name, measured, and recorded once it is the size its place holds. recorded: done, never send it again. pending: storage is still copying it, or another confirmation of it is under way, so ask again shortly. resend: not there, or not its size and removed, so seal it again, under a new nonce, send it and confirm it. Safe to send again.
|
|
965
|
+
*
|
|
966
|
+
* POST /v1/uploads/:id/fragments. Needs the scope files:write. Safe to send again.
|
|
967
|
+
*/
|
|
968
|
+
fragments: (id: string, body: UploadsFragmentsBody, options?: CallOptions) => Promise<UploadsFragmentsAnswer>;
|
|
858
969
|
/**
|
|
859
970
|
* Finish an upload.
|
|
860
971
|
*
|
|
@@ -876,7 +987,7 @@ export declare function bind(call: Call): {
|
|
|
876
987
|
/**
|
|
877
988
|
* What the app is using.
|
|
878
989
|
*
|
|
879
|
-
* What this app holds, against the ceiling set for it if there is one; and what the account it belongs to has used this calendar month, across its personal files and all its apps, against what its plan includes. An app's files count toward the account's one storage allowance. For a device signed in with
|
|
990
|
+
* What this app holds, against the ceiling set for it if there is one; and what the account it belongs to has used this calendar month, across its personal files and all its apps, against what its plan includes. An app's files count toward the account's one storage allowance. For a device signed in with filefreak login, which uses the personal drive, app is null.
|
|
880
991
|
*
|
|
881
992
|
* GET /v1/usage. Needs the scope usage:read.
|
|
882
993
|
*/
|
|
@@ -886,7 +997,7 @@ export declare function bind(call: Call): {
|
|
|
886
997
|
/**
|
|
887
998
|
* Who this is.
|
|
888
999
|
*
|
|
889
|
-
* The account a key, a token or a device acts for, and what it may do there. A key's program and a page's token are told the account's username and plan, never its email address: only a device signed in with
|
|
1000
|
+
* The account a key, a token or a device acts for, and what it may do there. A key's program and a page's token are told the account's username and plan, never its email address: only a device signed in with filefreak login, which is the person, is told that.
|
|
890
1001
|
*
|
|
891
1002
|
* GET /v1/me. Any key may call it.
|
|
892
1003
|
*/
|
|
@@ -896,25 +1007,25 @@ export declare function bind(call: Call): {
|
|
|
896
1007
|
/**
|
|
897
1008
|
* Make a share link.
|
|
898
1009
|
*
|
|
899
|
-
* A link that opens one file or folder for whoever holds it, separate from making it public: a private file can have one. It can have a password, an end date and a number of downloads after which it stops. Share links are a person's, so only a device signed in with
|
|
1010
|
+
* A link that opens one file or folder for whoever holds it, separate from making it public: a private file can have one. It can have a password, an end date and a number of downloads after which it stops. Share links are a person's, so only a device signed in with filefreak login can make them here, as on the website; an app's key cannot. A link to a file under Shard Protection is a shard link: whoever opens it is given the file's key with its map, so their browser can put the file back together, show it and save it. The storage it is kept in still gives nobody anything on its own.
|
|
900
1011
|
*
|
|
901
|
-
* POST /v1/shares. Only a device signed in with
|
|
1012
|
+
* POST /v1/shares. Only a device signed in with filefreak login may call it. Honours an Idempotency-Key.
|
|
902
1013
|
*/
|
|
903
1014
|
create: (body: SharesCreateBody, options?: CallOptions) => Promise<SharesCreateAnswer>;
|
|
904
1015
|
/**
|
|
905
1016
|
* List share links.
|
|
906
1017
|
*
|
|
907
|
-
* The links on one file or folder, or every link the account has, newest first. Removed links are not listed. Only a device signed in with
|
|
1018
|
+
* The links on one file or folder, or every link the account has, newest first. Removed links are not listed. Only a device signed in with filefreak login.
|
|
908
1019
|
*
|
|
909
|
-
* GET /v1/shares. Only a device signed in with
|
|
1020
|
+
* GET /v1/shares. Only a device signed in with filefreak login may call it.
|
|
910
1021
|
*/
|
|
911
1022
|
list: (query?: SharesListQuery, options?: CallOptions) => Promise<SharesListAnswer>;
|
|
912
1023
|
/**
|
|
913
1024
|
* Remove a share link.
|
|
914
1025
|
*
|
|
915
|
-
* It stops working with the next request, and cannot be brought back. Only a device signed in with
|
|
1026
|
+
* It stops working with the next request, and cannot be brought back. Only a device signed in with filefreak login.
|
|
916
1027
|
*
|
|
917
|
-
* DELETE /v1/shares/:id. Only a device signed in with
|
|
1028
|
+
* DELETE /v1/shares/:id. Only a device signed in with filefreak login may call it.
|
|
918
1029
|
*/
|
|
919
1030
|
revoke: (id: string, options?: CallOptions) => Promise<SharesRevokeAnswer>;
|
|
920
1031
|
};
|
|
@@ -922,9 +1033,9 @@ export declare function bind(call: Call): {
|
|
|
922
1033
|
/**
|
|
923
1034
|
* List sites.
|
|
924
1035
|
*
|
|
925
|
-
* The account's static sites, by name, with the deploy each serves. A site is a person's, so only a device signed in with
|
|
1036
|
+
* The account's static sites, by name, with the deploy each serves. A site is a person's, so only a device signed in with filefreak login reaches sites, as on the website; an app's key cannot. Sites are part of Pro.
|
|
926
1037
|
*
|
|
927
|
-
* GET /v1/sites. Only a device signed in with
|
|
1038
|
+
* GET /v1/sites. Only a device signed in with filefreak login may call it.
|
|
928
1039
|
*/
|
|
929
1040
|
list: (options?: CallOptions) => Promise<SitesListAnswer>;
|
|
930
1041
|
/**
|
|
@@ -932,7 +1043,7 @@ export declare function bind(call: Call): {
|
|
|
932
1043
|
*
|
|
933
1044
|
* A site with no deploy yet. Its name is its address: 3 to 40 lower-case letters, digits and single hyphens, and not a name FileFreak keeps, another account's username, or one that looks like another company's (invalid_site_name, site_name_taken). Refused with sites_need_pro on a plan without sites.
|
|
934
1045
|
*
|
|
935
|
-
* POST /v1/sites. Only a device signed in with
|
|
1046
|
+
* POST /v1/sites. Only a device signed in with filefreak login may call it. Honours an Idempotency-Key.
|
|
936
1047
|
*/
|
|
937
1048
|
create: (body: SitesCreateBody, options?: CallOptions) => Promise<SitesCreateAnswer>;
|
|
938
1049
|
/**
|
|
@@ -940,7 +1051,7 @@ export declare function bind(call: Call): {
|
|
|
940
1051
|
*
|
|
941
1052
|
* A site, and its deploys newest first. A site keeps its 10 newest deploys that have ended besides the live one.
|
|
942
1053
|
*
|
|
943
|
-
* GET /v1/sites/:id. Only a device signed in with
|
|
1054
|
+
* GET /v1/sites/:id. Only a device signed in with filefreak login may call it.
|
|
944
1055
|
*/
|
|
945
1056
|
get: (id: string, options?: CallOptions) => Promise<SitesGetAnswer>;
|
|
946
1057
|
/**
|
|
@@ -948,7 +1059,7 @@ export declare function bind(call: Call): {
|
|
|
948
1059
|
*
|
|
949
1060
|
* Begins a deploy with up to 1000 of its files: each one's path, size and SHA-256. Declare the rest with sites.declareFiles, more set to false on the last list. The answer says which files to send: PUT each one's bytes to its address, then call sites.finishDeploy. Bytes the site has stored already are not asked for. A deploy may have 20000 files, 100 MB each and 1 GB together, and what it adds counts as storage from the moment it is declared (quota_exceeded). An unfinished deploy nothing has asked about for an hour is given up on.
|
|
950
1061
|
*
|
|
951
|
-
* POST /v1/sites/:id/deploys. Only a device signed in with
|
|
1062
|
+
* POST /v1/sites/:id/deploys. Only a device signed in with filefreak login may call it. Honours an Idempotency-Key.
|
|
952
1063
|
*/
|
|
953
1064
|
startDeploy: (id: string, body: SitesStartDeployBody, options?: CallOptions) => Promise<SitesStartDeployAnswer>;
|
|
954
1065
|
/**
|
|
@@ -956,7 +1067,7 @@ export declare function bind(call: Call): {
|
|
|
956
1067
|
*
|
|
957
1068
|
* The next 1000 files of a deploy at most, as sites.startDeploy takes them. A path declared twice is refused (path_declared_twice).
|
|
958
1069
|
*
|
|
959
|
-
* POST /v1/sites/deploys/:id/files. Only a device signed in with
|
|
1070
|
+
* POST /v1/sites/deploys/:id/files. Only a device signed in with filefreak login may call it. Honours an Idempotency-Key.
|
|
960
1071
|
*/
|
|
961
1072
|
declareFiles: (id: string, body: SitesDeclareFilesBody, options?: CallOptions) => Promise<SitesDeclareFilesAnswer>;
|
|
962
1073
|
/**
|
|
@@ -964,7 +1075,7 @@ export declare function bind(call: Call): {
|
|
|
964
1075
|
*
|
|
965
1076
|
* New addresses for files of an unfinished deploy whose bytes have not arrived, when the first ones ran out or a finish answered deploy_incomplete. Files whose bytes have arrived are left out.
|
|
966
1077
|
*
|
|
967
|
-
* POST /v1/sites/deploys/:id/send. Only a device signed in with
|
|
1078
|
+
* POST /v1/sites/deploys/:id/send. Only a device signed in with filefreak login may call it. Safe to send again.
|
|
968
1079
|
*/
|
|
969
1080
|
sendAgain: (id: string, body: SitesSendAgainBody, options?: CallOptions) => Promise<SitesSendAgainAnswer>;
|
|
970
1081
|
/**
|
|
@@ -972,7 +1083,7 @@ export declare function bind(call: Call): {
|
|
|
972
1083
|
*
|
|
973
1084
|
* Storage puts each file in place and is asked its size, and the deploy is ready, and live if live is true. Safe to call again: storage may take longer than one request waits, and the answer is then 202 with how long to wait before asking again. A file whose bytes have not arrived, or arrived at another size, is answered with deploy_incomplete and the SHA-256s to send again.
|
|
974
1085
|
*
|
|
975
|
-
* POST /v1/sites/deploys/:id/finish. Only a device signed in with
|
|
1086
|
+
* POST /v1/sites/deploys/:id/finish. Only a device signed in with filefreak login may call it. Safe to send again.
|
|
976
1087
|
*/
|
|
977
1088
|
finishDeploy: (id: string, body?: SitesFinishDeployBody, options?: CallOptions) => Promise<SitesFinishDeployAnswer>;
|
|
978
1089
|
/**
|
|
@@ -980,7 +1091,7 @@ export declare function bind(call: Call): {
|
|
|
980
1091
|
*
|
|
981
1092
|
* Cancels a deploy that is uploading, and what it set aside is given back at once. Deletes one that has ended, with whatever bytes no other deploy of the site uses. Never the live one (deploy_live).
|
|
982
1093
|
*
|
|
983
|
-
* DELETE /v1/sites/deploys/:id. Only a device signed in with
|
|
1094
|
+
* DELETE /v1/sites/deploys/:id. Only a device signed in with filefreak login may call it.
|
|
984
1095
|
*/
|
|
985
1096
|
removeDeploy: (id: string, options?: CallOptions) => Promise<SitesRemoveDeployAnswer>;
|
|
986
1097
|
/**
|
|
@@ -988,7 +1099,7 @@ export declare function bind(call: Call): {
|
|
|
988
1099
|
*
|
|
989
1100
|
* Makes a ready deploy the one visitors are served, which is also how a site is rolled back; null takes the site offline. Visitors see the change within a minute.
|
|
990
1101
|
*
|
|
991
|
-
* POST /v1/sites/:id/live. Only a device signed in with
|
|
1102
|
+
* POST /v1/sites/:id/live. Only a device signed in with filefreak login may call it. Safe to send again.
|
|
992
1103
|
*/
|
|
993
1104
|
setLive: (id: string, body: SitesSetLiveBody, options?: CallOptions) => Promise<SitesSetLiveAnswer>;
|
|
994
1105
|
};
|