@voltro/plugin-storage 0.84.0 → 0.86.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/dist/rpc.js CHANGED
@@ -1,17 +1,21 @@
1
1
  import { StorageAccessDenied as e, StorageError as t, StorageRejected as n, StorageScanRejected as r } from "./types.js";
2
2
  import { Schema as i } from "effect";
3
- import { defineAction as a, defineMutation as o, defineQuery as s } from "@voltro/protocol";
3
+ import { StorageAccessPolicySchema as a, defineAction as o, defineMutation as s, defineQuery as c } from "@voltro/protocol";
4
4
  //#region src/rpc.ts
5
- var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u = i.Struct({
5
+ var l = i.Literals([
6
+ "user",
7
+ "group",
8
+ "apiKey"
9
+ ]), u = i.Literals(["read", "write"]), d = i.Struct({
6
10
  id: i.String,
7
11
  refId: i.String,
8
- principalType: c,
12
+ principalType: l,
9
13
  principalId: i.String,
10
- permission: l,
14
+ permission: u,
11
15
  createdAt: i.String,
12
16
  expiresAt: i.NullOr(i.String),
13
17
  createdBy: i.NullOr(i.String)
14
- }), d = i.Struct({
18
+ }), f = i.Struct({
15
19
  id: i.String,
16
20
  tenantId: i.NullOr(i.String),
17
21
  ownerId: i.NullOr(i.String),
@@ -20,7 +24,7 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
20
24
  contentType: i.String,
21
25
  size: i.Number,
22
26
  checksum: i.String,
23
- visibility: i.Literal("public", "private"),
27
+ visibility: i.Literals(["public", "private"]),
24
28
  hasPassword: i.Boolean,
25
29
  createdAt: i.String,
26
30
  width: i.NullOr(i.Number),
@@ -33,7 +37,7 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
33
37
  caption: i.NullOr(i.String),
34
38
  derivedFrom: i.NullOr(i.String),
35
39
  kind: i.NullOr(i.String)
36
- }), f = s({
40
+ }), p = c({
37
41
  name: "storage.listRefs",
38
42
  input: i.Struct({
39
43
  folder: i.optional(i.String),
@@ -44,12 +48,12 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
44
48
  offset: i.optional(i.Number)
45
49
  }),
46
50
  output: i.Struct({
47
- refs: i.Array(d),
51
+ refs: i.Array(f),
48
52
  nextOffset: i.NullOr(i.Number)
49
53
  }),
50
54
  error: t,
51
55
  guards: [{ scope: "storage:browse" }]
52
- }), p = a({
56
+ }), m = o({
53
57
  name: "storage.mintUrl",
54
58
  input: i.Struct({
55
59
  id: i.String,
@@ -57,9 +61,9 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
57
61
  expiresInSec: i.optional(i.Number)
58
62
  }),
59
63
  output: i.Struct({ url: i.String }),
60
- error: i.Union(t, e),
64
+ error: i.Union([t, e]),
61
65
  openAccess: "per-object authorization: the access policy + grants decide this subject's read (StorageAccessDenied on refusal); a scope here would double-gate what the policy already decides per object"
62
- }), m = a({
66
+ }), h = o({
63
67
  name: "storage.mintUploadUrl",
64
68
  input: i.Struct({
65
69
  key: i.String,
@@ -69,11 +73,13 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
69
73
  output: i.Struct({ url: i.String }),
70
74
  error: t,
71
75
  guards: [{ scope: "storage:manage" }]
72
- }), h = a({
76
+ }), g = o({
73
77
  name: "storage.mintUploadTicket",
74
78
  input: i.Struct({
79
+ operationId: i.optional(i.String.pipe(i.check(i.makeFilter((e) => e.trim().length > 0)), i.check(i.isMaxLength(200)))),
75
80
  contentType: i.String,
76
- visibility: i.optional(i.Literal("public", "private")),
81
+ visibility: i.optional(i.Literals(["public", "private"])),
82
+ access: i.optional(a),
77
83
  key: i.optional(i.String),
78
84
  folder: i.optional(i.String),
79
85
  tags: i.optional(i.Array(i.String)),
@@ -83,15 +89,17 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
83
89
  }),
84
90
  output: i.Struct({
85
91
  uploadUrl: i.String,
86
- expiresInSec: i.Number
92
+ expiresInSec: i.Number,
93
+ operationId: i.optional(i.String)
87
94
  }),
88
95
  error: t,
89
96
  openAccess: "self-service upload: the ticket binds the calling subject + tenant, caps size, and the finalize path runs limits + scan; an unidentified caller is refused in-handler unless the app set `anonymousUploads`"
90
- }), g = a({
97
+ }), _ = o({
91
98
  name: "storage.mintPresignedUpload",
92
99
  input: i.Struct({
93
100
  contentType: i.String,
94
- visibility: i.optional(i.Literal("public", "private")),
101
+ visibility: i.optional(i.Literals(["public", "private"])),
102
+ access: i.optional(a),
95
103
  folder: i.optional(i.String),
96
104
  tags: i.optional(i.Array(i.String)),
97
105
  alt: i.optional(i.String),
@@ -105,7 +113,7 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
105
113
  }),
106
114
  error: t,
107
115
  openAccess: "self-service upload: the finalize token binds the calling subject + tenant; finalizeUpload refuses another subject's token and runs limits + scan; an unidentified caller is refused in-handler unless the app set `anonymousUploads`"
108
- }), _ = a({
116
+ }), v = o({
109
117
  name: "storage.finalizeUpload",
110
118
  input: i.Struct({ finalizeToken: i.String }),
111
119
  output: i.Struct({
@@ -116,14 +124,19 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
116
124
  width: i.optional(i.Number),
117
125
  height: i.optional(i.Number)
118
126
  }),
119
- error: i.Union(t, n, r),
127
+ error: i.Union([
128
+ t,
129
+ n,
130
+ r
131
+ ]),
120
132
  openAccess: "authorization is the signed finalize token itself: it binds the minting subject where there was one (403 for another caller; an anonymous ticket is bound by possession of the short-lived token alone) and the finalize runs limits + scan"
121
- }), v = a({
133
+ }), y = o({
122
134
  name: "storage.beginResumableUpload",
123
135
  input: i.Struct({
124
136
  contentType: i.String,
125
137
  size: i.Number,
126
- visibility: i.optional(i.Literal("public", "private")),
138
+ visibility: i.optional(i.Literals(["public", "private"])),
139
+ access: i.optional(a),
127
140
  folder: i.optional(i.String),
128
141
  tags: i.optional(i.Array(i.String)),
129
142
  alt: i.optional(i.String),
@@ -140,12 +153,13 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
140
153
  }),
141
154
  error: t,
142
155
  openAccess: "self-service upload: the resumable token binds the calling subject + tenant and the assembled object runs limits + scan; an unidentified caller is refused in-handler unless the app set `anonymousUploads`"
143
- }), y = a({
156
+ }), b = o({
144
157
  name: "storage.beginMultipartUpload",
145
158
  input: i.Struct({
146
159
  contentType: i.String,
147
160
  size: i.Number,
148
- visibility: i.optional(i.Literal("public", "private")),
161
+ visibility: i.optional(i.Literals(["public", "private"])),
162
+ access: i.optional(a),
149
163
  folder: i.optional(i.String),
150
164
  tags: i.optional(i.Array(i.String)),
151
165
  alt: i.optional(i.String),
@@ -160,7 +174,7 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
160
174
  }),
161
175
  error: t,
162
176
  openAccess: "self-service upload: the multipart token binds the calling subject + tenant; completion refuses another subject's token; an unidentified caller is refused in-handler unless the app set `anonymousUploads`"
163
- }), b = a({
177
+ }), x = o({
164
178
  name: "storage.signMultipartPart",
165
179
  input: i.Struct({
166
180
  multipartToken: i.String,
@@ -169,7 +183,7 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
169
183
  output: i.Struct({ url: i.String }),
170
184
  error: t,
171
185
  openAccess: "authorization is the signed multipart token: parts can only be signed for a session a subject legitimately began"
172
- }), x = a({
186
+ }), S = o({
173
187
  name: "storage.completeMultipartUpload",
174
188
  input: i.Struct({
175
189
  multipartToken: i.String,
@@ -183,20 +197,21 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
183
197
  url: i.String,
184
198
  size: i.Number
185
199
  }),
186
- error: i.Union(t, n),
200
+ error: i.Union([t, n]),
187
201
  openAccess: "authorization is the signed multipart token: completion refuses a token minted by another subject, and where there was none the binding is possession of the short-lived token alone"
188
- }), S = a({
202
+ }), C = o({
189
203
  name: "storage.abortMultipartUpload",
190
204
  input: i.Struct({ multipartToken: i.String }),
191
205
  output: i.Struct({ ok: i.Boolean }),
192
206
  error: t,
193
207
  openAccess: "authorization is the signed multipart token: aborting releases the caller's own upload session"
194
- }), C = a({
208
+ }), w = o({
195
209
  name: "storage.upload",
196
210
  input: i.Struct({
197
211
  bytesBase64: i.String,
198
212
  contentType: i.String,
199
- visibility: i.optional(i.Literal("public", "private")),
213
+ visibility: i.optional(i.Literals(["public", "private"])),
214
+ access: i.optional(a),
200
215
  key: i.optional(i.String),
201
216
  password: i.optional(i.String)
202
217
  }),
@@ -204,13 +219,17 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
204
219
  id: i.String,
205
220
  url: i.String
206
221
  }),
207
- error: i.Union(t, n, r),
222
+ error: i.Union([
223
+ t,
224
+ n,
225
+ r
226
+ ]),
208
227
  openAccess: "self-service upload: ownerId/tenant come from the calling subject and the put runs limits + scan; an unidentified caller is refused in-handler unless the app set `anonymousUploads`"
209
- }), w = a({
228
+ }), T = o({
210
229
  name: "storage.ingestUrl",
211
230
  input: i.Struct({
212
231
  url: i.String,
213
- visibility: i.optional(i.Literal("public", "private")),
232
+ visibility: i.optional(i.Literals(["public", "private"])),
214
233
  folder: i.optional(i.String),
215
234
  tags: i.optional(i.Array(i.String)),
216
235
  alt: i.optional(i.String),
@@ -221,33 +240,37 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
221
240
  id: i.String,
222
241
  url: i.String
223
242
  }),
224
- error: i.Union(t, n, r),
243
+ error: i.Union([
244
+ t,
245
+ n,
246
+ r
247
+ ]),
225
248
  guards: [{ scope: "storage:manage" }]
226
- }), T = o({
249
+ }), E = s({
227
250
  name: "storage.share",
228
251
  input: i.Struct({
229
252
  refId: i.String,
230
- principalType: c,
253
+ principalType: l,
231
254
  principalId: i.String,
232
- permission: i.optional(l),
255
+ permission: i.optional(u),
233
256
  expiresInDays: i.optional(i.Number)
234
257
  }),
235
258
  output: i.Struct({ grantId: i.String }),
236
259
  error: t,
237
260
  openAccess: "owner-or-admin enforced in-handler (assertMayAdministerGrants): only the ref's owner or admin:full may grant, which is stricter per object than any global scope"
238
- }), E = o({
261
+ }), D = s({
239
262
  name: "storage.revoke",
240
263
  input: i.Struct({ grantId: i.String }),
241
264
  output: i.Struct({ ok: i.Boolean }),
242
265
  error: t,
243
266
  openAccess: "owner-or-admin enforced in-handler: only the owning subject (or admin:full) of the grant's object may revoke; unknown and unowned grants report the same 403"
244
- }), D = s({
267
+ }), O = c({
245
268
  name: "storage.listGrants",
246
269
  input: i.Struct({ refId: i.String }),
247
- output: i.Struct({ grants: i.Array(u) }),
270
+ output: i.Struct({ grants: i.Array(d) }),
248
271
  error: t,
249
272
  openAccess: "owner-or-admin enforced in-handler: who an object is shared with is readable only by the object's owner or admin:full"
250
- }), O = [
273
+ }), k = [
251
274
  {
252
275
  tag: "storage.mintUrl",
253
276
  kind: "action",
@@ -378,4 +401,4 @@ var c = i.Literal("user", "group", "apiKey"), l = i.Literal("read", "write"), u
378
401
  }
379
402
  ];
380
403
  //#endregion
381
- export { S as abortMultipartUploadDescriptor, y as beginMultipartUploadDescriptor, v as beginResumableUploadDescriptor, x as completeMultipartUploadDescriptor, _ as finalizeUploadDescriptor, w as ingestUrlDescriptor, D as listGrantsDescriptor, f as listRefsDescriptor, g as mintPresignedUploadDescriptor, h as mintUploadTicketDescriptor, m as mintUploadUrlDescriptor, p as mintUrlDescriptor, E as revokeDescriptor, T as shareDescriptor, b as signMultipartPartDescriptor, O as storageRpcClientImports, C as uploadDescriptor };
404
+ export { C as abortMultipartUploadDescriptor, b as beginMultipartUploadDescriptor, y as beginResumableUploadDescriptor, S as completeMultipartUploadDescriptor, v as finalizeUploadDescriptor, T as ingestUrlDescriptor, O as listGrantsDescriptor, p as listRefsDescriptor, _ as mintPresignedUploadDescriptor, g as mintUploadTicketDescriptor, h as mintUploadUrlDescriptor, m as mintUrlDescriptor, D as revokeDescriptor, E as shareDescriptor, x as signMultipartPartDescriptor, k as storageRpcClientImports, w as uploadDescriptor };
@@ -0,0 +1,46 @@
1
+ import { storageEnv as e } from "./env.js";
2
+ //#region src/scanners.ts
3
+ var t = (e, t = 65536) => {
4
+ let n = [Buffer.from("zINSTREAM\0", "utf8")];
5
+ for (let r = 0; r < e.length; r += t) {
6
+ let i = e.subarray(r, Math.min(r + t, e.length)), a = Buffer.alloc(4);
7
+ a.writeUInt32BE(i.length, 0), n.push(a, Buffer.from(i));
8
+ }
9
+ let r = Buffer.alloc(4);
10
+ return r.writeUInt32BE(0, 0), n.push(r), Buffer.concat(n);
11
+ }, n = (e) => {
12
+ let t = e.replace(/\0+$/, "").trim();
13
+ if (/\bOK$/.test(t)) return { clean: !0 };
14
+ let n = /:\s*(.+?)\s+FOUND$/.exec(t);
15
+ if (n) return {
16
+ clean: !1,
17
+ threat: n[1] ?? "unknown"
18
+ };
19
+ throw Error(`clamav: unexpected response: ${t}`);
20
+ }, r = async (r, i) => {
21
+ let a = await import("node:net"), o = e.read("CLAMAV_HOST", i.host) ?? "127.0.0.1", s = e.read("CLAMAV_PORT"), c = i.port ?? (s ? Number(s) : 3310), l = i.timeoutMs ?? 3e4;
22
+ return new Promise((e, s) => {
23
+ let u = a.createConnection({
24
+ host: o,
25
+ port: c
26
+ }), d = "", f = setTimeout(() => {
27
+ u.destroy(), s(/* @__PURE__ */ Error("clamav scan timed out"));
28
+ }, l);
29
+ u.on("error", (e) => {
30
+ clearTimeout(f), s(e);
31
+ }), u.on("connect", () => {
32
+ u.end(t(r, i.chunkSize));
33
+ }), u.on("data", (e) => {
34
+ d += e.toString("utf8");
35
+ }), u.on("close", () => {
36
+ clearTimeout(f);
37
+ try {
38
+ e(n(d));
39
+ } catch (e) {
40
+ s(e);
41
+ }
42
+ });
43
+ });
44
+ }, i = (e = {}) => (t) => r(t.bytes, e);
45
+ //#endregion
46
+ export { i as clamavScanner, t as encodeInstream, n as parseClamavResponse };