@hot-updater/cloudflare 1.0.0-rc.2 → 1.0.0-rc.4
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 +284 -162
- package/dist/iac/index.d.cts +1 -5
- package/dist/iac/index.d.mts +1 -5
- package/dist/iac/index.mjs +280 -158
- package/dist/index.cjs +69 -14
- package/dist/index.d.cts +1 -3
- package/dist/index.d.mts +1 -3
- package/dist/index.mjs +67 -12
- package/dist/worker/index.cjs +71 -15
- package/dist/worker/index.d.cts +2 -3
- package/dist/worker/index.d.mts +2 -3
- package/dist/worker/index.mjs +71 -15
- package/package.json +7 -7
- package/sql/bundles.sql +29 -7
- package/src/d1Database.spec.ts +99 -0
- package/src/d1Database.ts +7 -1
- package/src/d1Implementation.spec.ts +90 -0
- package/src/d1Implementation.ts +42 -3
- package/src/d1Query.ts +3 -0
- package/src/d1Rows.spec.ts +32 -0
- package/src/d1Rows.ts +35 -0
- package/src/worker/d1Database.spec.ts +36 -0
- package/src/worker/d1Database.ts +9 -1
- package/worker/dist/README.md +1 -1
- package/worker/dist/index.js +997 -659
- package/worker/dist/index.js.map +4 -4
- package/worker/migrations/0001_hot-updater_1.0.0.sql +30 -13
- package/worker/src/databaseMigration.integration.spec.ts +62 -1
- package/worker/src/databasePlugins.integration.spec.ts +35 -1
- package/worker/src/insightsMovement.integration.spec.ts +73 -0
package/dist/index.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
}
|
|
17
17
|
return to;
|
|
18
18
|
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
20
|
value: mod,
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
25
25
|
let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
|
|
26
26
|
let cloudflare = require("cloudflare");
|
|
27
|
-
cloudflare = __toESM(cloudflare);
|
|
27
|
+
cloudflare = __toESM(cloudflare, 1);
|
|
28
28
|
let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
|
|
29
29
|
let _aws_sdk_lib_storage = require("@aws-sdk/lib-storage");
|
|
30
30
|
//#region src/d1Rows.ts
|
|
@@ -134,6 +134,29 @@ const eventRow = (row) => {
|
|
|
134
134
|
received_at_ms: numberValue(row, "received_at_ms", "bundle_events")
|
|
135
135
|
};
|
|
136
136
|
};
|
|
137
|
+
const installationRow = (row) => {
|
|
138
|
+
const type = stringValue(row, "type", "bundle_installations");
|
|
139
|
+
const platform = stringValue(row, "platform", "bundle_installations");
|
|
140
|
+
if (![
|
|
141
|
+
"UPDATE_APPLIED",
|
|
142
|
+
"RECOVERED",
|
|
143
|
+
"RELEASE_ADOPTED",
|
|
144
|
+
"UNCHANGED"
|
|
145
|
+
].includes(type) || platform !== "ios" && platform !== "android") throw new InvalidD1RowError("bundle_installations");
|
|
146
|
+
return {
|
|
147
|
+
id: stringValue(row, "id", "bundle_installations"),
|
|
148
|
+
install_id: stringValue(row, "install_id", "bundle_installations"),
|
|
149
|
+
user_id: nullableString(row, "user_id", "bundle_installations"),
|
|
150
|
+
username: nullableString(row, "username", "bundle_installations"),
|
|
151
|
+
to_bundle_id: stringValue(row, "to_bundle_id", "bundle_installations"),
|
|
152
|
+
type,
|
|
153
|
+
platform,
|
|
154
|
+
app_version: stringValue(row, "app_version", "bundle_installations"),
|
|
155
|
+
channel: stringValue(row, "channel", "bundle_installations"),
|
|
156
|
+
cohort: stringValue(row, "cohort", "bundle_installations"),
|
|
157
|
+
received_at_ms: numberValue(row, "received_at_ms", "bundle_installations")
|
|
158
|
+
};
|
|
159
|
+
};
|
|
137
160
|
const apiKeyRow = (row) => {
|
|
138
161
|
const role = stringValue(row, "role", "api_keys");
|
|
139
162
|
if (role !== "client") throw new InvalidD1RowError("api_keys");
|
|
@@ -208,6 +231,7 @@ function parseD1Row(model, value) {
|
|
|
208
231
|
case "bundle_patches": return patchRow(value);
|
|
209
232
|
case "channels": return channelRow(value);
|
|
210
233
|
case "bundle_events": return eventRow(value);
|
|
234
|
+
case "bundle_installations": return installationRow(value);
|
|
211
235
|
case "api_keys": return apiKeyRow(value);
|
|
212
236
|
case "releases": return releaseRow(value);
|
|
213
237
|
case "release_catalogs": return releaseCatalogRow(value);
|
|
@@ -244,7 +268,8 @@ const stringPredicate = (condition, operator) => {
|
|
|
244
268
|
};
|
|
245
269
|
}
|
|
246
270
|
const literal = escapeLikePattern(condition.value);
|
|
247
|
-
const
|
|
271
|
+
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
272
|
+
const parameter = bind(pattern);
|
|
248
273
|
return {
|
|
249
274
|
sql: `lower(${condition.field}) LIKE lower(${parameter.sql}) ESCAPE '\\'`,
|
|
250
275
|
params: parameter.params
|
|
@@ -329,11 +354,13 @@ const d1TableNames = {
|
|
|
329
354
|
bundle_patches: "bundle_patches",
|
|
330
355
|
channels: "channels",
|
|
331
356
|
bundle_events: "bundle_events",
|
|
357
|
+
bundle_installations: "bundle_installations",
|
|
332
358
|
api_keys: "api_keys",
|
|
333
359
|
release_catalogs: "release_catalogs",
|
|
334
360
|
releases: "releases"
|
|
335
361
|
};
|
|
336
362
|
var D1QueryResultError = class extends Error {
|
|
363
|
+
result;
|
|
337
364
|
name = "D1QueryResultError";
|
|
338
365
|
operation = "count";
|
|
339
366
|
constructor(result) {
|
|
@@ -364,6 +391,7 @@ const findManyD1Rows = async (executor, input) => {
|
|
|
364
391
|
case "bundle_patches": return rows.map((row) => parseD1Row("bundle_patches", row));
|
|
365
392
|
case "channels": return rows.map((row) => parseD1Row("channels", row));
|
|
366
393
|
case "bundle_events": return rows.map((row) => parseD1Row("bundle_events", row));
|
|
394
|
+
case "bundle_installations": return rows.map((row) => parseD1Row("bundle_installations", row));
|
|
367
395
|
case "api_keys": return rows.map((row) => parseD1Row("api_keys", row));
|
|
368
396
|
case "releases": return rows.map((row) => parseD1Row("releases", row));
|
|
369
397
|
case "release_catalogs": return rows.map((row) => parseD1Row("release_catalogs", row));
|
|
@@ -371,6 +399,12 @@ const findManyD1Rows = async (executor, input) => {
|
|
|
371
399
|
};
|
|
372
400
|
//#endregion
|
|
373
401
|
//#region src/d1Implementation.ts
|
|
402
|
+
var D1ExecutionError = class extends Error {
|
|
403
|
+
name = "D1ExecutionError";
|
|
404
|
+
constructor() {
|
|
405
|
+
super("D1 did not successfully execute every requested statement");
|
|
406
|
+
}
|
|
407
|
+
};
|
|
374
408
|
const EXPECTATION_CONFLICT_MARKER = "HOT_UPDATER_COMMIT_EXPECTATION_CONFLICT";
|
|
375
409
|
const expectationGuard = (expectations) => {
|
|
376
410
|
const clauses = [];
|
|
@@ -408,7 +442,8 @@ const expectationConflict = async (executor, expectations) => {
|
|
|
408
442
|
const versionField = isRelease ? "revision" : "generation";
|
|
409
443
|
const key = isRelease ? expectation.id : expectation.scopeKey;
|
|
410
444
|
const expectedVersion = isRelease ? expectation.revision : expectation.generation;
|
|
411
|
-
const
|
|
445
|
+
const rows = await executor.query(`SELECT ${versionField} FROM ${table} WHERE ${keyField} = json_extract(?, '$') LIMIT 1`, encodeD1Values([key]));
|
|
446
|
+
const actualVersion = readVersion(rows[0], versionField);
|
|
412
447
|
if (actualVersion !== expectedVersion) return {
|
|
413
448
|
committed: false,
|
|
414
449
|
conflict: {
|
|
@@ -487,14 +522,14 @@ const insertQuery = (input, guard, conflictMode = "returnExisting") => {
|
|
|
487
522
|
values = channelValues(input.data);
|
|
488
523
|
break;
|
|
489
524
|
case "bundle_events":
|
|
525
|
+
case "bundle_installations":
|
|
490
526
|
case "api_keys":
|
|
491
527
|
case "release_catalogs":
|
|
492
528
|
case "releases":
|
|
493
529
|
columns = Object.keys(input.data);
|
|
494
530
|
values = Object.values(input.data);
|
|
495
|
-
break;
|
|
496
531
|
}
|
|
497
|
-
const conflict = input.onConflict !== "ignore" ? "" : input.model === "channels" ? conflictMode === "ignore" ? " ON CONFLICT(name) DO NOTHING" : " ON CONFLICT(name) DO UPDATE SET name = excluded.name" : input.model === "api_keys" ? conflictMode === "ignore" ? " ON CONFLICT(hash) DO NOTHING" : " ON CONFLICT(hash) DO UPDATE SET hash = excluded.hash" : "";
|
|
532
|
+
const conflict = input.onConflict !== "ignore" ? "" : input.model === "channels" ? conflictMode === "ignore" ? " ON CONFLICT(name) DO NOTHING" : " ON CONFLICT(name) DO UPDATE SET name = excluded.name" : input.model === "api_keys" ? conflictMode === "ignore" ? " ON CONFLICT(hash) DO NOTHING" : " ON CONFLICT(hash) DO UPDATE SET hash = excluded.hash" : " ON CONFLICT(install_id) DO UPDATE SET install_id = excluded.install_id";
|
|
498
533
|
return {
|
|
499
534
|
sql: `INSERT INTO ${d1TableNames[input.model]} (${columns.join(", ")}) ${guard === void 0 ? `VALUES (${d1Placeholders(values.length)})` : `SELECT ${d1Placeholders(values.length)} WHERE ${guard.sql}`}${conflict} RETURNING *`,
|
|
500
535
|
params: [...encodeD1Values(values), ...guard?.params ?? []]
|
|
@@ -558,9 +593,7 @@ const channelDeletePrecondition = (changes, changeIndex, channelId) => {
|
|
|
558
593
|
releaseEffects.set(change.row.id, change.row.channel_id);
|
|
559
594
|
break;
|
|
560
595
|
case "update": break;
|
|
561
|
-
case "delete":
|
|
562
|
-
releaseEffects.set(change.where.id, null);
|
|
563
|
-
break;
|
|
596
|
+
case "delete": releaseEffects.set(change.where.id, null);
|
|
564
597
|
}
|
|
565
598
|
}
|
|
566
599
|
return {
|
|
@@ -635,10 +668,6 @@ const changeQuery = (change, guard) => {
|
|
|
635
668
|
sql: `DELETE FROM channels WHERE id = json_extract(?, '$') AND NOT EXISTS (SELECT 1 FROM releases WHERE channel_id = json_extract(?, '$')) AND ${guard.sql}`,
|
|
636
669
|
params: [...encodeD1Values([change.where.id, change.where.id]), ...guard.params]
|
|
637
670
|
};
|
|
638
|
-
case "insights": return insertQuery({
|
|
639
|
-
model: "bundle_events",
|
|
640
|
-
data: change.row
|
|
641
|
-
}, guard);
|
|
642
671
|
case "apiKeys": return change.operation === "insert" ? insertQuery({
|
|
643
672
|
model: "api_keys",
|
|
644
673
|
data: change.row,
|
|
@@ -807,6 +836,25 @@ const deleteChannel = async (executor, input) => {
|
|
|
807
836
|
};
|
|
808
837
|
};
|
|
809
838
|
const createD1Implementation = (executor) => ({
|
|
839
|
+
async recordInsights({ event, installation }) {
|
|
840
|
+
const columns = Object.keys(installation);
|
|
841
|
+
const eventInsert = insertQuery({
|
|
842
|
+
model: "bundle_events",
|
|
843
|
+
data: event
|
|
844
|
+
});
|
|
845
|
+
await executor.batch([{
|
|
846
|
+
sql: `INSERT INTO bundle_installations (${columns.join(", ")})
|
|
847
|
+
SELECT ${d1Placeholders(columns.length)}
|
|
848
|
+
WHERE NOT EXISTS (SELECT 1 FROM bundle_events WHERE id = json_extract(?, '$'))
|
|
849
|
+
ON CONFLICT(install_id) DO UPDATE SET ${columns.filter((column) => column !== "install_id").map((column) => `${column} = excluded.${column}`).join(", ")}
|
|
850
|
+
WHERE (excluded.received_at_ms, excluded.id) >
|
|
851
|
+
(bundle_installations.received_at_ms, bundle_installations.id)`,
|
|
852
|
+
params: encodeD1Values([...Object.values(installation), event.id])
|
|
853
|
+
}, {
|
|
854
|
+
...eventInsert,
|
|
855
|
+
sql: eventInsert.sql.replace(" RETURNING *", " ON CONFLICT(id) DO NOTHING")
|
|
856
|
+
}]);
|
|
857
|
+
},
|
|
810
858
|
async create(input) {
|
|
811
859
|
const query = insertQuery(input);
|
|
812
860
|
const rows = await executor.query(query.sql, query.params);
|
|
@@ -815,6 +863,7 @@ const createD1Implementation = (executor) => ({
|
|
|
815
863
|
case "bundle_patches": return parseD1Row("bundle_patches", rows[0]);
|
|
816
864
|
case "channels": return parseD1Row("channels", rows[0]);
|
|
817
865
|
case "bundle_events": return parseD1Row("bundle_events", rows[0]);
|
|
866
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
818
867
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
819
868
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
820
869
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
@@ -829,6 +878,7 @@ const createD1Implementation = (executor) => ({
|
|
|
829
878
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
830
879
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
831
880
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
881
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
832
882
|
}
|
|
833
883
|
},
|
|
834
884
|
async delete(input) {
|
|
@@ -847,6 +897,7 @@ const createD1Implementation = (executor) => ({
|
|
|
847
897
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
848
898
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
849
899
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
900
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
850
901
|
}
|
|
851
902
|
},
|
|
852
903
|
findMany: (input) => findManyD1Rows(executor, input),
|
|
@@ -896,7 +947,11 @@ const d1Database = (config) => {
|
|
|
896
947
|
};
|
|
897
948
|
const page = await cloudflare$1.d1.database.query(config.databaseId, { ...body });
|
|
898
949
|
const results = [];
|
|
899
|
-
for await (const resultPage of page.iterPages()) for (const result of resultPage.result)
|
|
950
|
+
for await (const resultPage of page.iterPages()) for (const result of resultPage.result) {
|
|
951
|
+
if (result.success === false) throw new D1ExecutionError();
|
|
952
|
+
results.push(result.results ?? []);
|
|
953
|
+
}
|
|
954
|
+
if (results.length !== statements.length) throw new D1ExecutionError();
|
|
900
955
|
return results;
|
|
901
956
|
};
|
|
902
957
|
const adapter = (0, _hot_updater_plugin_core_internal.createDatabasePluginAdapter)("d1Database", createD1Implementation({
|
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import * as _$_hot_updater_plugin_core0 from "@hot-updater/plugin-core";
|
|
2
1
|
import { StoragePluginWith } from "@hot-updater/plugin-core";
|
|
3
2
|
import { S3ClientConfig } from "@aws-sdk/client-s3";
|
|
4
|
-
|
|
5
3
|
//#region src/d1Database.d.ts
|
|
6
4
|
interface D1DatabaseConfig {
|
|
7
5
|
readonly databaseId: string;
|
|
8
6
|
readonly accountId: string;
|
|
9
7
|
readonly cloudflareApiToken: string;
|
|
10
8
|
}
|
|
11
|
-
declare const d1Database: (config: D1DatabaseConfig) =>
|
|
9
|
+
declare const d1Database: (config: D1DatabaseConfig) => import("@hot-updater/plugin-core").DatabasePlugin;
|
|
12
10
|
//#endregion
|
|
13
11
|
//#region src/r2S3Storage.d.ts
|
|
14
12
|
interface R2S3StorageConfig extends S3ClientConfig {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import * as _$_hot_updater_plugin_core0 from "@hot-updater/plugin-core";
|
|
2
1
|
import { StoragePluginWith } from "@hot-updater/plugin-core";
|
|
3
2
|
import { S3ClientConfig } from "@aws-sdk/client-s3";
|
|
4
|
-
|
|
5
3
|
//#region src/d1Database.d.ts
|
|
6
4
|
interface D1DatabaseConfig {
|
|
7
5
|
readonly databaseId: string;
|
|
8
6
|
readonly accountId: string;
|
|
9
7
|
readonly cloudflareApiToken: string;
|
|
10
8
|
}
|
|
11
|
-
declare const d1Database: (config: D1DatabaseConfig) =>
|
|
9
|
+
declare const d1Database: (config: D1DatabaseConfig) => import("@hot-updater/plugin-core").DatabasePlugin;
|
|
12
10
|
//#endregion
|
|
13
11
|
//#region src/r2S3Storage.d.ts
|
|
14
12
|
interface R2S3StorageConfig extends S3ClientConfig {
|
package/dist/index.mjs
CHANGED
|
@@ -110,6 +110,29 @@ const eventRow = (row) => {
|
|
|
110
110
|
received_at_ms: numberValue(row, "received_at_ms", "bundle_events")
|
|
111
111
|
};
|
|
112
112
|
};
|
|
113
|
+
const installationRow = (row) => {
|
|
114
|
+
const type = stringValue(row, "type", "bundle_installations");
|
|
115
|
+
const platform = stringValue(row, "platform", "bundle_installations");
|
|
116
|
+
if (![
|
|
117
|
+
"UPDATE_APPLIED",
|
|
118
|
+
"RECOVERED",
|
|
119
|
+
"RELEASE_ADOPTED",
|
|
120
|
+
"UNCHANGED"
|
|
121
|
+
].includes(type) || platform !== "ios" && platform !== "android") throw new InvalidD1RowError("bundle_installations");
|
|
122
|
+
return {
|
|
123
|
+
id: stringValue(row, "id", "bundle_installations"),
|
|
124
|
+
install_id: stringValue(row, "install_id", "bundle_installations"),
|
|
125
|
+
user_id: nullableString(row, "user_id", "bundle_installations"),
|
|
126
|
+
username: nullableString(row, "username", "bundle_installations"),
|
|
127
|
+
to_bundle_id: stringValue(row, "to_bundle_id", "bundle_installations"),
|
|
128
|
+
type,
|
|
129
|
+
platform,
|
|
130
|
+
app_version: stringValue(row, "app_version", "bundle_installations"),
|
|
131
|
+
channel: stringValue(row, "channel", "bundle_installations"),
|
|
132
|
+
cohort: stringValue(row, "cohort", "bundle_installations"),
|
|
133
|
+
received_at_ms: numberValue(row, "received_at_ms", "bundle_installations")
|
|
134
|
+
};
|
|
135
|
+
};
|
|
113
136
|
const apiKeyRow = (row) => {
|
|
114
137
|
const role = stringValue(row, "role", "api_keys");
|
|
115
138
|
if (role !== "client") throw new InvalidD1RowError("api_keys");
|
|
@@ -184,6 +207,7 @@ function parseD1Row(model, value) {
|
|
|
184
207
|
case "bundle_patches": return patchRow(value);
|
|
185
208
|
case "channels": return channelRow(value);
|
|
186
209
|
case "bundle_events": return eventRow(value);
|
|
210
|
+
case "bundle_installations": return installationRow(value);
|
|
187
211
|
case "api_keys": return apiKeyRow(value);
|
|
188
212
|
case "releases": return releaseRow(value);
|
|
189
213
|
case "release_catalogs": return releaseCatalogRow(value);
|
|
@@ -220,7 +244,8 @@ const stringPredicate = (condition, operator) => {
|
|
|
220
244
|
};
|
|
221
245
|
}
|
|
222
246
|
const literal = escapeLikePattern(condition.value);
|
|
223
|
-
const
|
|
247
|
+
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
248
|
+
const parameter = bind(pattern);
|
|
224
249
|
return {
|
|
225
250
|
sql: `lower(${condition.field}) LIKE lower(${parameter.sql}) ESCAPE '\\'`,
|
|
226
251
|
params: parameter.params
|
|
@@ -305,11 +330,13 @@ const d1TableNames = {
|
|
|
305
330
|
bundle_patches: "bundle_patches",
|
|
306
331
|
channels: "channels",
|
|
307
332
|
bundle_events: "bundle_events",
|
|
333
|
+
bundle_installations: "bundle_installations",
|
|
308
334
|
api_keys: "api_keys",
|
|
309
335
|
release_catalogs: "release_catalogs",
|
|
310
336
|
releases: "releases"
|
|
311
337
|
};
|
|
312
338
|
var D1QueryResultError = class extends Error {
|
|
339
|
+
result;
|
|
313
340
|
name = "D1QueryResultError";
|
|
314
341
|
operation = "count";
|
|
315
342
|
constructor(result) {
|
|
@@ -340,6 +367,7 @@ const findManyD1Rows = async (executor, input) => {
|
|
|
340
367
|
case "bundle_patches": return rows.map((row) => parseD1Row("bundle_patches", row));
|
|
341
368
|
case "channels": return rows.map((row) => parseD1Row("channels", row));
|
|
342
369
|
case "bundle_events": return rows.map((row) => parseD1Row("bundle_events", row));
|
|
370
|
+
case "bundle_installations": return rows.map((row) => parseD1Row("bundle_installations", row));
|
|
343
371
|
case "api_keys": return rows.map((row) => parseD1Row("api_keys", row));
|
|
344
372
|
case "releases": return rows.map((row) => parseD1Row("releases", row));
|
|
345
373
|
case "release_catalogs": return rows.map((row) => parseD1Row("release_catalogs", row));
|
|
@@ -347,6 +375,12 @@ const findManyD1Rows = async (executor, input) => {
|
|
|
347
375
|
};
|
|
348
376
|
//#endregion
|
|
349
377
|
//#region src/d1Implementation.ts
|
|
378
|
+
var D1ExecutionError = class extends Error {
|
|
379
|
+
name = "D1ExecutionError";
|
|
380
|
+
constructor() {
|
|
381
|
+
super("D1 did not successfully execute every requested statement");
|
|
382
|
+
}
|
|
383
|
+
};
|
|
350
384
|
const EXPECTATION_CONFLICT_MARKER = "HOT_UPDATER_COMMIT_EXPECTATION_CONFLICT";
|
|
351
385
|
const expectationGuard = (expectations) => {
|
|
352
386
|
const clauses = [];
|
|
@@ -384,7 +418,8 @@ const expectationConflict = async (executor, expectations) => {
|
|
|
384
418
|
const versionField = isRelease ? "revision" : "generation";
|
|
385
419
|
const key = isRelease ? expectation.id : expectation.scopeKey;
|
|
386
420
|
const expectedVersion = isRelease ? expectation.revision : expectation.generation;
|
|
387
|
-
const
|
|
421
|
+
const rows = await executor.query(`SELECT ${versionField} FROM ${table} WHERE ${keyField} = json_extract(?, '$') LIMIT 1`, encodeD1Values([key]));
|
|
422
|
+
const actualVersion = readVersion(rows[0], versionField);
|
|
388
423
|
if (actualVersion !== expectedVersion) return {
|
|
389
424
|
committed: false,
|
|
390
425
|
conflict: {
|
|
@@ -463,14 +498,14 @@ const insertQuery = (input, guard, conflictMode = "returnExisting") => {
|
|
|
463
498
|
values = channelValues(input.data);
|
|
464
499
|
break;
|
|
465
500
|
case "bundle_events":
|
|
501
|
+
case "bundle_installations":
|
|
466
502
|
case "api_keys":
|
|
467
503
|
case "release_catalogs":
|
|
468
504
|
case "releases":
|
|
469
505
|
columns = Object.keys(input.data);
|
|
470
506
|
values = Object.values(input.data);
|
|
471
|
-
break;
|
|
472
507
|
}
|
|
473
|
-
const conflict = input.onConflict !== "ignore" ? "" : input.model === "channels" ? conflictMode === "ignore" ? " ON CONFLICT(name) DO NOTHING" : " ON CONFLICT(name) DO UPDATE SET name = excluded.name" : input.model === "api_keys" ? conflictMode === "ignore" ? " ON CONFLICT(hash) DO NOTHING" : " ON CONFLICT(hash) DO UPDATE SET hash = excluded.hash" : "";
|
|
508
|
+
const conflict = input.onConflict !== "ignore" ? "" : input.model === "channels" ? conflictMode === "ignore" ? " ON CONFLICT(name) DO NOTHING" : " ON CONFLICT(name) DO UPDATE SET name = excluded.name" : input.model === "api_keys" ? conflictMode === "ignore" ? " ON CONFLICT(hash) DO NOTHING" : " ON CONFLICT(hash) DO UPDATE SET hash = excluded.hash" : " ON CONFLICT(install_id) DO UPDATE SET install_id = excluded.install_id";
|
|
474
509
|
return {
|
|
475
510
|
sql: `INSERT INTO ${d1TableNames[input.model]} (${columns.join(", ")}) ${guard === void 0 ? `VALUES (${d1Placeholders(values.length)})` : `SELECT ${d1Placeholders(values.length)} WHERE ${guard.sql}`}${conflict} RETURNING *`,
|
|
476
511
|
params: [...encodeD1Values(values), ...guard?.params ?? []]
|
|
@@ -534,9 +569,7 @@ const channelDeletePrecondition = (changes, changeIndex, channelId) => {
|
|
|
534
569
|
releaseEffects.set(change.row.id, change.row.channel_id);
|
|
535
570
|
break;
|
|
536
571
|
case "update": break;
|
|
537
|
-
case "delete":
|
|
538
|
-
releaseEffects.set(change.where.id, null);
|
|
539
|
-
break;
|
|
572
|
+
case "delete": releaseEffects.set(change.where.id, null);
|
|
540
573
|
}
|
|
541
574
|
}
|
|
542
575
|
return {
|
|
@@ -611,10 +644,6 @@ const changeQuery = (change, guard) => {
|
|
|
611
644
|
sql: `DELETE FROM channels WHERE id = json_extract(?, '$') AND NOT EXISTS (SELECT 1 FROM releases WHERE channel_id = json_extract(?, '$')) AND ${guard.sql}`,
|
|
612
645
|
params: [...encodeD1Values([change.where.id, change.where.id]), ...guard.params]
|
|
613
646
|
};
|
|
614
|
-
case "insights": return insertQuery({
|
|
615
|
-
model: "bundle_events",
|
|
616
|
-
data: change.row
|
|
617
|
-
}, guard);
|
|
618
647
|
case "apiKeys": return change.operation === "insert" ? insertQuery({
|
|
619
648
|
model: "api_keys",
|
|
620
649
|
data: change.row,
|
|
@@ -783,6 +812,25 @@ const deleteChannel = async (executor, input) => {
|
|
|
783
812
|
};
|
|
784
813
|
};
|
|
785
814
|
const createD1Implementation = (executor) => ({
|
|
815
|
+
async recordInsights({ event, installation }) {
|
|
816
|
+
const columns = Object.keys(installation);
|
|
817
|
+
const eventInsert = insertQuery({
|
|
818
|
+
model: "bundle_events",
|
|
819
|
+
data: event
|
|
820
|
+
});
|
|
821
|
+
await executor.batch([{
|
|
822
|
+
sql: `INSERT INTO bundle_installations (${columns.join(", ")})
|
|
823
|
+
SELECT ${d1Placeholders(columns.length)}
|
|
824
|
+
WHERE NOT EXISTS (SELECT 1 FROM bundle_events WHERE id = json_extract(?, '$'))
|
|
825
|
+
ON CONFLICT(install_id) DO UPDATE SET ${columns.filter((column) => column !== "install_id").map((column) => `${column} = excluded.${column}`).join(", ")}
|
|
826
|
+
WHERE (excluded.received_at_ms, excluded.id) >
|
|
827
|
+
(bundle_installations.received_at_ms, bundle_installations.id)`,
|
|
828
|
+
params: encodeD1Values([...Object.values(installation), event.id])
|
|
829
|
+
}, {
|
|
830
|
+
...eventInsert,
|
|
831
|
+
sql: eventInsert.sql.replace(" RETURNING *", " ON CONFLICT(id) DO NOTHING")
|
|
832
|
+
}]);
|
|
833
|
+
},
|
|
786
834
|
async create(input) {
|
|
787
835
|
const query = insertQuery(input);
|
|
788
836
|
const rows = await executor.query(query.sql, query.params);
|
|
@@ -791,6 +839,7 @@ const createD1Implementation = (executor) => ({
|
|
|
791
839
|
case "bundle_patches": return parseD1Row("bundle_patches", rows[0]);
|
|
792
840
|
case "channels": return parseD1Row("channels", rows[0]);
|
|
793
841
|
case "bundle_events": return parseD1Row("bundle_events", rows[0]);
|
|
842
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
794
843
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
795
844
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
796
845
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
@@ -805,6 +854,7 @@ const createD1Implementation = (executor) => ({
|
|
|
805
854
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
806
855
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
807
856
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
857
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
808
858
|
}
|
|
809
859
|
},
|
|
810
860
|
async delete(input) {
|
|
@@ -823,6 +873,7 @@ const createD1Implementation = (executor) => ({
|
|
|
823
873
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
824
874
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
825
875
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
876
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
826
877
|
}
|
|
827
878
|
},
|
|
828
879
|
findMany: (input) => findManyD1Rows(executor, input),
|
|
@@ -872,7 +923,11 @@ const d1Database = (config) => {
|
|
|
872
923
|
};
|
|
873
924
|
const page = await cloudflare.d1.database.query(config.databaseId, { ...body });
|
|
874
925
|
const results = [];
|
|
875
|
-
for await (const resultPage of page.iterPages()) for (const result of resultPage.result)
|
|
926
|
+
for await (const resultPage of page.iterPages()) for (const result of resultPage.result) {
|
|
927
|
+
if (result.success === false) throw new D1ExecutionError();
|
|
928
|
+
results.push(result.results ?? []);
|
|
929
|
+
}
|
|
930
|
+
if (results.length !== statements.length) throw new D1ExecutionError();
|
|
876
931
|
return results;
|
|
877
932
|
};
|
|
878
933
|
const adapter = createDatabasePluginAdapter("d1Database", createD1Implementation({
|
package/dist/worker/index.cjs
CHANGED
|
@@ -108,6 +108,29 @@ const eventRow = (row) => {
|
|
|
108
108
|
received_at_ms: numberValue(row, "received_at_ms", "bundle_events")
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
|
+
const installationRow = (row) => {
|
|
112
|
+
const type = stringValue(row, "type", "bundle_installations");
|
|
113
|
+
const platform = stringValue(row, "platform", "bundle_installations");
|
|
114
|
+
if (![
|
|
115
|
+
"UPDATE_APPLIED",
|
|
116
|
+
"RECOVERED",
|
|
117
|
+
"RELEASE_ADOPTED",
|
|
118
|
+
"UNCHANGED"
|
|
119
|
+
].includes(type) || platform !== "ios" && platform !== "android") throw new InvalidD1RowError("bundle_installations");
|
|
120
|
+
return {
|
|
121
|
+
id: stringValue(row, "id", "bundle_installations"),
|
|
122
|
+
install_id: stringValue(row, "install_id", "bundle_installations"),
|
|
123
|
+
user_id: nullableString(row, "user_id", "bundle_installations"),
|
|
124
|
+
username: nullableString(row, "username", "bundle_installations"),
|
|
125
|
+
to_bundle_id: stringValue(row, "to_bundle_id", "bundle_installations"),
|
|
126
|
+
type,
|
|
127
|
+
platform,
|
|
128
|
+
app_version: stringValue(row, "app_version", "bundle_installations"),
|
|
129
|
+
channel: stringValue(row, "channel", "bundle_installations"),
|
|
130
|
+
cohort: stringValue(row, "cohort", "bundle_installations"),
|
|
131
|
+
received_at_ms: numberValue(row, "received_at_ms", "bundle_installations")
|
|
132
|
+
};
|
|
133
|
+
};
|
|
111
134
|
const apiKeyRow = (row) => {
|
|
112
135
|
const role = stringValue(row, "role", "api_keys");
|
|
113
136
|
if (role !== "client") throw new InvalidD1RowError("api_keys");
|
|
@@ -182,6 +205,7 @@ function parseD1Row(model, value) {
|
|
|
182
205
|
case "bundle_patches": return patchRow(value);
|
|
183
206
|
case "channels": return channelRow(value);
|
|
184
207
|
case "bundle_events": return eventRow(value);
|
|
208
|
+
case "bundle_installations": return installationRow(value);
|
|
185
209
|
case "api_keys": return apiKeyRow(value);
|
|
186
210
|
case "releases": return releaseRow(value);
|
|
187
211
|
case "release_catalogs": return releaseCatalogRow(value);
|
|
@@ -218,7 +242,8 @@ const stringPredicate = (condition, operator) => {
|
|
|
218
242
|
};
|
|
219
243
|
}
|
|
220
244
|
const literal = escapeLikePattern(condition.value);
|
|
221
|
-
const
|
|
245
|
+
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
246
|
+
const parameter = bind(pattern);
|
|
222
247
|
return {
|
|
223
248
|
sql: `lower(${condition.field}) LIKE lower(${parameter.sql}) ESCAPE '\\'`,
|
|
224
249
|
params: parameter.params
|
|
@@ -303,11 +328,13 @@ const d1TableNames = {
|
|
|
303
328
|
bundle_patches: "bundle_patches",
|
|
304
329
|
channels: "channels",
|
|
305
330
|
bundle_events: "bundle_events",
|
|
331
|
+
bundle_installations: "bundle_installations",
|
|
306
332
|
api_keys: "api_keys",
|
|
307
333
|
release_catalogs: "release_catalogs",
|
|
308
334
|
releases: "releases"
|
|
309
335
|
};
|
|
310
336
|
var D1QueryResultError = class extends Error {
|
|
337
|
+
result;
|
|
311
338
|
name = "D1QueryResultError";
|
|
312
339
|
operation = "count";
|
|
313
340
|
constructor(result) {
|
|
@@ -338,6 +365,7 @@ const findManyD1Rows = async (executor, input) => {
|
|
|
338
365
|
case "bundle_patches": return rows.map((row) => parseD1Row("bundle_patches", row));
|
|
339
366
|
case "channels": return rows.map((row) => parseD1Row("channels", row));
|
|
340
367
|
case "bundle_events": return rows.map((row) => parseD1Row("bundle_events", row));
|
|
368
|
+
case "bundle_installations": return rows.map((row) => parseD1Row("bundle_installations", row));
|
|
341
369
|
case "api_keys": return rows.map((row) => parseD1Row("api_keys", row));
|
|
342
370
|
case "releases": return rows.map((row) => parseD1Row("releases", row));
|
|
343
371
|
case "release_catalogs": return rows.map((row) => parseD1Row("release_catalogs", row));
|
|
@@ -345,6 +373,12 @@ const findManyD1Rows = async (executor, input) => {
|
|
|
345
373
|
};
|
|
346
374
|
//#endregion
|
|
347
375
|
//#region src/d1Implementation.ts
|
|
376
|
+
var D1ExecutionError = class extends Error {
|
|
377
|
+
name = "D1ExecutionError";
|
|
378
|
+
constructor() {
|
|
379
|
+
super("D1 did not successfully execute every requested statement");
|
|
380
|
+
}
|
|
381
|
+
};
|
|
348
382
|
const EXPECTATION_CONFLICT_MARKER = "HOT_UPDATER_COMMIT_EXPECTATION_CONFLICT";
|
|
349
383
|
const expectationGuard = (expectations) => {
|
|
350
384
|
const clauses = [];
|
|
@@ -382,7 +416,8 @@ const expectationConflict = async (executor, expectations) => {
|
|
|
382
416
|
const versionField = isRelease ? "revision" : "generation";
|
|
383
417
|
const key = isRelease ? expectation.id : expectation.scopeKey;
|
|
384
418
|
const expectedVersion = isRelease ? expectation.revision : expectation.generation;
|
|
385
|
-
const
|
|
419
|
+
const rows = await executor.query(`SELECT ${versionField} FROM ${table} WHERE ${keyField} = json_extract(?, '$') LIMIT 1`, encodeD1Values([key]));
|
|
420
|
+
const actualVersion = readVersion(rows[0], versionField);
|
|
386
421
|
if (actualVersion !== expectedVersion) return {
|
|
387
422
|
committed: false,
|
|
388
423
|
conflict: {
|
|
@@ -461,14 +496,14 @@ const insertQuery = (input, guard, conflictMode = "returnExisting") => {
|
|
|
461
496
|
values = channelValues(input.data);
|
|
462
497
|
break;
|
|
463
498
|
case "bundle_events":
|
|
499
|
+
case "bundle_installations":
|
|
464
500
|
case "api_keys":
|
|
465
501
|
case "release_catalogs":
|
|
466
502
|
case "releases":
|
|
467
503
|
columns = Object.keys(input.data);
|
|
468
504
|
values = Object.values(input.data);
|
|
469
|
-
break;
|
|
470
505
|
}
|
|
471
|
-
const conflict = input.onConflict !== "ignore" ? "" : input.model === "channels" ? conflictMode === "ignore" ? " ON CONFLICT(name) DO NOTHING" : " ON CONFLICT(name) DO UPDATE SET name = excluded.name" : input.model === "api_keys" ? conflictMode === "ignore" ? " ON CONFLICT(hash) DO NOTHING" : " ON CONFLICT(hash) DO UPDATE SET hash = excluded.hash" : "";
|
|
506
|
+
const conflict = input.onConflict !== "ignore" ? "" : input.model === "channels" ? conflictMode === "ignore" ? " ON CONFLICT(name) DO NOTHING" : " ON CONFLICT(name) DO UPDATE SET name = excluded.name" : input.model === "api_keys" ? conflictMode === "ignore" ? " ON CONFLICT(hash) DO NOTHING" : " ON CONFLICT(hash) DO UPDATE SET hash = excluded.hash" : " ON CONFLICT(install_id) DO UPDATE SET install_id = excluded.install_id";
|
|
472
507
|
return {
|
|
473
508
|
sql: `INSERT INTO ${d1TableNames[input.model]} (${columns.join(", ")}) ${guard === void 0 ? `VALUES (${d1Placeholders(values.length)})` : `SELECT ${d1Placeholders(values.length)} WHERE ${guard.sql}`}${conflict} RETURNING *`,
|
|
474
509
|
params: [...encodeD1Values(values), ...guard?.params ?? []]
|
|
@@ -532,9 +567,7 @@ const channelDeletePrecondition = (changes, changeIndex, channelId) => {
|
|
|
532
567
|
releaseEffects.set(change.row.id, change.row.channel_id);
|
|
533
568
|
break;
|
|
534
569
|
case "update": break;
|
|
535
|
-
case "delete":
|
|
536
|
-
releaseEffects.set(change.where.id, null);
|
|
537
|
-
break;
|
|
570
|
+
case "delete": releaseEffects.set(change.where.id, null);
|
|
538
571
|
}
|
|
539
572
|
}
|
|
540
573
|
return {
|
|
@@ -609,10 +642,6 @@ const changeQuery = (change, guard) => {
|
|
|
609
642
|
sql: `DELETE FROM channels WHERE id = json_extract(?, '$') AND NOT EXISTS (SELECT 1 FROM releases WHERE channel_id = json_extract(?, '$')) AND ${guard.sql}`,
|
|
610
643
|
params: [...encodeD1Values([change.where.id, change.where.id]), ...guard.params]
|
|
611
644
|
};
|
|
612
|
-
case "insights": return insertQuery({
|
|
613
|
-
model: "bundle_events",
|
|
614
|
-
data: change.row
|
|
615
|
-
}, guard);
|
|
616
645
|
case "apiKeys": return change.operation === "insert" ? insertQuery({
|
|
617
646
|
model: "api_keys",
|
|
618
647
|
data: change.row,
|
|
@@ -781,6 +810,25 @@ const deleteChannel = async (executor, input) => {
|
|
|
781
810
|
};
|
|
782
811
|
};
|
|
783
812
|
const createD1Implementation = (executor) => ({
|
|
813
|
+
async recordInsights({ event, installation }) {
|
|
814
|
+
const columns = Object.keys(installation);
|
|
815
|
+
const eventInsert = insertQuery({
|
|
816
|
+
model: "bundle_events",
|
|
817
|
+
data: event
|
|
818
|
+
});
|
|
819
|
+
await executor.batch([{
|
|
820
|
+
sql: `INSERT INTO bundle_installations (${columns.join(", ")})
|
|
821
|
+
SELECT ${d1Placeholders(columns.length)}
|
|
822
|
+
WHERE NOT EXISTS (SELECT 1 FROM bundle_events WHERE id = json_extract(?, '$'))
|
|
823
|
+
ON CONFLICT(install_id) DO UPDATE SET ${columns.filter((column) => column !== "install_id").map((column) => `${column} = excluded.${column}`).join(", ")}
|
|
824
|
+
WHERE (excluded.received_at_ms, excluded.id) >
|
|
825
|
+
(bundle_installations.received_at_ms, bundle_installations.id)`,
|
|
826
|
+
params: encodeD1Values([...Object.values(installation), event.id])
|
|
827
|
+
}, {
|
|
828
|
+
...eventInsert,
|
|
829
|
+
sql: eventInsert.sql.replace(" RETURNING *", " ON CONFLICT(id) DO NOTHING")
|
|
830
|
+
}]);
|
|
831
|
+
},
|
|
784
832
|
async create(input) {
|
|
785
833
|
const query = insertQuery(input);
|
|
786
834
|
const rows = await executor.query(query.sql, query.params);
|
|
@@ -789,6 +837,7 @@ const createD1Implementation = (executor) => ({
|
|
|
789
837
|
case "bundle_patches": return parseD1Row("bundle_patches", rows[0]);
|
|
790
838
|
case "channels": return parseD1Row("channels", rows[0]);
|
|
791
839
|
case "bundle_events": return parseD1Row("bundle_events", rows[0]);
|
|
840
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
792
841
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
793
842
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
794
843
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
@@ -803,6 +852,7 @@ const createD1Implementation = (executor) => ({
|
|
|
803
852
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
804
853
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
805
854
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
855
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
806
856
|
}
|
|
807
857
|
},
|
|
808
858
|
async delete(input) {
|
|
@@ -821,6 +871,7 @@ const createD1Implementation = (executor) => ({
|
|
|
821
871
|
case "api_keys": return parseD1Row("api_keys", rows[0]);
|
|
822
872
|
case "releases": return parseD1Row("releases", rows[0]);
|
|
823
873
|
case "release_catalogs": return parseD1Row("release_catalogs", rows[0]);
|
|
874
|
+
case "bundle_installations": return parseD1Row("bundle_installations", rows[0]);
|
|
824
875
|
}
|
|
825
876
|
},
|
|
826
877
|
findMany: (input) => findManyD1Rows(executor, input),
|
|
@@ -853,14 +904,19 @@ const createD1Implementation = (executor) => ({
|
|
|
853
904
|
//#endregion
|
|
854
905
|
//#region src/worker/d1Database.ts
|
|
855
906
|
const d1Database = (database) => {
|
|
856
|
-
const
|
|
907
|
+
const implementation = createD1Implementation({
|
|
857
908
|
async query(sql, params) {
|
|
858
|
-
|
|
909
|
+
const result = await database.prepare(sql).bind(...params).all();
|
|
910
|
+
if (result.success === false) throw new D1ExecutionError();
|
|
911
|
+
return result.results ?? [];
|
|
859
912
|
},
|
|
860
913
|
async batch(statements) {
|
|
861
|
-
|
|
914
|
+
const results = await database.batch(statements.map(({ sql, params }) => database.prepare(sql).bind(...params)));
|
|
915
|
+
if (results.length !== statements.length || results.some(({ success }) => success === false)) throw new D1ExecutionError();
|
|
916
|
+
return results.map(({ results }) => results ?? []);
|
|
862
917
|
}
|
|
863
|
-
})
|
|
918
|
+
});
|
|
919
|
+
const adapter = (0, _hot_updater_plugin_core_internal.createDatabasePluginAdapter)("d1Database", implementation);
|
|
864
920
|
return (0, _hot_updater_plugin_core.createDatabasePlugin)({
|
|
865
921
|
name: "d1Database",
|
|
866
922
|
models: adapter.models,
|
package/dist/worker/index.d.cts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import * as _$_hot_updater_plugin_core0 from "@hot-updater/plugin-core";
|
|
2
1
|
import { StoragePluginWith } from "@hot-updater/plugin-core";
|
|
3
|
-
|
|
4
2
|
//#region src/worker/d1Database.d.ts
|
|
5
3
|
type D1Result = {
|
|
6
4
|
readonly results?: readonly unknown[];
|
|
5
|
+
readonly success?: boolean;
|
|
7
6
|
};
|
|
8
7
|
type D1BoundStatement = {
|
|
9
8
|
all: () => Promise<D1Result>;
|
|
@@ -15,7 +14,7 @@ type D1Like = {
|
|
|
15
14
|
prepare(sql: string): D1PreparedStatement;
|
|
16
15
|
batch(statements: D1BoundStatement[]): Promise<readonly D1Result[]>;
|
|
17
16
|
};
|
|
18
|
-
declare const d1Database: (database: D1Like) =>
|
|
17
|
+
declare const d1Database: (database: D1Like) => import("@hot-updater/plugin-core").DatabasePlugin;
|
|
19
18
|
//#endregion
|
|
20
19
|
//#region src/r2WorkerStorage.d.ts
|
|
21
20
|
interface CloudflareWorkerStorageConfig {
|