@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
|
@@ -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_kyselyQuery = require("./kyselyQuery.cjs");
|
|
@@ -6,6 +5,7 @@ let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
|
6
5
|
let kysely = require("kysely");
|
|
7
6
|
//#region src/adapters/kyselyCrud.ts
|
|
8
7
|
var KyselyAdapterInvariantError = class extends Error {
|
|
8
|
+
reason;
|
|
9
9
|
name = "KyselyAdapterInvariantError";
|
|
10
10
|
constructor(reason) {
|
|
11
11
|
super(`Kysely plugin invariant failed: ${reason}`);
|
|
@@ -20,7 +20,10 @@ const orderClause = (input) => {
|
|
|
20
20
|
if (clauses === void 0 || clauses.length === 0) return empty;
|
|
21
21
|
return kysely.sql` order by ${kysely.sql.join(clauses.map((clause) => {
|
|
22
22
|
const field = kysely.sql.ref(clause.field);
|
|
23
|
-
|
|
23
|
+
if (input?.model === "bundle_events" || input?.model === "bundle_installations") return clause.direction === "asc" ? kysely.sql`${field} asc` : kysely.sql`${field} desc`;
|
|
24
|
+
const nullOrder = (clause.nulls ?? (clause.direction === "asc" ? "last" : "first")) === "first" ? kysely.sql`${field} is null desc` : kysely.sql`${field} is null asc`;
|
|
25
|
+
const valueOrder = clause.direction === "asc" ? kysely.sql`${field} asc` : kysely.sql`${field} desc`;
|
|
26
|
+
return kysely.sql`${nullOrder}, ${valueOrder}`;
|
|
24
27
|
}), kysely.sql`, `)}`;
|
|
25
28
|
};
|
|
26
29
|
const insertRow = async (executor, table, row, provider, onConflict = void 0) => {
|
|
@@ -30,6 +33,26 @@ const insertRow = async (executor, table, row, provider, onConflict = void 0) =>
|
|
|
30
33
|
const result = onConflict === void 0 ? await kysely.sql`insert into ${kysely.sql.table(table)} (${columns}) values (${values})`.execute(executor) : provider === "mysql" ? await kysely.sql`insert ignore into ${kysely.sql.table(table)} (${columns}) values (${values})`.execute(executor) : provider === "sqlite" ? await kysely.sql`insert or ignore into ${kysely.sql.table(table)} (${columns}) values (${values})`.execute(executor) : await kysely.sql`insert into ${kysely.sql.table(table)} (${columns}) values (${values}) on conflict do nothing`.execute(executor);
|
|
31
34
|
return Number(result.numAffectedRows ?? 0) > 0;
|
|
32
35
|
};
|
|
36
|
+
const recordKyselyInsights = async (executor, provider, { event, installation }) => {
|
|
37
|
+
const insert = (table, row) => {
|
|
38
|
+
const entries = Object.entries(row);
|
|
39
|
+
return kysely.sql`insert into ${kysely.sql.table(table)} (${kysely.sql.join(entries.map(([field]) => kysely.sql.ref(field)))}) values (${kysely.sql.join(entries.map(([, value]) => value))})`;
|
|
40
|
+
};
|
|
41
|
+
if (provider === "mysql") {
|
|
42
|
+
if ((await kysely.sql`select id from bundle_events where id = ${event.id} for update`.execute(executor)).rows.length > 0) return;
|
|
43
|
+
await insert("bundle_events", event).execute(executor);
|
|
44
|
+
await kysely.sql`${insert("bundle_installations", installation)} on duplicate key update install_id = ${installation.install_id}`.execute(executor);
|
|
45
|
+
} else {
|
|
46
|
+
if ((await kysely.sql`${insert("bundle_events", event)} on conflict (id) do nothing returning id`.execute(executor)).rows.length === 0) return;
|
|
47
|
+
await kysely.sql`${insert("bundle_installations", installation)} on conflict (install_id) do nothing`.execute(executor);
|
|
48
|
+
}
|
|
49
|
+
const assignments = Object.entries(installation).map(([field, value]) => kysely.sql`${kysely.sql.ref(field)} = ${value}`);
|
|
50
|
+
await kysely.sql`update ${kysely.sql.table("bundle_installations")} set ${kysely.sql.join(assignments)}
|
|
51
|
+
where ${kysely.sql.ref("install_id")} = ${installation.install_id}
|
|
52
|
+
and (${kysely.sql.ref("received_at_ms")} < ${installation.received_at_ms}
|
|
53
|
+
or (${kysely.sql.ref("received_at_ms")} = ${installation.received_at_ms}
|
|
54
|
+
and ${kysely.sql.ref("id")} < ${installation.id}))`.execute(executor);
|
|
55
|
+
};
|
|
33
56
|
const updateBundle = async (executor, id, update) => {
|
|
34
57
|
const assignments = Object.entries(update).filter(([, value]) => value !== void 0).map(([field, value]) => kysely.sql`${kysely.sql.ref(field)} = ${value}`);
|
|
35
58
|
if (assignments.length === 0) return;
|
|
@@ -44,7 +67,7 @@ const updateRow = async (executor, table, keyField, key, update) => {
|
|
|
44
67
|
await kysely.sql`update ${kysely.sql.table(table)} set ${kysely.sql.join(assignments)} where ${kysely.sql.ref(keyField)} = ${key}`.execute(executor);
|
|
45
68
|
};
|
|
46
69
|
const assertBundleReferences = async (executor, provider, relationMode, bundleId, baseBundleId) => {
|
|
47
|
-
const ids = [
|
|
70
|
+
const ids = [.../* @__PURE__ */ new Set([bundleId, baseBundleId])].sort((left, right) => left.localeCompare(right));
|
|
48
71
|
const result = await kysely.sql`select ${kysely.sql.ref("id")} from ${kysely.sql.table("bundles")} where ${kysely.sql.ref("id")} in (${kysely.sql.join(ids)}) order by ${kysely.sql.ref("id")}${lockClause(provider, relationMode)}`.execute(executor);
|
|
49
72
|
const storedIds = new Set(result.rows.map(({ id }) => id));
|
|
50
73
|
if (!storedIds.has(bundleId)) throw new KyselyAdapterInvariantError("bundle_patches.bundle_id.foreign-key");
|
|
@@ -96,6 +119,9 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
96
119
|
case "bundle_events":
|
|
97
120
|
await insertRow(executor, "bundle_events", input.data, provider);
|
|
98
121
|
return input.data;
|
|
122
|
+
case "bundle_installations":
|
|
123
|
+
await insertRow(executor, "bundle_installations", input.data, provider, input.onConflict);
|
|
124
|
+
return input.data;
|
|
99
125
|
case "releases":
|
|
100
126
|
await insertRow(executor, "releases", require_databasePluginUtils.toStoredReleaseRow(input.data, provider), provider);
|
|
101
127
|
return input.data;
|
|
@@ -111,6 +137,19 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
111
137
|
}
|
|
112
138
|
},
|
|
113
139
|
async update(input) {
|
|
140
|
+
if (input.model === "bundle_installations") {
|
|
141
|
+
const installId = input.where.find((item) => item.field === "install_id" && (item.operator === void 0 || item.operator === "eq") && typeof item.value === "string")?.value;
|
|
142
|
+
if (typeof installId !== "string") throw new KyselyAdapterInvariantError("bundle_installations.update.selector");
|
|
143
|
+
const assignments = Object.entries(input.update).filter(([, value]) => value !== void 0).map(([field, value]) => kysely.sql`${kysely.sql.ref(field)} = ${value}`);
|
|
144
|
+
const where = require_kyselyQuery.buildKyselyWhere(provider, input.where);
|
|
145
|
+
let updated = false;
|
|
146
|
+
if (assignments.length > 0 && where !== void 0) {
|
|
147
|
+
const result = await kysely.sql`update ${kysely.sql.table("bundle_installations")} set ${kysely.sql.join(assignments)} where ${where}`.execute(executor);
|
|
148
|
+
updated = Number(result.numAffectedRows ?? 0) > 0;
|
|
149
|
+
}
|
|
150
|
+
if (!updated) return null;
|
|
151
|
+
return (await kysely.sql`select * from ${kysely.sql.table("bundle_installations")} where ${kysely.sql.ref("install_id")} = ${installId} limit 1`.execute(executor)).rows[0] ?? null;
|
|
152
|
+
}
|
|
114
153
|
const selector = input.where[0];
|
|
115
154
|
if (selector === void 0 || typeof selector.value !== "string") throw new KyselyAdapterInvariantError(`${input.model}.update.selector`);
|
|
116
155
|
if (input.model === "api_keys") {
|
|
@@ -172,9 +211,11 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
172
211
|
async count(input) {
|
|
173
212
|
if (input.distinct !== void 0) throw new _hot_updater_plugin_core.DatabasePluginInputError("invalid-operation");
|
|
174
213
|
switch (input.model) {
|
|
214
|
+
case "bundle_events": return countRows(executor, "bundle_events", require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
175
215
|
case "bundles": return countRows(executor, "bundles", require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
176
216
|
case "bundle_patches": return countRows(executor, "bundle_patches", require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
177
217
|
case "releases": return countRows(executor, "releases", require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
218
|
+
case "bundle_installations": return countRows(executor, "bundle_installations", require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
178
219
|
}
|
|
179
220
|
},
|
|
180
221
|
async findOne(input) {
|
|
@@ -206,6 +247,10 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
206
247
|
const row = (await kysely.sql`select * from ${kysely.sql.table("release_catalogs")}${where} limit 1`.execute(executor)).rows[0];
|
|
207
248
|
return row === void 0 ? null : require_databasePluginUtils.fromStoredReleaseCatalogRow(row);
|
|
208
249
|
}
|
|
250
|
+
case "bundle_installations": {
|
|
251
|
+
const where = whereClause(require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
252
|
+
return (await kysely.sql`select * from ${kysely.sql.table("bundle_installations")}${where} limit 1`.execute(executor)).rows[0] ?? null;
|
|
253
|
+
}
|
|
209
254
|
}
|
|
210
255
|
},
|
|
211
256
|
async findMany(input) {
|
|
@@ -227,6 +272,11 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
227
272
|
const order = orderClause(input);
|
|
228
273
|
return [...(await kysely.sql`select * from ${kysely.sql.table("bundle_events")}${where}${order}${pagination}`.execute(executor)).rows];
|
|
229
274
|
}
|
|
275
|
+
case "bundle_installations": {
|
|
276
|
+
const where = whereClause(require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
277
|
+
const order = orderClause(input);
|
|
278
|
+
return [...(await kysely.sql`select * from ${kysely.sql.table("bundle_installations")}${where}${order}${pagination}`.execute(executor)).rows];
|
|
279
|
+
}
|
|
230
280
|
case "api_keys": {
|
|
231
281
|
const where = whereClause(require_kyselyQuery.buildKyselyWhere(provider, input.where));
|
|
232
282
|
const order = orderClause(input);
|
|
@@ -252,3 +302,4 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
252
302
|
});
|
|
253
303
|
//#endregion
|
|
254
304
|
exports.createKyselyCrud = createKyselyCrud;
|
|
305
|
+
exports.recordKyselyInsights = recordKyselyInsights;
|
|
@@ -5,6 +5,7 @@ import { DatabasePluginInputError } from "@hot-updater/plugin-core";
|
|
|
5
5
|
import { sql } from "kysely";
|
|
6
6
|
//#region src/adapters/kyselyCrud.ts
|
|
7
7
|
var KyselyAdapterInvariantError = class extends Error {
|
|
8
|
+
reason;
|
|
8
9
|
name = "KyselyAdapterInvariantError";
|
|
9
10
|
constructor(reason) {
|
|
10
11
|
super(`Kysely plugin invariant failed: ${reason}`);
|
|
@@ -19,7 +20,10 @@ const orderClause = (input) => {
|
|
|
19
20
|
if (clauses === void 0 || clauses.length === 0) return empty;
|
|
20
21
|
return sql` order by ${sql.join(clauses.map((clause) => {
|
|
21
22
|
const field = sql.ref(clause.field);
|
|
22
|
-
|
|
23
|
+
if (input?.model === "bundle_events" || input?.model === "bundle_installations") return clause.direction === "asc" ? sql`${field} asc` : sql`${field} desc`;
|
|
24
|
+
const nullOrder = (clause.nulls ?? (clause.direction === "asc" ? "last" : "first")) === "first" ? sql`${field} is null desc` : sql`${field} is null asc`;
|
|
25
|
+
const valueOrder = clause.direction === "asc" ? sql`${field} asc` : sql`${field} desc`;
|
|
26
|
+
return sql`${nullOrder}, ${valueOrder}`;
|
|
23
27
|
}), sql`, `)}`;
|
|
24
28
|
};
|
|
25
29
|
const insertRow = async (executor, table, row, provider, onConflict = void 0) => {
|
|
@@ -29,6 +33,26 @@ const insertRow = async (executor, table, row, provider, onConflict = void 0) =>
|
|
|
29
33
|
const result = onConflict === void 0 ? await sql`insert into ${sql.table(table)} (${columns}) values (${values})`.execute(executor) : provider === "mysql" ? await sql`insert ignore into ${sql.table(table)} (${columns}) values (${values})`.execute(executor) : provider === "sqlite" ? await sql`insert or ignore into ${sql.table(table)} (${columns}) values (${values})`.execute(executor) : await sql`insert into ${sql.table(table)} (${columns}) values (${values}) on conflict do nothing`.execute(executor);
|
|
30
34
|
return Number(result.numAffectedRows ?? 0) > 0;
|
|
31
35
|
};
|
|
36
|
+
const recordKyselyInsights = async (executor, provider, { event, installation }) => {
|
|
37
|
+
const insert = (table, row) => {
|
|
38
|
+
const entries = Object.entries(row);
|
|
39
|
+
return sql`insert into ${sql.table(table)} (${sql.join(entries.map(([field]) => sql.ref(field)))}) values (${sql.join(entries.map(([, value]) => value))})`;
|
|
40
|
+
};
|
|
41
|
+
if (provider === "mysql") {
|
|
42
|
+
if ((await sql`select id from bundle_events where id = ${event.id} for update`.execute(executor)).rows.length > 0) return;
|
|
43
|
+
await insert("bundle_events", event).execute(executor);
|
|
44
|
+
await sql`${insert("bundle_installations", installation)} on duplicate key update install_id = ${installation.install_id}`.execute(executor);
|
|
45
|
+
} else {
|
|
46
|
+
if ((await sql`${insert("bundle_events", event)} on conflict (id) do nothing returning id`.execute(executor)).rows.length === 0) return;
|
|
47
|
+
await sql`${insert("bundle_installations", installation)} on conflict (install_id) do nothing`.execute(executor);
|
|
48
|
+
}
|
|
49
|
+
const assignments = Object.entries(installation).map(([field, value]) => sql`${sql.ref(field)} = ${value}`);
|
|
50
|
+
await sql`update ${sql.table("bundle_installations")} set ${sql.join(assignments)}
|
|
51
|
+
where ${sql.ref("install_id")} = ${installation.install_id}
|
|
52
|
+
and (${sql.ref("received_at_ms")} < ${installation.received_at_ms}
|
|
53
|
+
or (${sql.ref("received_at_ms")} = ${installation.received_at_ms}
|
|
54
|
+
and ${sql.ref("id")} < ${installation.id}))`.execute(executor);
|
|
55
|
+
};
|
|
32
56
|
const updateBundle = async (executor, id, update) => {
|
|
33
57
|
const assignments = Object.entries(update).filter(([, value]) => value !== void 0).map(([field, value]) => sql`${sql.ref(field)} = ${value}`);
|
|
34
58
|
if (assignments.length === 0) return;
|
|
@@ -43,7 +67,7 @@ const updateRow = async (executor, table, keyField, key, update) => {
|
|
|
43
67
|
await sql`update ${sql.table(table)} set ${sql.join(assignments)} where ${sql.ref(keyField)} = ${key}`.execute(executor);
|
|
44
68
|
};
|
|
45
69
|
const assertBundleReferences = async (executor, provider, relationMode, bundleId, baseBundleId) => {
|
|
46
|
-
const ids = [
|
|
70
|
+
const ids = [.../* @__PURE__ */ new Set([bundleId, baseBundleId])].sort((left, right) => left.localeCompare(right));
|
|
47
71
|
const result = await sql`select ${sql.ref("id")} from ${sql.table("bundles")} where ${sql.ref("id")} in (${sql.join(ids)}) order by ${sql.ref("id")}${lockClause(provider, relationMode)}`.execute(executor);
|
|
48
72
|
const storedIds = new Set(result.rows.map(({ id }) => id));
|
|
49
73
|
if (!storedIds.has(bundleId)) throw new KyselyAdapterInvariantError("bundle_patches.bundle_id.foreign-key");
|
|
@@ -95,6 +119,9 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
95
119
|
case "bundle_events":
|
|
96
120
|
await insertRow(executor, "bundle_events", input.data, provider);
|
|
97
121
|
return input.data;
|
|
122
|
+
case "bundle_installations":
|
|
123
|
+
await insertRow(executor, "bundle_installations", input.data, provider, input.onConflict);
|
|
124
|
+
return input.data;
|
|
98
125
|
case "releases":
|
|
99
126
|
await insertRow(executor, "releases", toStoredReleaseRow(input.data, provider), provider);
|
|
100
127
|
return input.data;
|
|
@@ -110,6 +137,19 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
110
137
|
}
|
|
111
138
|
},
|
|
112
139
|
async update(input) {
|
|
140
|
+
if (input.model === "bundle_installations") {
|
|
141
|
+
const installId = input.where.find((item) => item.field === "install_id" && (item.operator === void 0 || item.operator === "eq") && typeof item.value === "string")?.value;
|
|
142
|
+
if (typeof installId !== "string") throw new KyselyAdapterInvariantError("bundle_installations.update.selector");
|
|
143
|
+
const assignments = Object.entries(input.update).filter(([, value]) => value !== void 0).map(([field, value]) => sql`${sql.ref(field)} = ${value}`);
|
|
144
|
+
const where = buildKyselyWhere(provider, input.where);
|
|
145
|
+
let updated = false;
|
|
146
|
+
if (assignments.length > 0 && where !== void 0) {
|
|
147
|
+
const result = await sql`update ${sql.table("bundle_installations")} set ${sql.join(assignments)} where ${where}`.execute(executor);
|
|
148
|
+
updated = Number(result.numAffectedRows ?? 0) > 0;
|
|
149
|
+
}
|
|
150
|
+
if (!updated) return null;
|
|
151
|
+
return (await sql`select * from ${sql.table("bundle_installations")} where ${sql.ref("install_id")} = ${installId} limit 1`.execute(executor)).rows[0] ?? null;
|
|
152
|
+
}
|
|
113
153
|
const selector = input.where[0];
|
|
114
154
|
if (selector === void 0 || typeof selector.value !== "string") throw new KyselyAdapterInvariantError(`${input.model}.update.selector`);
|
|
115
155
|
if (input.model === "api_keys") {
|
|
@@ -171,9 +211,11 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
171
211
|
async count(input) {
|
|
172
212
|
if (input.distinct !== void 0) throw new DatabasePluginInputError("invalid-operation");
|
|
173
213
|
switch (input.model) {
|
|
214
|
+
case "bundle_events": return countRows(executor, "bundle_events", buildKyselyWhere(provider, input.where));
|
|
174
215
|
case "bundles": return countRows(executor, "bundles", buildKyselyWhere(provider, input.where));
|
|
175
216
|
case "bundle_patches": return countRows(executor, "bundle_patches", buildKyselyWhere(provider, input.where));
|
|
176
217
|
case "releases": return countRows(executor, "releases", buildKyselyWhere(provider, input.where));
|
|
218
|
+
case "bundle_installations": return countRows(executor, "bundle_installations", buildKyselyWhere(provider, input.where));
|
|
177
219
|
}
|
|
178
220
|
},
|
|
179
221
|
async findOne(input) {
|
|
@@ -205,6 +247,10 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
205
247
|
const row = (await sql`select * from ${sql.table("release_catalogs")}${where} limit 1`.execute(executor)).rows[0];
|
|
206
248
|
return row === void 0 ? null : fromStoredReleaseCatalogRow(row);
|
|
207
249
|
}
|
|
250
|
+
case "bundle_installations": {
|
|
251
|
+
const where = whereClause(buildKyselyWhere(provider, input.where));
|
|
252
|
+
return (await sql`select * from ${sql.table("bundle_installations")}${where} limit 1`.execute(executor)).rows[0] ?? null;
|
|
253
|
+
}
|
|
208
254
|
}
|
|
209
255
|
},
|
|
210
256
|
async findMany(input) {
|
|
@@ -226,6 +272,11 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
226
272
|
const order = orderClause(input);
|
|
227
273
|
return [...(await sql`select * from ${sql.table("bundle_events")}${where}${order}${pagination}`.execute(executor)).rows];
|
|
228
274
|
}
|
|
275
|
+
case "bundle_installations": {
|
|
276
|
+
const where = whereClause(buildKyselyWhere(provider, input.where));
|
|
277
|
+
const order = orderClause(input);
|
|
278
|
+
return [...(await sql`select * from ${sql.table("bundle_installations")}${where}${order}${pagination}`.execute(executor)).rows];
|
|
279
|
+
}
|
|
229
280
|
case "api_keys": {
|
|
230
281
|
const where = whereClause(buildKyselyWhere(provider, input.where));
|
|
231
282
|
const order = orderClause(input);
|
|
@@ -250,4 +301,4 @@ const createKyselyCrud = (executor, provider, relationMode = "foreign-keys") =>
|
|
|
250
301
|
}
|
|
251
302
|
});
|
|
252
303
|
//#endregion
|
|
253
|
-
export { createKyselyCrud };
|
|
304
|
+
export { createKyselyCrud, recordKyselyInsights };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
1
|
const require_databasePluginUtils = require("./databasePluginUtils.cjs");
|
|
3
2
|
let kysely = require("kysely");
|
|
4
3
|
//#region src/adapters/kyselyQuery.ts
|
|
@@ -9,7 +8,8 @@ const stringPredicate = (provider, field, operator, value, insensitive) => {
|
|
|
9
8
|
const column = kysely.sql.ref(field);
|
|
10
9
|
if (provider === "sqlite" && !insensitive) {
|
|
11
10
|
const literal = require_databasePluginUtils.escapeGlobPattern(value);
|
|
12
|
-
|
|
11
|
+
const pattern = operator === "contains" ? `*${literal}*` : operator === "starts_with" ? `${literal}*` : `*${literal}`;
|
|
12
|
+
return kysely.sql`${column} glob ${pattern}`;
|
|
13
13
|
}
|
|
14
14
|
const literal = require_databasePluginUtils.escapeLikePattern(value);
|
|
15
15
|
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
@@ -8,7 +8,8 @@ const stringPredicate = (provider, field, operator, value, insensitive) => {
|
|
|
8
8
|
const column = sql.ref(field);
|
|
9
9
|
if (provider === "sqlite" && !insensitive) {
|
|
10
10
|
const literal = escapeGlobPattern(value);
|
|
11
|
-
|
|
11
|
+
const pattern = operator === "contains" ? `*${literal}*` : operator === "starts_with" ? `${literal}*` : `*${literal}`;
|
|
12
|
+
return sql`${column} glob ${pattern}`;
|
|
12
13
|
}
|
|
13
14
|
const literal = escapeLikePattern(value);
|
|
14
15
|
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
@@ -1,15 +1,41 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
3
2
|
const require_fixedMigratorMongo = require("../db/fixedMigratorMongo.cjs");
|
|
4
3
|
const require_mongodbCollections = require("./mongodbCollections.cjs");
|
|
5
4
|
const require_mongodbReads = require("./mongodbReads.cjs");
|
|
6
5
|
const require_mongodbWrites = require("./mongodbWrites.cjs");
|
|
7
6
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
8
7
|
let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
|
|
8
|
+
let mongodb = require("mongodb");
|
|
9
9
|
//#region src/adapters/mongodb.ts
|
|
10
10
|
const createMongoImplementation = (client, session) => {
|
|
11
11
|
const collections = require_mongodbCollections.createMongoCollections(client);
|
|
12
12
|
return {
|
|
13
|
+
recordInsights: async (input) => {
|
|
14
|
+
const record = () => client.withSession((recordSession) => recordSession.withTransaction(async () => {
|
|
15
|
+
const records = require_mongodbCollections.createMongoCollections(client);
|
|
16
|
+
const options = {
|
|
17
|
+
session: recordSession,
|
|
18
|
+
collation: { locale: "simple" }
|
|
19
|
+
};
|
|
20
|
+
if ((await records.bundleEvents.updateOne({ id: input.event.id }, { $setOnInsert: input.event }, {
|
|
21
|
+
...options,
|
|
22
|
+
upsert: true
|
|
23
|
+
})).upsertedCount === 0) return;
|
|
24
|
+
const current = await records.bundleInstallations.findOne({ install_id: input.installation.install_id }, options);
|
|
25
|
+
if (current === null) await records.bundleInstallations.insertOne({ ...input.installation }, { session: recordSession });
|
|
26
|
+
else if (input.installation.received_at_ms > current.received_at_ms || input.installation.received_at_ms === current.received_at_ms && (0, _hot_updater_plugin_core.compareInsightsText)(input.installation.id, current.id) > 0) await records.bundleInstallations.updateOne({ install_id: input.installation.install_id }, { $set: input.installation }, options);
|
|
27
|
+
}, {
|
|
28
|
+
readConcern: { level: "snapshot" },
|
|
29
|
+
readPreference: "primary",
|
|
30
|
+
writeConcern: { w: "majority" }
|
|
31
|
+
}));
|
|
32
|
+
try {
|
|
33
|
+
await record();
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (!(error instanceof mongodb.MongoServerError) || error.code !== 11e3) throw error;
|
|
36
|
+
await record();
|
|
37
|
+
}
|
|
38
|
+
},
|
|
13
39
|
...require_mongodbWrites.createMongoWrites(collections, session),
|
|
14
40
|
...require_mongodbReads.createMongoReads(collections, session)
|
|
15
41
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DatabaseAdapterWithCapabilities } from "../db/types.cjs";
|
|
2
2
|
import { MongoClient } from "mongodb";
|
|
3
|
-
|
|
4
3
|
//#region src/adapters/mongodb.d.ts
|
|
5
4
|
interface MongoDBConfig {
|
|
6
5
|
readonly client: MongoClient;
|
|
6
|
+
/** Enables atomic catalog commits. Insights always requires MongoDB 5+ on a replica set or sharded cluster. */
|
|
7
7
|
readonly transactions?: boolean;
|
|
8
8
|
}
|
|
9
9
|
declare const mongoAdapter: (config: MongoDBConfig) => DatabaseAdapterWithCapabilities;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DatabaseAdapterWithCapabilities } from "../db/types.mjs";
|
|
2
2
|
import { MongoClient } from "mongodb";
|
|
3
|
-
|
|
4
3
|
//#region src/adapters/mongodb.d.ts
|
|
5
4
|
interface MongoDBConfig {
|
|
6
5
|
readonly client: MongoClient;
|
|
6
|
+
/** Enables atomic catalog commits. Insights always requires MongoDB 5+ on a replica set or sharded cluster. */
|
|
7
7
|
readonly transactions?: boolean;
|
|
8
8
|
}
|
|
9
9
|
declare const mongoAdapter: (config: MongoDBConfig) => DatabaseAdapterWithCapabilities;
|
|
@@ -2,12 +2,39 @@ import { createMongoMigrator } from "../db/fixedMigratorMongo.mjs";
|
|
|
2
2
|
import { createMongoCollections } from "./mongodbCollections.mjs";
|
|
3
3
|
import { createMongoReads } from "./mongodbReads.mjs";
|
|
4
4
|
import { createMongoWrites } from "./mongodbWrites.mjs";
|
|
5
|
-
import { createDatabasePlugin } from "@hot-updater/plugin-core";
|
|
5
|
+
import { compareInsightsText, createDatabasePlugin } from "@hot-updater/plugin-core";
|
|
6
6
|
import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
|
|
7
|
+
import { MongoServerError } from "mongodb";
|
|
7
8
|
//#region src/adapters/mongodb.ts
|
|
8
9
|
const createMongoImplementation = (client, session) => {
|
|
9
10
|
const collections = createMongoCollections(client);
|
|
10
11
|
return {
|
|
12
|
+
recordInsights: async (input) => {
|
|
13
|
+
const record = () => client.withSession((recordSession) => recordSession.withTransaction(async () => {
|
|
14
|
+
const records = createMongoCollections(client);
|
|
15
|
+
const options = {
|
|
16
|
+
session: recordSession,
|
|
17
|
+
collation: { locale: "simple" }
|
|
18
|
+
};
|
|
19
|
+
if ((await records.bundleEvents.updateOne({ id: input.event.id }, { $setOnInsert: input.event }, {
|
|
20
|
+
...options,
|
|
21
|
+
upsert: true
|
|
22
|
+
})).upsertedCount === 0) return;
|
|
23
|
+
const current = await records.bundleInstallations.findOne({ install_id: input.installation.install_id }, options);
|
|
24
|
+
if (current === null) await records.bundleInstallations.insertOne({ ...input.installation }, { session: recordSession });
|
|
25
|
+
else if (input.installation.received_at_ms > current.received_at_ms || input.installation.received_at_ms === current.received_at_ms && compareInsightsText(input.installation.id, current.id) > 0) await records.bundleInstallations.updateOne({ install_id: input.installation.install_id }, { $set: input.installation }, options);
|
|
26
|
+
}, {
|
|
27
|
+
readConcern: { level: "snapshot" },
|
|
28
|
+
readPreference: "primary",
|
|
29
|
+
writeConcern: { w: "majority" }
|
|
30
|
+
}));
|
|
31
|
+
try {
|
|
32
|
+
await record();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (!(error instanceof MongoServerError) || error.code !== 11e3) throw error;
|
|
35
|
+
await record();
|
|
36
|
+
}
|
|
37
|
+
},
|
|
11
38
|
...createMongoWrites(collections, session),
|
|
12
39
|
...createMongoReads(collections, session)
|
|
13
40
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/adapters/mongodbCollections.ts
|
|
2
2
|
var MongoAdapterConstraintError = class extends Error {
|
|
3
|
+
reason;
|
|
3
4
|
name = "MongoAdapterConstraintError";
|
|
4
5
|
constructor(reason) {
|
|
5
6
|
super(`MongoDB adapter constraint failed: ${reason}`);
|
|
@@ -19,6 +20,7 @@ const createMongoCollections = (client) => {
|
|
|
19
20
|
bundles: database.collection("bundles"),
|
|
20
21
|
bundlePatches: database.collection("bundle_patches"),
|
|
21
22
|
bundleEvents: database.collection("bundle_events"),
|
|
23
|
+
bundleInstallations: database.collection("bundle_installations"),
|
|
22
24
|
channels: database.collection("channels"),
|
|
23
25
|
apiKeys: database.collection("api_keys"),
|
|
24
26
|
releases: database.collection("releases"),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/adapters/mongodbCollections.ts
|
|
2
2
|
var MongoAdapterConstraintError = class extends Error {
|
|
3
|
+
reason;
|
|
3
4
|
name = "MongoAdapterConstraintError";
|
|
4
5
|
constructor(reason) {
|
|
5
6
|
super(`MongoDB adapter constraint failed: ${reason}`);
|
|
@@ -19,6 +20,7 @@ const createMongoCollections = (client) => {
|
|
|
19
20
|
bundles: database.collection("bundles"),
|
|
20
21
|
bundlePatches: database.collection("bundle_patches"),
|
|
21
22
|
bundleEvents: database.collection("bundle_events"),
|
|
23
|
+
bundleInstallations: database.collection("bundle_installations"),
|
|
22
24
|
channels: database.collection("channels"),
|
|
23
25
|
apiKeys: database.collection("api_keys"),
|
|
24
26
|
releases: database.collection("releases"),
|
|
@@ -32,14 +32,27 @@ const predicate = (where) => {
|
|
|
32
32
|
case "ends_with": return { $expr: stringExpression(where.field, where.operator, where.value, where.mode) };
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
|
-
const createMongoWhereDocument = (where) => {
|
|
35
|
+
const createMongoWhereDocument = (where, toPredicate = predicate) => {
|
|
36
36
|
const items = Array.isArray(where) ? where : [];
|
|
37
37
|
const first = items[0];
|
|
38
38
|
if (first === void 0) return {};
|
|
39
|
-
let result =
|
|
40
|
-
for (const item of items.slice(1)) result = { [item.connector === "OR" ? "$or" : "$and"]: [result,
|
|
39
|
+
let result = toPredicate(first);
|
|
40
|
+
for (const item of items.slice(1)) result = { [item.connector === "OR" ? "$or" : "$and"]: [result, toPredicate(item)] };
|
|
41
41
|
return result;
|
|
42
42
|
};
|
|
43
|
+
const insightsPredicate = (where) => {
|
|
44
|
+
if ("mode" in where && where.mode === "insensitive") return predicate(where);
|
|
45
|
+
switch (where.operator) {
|
|
46
|
+
case void 0:
|
|
47
|
+
case "eq": return { [where.field]: { $eq: where.value } };
|
|
48
|
+
case "gt":
|
|
49
|
+
case "gte":
|
|
50
|
+
case "lt":
|
|
51
|
+
case "lte":
|
|
52
|
+
case "in": return { [where.field]: { [`$${where.operator}`]: where.value } };
|
|
53
|
+
default: return predicate(where);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
43
56
|
function createMongoBundleWhere(where) {
|
|
44
57
|
return createMongoWhereDocument(where);
|
|
45
58
|
}
|
|
@@ -47,7 +60,10 @@ function createMongoPatchWhere(where) {
|
|
|
47
60
|
return createMongoWhereDocument(where);
|
|
48
61
|
}
|
|
49
62
|
function createMongoEventWhere(where) {
|
|
50
|
-
return createMongoWhereDocument(where);
|
|
63
|
+
return createMongoWhereDocument(where, insightsPredicate);
|
|
64
|
+
}
|
|
65
|
+
function createMongoInstallationWhere(where) {
|
|
66
|
+
return createMongoWhereDocument(where, insightsPredicate);
|
|
51
67
|
}
|
|
52
68
|
function createMongoApiKeyWhere(where) {
|
|
53
69
|
return createMongoWhereDocument(where);
|
|
@@ -71,6 +87,7 @@ exports.createMongoApiKeyWhere = createMongoApiKeyWhere;
|
|
|
71
87
|
exports.createMongoBundleWhere = createMongoBundleWhere;
|
|
72
88
|
exports.createMongoChannelWhere = createMongoChannelWhere;
|
|
73
89
|
exports.createMongoEventWhere = createMongoEventWhere;
|
|
90
|
+
exports.createMongoInstallationWhere = createMongoInstallationWhere;
|
|
74
91
|
exports.createMongoPatchWhere = createMongoPatchWhere;
|
|
75
92
|
exports.createMongoReleaseCatalogWhere = createMongoReleaseCatalogWhere;
|
|
76
93
|
exports.createMongoReleaseWhere = createMongoReleaseWhere;
|
|
@@ -32,14 +32,27 @@ const predicate = (where) => {
|
|
|
32
32
|
case "ends_with": return { $expr: stringExpression(where.field, where.operator, where.value, where.mode) };
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
|
-
const createMongoWhereDocument = (where) => {
|
|
35
|
+
const createMongoWhereDocument = (where, toPredicate = predicate) => {
|
|
36
36
|
const items = Array.isArray(where) ? where : [];
|
|
37
37
|
const first = items[0];
|
|
38
38
|
if (first === void 0) return {};
|
|
39
|
-
let result =
|
|
40
|
-
for (const item of items.slice(1)) result = { [item.connector === "OR" ? "$or" : "$and"]: [result,
|
|
39
|
+
let result = toPredicate(first);
|
|
40
|
+
for (const item of items.slice(1)) result = { [item.connector === "OR" ? "$or" : "$and"]: [result, toPredicate(item)] };
|
|
41
41
|
return result;
|
|
42
42
|
};
|
|
43
|
+
const insightsPredicate = (where) => {
|
|
44
|
+
if ("mode" in where && where.mode === "insensitive") return predicate(where);
|
|
45
|
+
switch (where.operator) {
|
|
46
|
+
case void 0:
|
|
47
|
+
case "eq": return { [where.field]: { $eq: where.value } };
|
|
48
|
+
case "gt":
|
|
49
|
+
case "gte":
|
|
50
|
+
case "lt":
|
|
51
|
+
case "lte":
|
|
52
|
+
case "in": return { [where.field]: { [`$${where.operator}`]: where.value } };
|
|
53
|
+
default: return predicate(where);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
43
56
|
function createMongoBundleWhere(where) {
|
|
44
57
|
return createMongoWhereDocument(where);
|
|
45
58
|
}
|
|
@@ -47,7 +60,10 @@ function createMongoPatchWhere(where) {
|
|
|
47
60
|
return createMongoWhereDocument(where);
|
|
48
61
|
}
|
|
49
62
|
function createMongoEventWhere(where) {
|
|
50
|
-
return createMongoWhereDocument(where);
|
|
63
|
+
return createMongoWhereDocument(where, insightsPredicate);
|
|
64
|
+
}
|
|
65
|
+
function createMongoInstallationWhere(where) {
|
|
66
|
+
return createMongoWhereDocument(where, insightsPredicate);
|
|
51
67
|
}
|
|
52
68
|
function createMongoApiKeyWhere(where) {
|
|
53
69
|
return createMongoWhereDocument(where);
|
|
@@ -67,4 +83,4 @@ const createMongoSort = (input) => {
|
|
|
67
83
|
return Object.fromEntries(clauses.map((clause) => [clause.field, clause.direction === "asc" ? 1 : -1]));
|
|
68
84
|
};
|
|
69
85
|
//#endregion
|
|
70
|
-
export { createMongoApiKeyWhere, createMongoBundleWhere, createMongoChannelWhere, createMongoEventWhere, createMongoPatchWhere, createMongoReleaseCatalogWhere, createMongoReleaseWhere, createMongoSort };
|
|
86
|
+
export { createMongoApiKeyWhere, createMongoBundleWhere, createMongoChannelWhere, createMongoEventWhere, createMongoInstallationWhere, createMongoPatchWhere, createMongoReleaseCatalogWhere, createMongoReleaseWhere, createMongoSort };
|