@voltro/plugin-releases 0.85.0 → 0.87.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/names.js ADDED
@@ -0,0 +1,4 @@
1
+ //#region src/names.ts
2
+ var e = "_voltro_release_apps", t = "_voltro_release_channels", n = "_voltro_releases", r = "_voltro_release_artifacts", i = "_voltro_release_events";
3
+ //#endregion
4
+ export { n as RELEASES_TABLE, e as RELEASE_APPS_TABLE, r as RELEASE_ARTIFACTS_TABLE, t as RELEASE_CHANNELS_TABLE, i as RELEASE_EVENTS_TABLE };
@@ -0,0 +1,13 @@
1
+ import { compareVersions as e } from "./rollout.js";
2
+ var t = (t, n, r) => {
3
+ let i = /* @__PURE__ */ new Set();
4
+ for (let e of n) e.currentReleaseId !== null && i.add(e.currentReleaseId);
5
+ let a = [];
6
+ for (let o of n) {
7
+ let n = r(o.name), s = Number.isFinite(n) ? Math.max(1, Math.floor(n)) : 10, c = t.filter((e) => e.channelId === o.id).sort((t, n) => e(n.version, t.version));
8
+ for (let e of c.slice(s)) i.has(e.id) || a.push(e);
9
+ }
10
+ return a;
11
+ };
12
+ //#endregion
13
+ export { t as planRetention };
@@ -52,4 +52,4 @@ var e = (e) => {
52
52
  };
53
53
  }, s = (e) => [...e].sort((e, n) => t(n, e));
54
54
  //#endregion
