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