@voltro/plugin-releases 0.83.1 → 0.84.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/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { ReleaseNotFound as e, ReleaseRefused as t } from "./errors.js";
2
2
  import { a as n, i as r, n as i, o as a, r as o, s, t as c } from "./rollout-CGRKMTfv.js";
3
- import { _ as l, a as u, c as d, d as ee, f as te, g as f, h as p, l as ne, m as re, o as ie, p as ae, r as m, s as oe, t as h, u as se, v as g, y as _ } from "./rpc-U7ytx6SC.js";
4
- import { Effect as v } from "effect";
5
- import { randomBytes as y } from "node:crypto";
6
- import { definePlugin as ce } from "@voltro/protocol";
7
- import { boolean as b, eq as x, id as S, integer as C, json as w, queryFor as T, registerRetention as le, retentionTtlMsFromEnv as ue, table as E, text as D, timestamp as O } from "@voltro/database";
8
- import { newTraceId as de } from "@voltro/runtime";
9
- var fe = (e, t, n) => {
3
+ import { _ as l, a as u, c as ee, d as te, f as ne, g as d, h as f, l as re, m as ie, o as ae, p as oe, r as p, s as se, t as m, u as ce, v as h, y as g } from "./rpc-DeEV8l3U.js";
4
+ import { Effect as _, Runtime as le, Schema as ue } from "effect";
5
+ import { randomBytes as v } from "node:crypto";
6
+ import { AsyncLocalStorage as y } from "node:async_hooks";
7
+ import { definePlugin as de } from "@voltro/protocol";
8
+ import { and as fe, boolean as b, eq as x, id as S, integer as C, json as w, queryFor as T, registerRetention as pe, retentionTtlMsFromEnv as me, table as E, text as D, timestamp as O } from "@voltro/database";
9
+ import { newTraceId as he } from "@voltro/runtime";
10
+ var ge = (e, t, n) => {
10
11
  let r = /* @__PURE__ */ new Set();
11
12
  for (let e of t) e.currentReleaseId !== null && r.add(e.currentReleaseId);
12
13
  let i = [];
@@ -15,23 +16,24 @@ var fe = (e, t, n) => {
15
16
  for (let e of s.slice(o)) r.has(e.id) || i.push(e);
16
17
  }
17
18
  return i;
18
- }, pe = [
19
+ }, k = [
19
20
  "web",
20
21
  "ios",
21
22
  "android",
22
23
  "macos",
23
24
  "windows",
24
25
  "linux"
25
- ], me = [
26
+ ], A = [
26
27
  "pwa",
27
28
  "expo",
28
29
  "tauri",
29
30
  "electron"
30
- ], k = E(f, {
31
+ ], j = E(d, {
31
32
  id: S({ prefix: "relapp" }),
32
33
  app: D(),
33
34
  platform: D(),
34
35
  shell: D(),
36
+ revision: C().default(0),
35
37
  bundleId: D().nullable(),
36
38
  updaterPublicKey: D().nullable(),
37
39
  runtimeVersion: D().nullable(),
@@ -40,7 +42,7 @@ var fe = (e, t, n) => {
40
42
  "app",
41
43
  "platform",
42
44
  "shell"
43
- ]), A = E(g, {
45
+ ]), M = E(h, {
44
46
  id: S({ prefix: "relch" }),
45
47
  appId: D(),
46
48
  name: D(),
@@ -50,7 +52,7 @@ var fe = (e, t, n) => {
50
52
  public: b().default(!1),
51
53
  allowUnsigned: b().default(!1),
52
54
  updatedAt: O().default("now").onUpdate("now")
53
- }).index("byReleaseChannelApp", ["appId", "name"]), j = E(p, {
55
+ }).index("byReleaseChannelApp", ["appId", "name"]), N = E(f, {
54
56
  id: S({ prefix: "rel" }),
55
57
  appId: D(),
56
58
  channelId: D(),
@@ -64,7 +66,7 @@ var fe = (e, t, n) => {
64
66
  createdBy: D().nullable(),
65
67
  createdAt: O().default("now"),
66
68
  updatedAt: O().default("now").onUpdate("now")
67
- }).index("byReleaseAppChannel", ["appId", "channelId"]).index("byReleaseVersion", ["appId", "version"]), M = E(l, {
69
+ }).index("byReleaseAppChannel", ["appId", "channelId"]).index("byReleaseVersion", ["appId", "version"]), P = E(l, {
68
70
  id: S({ prefix: "relart" }),
69
71
  releaseId: D(),
70
72
  kind: D(),
@@ -77,7 +79,7 @@ var fe = (e, t, n) => {
77
79
  assetKey: D().nullable(),
78
80
  contentType: D().nullable(),
79
81
  createdAt: O().default("now")
80
- }).index("byReleaseArtifactRelease", ["releaseId"]), N = E(_, {
82
+ }).index("byReleaseArtifactRelease", ["releaseId"]), F = E(g, {
81
83
  id: S({ prefix: "relev" }),
82
84
  appId: D(),
83
85
  channelId: D().nullable(),
@@ -87,20 +89,20 @@ var fe = (e, t, n) => {
87
89
  actorId: D().nullable(),
88
90
  detail: w().nullable(),
89
91
  at: O().default("now")
90
- }).index("byReleaseEventApp", ["appId", "at"]), P = [
91
- k,
92
- A,
92
+ }).index("byReleaseEventApp", ["appId", "at"]), I = [
93
93
  j,
94
94
  M,
95
- N
96
- ], F = (e, t) => t.currentVersion !== null && c(e.version, t.currentVersion) <= 0 ? !1 : o({
95
+ N,
96
+ P,
97
+ F
98
+ ], L = (e, t) => t.currentVersion !== null && c(e.version, t.currentVersion) <= 0 ? !1 : o({
97
99
  installId: t.installId,
98
100
  salt: e.rolloutSalt,
99
101
  percent: e.rolloutPercent,
100
102
  ...t.cohorts === void 0 ? {} : { installCohorts: t.cohorts },
101
103
  releaseCohorts: e.cohorts
102
- }), I = (e, t) => {
103
- if (!F(e, t)) return null;
104
+ }), R = (e, t) => {
105
+ if (!L(e, t)) return null;
104
106
  let n = e.artifacts.find((e) => e.target === t.target && e.signature !== null);
105
107
  return !n || n.signature === null ? null : {
106
108
  version: e.version,
@@ -111,7 +113,7 @@ var fe = (e, t, n) => {
111
113
  url: n.url
112
114
  } }
113
115
  };
114
- }, L = (e, t, n = {}) => {
116
+ }, z = (e, t, n = {}) => {
115
117
  let r = {
116
118
  win: [
117
119
  "nsis",
@@ -136,14 +138,14 @@ var fe = (e, t, n) => {
136
138
  a.push(`path: ${o.url}`);
137
139
  let s = n[o.sha256];
138
140
  return a.push(s === void 0 ? `sha256: ${o.sha256}` : `sha512: ${s}`), a.push(`releaseDate: '${e.createdAt.toISOString()}'`), e.notes && a.push(`releaseNotes: ${JSON.stringify(e.notes)}`), a.join("\n") + "\n";
139
- }, R = (e, t, n) => {
141
+ }, B = (e, t, n) => {
140
142
  if (n.rolledBackTo !== null) return {
141
143
  kind: "rollback",
142
144
  commitTime: n.rolledBackTo.commitTime.toISOString()
143
145
  };
144
146
  if (e === null || n.runtimeVersion !== null && n.runtimeVersion !== t.runtimeVersion) return { kind: "no-update" };
145
147
  let r = e.buildId ?? e.id;
146
- if (t.currentUpdateId === r || !F(e, {
148
+ if (t.currentUpdateId === r || !L(e, {
147
149
  installId: t.installId,
148
150
  currentVersion: null,
149
151
  ...t.cohorts === void 0 ? {} : { cohorts: t.cohorts }
@@ -176,7 +178,7 @@ var fe = (e, t, n) => {
176
178
  }
177
179
  }
178
180
  };
179
- }, z = {
181
+ }, V = {
180
182
  macos: ["dmg", "zip"],
181
183
  windows: [
182
184
  "nsis",
@@ -190,21 +192,21 @@ var fe = (e, t, n) => {
190
192
  ],
191
193
  ios: ["ipa"],
192
194
  android: ["apk", "aab"]
193
- }, B = (e, t, n) => {
194
- let r = z[t] ?? [], i = e.artifacts.filter((e) => r.includes(e.kind));
195
+ }, _e = (e, t, n) => {
196
+ let r = V[t] ?? [], i = e.artifacts.filter((e) => r.includes(e.kind));
195
197
  if (i.length === 0) return null;
196
198
  if (n !== void 0) {
197
199
  let e = i.find((e) => e.target !== null && e.target.endsWith(n));
198
200
  if (e) return e;
199
201
  }
200
202
  return i[0];
201
- }, V = (e) => /Windows/i.test(e) ? {
203
+ }, H = (e) => /Windows/i.test(e) ? {
202
204
  os: "windows",
203
205
  arch: /ARM64|aarch64/i.test(e) ? "aarch64" : "x86_64"
204
206
  } : /Macintosh|Mac OS X/i.test(e) ? { os: "macos" } : /Android/i.test(e) ? { os: "android" } : /iPhone|iPad|iPod/i.test(e) ? { os: "ios" } : /Linux/i.test(e) ? {
205
207
  os: "linux",
206
208
  arch: /aarch64|arm64/i.test(e) ? "aarch64" : "x86_64"
207
- } : null, H = (e, t, n = {}) => ({
209
+ } : null, U = (e, t, n = {}) => ({
208
210
  status: e,
209
211
  body: JSON.stringify(t),
210
212
  contentType: "application/json; charset=utf-8",
@@ -212,38 +214,41 @@ var fe = (e, t, n) => {
212
214
  "cache-control": "no-store",
213
215
  ...n
214
216
  }
215
- }), he = (e, t, n) => ({
217
+ }), ve = (e, t, n) => ({
216
218
  status: e,
217
219
  body: t,
218
220
  contentType: n,
219
221
  headers: { "cache-control": "no-store" }
220
- }), U = (e) => ({
222
+ }), W = (e) => ({
221
223
  status: e,
222
224
  body: "",
223
225
  headers: { "cache-control": "no-store" }
224
- }), W = (e) => `${e}_${y(9).toString("base64url")}`, G = (n) => {
225
- let r = (n.prefix ?? "/releases").replace(/\/+$/, ""), a = n.now ?? Date.now, o, s = () => {
226
+ }), G = (e) => `${e}_${v(9).toString("base64url")}`, ye = (n) => {
227
+ let r = (n.prefix ?? "/releases").replace(/\/+$/, ""), a = n.now ?? Date.now, o, s = new y(), p = new y(), v = () => {
228
+ let e = s.getStore();
229
+ if (e) return e;
226
230
  if (!o) throw new t({ reason: "releases: the app store is not bound yet" });
227
231
  return o;
228
- }, m = null, y = async (e) => {
229
- let t = (await s().query(T(k).where(x("app", e.app)).descriptor)).find((t) => t.platform === e.platform && t.shell === e.shell), n = !t;
230
- t ||= await s().insert(f, {
231
- id: W("relapp"),
232
+ }, b = null, S = async (e) => {
233
+ let t = (await v().query(T(j).where(x("app", e.app)).descriptor)).find((t) => t.platform === e.platform && t.shell === e.shell), n = !t;
234
+ t ||= await v().insert(d, {
235
+ id: G("relapp"),
232
236
  app: e.app,
233
237
  platform: e.platform,
234
238
  shell: e.shell,
239
+ revision: 0,
235
240
  bundleId: e.bundleId ?? null,
236
241
  updaterPublicKey: e.updaterPublicKey ?? null,
237
242
  runtimeVersion: e.runtimeVersion ?? null,
238
243
  createdAt: new Date(a())
239
244
  });
240
- let r = await s().query(T(A).where(x("appId", t.id)).descriptor);
245
+ let r = await v().query(T(M).where(x("appId", t.id)).descriptor);
241
246
  for (let n of e.channels ?? [
242
247
  "stable",
243
248
  "beta",
244
249
  "internal"
245
- ]) r.some((e) => e.name === n) || await s().insert(g, {
246
- id: W("relch"),
250
+ ]) r.some((e) => e.name === n) || await v().insert(h, {
251
+ id: G("relch"),
247
252
  appId: t.id,
248
253
  name: n,
249
254
  currentReleaseId: null,
@@ -257,19 +262,19 @@ var fe = (e, t, n) => {
257
262
  row: t,
258
263
  created: n
259
264
  };
260
- }, b = async () => {
261
- for (let e of n.apps) await y(e);
262
- }, S = () => m ?? Promise.resolve(), C = (t, n, r) => v.tryPromise({
265
+ }, C = async () => {
266
+ for (let e of n.apps) await S(e);
267
+ }, w = () => b ?? Promise.resolve(), E = (t, n, r) => _.tryPromise({
263
268
  try: async () => {
264
- await S();
265
- let i = (await s().query(T(k).where(x("app", t)).descriptor)).find((e) => (n === void 0 || e.platform === n) && (r === void 0 || e.shell === r));
266
- if (!i) throw new e({ app: t });
267
- return i;
269
+ await w();
270
+ let i = await v().query(T(j).where(x("app", t)).descriptor), a = p.getStore(), o = i.find((e) => (a === void 0 || e.id === a) && (n === void 0 || e.platform === n) && (r === void 0 || e.shell === r));
271
+ if (!o) throw new e({ app: t });
272
+ return o;
268
273
  },
269
274
  catch: (n) => n instanceof e ? n : new e({ app: t })
270
- }), w = (t, n, r) => v.tryPromise({
275
+ }), D = (t, n, r) => _.tryPromise({
271
276
  try: async () => {
272
- let i = (await s().query(T(A).where(x("appId", t)).descriptor)).find((e) => e.name === n);
277
+ let i = (await v().query(T(M).where(x("appId", t)).descriptor)).find((e) => e.name === n);
273
278
  if (!i) throw new e({
274
279
  app: r,
275
280
  channel: n
@@ -280,11 +285,11 @@ var fe = (e, t, n) => {
280
285
  app: r,
281
286
  channel: n
282
287
  })
283
- }), E = (e) => s().query(T(j).where(x("id", e)).descriptor).then((e) => e[0] ?? null), D = (e) => s().query(T(j).where(x("appId", e)).descriptor), O = (e) => s().query(T(M).where(x("releaseId", e)).descriptor), pe = (e) => s().query(T(A).where(x("appId", e)).descriptor), me = (e) => n.retention?.perChannel?.[e] ?? n.retention?.keep ?? 10, F = async (e, t) => {
284
- let n = await pe(e), r = fe(await D(e), n, me);
288
+ }), O = (e) => v().query(T(N).where(x("id", e)).descriptor).then((e) => e[0] ?? null), k = (e) => v().query(T(N).where(x("appId", e)).descriptor), A = (e) => v().query(T(P).where(x("releaseId", e)).descriptor), L = (e) => v().query(T(M).where(x("appId", e)).descriptor), V = (e) => n.retention?.perChannel?.[e] ?? n.retention?.keep ?? 10, ye = async (e, t) => {
289
+ let n = await L(e), r = ge(await k(e), n, V);
285
290
  if (r.length === 0) return [];
286
- for (let e of r) await s().deleteMany(l, { where: x("releaseId", e.id) }), await s().delete(p, e.id);
287
- return await K({
291
+ for (let e of r) await v().deleteMany(l, { where: x("releaseId", e.id) }), await v().delete(f, e.id);
292
+ return await q({
288
293
  appId: e,
289
294
  kind: "prune",
290
295
  actorId: t,
@@ -293,8 +298,8 @@ var fe = (e, t, n) => {
293
298
  channel: n.find((t) => t.id === e.channelId)?.name ?? null
294
299
  })) }
295
300
  }), r;
296
- }, z = async (e) => {
297
- let t = await O(e.id);
301
+ }, Se = async (e) => {
302
+ let t = await A(e.id);
298
303
  return {
299
304
  id: e.id,
300
305
  version: e.version,
@@ -315,8 +320,8 @@ var fe = (e, t, n) => {
315
320
  contentType: e.contentType
316
321
  }))
317
322
  };
318
- }, G = async (e, t) => {
319
- let n = await v.runPromise(C(e)), r = await v.runPromise(w(n.id, t, e)), i = r.currentReleaseId ? await E(r.currentReleaseId) : null;
323
+ }, K = async (e, t) => {
324
+ let n = await _.runPromise(E(e)), r = await _.runPromise(D(n.id, t, e)), i = r.currentReleaseId ? await O(r.currentReleaseId) : null;
320
325
  return {
321
326
  app: e,
322
327
  channel: t,
@@ -327,8 +332,8 @@ var fe = (e, t, n) => {
327
332
  rolloutSalt: i?.rolloutSalt ?? null,
328
333
  cohorts: i?.cohorts ?? null
329
334
  };
330
- }, K = (e) => s().insert(_, {
331
- id: W("relev"),
335
+ }, q = (e) => v().insert(g, {
336
+ id: G("relev"),
332
337
  appId: e.appId,
333
338
  channelId: e.channelId ?? null,
334
339
  releaseId: e.releaseId ?? null,
@@ -337,20 +342,20 @@ var fe = (e, t, n) => {
337
342
  actorId: e.actorId ?? null,
338
343
  detail: e.detail ?? null,
339
344
  at: new Date(a())
340
- }), q = (e) => e.request.subject.type === "user" ? e.request.subject.id : null, ve = {
341
- ...oe,
345
+ }), J = (e) => e.request.subject.type === "user" ? e.request.subject.id : null, Ce = {
346
+ ...se,
342
347
  description: "The reactive release policy of a channel: latest version, minimum supported version, kill switches, rollout.",
343
- execute: (e) => v.tryPromise({
344
- try: () => G(e.app, e.channel),
348
+ execute: (e) => _.tryPromise({
349
+ try: () => K(e.app, e.channel),
345
350
  catch: (e) => e
346
351
  })
347
- }, ye = {
348
- ...ie,
352
+ }, we = {
353
+ ...ae,
349
354
  description: "Every release of an app target, newest first.",
350
- execute: (e) => v.gen(function* () {
351
- let t = yield* C(e.app), n = yield* v.promise(() => D(t.id)), r = yield* v.promise(() => s().query(T(A).where(x("appId", t.id)).descriptor)), i = [];
355
+ execute: (e) => _.gen(function* () {
356
+ let t = yield* E(e.app), n = yield* _.promise(() => k(t.id)), r = yield* _.promise(() => v().query(T(M).where(x("appId", t.id)).descriptor)), i = [];
352
357
  for (let e of [...n].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || c(t.version, e.version))) {
353
- let t = yield* v.promise(() => O(e.id));
358
+ let t = yield* _.promise(() => A(e.id));
354
359
  i.push({
355
360
  id: e.id,
356
361
  version: e.version,
@@ -365,13 +370,13 @@ var fe = (e, t, n) => {
365
370
  }
366
371
  return i;
367
372
  })
368
- }, be = {
369
- ...ne,
373
+ }, Te = {
374
+ ...re,
370
375
  description: "Register an app target at runtime, with its channels; idempotent.",
371
- execute: (e) => v.tryPromise({
376
+ execute: (e) => _.tryPromise({
372
377
  try: async () => {
373
- await S();
374
- let { row: t, created: n } = await y({
378
+ await w();
379
+ let { row: t, created: n } = await S({
375
380
  app: e.app,
376
381
  platform: e.platform,
377
382
  shell: e.shell,
@@ -387,14 +392,14 @@ var fe = (e, t, n) => {
387
392
  },
388
393
  catch: (n) => new t({ reason: `releases: ${e.app} could not be registered: ${n instanceof Error ? n.message : String(n)}` })
389
394
  })
390
- }, xe = {
395
+ }, Ee = {
391
396
  ...u,
392
397
  description: "Create a draft release of a version on a channel.",
393
- execute: (e, n) => v.gen(function* () {
394
- let r = yield* C(e.app), i = yield* w(r.id, e.channel, e.app);
395
- if ((yield* v.promise(() => D(r.id))).some((t) => t.version === e.version)) return yield* v.fail(new t({ reason: `version ${e.version} already exists for ${e.app}` }));
396
- let o = W("rel");
397
- return yield* v.promise(() => s().insert(p, {
398
+ execute: (e, n) => _.gen(function* () {
399
+ let r = yield* E(e.app), i = yield* D(r.id, e.channel, e.app);
400
+ if ((yield* _.promise(() => k(r.id))).some((t) => t.version === e.version)) return yield* _.fail(new t({ reason: `version ${e.version} already exists for ${e.app}` }));
401
+ let o = G("rel");
402
+ return yield* _.promise(() => v().insert(f, {
398
403
  id: o,
399
404
  appId: r.id,
400
405
  channelId: i.id,
@@ -403,32 +408,32 @@ var fe = (e, t, n) => {
403
408
  notes: e.notes ?? null,
404
409
  state: "draft",
405
410
  rolloutPercent: 0,
406
- rolloutSalt: W("salt"),
411
+ rolloutSalt: G("salt"),
407
412
  cohorts: e.cohorts ?? null,
408
- createdBy: q(n),
413
+ createdBy: J(n),
409
414
  createdAt: new Date(a()),
410
415
  updatedAt: new Date(a())
411
- })), yield* v.promise(() => K({
416
+ })), yield* _.promise(() => q({
412
417
  appId: r.id,
413
418
  channelId: i.id,
414
419
  releaseId: o,
415
420
  kind: "create",
416
- actorId: q(n),
421
+ actorId: J(n),
417
422
  detail: { version: e.version }
418
- })), yield* v.promise(() => F(r.id, q(n))), { id: o };
423
+ })), yield* _.promise(() => ye(r.id, J(n))), { id: o };
419
424
  })
420
- }, Se = {
421
- ...re,
425
+ }, De = {
426
+ ...ie,
422
427
  description: "Attach an artefact (a file the client downloads) to a release.",
423
- execute: (n, r) => v.gen(function* () {
424
- let i = yield* v.promise(() => E(n.releaseId));
425
- if (!i) return yield* v.fail(new e({
428
+ execute: (n, r) => _.gen(function* () {
429
+ let i = yield* _.promise(() => O(n.releaseId));
430
+ if (!i) return yield* _.fail(new e({
426
431
  app: "?",
427
432
  version: n.releaseId
428
433
  }));
429
- if (!/^[a-f0-9]{64}$/i.test(n.sha256)) return yield* v.fail(new t({ reason: "sha256 must be 64 hex characters" }));
430
- let o = W("relart");
431
- return yield* v.promise(() => s().insert(l, {
434
+ if (!/^[a-f0-9]{64}$/i.test(n.sha256)) return yield* _.fail(new t({ reason: "sha256 must be 64 hex characters" }));
435
+ let o = G("relart");
436
+ return yield* _.promise(() => v().insert(l, {
432
437
  id: o,
433
438
  releaseId: i.id,
434
439
  kind: n.kind,
@@ -441,158 +446,158 @@ var fe = (e, t, n) => {
441
446
  assetKey: n.assetKey ?? null,
442
447
  contentType: n.contentType ?? null,
443
448
  createdAt: new Date(a())
444
- })), yield* v.promise(() => K({
449
+ })), yield* _.promise(() => q({
445
450
  appId: i.appId,
446
451
  releaseId: i.id,
447
452
  kind: "upload",
448
- actorId: q(r),
453
+ actorId: J(r),
449
454
  detail: {
450
455
  kind: n.kind,
451
456
  target: n.target ?? null
452
457
  }
453
458
  })), { id: o };
454
459
  })
455
- }, Ce = {
456
- ...d,
460
+ }, Oe = {
461
+ ...ee,
457
462
  description: "Point a channel at a release (no rebuild) and start its rollout.",
458
- execute: (n, r) => v.gen(function* () {
459
- let i = yield* C(n.app), o = yield* w(i.id, n.to, n.app), c = yield* v.promise(() => D(i.id)), l = c.find((e) => e.version === n.version);
460
- if (!l) return yield* v.fail(new e({
463
+ execute: (n, r) => _.gen(function* () {
464
+ let i = yield* E(n.app), o = yield* D(i.id, n.to, n.app), s = yield* _.promise(() => k(i.id)), c = s.find((e) => e.version === n.version);
465
+ if (!c) return yield* _.fail(new e({
461
466
  app: n.app,
462
467
  version: n.version
463
468
  }));
464
- let u = yield* v.promise(() => O(l.id));
465
- if (!o.allowUnsigned && u.some((e) => e.signature === null)) return yield* v.fail(new t({ reason: `release ${n.version} has unsigned artefacts; channel ${n.to} refuses them` }));
466
- let d = Math.max(0, Math.min(100, n.rolloutPercent ?? 100));
467
- return yield* v.promise(() => s().update(p, l.id, {
469
+ let l = yield* _.promise(() => A(c.id));
470
+ if (!o.allowUnsigned && l.some((e) => e.signature === null)) return yield* _.fail(new t({ reason: `release ${n.version} has unsigned artefacts; channel ${n.to} refuses them` }));
471
+ let u = Math.max(0, Math.min(100, n.rolloutPercent ?? 100));
472
+ return yield* _.promise(() => v().update(f, c.id, {
468
473
  channelId: o.id,
469
- state: d >= 100 ? "complete" : "rolling",
470
- rolloutPercent: d,
474
+ state: u >= 100 ? "complete" : "rolling",
475
+ rolloutPercent: u,
471
476
  updatedAt: new Date(a())
472
- })), yield* v.promise(() => s().update(g, o.id, {
473
- currentReleaseId: l.id,
477
+ })), yield* _.promise(() => v().update(h, o.id, {
478
+ currentReleaseId: c.id,
474
479
  updatedAt: new Date(a())
475
- })), yield* v.promise(() => K({
480
+ })), yield* _.promise(() => q({
476
481
  appId: i.id,
477
482
  channelId: o.id,
478
- releaseId: l.id,
483
+ releaseId: c.id,
479
484
  kind: "promote",
480
- actorId: q(r),
485
+ actorId: J(r),
481
486
  detail: {
482
- from: c.find((e) => e.id === o.currentReleaseId)?.version ?? null,
487
+ from: s.find((e) => e.id === o.currentReleaseId)?.version ?? null,
483
488
  to: n.version,
484
- rolloutPercent: d
489
+ rolloutPercent: u
485
490
  }
486
491
  })), {
487
492
  channel: n.to,
488
493
  version: n.version,
489
- rolloutPercent: d
494
+ rolloutPercent: u
490
495
  };
491
496
  })
492
- }, we = {
493
- ...te,
497
+ }, ke = {
498
+ ...ne,
494
499
  description: "Change the rollout percentage of the channel's current release.",
495
- execute: (n, r) => v.gen(function* () {
496
- let i = yield* C(n.app), o = yield* w(i.id, n.channel, n.app);
497
- if (!o.currentReleaseId) return yield* v.fail(new t({ reason: `channel ${n.channel} has no current release` }));
498
- let c = yield* v.promise(() => E(o.currentReleaseId));
499
- if (!c) return yield* v.fail(new e({
500
+ execute: (n, r) => _.gen(function* () {
501
+ let i = yield* E(n.app), o = yield* D(i.id, n.channel, n.app);
502
+ if (!o.currentReleaseId) return yield* _.fail(new t({ reason: `channel ${n.channel} has no current release` }));
503
+ let s = yield* _.promise(() => O(o.currentReleaseId));
504
+ if (!s) return yield* _.fail(new e({
500
505
  app: n.app,
501
506
  channel: n.channel
502
507
  }));
503
- let l = Math.max(0, Math.min(100, n.percent));
504
- return yield* v.promise(() => s().update(p, c.id, {
505
- rolloutPercent: l,
506
- state: l >= 100 ? "complete" : "rolling",
508
+ let c = Math.max(0, Math.min(100, n.percent));
509
+ return yield* _.promise(() => v().update(f, s.id, {
510
+ rolloutPercent: c,
511
+ state: c >= 100 ? "complete" : "rolling",
507
512
  updatedAt: new Date(a())
508
- })), yield* v.promise(() => K({
513
+ })), yield* _.promise(() => q({
509
514
  appId: i.id,
510
515
  channelId: o.id,
511
- releaseId: c.id,
516
+ releaseId: s.id,
512
517
  kind: "rollout",
513
- actorId: q(r),
514
- detail: { percent: l }
518
+ actorId: J(r),
519
+ detail: { percent: c }
515
520
  })), {
516
- version: c.version,
517
- rolloutPercent: l
521
+ version: s.version,
522
+ rolloutPercent: c
518
523
  };
519
524
  })
520
- }, Te = {
521
- ...ee,
525
+ }, Ae = {
526
+ ...te,
522
527
  description: "Point the channel back at the previous release; the current one is marked rolled back.",
523
- execute: (e, n) => v.gen(function* () {
524
- let r = yield* C(e.app), i = yield* w(r.id, e.channel, e.app);
525
- if (!i.currentReleaseId) return yield* v.fail(new t({ reason: `channel ${e.channel} has no current release` }));
526
- let o = yield* v.promise(() => D(r.id)), l = o.find((e) => e.id === i.currentReleaseId), u = o.filter((e) => e.channelId === i.id && e.id !== i.currentReleaseId && e.state !== "rolledBack").sort((e, t) => c(t.version, e.version))[0];
527
- return l && (yield* v.promise(() => s().update(p, l.id, {
528
+ execute: (e, n) => _.gen(function* () {
529
+ let r = yield* E(e.app), i = yield* D(r.id, e.channel, e.app);
530
+ if (!i.currentReleaseId) return yield* _.fail(new t({ reason: `channel ${e.channel} has no current release` }));
531
+ let o = yield* _.promise(() => k(r.id)), s = o.find((e) => e.id === i.currentReleaseId), l = o.filter((e) => e.channelId === i.id && e.id !== i.currentReleaseId && e.state !== "rolledBack").sort((e, t) => c(t.version, e.version))[0];
532
+ return s && (yield* _.promise(() => v().update(f, s.id, {
528
533
  state: "rolledBack",
529
534
  updatedAt: new Date(a())
530
- }))), yield* v.promise(() => s().update(g, i.id, {
531
- currentReleaseId: u?.id ?? null,
535
+ }))), yield* _.promise(() => v().update(h, i.id, {
536
+ currentReleaseId: l?.id ?? null,
532
537
  updatedAt: new Date(a())
533
- })), yield* v.promise(() => K({
538
+ })), yield* _.promise(() => q({
534
539
  appId: r.id,
535
540
  channelId: i.id,
536
- releaseId: l?.id ?? null,
541
+ releaseId: s?.id ?? null,
537
542
  kind: "rollback",
538
543
  reason: e.reason,
539
- actorId: q(n),
544
+ actorId: J(n),
540
545
  detail: {
541
- from: l?.version ?? null,
542
- to: u?.version ?? null
546
+ from: s?.version ?? null,
547
+ to: l?.version ?? null
543
548
  }
544
- })), { version: u?.version ?? null };
549
+ })), { version: l?.version ?? null };
545
550
  })
546
- }, J = {
547
- ...ae,
551
+ }, je = {
552
+ ...oe,
548
553
  description: "Set the minimum supported version and kill switches of a channel.",
549
- execute: (e, t) => v.gen(function* () {
550
- let n = yield* C(e.app), r = yield* w(n.id, e.channel, e.app);
551
- return yield* v.promise(() => s().update(g, r.id, {
554
+ execute: (e, t) => _.gen(function* () {
555
+ let n = yield* E(e.app), r = yield* D(n.id, e.channel, e.app);
556
+ return yield* _.promise(() => v().update(h, r.id, {
552
557
  ...e.minSupportedVersion === void 0 ? {} : { minSupportedVersion: e.minSupportedVersion },
553
558
  ...e.killSwitches === void 0 ? {} : { killSwitches: e.killSwitches },
554
559
  updatedAt: new Date(a())
555
- })), yield* v.promise(() => K({
560
+ })), yield* _.promise(() => q({
556
561
  appId: n.id,
557
562
  channelId: r.id,
558
563
  kind: "policy",
559
564
  reason: e.reason,
560
- actorId: q(t),
565
+ actorId: J(t),
561
566
  detail: {
562
567
  minSupportedVersion: e.minSupportedVersion ?? null,
563
568
  killSwitches: e.killSwitches ?? null
564
569
  }
565
- })), yield* v.promise(() => G(e.app, e.channel));
570
+ })), yield* _.promise(() => K(e.app, e.channel));
566
571
  })
567
572
  }, Y = async (e, t) => {
568
- let n = await v.runPromise(C(e)), r = await v.runPromise(w(n.id, t, e)), i = r.currentReleaseId ? await E(r.currentReleaseId) : null;
573
+ let n = await _.runPromise(E(e)), r = await _.runPromise(D(n.id, t, e)), i = r.currentReleaseId ? await O(r.currentReleaseId) : null;
569
574
  return {
570
575
  app: n,
571
576
  channel: r,
572
- release: i ? await z(i) : null
577
+ release: i ? await Se(i) : null
573
578
  };
574
- }, X = (e, t) => t.get("install") ?? e.headers["x-voltro-install-id"] ?? e.headers["expo-embedded-update-id"] ?? "anonymous", Ee = {
579
+ }, X = (e, t) => t.get("install") ?? e.headers["x-voltro-install-id"] ?? e.headers["expo-embedded-update-id"] ?? "anonymous", Me = {
575
580
  method: "GET",
576
581
  path: r,
577
582
  handle: async (t) => {
578
- if (t.method !== "GET" && t.method !== "HEAD") return H(405, { error: "method_not_allowed" });
583
+ if (t.method !== "GET" && t.method !== "HEAD") return U(405, { error: "method_not_allowed" });
579
584
  let n = t.path.slice(r.length).split("/").filter((e) => e.length > 0).map(decodeURIComponent), a = new URLSearchParams(t.query), [o, s] = n;
580
- if (!o || !s) return H(404, { error: "not_found" });
585
+ if (!o || !s) return U(404, { error: "not_found" });
581
586
  try {
582
587
  if (s === "tauri") {
583
588
  let [, , e, r, i] = n;
584
- if (!e || !r || !i) return H(400, { error: "expected /tauri/:channel/:target/:currentVersion" });
585
- let { release: s } = await Y(o, e), c = s ? I(s, {
589
+ if (!e || !r || !i) return U(400, { error: "expected /tauri/:channel/:target/:currentVersion" });
590
+ let { release: s } = await Y(o, e), c = s ? R(s, {
586
591
  installId: X(t, a),
587
592
  currentVersion: i,
588
593
  target: r
589
594
  }) : null;
590
- return c ? H(200, c) : U(204);
595
+ return c ? U(200, c) : W(204);
591
596
  }
592
597
  if (s === "expo" && n[2] === "manifest") {
593
598
  let e = t.headers["expo-channel-name"] ?? a.get("channel") ?? "stable", n = t.headers["expo-platform"] ?? a.get("platform"), r = t.headers["expo-runtime-version"] ?? a.get("runtimeVersion") ?? "";
594
- if (n !== "ios" && n !== "android") return H(400, { error: "expo-platform must be ios or android" });
595
- let { app: i, release: s } = await Y(o, e), c = R(s, {
599
+ if (n !== "ios" && n !== "android") return U(400, { error: "expo-platform must be ios or android" });
600
+ let { app: i, release: s } = await Y(o, e), c = B(s, {
596
601
  installId: X(t, a),
597
602
  currentVersion: null,
598
603
  platform: n,
@@ -602,16 +607,16 @@ var fe = (e, t, n) => {
602
607
  runtimeVersion: i.runtimeVersion,
603
608
  rolledBackTo: null
604
609
  });
605
- return c.kind === "no-update" ? H(200, { type: "noUpdateAvailable" }, {
610
+ return c.kind === "no-update" ? U(200, { type: "noUpdateAvailable" }, {
606
611
  "expo-protocol-version": "1",
607
612
  "expo-sfv-version": "0"
608
- }) : c.kind === "rollback" ? H(200, {
613
+ }) : c.kind === "rollback" ? U(200, {
609
614
  type: "rollBackToEmbedded",
610
615
  parameters: { commitTime: c.commitTime }
611
616
  }, {
612
617
  "expo-protocol-version": "1",
613
618
  "expo-sfv-version": "0"
614
- }) : H(200, c.manifest, {
619
+ }) : U(200, c.manifest, {
615
620
  "expo-protocol-version": "1",
616
621
  "expo-sfv-version": "0",
617
622
  "expo-manifest-filters": ""
@@ -619,21 +624,21 @@ var fe = (e, t, n) => {
619
624
  }
620
625
  if (s === "electron") {
621
626
  let [, , e, t] = n;
622
- if (!e || !t) return H(400, { error: "expected /electron/:channel/latest.yml" });
627
+ if (!e || !t) return U(400, { error: "expected /electron/:channel/latest.yml" });
623
628
  let r = t === "latest-mac.yml" ? "mac" : t === "latest-linux.yml" ? "linux" : t === "latest.yml" ? "win" : null;
624
- if (r === null) return H(404, { error: "not_found" });
625
- let { release: i } = await Y(o, e), a = i ? L(i, r) : null;
626
- return a ? he(200, a, "text/yaml; charset=utf-8") : U(204);
629
+ if (r === null) return U(404, { error: "not_found" });
630
+ let { release: i } = await Y(o, e), a = i ? z(i, r) : null;
631
+ return a ? ve(200, a, "text/yaml; charset=utf-8") : W(204);
627
632
  }
628
633
  if (s === "download") {
629
634
  let [, , e] = n;
630
- if (!e) return H(400, { error: "expected /download/:channel" });
635
+ if (!e) return U(400, { error: "expected /download/:channel" });
631
636
  let { channel: r, release: i } = await Y(o, e);
632
- if (!r.public) return H(403, { error: "channel_not_public" });
633
- if (!i) return U(204);
634
- let s = a.get("os") ?? V(t.headers["user-agent"] ?? "")?.os, c = a.get("arch") ?? V(t.headers["user-agent"] ?? "")?.arch;
635
- if (!s) return H(400, { error: "os is required (?os=macos|windows|linux|ios|android)" });
636
- let l = B(i, s, c);
637
+ if (!r.public) return U(403, { error: "channel_not_public" });
638
+ if (!i) return W(204);
639
+ let s = a.get("os") ?? H(t.headers["user-agent"] ?? "")?.os, c = a.get("arch") ?? H(t.headers["user-agent"] ?? "")?.arch;
640
+ if (!s) return U(400, { error: "os is required (?os=macos|windows|linux|ios|android)" });
641
+ let l = _e(i, s, c);
637
642
  return l ? {
638
643
  status: 302,
639
644
  body: "",
@@ -641,23 +646,23 @@ var fe = (e, t, n) => {
641
646
  location: l.url,
642
647
  "cache-control": "no-store"
643
648
  }
644
- } : H(404, { error: "no_artifact_for_os" });
649
+ } : U(404, { error: "no_artifact_for_os" });
645
650
  }
646
651
  if (s === "policy") {
647
652
  let [, , e] = n;
648
- if (!e) return H(400, { error: "expected /policy/:channel" });
649
- let r = await G(o, e), s = a.get("version"), c = s ? i(r, {
653
+ if (!e) return U(400, { error: "expected /policy/:channel" });
654
+ let r = await K(o, e), s = a.get("version"), c = s ? i(r, {
650
655
  version: s,
651
656
  installId: X(t, a)
652
657
  }) : null;
653
- return H(200, {
658
+ return U(200, {
654
659
  policy: r,
655
660
  ...c ? { verdict: c } : {}
656
661
  });
657
662
  }
658
- return H(404, { error: "not_found" });
663
+ return U(404, { error: "not_found" });
659
664
  } catch (t) {
660
- if (t instanceof e) return H(404, {
665
+ if (t instanceof e) return U(404, {
661
666
  error: "not_found",
662
667
  app: t.app
663
668
  });
@@ -667,18 +672,19 @@ var fe = (e, t, n) => {
667
672
  }, Z = (e) => ({
668
673
  kind: "json",
669
674
  data: e
670
- }), De = [{
675
+ }), Ne = [{
671
676
  method: "GET",
672
677
  path: "/overview",
673
678
  scope: "shared-store",
674
679
  description: "Every app target with its channels, current versions and rollout state.",
675
- handler: () => v.promise(async () => {
676
- let e = await s().query(T(k).descriptor), t = await s().query(T(A).descriptor), n = await s().query(T(j).descriptor);
680
+ handler: () => _.promise(async () => {
681
+ let e = await v().query(T(j).descriptor), t = await v().query(T(M).descriptor), n = await v().query(T(N).descriptor);
677
682
  return Z({ apps: e.map((e) => ({
678
683
  id: e.id,
679
684
  app: e.app,
680
685
  platform: e.platform,
681
686
  shell: e.shell,
687
+ revision: e.revision,
682
688
  channels: t.filter((t) => t.appId === e.id).map((e) => {
683
689
  let t = n.find((t) => t.id === e.currentReleaseId);
684
690
  return {
@@ -698,20 +704,48 @@ var fe = (e, t, n) => {
698
704
  path: "/events",
699
705
  scope: "shared-store",
700
706
  description: "The last 100 release events (promote, rollback, rollout, policy).",
701
- handler: () => v.promise(async () => {
702
- let e = await s().query(T(N).descriptor);
707
+ handler: () => _.promise(async () => {
708
+ let e = await v().query(T(F).descriptor), t = await v().query(T(M).descriptor), n = new Map(t.map((e) => [e.id, e.name]));
703
709
  return Z({ events: [...e].sort((e, t) => t.at.getTime() - e.at.getTime()).slice(0, 100).map((e) => ({
704
710
  ...e,
711
+ channelName: e.channelId === null ? null : n.get(e.channelId) ?? null,
705
712
  at: e.at.toISOString()
706
713
  })) });
707
714
  })
708
- }], Oe = () => ({ request: {
715
+ }], Pe = async (n, r) => {
716
+ let i = n.releaseId === void 0 ? null : await O(n.releaseId);
717
+ if (n.releaseId !== void 0 && !i) throw new e({ app: n.releaseId });
718
+ let a = (await v().query(T(j).descriptor)).filter((e) => (n.app === void 0 || e.app === n.app) && (n.platform === void 0 || e.platform === n.platform) && (n.shell === void 0 || e.shell === n.shell) && (i === null || e.id === i.appId) && (n.expectedTarget === void 0 || e.id === n.expectedTarget.id));
719
+ if (a.length === 0 && r) return;
720
+ if (a.length === 0) throw new e({ app: n.app ?? n.releaseId ?? "" });
721
+ if (a.length !== 1) throw new t({ reason: "Multiple release targets match this app. Select an exact target." });
722
+ let o = a[0], s = n.expectedTarget?.revision ?? o.revision;
723
+ if (!Number.isSafeInteger(s) || s < 0 || s >= 2 ** 53 - 1 || o.revision !== s || await v().updateMany("_voltro_release_apps", { revision: s + 1 }, { where: fe(x("id", o.id), x("revision", s)) }) !== 1) throw new t({ reason: "Release target changed. Refresh and review the action again." });
724
+ return o.id;
725
+ }, Fe = (e) => e.kind === "mutation" ? {
726
+ ...e,
727
+ execute: (t, n) => _.gen(function* () {
728
+ let r = yield* _.runtime();
729
+ return yield* _.tryPromise({
730
+ try: async (i) => {
731
+ await w();
732
+ let a = (a) => s.run(a, async () => {
733
+ let a = await Pe(t, e.name === "releases.registerApp"), o = () => le.runPromise(r)(e.execute(t, n).pipe(_.either), { signal: i }), s = a === void 0 ? await o() : await p.run(a, o);
734
+ if (s._tag === "Left") throw s.left;
735
+ return s.right;
736
+ });
737
+ return n.mutationStore ? a(n.mutationStore) : v().transactional(a);
738
+ },
739
+ catch: (e) => e
740
+ });
741
+ })
742
+ } : e, Ie = () => ({ request: {
709
743
  subject: {
710
744
  type: "anonymous",
711
745
  id: null,
712
746
  tenantId: null
713
747
  },
714
- traceId: de()
748
+ traceId: he()
715
749
  } }), Q = (e, t) => ({
716
750
  kind: "json",
717
751
  status: e,
@@ -720,7 +754,7 @@ var fe = (e, t, n) => {
720
754
  method: "POST",
721
755
  path: n,
722
756
  description: i,
723
- handler: (n) => v.gen(function* () {
757
+ handler: (n) => _.gen(function* () {
724
758
  let i;
725
759
  try {
726
760
  i = JSON.parse(n.body || "{}");
@@ -728,30 +762,32 @@ var fe = (e, t, n) => {
728
762
  return Q(400, "invalid JSON body");
729
763
  }
730
764
  if (typeof i != "object" || !i || Array.isArray(i)) return Q(400, "expected a JSON object body");
731
- let a = yield* r.execute(i, Oe()).pipe(v.either);
732
- if (a._tag === "Left") {
733
- let n = a.left;
734
- return n instanceof e ? Q(404, `not found: ${n.app}${n.version ? ` ${n.version}` : ""}${n.channel ? ` (${n.channel})` : ""}`) : n instanceof t ? Q(409, n.reason) : Q(400, n instanceof Error ? n.message : String(n));
765
+ let a = yield* ue.decodeUnknown(r.input)(i).pipe(_.either);
766
+ if (a._tag === "Left") return Q(400, "invalid action input");
767
+ let o = yield* Fe(r).execute(a.right, Ie()).pipe(_.either);
768
+ if (o._tag === "Left") {
769
+ let n = o.left;
770
+ return n instanceof e ? Q(404, `not found: ${n.app}${n.version ? ` ${n.version}` : ""}${n.channel ? ` (${n.channel})` : ""}`) : n instanceof t ? Q(409, n.reason) : Q(500, "release action failed");
735
771
  }
736
- return Z({ result: a.right });
772
+ return Z({ result: o.right });
737
773
  })
738
- }), ke = [
739
- $("/apps", be, "Register an app target at runtime: { app, platform, shell, channels? }."),
740
- $("/create", xe, "Create a draft release: { app, channel, version, buildId?, notes? }."),
741
- $("/upload", Se, "Attach an artefact: { releaseId, kind, target?, url, sha256, size, signature? }."),
742
- $("/promote", Ce, "Promote a version onto a channel: { app, version, to, rolloutPercent? }."),
743
- $("/rollout", we, "Set the rollout percentage: { app, channel, percent }."),
744
- $("/rollback", Te, "Roll a channel back: { app, channel, reason }."),
745
- $("/policy", J, "Set the policy: { app, channel, minSupportedVersion?, killSwitches?, reason }.")
774
+ }), Le = [
775
+ $("/apps", Te, "Register an app target at runtime: { app, platform, shell, channels? }."),
776
+ $("/create", Ee, "Create a draft release: { app, channel, version, buildId?, notes? }."),
777
+ $("/upload", De, "Attach an artefact: { releaseId, kind, target?, url, sha256, size, signature? }."),
778
+ $("/promote", Oe, "Promote a version onto a channel: { app, version, to, rolloutPercent? }."),
779
+ $("/rollout", ke, "Set the rollout percentage: { app, channel, percent }."),
780
+ $("/rollback", Ae, "Roll a channel back: { app, channel, reason }."),
781
+ $("/policy", je, "Set the policy: { app, channel, minSupportedVersion?, killSwitches?, reason }.")
746
782
  ];
747
- return le({
783
+ return pe({
748
784
  source: "plugin",
749
- table: _,
785
+ table: g,
750
786
  timeColumn: "at",
751
- ttlMs: ue(process.env.VOLTRO_RELEASE_EVENTS_TTL_HOURS, 8760),
787
+ ttlMs: me(process.env.VOLTRO_RELEASE_EVENTS_TTL_HOURS, 8760),
752
788
  envVar: "VOLTRO_RELEASE_EVENTS_TTL_HOURS"
753
- }), ce({
754
- name: n.name ? `${h}#${n.name}` : h,
789
+ }), de({
790
+ name: n.name ? `${m}#${n.name}` : m,
755
791
  description: "Release channels, artefacts and rollouts — the self-hosted update server behind Tauri, Expo OTA, electron-updater and PWA feeds, with a reactive release policy.",
756
792
  permissions: [
757
793
  "inspect:read",
@@ -759,40 +795,40 @@ var fe = (e, t, n) => {
759
795
  "store:write"
760
796
  ],
761
797
  routes: [
762
- ve,
763
- ye,
764
- be,
765
- xe,
766
- Se,
767
798
  Ce,
768
799
  we,
769
800
  Te,
770
- J
771
- ],
772
- rpcClientDescriptors: se,
773
- httpRoutes: [Ee],
774
- inspectEndpoints: [...De, ...ke],
775
- extendSchema: { tables: [...P] },
776
- declaredEnv: _e,
777
- privacy: ge,
801
+ Ee,
802
+ De,
803
+ Oe,
804
+ ke,
805
+ Ae,
806
+ je
807
+ ].map(Fe),
808
+ rpcClientDescriptors: ce,
809
+ httpRoutes: [Me],
810
+ inspectEndpoints: [...Ne, ...Le],
811
+ extendSchema: { tables: [...I] },
812
+ declaredEnv: xe,
813
+ privacy: be,
778
814
  bindDataStore: (e) => {
779
- o = e, m = b(), m.catch(() => {});
815
+ o = e, b = C(), b.catch(() => {});
780
816
  },
781
- onActivate: () => v.tryPromise({
817
+ onActivate: () => _.tryPromise({
782
818
  catch: (e) => /* @__PURE__ */ Error(`@voltro/plugin-releases could not seed its targets and channels: ${e instanceof Error ? e.message : String(e)}`),
783
- try: () => S()
819
+ try: () => w()
784
820
  })
785
821
  });
786
- }, ge = { collects: [{
822
+ }, be = { collects: [{
787
823
  category: "device-id",
788
824
  linked: !1,
789
825
  tracking: !1,
790
826
  purposes: ["app-functionality"]
791
- }] }, _e = [{
827
+ }] }, xe = [{
792
828
  name: "VOLTRO_RELEASE_EVENTS_TTL_HOURS",
793
829
  required: !1,
794
830
  secret: !1,
795
831
  description: "Hours a release event (create, upload, promote, rollout, rollback, policy, prune) is kept before the retention sweep removes it. Default 8760 (one year)."
796
832
  }];
797
833
  //#endregion
798
- export { h as BASE_NAME, m as RELEASES_MANAGE_SCOPE, p as RELEASES_TABLE, f as RELEASE_APPS_TABLE, l as RELEASE_ARTIFACTS_TABLE, g as RELEASE_CHANNELS_TABLE, _ as RELEASE_EVENTS_TABLE, pe as RELEASE_PLATFORMS, me as RELEASE_SHELLS, e as ReleaseNotFound, t as ReleaseRefused, c as compareVersions, i as evaluatePolicy, o as inRollout, r as isNewerVersion, F as offeredTo, V as osFromUserAgent, n as parseVersion, B as pickDownload, k as releaseAppsTable, M as releaseArtifactsTable, A as releaseChannelsTable, N as releaseEventsTable, P as releaseTables, G as releasesPlugin, j as releasesTable, L as renderElectronLatestYml, R as renderExpoFeed, I as renderTauriFeed, a as rolloutBucket, s as sortVersionsDesc };
834
+ export { m as BASE_NAME, p as RELEASES_MANAGE_SCOPE, f as RELEASES_TABLE, d as RELEASE_APPS_TABLE, l as RELEASE_ARTIFACTS_TABLE, h as RELEASE_CHANNELS_TABLE, g as RELEASE_EVENTS_TABLE, k as RELEASE_PLATFORMS, A as RELEASE_SHELLS, e as ReleaseNotFound, t as ReleaseRefused, c as compareVersions, i as evaluatePolicy, o as inRollout, r as isNewerVersion, L as offeredTo, H as osFromUserAgent, n as parseVersion, _e as pickDownload, j as releaseAppsTable, P as releaseArtifactsTable, M as releaseChannelsTable, F as releaseEventsTable, I as releaseTables, ye as releasesPlugin, N as releasesTable, z as renderElectronLatestYml, B as renderExpoFeed, R as renderTauriFeed, a as rolloutBucket, s as sortVersionsDesc };