55
- export { e as a, n as i, o as n, i as o, a as r, s, t };
55
+ export { t as compareVersions, o as evaluatePolicy, a as inRollout, n as isNewerVersion, e as parseVersion, i as rolloutBucket, s as sortVersionsDesc };
package/dist/rpc.d.ts CHANGED
@@ -64,6 +64,22 @@ export declare const PolicySchema: Schema.Struct<{
64
64
 
65
65
  export declare type PolicyWire = typeof PolicySchema.Type;
66
66
 
67
+ export declare const prepareUploadDescriptor: QueryProcedureDescriptor<"releases.prepareUpload", Schema.Struct<{
68
+ readonly operationId: Schema.optionalKey<Schema.String>;
69
+ readonly expectedTarget: Schema.optional<Schema.Struct<{
70
+ readonly id: Schema.String;
71
+ readonly revision: Schema.Number;
72
+ }>>;
73
+ readonly appPrefix: Schema.optional<Schema.NonEmptyString>;
74
+ readonly releaseId: Schema.String;
75
+ readonly app: Schema.optional<Schema.String>;
76
+ readonly version: Schema.optional<Schema.String>;
77
+ }>, Schema.Struct<{
78
+ readonly releaseId: Schema.String;
79
+ readonly app: Schema.String;
80
+ readonly version: Schema.String;
81
+ }>, Schema.Union<readonly [typeof ReleaseRefused, typeof ReleaseNotFound]>>;
82
+
67
83
  export declare const promoteDescriptor: MutationProcedureDescriptor<"releases.promote", Schema.Struct<{
68
84
  readonly expectedTarget: Schema.optional<Schema.Struct<{
69
85
  readonly id: Schema.String;
@@ -129,6 +145,18 @@ export declare const ReleaseSummarySchema: Schema.Struct<{
129
145
  readonly signed: Schema.Boolean;
130
146
  }>;
131
147
 
148
+ export declare const ReleaseUploadPreparationInput: Schema.Struct<{
149
+ readonly operationId: Schema.optionalKey<Schema.String>;
150
+ readonly expectedTarget: Schema.optional<Schema.Struct<{
151
+ readonly id: Schema.String;
152
+ readonly revision: Schema.Number;
153
+ }>>;
154
+ readonly appPrefix: Schema.optional<Schema.NonEmptyString>;
155
+ readonly releaseId: Schema.String;
156
+ readonly app: Schema.optional<Schema.String>;
157
+ readonly version: Schema.optional<Schema.String>;
158
+ }>;
159
+
132
160
  export declare const rollbackDescriptor: MutationProcedureDescriptor<"releases.rollback", Schema.Struct<{
133
161
  readonly app: Schema.String;
134
162
  readonly channel: Schema.String;
@@ -176,11 +204,6 @@ export declare const setPolicyDescriptor: MutationProcedureDescriptor<"releases.
176
204
  }>, Schema.Union<readonly [typeof ReleaseRefused, typeof ReleaseNotFound]>>;
177
205
 
178
206
  export declare const uploadDescriptor: MutationProcedureDescriptor<"releases.upload", Schema.Struct<{
179
- readonly expectedTarget: Schema.optional<Schema.Struct<{
180
- readonly id: Schema.String;
181
- readonly revision: Schema.Number;
182
- }>>;
183
- readonly releaseId: Schema.String;
184
207
  readonly kind: Schema.String;
185
208
  readonly target: Schema.optional<Schema.String>;
186
209
  readonly url: Schema.String;
@@ -190,6 +213,15 @@ export declare const uploadDescriptor: MutationProcedureDescriptor<"releases.upl
190
213
  readonly notarized: Schema.optional<Schema.Boolean>;
191
214
  readonly assetKey: Schema.optional<Schema.String>;
192
215
  readonly contentType: Schema.optional<Schema.String>;
216
+ readonly operationId: Schema.optionalKey<Schema.String>;
217
+ readonly expectedTarget: Schema.optional<Schema.Struct<{
218
+ readonly id: Schema.String;
219
+ readonly revision: Schema.Number;
220
+ }>>;
221
+ readonly appPrefix: Schema.optional<Schema.NonEmptyString>;
222
+ readonly releaseId: Schema.String;
223
+ readonly app: Schema.optional<Schema.String>;
224
+ readonly version: Schema.optional<Schema.String>;
193
225
  }>, Schema.Struct<{
194
226
  readonly id: Schema.String;
195
227
  }>, Schema.Union<readonly [typeof ReleaseRefused, typeof ReleaseNotFound]>>;
package/dist/rpc.js CHANGED
@@ -1,2 +1,263 @@
1
- import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p } from "./rpc-DrfZqJIA.js";
2
- export { f as BASE_NAME, s as PolicySchema, u as RELEASES_MANAGE_SCOPE, i as ReleaseSummarySchema, e as createDescriptor, c as listDescriptor, d as policyDescriptor, t as promoteDescriptor, a as registerAppDescriptor, p as releasesRpcClientImports, n as rollbackDescriptor, r as rolloutDescriptor, l as setPolicyDescriptor, o as uploadDescriptor };
1
+ import { artifactHash as e, artifactOperationId as t, artifactSize as n, artifactText as r, hasArtifactSignature as i } from "./artifactMetadata.js";
2
+ import { ReleaseNotFound as a, ReleaseRefused as o } from "./errors.js";
3
+ import { RELEASES_TABLE as s, RELEASE_APPS_TABLE as c, RELEASE_ARTIFACTS_TABLE as l, RELEASE_CHANNELS_TABLE as u } from "./names.js";
4
+ import { Schema as d } from "effect";
5
+ import { defineMutation as f, defineQuery as p } from "@voltro/protocol";
6
+ //#region src/rpc.ts
7
+ var m = "@voltro/plugin-releases", h = "releases:manage", g = d.optional(d.Struct({
8
+ id: d.String,
9
+ revision: d.Number.pipe(d.check(d.isInt()), d.check(d.isGreaterThanOrEqualTo(0)))
10
+ })), _ = d.Struct({
11
+ app: d.String,
12
+ channel: d.String,
13
+ latestVersion: d.NullOr(d.String),
14
+ minSupportedVersion: d.NullOr(d.String),
15
+ killSwitches: d.Record(d.String, d.Array(d.String)),
16
+ rolloutPercent: d.Number,
17
+ rolloutSalt: d.NullOr(d.String),
18
+ cohorts: d.NullOr(d.Array(d.String))
19
+ }), v = p({
20
+ name: "releases.policy",
21
+ input: d.Struct({
22
+ app: d.String,
23
+ channel: d.String
24
+ }),
25
+ output: _,
26
+ source: [u, s],
27
+ openAccess: "the release policy of a channel is what every client — signed in or not — must evaluate before it may continue; it carries versions and feature keys, no data"
28
+ }), y = d.Struct({
29
+ id: d.String,
30
+ version: d.String,
31
+ buildId: d.NullOr(d.String),
32
+ state: d.String,
33
+ rolloutPercent: d.Number,
34
+ channel: d.String,
35
+ createdAt: d.String,
36
+ artifacts: d.Number,
37
+ signed: d.Boolean
38
+ }), b = p({
39
+ name: "releases.list",
40
+ input: d.Struct({ app: d.String }),
41
+ output: d.Array(y),
42
+ source: [s],
43
+ guards: [{ scope: h }]
44
+ }), x = f({
45
+ name: "releases.registerApp",
46
+ input: d.Struct({
47
+ app: d.String,
48
+ platform: d.Literals([
49
+ "web",
50
+ "ios",
51
+ "android",
52
+ "macos",
53
+ "windows",
54
+ "linux"
55
+ ]),
56
+ shell: d.Literals([
57
+ "pwa",
58
+ "expo",
59
+ "tauri",
60
+ "electron"
61
+ ]),
62
+ bundleId: d.optional(d.String),
63
+ updaterPublicKey: d.optional(d.String),
64
+ runtimeVersion: d.optional(d.String),
65
+ channels: d.optional(d.Array(d.String))
66
+ }),
67
+ output: d.Struct({
68
+ id: d.String,
69
+ created: d.Boolean
70
+ }),
71
+ error: o,
72
+ guards: [{ scope: h }]
73
+ }), S = f({
74
+ name: "releases.create",
75
+ input: d.Struct({
76
+ expectedTarget: g,
77
+ app: d.String,
78
+ channel: d.String,
79
+ version: d.String,
80
+ buildId: d.optional(d.String),
81
+ notes: d.optional(d.String),
82
+ cohorts: d.optional(d.Array(d.String))
83
+ }),
84
+ output: d.Struct({ id: d.String }),
85
+ error: d.Union([o, a]),
86
+ guards: [{ scope: h }]
87
+ }), C = d.String.check(d.makeFilter(r, { message: "Artifact metadata must be nonblank text without control characters" })), w = d.String.check(d.makeFilter(e, { message: "Artifact sha256 must contain exactly 64 hexadecimal characters" })), T = d.Number.check(d.makeFilter(n, { message: "Artifact size must be a positive safe integer" })), E = d.String.check(d.makeFilter(i, { message: "Artifact signature must not be blank or contain NUL" })), D = d.String.check(d.makeFilter(t, { message: "Artifact operationId must be nonblank text without control characters and at most 200 characters" })), O = d.Struct({
88
+ operationId: d.optionalKey(D),
89
+ expectedTarget: g,
90
+ appPrefix: d.optional(d.NonEmptyString),
91
+ releaseId: C,
92
+ app: d.optional(C),
93
+ version: d.optional(C)
94
+ }), k = p({
95
+ name: "releases.prepareUpload",
96
+ input: O,
97
+ output: d.Struct({
98
+ releaseId: d.String,
99
+ app: d.String,
100
+ version: d.String
101
+ }),
102
+ source: [
103
+ c,
104
+ s,
105
+ l
106
+ ],
107
+ error: d.Union([o, a]),
108
+ guards: [{ scope: h }]
109
+ }), A = f({
110
+ name: "releases.upload",
111
+ input: d.Struct({
112
+ ...O.fields,
113
+ kind: C,
114
+ target: d.optional(C),
115
+ url: C,
116
+ sha256: w,
117
+ size: T,
118
+ signature: d.optional(E),
119
+ notarized: d.optional(d.Boolean),
120
+ assetKey: d.optional(C),
121
+ contentType: d.optional(C)
122
+ }),
123
+ output: d.Struct({ id: d.String }),
124
+ error: d.Union([o, a]),
125
+ guards: [{ scope: h }]
126
+ }), j = f({
127
+ name: "releases.promote",
128
+ input: d.Struct({
129
+ expectedTarget: g,
130
+ app: d.String,
131
+ version: d.String,
132
+ to: d.String,
133
+ rolloutPercent: d.optional(d.Number.pipe(d.check(d.isInt())))
134
+ }),
135
+ output: d.Struct({
136
+ channel: d.String,
137
+ version: d.String,
138
+ rolloutPercent: d.Number
139
+ }),
140
+ error: d.Union([o, a]),
141
+ guards: [{ scope: h }]
142
+ }), M = f({
143
+ name: "releases.rollout",
144
+ input: d.Struct({
145
+ app: d.String,
146
+ channel: d.String,
147
+ percent: d.Number.pipe(d.check(d.isInt())),
148
+ expectedTarget: g
149
+ }),
150
+ output: d.Struct({
151
+ version: d.String,
152
+ rolloutPercent: d.Number
153
+ }),
154
+ error: d.Union([o, a]),
155
+ guards: [{ scope: h }]
156
+ }), N = f({
157
+ name: "releases.rollback",
158
+ input: d.Struct({
159
+ app: d.String,
160
+ channel: d.String,
161
+ reason: d.String,
162
+ expectedTarget: g
163
+ }),
164
+ output: d.Struct({ version: d.NullOr(d.String) }),
165
+ error: d.Union([o, a]),
166
+ guards: [{ scope: h }]
167
+ }), P = f({
168
+ name: "releases.setPolicy",
169
+ input: d.Struct({
170
+ expectedTarget: g,
171
+ app: d.String,
172
+ channel: d.String,
173
+ minSupportedVersion: d.optional(d.NullOr(d.String)),
174
+ killSwitches: d.optional(d.Record(d.String, d.Array(d.String))),
175
+ reason: d.String
176
+ }),
177
+ output: _,
178
+ error: d.Union([o, a]),
179
+ guards: [{ scope: h }]
180
+ }), F = [
181
+ {
182
+ tag: "releases.policy",
183
+ kind: "query",
184
+ import: {
185
+ module: "@voltro/plugin-releases/rpc",
186
+ name: "policyDescriptor"
187
+ }
188
+ },
189
+ {
190
+ tag: "releases.list",
191
+ kind: "query",
192
+ import: {
193
+ module: "@voltro/plugin-releases/rpc",
194
+ name: "listDescriptor"
195
+ }
196
+ },
197
+ {
198
+ tag: "releases.registerApp",
199
+ kind: "mutation",
200
+ import: {
201
+ module: "@voltro/plugin-releases/rpc",
202
+ name: "registerAppDescriptor"
203
+ }
204
+ },
205
+ {
206
+ tag: "releases.create",
207
+ kind: "mutation",
208
+ import: {
209
+ module: "@voltro/plugin-releases/rpc",
210
+ name: "createDescriptor"
211
+ }
212
+ },
213
+ {
214
+ tag: "releases.prepareUpload",
215
+ kind: "query",
216
+ import: {
217
+ module: "@voltro/plugin-releases/rpc",
218
+ name: "prepareUploadDescriptor"
219
+ }
220
+ },
221
+ {
222
+ tag: "releases.upload",
223
+ kind: "mutation",
224
+ import: {
225
+ module: "@voltro/plugin-releases/rpc",
226
+ name: "uploadDescriptor"
227
+ }
228
+ },
229
+ {
230
+ tag: "releases.promote",
231
+ kind: "mutation",
232
+ import: {
233
+ module: "@voltro/plugin-releases/rpc",
234
+ name: "promoteDescriptor"
235
+ }
236
+ },
237
+ {
238
+ tag: "releases.rollout",
239
+ kind: "mutation",
240
+ import: {
241
+ module: "@voltro/plugin-releases/rpc",
242
+ name: "rolloutDescriptor"
243
+ }
244
+ },
245
+ {
246
+ tag: "releases.rollback",
247
+ kind: "mutation",
248
+ import: {
249
+ module: "@voltro/plugin-releases/rpc",
250
+ name: "rollbackDescriptor"
251
+ }
252
+ },
253
+ {
254
+ tag: "releases.setPolicy",
255
+ kind: "mutation",
256
+ import: {
257
+ module: "@voltro/plugin-releases/rpc",
258
+ name: "setPolicyDescriptor"
259
+ }
260
+ }
261
+ ];
262
+ //#endregion
263
+ export { m as BASE_NAME, _ as PolicySchema, h as RELEASES_MANAGE_SCOPE, y as ReleaseSummarySchema, O as ReleaseUploadPreparationInput, S as createDescriptor, b as listDescriptor, v as policyDescriptor, k as prepareUploadDescriptor, j as promoteDescriptor, x as registerAppDescriptor, F as releasesRpcClientImports, N as rollbackDescriptor, M as rolloutDescriptor, P as setPolicyDescriptor, A as uploadDescriptor };
package/dist/schema.js ADDED
@@ -0,0 +1,85 @@
1
+ import { RELEASES_TABLE as e, RELEASE_APPS_TABLE as t, RELEASE_ARTIFACTS_TABLE as n, RELEASE_CHANNELS_TABLE as r, RELEASE_EVENTS_TABLE as i } from "./names.js";
2
+ import { bigint as a, boolean as o, id as s, integer as c, json as l, table as u, text as d, timestamp as f } from "@voltro/database";
3
+ //#region src/schema.ts
4
+ var p = [
5
+ "web",
6
+ "ios",
7
+ "android",
8
+ "macos",
9
+ "windows",
10
+ "linux"
11
+ ], m = [
12
+ "pwa",
13
+ "expo",
14
+ "tauri",
15
+ "electron"
16
+ ], h = u(t, {
17
+ id: s({ prefix: "relapp" }),
18
+ app: d(),
19
+ platform: d(),
20
+ shell: d(),
21
+ revision: c().default(0),
22
+ bundleId: d().nullable(),
23
+ updaterPublicKey: d().nullable(),
24
+ runtimeVersion: d().nullable(),
25
+ createdAt: f().default("now")
26
+ }).index("byReleaseAppTarget", [
27
+ "app",
28
+ "platform",
29
+ "shell"
30
+ ]), g = u(r, {
31
+ id: s({ prefix: "relch" }),
32
+ appId: d(),
33
+ name: d(),
34
+ currentReleaseId: d().nullable(),
35
+ minSupportedVersion: d().nullable(),
36
+ killSwitches: l().nullable(),
37
+ public: o().default(!1),
38
+ allowUnsigned: o().default(!1),
39
+ updatedAt: f().default("now").onUpdate("now")
40
+ }).index("byReleaseChannelApp", ["appId", "name"]), _ = u(e, {
41
+ id: s({ prefix: "rel" }),
42
+ appId: d(),
43
+ channelId: d(),
44
+ version: d(),
45
+ buildId: d().nullable(),
46
+ notes: d().nullable(),
47
+ state: d().default("draft"),
48
+ rolloutPercent: c().default(0),
49
+ rolloutSalt: d(),
50
+ cohorts: l().nullable(),
51
+ createdBy: d().nullable(),
52
+ createdAt: f().default("now"),
53
+ updatedAt: f().default("now").onUpdate("now")
54
+ }).index("byReleaseAppChannel", ["appId", "channelId"]).index("byReleaseVersion", ["appId", "version"]), v = u(n, {
55
+ id: s({ prefix: "relart" }),
56
+ releaseId: d(),
57
+ kind: d(),
58
+ target: d().nullable(),
59
+ url: d(),
60
+ sha256: d(),
61
+ size: a(),
62
+ signature: d().nullable(),
63
+ notarized: o().default(!1),
64
+ assetKey: d().nullable(),
65
+ contentType: d().nullable(),
66
+ createdAt: f().default("now")
67
+ }).index("byReleaseArtifactRelease", ["releaseId"]), y = u(i, {
68
+ id: s({ prefix: "relev" }),
69
+ appId: d(),
70
+ channelId: d().nullable(),
71
+ releaseId: d().nullable(),
72
+ kind: d(),
73
+ reason: d().nullable(),
74
+ actorId: d().nullable(),
75
+ detail: l().nullable(),
76
+ at: f().default("now")
77
+ }).index("byReleaseEventApp", ["appId", "at"]), b = [
78
+ h,
79
+ g,
80
+ _,
81
+ v,
82
+ y
83
+ ];
84
+ //#endregion
85
+ export { e as RELEASES_TABLE, t as RELEASE_APPS_TABLE, n as RELEASE_ARTIFACTS_TABLE, r as RELEASE_CHANNELS_TABLE, i as RELEASE_EVENTS_TABLE, p as RELEASE_PLATFORMS, m as RELEASE_SHELLS, h as releaseAppsTable, v as releaseArtifactsTable, g as releaseChannelsTable, y as releaseEventsTable, b as releaseTables, _ as releasesTable };
@@ -0,0 +1,5 @@
1
+ import { createHash as e } from "node:crypto";
2
+ //#region src/uploadIdentity.server.ts
3
+ var t = (t, n) => "relart_" + e("sha256").update(JSON.stringify([t, n])).digest("hex"), n = (e, t) => e.releaseId === t.releaseId && e.kind === t.kind && e.target === (t.target ?? null) && e.url === t.url && e.sha256 === t.sha256.toLowerCase() && e.size === String(t.size) && e.signature === (t.signature ?? null) && e.notarized === (t.notarized ?? !1) && e.assetKey === (t.assetKey ?? null) && e.contentType === (t.contentType ?? null);
4
+ //#endregion
5
+ export { n as matchesUploadArtifact, t as uploadArtifactId };
package/dist/web.js CHANGED
@@ -1,5 +1,5 @@
1
- import { n as e } from "./rollout-CGRKMTfv.js";
2
- import { t } from "./rpc-DrfZqJIA.js";
1
+ import { evaluatePolicy as e } from "./rollout.js";
2
+ import { BASE_NAME as t } from "./rpc.js";
3
3
  import { pluginTag as n } from "@voltro/protocol";
4
4
  import { createElement as r, useEffect as i, useRef as a } from "react";
5
5
  import { usePlatform as o, useSubscription as s } from "@voltro/client";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/plugin-releases",
3
- "version": "0.85.0",
3
+ "version": "0.87.0",
4
4
  "description": "Release channels, artefacts and rollouts for the apps a Voltro api serves — the self-hosted update server behind Tauri, Expo OTA, electron-updater and PWA update feeds, with a reactive release policy every client subscribes to.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -48,11 +48,11 @@
48
48
  "node": ">=24.0.0"
49
49
  },
50
50
  "dependencies": {
51
- "@voltro/client": "0.85.0",
52
- "@voltro/database": "0.85.0",
53
- "@voltro/logger": "0.85.0",
54
- "@voltro/protocol": "0.85.0",
55
- "@voltro/runtime": "0.85.0"
51
+ "@voltro/client": "0.87.0",
52
+ "@voltro/database": "0.87.0",
53
+ "@voltro/logger": "0.87.0",
54
+ "@voltro/protocol": "0.87.0",
55
+ "@voltro/runtime": "0.87.0"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "effect": "4.0.1",