agentic-drive 0.1.0 → 0.2.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/CHANGELOG.md +112 -0
- package/README.md +32 -12
- package/SKILL.md +1 -1
- package/dist/chunk-3LISWG7H.js +65 -0
- package/dist/{chunk-QRGKXPLX.js → chunk-6CWBHSJ7.js} +489 -73
- package/dist/{chunk-4QE7E5UQ.js → chunk-RWMBGIAS.js} +1 -1
- package/dist/cli.js +22 -5
- package/dist/drive-DKOs1FyM.d.ts +325 -0
- package/dist/index.d.ts +12 -4
- package/dist/index.js +8 -2
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +20 -3
- package/dist/migrate-B79gRPMu.d.ts +29 -0
- package/dist/worker.d.ts +10 -10
- package/dist/worker.js +115 -38
- package/package.json +4 -2
- package/dist/drive-DRQ8LiHl.d.ts +0 -144
package/dist/worker.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
backfillAuthorIds,
|
|
3
|
+
backfillResources
|
|
4
|
+
} from "./chunk-3LISWG7H.js";
|
|
5
|
+
import {
|
|
3
6
|
DEFAULT_MAX_BYTES,
|
|
4
7
|
DEFAULT_URL_SECONDS,
|
|
5
8
|
DriveError,
|
|
@@ -8,14 +11,16 @@ import {
|
|
|
8
11
|
publicNode,
|
|
9
12
|
safeMime,
|
|
10
13
|
upload
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6CWBHSJ7.js";
|
|
12
15
|
|
|
13
16
|
// src/worker.ts
|
|
14
17
|
import { Hono } from "hono";
|
|
15
|
-
import { parseRegion } from "agentic-identity";
|
|
16
18
|
import { D1_SCHEMA, createD1Store, createR2Blobs, verifySignedBlobUrl } from "agentic-identity/cloudflare";
|
|
17
|
-
|
|
19
|
+
import { createSharing, createStoreAuth, parseRegion } from "agentic-identity";
|
|
18
20
|
var STATUS = {
|
|
21
|
+
CROSS_DRIVE: 409,
|
|
22
|
+
INVALID_SHARE: 400,
|
|
23
|
+
TOO_MANY_ITEMS: 409,
|
|
19
24
|
TOO_DEEP: 400,
|
|
20
25
|
INVALID_EXPIRY: 400,
|
|
21
26
|
BUSY: 409,
|
|
@@ -37,35 +42,10 @@ var STATUS = {
|
|
|
37
42
|
TOO_LARGE: 413
|
|
38
43
|
};
|
|
39
44
|
var fail = (code, message, status) => new Response(JSON.stringify({ error: { code, message } }), { status, headers: { "content-type": "application/json" } });
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
for (let i = 0; i < Math.max(x.length, y.length); i++) diff |= (x[i] ?? 0) ^ (y[i] ?? 0);
|
|
45
|
-
return diff === 0;
|
|
46
|
-
}
|
|
47
|
-
var isText = (v) => typeof v === "string" && v !== "";
|
|
48
|
-
function principalOf(grant) {
|
|
49
|
-
if (typeof grant !== "object" || grant === null) return null;
|
|
50
|
-
const { owner, actor, kind } = grant;
|
|
51
|
-
if (!isText(owner) || !isText(actor) || !ACTOR_KINDS.includes(kind)) return null;
|
|
52
|
-
return { owner, actor: { id: actor, kind } };
|
|
53
|
-
}
|
|
54
|
-
function authenticate(request, env) {
|
|
55
|
-
const token = /^Bearer (.+)$/.exec(request.headers.get("authorization") ?? "")?.[1];
|
|
56
|
-
if (!token || !env.DRIVE_API_TOKENS) return null;
|
|
57
|
-
let grants;
|
|
58
|
-
try {
|
|
59
|
-
grants = JSON.parse(env.DRIVE_API_TOKENS);
|
|
60
|
-
} catch {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
if (typeof grants !== "object" || grants === null) return null;
|
|
64
|
-
let found;
|
|
65
|
-
for (const [candidate, grant] of Object.entries(grants)) {
|
|
66
|
-
if (sameText(candidate, token) && candidate.length >= MIN_TOKEN_LENGTH) found = grant;
|
|
67
|
-
}
|
|
68
|
-
return principalOf(found);
|
|
45
|
+
async function authenticate(request, store, now) {
|
|
46
|
+
if (!/^Bearer [A-Za-z0-9_-]{1,512}$/.test(request.headers.get("authorization") ?? "")) return null;
|
|
47
|
+
const principal = await createStoreAuth(store, now ? { now } : {}).authenticate(request);
|
|
48
|
+
return principal ? { owner: principal.chain[0].id, actor: { id: principal.principalId, kind: principal.kind }, principal } : null;
|
|
69
49
|
}
|
|
70
50
|
var schemas = /* @__PURE__ */ new WeakMap();
|
|
71
51
|
function settings(env) {
|
|
@@ -92,7 +72,8 @@ async function driveFor(env, config) {
|
|
|
92
72
|
schemas.set(env.DB, ready);
|
|
93
73
|
}
|
|
94
74
|
await ready;
|
|
95
|
-
|
|
75
|
+
const store = createD1Store(env.DB, { region: regionOf(env) });
|
|
76
|
+
return { store, drive: createDrive({ store, blobs: blobsFor(env, config), sharing: createSharing(store) }) };
|
|
96
77
|
}
|
|
97
78
|
var number = (v, name) => {
|
|
98
79
|
if (v === void 0) return void 0;
|
|
@@ -108,10 +89,12 @@ function createApp() {
|
|
|
108
89
|
api.use("*", async (c, next) => {
|
|
109
90
|
const config = settings(c.env);
|
|
110
91
|
if (!config) return fail("NOT_CONFIGURED", "set DRIVE_PUBLIC_URL and DRIVE_URL_SECRET (32 bytes or more)", 503);
|
|
111
|
-
const
|
|
92
|
+
const { drive, store } = await driveFor(c.env, config);
|
|
93
|
+
const ctx = await authenticate(c.req.raw, store);
|
|
112
94
|
if (!ctx) return fail("UNAUTHORIZED", "send a valid bearer token", 401);
|
|
113
95
|
c.set("ctx", ctx);
|
|
114
|
-
c.set("drive",
|
|
96
|
+
c.set("drive", drive);
|
|
97
|
+
c.set("store", store);
|
|
115
98
|
await next();
|
|
116
99
|
});
|
|
117
100
|
const q = (c, k) => c.req.query(k);
|
|
@@ -187,15 +170,25 @@ function createApp() {
|
|
|
187
170
|
minSize: number(q(c, "minSize"), "minSize"),
|
|
188
171
|
maxSize: number(q(c, "maxSize"), "maxSize"),
|
|
189
172
|
createdByKind: q(c, "createdByKind"),
|
|
173
|
+
app: q(c, "app"),
|
|
190
174
|
limit: number(q(c, "limit"), "limit")
|
|
191
175
|
};
|
|
192
176
|
return c.json((await c.var.drive.search(c.var.ctx, query)).map((r) => publicNode(r.node, r.path)));
|
|
193
177
|
});
|
|
194
178
|
api.get("/export", async (c) => new Response(await buildExport(c.var.drive, c.var.ctx), { headers: { "content-type": "application/zip", "content-disposition": 'attachment; filename="drive-export.zip"' } }));
|
|
195
179
|
api.delete("/account", async (c) => {
|
|
196
|
-
if (q(c, "confirm") !== "yes") throw new DriveError("INVALID_PATH", "add ?confirm=yes to
|
|
197
|
-
return c.json(await c.var.drive.
|
|
180
|
+
if (q(c, "confirm") !== "yes") throw new DriveError("INVALID_PATH", "add ?confirm=yes to erase you for good: your drive, and what you shared or held");
|
|
181
|
+
return c.json(await c.var.drive.erasePerson(c.var.ctx));
|
|
198
182
|
});
|
|
183
|
+
api.get("/home", async (c) => {
|
|
184
|
+
const home = await c.var.drive.home(c.var.ctx, { app: q(c, "app"), limit: number(q(c, "limit"), "limit") });
|
|
185
|
+
return c.json({ apps: home.apps, files: home.files, items: home.items.map((i) => ({ ...publicNode(i.node, i.path), app: i.app })) });
|
|
186
|
+
});
|
|
187
|
+
api.post("/documents", async (c) => {
|
|
188
|
+
const b = await body(c);
|
|
189
|
+
return c.json(publicNode(await c.var.drive.registerDocument(c.var.ctx, { ref: str(b.ref, "ref"), name: str(b.name, "name"), folder: opt(b.folder, "folder") })), 201);
|
|
190
|
+
});
|
|
191
|
+
api.delete("/documents", async (c) => c.json(await c.var.drive.forgetDocument(c.var.ctx, need(q(c, "ref"), "ref"))));
|
|
199
192
|
app2.get("/api/v1/drive/blob", async (c) => {
|
|
200
193
|
const config = settings(c.env);
|
|
201
194
|
if (!config) return fail("NOT_CONFIGURED", "set DRIVE_PUBLIC_URL and DRIVE_URL_SECRET (32 bytes or more)", 503);
|
|
@@ -212,6 +205,88 @@ function createApp() {
|
|
|
212
205
|
}
|
|
213
206
|
});
|
|
214
207
|
});
|
|
208
|
+
const roleOf = (v) => v;
|
|
209
|
+
const lifetime = (v, name) => {
|
|
210
|
+
if (v === void 0) return void 0;
|
|
211
|
+
if (typeof v !== "number") throw new DriveError("INVALID_SHARE", `${name} must be a number of milliseconds`);
|
|
212
|
+
return v;
|
|
213
|
+
};
|
|
214
|
+
api.get("/shares", async (c) => c.json(await c.var.drive.shares(c.var.ctx, need(q(c, "path"), "path"))));
|
|
215
|
+
api.post("/shares", async (c) => {
|
|
216
|
+
const b = await body(c);
|
|
217
|
+
await c.var.drive.shareWith(c.var.ctx, str(b.path, "path"), str(b.subjectId, "subjectId"), roleOf(b.role));
|
|
218
|
+
return c.json({ ok: true });
|
|
219
|
+
});
|
|
220
|
+
api.delete("/shares", async (c) => {
|
|
221
|
+
await c.var.drive.unshare(c.var.ctx, need(q(c, "path"), "path"), need(q(c, "subjectId"), "subjectId"));
|
|
222
|
+
return c.json({ ok: true });
|
|
223
|
+
});
|
|
224
|
+
api.post("/invites", async (c) => {
|
|
225
|
+
const b = await body(c);
|
|
226
|
+
const expiresInMs = lifetime(b.expiresInMs, "expiresInMs");
|
|
227
|
+
const invite = await c.var.drive.invite(c.var.ctx, str(b.path, "path"), {
|
|
228
|
+
role: roleOf(b.role),
|
|
229
|
+
...b.email === void 0 ? {} : { email: str(b.email, "email") },
|
|
230
|
+
...b.handle === void 0 ? {} : { handle: str(b.handle, "handle") },
|
|
231
|
+
...expiresInMs === void 0 ? {} : { expiresInMs }
|
|
232
|
+
});
|
|
233
|
+
return c.json(invite, 201);
|
|
234
|
+
});
|
|
235
|
+
api.post("/invites/accept", async (c) => {
|
|
236
|
+
const id = str((await body(c)).id, "id");
|
|
237
|
+
const user = await c.var.store.get("users", c.var.ctx.actor.id);
|
|
238
|
+
const agent = await c.var.store.get("principals", c.var.ctx.actor.id);
|
|
239
|
+
await c.var.drive.acceptInvite(c.var.ctx, id, {
|
|
240
|
+
...user?.emailVerified === true && typeof user.email === "string" ? { email: user.email } : {},
|
|
241
|
+
...typeof agent?.handle === "string" ? { handle: agent.handle } : {}
|
|
242
|
+
});
|
|
243
|
+
return c.json({ ok: true });
|
|
244
|
+
});
|
|
245
|
+
api.post("/links", async (c) => {
|
|
246
|
+
const b = await body(c);
|
|
247
|
+
const expiresInMs = lifetime(b.expiresInMs, "expiresInMs");
|
|
248
|
+
const link = await c.var.drive.createLink(c.var.ctx, str(b.path, "path"), {
|
|
249
|
+
role: roleOf(b.role),
|
|
250
|
+
signedInOnly: b.signedInOnly === true,
|
|
251
|
+
...expiresInMs === void 0 ? {} : { expiresAt: Date.now() + expiresInMs }
|
|
252
|
+
});
|
|
253
|
+
return c.json(link, 201);
|
|
254
|
+
});
|
|
255
|
+
api.delete("/links", async (c) => {
|
|
256
|
+
await c.var.drive.revokeLink(c.var.ctx, need(q(c, "id"), "id"));
|
|
257
|
+
return c.json({ ok: true });
|
|
258
|
+
});
|
|
259
|
+
const shared = new Hono();
|
|
260
|
+
const visit = async (c) => {
|
|
261
|
+
const config = settings(c.env);
|
|
262
|
+
if (!config) return { stop: fail("NOT_CONFIGURED", "set DRIVE_PUBLIC_URL and DRIVE_URL_SECRET (32 bytes or more)", 503) };
|
|
263
|
+
const { drive, store } = await driveFor(c.env, config);
|
|
264
|
+
const ctx = await authenticate(c.req.raw, store);
|
|
265
|
+
if (!ctx && c.req.header("authorization")) return { stop: fail("UNAUTHORIZED", "send a valid bearer token", 401) };
|
|
266
|
+
return { drive, principal: ctx?.principal ?? null, token: c.req.header("x-link-token") };
|
|
267
|
+
};
|
|
268
|
+
shared.get("/:id", async (c) => {
|
|
269
|
+
const v = await visit(c);
|
|
270
|
+
return "stop" in v ? v.stop : c.json(publicNode(await v.drive.openShared(v.principal, c.req.param("id"), v.token)));
|
|
271
|
+
});
|
|
272
|
+
shared.get("/:id/items", async (c) => {
|
|
273
|
+
const v = await visit(c);
|
|
274
|
+
return "stop" in v ? v.stop : c.json((await v.drive.listShared(v.principal, c.req.param("id"), v.token)).map((n) => publicNode(n)));
|
|
275
|
+
});
|
|
276
|
+
shared.get("/:id/content", async (c) => {
|
|
277
|
+
const v = await visit(c);
|
|
278
|
+
if ("stop" in v) return v.stop;
|
|
279
|
+
const { node, data } = await v.drive.readShared(v.principal, c.req.param("id"), v.token);
|
|
280
|
+
return new Response(data, {
|
|
281
|
+
headers: {
|
|
282
|
+
"content-type": safeMime(node.mime),
|
|
283
|
+
"content-disposition": `attachment; filename*=UTF-8''${encodeURIComponent(node.name)}`,
|
|
284
|
+
"x-content-type-options": "nosniff",
|
|
285
|
+
"cache-control": "private, no-store"
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
app2.route("/api/v1/drive/shared", shared);
|
|
215
290
|
app2.route("/api/v1/drive", api);
|
|
216
291
|
app2.notFound(() => fail("NOT_FOUND", "no such route", 404));
|
|
217
292
|
app2.onError((error) => {
|
|
@@ -225,6 +300,8 @@ var app = createApp();
|
|
|
225
300
|
var worker_default = { fetch: (request, env, ctx) => app.fetch(request, env, ctx) };
|
|
226
301
|
export {
|
|
227
302
|
authenticate,
|
|
303
|
+
backfillAuthorIds,
|
|
304
|
+
backfillResources,
|
|
228
305
|
createApp,
|
|
229
306
|
worker_default as default
|
|
230
307
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-drive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Store, sort, and share files and folders.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"drive",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"files": [
|
|
29
29
|
"dist",
|
|
30
30
|
"README.md",
|
|
31
|
+
"CHANGELOG.md",
|
|
31
32
|
"LICENSE",
|
|
32
33
|
"llms.txt",
|
|
33
34
|
"SKILL.md"
|
|
@@ -53,11 +54,12 @@
|
|
|
53
54
|
"typecheck": "tsc --noEmit",
|
|
54
55
|
"test": "vitest run",
|
|
55
56
|
"clean": "rm -rf dist",
|
|
57
|
+
"prepack": "npm run build --silent >&2",
|
|
56
58
|
"ci:local": "npm run build && npm run typecheck && npm test"
|
|
57
59
|
},
|
|
58
60
|
"dependencies": {
|
|
59
61
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
60
|
-
"agentic-identity": "^0.
|
|
62
|
+
"agentic-identity": "^0.3.0",
|
|
61
63
|
"hono": "^4.13.14",
|
|
62
64
|
"zod": "^3.25.0"
|
|
63
65
|
},
|
package/dist/drive-DRQ8LiHl.d.ts
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { Store, Blobs } from 'agentic-identity';
|
|
2
|
-
|
|
3
|
-
declare const ROOT_ID = "root";
|
|
4
|
-
declare const ACTOR_KINDS: readonly ["human", "agent_of_human", "agent_of_agent", "agent", "user_token"];
|
|
5
|
-
type ActorKind = (typeof ACTOR_KINDS)[number];
|
|
6
|
-
type Actor = {
|
|
7
|
-
id: string;
|
|
8
|
-
kind: ActorKind;
|
|
9
|
-
};
|
|
10
|
-
/** `owner` is the drive's owner. `actor` is who acts for them. */
|
|
11
|
-
type Ctx = {
|
|
12
|
-
owner: string;
|
|
13
|
-
actor: Actor;
|
|
14
|
-
};
|
|
15
|
-
type Action = "read" | "write" | "delete";
|
|
16
|
-
/** The seam for sharing. A later release swaps this for a role check. */
|
|
17
|
-
type Can = (ctx: Ctx, action: Action, node: Node) => boolean | Promise<boolean>;
|
|
18
|
-
type Node = {
|
|
19
|
-
id: string;
|
|
20
|
-
owner: string;
|
|
21
|
-
parentId: string;
|
|
22
|
-
kind: "folder" | "file" | "ref";
|
|
23
|
-
name: string;
|
|
24
|
-
nameKey: string;
|
|
25
|
-
size: number;
|
|
26
|
-
mime: string | null;
|
|
27
|
-
hash: string | null;
|
|
28
|
-
/** A typed reference such as `docs:<id>`. Set when kind is "ref". */
|
|
29
|
-
ref: string | null;
|
|
30
|
-
blobKey: string | null;
|
|
31
|
-
createdAt: number;
|
|
32
|
-
updatedAt: number;
|
|
33
|
-
createdBy: Actor;
|
|
34
|
-
updatedBy: Actor;
|
|
35
|
-
trashed: boolean;
|
|
36
|
-
trashedAt: number | null;
|
|
37
|
-
/** Set while a purge deletes the item. Nothing can see or change it then. */
|
|
38
|
-
purging: boolean;
|
|
39
|
-
};
|
|
40
|
-
type ErrorCode = "NOT_FOUND" | "NAME_TAKEN" | "BLOB_EXISTS" | "INVALID_NAME" | "INVALID_PATH" | "INVALID_REF" | "NOT_A_FOLDER" | "NOT_A_FILE" | "MOVE_INTO_SELF" | "TOO_DEEP" | "PARENT_GONE" | "TRASHED" | "NOT_TRASHED" | "IS_ROOT" | "FORBIDDEN" | "BLOB_MISSING" | "TOO_LARGE" | "INVALID_EXPIRY" | "BUSY";
|
|
41
|
-
declare class DriveError extends Error {
|
|
42
|
-
readonly code: ErrorCode;
|
|
43
|
-
constructor(code: ErrorCode, message: string);
|
|
44
|
-
}
|
|
45
|
-
interface SearchQuery {
|
|
46
|
-
/** Part of the name. Case and Unicode form do not matter. */
|
|
47
|
-
name?: string;
|
|
48
|
-
/** An exact type, or a family such as `image/*`. */
|
|
49
|
-
mime?: string;
|
|
50
|
-
kind?: Node["kind"];
|
|
51
|
-
minSize?: number;
|
|
52
|
-
maxSize?: number;
|
|
53
|
-
/** Items first made by this kind of actor, such as `agent_of_human`. */
|
|
54
|
-
createdByKind?: ActorKind;
|
|
55
|
-
/** At most this many results. Defaults to 100. */
|
|
56
|
-
limit?: number;
|
|
57
|
-
}
|
|
58
|
-
type OnConflict = "fail" | "rename" | "replace";
|
|
59
|
-
interface DriveDeps {
|
|
60
|
-
store: Store;
|
|
61
|
-
blobs: Blobs;
|
|
62
|
-
now?: () => number;
|
|
63
|
-
newId?: () => string;
|
|
64
|
-
can?: Can;
|
|
65
|
-
/** Most parent steps any ancestor walk takes. A walk that hits it fails closed. */
|
|
66
|
-
maxDepth?: number;
|
|
67
|
-
/** Called with a blob key that no node points at and that could not be deleted. */
|
|
68
|
-
onOrphan?: (key: string, error: unknown) => void;
|
|
69
|
-
}
|
|
70
|
-
type Drive = ReturnType<typeof createDrive>;
|
|
71
|
-
/** Validates a name. Names are NFC-normalized. Two names clash when their keys match. */
|
|
72
|
-
declare function parseName(raw: string): {
|
|
73
|
-
name: string;
|
|
74
|
-
key: string;
|
|
75
|
-
};
|
|
76
|
-
declare function createDrive(deps: DriveDeps): {
|
|
77
|
-
stat(ctx: Ctx, loc: string): Promise<Node>;
|
|
78
|
-
/** Live children, sorted by name. */
|
|
79
|
-
list(ctx: Ctx, loc?: string): Promise<Node[]>;
|
|
80
|
-
mkdir(ctx: Ctx, path: string, opts?: {
|
|
81
|
-
parents?: boolean;
|
|
82
|
-
}): Promise<Node>;
|
|
83
|
-
/**
|
|
84
|
-
* Stores one blob and one node. The blob is written first. The new node commits before
|
|
85
|
-
* any old blob goes. A failed old-blob delete leaves an orphan and never undoes the commit.
|
|
86
|
-
*/
|
|
87
|
-
putFile(ctx: Ctx, path: string, data: Uint8Array, opts?: {
|
|
88
|
-
mime?: string;
|
|
89
|
-
parents?: boolean;
|
|
90
|
-
onConflict?: OnConflict;
|
|
91
|
-
}): Promise<Node>;
|
|
92
|
-
/** A reference points at a document in another app, such as `docs:<id>`. */
|
|
93
|
-
putRef(ctx: Ctx, path: string, ref: string, opts?: {
|
|
94
|
-
parents?: boolean;
|
|
95
|
-
onConflict?: OnConflict;
|
|
96
|
-
}): Promise<Node>;
|
|
97
|
-
read(ctx: Ctx, loc: string): Promise<{
|
|
98
|
-
node: Node;
|
|
99
|
-
data: Uint8Array;
|
|
100
|
-
contentType?: string;
|
|
101
|
-
}>;
|
|
102
|
-
/**
|
|
103
|
-
* A time-limited URL to fetch the bytes. The URL signs an attachment header and the stored
|
|
104
|
-
* type, so the link holder cannot change how the bytes are served. Trashing an item does
|
|
105
|
-
* not revoke a link already issued.
|
|
106
|
-
*/
|
|
107
|
-
downloadUrl(ctx: Ctx, loc: string, expiresInSeconds?: number): Promise<string>;
|
|
108
|
-
move(ctx: Ctx, src: string, destLoc: string, opts?: {
|
|
109
|
-
name?: string;
|
|
110
|
-
onConflict?: OnConflict;
|
|
111
|
-
}): Promise<Node>;
|
|
112
|
-
rename(ctx: Ctx, loc: string, name: string): Promise<Node>;
|
|
113
|
-
/** Hides an item and, for a folder, everything under it. Nothing else changes. */
|
|
114
|
-
trash(ctx: Ctx, loc: string): Promise<Node>;
|
|
115
|
-
/** Items trashed on their own, newest first. */
|
|
116
|
-
listTrash(ctx: Ctx): Promise<Node[]>;
|
|
117
|
-
/** Puts a trashed item back. It needs a live parent folder. */
|
|
118
|
-
restore(ctx: Ctx, id: string, opts?: {
|
|
119
|
-
parentId?: string;
|
|
120
|
-
onConflict?: OnConflict;
|
|
121
|
-
}): Promise<Node>;
|
|
122
|
-
/** Live items that match every field given, sorted by path. */
|
|
123
|
-
search(ctx: Ctx, q?: SearchQuery): Promise<{
|
|
124
|
-
node: Node;
|
|
125
|
-
path: string;
|
|
126
|
-
}[]>;
|
|
127
|
-
/** Every item of the owner, trashed or not, with its original path and bytes. For export. */
|
|
128
|
-
exportData(ctx: Ctx): Promise<{
|
|
129
|
-
node: Node;
|
|
130
|
-
path: string;
|
|
131
|
-
data: Uint8Array | null;
|
|
132
|
-
missing: boolean;
|
|
133
|
-
}[]>;
|
|
134
|
-
/** Deletes every item and blob of the owner for good. Only the owner may do this, never an agent for them. A failed call can run again. */
|
|
135
|
-
deleteAll(ctx: Ctx): Promise<{
|
|
136
|
-
removed: number;
|
|
137
|
-
}>;
|
|
138
|
-
/** Deletes a trashed item for good, with everything under it and all their bytes. */
|
|
139
|
-
purge(ctx: Ctx, id: string): Promise<{
|
|
140
|
-
removed: number;
|
|
141
|
-
}>;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
export { type ActorKind as A, type Ctx as C, type Drive as D, type ErrorCode as E, type Node as N, type OnConflict as O, ROOT_ID as R, type SearchQuery as S, type Actor as a, ACTOR_KINDS as b, type Action as c, type Can as d, type DriveDeps as e, DriveError as f, createDrive as g, parseName as p };
|