@hot-updater/cloudflare 1.0.0-rc.17 → 1.0.0-rc.18
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/iac/index.cjs +15 -33
- package/dist/iac/index.mjs +18 -36
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +107 -26
- package/dist/index.d.mts +107 -26
- package/dist/index.mjs +6 -6
- package/dist/worker/index.d.cts +107 -26
- package/dist/worker/index.d.mts +107 -26
- package/package.json +5 -5
- package/sql/bundles.sql +32 -4
- package/src/d1Database.spec.ts +1 -1
- package/src/d1Database.ts +4 -4
- package/src/d1Schema.spec.ts +7 -2
- package/src/d1Schema.ts +4 -4
- package/worker/dist/README.md +1 -1
- package/worker/dist/index.js +10465 -9001
- package/worker/dist/index.js.map +4 -4
- package/worker/migrations/0001_hot-updater_1.0.0.sql +32 -4
- package/worker/src/d1.conformance.integration.spec.ts +2 -2
- package/worker/src/d1.readBudgets.integration.spec.ts +2 -2
- package/worker/src/databaseMigration.integration.spec.ts +5 -4
- package/worker/src/databasePlugins.integration.spec.ts +20 -8
- package/worker/src/index.integration.spec.ts +47 -0
- package/worker/src/readPlans.integration.spec.ts +2 -4
package/dist/iac/index.cjs
CHANGED
|
@@ -109,10 +109,10 @@ const createD1Database = (runner) => {
|
|
|
109
109
|
//#region src/d1Schema.ts
|
|
110
110
|
/**
|
|
111
111
|
* D1's schema: the guard table batch writes need, then the shared SQL
|
|
112
|
-
* schema, settings last. Every statement can
|
|
113
|
-
* server's plugin tables repeats
|
|
112
|
+
* schema of core and the target's plugins, settings last. Every statement can
|
|
113
|
+
* run again, so a migration for a server's plugin tables repeats core's.
|
|
114
114
|
*/
|
|
115
|
-
const d1SchemaStatements = ({ schema, settings } = _hot_updater_server_database.
|
|
115
|
+
const d1SchemaStatements = ({ schema, settings } = _hot_updater_server_database.coreTarget) => [...(0, _hot_updater_server_database.createTableStatements)("sqlite", [_hot_updater_server_database.WRITE_GUARD_TABLE]), ...(0, _hot_updater_server_db.generateEngineSql)("sqlite", schema, settings)];
|
|
116
116
|
/** The schema as a D1 migration, which `wrangler d1 migrations apply` runs. */
|
|
117
117
|
const d1SchemaSql = (target) => `-- HotUpdater.schema\n\n${d1SchemaStatements(target).map((statement) => `${statement};`).join("\n\n")}\n`;
|
|
118
118
|
//#endregion
|
|
@@ -151,8 +151,8 @@ const d1Database = (config) => {
|
|
|
151
151
|
query: async (statement) => (await execute([statement]))[0],
|
|
152
152
|
batch: execute
|
|
153
153
|
}),
|
|
154
|
-
generateSchema: ((version, _name, target = _hot_updater_server_database.
|
|
155
|
-
if (version !== "latest" && version !== _hot_updater_server_database.
|
|
154
|
+
generateSchema: ((version, _name, target = _hot_updater_server_database.coreTarget) => {
|
|
155
|
+
if (version !== "latest" && version !== _hot_updater_server_database.coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
|
|
156
156
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, "").slice(0, 14);
|
|
157
157
|
return {
|
|
158
158
|
code: d1SchemaSql(target),
|
|
@@ -11427,23 +11427,6 @@ const getConfigScaffold = (build) => {
|
|
|
11427
11427
|
};
|
|
11428
11428
|
//#endregion
|
|
11429
11429
|
//#region iac/index.ts
|
|
11430
|
-
const SOURCE_TEMPLATE = `// add this to your App.tsx
|
|
11431
|
-
import { HotUpdater } from "@hot-updater/react-native";
|
|
11432
|
-
|
|
11433
|
-
function App() {
|
|
11434
|
-
return null; // Replace with your app root
|
|
11435
|
-
}
|
|
11436
|
-
|
|
11437
|
-
HotUpdater.init({
|
|
11438
|
-
baseURL: "%%source%%",
|
|
11439
|
-
requestHeaders: {
|
|
11440
|
-
"x-api-key": %%apiKey%%,
|
|
11441
|
-
},
|
|
11442
|
-
});
|
|
11443
|
-
|
|
11444
|
-
// Call HotUpdater.checkForUpdate({ updateStrategy: "appVersion" })
|
|
11445
|
-
// when your app is ready to check.
|
|
11446
|
-
export default App;`;
|
|
11447
11430
|
const deployWorker = async (apiToken, accountId, { credentialSource, d1DatabaseId, d1DatabaseName, nonInteractive, r2BucketName, workerName }) => {
|
|
11448
11431
|
const cwd = (0, _hot_updater_cli_tools.getCwd)();
|
|
11449
11432
|
const cloudflarePackagePath = require.resolve("@hot-updater/cloudflare/package.json", { paths: [cwd] });
|
|
@@ -11827,13 +11810,13 @@ const runInit = async ({ build, envFile }) => {
|
|
|
11827
11810
|
cloudflareApiToken: apiToken,
|
|
11828
11811
|
databaseId: selectedD1DatabaseId
|
|
11829
11812
|
});
|
|
11830
|
-
let
|
|
11813
|
+
let credential;
|
|
11831
11814
|
try {
|
|
11832
|
-
|
|
11833
|
-
|
|
11815
|
+
credential = await (0, _hot_updater_server_db.provisionClientCredential)(database, plugins, {
|
|
11816
|
+
env: initInputEnv,
|
|
11834
11817
|
name: "Cloudflare init"
|
|
11835
|
-
})
|
|
11836
|
-
await (0, _hot_updater_cli_tools.makeEnv)({
|
|
11818
|
+
});
|
|
11819
|
+
if (credential !== void 0) await (0, _hot_updater_cli_tools.makeEnv)({ [credential.env]: credential.value });
|
|
11837
11820
|
} finally {
|
|
11838
11821
|
await database.dispose?.();
|
|
11839
11822
|
}
|
|
@@ -11843,12 +11826,11 @@ const runInit = async ({ build, envFile }) => {
|
|
|
11843
11826
|
else if (configWriteResult.status === "merged") _hot_updater_cli_tools.p.log.success("Updated 'hot-updater.config.ts' file with Cloudflare settings.");
|
|
11844
11827
|
else _hot_updater_cli_tools.p.log.warn(`Kept existing 'hot-updater.config.ts' unchanged: ${configWriteResult.reason}`);
|
|
11845
11828
|
await (0, _hot_updater_cli_tools.generateHotUpdaterPlugins)("@hot-updater/cloudflare");
|
|
11846
|
-
|
|
11847
|
-
|
|
11848
|
-
|
|
11849
|
-
|
|
11850
|
-
|
|
11851
|
-
_hot_updater_cli_tools.p.log.message("Store this API key separately in a secure place.");
|
|
11829
|
+
(0, _hot_updater_cli_tools.printAppSetup)({
|
|
11830
|
+
...subdomains.subdomain ? { baseURL: `https://${workerName}.${subdomains.subdomain}.workers.dev` } : {},
|
|
11831
|
+
...credential === void 0 ? {} : { credential },
|
|
11832
|
+
clientPlugins: (0, _hot_updater_server_db.clientPluginsOf)(plugins)
|
|
11833
|
+
});
|
|
11852
11834
|
_hot_updater_cli_tools.p.log.message(`Next step: ${(0, _hot_updater_cli_tools.link)("https://hot-updater.dev/docs/managed/cloudflare#step-4-add-hotupdater-to-your-project")}`);
|
|
11853
11835
|
_hot_updater_cli_tools.p.log.success("Done! 🎉");
|
|
11854
11836
|
};
|
package/dist/iac/index.mjs
CHANGED
|
@@ -2,10 +2,10 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import crypto from "crypto";
|
|
3
3
|
import fs from "fs/promises";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import { ConfigBuilder, InitError, LegacyInfrastructureError, assertInfrastructureGenerationAtUrl, assertInitInputs, assertInitProviderInputs, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder,
|
|
6
|
-
import {
|
|
5
|
+
import { ConfigBuilder, InitError, LegacyInfrastructureError, assertInfrastructureGenerationAtUrl, assertInitInputs, assertInitProviderInputs, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder, generateHotUpdaterPlugins, getCwd, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, p, printAppSetup, readHotUpdaterInitEnv, resolveInitProviderInput, transformTemplate, writeHotUpdaterConfig } from "@hot-updater/cli-tools";
|
|
6
|
+
import { clientPluginsOf, generateEngineSql, provisionClientCredential } from "@hot-updater/server/db";
|
|
7
7
|
import Cloudflare$1, { Cloudflare } from "cloudflare";
|
|
8
|
-
import { WRITE_GUARD_TABLE,
|
|
8
|
+
import { WRITE_GUARD_TABLE, coreSettings, coreTarget, createEngineDatabase, createSqlAdapter, createTableStatements } from "@hot-updater/server/database";
|
|
9
9
|
import { apiKeys } from "@hot-updater/server/plugins/api-keys";
|
|
10
10
|
import { insights } from "@hot-updater/server/plugins/insights";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
@@ -101,10 +101,10 @@ const createD1Database = (runner) => {
|
|
|
101
101
|
//#region src/d1Schema.ts
|
|
102
102
|
/**
|
|
103
103
|
* D1's schema: the guard table batch writes need, then the shared SQL
|
|
104
|
-
* schema, settings last. Every statement can
|
|
105
|
-
* server's plugin tables repeats
|
|
104
|
+
* schema of core and the target's plugins, settings last. Every statement can
|
|
105
|
+
* run again, so a migration for a server's plugin tables repeats core's.
|
|
106
106
|
*/
|
|
107
|
-
const d1SchemaStatements = ({ schema, settings } =
|
|
107
|
+
const d1SchemaStatements = ({ schema, settings } = coreTarget) => [...createTableStatements("sqlite", [WRITE_GUARD_TABLE]), ...generateEngineSql("sqlite", schema, settings)];
|
|
108
108
|
/** The schema as a D1 migration, which `wrangler d1 migrations apply` runs. */
|
|
109
109
|
const d1SchemaSql = (target) => `-- HotUpdater.schema\n\n${d1SchemaStatements(target).map((statement) => `${statement};`).join("\n\n")}\n`;
|
|
110
110
|
//#endregion
|
|
@@ -143,8 +143,8 @@ const d1Database = (config) => {
|
|
|
143
143
|
query: async (statement) => (await execute([statement]))[0],
|
|
144
144
|
batch: execute
|
|
145
145
|
}),
|
|
146
|
-
generateSchema: ((version, _name, target =
|
|
147
|
-
if (version !== "latest" && version !==
|
|
146
|
+
generateSchema: ((version, _name, target = coreTarget) => {
|
|
147
|
+
if (version !== "latest" && version !== coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
|
|
148
148
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, "").slice(0, 14);
|
|
149
149
|
return {
|
|
150
150
|
code: d1SchemaSql(target),
|
|
@@ -11419,23 +11419,6 @@ const getConfigScaffold = (build) => {
|
|
|
11419
11419
|
};
|
|
11420
11420
|
//#endregion
|
|
11421
11421
|
//#region iac/index.ts
|
|
11422
|
-
const SOURCE_TEMPLATE = `// add this to your App.tsx
|
|
11423
|
-
import { HotUpdater } from "@hot-updater/react-native";
|
|
11424
|
-
|
|
11425
|
-
function App() {
|
|
11426
|
-
return null; // Replace with your app root
|
|
11427
|
-
}
|
|
11428
|
-
|
|
11429
|
-
HotUpdater.init({
|
|
11430
|
-
baseURL: "%%source%%",
|
|
11431
|
-
requestHeaders: {
|
|
11432
|
-
"x-api-key": %%apiKey%%,
|
|
11433
|
-
},
|
|
11434
|
-
});
|
|
11435
|
-
|
|
11436
|
-
// Call HotUpdater.checkForUpdate({ updateStrategy: "appVersion" })
|
|
11437
|
-
// when your app is ready to check.
|
|
11438
|
-
export default App;`;
|
|
11439
11422
|
const deployWorker = async (apiToken, accountId, { credentialSource, d1DatabaseId, d1DatabaseName, nonInteractive, r2BucketName, workerName }) => {
|
|
11440
11423
|
const cwd = getCwd();
|
|
11441
11424
|
const cloudflarePackagePath = __require.resolve("@hot-updater/cloudflare/package.json", { paths: [cwd] });
|
|
@@ -11819,13 +11802,13 @@ const runInit = async ({ build, envFile }) => {
|
|
|
11819
11802
|
cloudflareApiToken: apiToken,
|
|
11820
11803
|
databaseId: selectedD1DatabaseId
|
|
11821
11804
|
});
|
|
11822
|
-
let
|
|
11805
|
+
let credential;
|
|
11823
11806
|
try {
|
|
11824
|
-
|
|
11825
|
-
|
|
11807
|
+
credential = await provisionClientCredential(database, plugins, {
|
|
11808
|
+
env: initInputEnv,
|
|
11826
11809
|
name: "Cloudflare init"
|
|
11827
|
-
})
|
|
11828
|
-
await makeEnv({
|
|
11810
|
+
});
|
|
11811
|
+
if (credential !== void 0) await makeEnv({ [credential.env]: credential.value });
|
|
11829
11812
|
} finally {
|
|
11830
11813
|
await database.dispose?.();
|
|
11831
11814
|
}
|
|
@@ -11835,12 +11818,11 @@ const runInit = async ({ build, envFile }) => {
|
|
|
11835
11818
|
else if (configWriteResult.status === "merged") p.log.success("Updated 'hot-updater.config.ts' file with Cloudflare settings.");
|
|
11836
11819
|
else p.log.warn(`Kept existing 'hot-updater.config.ts' unchanged: ${configWriteResult.reason}`);
|
|
11837
11820
|
await generateHotUpdaterPlugins("@hot-updater/cloudflare");
|
|
11838
|
-
|
|
11839
|
-
|
|
11840
|
-
|
|
11841
|
-
|
|
11842
|
-
|
|
11843
|
-
p.log.message("Store this API key separately in a secure place.");
|
|
11821
|
+
printAppSetup({
|
|
11822
|
+
...subdomains.subdomain ? { baseURL: `https://${workerName}.${subdomains.subdomain}.workers.dev` } : {},
|
|
11823
|
+
...credential === void 0 ? {} : { credential },
|
|
11824
|
+
clientPlugins: clientPluginsOf(plugins)
|
|
11825
|
+
});
|
|
11844
11826
|
p.log.message(`Next step: ${link("https://hot-updater.dev/docs/managed/cloudflare#step-4-add-hotupdater-to-your-project")}`);
|
|
11845
11827
|
p.log.success("Done! 🎉");
|
|
11846
11828
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -81,10 +81,10 @@ const createD1Database = (runner) => {
|
|
|
81
81
|
//#region src/d1Schema.ts
|
|
82
82
|
/**
|
|
83
83
|
* D1's schema: the guard table batch writes need, then the shared SQL
|
|
84
|
-
* schema, settings last. Every statement can
|
|
85
|
-
* server's plugin tables repeats
|
|
84
|
+
* schema of core and the target's plugins, settings last. Every statement can
|
|
85
|
+
* run again, so a migration for a server's plugin tables repeats core's.
|
|
86
86
|
*/
|
|
87
|
-
const d1SchemaStatements = ({ schema, settings } = _hot_updater_server_database.
|
|
87
|
+
const d1SchemaStatements = ({ schema, settings } = _hot_updater_server_database.coreTarget) => [...(0, _hot_updater_server_database.createTableStatements)("sqlite", [_hot_updater_server_database.WRITE_GUARD_TABLE]), ...(0, _hot_updater_server_db.generateEngineSql)("sqlite", schema, settings)];
|
|
88
88
|
/** The schema as a D1 migration, which `wrangler d1 migrations apply` runs. */
|
|
89
89
|
const d1SchemaSql = (target) => `-- HotUpdater.schema\n\n${d1SchemaStatements(target).map((statement) => `${statement};`).join("\n\n")}\n`;
|
|
90
90
|
//#endregion
|
|
@@ -123,8 +123,8 @@ const d1Database = (config) => {
|
|
|
123
123
|
query: async (statement) => (await execute([statement]))[0],
|
|
124
124
|
batch: execute
|
|
125
125
|
}),
|
|
126
|
-
generateSchema: ((version, _name, target = _hot_updater_server_database.
|
|
127
|
-
if (version !== "latest" && version !== _hot_updater_server_database.
|
|
126
|
+
generateSchema: ((version, _name, target = _hot_updater_server_database.coreTarget) => {
|
|
127
|
+
if (version !== "latest" && version !== _hot_updater_server_database.coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
|
|
128
128
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, "").slice(0, 14);
|
|
129
129
|
return {
|
|
130
130
|
code: d1SchemaSql(target),
|
package/dist/index.d.cts
CHANGED
|
@@ -171,12 +171,7 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
171
171
|
readonly received_at_ms: {
|
|
172
172
|
readonly type: "integer";
|
|
173
173
|
};
|
|
174
|
-
|
|
175
|
-
readonly type: "string";
|
|
176
|
-
readonly maxLength: 36;
|
|
177
|
-
readonly required: false;
|
|
178
|
-
};
|
|
179
|
-
}, {}, {
|
|
174
|
+
}, Readonly<Record<string, import("@hot-updater/server/database").FieldType>>, {
|
|
180
175
|
readonly byUser: {
|
|
181
176
|
readonly eq: readonly ["user_id"];
|
|
182
177
|
readonly sort: readonly ["install_id"];
|
|
@@ -190,7 +185,7 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
190
185
|
readonly bucket_start_ms: {
|
|
191
186
|
readonly type: "integer";
|
|
192
187
|
};
|
|
193
|
-
}, "downloads" | "launches" | "failed_launches", {
|
|
188
|
+
}, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
|
|
194
189
|
readonly window: {
|
|
195
190
|
readonly eq: readonly ["identity"];
|
|
196
191
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -209,7 +204,63 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
209
204
|
readonly eq: readonly ["identity"];
|
|
210
205
|
readonly sort: readonly ["bucket_start_ms"];
|
|
211
206
|
};
|
|
212
|
-
}, "launch_users" | "activity_users", readonly ["identity", "bucket_start_ms"]>;
|
|
207
|
+
}, "launch_users" | "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
208
|
+
readonly insights_overview_daily: import("@hot-updater/server/database").AggregateDefinition<{
|
|
209
|
+
readonly identity: {
|
|
210
|
+
readonly type: "string";
|
|
211
|
+
readonly maxLength: 32;
|
|
212
|
+
};
|
|
213
|
+
readonly bucket_start_ms: {
|
|
214
|
+
readonly type: "integer";
|
|
215
|
+
};
|
|
216
|
+
}, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
|
|
217
|
+
readonly window: {
|
|
218
|
+
readonly eq: readonly ["identity"];
|
|
219
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
220
|
+
};
|
|
221
|
+
}, never, readonly ["identity", "bucket_start_ms"]>;
|
|
222
|
+
readonly insights_sketches_daily: import("@hot-updater/server/database").AggregateDefinition<{
|
|
223
|
+
readonly identity: {
|
|
224
|
+
readonly type: "string";
|
|
225
|
+
readonly maxLength: 32;
|
|
226
|
+
};
|
|
227
|
+
readonly bucket_start_ms: {
|
|
228
|
+
readonly type: "integer";
|
|
229
|
+
};
|
|
230
|
+
}, never, {
|
|
231
|
+
readonly window: {
|
|
232
|
+
readonly eq: readonly ["identity"];
|
|
233
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
234
|
+
};
|
|
235
|
+
}, "launch_users" | "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
236
|
+
readonly insights_overview_lifetime: import("@hot-updater/server/database").AggregateDefinition<{
|
|
237
|
+
readonly identity: {
|
|
238
|
+
readonly type: "string";
|
|
239
|
+
readonly maxLength: 32;
|
|
240
|
+
};
|
|
241
|
+
readonly bucket_start_ms: {
|
|
242
|
+
readonly type: "integer";
|
|
243
|
+
};
|
|
244
|
+
}, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
|
|
245
|
+
readonly window: {
|
|
246
|
+
readonly eq: readonly ["identity"];
|
|
247
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
248
|
+
};
|
|
249
|
+
}, never, readonly ["identity", "bucket_start_ms"]>;
|
|
250
|
+
readonly insights_sketches_lifetime: import("@hot-updater/server/database").AggregateDefinition<{
|
|
251
|
+
readonly identity: {
|
|
252
|
+
readonly type: "string";
|
|
253
|
+
readonly maxLength: 32;
|
|
254
|
+
};
|
|
255
|
+
readonly bucket_start_ms: {
|
|
256
|
+
readonly type: "integer";
|
|
257
|
+
};
|
|
258
|
+
}, never, {
|
|
259
|
+
readonly window: {
|
|
260
|
+
readonly eq: readonly ["identity"];
|
|
261
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
262
|
+
};
|
|
263
|
+
}, "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
213
264
|
readonly insights_distribution: import("@hot-updater/server/database").AggregateDefinition<{
|
|
214
265
|
readonly channel: {
|
|
215
266
|
readonly type: "string";
|
|
@@ -292,22 +343,52 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
292
343
|
readonly sort: readonly ["bucket_start_ms"];
|
|
293
344
|
};
|
|
294
345
|
}, never, readonly ["platform", "channel", "type", "bundle_ref", "bucket_start_ms"]>;
|
|
346
|
+
readonly insights_failures: import("@hot-updater/server/database").AggregateDefinition<{
|
|
347
|
+
readonly platform: {
|
|
348
|
+
readonly type: "string";
|
|
349
|
+
readonly maxLength: 16;
|
|
350
|
+
};
|
|
351
|
+
readonly channel: {
|
|
352
|
+
readonly type: "string";
|
|
353
|
+
};
|
|
354
|
+
readonly bucket_start_ms: {
|
|
355
|
+
readonly type: "integer";
|
|
356
|
+
};
|
|
357
|
+
readonly release_id: {
|
|
358
|
+
readonly type: "string";
|
|
359
|
+
readonly maxLength: 36;
|
|
360
|
+
};
|
|
361
|
+
readonly stage: {
|
|
362
|
+
readonly type: "string";
|
|
363
|
+
readonly maxLength: 16;
|
|
364
|
+
};
|
|
365
|
+
readonly reason: {
|
|
366
|
+
readonly type: "string";
|
|
367
|
+
readonly maxLength: 64;
|
|
368
|
+
};
|
|
369
|
+
readonly detail: {
|
|
370
|
+
readonly type: "string";
|
|
371
|
+
readonly maxLength: 160;
|
|
372
|
+
};
|
|
373
|
+
}, "events", {
|
|
374
|
+
readonly byScope: {
|
|
375
|
+
readonly eq: readonly ["platform", "channel"];
|
|
376
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
377
|
+
};
|
|
378
|
+
}, never, readonly ["platform", "channel", "bucket_start_ms", "release_id", "stage", "reason", "detail"]>;
|
|
295
379
|
}, {
|
|
296
380
|
api: {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
381
|
+
retention: import("@hot-updater/server/plugins/insights").InsightsRetention;
|
|
382
|
+
recordEvent: (event: import("@hot-updater/server/plugins/insights").BundleEventRow) => Promise<void>;
|
|
383
|
+
listEvents: (input: import("@hot-updater/server/plugins/insights").InsightsListEventsInput) => Promise<readonly import("@hot-updater/server/plugins/insights").BundleEventRow[]>;
|
|
384
|
+
findLatestEvents: (input: import("@hot-updater/server/plugins/insights").InsightsFindLatestEventsInput) => Promise<readonly import("@hot-updater/server/plugins/insights").BundleEventRow[]>;
|
|
385
|
+
countLatestEvents: (input: import("@hot-updater/server/plugins/insights").InsightsCountLatestEventsInput) => Promise<number>;
|
|
386
|
+
countEvents: (input: import("@hot-updater/server/plugins/insights").InsightsCountEventsInput) => Promise<number>;
|
|
387
|
+
getReleaseActivity: (input: import("@hot-updater/server/plugins/insights").InsightsGetReleaseActivityInput) => Promise<import("@hot-updater/server/plugins/insights").InsightsGetReleaseActivityResult>;
|
|
388
|
+
getAppUsage: (input: import("@hot-updater/server/plugins/insights").InsightsGetAppUsageInput) => Promise<import("@hot-updater/server/plugins/insights").InsightsGetAppUsageResult>;
|
|
389
|
+
getUpdateFailures: (input: import("@hot-updater/server/plugins/insights").InsightsUpdateFailuresInput) => Promise<import("@hot-updater/server/plugins/insights").InsightsUpdateFailures>;
|
|
304
390
|
};
|
|
305
|
-
endpoints:
|
|
306
|
-
access: "client" | "admin";
|
|
307
|
-
method: "POST" | "GET";
|
|
308
|
-
path: "/events" | "/overview" | "/installations" | "/installations/:installId/events" | "/installations/:installId";
|
|
309
|
-
handler: (request: Request, params: Readonly<Record<string, string>>) => Promise<Response>;
|
|
310
|
-
}[];
|
|
391
|
+
endpoints: import("@hot-updater/server/plugins").PluginEndpoint[];
|
|
311
392
|
}, {}>, import("@hot-updater/server/plugins").HotUpdaterPlugin<"apiKeys", {
|
|
312
393
|
readonly api_keys: import("@hot-updater/server/database").TableDefinition<{
|
|
313
394
|
readonly id: {
|
|
@@ -350,21 +431,21 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
350
431
|
readonly apiKey: string;
|
|
351
432
|
readonly name: string;
|
|
352
433
|
readonly createdAtMs?: number;
|
|
353
|
-
}) => Promise<import("@hot-updater/server").CreatedApiKey>;
|
|
434
|
+
}) => Promise<import("@hot-updater/server/plugins/api-keys").CreatedApiKey>;
|
|
354
435
|
provision: (input: {
|
|
355
436
|
readonly existingApiKey?: string;
|
|
356
437
|
readonly name: string;
|
|
357
|
-
}) => Promise<import("@hot-updater/server").CreatedApiKey>;
|
|
438
|
+
}) => Promise<import("@hot-updater/server/plugins/api-keys").CreatedApiKey>;
|
|
358
439
|
create(input: {
|
|
359
440
|
readonly name: string;
|
|
360
441
|
}): Promise<{
|
|
361
442
|
readonly apiKey: string;
|
|
362
|
-
readonly record: import("@hot-updater/server").ApiKeyMetadata;
|
|
443
|
+
readonly record: import("@hot-updater/server/plugins/api-keys").ApiKeyMetadata;
|
|
363
444
|
}>;
|
|
364
|
-
list(): Promise<readonly import("@hot-updater/server").ApiKeyMetadata[]>;
|
|
445
|
+
list(): Promise<readonly import("@hot-updater/server/plugins/api-keys").ApiKeyMetadata[]>;
|
|
365
446
|
revoke(input: {
|
|
366
447
|
readonly id: string;
|
|
367
|
-
}): Promise<import("@hot-updater/server").ApiKeyMetadata | null>;
|
|
448
|
+
}): Promise<import("@hot-updater/server/plugins/api-keys").ApiKeyMetadata | null>;
|
|
368
449
|
};
|
|
369
450
|
clientAuth: {
|
|
370
451
|
varyHeaders: string[];
|
package/dist/index.d.mts
CHANGED
|
@@ -171,12 +171,7 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
171
171
|
readonly received_at_ms: {
|
|
172
172
|
readonly type: "integer";
|
|
173
173
|
};
|
|
174
|
-
|
|
175
|
-
readonly type: "string";
|
|
176
|
-
readonly maxLength: 36;
|
|
177
|
-
readonly required: false;
|
|
178
|
-
};
|
|
179
|
-
}, {}, {
|
|
174
|
+
}, Readonly<Record<string, import("@hot-updater/server/database").FieldType>>, {
|
|
180
175
|
readonly byUser: {
|
|
181
176
|
readonly eq: readonly ["user_id"];
|
|
182
177
|
readonly sort: readonly ["install_id"];
|
|
@@ -190,7 +185,7 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
190
185
|
readonly bucket_start_ms: {
|
|
191
186
|
readonly type: "integer";
|
|
192
187
|
};
|
|
193
|
-
}, "downloads" | "launches" | "failed_launches", {
|
|
188
|
+
}, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
|
|
194
189
|
readonly window: {
|
|
195
190
|
readonly eq: readonly ["identity"];
|
|
196
191
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -209,7 +204,63 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
209
204
|
readonly eq: readonly ["identity"];
|
|
210
205
|
readonly sort: readonly ["bucket_start_ms"];
|
|
211
206
|
};
|
|
212
|
-
}, "launch_users" | "activity_users", readonly ["identity", "bucket_start_ms"]>;
|
|
207
|
+
}, "launch_users" | "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
208
|
+
readonly insights_overview_daily: import("@hot-updater/server/database").AggregateDefinition<{
|
|
209
|
+
readonly identity: {
|
|
210
|
+
readonly type: "string";
|
|
211
|
+
readonly maxLength: 32;
|
|
212
|
+
};
|
|
213
|
+
readonly bucket_start_ms: {
|
|
214
|
+
readonly type: "integer";
|
|
215
|
+
};
|
|
216
|
+
}, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
|
|
217
|
+
readonly window: {
|
|
218
|
+
readonly eq: readonly ["identity"];
|
|
219
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
220
|
+
};
|
|
221
|
+
}, never, readonly ["identity", "bucket_start_ms"]>;
|
|
222
|
+
readonly insights_sketches_daily: import("@hot-updater/server/database").AggregateDefinition<{
|
|
223
|
+
readonly identity: {
|
|
224
|
+
readonly type: "string";
|
|
225
|
+
readonly maxLength: 32;
|
|
226
|
+
};
|
|
227
|
+
readonly bucket_start_ms: {
|
|
228
|
+
readonly type: "integer";
|
|
229
|
+
};
|
|
230
|
+
}, never, {
|
|
231
|
+
readonly window: {
|
|
232
|
+
readonly eq: readonly ["identity"];
|
|
233
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
234
|
+
};
|
|
235
|
+
}, "launch_users" | "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
236
|
+
readonly insights_overview_lifetime: import("@hot-updater/server/database").AggregateDefinition<{
|
|
237
|
+
readonly identity: {
|
|
238
|
+
readonly type: "string";
|
|
239
|
+
readonly maxLength: 32;
|
|
240
|
+
};
|
|
241
|
+
readonly bucket_start_ms: {
|
|
242
|
+
readonly type: "integer";
|
|
243
|
+
};
|
|
244
|
+
}, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
|
|
245
|
+
readonly window: {
|
|
246
|
+
readonly eq: readonly ["identity"];
|
|
247
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
248
|
+
};
|
|
249
|
+
}, never, readonly ["identity", "bucket_start_ms"]>;
|
|
250
|
+
readonly insights_sketches_lifetime: import("@hot-updater/server/database").AggregateDefinition<{
|
|
251
|
+
readonly identity: {
|
|
252
|
+
readonly type: "string";
|
|
253
|
+
readonly maxLength: 32;
|
|
254
|
+
};
|
|
255
|
+
readonly bucket_start_ms: {
|
|
256
|
+
readonly type: "integer";
|
|
257
|
+
};
|
|
258
|
+
}, never, {
|
|
259
|
+
readonly window: {
|
|
260
|
+
readonly eq: readonly ["identity"];
|
|
261
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
262
|
+
};
|
|
263
|
+
}, "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
213
264
|
readonly insights_distribution: import("@hot-updater/server/database").AggregateDefinition<{
|
|
214
265
|
readonly channel: {
|
|
215
266
|
readonly type: "string";
|
|
@@ -292,22 +343,52 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
292
343
|
readonly sort: readonly ["bucket_start_ms"];
|
|
293
344
|
};
|
|
294
345
|
}, never, readonly ["platform", "channel", "type", "bundle_ref", "bucket_start_ms"]>;
|
|
346
|
+
readonly insights_failures: import("@hot-updater/server/database").AggregateDefinition<{
|
|
347
|
+
readonly platform: {
|
|
348
|
+
readonly type: "string";
|
|
349
|
+
readonly maxLength: 16;
|
|
350
|
+
};
|
|
351
|
+
readonly channel: {
|
|
352
|
+
readonly type: "string";
|
|
353
|
+
};
|
|
354
|
+
readonly bucket_start_ms: {
|
|
355
|
+
readonly type: "integer";
|
|
356
|
+
};
|
|
357
|
+
readonly release_id: {
|
|
358
|
+
readonly type: "string";
|
|
359
|
+
readonly maxLength: 36;
|
|
360
|
+
};
|
|
361
|
+
readonly stage: {
|
|
362
|
+
readonly type: "string";
|
|
363
|
+
readonly maxLength: 16;
|
|
364
|
+
};
|
|
365
|
+
readonly reason: {
|
|
366
|
+
readonly type: "string";
|
|
367
|
+
readonly maxLength: 64;
|
|
368
|
+
};
|
|
369
|
+
readonly detail: {
|
|
370
|
+
readonly type: "string";
|
|
371
|
+
readonly maxLength: 160;
|
|
372
|
+
};
|
|
373
|
+
}, "events", {
|
|
374
|
+
readonly byScope: {
|
|
375
|
+
readonly eq: readonly ["platform", "channel"];
|
|
376
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
377
|
+
};
|
|
378
|
+
}, never, readonly ["platform", "channel", "bucket_start_ms", "release_id", "stage", "reason", "detail"]>;
|
|
295
379
|
}, {
|
|
296
380
|
api: {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
381
|
+
retention: import("@hot-updater/server/plugins/insights").InsightsRetention;
|
|
382
|
+
recordEvent: (event: import("@hot-updater/server/plugins/insights").BundleEventRow) => Promise<void>;
|
|
383
|
+
listEvents: (input: import("@hot-updater/server/plugins/insights").InsightsListEventsInput) => Promise<readonly import("@hot-updater/server/plugins/insights").BundleEventRow[]>;
|
|
384
|
+
findLatestEvents: (input: import("@hot-updater/server/plugins/insights").InsightsFindLatestEventsInput) => Promise<readonly import("@hot-updater/server/plugins/insights").BundleEventRow[]>;
|
|
385
|
+
countLatestEvents: (input: import("@hot-updater/server/plugins/insights").InsightsCountLatestEventsInput) => Promise<number>;
|
|
386
|
+
countEvents: (input: import("@hot-updater/server/plugins/insights").InsightsCountEventsInput) => Promise<number>;
|
|
387
|
+
getReleaseActivity: (input: import("@hot-updater/server/plugins/insights").InsightsGetReleaseActivityInput) => Promise<import("@hot-updater/server/plugins/insights").InsightsGetReleaseActivityResult>;
|
|
388
|
+
getAppUsage: (input: import("@hot-updater/server/plugins/insights").InsightsGetAppUsageInput) => Promise<import("@hot-updater/server/plugins/insights").InsightsGetAppUsageResult>;
|
|
389
|
+
getUpdateFailures: (input: import("@hot-updater/server/plugins/insights").InsightsUpdateFailuresInput) => Promise<import("@hot-updater/server/plugins/insights").InsightsUpdateFailures>;
|
|
304
390
|
};
|
|
305
|
-
endpoints:
|
|
306
|
-
access: "client" | "admin";
|
|
307
|
-
method: "POST" | "GET";
|
|
308
|
-
path: "/events" | "/overview" | "/installations" | "/installations/:installId/events" | "/installations/:installId";
|
|
309
|
-
handler: (request: Request, params: Readonly<Record<string, string>>) => Promise<Response>;
|
|
310
|
-
}[];
|
|
391
|
+
endpoints: import("@hot-updater/server/plugins").PluginEndpoint[];
|
|
311
392
|
}, {}>, import("@hot-updater/server/plugins").HotUpdaterPlugin<"apiKeys", {
|
|
312
393
|
readonly api_keys: import("@hot-updater/server/database").TableDefinition<{
|
|
313
394
|
readonly id: {
|
|
@@ -350,21 +431,21 @@ declare const plugins: readonly [import("@hot-updater/server/plugins").HotUpdate
|
|
|
350
431
|
readonly apiKey: string;
|
|
351
432
|
readonly name: string;
|
|
352
433
|
readonly createdAtMs?: number;
|
|
353
|
-
}) => Promise<import("@hot-updater/server").CreatedApiKey>;
|
|
434
|
+
}) => Promise<import("@hot-updater/server/plugins/api-keys").CreatedApiKey>;
|
|
354
435
|
provision: (input: {
|
|
355
436
|
readonly existingApiKey?: string;
|
|
356
437
|
readonly name: string;
|
|
357
|
-
}) => Promise<import("@hot-updater/server").CreatedApiKey>;
|
|
438
|
+
}) => Promise<import("@hot-updater/server/plugins/api-keys").CreatedApiKey>;
|
|
358
439
|
create(input: {
|
|
359
440
|
readonly name: string;
|
|
360
441
|
}): Promise<{
|
|
361
442
|
readonly apiKey: string;
|
|
362
|
-
readonly record: import("@hot-updater/server").ApiKeyMetadata;
|
|
443
|
+
readonly record: import("@hot-updater/server/plugins/api-keys").ApiKeyMetadata;
|
|
363
444
|
}>;
|
|
364
|
-
list(): Promise<readonly import("@hot-updater/server").ApiKeyMetadata[]>;
|
|
445
|
+
list(): Promise<readonly import("@hot-updater/server/plugins/api-keys").ApiKeyMetadata[]>;
|
|
365
446
|
revoke(input: {
|
|
366
447
|
readonly id: string;
|
|
367
|
-
}): Promise<import("@hot-updater/server").ApiKeyMetadata | null>;
|
|
448
|
+
}): Promise<import("@hot-updater/server/plugins/api-keys").ApiKeyMetadata | null>;
|
|
368
449
|
};
|
|
369
450
|
clientAuth: {
|
|
370
451
|
varyHeaders: string[];
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WRITE_GUARD_TABLE,
|
|
1
|
+
import { WRITE_GUARD_TABLE, coreSettings, coreTarget, createEngineDatabase, createSqlAdapter, createTableStatements } from "@hot-updater/server/database";
|
|
2
2
|
import Cloudflare from "cloudflare";
|
|
3
3
|
import { generateEngineSql } from "@hot-updater/server/db";
|
|
4
4
|
import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
@@ -57,10 +57,10 @@ const createD1Database = (runner) => {
|
|
|
57
57
|
//#region src/d1Schema.ts
|
|
58
58
|
/**
|
|
59
59
|
* D1's schema: the guard table batch writes need, then the shared SQL
|
|
60
|
-
* schema, settings last. Every statement can
|
|
61
|
-
* server's plugin tables repeats
|
|
60
|
+
* schema of core and the target's plugins, settings last. Every statement can
|
|
61
|
+
* run again, so a migration for a server's plugin tables repeats core's.
|
|
62
62
|
*/
|
|
63
|
-
const d1SchemaStatements = ({ schema, settings } =
|
|
63
|
+
const d1SchemaStatements = ({ schema, settings } = coreTarget) => [...createTableStatements("sqlite", [WRITE_GUARD_TABLE]), ...generateEngineSql("sqlite", schema, settings)];
|
|
64
64
|
/** The schema as a D1 migration, which `wrangler d1 migrations apply` runs. */
|
|
65
65
|
const d1SchemaSql = (target) => `-- HotUpdater.schema\n\n${d1SchemaStatements(target).map((statement) => `${statement};`).join("\n\n")}\n`;
|
|
66
66
|
//#endregion
|
|
@@ -99,8 +99,8 @@ const d1Database = (config) => {
|
|
|
99
99
|
query: async (statement) => (await execute([statement]))[0],
|
|
100
100
|
batch: execute
|
|
101
101
|
}),
|
|
102
|
-
generateSchema: ((version, _name, target =
|
|
103
|
-
if (version !== "latest" && version !==
|
|
102
|
+
generateSchema: ((version, _name, target = coreTarget) => {
|
|
103
|
+
if (version !== "latest" && version !== coreSettings["schema.core"]) throw new Error(`Invalid version ${version}`);
|
|
104
104
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, "").slice(0, 14);
|
|
105
105
|
return {
|
|
106
106
|
code: d1SchemaSql(target),
|