@voltro/plugin-releases 0.84.0 → 0.86.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1215 -0
- package/THIRD-PARTY-NOTICES.md +127 -609
- package/dist/artifactMetadata.js +27 -0
- package/dist/errors.d.ts +10 -12
- package/dist/errors.js +5 -1
- package/dist/feeds.js +112 -0
- package/dist/index.d.ts +37 -23
- package/dist/index.js +441 -536
- package/dist/names.js +4 -0
- package/dist/retention.js +13 -0
- package/dist/{rollout-CGRKMTfv.js → rollout.js} +1 -1
- package/dist/rpc.d.ts +162 -132
- package/dist/rpc.js +263 -2
- package/dist/schema.js +85 -0
- package/dist/uploadIdentity.server.js +5 -0
- package/dist/web.js +2 -2
- package/package.json +7 -7
- package/dist/rpc-DeEV8l3U.js +0 -226
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/artifactMetadata.ts
|
|
2
|
+
var e = (e) => typeof e == "string" && e.trim().length > 0 && !/[\u0000-\u001f\u007f]/.test(e), t = (t) => e(t) && t.length <= 200, n = (e) => typeof e == "string" && /^[a-f0-9]{64}$/i.test(e), r = (e) => Number.isSafeInteger(e) && e > 0, i = (e) => typeof e == "string" && e.trim().length > 0 && !e.includes("\0"), a = (a) => {
|
|
3
|
+
for (let t of [
|
|
4
|
+
"releaseId",
|
|
5
|
+
"kind",
|
|
6
|
+
"url"
|
|
7
|
+
]) if (!e(a[t])) return `Artifact ${t} must be nonblank text without control characters`;
|
|
8
|
+
if (a.operationId !== void 0 && !t(a.operationId)) return "Artifact operationId must be nonblank text without control characters and at most 200 characters";
|
|
9
|
+
if (!n(a.sha256)) return "Artifact sha256 must contain exactly 64 hexadecimal characters";
|
|
10
|
+
if (!r(a.size)) return "Artifact size must be a positive safe integer";
|
|
11
|
+
for (let t of [
|
|
12
|
+
"target",
|
|
13
|
+
"assetKey",
|
|
14
|
+
"contentType"
|
|
15
|
+
]) {
|
|
16
|
+
let n = a[t];
|
|
17
|
+
if (n !== void 0 && !e(n)) return `Artifact ${t} must be nonblank text without control characters`;
|
|
18
|
+
}
|
|
19
|
+
if (a.signature !== void 0 && !i(a.signature)) return "Artifact signature must not be blank or contain NUL";
|
|
20
|
+
}, o = (e) => {
|
|
21
|
+
if (typeof e != "string" || !/^[1-9][0-9]*$/.test(e)) throw Error("Stored artifact size must be a positive integer");
|
|
22
|
+
let t = Number(e);
|
|
23
|
+
if (!r(t)) throw Error("Stored artifact size exceeds the numeric feed range");
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { n as artifactHash, a as artifactMetadataIssue, t as artifactOperationId, r as artifactSize, o as artifactStoredSize, e as artifactText, i as hasArtifactSignature };
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import { Schema } from 'effect';
|
|
2
|
+
import { YieldableError } from 'effect/Cause';
|
|
2
3
|
|
|
3
4
|
export declare const releaseErrors: readonly [typeof ReleaseNotFound, typeof ReleaseRefused];
|
|
4
5
|
|
|
5
6
|
export declare class ReleaseNotFound extends ReleaseNotFound_base {
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
declare const ReleaseNotFound_base: Schema.
|
|
9
|
-
readonly
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
channel: Schema.optional<typeof Schema.String>;
|
|
14
|
-
}>;
|
|
9
|
+
declare const ReleaseNotFound_base: Schema.Class<ReleaseNotFound, Schema.TaggedStruct<"ReleaseNotFound", {
|
|
10
|
+
readonly app: Schema.String;
|
|
11
|
+
readonly version: Schema.optional<Schema.String>;
|
|
12
|
+
readonly channel: Schema.optional<Schema.String>;
|
|
13
|
+
}>, YieldableError>;
|
|
15
14
|
|
|
16
15
|
export declare class ReleaseRefused extends ReleaseRefused_base {
|
|
16
|
+
get message(): string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
declare const ReleaseRefused_base: Schema.
|
|
20
|
-
readonly
|
|
21
|
-
}
|
|
22
|
-
reason: typeof Schema.String;
|
|
23
|
-
}>;
|
|
19
|
+
declare const ReleaseRefused_base: Schema.Class<ReleaseRefused, Schema.TaggedStruct<"ReleaseRefused", {
|
|
20
|
+
readonly reason: Schema.String;
|
|
21
|
+
}>, YieldableError>;
|
|
24
22
|
|
|
25
23
|
export { }
|
package/dist/errors.js
CHANGED
|
@@ -4,6 +4,10 @@ var t = class extends e.TaggedError()("ReleaseNotFound", {
|
|
|
4
4
|
app: e.String,
|
|
5
5
|
version: e.optional(e.String),
|
|
6
6
|
channel: e.optional(e.String)
|
|
7
|
-
}) {}, n = class extends e.TaggedError()("ReleaseRefused", { reason: e.String }) {
|
|
7
|
+
}) {}, n = class extends e.TaggedError()("ReleaseRefused", { reason: e.String }) {
|
|
8
|
+
get message() {
|
|
9
|
+
return this.reason;
|
|
10
|
+
}
|
|
11
|
+
}, r = [t, n];
|
|
8
12
|
//#endregion
|
|
9
13
|
export { t as ReleaseNotFound, n as ReleaseRefused, r as releaseErrors };
|
package/dist/feeds.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { hasArtifactSignature as e } from "./artifactMetadata.js";
|
|
2
|
+
import { compareVersions as t, inRollout as n } from "./rollout.js";
|
|
3
|
+
//#region src/feeds.ts
|
|
4
|
+
var r = (e, r) => r.currentVersion !== null && t(e.version, r.currentVersion) <= 0 ? !1 : n({
|
|
5
|
+
installId: r.installId,
|
|
6
|
+
salt: e.rolloutSalt,
|
|
7
|
+
percent: e.rolloutPercent,
|
|
8
|
+
...r.cohorts === void 0 ? {} : { installCohorts: r.cohorts },
|
|
9
|
+
releaseCohorts: e.cohorts
|
|
10
|
+
}), i = (t, n) => {
|
|
11
|
+
if (!r(t, n)) return null;
|
|
12
|
+
let i = t.artifacts.find((t) => t.target === n.target && e(t.signature)) ?? (n.target === "darwin-aarch64" || n.target === "darwin-x86_64" ? t.artifacts.find((t) => t.target === "darwin-universal" && e(t.signature)) : void 0);
|
|
13
|
+
return !i || !e(i.signature) ? null : {
|
|
14
|
+
version: t.version,
|
|
15
|
+
notes: t.notes ?? "",
|
|
16
|
+
pub_date: t.createdAt.toISOString(),
|
|
17
|
+
platforms: { [n.target]: {
|
|
18
|
+
signature: i.signature,
|
|
19
|
+
url: i.url
|
|
20
|
+
} }
|
|
21
|
+
};
|
|
22
|
+
}, a = (e, t, n = {}) => {
|
|
23
|
+
let r = {
|
|
24
|
+
win: [
|
|
25
|
+
"nsis",
|
|
26
|
+
"msi",
|
|
27
|
+
"exe"
|
|
28
|
+
],
|
|
29
|
+
mac: ["dmg", "zip"],
|
|
30
|
+
linux: [
|
|
31
|
+
"appimage",
|
|
32
|
+
"deb",
|
|
33
|
+
"rpm"
|
|
34
|
+
]
|
|
35
|
+
}, i = e.artifacts.filter((e) => r[t].includes(e.kind));
|
|
36
|
+
if (i.length === 0) return null;
|
|
37
|
+
let a = [`version: ${e.version}`, "files:"];
|
|
38
|
+
for (let e of i) {
|
|
39
|
+
a.push(` - url: ${e.url}`);
|
|
40
|
+
let t = n[e.sha256];
|
|
41
|
+
a.push(t === void 0 ? ` sha256: ${e.sha256}` : ` sha512: ${t}`), a.push(` size: ${e.size}`);
|
|
42
|
+
}
|
|
43
|
+
let o = i[0];
|
|
44
|
+
a.push(`path: ${o.url}`);
|
|
45
|
+
let s = n[o.sha256];
|
|
46
|
+
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";
|
|
47
|
+
}, o = (e, t, n) => {
|
|
48
|
+
if (n.rolledBackTo !== null) return {
|
|
49
|
+
kind: "rollback",
|
|
50
|
+
commitTime: n.rolledBackTo.commitTime.toISOString()
|
|
51
|
+
};
|
|
52
|
+
if (e === null || n.runtimeVersion !== null && n.runtimeVersion !== t.runtimeVersion) return { kind: "no-update" };
|
|
53
|
+
let i = e.buildId ?? e.id;
|
|
54
|
+
if (t.currentUpdateId === i || !r(e, {
|
|
55
|
+
installId: t.installId,
|
|
56
|
+
currentVersion: null,
|
|
57
|
+
...t.cohorts === void 0 ? {} : { cohorts: t.cohorts }
|
|
58
|
+
})) return { kind: "no-update" };
|
|
59
|
+
let a = e.artifacts.find((e) => e.kind === "expo-bundle" && e.target === t.platform);
|
|
60
|
+
if (!a) return { kind: "no-update" };
|
|
61
|
+
let o = e.artifacts.filter((e) => e.kind === "expo-asset" && (e.target === null || e.target === t.platform)).map((e) => ({
|
|
62
|
+
hash: e.sha256,
|
|
63
|
+
key: e.assetKey ?? e.sha256,
|
|
64
|
+
contentType: e.contentType ?? "application/octet-stream",
|
|
65
|
+
url: e.url
|
|
66
|
+
}));
|
|
67
|
+
return {
|
|
68
|
+
kind: "manifest",
|
|
69
|
+
manifest: {
|
|
70
|
+
id: i,
|
|
71
|
+
createdAt: e.createdAt.toISOString(),
|
|
72
|
+
runtimeVersion: t.runtimeVersion,
|
|
73
|
+
launchAsset: {
|
|
74
|
+
hash: a.sha256,
|
|
75
|
+
key: a.assetKey ?? "bundle",
|
|
76
|
+
contentType: a.contentType ?? "application/javascript",
|
|
77
|
+
url: a.url
|
|
78
|
+
},
|
|
79
|
+
assets: o,
|
|
80
|
+
metadata: {},
|
|
81
|
+
extra: {
|
|
82
|
+
version: e.version,
|
|
83
|
+
...e.notes ? { notes: e.notes } : {}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}, s = {
|
|
88
|
+
macos: ["dmg", "zip"],
|
|
89
|
+
windows: [
|
|
90
|
+
"nsis",
|
|
91
|
+
"msi",
|
|
92
|
+
"exe"
|
|
93
|
+
],
|
|
94
|
+
linux: [
|
|
95
|
+
"appimage",
|
|
96
|
+
"deb",
|
|
97
|
+
"rpm"
|
|
98
|
+
],
|
|
99
|
+
ios: ["ipa"],
|
|
100
|
+
android: ["apk", "aab"]
|
|
101
|
+
}, c = (e, t, n) => {
|
|
102
|
+
let r = s[t] ?? [], i = e.artifacts.filter((e) => r.includes(e.kind));
|
|
103
|
+
return i.length === 0 ? null : n === void 0 ? (t === "macos" ? i.find((e) => e.target === "darwin-universal") : void 0) ?? i[0] : i.find((e) => e.target === `${t === "macos" ? "darwin" : t}-${n}`) || (t === "macos" && (n === "aarch64" || n === "x86_64") ? i.find((e) => e.target === "darwin-universal") ?? null : null);
|
|
104
|
+
}, l = (e) => /Windows/i.test(e) ? {
|
|
105
|
+
os: "windows",
|
|
106
|
+
arch: /ARM64|aarch64/i.test(e) ? "aarch64" : "x86_64"
|
|
107
|
+
} : /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) ? {
|
|
108
|
+
os: "linux",
|
|
109
|
+
arch: /aarch64|arm64/i.test(e) ? "aarch64" : "x86_64"
|
|
110
|
+
} : null;
|
|
111
|
+
//#endregion
|
|
112
|
+
export { r as offeredTo, l as osFromUserAgent, c as pickDownload, a as renderElectronLatestYml, o as renderExpoFeed, i as renderTauriFeed };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { ColumnBuilder } from '@voltro/database';
|
|
2
|
+
import { DataStore } from '@voltro/database';
|
|
3
|
+
import { Effect } from 'effect';
|
|
2
4
|
import { FieldDefinitions } from '@voltro/database';
|
|
3
5
|
import { InferRow } from '@voltro/database';
|
|
6
|
+
import { PluginRouteContext } from '@voltro/protocol';
|
|
4
7
|
import { Schema } from 'effect';
|
|
5
8
|
import { Table } from '@voltro/database';
|
|
6
9
|
import { VoltroPlugin } from '@voltro/protocol';
|
|
10
|
+
import { YieldableError } from 'effect/Cause';
|
|
7
11
|
|
|
8
12
|
export declare const BASE_NAME = "@voltro/plugin-releases";
|
|
9
13
|
|
|
@@ -105,14 +109,14 @@ export declare const parseVersion: (raw: string) => {
|
|
|
105
109
|
export declare const pickDownload: (release: FeedRelease, os: string, arch?: string) => FeedArtifact | null;
|
|
106
110
|
|
|
107
111
|
declare const PolicySchema: Schema.Struct<{
|
|
108
|
-
app:
|
|
109
|
-
channel:
|
|
110
|
-
latestVersion: Schema.NullOr<
|
|
111
|
-
minSupportedVersion: Schema.NullOr<
|
|
112
|
-
killSwitches: Schema
|
|
113
|
-
rolloutPercent:
|
|
114
|
-
rolloutSalt: Schema.NullOr<
|
|
115
|
-
cohorts: Schema.NullOr<Schema
|
|
112
|
+
readonly app: Schema.String;
|
|
113
|
+
readonly channel: Schema.String;
|
|
114
|
+
readonly latestVersion: Schema.NullOr<Schema.String>;
|
|
115
|
+
readonly minSupportedVersion: Schema.NullOr<Schema.String>;
|
|
116
|
+
readonly killSwitches: Schema.$Record<Schema.String, Schema.$Array<Schema.String>>;
|
|
117
|
+
readonly rolloutPercent: Schema.Number;
|
|
118
|
+
readonly rolloutSalt: Schema.NullOr<Schema.String>;
|
|
119
|
+
readonly cohorts: Schema.NullOr<Schema.$Array<Schema.String>>;
|
|
116
120
|
}>;
|
|
117
121
|
|
|
118
122
|
export declare interface PolicyVerdict {
|
|
@@ -183,7 +187,7 @@ export declare const releaseArtifactsTable: Table<"_voltro_release_artifacts", F
|
|
|
183
187
|
/** Where the bytes are — a storage ref URL, a CDN URL. The feed hands this out. */
|
|
184
188
|
readonly url: ColumnBuilder<string, "text", boolean>;
|
|
185
189
|
readonly sha256: ColumnBuilder<string, "text", boolean>;
|
|
186
|
-
readonly size: ColumnBuilder<
|
|
190
|
+
readonly size: ColumnBuilder<string, "bigint", boolean>;
|
|
187
191
|
/** minisign / Expo code-signing signature over the bytes. */
|
|
188
192
|
readonly signature: ColumnBuilder<string | null, "text", boolean>;
|
|
189
193
|
readonly notarized: ColumnBuilder<boolean, "boolean", true>;
|
|
@@ -227,16 +231,20 @@ export declare const releaseEventsTable: Table<"_voltro_release_events", FieldDe
|
|
|
227
231
|
readonly at: ColumnBuilder<Date, "timestamp", true>;
|
|
228
232
|
}>, true, "byReleaseEventApp">;
|
|
229
233
|
|
|
234
|
+
export declare type ReleaseManagementAction = 'apps' | 'create' | 'prepare-upload' | 'upload' | 'promote' | 'rollout' | 'rollback' | 'policy';
|
|
235
|
+
|
|
236
|
+
export declare interface ReleaseManagementContext extends PluginRouteContext {
|
|
237
|
+
readonly mutationStore: DataStore;
|
|
238
|
+
}
|
|
239
|
+
|
|
230
240
|
export declare class ReleaseNotFound extends ReleaseNotFound_base {
|
|
231
241
|
}
|
|
232
242
|
|
|
233
|
-
declare const ReleaseNotFound_base: Schema.
|
|
234
|
-
readonly
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
channel: Schema.optional<typeof Schema.String>;
|
|
239
|
-
}>;
|
|
243
|
+
declare const ReleaseNotFound_base: Schema.Class<ReleaseNotFound, Schema.TaggedStruct<"ReleaseNotFound", {
|
|
244
|
+
readonly app: Schema.String;
|
|
245
|
+
readonly version: Schema.optional<Schema.String>;
|
|
246
|
+
readonly channel: Schema.optional<Schema.String>;
|
|
247
|
+
}>, YieldableError>;
|
|
240
248
|
|
|
241
249
|
export declare type ReleasePlatform = (typeof RELEASE_PLATFORMS)[number];
|
|
242
250
|
|
|
@@ -254,13 +262,12 @@ export declare interface ReleasePolicy {
|
|
|
254
262
|
}
|
|
255
263
|
|
|
256
264
|
export declare class ReleaseRefused extends ReleaseRefused_base {
|
|
265
|
+
get message(): string;
|
|
257
266
|
}
|
|
258
267
|
|
|
259
|
-
declare const ReleaseRefused_base: Schema.
|
|
260
|
-
readonly
|
|
261
|
-
}
|
|
262
|
-
reason: typeof Schema.String;
|
|
263
|
-
}>;
|
|
268
|
+
declare const ReleaseRefused_base: Schema.Class<ReleaseRefused, Schema.TaggedStruct<"ReleaseRefused", {
|
|
269
|
+
readonly reason: Schema.String;
|
|
270
|
+
}>, YieldableError>;
|
|
264
271
|
|
|
265
272
|
export declare type ReleaseRow = InferRow<typeof releasesTable>;
|
|
266
273
|
|
|
@@ -271,7 +278,14 @@ export declare const RELEASES_TABLE = "_voltro_releases";
|
|
|
271
278
|
|
|
272
279
|
export declare type ReleaseShell = (typeof RELEASE_SHELLS)[number];
|
|
273
280
|
|
|
274
|
-
export declare
|
|
281
|
+
export declare interface ReleasesPlugin extends VoltroPlugin {
|
|
282
|
+
/** Trusted server capability. Authorize the caller and execute inside its
|
|
283
|
+
* transaction; failed Effects must escape that transaction to roll it back.
|
|
284
|
+
* Uses the same input schemas and atomic writers as RPC and Inspect. */
|
|
285
|
+
readonly manage: (action: ReleaseManagementAction, input: unknown, context: ReleaseManagementContext) => Effect.Effect<unknown, unknown>;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export declare const releasesPlugin: (options: ReleasesPluginOptions) => ReleasesPlugin;
|
|
275
289
|
|
|
276
290
|
export declare interface ReleasesPluginOptions {
|
|
277
291
|
/** The app targets this api releases for; created on activation if absent. */
|
|
@@ -374,7 +388,7 @@ export declare const releaseTables: readonly [ Table<"_voltro_release_apps", Fie
|
|
|
374
388
|
/** Where the bytes are — a storage ref URL, a CDN URL. The feed hands this out. */
|
|
375
389
|
readonly url: ColumnBuilder<string, "text", boolean>;
|
|
376
390
|
readonly sha256: ColumnBuilder<string, "text", boolean>;
|
|
377
|
-
readonly size: ColumnBuilder<
|
|
391
|
+
readonly size: ColumnBuilder<string, "bigint", boolean>;
|
|
378
392
|
/** minisign / Expo code-signing signature over the bytes. */
|
|
379
393
|
readonly signature: ColumnBuilder<string | null, "text", boolean>;
|
|
380
394
|
readonly notarized: ColumnBuilder<boolean, "boolean", true>;
|