@hot-updater/server 1.0.0-rc.0 → 1.0.0-rc.2
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/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/adapters/databaseConstraintErrors.cjs +0 -1
- package/dist/adapters/databasePluginUtils.cjs +0 -1
- package/dist/adapters/drizzle.cjs +11 -4
- package/dist/adapters/drizzle.d.cts +0 -1
- package/dist/adapters/drizzle.d.mts +0 -1
- package/dist/adapters/drizzle.mjs +12 -4
- package/dist/adapters/drizzleCrud.cjs +62 -1
- package/dist/adapters/drizzleCrud.mjs +61 -2
- package/dist/adapters/drizzleLazyDB.cjs +6 -1
- package/dist/adapters/drizzleLazyDB.mjs +6 -1
- package/dist/adapters/drizzleQuery.cjs +3 -2
- package/dist/adapters/drizzleQuery.mjs +3 -1
- package/dist/adapters/insightsTransaction.cjs +22 -0
- package/dist/adapters/insightsTransaction.mjs +22 -0
- package/dist/adapters/kysely.cjs +2 -1
- package/dist/adapters/kysely.d.cts +0 -1
- package/dist/adapters/kysely.d.mts +0 -1
- package/dist/adapters/kysely.mjs +3 -1
- package/dist/adapters/kyselyCrud.cjs +54 -3
- package/dist/adapters/kyselyCrud.mjs +54 -3
- package/dist/adapters/kyselyQuery.cjs +2 -2
- package/dist/adapters/kyselyQuery.mjs +2 -1
- package/dist/adapters/mongodb.cjs +27 -1
- package/dist/adapters/mongodb.d.cts +1 -1
- package/dist/adapters/mongodb.d.mts +1 -1
- package/dist/adapters/mongodb.mjs +28 -1
- package/dist/adapters/mongodbCollections.cjs +2 -0
- package/dist/adapters/mongodbCollections.mjs +2 -0
- package/dist/adapters/mongodbQuery.cjs +21 -4
- package/dist/adapters/mongodbQuery.mjs +21 -5
- package/dist/adapters/mongodbReads.cjs +91 -29
- package/dist/adapters/mongodbReads.mjs +92 -29
- package/dist/adapters/mongodbWrites.cjs +16 -2
- package/dist/adapters/mongodbWrites.mjs +18 -3
- package/dist/adapters/prisma.cjs +55 -7
- package/dist/adapters/prisma.d.cts +0 -1
- package/dist/adapters/prisma.d.mts +0 -1
- package/dist/adapters/prisma.mjs +56 -7
- package/dist/adapters/prismaQuery.cjs +0 -1
- package/dist/adapters/prismaRows.cjs +22 -1
- package/dist/adapters/prismaRows.mjs +22 -1
- package/dist/apiKeys.cjs +6 -2
- package/dist/apiKeys.d.cts +0 -1
- package/dist/apiKeys.d.mts +0 -1
- package/dist/apiKeys.mjs +3 -3
- package/dist/createHotUpdaterCore.cjs +27 -12
- package/dist/createHotUpdaterCore.d.cts +8 -8
- package/dist/createHotUpdaterCore.d.mts +8 -8
- package/dist/createHotUpdaterCore.mjs +26 -12
- package/dist/db/createBundleDiff.cjs +2 -2
- package/dist/db/createBundleDiff.d.cts +1 -5
- package/dist/db/createBundleDiff.d.mts +1 -5
- package/dist/db/databasePluginCore.cjs +0 -1
- package/dist/db/fixedMigrator.cjs +2 -2
- package/dist/db/fixedMigrator.mjs +2 -2
- package/dist/db/fixedMigratorMongo.cjs +6 -4
- package/dist/db/fixedMigratorMongo.mjs +6 -4
- package/dist/db/index.d.cts +0 -1
- package/dist/db/index.d.mts +0 -1
- package/dist/db/releaseCatalog.cjs +0 -1
- package/dist/db/releaseCatalog.d.cts +0 -1
- package/dist/db/releaseCatalog.d.mts +0 -1
- package/dist/db/schema/insightsCollation.cjs +14 -0
- package/dist/db/schema/insightsCollation.mjs +14 -0
- package/dist/db/schema/sql.cjs +11 -7
- package/dist/db/schema/sql.mjs +8 -8
- package/dist/db/schemaGenerators.cjs +28 -9
- package/dist/db/schemaGenerators.mjs +28 -9
- package/dist/db/schemaReadiness.cjs +2 -0
- package/dist/db/schemaReadiness.d.cts +1 -0
- package/dist/db/schemaReadiness.d.mts +1 -0
- package/dist/db/schemaReadiness.mjs +2 -0
- package/dist/db/sqlMigrationExecution.cjs +1 -1
- package/dist/db/sqlMigrationExecution.mjs +1 -0
- package/dist/db/types.cjs +3 -1
- package/dist/db/types.d.cts +3 -6
- package/dist/db/types.d.mts +3 -6
- package/dist/db/types.mjs +2 -2
- package/dist/db/updateArtifacts.cjs +0 -1
- package/dist/handler.cjs +5 -5
- package/dist/handler.d.cts +1 -2
- package/dist/handler.d.mts +1 -2
- package/dist/handler.mjs +5 -5
- package/dist/handlerReleaseCatalogRoutes.cjs +0 -1
- package/dist/handlerReleaseManagementRoutes.cjs +0 -1
- package/dist/handlerTypes.d.cts +0 -1
- package/dist/handlerTypes.d.mts +0 -1
- package/dist/handlerVersionRoutes.d.cts +1 -0
- package/dist/handlerVersionRoutes.d.mts +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -2
- package/dist/insights/domain.d.cts +89 -0
- package/dist/insights/domain.d.mts +89 -0
- package/dist/insights/errors.cjs +15 -0
- package/dist/insights/errors.mjs +14 -0
- package/dist/{analytics → insights}/eventInput.cjs +58 -14
- package/dist/{analytics → insights}/eventInput.mjs +58 -16
- package/dist/insights/provider.cjs +314 -0
- package/dist/insights/provider.d.cts +6 -0
- package/dist/insights/provider.d.mts +6 -0
- package/dist/insights/provider.mjs +314 -0
- package/dist/insights/queryInput.cjs +93 -0
- package/dist/insights/queryInput.mjs +91 -0
- package/dist/insights/routes.cjs +58 -0
- package/dist/insights/routes.mjs +56 -0
- package/dist/insights/types.d.cts +32 -0
- package/dist/insights/types.d.mts +32 -0
- package/dist/node.d.cts +0 -1
- package/dist/node.d.mts +0 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/schema/index.cjs +17 -3
- package/dist/schema/index.mjs +4 -4
- package/dist/schema/v1_0_0.cjs +72 -30
- package/dist/schema/v1_0_0.mjs +72 -31
- package/dist/storageAccess.cjs +0 -1
- package/dist/types/index.d.cts +0 -1
- package/dist/types/index.d.mts +0 -1
- package/package.json +7 -7
- package/src/adapters/databasePluginTestDatabase.ts +14 -0
- package/src/adapters/drizzle.spec.ts +99 -0
- package/src/adapters/drizzle.ts +22 -4
- package/src/adapters/drizzleCrud.ts +154 -2
- package/src/adapters/drizzleLazyDB.ts +17 -3
- package/src/adapters/insightsTransaction.ts +32 -0
- package/src/adapters/kysely.spec.ts +29 -0
- package/src/adapters/kysely.ts +10 -1
- package/src/adapters/kyselyCrud.ts +121 -0
- package/src/adapters/mongodb.integration.spec.ts +210 -0
- package/src/adapters/mongodb.spec.ts +69 -1
- package/src/adapters/mongodb.ts +66 -2
- package/src/adapters/mongodbCollections.ts +5 -0
- package/src/adapters/mongodbQuery.ts +32 -3
- package/src/adapters/mongodbReads.ts +69 -0
- package/src/adapters/mongodbTestClient.ts +41 -6
- package/src/adapters/mongodbTestFilter.ts +4 -1
- package/src/adapters/mongodbWrites.ts +27 -0
- package/src/adapters/prisma.spec.ts +97 -0
- package/src/adapters/prisma.ts +103 -3
- package/src/adapters/prismaRows.ts +37 -1
- package/src/adapters/prismaTestClient.ts +22 -5
- package/src/apiKeys.integration.spec.ts +3 -3
- package/src/createHotUpdaterCore.ts +30 -16
- package/src/db/databasePluginUpdateCheck.bench.ts +3 -0
- package/src/db/fixedMigrator.spec.ts +65 -0
- package/src/db/fixedMigratorMongo.spec.ts +56 -9
- package/src/db/fixedMigratorMongo.ts +10 -10
- package/src/db/index.spec.ts +8 -1
- package/src/db/schema/insightsCollation.ts +21 -0
- package/src/db/schema/sql.ts +8 -5
- package/src/db/schemaGenerators.ts +41 -13
- package/src/db/types.spec.ts +11 -3
- package/src/db/types.ts +13 -7
- package/src/handler-standalone.integration.spec.ts +6 -8
- package/src/handler.ts +12 -12
- package/src/index.ts +3 -3
- package/src/insights/domain.ts +103 -0
- package/src/insights/errors.ts +11 -0
- package/src/{analytics → insights}/eventInput.ts +71 -14
- package/src/insights/insights.integration.spec.ts +381 -0
- package/src/insights/provider.spec.ts +385 -0
- package/src/insights/provider.ts +591 -0
- package/src/insights/queryInput.ts +141 -0
- package/src/insights/routes.ts +104 -0
- package/src/insights/types.ts +55 -0
- package/src/schema/dsl-all-versions.spec.ts +3 -1
- package/src/schema/v1_0_0.spec.ts +77 -3
- package/src/schema/v1_0_0.ts +94 -30
- package/dist/analytics/bounded/activeOverview.cjs +0 -87
- package/dist/analytics/bounded/activeOverview.mjs +0 -85
- package/dist/analytics/bounded/installationSearch.cjs +0 -42
- package/dist/analytics/bounded/installationSearch.mjs +0 -42
- package/dist/analytics/bounded/persistence.cjs +0 -39
- package/dist/analytics/bounded/persistence.mjs +0 -38
- package/dist/analytics/bounded/provider.cjs +0 -170
- package/dist/analytics/bounded/provider.d.cts +0 -7
- package/dist/analytics/bounded/provider.d.mts +0 -7
- package/dist/analytics/bounded/provider.mjs +0 -170
- package/dist/analytics/bounded/scan.cjs +0 -144
- package/dist/analytics/bounded/scan.mjs +0 -138
- package/dist/analytics/domain.d.cts +0 -121
- package/dist/analytics/domain.d.mts +0 -121
- package/dist/analytics/errors.cjs +0 -22
- package/dist/analytics/errors.mjs +0 -20
- package/dist/analytics/persistence.d.cts +0 -6
- package/dist/analytics/persistence.d.mts +0 -6
- package/dist/analytics/queryInput.cjs +0 -58
- package/dist/analytics/queryInput.mjs +0 -55
- package/dist/analytics/routes.cjs +0 -63
- package/dist/analytics/routes.mjs +0 -61
- package/dist/analytics/types.d.cts +0 -17
- package/dist/analytics/types.d.mts +0 -17
- package/src/analytics/analytics.integration.spec.ts +0 -144
- package/src/analytics/bounded/activeOverview.spec.ts +0 -189
- package/src/analytics/bounded/activeOverview.ts +0 -148
- package/src/analytics/bounded/installationSearch.spec.ts +0 -130
- package/src/analytics/bounded/installationSearch.ts +0 -69
- package/src/analytics/bounded/persistence.ts +0 -43
- package/src/analytics/bounded/provider.spec.ts +0 -219
- package/src/analytics/bounded/provider.ts +0 -229
- package/src/analytics/bounded/scan.ts +0 -235
- package/src/analytics/domain.ts +0 -139
- package/src/analytics/errors.ts +0 -18
- package/src/analytics/persistence.ts +0 -10
- package/src/analytics/queryInput.ts +0 -102
- package/src/analytics/routes.ts +0 -123
- package/src/analytics/types.ts +0 -44
|
@@ -15,7 +15,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
15
|
}
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
19
19
|
value: mod,
|
|
20
20
|
enumerable: true
|
|
21
21
|
}) : target, mod));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
3
2
|
const require_registry = require("../db/schema/registry.cjs");
|
|
4
3
|
const require_schemaGenerators = require("../db/schemaGenerators.cjs");
|
|
4
|
+
const require_insightsTransaction = require("./insightsTransaction.cjs");
|
|
5
5
|
const require_drizzleCrud = require("./drizzleCrud.cjs");
|
|
6
6
|
const require_drizzleLazyDB = require("./drizzleLazyDB.cjs");
|
|
7
7
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
@@ -13,6 +13,10 @@ const createImplementation = (config) => {
|
|
|
13
13
|
const transaction = db.transaction?.bind(db);
|
|
14
14
|
return {
|
|
15
15
|
...crud,
|
|
16
|
+
recordInsights: (input) => {
|
|
17
|
+
if (transaction === void 0) throw new Error("Drizzle Insights recording requires transaction support.");
|
|
18
|
+
return require_insightsTransaction.runInsightsTransaction(() => transaction((transactionDatabase) => require_drizzleCrud.recordDrizzleInsights(transactionDatabase, config.provider, input)));
|
|
19
|
+
},
|
|
16
20
|
deleteChannel: (input) => {
|
|
17
21
|
if (transaction === void 0) throw new Error("Drizzle channel deletion requires transaction support.");
|
|
18
22
|
return transaction((transactionDatabase) => require_drizzleCrud.createDrizzleCrud(transactionDatabase, config.provider).deleteChannel(input));
|
|
@@ -50,9 +54,12 @@ const drizzleAdapter = (config) => {
|
|
|
50
54
|
list: (input) => getAdapter().models.channels.list(input),
|
|
51
55
|
delete: (input) => getAdapter().models.channels.delete(input)
|
|
52
56
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
insights: {
|
|
58
|
+
record: (input) => getAdapter().models.insights.record(input),
|
|
59
|
+
listEvents: (input) => getAdapter().models.insights.listEvents(input),
|
|
60
|
+
findInstallations: (input) => getAdapter().models.insights.findInstallations(input),
|
|
61
|
+
countInstallations: (input) => getAdapter().models.insights.countInstallations(input),
|
|
62
|
+
countEvents: (input) => getAdapter().models.insights.countEvents(input)
|
|
56
63
|
},
|
|
57
64
|
apiKeys: {
|
|
58
65
|
create: (row) => getAdapter().models.apiKeys.create(row),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getHotUpdaterSchemaVersion, hotUpdaterSchema } from "../db/schema/registry.mjs";
|
|
2
2
|
import { generateDrizzleSchema } from "../db/schemaGenerators.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { runInsightsTransaction } from "./insightsTransaction.mjs";
|
|
4
|
+
import { createDrizzleCrud, recordDrizzleInsights } from "./drizzleCrud.mjs";
|
|
4
5
|
import { createLazyDB } from "./drizzleLazyDB.mjs";
|
|
5
6
|
import { createDatabasePlugin } from "@hot-updater/plugin-core";
|
|
6
7
|
import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
|
|
@@ -11,6 +12,10 @@ const createImplementation = (config) => {
|
|
|
11
12
|
const transaction = db.transaction?.bind(db);
|
|
12
13
|
return {
|
|
13
14
|
...crud,
|
|
15
|
+
recordInsights: (input) => {
|
|
16
|
+
if (transaction === void 0) throw new Error("Drizzle Insights recording requires transaction support.");
|
|
17
|
+
return runInsightsTransaction(() => transaction((transactionDatabase) => recordDrizzleInsights(transactionDatabase, config.provider, input)));
|
|
18
|
+
},
|
|
14
19
|
deleteChannel: (input) => {
|
|
15
20
|
if (transaction === void 0) throw new Error("Drizzle channel deletion requires transaction support.");
|
|
16
21
|
return transaction((transactionDatabase) => createDrizzleCrud(transactionDatabase, config.provider).deleteChannel(input));
|
|
@@ -48,9 +53,12 @@ const drizzleAdapter = (config) => {
|
|
|
48
53
|
list: (input) => getAdapter().models.channels.list(input),
|
|
49
54
|
delete: (input) => getAdapter().models.channels.delete(input)
|
|
50
55
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
insights: {
|
|
57
|
+
record: (input) => getAdapter().models.insights.record(input),
|
|
58
|
+
listEvents: (input) => getAdapter().models.insights.listEvents(input),
|
|
59
|
+
findInstallations: (input) => getAdapter().models.insights.findInstallations(input),
|
|
60
|
+
countInstallations: (input) => getAdapter().models.insights.countInstallations(input),
|
|
61
|
+
countEvents: (input) => getAdapter().models.insights.countEvents(input)
|
|
54
62
|
},
|
|
55
63
|
apiKeys: {
|
|
56
64
|
create: (row) => getAdapter().models.apiKeys.create(row),
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
1
|
const require_databaseConstraintErrors = require("./databaseConstraintErrors.cjs");
|
|
3
2
|
const require_databasePluginUtils = require("./databasePluginUtils.cjs");
|
|
4
3
|
const require_drizzleQuery = require("./drizzleQuery.cjs");
|
|
@@ -6,6 +5,7 @@ let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
|
6
5
|
let drizzle_orm = require("drizzle-orm");
|
|
7
6
|
//#region src/adapters/drizzleCrud.ts
|
|
8
7
|
var MissingDrizzleTableError = class extends Error {
|
|
8
|
+
table;
|
|
9
9
|
name = "MissingDrizzleTableError";
|
|
10
10
|
constructor(table) {
|
|
11
11
|
super(`Drizzle schema is missing table "${table}".`);
|
|
@@ -37,9 +37,45 @@ const executeInsert = async (db, provider, table, data, onConflict) => {
|
|
|
37
37
|
if (ignored === void 0) throw new DrizzleAdapterInvariantError();
|
|
38
38
|
await ignored.execute();
|
|
39
39
|
};
|
|
40
|
+
const recordDrizzleInsights = (db, provider, input) => {
|
|
41
|
+
if (db.resultKind !== "sync") return recordAsyncDrizzleInsights(db, provider, input);
|
|
42
|
+
const events = getDrizzleTable(db, "bundle_events");
|
|
43
|
+
const installations = getDrizzleTable(db, "bundle_installations");
|
|
44
|
+
const eventInsert = db.insert(events).values(input.event).onConflictDoNothing?.().returning?.({ id: getDrizzleColumn(events, "id") });
|
|
45
|
+
const installationInsert = db.insert(installations).values(input.installation).onConflictDoNothing?.();
|
|
46
|
+
const installationUpdate = db.update(installations).set(input.installation).where(newerInstallationWhere(installations, input.installation));
|
|
47
|
+
if (eventInsert?.all === void 0 || installationInsert?.run === void 0 || installationUpdate.run === void 0) throw new DrizzleAdapterInvariantError();
|
|
48
|
+
if (eventInsert.all().length === 0) return;
|
|
49
|
+
installationInsert.run();
|
|
50
|
+
installationUpdate.run();
|
|
51
|
+
};
|
|
52
|
+
const newerInstallationWhere = (installations, installation) => {
|
|
53
|
+
const receivedAt = getDrizzleColumn(installations, "received_at_ms");
|
|
54
|
+
return (0, drizzle_orm.and)((0, drizzle_orm.eq)(getDrizzleColumn(installations, "install_id"), installation.install_id), (0, drizzle_orm.or)((0, drizzle_orm.lt)(receivedAt, installation.received_at_ms), (0, drizzle_orm.and)((0, drizzle_orm.eq)(receivedAt, installation.received_at_ms), (0, drizzle_orm.lt)(getDrizzleColumn(installations, "id"), installation.id))));
|
|
55
|
+
};
|
|
56
|
+
const recordAsyncDrizzleInsights = async (db, provider, { event, installation }) => {
|
|
57
|
+
const events = getDrizzleTable(db, "bundle_events");
|
|
58
|
+
const installations = getDrizzleTable(db, "bundle_installations");
|
|
59
|
+
if (provider === "mysql") {
|
|
60
|
+
if (await db.query.bundle_events.findFirst({ where: (0, drizzle_orm.eq)(getDrizzleColumn(events, "id"), event.id) }) !== void 0) return;
|
|
61
|
+
await db.insert(events).values(event).execute();
|
|
62
|
+
const insertInstallation = db.insert(installations).values(installation).onDuplicateKeyUpdate?.({ set: { install_id: installation.install_id } });
|
|
63
|
+
if (insertInstallation === void 0) throw new DrizzleAdapterInvariantError();
|
|
64
|
+
await insertInstallation.execute();
|
|
65
|
+
} else {
|
|
66
|
+
const returning = (db.insert(events).values(event).onConflictDoNothing?.())?.returning?.({ id: getDrizzleColumn(events, "id") });
|
|
67
|
+
if (returning === void 0) throw new DrizzleAdapterInvariantError();
|
|
68
|
+
const rows = await returning.execute();
|
|
69
|
+
if (!Array.isArray(rows)) throw new DrizzleAdapterInvariantError();
|
|
70
|
+
if (rows.length === 0) return;
|
|
71
|
+
await executeInsert(db, provider, installations, installation, "ignore");
|
|
72
|
+
}
|
|
73
|
+
await db.update(installations).set(installation).where(newerInstallationWhere(installations, installation)).execute();
|
|
74
|
+
};
|
|
40
75
|
const toOrderBy = (table, input) => {
|
|
41
76
|
return input.orderBy?.flatMap((clause) => {
|
|
42
77
|
const column = getDrizzleColumn(table, clause.field);
|
|
78
|
+
if (input.model === "bundle_events" || input.model === "bundle_installations") return [clause.direction === "asc" ? (0, drizzle_orm.asc)(column) : (0, drizzle_orm.desc)(column)];
|
|
43
79
|
return [(clause.nulls ?? (clause.direction === "asc" ? "last" : "first")) === "first" ? drizzle_orm.sql`${column} is null desc` : drizzle_orm.sql`${column} is null asc`, clause.direction === "asc" ? (0, drizzle_orm.asc)(column) : (0, drizzle_orm.desc)(column)];
|
|
44
80
|
});
|
|
45
81
|
};
|
|
@@ -47,6 +83,7 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
47
83
|
const bundles = getDrizzleTable(db, "bundles");
|
|
48
84
|
const patches = getDrizzleTable(db, "bundle_patches");
|
|
49
85
|
const events = getDrizzleTable(db, "bundle_events");
|
|
86
|
+
const installations = getDrizzleTable(db, "bundle_installations");
|
|
50
87
|
const releases = getDrizzleTable(db, "releases");
|
|
51
88
|
const releaseCatalogs = getDrizzleTable(db, "release_catalogs");
|
|
52
89
|
const channels = getDrizzleTable(db, "channels");
|
|
@@ -98,6 +135,9 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
98
135
|
case "bundle_events":
|
|
99
136
|
await executeInsert(db, provider, events, input.data, void 0);
|
|
100
137
|
return input.data;
|
|
138
|
+
case "bundle_installations":
|
|
139
|
+
await executeInsert(db, provider, installations, input.data, input.onConflict);
|
|
140
|
+
return input.data;
|
|
101
141
|
case "releases":
|
|
102
142
|
await executeInsert(db, provider, releases, require_databasePluginUtils.toStoredReleaseRow(input.data, provider), void 0);
|
|
103
143
|
return input.data;
|
|
@@ -113,6 +153,15 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
113
153
|
}
|
|
114
154
|
},
|
|
115
155
|
async update(input) {
|
|
156
|
+
if (input.model === "bundle_installations") {
|
|
157
|
+
const installId = input.where.find((item) => item.field === "install_id" && (item.operator === void 0 || item.operator === "eq") && typeof item.value === "string")?.value;
|
|
158
|
+
if (typeof installId !== "string") throw new DrizzleAdapterInvariantError();
|
|
159
|
+
const where = require_drizzleQuery.buildDrizzleWhere(provider, installations, input.where);
|
|
160
|
+
if (where === void 0) throw new DrizzleAdapterInvariantError();
|
|
161
|
+
await db.update(installations).set(input.update).where(where).execute();
|
|
162
|
+
const row = await db.query.bundle_installations.findFirst({ where: (0, drizzle_orm.eq)(getDrizzleColumn(installations, "install_id"), installId) });
|
|
163
|
+
return row?.id === input.update.id && row.received_at_ms === input.update.received_at_ms ? row : null;
|
|
164
|
+
}
|
|
116
165
|
const selector = input.where[0];
|
|
117
166
|
if (selector === void 0 || typeof selector.value !== "string") throw new DrizzleAdapterInvariantError();
|
|
118
167
|
if (input.model === "api_keys") {
|
|
@@ -173,9 +222,11 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
173
222
|
async count(input) {
|
|
174
223
|
if (input.distinct !== void 0) throw new _hot_updater_plugin_core.DatabasePluginInputError("invalid-operation");
|
|
175
224
|
switch (input.model) {
|
|
225
|
+
case "bundle_events": return db.$count(events, require_drizzleQuery.buildDrizzleWhere(provider, events, input.where));
|
|
176
226
|
case "bundles": return db.$count(bundles, require_drizzleQuery.buildDrizzleWhere(provider, bundles, input.where));
|
|
177
227
|
case "bundle_patches": return db.$count(patches, require_drizzleQuery.buildDrizzleWhere(provider, patches, input.where));
|
|
178
228
|
case "releases": return db.$count(releases, require_drizzleQuery.buildDrizzleWhere(provider, releases, input.where));
|
|
229
|
+
case "bundle_installations": return db.$count(installations, require_drizzleQuery.buildDrizzleWhere(provider, installations, input.where));
|
|
179
230
|
}
|
|
180
231
|
},
|
|
181
232
|
async findOne(input) {
|
|
@@ -195,6 +246,7 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
195
246
|
const row = await db.query.release_catalogs.findFirst({ where: require_drizzleQuery.buildDrizzleWhere(provider, releaseCatalogs, input.where) });
|
|
196
247
|
return row === void 0 ? null : require_databasePluginUtils.fromStoredReleaseCatalogRow(row);
|
|
197
248
|
}
|
|
249
|
+
case "bundle_installations": return await db.query.bundle_installations.findFirst({ where: require_drizzleQuery.buildDrizzleWhere(provider, installations, input.where) }) ?? null;
|
|
198
250
|
}
|
|
199
251
|
},
|
|
200
252
|
async findMany(input) {
|
|
@@ -212,6 +264,12 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
212
264
|
limit: input.limit,
|
|
213
265
|
offset: input.offset
|
|
214
266
|
});
|
|
267
|
+
case "bundle_installations": return db.query.bundle_installations.findMany({
|
|
268
|
+
where: require_drizzleQuery.buildDrizzleWhere(provider, installations, input.where),
|
|
269
|
+
orderBy: toOrderBy(installations, input),
|
|
270
|
+
limit: input.limit,
|
|
271
|
+
offset: input.offset
|
|
272
|
+
});
|
|
215
273
|
case "api_keys": return db.query.api_keys.findMany({
|
|
216
274
|
where: require_drizzleQuery.buildDrizzleWhere(provider, apiKeys, input.where),
|
|
217
275
|
orderBy: toOrderBy(apiKeys, input),
|
|
@@ -248,3 +306,6 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
248
306
|
};
|
|
249
307
|
//#endregion
|
|
250
308
|
exports.createDrizzleCrud = createDrizzleCrud;
|
|
309
|
+
exports.getDrizzleColumn = getDrizzleColumn;
|
|
310
|
+
exports.getDrizzleTable = getDrizzleTable;
|
|
311
|
+
exports.recordDrizzleInsights = recordDrizzleInsights;
|
|
@@ -2,9 +2,10 @@ import { isChannelDeleteReferencedError, translateChannelDeleteError } from "./d
|
|
|
2
2
|
import { fromStoredBundleRow, fromStoredReleaseCatalogRow, fromStoredReleaseRow, toStoredBundleRow, toStoredBundleUpdate, toStoredReleaseRow, toStoredReleaseUpdate } from "./databasePluginUtils.mjs";
|
|
3
3
|
import { buildDrizzleWhere } from "./drizzleQuery.mjs";
|
|
4
4
|
import { DatabasePluginInputError } from "@hot-updater/plugin-core";
|
|
5
|
-
import { asc, desc, eq, sql } from "drizzle-orm";
|
|
5
|
+
import { and, asc, desc, eq, lt, or, sql } from "drizzle-orm";
|
|
6
6
|
//#region src/adapters/drizzleCrud.ts
|
|
7
7
|
var MissingDrizzleTableError = class extends Error {
|
|
8
|
+
table;
|
|
8
9
|
name = "MissingDrizzleTableError";
|
|
9
10
|
constructor(table) {
|
|
10
11
|
super(`Drizzle schema is missing table "${table}".`);
|
|
@@ -36,9 +37,45 @@ const executeInsert = async (db, provider, table, data, onConflict) => {
|
|
|
36
37
|
if (ignored === void 0) throw new DrizzleAdapterInvariantError();
|
|
37
38
|
await ignored.execute();
|
|
38
39
|
};
|
|
40
|
+
const recordDrizzleInsights = (db, provider, input) => {
|
|
41
|
+
if (db.resultKind !== "sync") return recordAsyncDrizzleInsights(db, provider, input);
|
|
42
|
+
const events = getDrizzleTable(db, "bundle_events");
|
|
43
|
+
const installations = getDrizzleTable(db, "bundle_installations");
|
|
44
|
+
const eventInsert = db.insert(events).values(input.event).onConflictDoNothing?.().returning?.({ id: getDrizzleColumn(events, "id") });
|
|
45
|
+
const installationInsert = db.insert(installations).values(input.installation).onConflictDoNothing?.();
|
|
46
|
+
const installationUpdate = db.update(installations).set(input.installation).where(newerInstallationWhere(installations, input.installation));
|
|
47
|
+
if (eventInsert?.all === void 0 || installationInsert?.run === void 0 || installationUpdate.run === void 0) throw new DrizzleAdapterInvariantError();
|
|
48
|
+
if (eventInsert.all().length === 0) return;
|
|
49
|
+
installationInsert.run();
|
|
50
|
+
installationUpdate.run();
|
|
51
|
+
};
|
|
52
|
+
const newerInstallationWhere = (installations, installation) => {
|
|
53
|
+
const receivedAt = getDrizzleColumn(installations, "received_at_ms");
|
|
54
|
+
return and(eq(getDrizzleColumn(installations, "install_id"), installation.install_id), or(lt(receivedAt, installation.received_at_ms), and(eq(receivedAt, installation.received_at_ms), lt(getDrizzleColumn(installations, "id"), installation.id))));
|
|
55
|
+
};
|
|
56
|
+
const recordAsyncDrizzleInsights = async (db, provider, { event, installation }) => {
|
|
57
|
+
const events = getDrizzleTable(db, "bundle_events");
|
|
58
|
+
const installations = getDrizzleTable(db, "bundle_installations");
|
|
59
|
+
if (provider === "mysql") {
|
|
60
|
+
if (await db.query.bundle_events.findFirst({ where: eq(getDrizzleColumn(events, "id"), event.id) }) !== void 0) return;
|
|
61
|
+
await db.insert(events).values(event).execute();
|
|
62
|
+
const insertInstallation = db.insert(installations).values(installation).onDuplicateKeyUpdate?.({ set: { install_id: installation.install_id } });
|
|
63
|
+
if (insertInstallation === void 0) throw new DrizzleAdapterInvariantError();
|
|
64
|
+
await insertInstallation.execute();
|
|
65
|
+
} else {
|
|
66
|
+
const returning = (db.insert(events).values(event).onConflictDoNothing?.())?.returning?.({ id: getDrizzleColumn(events, "id") });
|
|
67
|
+
if (returning === void 0) throw new DrizzleAdapterInvariantError();
|
|
68
|
+
const rows = await returning.execute();
|
|
69
|
+
if (!Array.isArray(rows)) throw new DrizzleAdapterInvariantError();
|
|
70
|
+
if (rows.length === 0) return;
|
|
71
|
+
await executeInsert(db, provider, installations, installation, "ignore");
|
|
72
|
+
}
|
|
73
|
+
await db.update(installations).set(installation).where(newerInstallationWhere(installations, installation)).execute();
|
|
74
|
+
};
|
|
39
75
|
const toOrderBy = (table, input) => {
|
|
40
76
|
return input.orderBy?.flatMap((clause) => {
|
|
41
77
|
const column = getDrizzleColumn(table, clause.field);
|
|
78
|
+
if (input.model === "bundle_events" || input.model === "bundle_installations") return [clause.direction === "asc" ? asc(column) : desc(column)];
|
|
42
79
|
return [(clause.nulls ?? (clause.direction === "asc" ? "last" : "first")) === "first" ? sql`${column} is null desc` : sql`${column} is null asc`, clause.direction === "asc" ? asc(column) : desc(column)];
|
|
43
80
|
});
|
|
44
81
|
};
|
|
@@ -46,6 +83,7 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
46
83
|
const bundles = getDrizzleTable(db, "bundles");
|
|
47
84
|
const patches = getDrizzleTable(db, "bundle_patches");
|
|
48
85
|
const events = getDrizzleTable(db, "bundle_events");
|
|
86
|
+
const installations = getDrizzleTable(db, "bundle_installations");
|
|
49
87
|
const releases = getDrizzleTable(db, "releases");
|
|
50
88
|
const releaseCatalogs = getDrizzleTable(db, "release_catalogs");
|
|
51
89
|
const channels = getDrizzleTable(db, "channels");
|
|
@@ -97,6 +135,9 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
97
135
|
case "bundle_events":
|
|
98
136
|
await executeInsert(db, provider, events, input.data, void 0);
|
|
99
137
|
return input.data;
|
|
138
|
+
case "bundle_installations":
|
|
139
|
+
await executeInsert(db, provider, installations, input.data, input.onConflict);
|
|
140
|
+
return input.data;
|
|
100
141
|
case "releases":
|
|
101
142
|
await executeInsert(db, provider, releases, toStoredReleaseRow(input.data, provider), void 0);
|
|
102
143
|
return input.data;
|
|
@@ -112,6 +153,15 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
112
153
|
}
|
|
113
154
|
},
|
|
114
155
|
async update(input) {
|
|
156
|
+
if (input.model === "bundle_installations") {
|
|
157
|
+
const installId = input.where.find((item) => item.field === "install_id" && (item.operator === void 0 || item.operator === "eq") && typeof item.value === "string")?.value;
|
|
158
|
+
if (typeof installId !== "string") throw new DrizzleAdapterInvariantError();
|
|
159
|
+
const where = buildDrizzleWhere(provider, installations, input.where);
|
|
160
|
+
if (where === void 0) throw new DrizzleAdapterInvariantError();
|
|
161
|
+
await db.update(installations).set(input.update).where(where).execute();
|
|
162
|
+
const row = await db.query.bundle_installations.findFirst({ where: eq(getDrizzleColumn(installations, "install_id"), installId) });
|
|
163
|
+
return row?.id === input.update.id && row.received_at_ms === input.update.received_at_ms ? row : null;
|
|
164
|
+
}
|
|
115
165
|
const selector = input.where[0];
|
|
116
166
|
if (selector === void 0 || typeof selector.value !== "string") throw new DrizzleAdapterInvariantError();
|
|
117
167
|
if (input.model === "api_keys") {
|
|
@@ -172,9 +222,11 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
172
222
|
async count(input) {
|
|
173
223
|
if (input.distinct !== void 0) throw new DatabasePluginInputError("invalid-operation");
|
|
174
224
|
switch (input.model) {
|
|
225
|
+
case "bundle_events": return db.$count(events, buildDrizzleWhere(provider, events, input.where));
|
|
175
226
|
case "bundles": return db.$count(bundles, buildDrizzleWhere(provider, bundles, input.where));
|
|
176
227
|
case "bundle_patches": return db.$count(patches, buildDrizzleWhere(provider, patches, input.where));
|
|
177
228
|
case "releases": return db.$count(releases, buildDrizzleWhere(provider, releases, input.where));
|
|
229
|
+
case "bundle_installations": return db.$count(installations, buildDrizzleWhere(provider, installations, input.where));
|
|
178
230
|
}
|
|
179
231
|
},
|
|
180
232
|
async findOne(input) {
|
|
@@ -194,6 +246,7 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
194
246
|
const row = await db.query.release_catalogs.findFirst({ where: buildDrizzleWhere(provider, releaseCatalogs, input.where) });
|
|
195
247
|
return row === void 0 ? null : fromStoredReleaseCatalogRow(row);
|
|
196
248
|
}
|
|
249
|
+
case "bundle_installations": return await db.query.bundle_installations.findFirst({ where: buildDrizzleWhere(provider, installations, input.where) }) ?? null;
|
|
197
250
|
}
|
|
198
251
|
},
|
|
199
252
|
async findMany(input) {
|
|
@@ -211,6 +264,12 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
211
264
|
limit: input.limit,
|
|
212
265
|
offset: input.offset
|
|
213
266
|
});
|
|
267
|
+
case "bundle_installations": return db.query.bundle_installations.findMany({
|
|
268
|
+
where: buildDrizzleWhere(provider, installations, input.where),
|
|
269
|
+
orderBy: toOrderBy(installations, input),
|
|
270
|
+
limit: input.limit,
|
|
271
|
+
offset: input.offset
|
|
272
|
+
});
|
|
214
273
|
case "api_keys": return db.query.api_keys.findMany({
|
|
215
274
|
where: buildDrizzleWhere(provider, apiKeys, input.where),
|
|
216
275
|
orderBy: toOrderBy(apiKeys, input),
|
|
@@ -246,4 +305,4 @@ const createDrizzleCrud = (db, provider) => {
|
|
|
246
305
|
};
|
|
247
306
|
};
|
|
248
307
|
//#endregion
|
|
249
|
-
export { createDrizzleCrud };
|
|
308
|
+
export { createDrizzleCrud, getDrizzleColumn, getDrizzleTable, recordDrizzleInsights };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/adapters/drizzleLazyDB.ts
|
|
2
2
|
var InvalidDrizzleDatabaseError = class extends Error {
|
|
3
|
+
reason;
|
|
3
4
|
name = "InvalidDrizzleDatabaseError";
|
|
4
5
|
constructor(reason) {
|
|
5
6
|
super(`[hot-updater] ${reason}`);
|
|
@@ -14,7 +15,7 @@ const isDrizzleDB = (value) => {
|
|
|
14
15
|
const metadata = value["_"];
|
|
15
16
|
if (!isRecord(metadata) || !isRecord(metadata["fullSchema"])) return false;
|
|
16
17
|
const query = value["query"];
|
|
17
|
-
if (!isRecord(query) || !isDrizzleQuery(query["bundle_events"]) || !isDrizzleQuery(query["bundle_patches"]) || !isDrizzleQuery(query["bundles"]) || !isDrizzleQuery(query["channels"]) || !isDrizzleQuery(query["api_keys"]) || !isDrizzleQuery(query["releases"]) || !isDrizzleQuery(query["release_catalogs"])) return false;
|
|
18
|
+
if (!isRecord(query) || !isDrizzleQuery(query["bundle_events"]) || !isDrizzleQuery(query["bundle_installations"]) || !isDrizzleQuery(query["bundle_patches"]) || !isDrizzleQuery(query["bundles"]) || !isDrizzleQuery(query["channels"]) || !isDrizzleQuery(query["api_keys"]) || !isDrizzleQuery(query["releases"]) || !isDrizzleQuery(query["release_catalogs"])) return false;
|
|
18
19
|
if (value["transaction"] !== void 0 && !hasFunction(value, "transaction")) return false;
|
|
19
20
|
return hasFunction(value, "$count") && hasFunction(value, "delete") && hasFunction(value, "insert") && hasFunction(value, "update");
|
|
20
21
|
};
|
|
@@ -64,6 +65,10 @@ const createLazyDB = (config) => {
|
|
|
64
65
|
findFirst: async (args) => (await getDB()).query.bundle_events.findFirst(args),
|
|
65
66
|
findMany: async (args) => (await getDB()).query.bundle_events.findMany(args)
|
|
66
67
|
},
|
|
68
|
+
bundle_installations: {
|
|
69
|
+
findFirst: async (args) => (await getDB()).query.bundle_installations.findFirst(args),
|
|
70
|
+
findMany: async (args) => (await getDB()).query.bundle_installations.findMany(args)
|
|
71
|
+
},
|
|
67
72
|
bundle_patches: {
|
|
68
73
|
findFirst: async (args) => (await getDB()).query.bundle_patches.findFirst(args),
|
|
69
74
|
findMany: async (args) => (await getDB()).query.bundle_patches.findMany(args)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/adapters/drizzleLazyDB.ts
|
|
2
2
|
var InvalidDrizzleDatabaseError = class extends Error {
|
|
3
|
+
reason;
|
|
3
4
|
name = "InvalidDrizzleDatabaseError";
|
|
4
5
|
constructor(reason) {
|
|
5
6
|
super(`[hot-updater] ${reason}`);
|
|
@@ -14,7 +15,7 @@ const isDrizzleDB = (value) => {
|
|
|
14
15
|
const metadata = value["_"];
|
|
15
16
|
if (!isRecord(metadata) || !isRecord(metadata["fullSchema"])) return false;
|
|
16
17
|
const query = value["query"];
|
|
17
|
-
if (!isRecord(query) || !isDrizzleQuery(query["bundle_events"]) || !isDrizzleQuery(query["bundle_patches"]) || !isDrizzleQuery(query["bundles"]) || !isDrizzleQuery(query["channels"]) || !isDrizzleQuery(query["api_keys"]) || !isDrizzleQuery(query["releases"]) || !isDrizzleQuery(query["release_catalogs"])) return false;
|
|
18
|
+
if (!isRecord(query) || !isDrizzleQuery(query["bundle_events"]) || !isDrizzleQuery(query["bundle_installations"]) || !isDrizzleQuery(query["bundle_patches"]) || !isDrizzleQuery(query["bundles"]) || !isDrizzleQuery(query["channels"]) || !isDrizzleQuery(query["api_keys"]) || !isDrizzleQuery(query["releases"]) || !isDrizzleQuery(query["release_catalogs"])) return false;
|
|
18
19
|
if (value["transaction"] !== void 0 && !hasFunction(value, "transaction")) return false;
|
|
19
20
|
return hasFunction(value, "$count") && hasFunction(value, "delete") && hasFunction(value, "insert") && hasFunction(value, "update");
|
|
20
21
|
};
|
|
@@ -64,6 +65,10 @@ const createLazyDB = (config) => {
|
|
|
64
65
|
findFirst: async (args) => (await getDB()).query.bundle_events.findFirst(args),
|
|
65
66
|
findMany: async (args) => (await getDB()).query.bundle_events.findMany(args)
|
|
66
67
|
},
|
|
68
|
+
bundle_installations: {
|
|
69
|
+
findFirst: async (args) => (await getDB()).query.bundle_installations.findFirst(args),
|
|
70
|
+
findMany: async (args) => (await getDB()).query.bundle_installations.findMany(args)
|
|
71
|
+
},
|
|
67
72
|
bundle_patches: {
|
|
68
73
|
findFirst: async (args) => (await getDB()).query.bundle_patches.findFirst(args),
|
|
69
74
|
findMany: async (args) => (await getDB()).query.bundle_patches.findMany(args)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
1
|
const require_databasePluginUtils = require("./databasePluginUtils.cjs");
|
|
3
2
|
let drizzle_orm = require("drizzle-orm");
|
|
4
3
|
//#region src/adapters/drizzleQuery.ts
|
|
@@ -6,6 +5,7 @@ var InvalidDatabasePredicateError = class extends Error {
|
|
|
6
5
|
name = "InvalidDatabasePredicateError";
|
|
7
6
|
};
|
|
8
7
|
var MissingDrizzleColumnError = class extends Error {
|
|
8
|
+
column;
|
|
9
9
|
name = "MissingDrizzleColumnError";
|
|
10
10
|
constructor(column) {
|
|
11
11
|
super(`Drizzle schema is missing column "${column}".`);
|
|
@@ -21,7 +21,8 @@ const column = (table, field) => {
|
|
|
21
21
|
const stringPredicate = (provider, field, operator, value, insensitive) => {
|
|
22
22
|
if (provider === "sqlite" && !insensitive) {
|
|
23
23
|
const literal = require_databasePluginUtils.escapeGlobPattern(value);
|
|
24
|
-
|
|
24
|
+
const pattern = operator === "contains" ? `*${literal}*` : operator === "starts_with" ? `${literal}*` : `*${literal}`;
|
|
25
|
+
return drizzle_orm.sql`${field} glob ${pattern}`;
|
|
25
26
|
}
|
|
26
27
|
const literal = require_databasePluginUtils.escapeLikePattern(value);
|
|
27
28
|
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
@@ -5,6 +5,7 @@ var InvalidDatabasePredicateError = class extends Error {
|
|
|
5
5
|
name = "InvalidDatabasePredicateError";
|
|
6
6
|
};
|
|
7
7
|
var MissingDrizzleColumnError = class extends Error {
|
|
8
|
+
column;
|
|
8
9
|
name = "MissingDrizzleColumnError";
|
|
9
10
|
constructor(column) {
|
|
10
11
|
super(`Drizzle schema is missing column "${column}".`);
|
|
@@ -20,7 +21,8 @@ const column = (table, field) => {
|
|
|
20
21
|
const stringPredicate = (provider, field, operator, value, insensitive) => {
|
|
21
22
|
if (provider === "sqlite" && !insensitive) {
|
|
22
23
|
const literal = escapeGlobPattern(value);
|
|
23
|
-
|
|
24
|
+
const pattern = operator === "contains" ? `*${literal}*` : operator === "starts_with" ? `${literal}*` : `*${literal}`;
|
|
25
|
+
return sql`${field} glob ${pattern}`;
|
|
24
26
|
}
|
|
25
27
|
const literal = escapeLikePattern(value);
|
|
26
28
|
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/adapters/insightsTransaction.ts
|
|
2
|
+
const isRetryableConflict = (error) => {
|
|
3
|
+
if (typeof error !== "object" || error === null) return false;
|
|
4
|
+
if ("code" in error && [
|
|
5
|
+
"ER_DUP_ENTRY",
|
|
6
|
+
"ER_LOCK_DEADLOCK",
|
|
7
|
+
"ER_LOCK_WAIT_TIMEOUT",
|
|
8
|
+
"40001",
|
|
9
|
+
"40P01"
|
|
10
|
+
].includes(String(error.code))) return true;
|
|
11
|
+
return "cause" in error && error.cause !== error && isRetryableConflict(error.cause);
|
|
12
|
+
};
|
|
13
|
+
const runInsightsTransaction = async (operation) => {
|
|
14
|
+
for (let attempt = 0;; attempt += 1) try {
|
|
15
|
+
await operation();
|
|
16
|
+
return;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (attempt >= 2 || !isRetryableConflict(error)) throw error;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
exports.runInsightsTransaction = runInsightsTransaction;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/adapters/insightsTransaction.ts
|
|
2
|
+
const isRetryableConflict = (error) => {
|
|
3
|
+
if (typeof error !== "object" || error === null) return false;
|
|
4
|
+
if ("code" in error && [
|
|
5
|
+
"ER_DUP_ENTRY",
|
|
6
|
+
"ER_LOCK_DEADLOCK",
|
|
7
|
+
"ER_LOCK_WAIT_TIMEOUT",
|
|
8
|
+
"40001",
|
|
9
|
+
"40P01"
|
|
10
|
+
].includes(String(error.code))) return true;
|
|
11
|
+
return "cause" in error && error.cause !== error && isRetryableConflict(error.cause);
|
|
12
|
+
};
|
|
13
|
+
const runInsightsTransaction = async (operation) => {
|
|
14
|
+
for (let attempt = 0;; attempt += 1) try {
|
|
15
|
+
await operation();
|
|
16
|
+
return;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (attempt >= 2 || !isRetryableConflict(error)) throw error;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { runInsightsTransaction };
|
package/dist/adapters/kysely.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
3
2
|
const require_fixedMigrator = require("../db/fixedMigrator.cjs");
|
|
3
|
+
const require_insightsTransaction = require("./insightsTransaction.cjs");
|
|
4
4
|
const require_kyselyCrud = require("./kyselyCrud.cjs");
|
|
5
5
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
6
6
|
let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
|
|
@@ -10,6 +10,7 @@ const createImplementation = (config) => {
|
|
|
10
10
|
const relationMode = config.relationMode ?? "foreign-keys";
|
|
11
11
|
return {
|
|
12
12
|
...require_kyselyCrud.createKyselyCrud(db, config.provider, relationMode),
|
|
13
|
+
recordInsights: (input) => require_insightsTransaction.runInsightsTransaction(() => db.transaction().execute((transaction) => require_kyselyCrud.recordKyselyInsights(transaction, config.provider, input))),
|
|
13
14
|
deleteChannel: (input) => db.transaction().execute((transaction) => require_kyselyCrud.createKyselyCrud(transaction, config.provider, relationMode).deleteChannel(input)),
|
|
14
15
|
create: (input) => db.transaction().execute((transaction) => require_kyselyCrud.createKyselyCrud(transaction, config.provider, relationMode).create(input)),
|
|
15
16
|
update: (input) => db.transaction().execute((transaction) => require_kyselyCrud.createKyselyCrud(transaction, config.provider, relationMode).update(input)),
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { DatabaseAdapterWithCapabilities, ORMSQLProvider, RelationMode } from "../db/types.cjs";
|
|
2
2
|
import { Kysely } from "kysely";
|
|
3
|
-
|
|
4
3
|
//#region src/adapters/kysely.d.ts
|
|
5
4
|
type KyselySQLProvider = Exclude<ORMSQLProvider, "mssql">;
|
|
6
5
|
interface KyselyAdapterConfig<TDatabase extends object = object> {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { DatabaseAdapterWithCapabilities, ORMSQLProvider, RelationMode } from "../db/types.mjs";
|
|
2
2
|
import { Kysely } from "kysely";
|
|
3
|
-
|
|
4
3
|
//#region src/adapters/kysely.d.ts
|
|
5
4
|
type KyselySQLProvider = Exclude<ORMSQLProvider, "mssql">;
|
|
6
5
|
interface KyselyAdapterConfig<TDatabase extends object = object> {
|
package/dist/adapters/kysely.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createKyselyMigrator } from "../db/fixedMigrator.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { runInsightsTransaction } from "./insightsTransaction.mjs";
|
|
3
|
+
import { createKyselyCrud, recordKyselyInsights } from "./kyselyCrud.mjs";
|
|
3
4
|
import { createDatabasePlugin } from "@hot-updater/plugin-core";
|
|
4
5
|
import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
|
|
5
6
|
//#region src/adapters/kysely.ts
|
|
@@ -8,6 +9,7 @@ const createImplementation = (config) => {
|
|
|
8
9
|
const relationMode = config.relationMode ?? "foreign-keys";
|
|
9
10
|
return {
|
|
10
11
|
...createKyselyCrud(db, config.provider, relationMode),
|
|
12
|
+
recordInsights: (input) => runInsightsTransaction(() => db.transaction().execute((transaction) => recordKyselyInsights(transaction, config.provider, input))),
|
|
11
13
|
deleteChannel: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).deleteChannel(input)),
|
|
12
14
|
create: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).create(input)),
|
|
13
15
|
update: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).update(input)),
|