@voltro/plugin-releases 0.0.0-stage → 0.83.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 +17076 -0
- package/LICENSE +57 -0
- package/README.md +24 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +4850 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.js +9 -0
- package/dist/index.d.ts +445 -0
- package/dist/index.js +798 -0
- package/dist/rollout-CGRKMTfv.js +55 -0
- package/dist/rpc-U7ytx6SC.js +217 -0
- package/dist/rpc.d.ts +175 -0
- package/dist/rpc.js +2 -0
- package/dist/web.d.ts +73 -0
- package/dist/web.js +47 -0
- package/package.json +67 -4
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
|
|
3
|
+
export declare const releaseErrors: readonly [typeof ReleaseNotFound, typeof ReleaseRefused];
|
|
4
|
+
|
|
5
|
+
export declare class ReleaseNotFound extends ReleaseNotFound_base {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare const ReleaseNotFound_base: Schema.TaggedErrorClass<ReleaseNotFound, "ReleaseNotFound", {
|
|
9
|
+
readonly _tag: Schema.tag<"ReleaseNotFound">;
|
|
10
|
+
} & {
|
|
11
|
+
app: typeof Schema.String;
|
|
12
|
+
version: Schema.optional<typeof Schema.String>;
|
|
13
|
+
channel: Schema.optional<typeof Schema.String>;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
export declare class ReleaseRefused extends ReleaseRefused_base {
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare const ReleaseRefused_base: Schema.TaggedErrorClass<ReleaseRefused, "ReleaseRefused", {
|
|
20
|
+
readonly _tag: Schema.tag<"ReleaseRefused">;
|
|
21
|
+
} & {
|
|
22
|
+
reason: typeof Schema.String;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
export { }
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Schema as e } from "effect";
|
|
2
|
+
//#region src/errors.ts
|
|
3
|
+
var t = class extends e.TaggedError()("ReleaseNotFound", {
|
|
4
|
+
app: e.String,
|
|
5
|
+
version: e.optional(e.String),
|
|
6
|
+
channel: e.optional(e.String)
|
|
7
|
+
}) {}, n = class extends e.TaggedError()("ReleaseRefused", { reason: e.String }) {}, r = [t, n];
|
|
8
|
+
//#endregion
|
|
9
|
+
export { t as ReleaseNotFound, n as ReleaseRefused, r as releaseErrors };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { ColumnBuilder } from '@voltro/database';
|
|
2
|
+
import { FieldDefinitions } from '@voltro/database';
|
|
3
|
+
import { InferRow } from '@voltro/database';
|
|
4
|
+
import { Schema } from 'effect';
|
|
5
|
+
import { Table } from '@voltro/database';
|
|
6
|
+
import { VoltroPlugin } from '@voltro/protocol';
|
|
7
|
+
|
|
8
|
+
export declare const BASE_NAME = "@voltro/plugin-releases";
|
|
9
|
+
|
|
10
|
+
/** -1 / 0 / 1 like `Array.sort` wants. A pre-release sorts below its release. */
|
|
11
|
+
export declare const compareVersions: (a: string, b: string) => number;
|
|
12
|
+
|
|
13
|
+
/** What the running client should do, from the policy and its own version. */
|
|
14
|
+
export declare const evaluatePolicy: (policy: ReleasePolicy, client: {
|
|
15
|
+
readonly version: string;
|
|
16
|
+
readonly installId: string;
|
|
17
|
+
readonly cohorts?: ReadonlyArray<string>;
|
|
18
|
+
}) => PolicyVerdict;
|
|
19
|
+
|
|
20
|
+
export declare type ExpoFeedAnswer = {
|
|
21
|
+
readonly kind: 'manifest';
|
|
22
|
+
readonly manifest: ExpoManifest;
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: 'no-update';
|
|
25
|
+
} | {
|
|
26
|
+
readonly kind: 'rollback';
|
|
27
|
+
readonly commitTime: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export declare interface ExpoManifest {
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly createdAt: string;
|
|
33
|
+
readonly runtimeVersion: string;
|
|
34
|
+
readonly launchAsset: {
|
|
35
|
+
readonly hash: string;
|
|
36
|
+
readonly key: string;
|
|
37
|
+
readonly contentType: string;
|
|
38
|
+
readonly url: string;
|
|
39
|
+
};
|
|
40
|
+
readonly assets: ReadonlyArray<{
|
|
41
|
+
readonly hash: string;
|
|
42
|
+
readonly key: string;
|
|
43
|
+
readonly contentType: string;
|
|
44
|
+
readonly url: string;
|
|
45
|
+
}>;
|
|
46
|
+
readonly metadata: Readonly<Record<string, string>>;
|
|
47
|
+
readonly extra: Readonly<Record<string, unknown>>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export declare interface FeedArtifact {
|
|
51
|
+
readonly kind: string;
|
|
52
|
+
readonly target: string | null;
|
|
53
|
+
readonly url: string;
|
|
54
|
+
readonly sha256: string;
|
|
55
|
+
readonly size: number;
|
|
56
|
+
readonly signature: string | null;
|
|
57
|
+
readonly assetKey: string | null;
|
|
58
|
+
readonly contentType: string | null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export declare interface FeedClient {
|
|
62
|
+
readonly installId: string;
|
|
63
|
+
readonly currentVersion: string | null;
|
|
64
|
+
readonly cohorts?: ReadonlyArray<string>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export declare interface FeedRelease {
|
|
68
|
+
readonly id: string;
|
|
69
|
+
readonly version: string;
|
|
70
|
+
readonly buildId: string | null;
|
|
71
|
+
readonly notes: string | null;
|
|
72
|
+
readonly createdAt: Date;
|
|
73
|
+
readonly rolloutPercent: number;
|
|
74
|
+
readonly rolloutSalt: string;
|
|
75
|
+
readonly cohorts: ReadonlyArray<string> | null;
|
|
76
|
+
readonly artifacts: ReadonlyArray<FeedArtifact>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Is this install inside the rollout? Monotonic in `percent`: an install that
|
|
81
|
+
* was in at 10 % is still in at 50 %, because the bucket does not move while
|
|
82
|
+
* the salt stands. A named cohort is always in.
|
|
83
|
+
*/
|
|
84
|
+
export declare const inRollout: (input: RolloutInput) => boolean;
|
|
85
|
+
|
|
86
|
+
export declare const isNewerVersion: (candidate: string, current: string) => boolean;
|
|
87
|
+
|
|
88
|
+
/** Is this release the one to hand this client? Newer than what it runs, and
|
|
89
|
+
* the client is inside the rollout. */
|
|
90
|
+
export declare const offeredTo: (release: FeedRelease, client: FeedClient) => boolean;
|
|
91
|
+
|
|
92
|
+
/** `darwin-aarch64` from a user agent, best effort; null when unknown. */
|
|
93
|
+
export declare const osFromUserAgent: (ua: string) => {
|
|
94
|
+
readonly os: string;
|
|
95
|
+
readonly arch?: string;
|
|
96
|
+
} | null;
|
|
97
|
+
|
|
98
|
+
/** Parse `1.4.0`, `1.4.0-beta.2`, `v2.0.1`; `null` when it is not a version. */
|
|
99
|
+
export declare const parseVersion: (raw: string) => {
|
|
100
|
+
readonly parts: ReadonlyArray<number>;
|
|
101
|
+
readonly pre: ReadonlyArray<string>;
|
|
102
|
+
} | null;
|
|
103
|
+
|
|
104
|
+
/** Which artefact a download link should hand an OS/arch, or null. */
|
|
105
|
+
export declare const pickDownload: (release: FeedRelease, os: string, arch?: string) => FeedArtifact | null;
|
|
106
|
+
|
|
107
|
+
declare const PolicySchema: Schema.Struct<{
|
|
108
|
+
app: typeof Schema.String;
|
|
109
|
+
channel: typeof Schema.String;
|
|
110
|
+
latestVersion: Schema.NullOr<typeof Schema.String>;
|
|
111
|
+
minSupportedVersion: Schema.NullOr<typeof Schema.String>;
|
|
112
|
+
killSwitches: Schema.Record$<typeof Schema.String, Schema.Array$<typeof Schema.String>>;
|
|
113
|
+
rolloutPercent: typeof Schema.Number;
|
|
114
|
+
rolloutSalt: Schema.NullOr<typeof Schema.String>;
|
|
115
|
+
cohorts: Schema.NullOr<Schema.Array$<typeof Schema.String>>;
|
|
116
|
+
}>;
|
|
117
|
+
|
|
118
|
+
export declare interface PolicyVerdict {
|
|
119
|
+
/** The client must update before it may continue. */
|
|
120
|
+
readonly blocked: boolean;
|
|
121
|
+
/** A newer version exists on the channel — and this install is in its rollout. */
|
|
122
|
+
readonly updateAvailable: boolean;
|
|
123
|
+
readonly latestVersion: string | null;
|
|
124
|
+
/** Feature keys the running version must treat as off. */
|
|
125
|
+
readonly killed: ReadonlyArray<string>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export declare type PolicyWire = typeof PolicySchema.Type;
|
|
129
|
+
|
|
130
|
+
export declare const RELEASE_APPS_TABLE = "_voltro_release_apps";
|
|
131
|
+
|
|
132
|
+
export declare const RELEASE_ARTIFACTS_TABLE = "_voltro_release_artifacts";
|
|
133
|
+
|
|
134
|
+
export declare const RELEASE_CHANNELS_TABLE = "_voltro_release_channels";
|
|
135
|
+
|
|
136
|
+
export declare const RELEASE_EVENTS_TABLE = "_voltro_release_events";
|
|
137
|
+
|
|
138
|
+
export declare const RELEASE_PLATFORMS: readonly ["web", "ios", "android", "macos", "windows", "linux"];
|
|
139
|
+
|
|
140
|
+
export declare const RELEASE_SHELLS: readonly ["pwa", "expo", "tauri", "electron"];
|
|
141
|
+
|
|
142
|
+
export declare type ReleaseAppRow = InferRow<typeof releaseAppsTable>;
|
|
143
|
+
|
|
144
|
+
export declare const releaseAppsTable: Table<"_voltro_release_apps", FieldDefinitions<{
|
|
145
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
146
|
+
/** The app's name as the project spells it (`mobile`, `desktop`, `web`). */
|
|
147
|
+
readonly app: ColumnBuilder<string, "text", boolean>;
|
|
148
|
+
readonly platform: ColumnBuilder<string, "text", boolean>;
|
|
149
|
+
readonly shell: ColumnBuilder<string, "text", boolean>;
|
|
150
|
+
/** `com.acme.orders` — the store identity, where one exists. */
|
|
151
|
+
readonly bundleId: ColumnBuilder<string | null, "text", boolean>;
|
|
152
|
+
/** Public key the client verifies the feed with (minisign for Tauri,
|
|
153
|
+
* the Expo code-signing certificate for expo-updates). */
|
|
154
|
+
readonly updaterPublicKey: ColumnBuilder<string | null, "text", boolean>;
|
|
155
|
+
/** Expo: the runtime version the OTA bundles target. */
|
|
156
|
+
readonly runtimeVersion: ColumnBuilder<string | null, "text", boolean>;
|
|
157
|
+
readonly createdAt: ColumnBuilder<Date, "timestamp", true>;
|
|
158
|
+
}>, true, "byReleaseAppTarget">;
|
|
159
|
+
|
|
160
|
+
export declare interface ReleaseAppTarget {
|
|
161
|
+
/** `desktop`, `mobile`, `web` — the app as the project names it. */
|
|
162
|
+
readonly app: string;
|
|
163
|
+
readonly platform: 'web' | 'ios' | 'android' | 'macos' | 'windows' | 'linux';
|
|
164
|
+
readonly shell: 'pwa' | 'expo' | 'tauri' | 'electron';
|
|
165
|
+
readonly bundleId?: string;
|
|
166
|
+
readonly updaterPublicKey?: string;
|
|
167
|
+
readonly runtimeVersion?: string;
|
|
168
|
+
/** Channels to create at boot. Default `['stable', 'beta', 'internal']`. */
|
|
169
|
+
readonly channels?: ReadonlyArray<string>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export declare type ReleaseArtifactRow = InferRow<typeof releaseArtifactsTable>;
|
|
173
|
+
|
|
174
|
+
export declare const releaseArtifactsTable: Table<"_voltro_release_artifacts", FieldDefinitions<{
|
|
175
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
176
|
+
readonly releaseId: ColumnBuilder<string, "text", boolean>;
|
|
177
|
+
/** `dmg` | `msi` | `nsis` | `appimage` | `deb` | `rpm` | `ipa` | `aab` | `apk` | `expo-bundle` | `expo-asset` | `web-build`. */
|
|
178
|
+
readonly kind: ColumnBuilder<string, "text", boolean>;
|
|
179
|
+
/** Updater target: `darwin-aarch64`, `windows-x86_64`, `linux-x86_64`, `ios`, `android`. */
|
|
180
|
+
readonly target: ColumnBuilder<string | null, "text", boolean>;
|
|
181
|
+
/** Where the bytes are — a storage ref URL, a CDN URL. The feed hands this out. */
|
|
182
|
+
readonly url: ColumnBuilder<string, "text", boolean>;
|
|
183
|
+
readonly sha256: ColumnBuilder<string, "text", boolean>;
|
|
184
|
+
readonly size: ColumnBuilder<number, "integer", boolean>;
|
|
185
|
+
/** minisign / Expo code-signing signature over the bytes. */
|
|
186
|
+
readonly signature: ColumnBuilder<string | null, "text", boolean>;
|
|
187
|
+
readonly notarized: ColumnBuilder<boolean, "boolean", true>;
|
|
188
|
+
/** Expo: the asset's key/path inside the update. */
|
|
189
|
+
readonly assetKey: ColumnBuilder<string | null, "text", boolean>;
|
|
190
|
+
readonly contentType: ColumnBuilder<string | null, "text", boolean>;
|
|
191
|
+
readonly createdAt: ColumnBuilder<Date, "timestamp", true>;
|
|
192
|
+
}>, true, "byReleaseArtifactRelease">;
|
|
193
|
+
|
|
194
|
+
export declare type ReleaseChannelRow = InferRow<typeof releaseChannelsTable>;
|
|
195
|
+
|
|
196
|
+
export declare const releaseChannelsTable: Table<"_voltro_release_channels", FieldDefinitions<{
|
|
197
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
198
|
+
readonly appId: ColumnBuilder<string, "text", boolean>;
|
|
199
|
+
/** `stable`, `beta`, `internal`, … */
|
|
200
|
+
readonly name: ColumnBuilder<string, "text", boolean>;
|
|
201
|
+
readonly currentReleaseId: ColumnBuilder<string | null, "text", boolean>;
|
|
202
|
+
/** Below this version a client is blocked until it updates. */
|
|
203
|
+
readonly minSupportedVersion: ColumnBuilder<string | null, "text", boolean>;
|
|
204
|
+
/** Feature keys switched off for specific versions: `{ key: [versions] }`. */
|
|
205
|
+
readonly killSwitches: ColumnBuilder<unknown, "json", boolean>;
|
|
206
|
+
/** Public channel: downloads need no session. */
|
|
207
|
+
readonly public: ColumnBuilder<boolean, "boolean", true>;
|
|
208
|
+
/** Unsigned artefacts are refused unless this is set (internal only). */
|
|
209
|
+
readonly allowUnsigned: ColumnBuilder<boolean, "boolean", true>;
|
|
210
|
+
readonly updatedAt: ColumnBuilder<Date, "timestamp", true>;
|
|
211
|
+
}>, true, "byReleaseChannelApp">;
|
|
212
|
+
|
|
213
|
+
export declare type ReleaseEventRow = InferRow<typeof releaseEventsTable>;
|
|
214
|
+
|
|
215
|
+
export declare const releaseEventsTable: Table<"_voltro_release_events", FieldDefinitions<{
|
|
216
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
217
|
+
readonly appId: ColumnBuilder<string, "text", boolean>;
|
|
218
|
+
readonly channelId: ColumnBuilder<string | null, "text", boolean>;
|
|
219
|
+
readonly releaseId: ColumnBuilder<string | null, "text", boolean>;
|
|
220
|
+
/** `promote` | `rollback` | `rollout` | `policy` | `create` | `upload`. */
|
|
221
|
+
readonly kind: ColumnBuilder<string, "text", boolean>;
|
|
222
|
+
readonly reason: ColumnBuilder<string | null, "text", boolean>;
|
|
223
|
+
readonly actorId: ColumnBuilder<string | null, "text", boolean>;
|
|
224
|
+
readonly detail: ColumnBuilder<unknown, "json", boolean>;
|
|
225
|
+
readonly at: ColumnBuilder<Date, "timestamp", true>;
|
|
226
|
+
}>, true, "byReleaseEventApp">;
|
|
227
|
+
|
|
228
|
+
export declare class ReleaseNotFound extends ReleaseNotFound_base {
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
declare const ReleaseNotFound_base: Schema.TaggedErrorClass<ReleaseNotFound, "ReleaseNotFound", {
|
|
232
|
+
readonly _tag: Schema.tag<"ReleaseNotFound">;
|
|
233
|
+
} & {
|
|
234
|
+
app: typeof Schema.String;
|
|
235
|
+
version: Schema.optional<typeof Schema.String>;
|
|
236
|
+
channel: Schema.optional<typeof Schema.String>;
|
|
237
|
+
}>;
|
|
238
|
+
|
|
239
|
+
export declare type ReleasePlatform = (typeof RELEASE_PLATFORMS)[number];
|
|
240
|
+
|
|
241
|
+
export declare interface ReleasePolicy {
|
|
242
|
+
readonly app: string;
|
|
243
|
+
readonly channel: string;
|
|
244
|
+
/** The channel's current release version, or null before the first promote. */
|
|
245
|
+
readonly latestVersion: string | null;
|
|
246
|
+
readonly minSupportedVersion: string | null;
|
|
247
|
+
/** `{ featureKey: [versions the feature is switched off for] }` */
|
|
248
|
+
readonly killSwitches: Readonly<Record<string, ReadonlyArray<string>>>;
|
|
249
|
+
readonly rolloutPercent: number;
|
|
250
|
+
readonly rolloutSalt: string | null;
|
|
251
|
+
readonly cohorts: ReadonlyArray<string> | null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export declare class ReleaseRefused extends ReleaseRefused_base {
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
declare const ReleaseRefused_base: Schema.TaggedErrorClass<ReleaseRefused, "ReleaseRefused", {
|
|
258
|
+
readonly _tag: Schema.tag<"ReleaseRefused">;
|
|
259
|
+
} & {
|
|
260
|
+
reason: typeof Schema.String;
|
|
261
|
+
}>;
|
|
262
|
+
|
|
263
|
+
export declare type ReleaseRow = InferRow<typeof releasesTable>;
|
|
264
|
+
|
|
265
|
+
/** The scope that promotes, rolls out, rolls back and changes policy. */
|
|
266
|
+
export declare const RELEASES_MANAGE_SCOPE = "releases:manage";
|
|
267
|
+
|
|
268
|
+
export declare const RELEASES_TABLE = "_voltro_releases";
|
|
269
|
+
|
|
270
|
+
export declare type ReleaseShell = (typeof RELEASE_SHELLS)[number];
|
|
271
|
+
|
|
272
|
+
export declare const releasesPlugin: (options: ReleasesPluginOptions) => VoltroPlugin;
|
|
273
|
+
|
|
274
|
+
export declare interface ReleasesPluginOptions {
|
|
275
|
+
/** The app targets this api releases for; created on activation if absent. */
|
|
276
|
+
readonly apps: ReadonlyArray<ReleaseAppTarget>;
|
|
277
|
+
/** Write-time compaction after every `create`; see `planRetention`. */
|
|
278
|
+
readonly retention?: ReleasesRetention;
|
|
279
|
+
/** HTTP prefix of the feeds. Default `/releases`. */
|
|
280
|
+
readonly prefix?: string;
|
|
281
|
+
readonly name?: string;
|
|
282
|
+
/** Testing seam. */
|
|
283
|
+
readonly now?: () => number;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export declare interface ReleasesRetention {
|
|
287
|
+
/** Releases kept per channel (newest by version), beyond whatever any channel
|
|
288
|
+
* points to. Default 10; floors at 1. */
|
|
289
|
+
readonly keep?: number;
|
|
290
|
+
/** Per-channel override by channel name: `{ internal: 3 }`. */
|
|
291
|
+
readonly perChannel?: Readonly<Record<string, number>>;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export declare const releasesTable: Table<"_voltro_releases", FieldDefinitions<{
|
|
295
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
296
|
+
readonly appId: ColumnBuilder<string, "text", boolean>;
|
|
297
|
+
readonly channelId: ColumnBuilder<string, "text", boolean>;
|
|
298
|
+
readonly version: ColumnBuilder<string, "text", boolean>;
|
|
299
|
+
/** Build identity (the worker's build id, the OTA update id, the CI run). */
|
|
300
|
+
readonly buildId: ColumnBuilder<string | null, "text", boolean>;
|
|
301
|
+
/** Markdown release notes. */
|
|
302
|
+
readonly notes: ColumnBuilder<string | null, "text", boolean>;
|
|
303
|
+
readonly state: ColumnBuilder<string, "text", true>;
|
|
304
|
+
/** 0–100; 100 once complete. */
|
|
305
|
+
readonly rolloutPercent: ColumnBuilder<number, "integer", true>;
|
|
306
|
+
/** Salt for the deterministic cohort hash — fixed per release. */
|
|
307
|
+
readonly rolloutSalt: ColumnBuilder<string, "text", boolean>;
|
|
308
|
+
/** Named cohorts that always get the release (`tenant:acme`). */
|
|
309
|
+
readonly cohorts: ColumnBuilder<unknown, "json", boolean>;
|
|
310
|
+
readonly createdBy: ColumnBuilder<string | null, "text", boolean>;
|
|
311
|
+
readonly createdAt: ColumnBuilder<Date, "timestamp", true>;
|
|
312
|
+
readonly updatedAt: ColumnBuilder<Date, "timestamp", true>;
|
|
313
|
+
}>, true, "byReleaseAppChannel" | "byReleaseVersion">;
|
|
314
|
+
|
|
315
|
+
export declare const releaseTables: readonly [ Table<"_voltro_release_apps", FieldDefinitions<{
|
|
316
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
317
|
+
/** The app's name as the project spells it (`mobile`, `desktop`, `web`). */
|
|
318
|
+
readonly app: ColumnBuilder<string, "text", boolean>;
|
|
319
|
+
readonly platform: ColumnBuilder<string, "text", boolean>;
|
|
320
|
+
readonly shell: ColumnBuilder<string, "text", boolean>;
|
|
321
|
+
/** `com.acme.orders` — the store identity, where one exists. */
|
|
322
|
+
readonly bundleId: ColumnBuilder<string | null, "text", boolean>;
|
|
323
|
+
/** Public key the client verifies the feed with (minisign for Tauri,
|
|
324
|
+
* the Expo code-signing certificate for expo-updates). */
|
|
325
|
+
readonly updaterPublicKey: ColumnBuilder<string | null, "text", boolean>;
|
|
326
|
+
/** Expo: the runtime version the OTA bundles target. */
|
|
327
|
+
readonly runtimeVersion: ColumnBuilder<string | null, "text", boolean>;
|
|
328
|
+
readonly createdAt: ColumnBuilder<Date, "timestamp", true>;
|
|
329
|
+
}>, true, "byReleaseAppTarget">, Table<"_voltro_release_channels", FieldDefinitions<{
|
|
330
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
331
|
+
readonly appId: ColumnBuilder<string, "text", boolean>;
|
|
332
|
+
/** `stable`, `beta`, `internal`, … */
|
|
333
|
+
readonly name: ColumnBuilder<string, "text", boolean>;
|
|
334
|
+
readonly currentReleaseId: ColumnBuilder<string | null, "text", boolean>;
|
|
335
|
+
/** Below this version a client is blocked until it updates. */
|
|
336
|
+
readonly minSupportedVersion: ColumnBuilder<string | null, "text", boolean>;
|
|
337
|
+
/** Feature keys switched off for specific versions: `{ key: [versions] }`. */
|
|
338
|
+
readonly killSwitches: ColumnBuilder<unknown, "json", boolean>;
|
|
339
|
+
/** Public channel: downloads need no session. */
|
|
340
|
+
readonly public: ColumnBuilder<boolean, "boolean", true>;
|
|
341
|
+
/** Unsigned artefacts are refused unless this is set (internal only). */
|
|
342
|
+
readonly allowUnsigned: ColumnBuilder<boolean, "boolean", true>;
|
|
343
|
+
readonly updatedAt: ColumnBuilder<Date, "timestamp", true>;
|
|
344
|
+
}>, true, "byReleaseChannelApp">, Table<"_voltro_releases", FieldDefinitions<{
|
|
345
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
346
|
+
readonly appId: ColumnBuilder<string, "text", boolean>;
|
|
347
|
+
readonly channelId: ColumnBuilder<string, "text", boolean>;
|
|
348
|
+
readonly version: ColumnBuilder<string, "text", boolean>;
|
|
349
|
+
/** Build identity (the worker's build id, the OTA update id, the CI run). */
|
|
350
|
+
readonly buildId: ColumnBuilder<string | null, "text", boolean>;
|
|
351
|
+
/** Markdown release notes. */
|
|
352
|
+
readonly notes: ColumnBuilder<string | null, "text", boolean>;
|
|
353
|
+
readonly state: ColumnBuilder<string, "text", true>;
|
|
354
|
+
/** 0–100; 100 once complete. */
|
|
355
|
+
readonly rolloutPercent: ColumnBuilder<number, "integer", true>;
|
|
356
|
+
/** Salt for the deterministic cohort hash — fixed per release. */
|
|
357
|
+
readonly rolloutSalt: ColumnBuilder<string, "text", boolean>;
|
|
358
|
+
/** Named cohorts that always get the release (`tenant:acme`). */
|
|
359
|
+
readonly cohorts: ColumnBuilder<unknown, "json", boolean>;
|
|
360
|
+
readonly createdBy: ColumnBuilder<string | null, "text", boolean>;
|
|
361
|
+
readonly createdAt: ColumnBuilder<Date, "timestamp", true>;
|
|
362
|
+
readonly updatedAt: ColumnBuilder<Date, "timestamp", true>;
|
|
363
|
+
}>, true, "byReleaseAppChannel" | "byReleaseVersion">, Table<"_voltro_release_artifacts", FieldDefinitions<{
|
|
364
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
365
|
+
readonly releaseId: ColumnBuilder<string, "text", boolean>;
|
|
366
|
+
/** `dmg` | `msi` | `nsis` | `appimage` | `deb` | `rpm` | `ipa` | `aab` | `apk` | `expo-bundle` | `expo-asset` | `web-build`. */
|
|
367
|
+
readonly kind: ColumnBuilder<string, "text", boolean>;
|
|
368
|
+
/** Updater target: `darwin-aarch64`, `windows-x86_64`, `linux-x86_64`, `ios`, `android`. */
|
|
369
|
+
readonly target: ColumnBuilder<string | null, "text", boolean>;
|
|
370
|
+
/** Where the bytes are — a storage ref URL, a CDN URL. The feed hands this out. */
|
|
371
|
+
readonly url: ColumnBuilder<string, "text", boolean>;
|
|
372
|
+
readonly sha256: ColumnBuilder<string, "text", boolean>;
|
|
373
|
+
readonly size: ColumnBuilder<number, "integer", boolean>;
|
|
374
|
+
/** minisign / Expo code-signing signature over the bytes. */
|
|
375
|
+
readonly signature: ColumnBuilder<string | null, "text", boolean>;
|
|
376
|
+
readonly notarized: ColumnBuilder<boolean, "boolean", true>;
|
|
377
|
+
/** Expo: the asset's key/path inside the update. */
|
|
378
|
+
readonly assetKey: ColumnBuilder<string | null, "text", boolean>;
|
|
379
|
+
readonly contentType: ColumnBuilder<string | null, "text", boolean>;
|
|
380
|
+
readonly createdAt: ColumnBuilder<Date, "timestamp", true>;
|
|
381
|
+
}>, true, "byReleaseArtifactRelease">, Table<"_voltro_release_events", FieldDefinitions<{
|
|
382
|
+
readonly id: ColumnBuilder<string, "id", boolean>;
|
|
383
|
+
readonly appId: ColumnBuilder<string, "text", boolean>;
|
|
384
|
+
readonly channelId: ColumnBuilder<string | null, "text", boolean>;
|
|
385
|
+
readonly releaseId: ColumnBuilder<string | null, "text", boolean>;
|
|
386
|
+
/** `promote` | `rollback` | `rollout` | `policy` | `create` | `upload`. */
|
|
387
|
+
readonly kind: ColumnBuilder<string, "text", boolean>;
|
|
388
|
+
readonly reason: ColumnBuilder<string | null, "text", boolean>;
|
|
389
|
+
readonly actorId: ColumnBuilder<string | null, "text", boolean>;
|
|
390
|
+
readonly detail: ColumnBuilder<unknown, "json", boolean>;
|
|
391
|
+
readonly at: ColumnBuilder<Date, "timestamp", true>;
|
|
392
|
+
}>, true, "byReleaseEventApp">];
|
|
393
|
+
|
|
394
|
+
/** The `latest*.yml` document. `sha512` is what electron-updater verifies; a
|
|
395
|
+
* release uploaded with sha256 only carries it under `sha256` and the file
|
|
396
|
+
* entry says so — the client refuses, which is the honest outcome. */
|
|
397
|
+
export declare const renderElectronLatestYml: (release: FeedRelease, platform: "win" | "mac" | "linux", sha512ByArtifact?: Readonly<Record<string, string>>) => string | null;
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* The expo-updates answer for a client (`expo-runtime-version`,
|
|
401
|
+
* `expo-current-update-id`). The launch asset is the `expo-bundle` artefact
|
|
402
|
+
* whose `target` is the client platform; every other `expo-asset` rides along.
|
|
403
|
+
*/
|
|
404
|
+
export declare const renderExpoFeed: (release: FeedRelease | null, client: FeedClient & {
|
|
405
|
+
readonly platform: "ios" | "android";
|
|
406
|
+
readonly runtimeVersion: string;
|
|
407
|
+
readonly currentUpdateId: string | null;
|
|
408
|
+
}, channel: {
|
|
409
|
+
readonly runtimeVersion: string | null;
|
|
410
|
+
readonly rolledBackTo: {
|
|
411
|
+
readonly commitTime: Date;
|
|
412
|
+
} | null;
|
|
413
|
+
}) => ExpoFeedAnswer;
|
|
414
|
+
|
|
415
|
+
/** The Tauri updater document for one target, or null for "no update". */
|
|
416
|
+
export declare const renderTauriFeed: (release: FeedRelease, client: FeedClient & {
|
|
417
|
+
readonly target: string;
|
|
418
|
+
}) => TauriUpdaterResponse | null;
|
|
419
|
+
|
|
420
|
+
/** The install's bucket, 0–99, stable for one salt. */
|
|
421
|
+
export declare const rolloutBucket: (installId: string, salt: string) => number;
|
|
422
|
+
|
|
423
|
+
export declare interface RolloutInput {
|
|
424
|
+
readonly installId: string;
|
|
425
|
+
readonly salt: string;
|
|
426
|
+
readonly percent: number;
|
|
427
|
+
/** The install's named cohorts (`tenant:acme`), matched against the release's. */
|
|
428
|
+
readonly installCohorts?: ReadonlyArray<string>;
|
|
429
|
+
readonly releaseCohorts?: ReadonlyArray<string> | null;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/** Sort versions descending. */
|
|
433
|
+
export declare const sortVersionsDesc: (versions: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
434
|
+
|
|
435
|
+
export declare interface TauriUpdaterResponse {
|
|
436
|
+
readonly version: string;
|
|
437
|
+
readonly notes: string;
|
|
438
|
+
readonly pub_date: string;
|
|
439
|
+
readonly platforms: Readonly<Record<string, {
|
|
440
|
+
readonly signature: string;
|
|
441
|
+
readonly url: string;
|
|
442
|
+
}>>;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export { }
|