@hot-updater/server 1.0.0-rc.1 → 1.0.0-rc.14

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.
Files changed (194) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +1 -1
  2. package/dist/adapters/databaseConstraintErrors.cjs +0 -1
  3. package/dist/adapters/databasePluginUtils.cjs +14 -1
  4. package/dist/adapters/databasePluginUtils.mjs +14 -2
  5. package/dist/adapters/drizzle.cjs +8 -3
  6. package/dist/adapters/drizzle.d.cts +0 -1
  7. package/dist/adapters/drizzle.d.mts +0 -1
  8. package/dist/adapters/drizzle.mjs +9 -3
  9. package/dist/adapters/drizzleCrud.cjs +93 -3
  10. package/dist/adapters/drizzleCrud.mjs +93 -5
  11. package/dist/adapters/drizzleLazyDB.cjs +2 -0
  12. package/dist/adapters/drizzleLazyDB.mjs +2 -0
  13. package/dist/adapters/drizzleQuery.cjs +3 -2
  14. package/dist/adapters/drizzleQuery.mjs +3 -1
  15. package/dist/adapters/kysely.cjs +1 -1
  16. package/dist/adapters/kysely.d.cts +0 -1
  17. package/dist/adapters/kysely.d.mts +0 -1
  18. package/dist/adapters/kysely.mjs +2 -1
  19. package/dist/adapters/kyselyCrud.cjs +44 -5
  20. package/dist/adapters/kyselyCrud.mjs +45 -6
  21. package/dist/adapters/kyselyQuery.cjs +2 -2
  22. package/dist/adapters/kyselyQuery.mjs +2 -1
  23. package/dist/adapters/mongodb.cjs +36 -1
  24. package/dist/adapters/mongodb.d.cts +1 -1
  25. package/dist/adapters/mongodb.d.mts +1 -1
  26. package/dist/adapters/mongodb.mjs +36 -0
  27. package/dist/adapters/mongodbCollections.cjs +2 -0
  28. package/dist/adapters/mongodbCollections.mjs +2 -0
  29. package/dist/adapters/mongodbQuery.cjs +17 -4
  30. package/dist/adapters/mongodbQuery.mjs +17 -4
  31. package/dist/adapters/mongodbReads.cjs +88 -30
  32. package/dist/adapters/mongodbReads.mjs +88 -29
  33. package/dist/adapters/mongodbWrites.cjs +1 -2
  34. package/dist/adapters/mongodbWrites.mjs +1 -1
  35. package/dist/adapters/prisma.cjs +44 -7
  36. package/dist/adapters/prisma.d.cts +0 -1
  37. package/dist/adapters/prisma.d.mts +0 -1
  38. package/dist/adapters/prisma.mjs +44 -6
  39. package/dist/adapters/prismaInsights.cjs +99 -0
  40. package/dist/adapters/prismaInsights.mjs +97 -0
  41. package/dist/adapters/prismaQuery.cjs +0 -1
  42. package/dist/adapters/prismaRows.cjs +7 -8
  43. package/dist/adapters/prismaRows.mjs +8 -8
  44. package/dist/apiKeys.cjs +6 -2
  45. package/dist/apiKeys.d.cts +0 -1
  46. package/dist/apiKeys.d.mts +0 -1
  47. package/dist/apiKeys.mjs +3 -3
  48. package/dist/createHotUpdaterCore.cjs +24 -9
  49. package/dist/createHotUpdaterCore.d.cts +1 -1
  50. package/dist/createHotUpdaterCore.d.mts +1 -1
  51. package/dist/createHotUpdaterCore.mjs +23 -9
  52. package/dist/db/createBundleDiff.cjs +2 -2
  53. package/dist/db/createBundleDiff.d.cts +1 -5
  54. package/dist/db/createBundleDiff.d.mts +1 -5
  55. package/dist/db/databasePluginCore.cjs +0 -1
  56. package/dist/db/fixedMigrator.cjs +2 -2
  57. package/dist/db/fixedMigrator.mjs +2 -2
  58. package/dist/db/fixedMigratorMongo.cjs +6 -4
  59. package/dist/db/fixedMigratorMongo.mjs +6 -4
  60. package/dist/db/index.d.cts +0 -1
  61. package/dist/db/index.d.mts +0 -1
  62. package/dist/db/releaseCatalog.cjs +0 -1
  63. package/dist/db/releaseCatalog.d.cts +0 -1
  64. package/dist/db/releaseCatalog.d.mts +0 -1
  65. package/dist/db/schema/insightsCollation.cjs +14 -0
  66. package/dist/db/schema/insightsCollation.mjs +14 -0
  67. package/dist/db/schema/sql.cjs +11 -7
  68. package/dist/db/schema/sql.mjs +8 -8
  69. package/dist/db/schemaGenerators.cjs +29 -9
  70. package/dist/db/schemaGenerators.mjs +29 -9
  71. package/dist/db/schemaReadiness.cjs +2 -0
  72. package/dist/db/schemaReadiness.d.cts +1 -0
  73. package/dist/db/schemaReadiness.d.mts +1 -0
  74. package/dist/db/schemaReadiness.mjs +2 -0
  75. package/dist/db/sqlMigrationExecution.cjs +1 -1
  76. package/dist/db/sqlMigrationExecution.mjs +1 -0
  77. package/dist/db/types.cjs +3 -1
  78. package/dist/db/types.d.cts +3 -6
  79. package/dist/db/types.d.mts +3 -6
  80. package/dist/db/types.mjs +2 -2
  81. package/dist/db/updateArtifacts.cjs +0 -1
  82. package/dist/handler.d.cts +1 -2
  83. package/dist/handler.d.mts +1 -2
  84. package/dist/handlerReleaseCatalogRoutes.cjs +0 -1
  85. package/dist/handlerReleaseManagementRoutes.cjs +0 -1
  86. package/dist/handlerTypes.d.cts +0 -1
  87. package/dist/handlerTypes.d.mts +0 -1
  88. package/dist/handlerVersionRoutes.d.cts +1 -0
  89. package/dist/handlerVersionRoutes.d.mts +1 -0
  90. package/dist/index.cjs +1 -1
  91. package/dist/index.d.cts +4 -4
  92. package/dist/index.d.mts +4 -4
  93. package/dist/index.mjs +1 -1
  94. package/dist/insights/domain.d.cts +41 -70
  95. package/dist/insights/domain.d.mts +41 -70
  96. package/dist/insights/errors.cjs +1 -8
  97. package/dist/insights/errors.mjs +2 -8
  98. package/dist/insights/eventInput.cjs +52 -7
  99. package/dist/insights/eventInput.mjs +51 -8
  100. package/dist/insights/provider.cjs +332 -0
  101. package/dist/insights/provider.d.cts +6 -0
  102. package/dist/insights/provider.d.mts +6 -0
  103. package/dist/insights/provider.mjs +332 -0
  104. package/dist/insights/queryInput.cjs +78 -43
  105. package/dist/insights/queryInput.mjs +76 -40
  106. package/dist/insights/routes.cjs +20 -25
  107. package/dist/insights/routes.mjs +22 -27
  108. package/dist/insights/types.d.cts +27 -12
  109. package/dist/insights/types.d.mts +27 -12
  110. package/dist/node.d.cts +0 -1
  111. package/dist/node.d.mts +0 -1
  112. package/dist/package.cjs +1 -1
  113. package/dist/package.mjs +1 -1
  114. package/dist/schema/index.cjs +17 -3
  115. package/dist/schema/index.mjs +4 -4
  116. package/dist/schema/v1_0_0.cjs +64 -35
  117. package/dist/schema/v1_0_0.mjs +64 -36
  118. package/dist/storageAccess.cjs +0 -1
  119. package/dist/types/index.d.cts +0 -1
  120. package/dist/types/index.d.mts +0 -1
  121. package/package.json +7 -7
  122. package/src/adapters/databasePluginTestDatabase.ts +15 -5
  123. package/src/adapters/databasePluginUtils.ts +24 -0
  124. package/src/adapters/drizzle.spec.ts +203 -5
  125. package/src/adapters/drizzle.ts +15 -3
  126. package/src/adapters/drizzleCrud.ts +200 -9
  127. package/src/adapters/drizzleLazyDB.ts +33 -6
  128. package/src/adapters/kysely.spec.ts +62 -0
  129. package/src/adapters/kysely.ts +7 -1
  130. package/src/adapters/kyselyCrud.ts +115 -7
  131. package/src/adapters/kyselyInsights.spec.ts +168 -0
  132. package/src/adapters/mongodb.integration.spec.ts +483 -0
  133. package/src/adapters/mongodb.spec.ts +89 -0
  134. package/src/adapters/mongodb.ts +59 -1
  135. package/src/adapters/mongodbCollections.ts +16 -0
  136. package/src/adapters/mongodbQuery.ts +22 -3
  137. package/src/adapters/mongodbReads.ts +78 -2
  138. package/src/adapters/mongodbTestClient.ts +107 -6
  139. package/src/adapters/mongodbTestFilter.ts +5 -1
  140. package/src/adapters/mongodbWrites.ts +1 -0
  141. package/src/adapters/prisma.spec.ts +270 -0
  142. package/src/adapters/prisma.ts +75 -2
  143. package/src/adapters/prismaInsights.ts +190 -0
  144. package/src/adapters/prismaRows.ts +17 -10
  145. package/src/adapters/prismaTestClient.ts +89 -7
  146. package/src/apiKeys.integration.spec.ts +1 -1
  147. package/src/createHotUpdaterCore.ts +21 -7
  148. package/src/db/databasePluginUpdateCheck.bench.ts +10 -0
  149. package/src/db/fixedMigrator.spec.ts +63 -0
  150. package/src/db/fixedMigratorMongo.spec.ts +70 -9
  151. package/src/db/fixedMigratorMongo.ts +10 -10
  152. package/src/db/index.spec.ts +6 -1
  153. package/src/db/schema/insightsCollation.ts +21 -0
  154. package/src/db/schema/sql.ts +8 -5
  155. package/src/db/schemaGenerators.ts +42 -13
  156. package/src/db/types.spec.ts +8 -0
  157. package/src/db/types.ts +10 -4
  158. package/src/handler-standalone.integration.spec.ts +5 -7
  159. package/src/index.ts +2 -2
  160. package/src/insights/domain.ts +44 -77
  161. package/src/insights/errors.ts +0 -7
  162. package/src/insights/eventInput.ts +55 -5
  163. package/src/insights/insights.integration.spec.ts +348 -17
  164. package/src/insights/provider.spec.ts +396 -0
  165. package/src/insights/provider.ts +611 -0
  166. package/src/insights/queryInput.ts +113 -73
  167. package/src/insights/routes.ts +37 -56
  168. package/src/insights/types.ts +47 -36
  169. package/src/schema/dsl-all-versions.spec.ts +1 -1
  170. package/src/schema/v1_0_0.spec.ts +77 -3
  171. package/src/schema/v1_0_0.ts +83 -37
  172. package/dist/insights/bounded/activeOverview.cjs +0 -87
  173. package/dist/insights/bounded/activeOverview.mjs +0 -85
  174. package/dist/insights/bounded/installationSearch.cjs +0 -42
  175. package/dist/insights/bounded/installationSearch.mjs +0 -42
  176. package/dist/insights/bounded/persistence.cjs +0 -39
  177. package/dist/insights/bounded/persistence.mjs +0 -38
  178. package/dist/insights/bounded/provider.cjs +0 -170
  179. package/dist/insights/bounded/provider.d.cts +0 -7
  180. package/dist/insights/bounded/provider.d.mts +0 -7
  181. package/dist/insights/bounded/provider.mjs +0 -170
  182. package/dist/insights/bounded/scan.cjs +0 -144
  183. package/dist/insights/bounded/scan.mjs +0 -138
  184. package/dist/insights/persistence.d.cts +0 -6
  185. package/dist/insights/persistence.d.mts +0 -6
  186. package/src/insights/bounded/activeOverview.spec.ts +0 -189
  187. package/src/insights/bounded/activeOverview.ts +0 -148
  188. package/src/insights/bounded/installationSearch.spec.ts +0 -130
  189. package/src/insights/bounded/installationSearch.ts +0 -69
  190. package/src/insights/bounded/persistence.ts +0 -43
  191. package/src/insights/bounded/provider.spec.ts +0 -219
  192. package/src/insights/bounded/provider.ts +0 -229
  193. package/src/insights/bounded/scan.ts +0 -235
  194. package/src/insights/persistence.ts +0 -10
@@ -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,4 +1,3 @@
1
- require("../_virtual/_rolldown/runtime.cjs");
2
1
  let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
3
2
  //#region src/adapters/databaseConstraintErrors.ts
4
3
  const readErrorCode = (error) => {
@@ -1,4 +1,3 @@
1
- require("../_virtual/_rolldown/runtime.cjs");
2
1
  let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
3
2
  //#region src/adapters/databasePluginUtils.ts
4
3
  var StoredBundleRowError = class extends Error {
@@ -103,14 +102,28 @@ const fromStoredReleaseCatalogRow = (row) => ({
103
102
  });
104
103
  const escapeLikePattern = (value) => value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
105
104
  const escapeGlobPattern = (value) => value.replaceAll("[", "[[]").replaceAll("*", "[*]").replaceAll("?", "[?]");
105
+ const fromStoredBundleEventRow = (row) => {
106
+ const metadata = typeof row.metadata === "string" ? parseJson(row.metadata) : row.metadata;
107
+ if (!(0, _hot_updater_plugin_core.isDatabaseBundleEventMetadata)(metadata)) throw new StoredBundleRowError("Invalid event metadata field.");
108
+ return {
109
+ ...row,
110
+ metadata
111
+ };
112
+ };
113
+ const toStoredBundleEventRow = (row, provider) => provider === "mysql" || provider === "sqlite" ? {
114
+ ...row,
115
+ metadata: JSON.stringify(row.metadata)
116
+ } : row;
106
117
  //#endregion
107
118
  exports.escapeGlobPattern = escapeGlobPattern;
108
119
  exports.escapeLikePattern = escapeLikePattern;
120
+ exports.fromStoredBundleEventRow = fromStoredBundleEventRow;
109
121
  exports.fromStoredBundleRow = fromStoredBundleRow;
110
122
  exports.fromStoredReleaseCatalogRow = fromStoredReleaseCatalogRow;
111
123
  exports.fromStoredReleaseRow = fromStoredReleaseRow;
112
124
  exports.hasNullOrderOverrides = hasNullOrderOverrides;
113
125
  exports.sortRowsByOrder = sortRowsByOrder;
126
+ exports.toStoredBundleEventRow = toStoredBundleEventRow;
114
127
  exports.toStoredBundleRow = toStoredBundleRow;
115
128
  exports.toStoredBundleUpdate = toStoredBundleUpdate;
116
129
  exports.toStoredReleaseRow = toStoredReleaseRow;
@@ -1,4 +1,4 @@
1
- import { isDatabaseMetadataObject } from "@hot-updater/plugin-core";
1
+ import { isDatabaseBundleEventMetadata, isDatabaseMetadataObject } from "@hot-updater/plugin-core";
2
2
  //#region src/adapters/databasePluginUtils.ts
3
3
  var StoredBundleRowError = class extends Error {
4
4
  name = "StoredBundleRowError";
@@ -102,5 +102,17 @@ const fromStoredReleaseCatalogRow = (row) => ({
102
102
  });
103
103
  const escapeLikePattern = (value) => value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
104
104
  const escapeGlobPattern = (value) => value.replaceAll("[", "[[]").replaceAll("*", "[*]").replaceAll("?", "[?]");
105
+ const fromStoredBundleEventRow = (row) => {
106
+ const metadata = typeof row.metadata === "string" ? parseJson(row.metadata) : row.metadata;
107
+ if (!isDatabaseBundleEventMetadata(metadata)) throw new StoredBundleRowError("Invalid event metadata field.");
108
+ return {
109
+ ...row,
110
+ metadata
111
+ };
112
+ };
113
+ const toStoredBundleEventRow = (row, provider) => provider === "mysql" || provider === "sqlite" ? {
114
+ ...row,
115
+ metadata: JSON.stringify(row.metadata)
116
+ } : row;
105
117
  //#endregion
106
- export { escapeGlobPattern, escapeLikePattern, fromStoredBundleRow, fromStoredReleaseCatalogRow, fromStoredReleaseRow, hasNullOrderOverrides, sortRowsByOrder, toStoredBundleRow, toStoredBundleUpdate, toStoredReleaseRow, toStoredReleaseUpdate };
118
+ export { escapeGlobPattern, escapeLikePattern, fromStoredBundleEventRow, fromStoredBundleRow, fromStoredReleaseCatalogRow, fromStoredReleaseRow, hasNullOrderOverrides, sortRowsByOrder, toStoredBundleEventRow, toStoredBundleRow, toStoredBundleUpdate, toStoredReleaseRow, toStoredReleaseUpdate };
@@ -1,5 +1,4 @@
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");
5
4
  const require_drizzleCrud = require("./drizzleCrud.cjs");
@@ -13,6 +12,9 @@ const createImplementation = (config) => {
13
12
  const transaction = db.transaction?.bind(db);
14
13
  return {
15
14
  ...crud,
15
+ recordInsights: async (input) => {
16
+ await require_drizzleCrud.recordDrizzleInsights(db.resolve === void 0 ? db : await db.resolve(), config.provider, input);
17
+ },
16
18
  deleteChannel: (input) => {
17
19
  if (transaction === void 0) throw new Error("Drizzle channel deletion requires transaction support.");
18
20
  return transaction((transactionDatabase) => require_drizzleCrud.createDrizzleCrud(transactionDatabase, config.provider).deleteChannel(input));
@@ -51,8 +53,11 @@ const drizzleAdapter = (config) => {
51
53
  delete: (input) => getAdapter().models.channels.delete(input)
52
54
  },
53
55
  insights: {
54
- append: (row) => getAdapter().models.insights.append(row),
55
- scan: (input) => getAdapter().models.insights.scan(input)
56
+ recordEvent: (input) => getAdapter().models.insights.recordEvent(input),
57
+ listEvents: (input) => getAdapter().models.insights.listEvents(input),
58
+ findLatestEvents: (input) => getAdapter().models.insights.findLatestEvents(input),
59
+ countLatestEvents: (input) => getAdapter().models.insights.countLatestEvents(input),
60
+ countEvents: (input) => getAdapter().models.insights.countEvents(input)
56
61
  },
57
62
  apiKeys: {
58
63
  create: (row) => getAdapter().models.apiKeys.create(row),
@@ -1,5 +1,4 @@
1
1
  import { DatabaseAdapterWithCapabilities, ORMProvider } from "../db/types.cjs";
2
-
3
2
  //#region src/adapters/drizzle.d.ts
4
3
  type DrizzleProvider = Exclude<ORMProvider, "cockroachdb" | "mongodb" | "mssql">;
5
4
  interface DrizzleConfig {
@@ -1,5 +1,4 @@
1
1
  import { DatabaseAdapterWithCapabilities, ORMProvider } from "../db/types.mjs";
2
-
3
2
  //#region src/adapters/drizzle.d.ts
4
3
  type DrizzleProvider = Exclude<ORMProvider, "cockroachdb" | "mongodb" | "mssql">;
5
4
  interface DrizzleConfig {
@@ -1,6 +1,6 @@
1
1
  import { getHotUpdaterSchemaVersion, hotUpdaterSchema } from "../db/schema/registry.mjs";
2
2
  import { generateDrizzleSchema } from "../db/schemaGenerators.mjs";
3
- import { createDrizzleCrud } from "./drizzleCrud.mjs";
3
+ import { createDrizzleCrud, recordDrizzleInsights } from "./drizzleCrud.mjs";
4
4
  import { createLazyDB } from "./drizzleLazyDB.mjs";
5
5
  import { createDatabasePlugin } from "@hot-updater/plugin-core";
6
6
  import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
@@ -11,6 +11,9 @@ const createImplementation = (config) => {
11
11
  const transaction = db.transaction?.bind(db);
12
12
  return {
13
13
  ...crud,
14
+ recordInsights: async (input) => {
15
+ await recordDrizzleInsights(db.resolve === void 0 ? db : await db.resolve(), config.provider, input);
16
+ },
14
17
  deleteChannel: (input) => {
15
18
  if (transaction === void 0) throw new Error("Drizzle channel deletion requires transaction support.");
16
19
  return transaction((transactionDatabase) => createDrizzleCrud(transactionDatabase, config.provider).deleteChannel(input));
@@ -49,8 +52,11 @@ const drizzleAdapter = (config) => {
49
52
  delete: (input) => getAdapter().models.channels.delete(input)
50
53
  },
51
54
  insights: {
52
- append: (row) => getAdapter().models.insights.append(row),
53
- scan: (input) => getAdapter().models.insights.scan(input)
55
+ recordEvent: (input) => getAdapter().models.insights.recordEvent(input),
56
+ listEvents: (input) => getAdapter().models.insights.listEvents(input),
57
+ findLatestEvents: (input) => getAdapter().models.insights.findLatestEvents(input),
58
+ countLatestEvents: (input) => getAdapter().models.insights.countLatestEvents(input),
59
+ countEvents: (input) => getAdapter().models.insights.countEvents(input)
54
60
  },
55
61
  apiKeys: {
56
62
  create: (row) => getAdapter().models.apiKeys.create(row),
@@ -1,11 +1,12 @@
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");
5
4
  let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
5
+ let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
6
6
  let drizzle_orm = require("drizzle-orm");
7
7
  //#region src/adapters/drizzleCrud.ts
8
8
  var MissingDrizzleTableError = class extends Error {
9
+ table;
9
10
  name = "MissingDrizzleTableError";
10
11
  constructor(table) {
11
12
  super(`Drizzle schema is missing table "${table}".`);
@@ -37,9 +38,73 @@ const executeInsert = async (db, provider, table, data, onConflict) => {
37
38
  if (ignored === void 0) throw new DrizzleAdapterInvariantError();
38
39
  await ignored.execute();
39
40
  };
41
+ const recordDrizzleInsights = (db, provider, { event }) => {
42
+ const events = getDrizzleTable(db, "bundle_events");
43
+ const heads = getDrizzleTable(db, "bundle_event_heads");
44
+ if (!(0, drizzle_orm.is)(heads, drizzle_orm.Table) || !(0, drizzle_orm.is)(events, drizzle_orm.Table)) throw new DrizzleAdapterInvariantError();
45
+ const fields = Object.keys((0, drizzle_orm.getTableColumns)(heads));
46
+ if (provider === "mysql") {
47
+ if (!db.transaction) throw new DrizzleAdapterInvariantError();
48
+ return db.transaction(async (transaction) => {
49
+ const accepted = transaction.insert(events).values(event).onDuplicateKeyUpdate?.({ set: { id: drizzle_orm.sql`id` } });
50
+ if (!accepted || !transaction.execute) throw new DrizzleAdapterInvariantError();
51
+ await accepted.execute();
52
+ const wins = drizzle_orm.sql`VALUES(received_at_ms) > bundle_event_heads.received_at_ms OR (VALUES(received_at_ms) = bundle_event_heads.received_at_ms AND VALUES(id) > bundle_event_heads.id)`;
53
+ const ordered = [
54
+ ...fields.filter((field) => ![
55
+ "install_id",
56
+ "id",
57
+ "received_at_ms"
58
+ ].includes(field)),
59
+ "id",
60
+ "received_at_ms"
61
+ ];
62
+ const columns = drizzle_orm.sql.join(fields.map((field) => drizzle_orm.sql.identifier(field)), drizzle_orm.sql`, `);
63
+ const assignments = drizzle_orm.sql.join(ordered.map((field) => drizzle_orm.sql`${drizzle_orm.sql.identifier(field)} = CASE WHEN ${wins} THEN VALUES(${drizzle_orm.sql.identifier(field)}) ELSE bundle_event_heads.${drizzle_orm.sql.identifier(field)} END`), drizzle_orm.sql`, `);
64
+ await transaction.execute(drizzle_orm.sql`INSERT INTO bundle_event_heads (${columns}) SELECT ${columns} FROM bundle_events WHERE id = ${event.id} ON DUPLICATE KEY UPDATE ${assignments}`);
65
+ });
66
+ }
67
+ const newer = drizzle_orm.sql`excluded.received_at_ms > bundle_event_heads.received_at_ms OR (excluded.received_at_ms = bundle_event_heads.received_at_ms AND excluded.id > bundle_event_heads.id)`;
68
+ const mutations = (executor, fromInserted = false) => {
69
+ const accepted = executor.insert(events).values(event).onConflictDoNothing?.();
70
+ const select = fromInserted ? drizzle_orm.sql`SELECT ${drizzle_orm.sql.join(fields.map((field) => drizzle_orm.sql.identifier(field)), drizzle_orm.sql`, `)} FROM inserted` : drizzle_orm.sql`SELECT ${drizzle_orm.sql.join(fields.map((field) => drizzle_orm.sql.identifier(field)), drizzle_orm.sql`, `)} FROM bundle_events WHERE id = ${event.id}`;
71
+ const head = (executor.insert(heads).select?.(select))?.onConflictDoUpdate?.({
72
+ target: getDrizzleColumn(heads, "install_id"),
73
+ set: Object.fromEntries(fields.filter((field) => field !== "install_id").map((field) => [field, drizzle_orm.sql`excluded.${drizzle_orm.sql.identifier(field)}`])),
74
+ setWhere: newer
75
+ });
76
+ if (accepted === void 0 || head === void 0) throw new DrizzleAdapterInvariantError();
77
+ return {
78
+ accepted,
79
+ head
80
+ };
81
+ };
82
+ if (provider === "postgresql") {
83
+ const { accepted, head } = mutations(db, true);
84
+ const returning = "returning" in accepted && typeof accepted.returning === "function" ? accepted.returning((0, drizzle_orm.getTableColumns)(events)) : void 0;
85
+ if (!returning?.getSQL || !head.getSQL || !db.execute) throw new DrizzleAdapterInvariantError();
86
+ return db.execute(drizzle_orm.sql`WITH inserted AS (${returning.getSQL()}) ${head.getSQL()}`).then(() => void 0);
87
+ }
88
+ if (db.batch !== void 0) {
89
+ const { accepted, head } = mutations(db);
90
+ return db.batch([accepted, head]).then(() => void 0);
91
+ }
92
+ if (db.transaction === void 0) throw new DrizzleAdapterInvariantError();
93
+ return db.transaction((transaction) => {
94
+ const { accepted, head } = mutations(transaction);
95
+ if (db.resultKind === "sync") {
96
+ if (!accepted.run || !head.run) throw new DrizzleAdapterInvariantError();
97
+ accepted.run();
98
+ head.run();
99
+ return;
100
+ }
101
+ return accepted.execute().then(() => head.execute()).then(() => void 0);
102
+ });
103
+ };
40
104
  const toOrderBy = (table, input) => {
41
105
  return input.orderBy?.flatMap((clause) => {
42
106
  const column = getDrizzleColumn(table, clause.field);
107
+ if (input.model === "bundle_events") return [clause.direction === "asc" ? (0, drizzle_orm.asc)(column) : (0, drizzle_orm.desc)(column)];
43
108
  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
109
  });
45
110
  };
@@ -47,11 +112,32 @@ const createDrizzleCrud = (db, provider) => {
47
112
  const bundles = getDrizzleTable(db, "bundles");
48
113
  const patches = getDrizzleTable(db, "bundle_patches");
49
114
  const events = getDrizzleTable(db, "bundle_events");
115
+ const heads = getDrizzleTable(db, "bundle_event_heads");
50
116
  const releases = getDrizzleTable(db, "releases");
51
117
  const releaseCatalogs = getDrizzleTable(db, "release_catalogs");
52
118
  const channels = getDrizzleTable(db, "channels");
53
119
  const apiKeys = getDrizzleTable(db, "api_keys");
54
120
  return {
121
+ async findLatestInsightsEvents(input) {
122
+ const where = drizzle_orm.sql.join((0, _hot_updater_plugin_core_internal.latestInsightsWhere)(input).map((condition) => condition.operator === "gt" ? drizzle_orm.sql`${drizzle_orm.sql.identifier(condition.field)} > ${condition.value}` : drizzle_orm.sql`${drizzle_orm.sql.identifier(condition.field)} = ${condition.value}`), drizzle_orm.sql` AND `);
123
+ return (await db.query.bundle_events.findMany({
124
+ where: drizzle_orm.sql`${getDrizzleColumn(events, "id")} IN (SELECT id FROM (SELECT id FROM bundle_event_heads WHERE ${where} ORDER BY install_id ASC LIMIT ${"installId" in input ? 1 : input.limit}) AS latest)`,
125
+ orderBy: [(0, drizzle_orm.asc)(getDrizzleColumn(events, "install_id"))],
126
+ limit: "installId" in input ? 1 : input.limit
127
+ })).map(require_databasePluginUtils.fromStoredBundleEventRow);
128
+ },
129
+ async countLatestInsightsEvents(input) {
130
+ const groups = (0, _hot_updater_plugin_core_internal.latestInsightsCountGroups)(input).map((where) => require_drizzleQuery.buildDrizzleWhere(provider, heads, where));
131
+ if (provider === "mysql" && groups.length === 2) {
132
+ const native = db.resolve === void 0 ? db : await db.resolve();
133
+ if (!native.select) throw new DrizzleAdapterInvariantError();
134
+ const row = (await native.select({ count: drizzle_orm.sql`(SELECT COUNT(*) FROM bundle_event_heads WHERE ${groups[0]}) + (SELECT COUNT(*) FROM bundle_event_heads WHERE ${groups[1]} AND (${groups[0]}) IS NOT TRUE)` }).from(drizzle_orm.sql`(SELECT 1) AS counted`).execute())[0];
135
+ const count = typeof row === "object" && row !== null ? Reflect.get(row, "count") : void 0;
136
+ if (typeof count !== "number" && typeof count !== "string" && typeof count !== "bigint") throw new DrizzleAdapterInvariantError();
137
+ return Number(count);
138
+ }
139
+ return db.$count(heads, (0, drizzle_orm.or)(...groups));
140
+ },
55
141
  async deleteChannel({ id }) {
56
142
  const idPredicate = (0, drizzle_orm.eq)(getDrizzleColumn(channels, "id"), id);
57
143
  if (await db.query.channels.findFirst({ where: idPredicate }) === void 0) return {
@@ -173,6 +259,7 @@ const createDrizzleCrud = (db, provider) => {
173
259
  async count(input) {
174
260
  if (input.distinct !== void 0) throw new _hot_updater_plugin_core.DatabasePluginInputError("invalid-operation");
175
261
  switch (input.model) {
262
+ case "bundle_events": return db.$count(events, require_drizzleQuery.buildDrizzleWhere(provider, events, input.where));
176
263
  case "bundles": return db.$count(bundles, require_drizzleQuery.buildDrizzleWhere(provider, bundles, input.where));
177
264
  case "bundle_patches": return db.$count(patches, require_drizzleQuery.buildDrizzleWhere(provider, patches, input.where));
178
265
  case "releases": return db.$count(releases, require_drizzleQuery.buildDrizzleWhere(provider, releases, input.where));
@@ -206,12 +293,12 @@ const createDrizzleCrud = (db, provider) => {
206
293
  limit: input.limit,
207
294
  offset: input.offset
208
295
  })).map(require_databasePluginUtils.fromStoredBundleRow);
209
- case "bundle_events": return db.query.bundle_events.findMany({
296
+ case "bundle_events": return (await db.query.bundle_events.findMany({
210
297
  where: require_drizzleQuery.buildDrizzleWhere(provider, events, input.where),
211
298
  orderBy: toOrderBy(events, input),
212
299
  limit: input.limit,
213
300
  offset: input.offset
214
- });
301
+ })).map(require_databasePluginUtils.fromStoredBundleEventRow);
215
302
  case "api_keys": return db.query.api_keys.findMany({
216
303
  where: require_drizzleQuery.buildDrizzleWhere(provider, apiKeys, input.where),
217
304
  orderBy: toOrderBy(apiKeys, input),
@@ -248,3 +335,6 @@ const createDrizzleCrud = (db, provider) => {
248
335
  };
249
336
  //#endregion
250
337
  exports.createDrizzleCrud = createDrizzleCrud;
338
+ exports.getDrizzleColumn = getDrizzleColumn;
339
+ exports.getDrizzleTable = getDrizzleTable;
340
+ exports.recordDrizzleInsights = recordDrizzleInsights;
@@ -1,10 +1,12 @@
1
1
  import { isChannelDeleteReferencedError, translateChannelDeleteError } from "./databaseConstraintErrors.mjs";
2
- import { fromStoredBundleRow, fromStoredReleaseCatalogRow, fromStoredReleaseRow, toStoredBundleRow, toStoredBundleUpdate, toStoredReleaseRow, toStoredReleaseUpdate } from "./databasePluginUtils.mjs";
2
+ import { fromStoredBundleEventRow, 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 { latestInsightsCountGroups, latestInsightsWhere } from "@hot-updater/plugin-core/internal";
6
+ import { Table, asc, desc, eq, getTableColumns, is, or, sql } from "drizzle-orm";
6
7
  //#region src/adapters/drizzleCrud.ts
7
8
  var MissingDrizzleTableError = class extends Error {
9
+ table;
8
10
  name = "MissingDrizzleTableError";
9
11
  constructor(table) {
10
12
  super(`Drizzle schema is missing table "${table}".`);
@@ -36,9 +38,73 @@ const executeInsert = async (db, provider, table, data, onConflict) => {
36
38
  if (ignored === void 0) throw new DrizzleAdapterInvariantError();
37
39
  await ignored.execute();
38
40
  };
41
+ const recordDrizzleInsights = (db, provider, { event }) => {
42
+ const events = getDrizzleTable(db, "bundle_events");
43
+ const heads = getDrizzleTable(db, "bundle_event_heads");
44
+ if (!is(heads, Table) || !is(events, Table)) throw new DrizzleAdapterInvariantError();
45
+ const fields = Object.keys(getTableColumns(heads));
46
+ if (provider === "mysql") {
47
+ if (!db.transaction) throw new DrizzleAdapterInvariantError();
48
+ return db.transaction(async (transaction) => {
49
+ const accepted = transaction.insert(events).values(event).onDuplicateKeyUpdate?.({ set: { id: sql`id` } });
50
+ if (!accepted || !transaction.execute) throw new DrizzleAdapterInvariantError();
51
+ await accepted.execute();
52
+ const wins = sql`VALUES(received_at_ms) > bundle_event_heads.received_at_ms OR (VALUES(received_at_ms) = bundle_event_heads.received_at_ms AND VALUES(id) > bundle_event_heads.id)`;
53
+ const ordered = [
54
+ ...fields.filter((field) => ![
55
+ "install_id",
56
+ "id",
57
+ "received_at_ms"
58
+ ].includes(field)),
59
+ "id",
60
+ "received_at_ms"
61
+ ];
62
+ const columns = sql.join(fields.map((field) => sql.identifier(field)), sql`, `);
63
+ const assignments = sql.join(ordered.map((field) => sql`${sql.identifier(field)} = CASE WHEN ${wins} THEN VALUES(${sql.identifier(field)}) ELSE bundle_event_heads.${sql.identifier(field)} END`), sql`, `);
64
+ await transaction.execute(sql`INSERT INTO bundle_event_heads (${columns}) SELECT ${columns} FROM bundle_events WHERE id = ${event.id} ON DUPLICATE KEY UPDATE ${assignments}`);
65
+ });
66
+ }
67
+ const newer = sql`excluded.received_at_ms > bundle_event_heads.received_at_ms OR (excluded.received_at_ms = bundle_event_heads.received_at_ms AND excluded.id > bundle_event_heads.id)`;
68
+ const mutations = (executor, fromInserted = false) => {
69
+ const accepted = executor.insert(events).values(event).onConflictDoNothing?.();
70
+ const select = fromInserted ? sql`SELECT ${sql.join(fields.map((field) => sql.identifier(field)), sql`, `)} FROM inserted` : sql`SELECT ${sql.join(fields.map((field) => sql.identifier(field)), sql`, `)} FROM bundle_events WHERE id = ${event.id}`;
71
+ const head = (executor.insert(heads).select?.(select))?.onConflictDoUpdate?.({
72
+ target: getDrizzleColumn(heads, "install_id"),
73
+ set: Object.fromEntries(fields.filter((field) => field !== "install_id").map((field) => [field, sql`excluded.${sql.identifier(field)}`])),
74
+ setWhere: newer
75
+ });
76
+ if (accepted === void 0 || head === void 0) throw new DrizzleAdapterInvariantError();
77
+ return {
78
+ accepted,
79
+ head
80
+ };
81
+ };
82
+ if (provider === "postgresql") {
83
+ const { accepted, head } = mutations(db, true);
84
+ const returning = "returning" in accepted && typeof accepted.returning === "function" ? accepted.returning(getTableColumns(events)) : void 0;
85
+ if (!returning?.getSQL || !head.getSQL || !db.execute) throw new DrizzleAdapterInvariantError();
86
+ return db.execute(sql`WITH inserted AS (${returning.getSQL()}) ${head.getSQL()}`).then(() => void 0);
87
+ }
88
+ if (db.batch !== void 0) {
89
+ const { accepted, head } = mutations(db);
90
+ return db.batch([accepted, head]).then(() => void 0);
91
+ }
92
+ if (db.transaction === void 0) throw new DrizzleAdapterInvariantError();
93
+ return db.transaction((transaction) => {
94
+ const { accepted, head } = mutations(transaction);
95
+ if (db.resultKind === "sync") {
96
+ if (!accepted.run || !head.run) throw new DrizzleAdapterInvariantError();
97
+ accepted.run();
98
+ head.run();
99
+ return;
100
+ }
101
+ return accepted.execute().then(() => head.execute()).then(() => void 0);
102
+ });
103
+ };
39
104
  const toOrderBy = (table, input) => {
40
105
  return input.orderBy?.flatMap((clause) => {
41
106
  const column = getDrizzleColumn(table, clause.field);
107
+ if (input.model === "bundle_events") return [clause.direction === "asc" ? asc(column) : desc(column)];
42
108
  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
109
  });
44
110
  };
@@ -46,11 +112,32 @@ const createDrizzleCrud = (db, provider) => {
46
112
  const bundles = getDrizzleTable(db, "bundles");
47
113
  const patches = getDrizzleTable(db, "bundle_patches");
48
114
  const events = getDrizzleTable(db, "bundle_events");
115
+ const heads = getDrizzleTable(db, "bundle_event_heads");
49
116
  const releases = getDrizzleTable(db, "releases");
50
117
  const releaseCatalogs = getDrizzleTable(db, "release_catalogs");
51
118
  const channels = getDrizzleTable(db, "channels");
52
119
  const apiKeys = getDrizzleTable(db, "api_keys");
53
120
  return {
121
+ async findLatestInsightsEvents(input) {
122
+ const where = sql.join(latestInsightsWhere(input).map((condition) => condition.operator === "gt" ? sql`${sql.identifier(condition.field)} > ${condition.value}` : sql`${sql.identifier(condition.field)} = ${condition.value}`), sql` AND `);
123
+ return (await db.query.bundle_events.findMany({
124
+ where: sql`${getDrizzleColumn(events, "id")} IN (SELECT id FROM (SELECT id FROM bundle_event_heads WHERE ${where} ORDER BY install_id ASC LIMIT ${"installId" in input ? 1 : input.limit}) AS latest)`,
125
+ orderBy: [asc(getDrizzleColumn(events, "install_id"))],
126
+ limit: "installId" in input ? 1 : input.limit
127
+ })).map(fromStoredBundleEventRow);
128
+ },
129
+ async countLatestInsightsEvents(input) {
130
+ const groups = latestInsightsCountGroups(input).map((where) => buildDrizzleWhere(provider, heads, where));
131
+ if (provider === "mysql" && groups.length === 2) {
132
+ const native = db.resolve === void 0 ? db : await db.resolve();
133
+ if (!native.select) throw new DrizzleAdapterInvariantError();
134
+ const row = (await native.select({ count: sql`(SELECT COUNT(*) FROM bundle_event_heads WHERE ${groups[0]}) + (SELECT COUNT(*) FROM bundle_event_heads WHERE ${groups[1]} AND (${groups[0]}) IS NOT TRUE)` }).from(sql`(SELECT 1) AS counted`).execute())[0];
135
+ const count = typeof row === "object" && row !== null ? Reflect.get(row, "count") : void 0;
136
+ if (typeof count !== "number" && typeof count !== "string" && typeof count !== "bigint") throw new DrizzleAdapterInvariantError();
137
+ return Number(count);
138
+ }
139
+ return db.$count(heads, or(...groups));
140
+ },
54
141
  async deleteChannel({ id }) {
55
142
  const idPredicate = eq(getDrizzleColumn(channels, "id"), id);
56
143
  if (await db.query.channels.findFirst({ where: idPredicate }) === void 0) return {
@@ -172,6 +259,7 @@ const createDrizzleCrud = (db, provider) => {
172
259
  async count(input) {
173
260
  if (input.distinct !== void 0) throw new DatabasePluginInputError("invalid-operation");
174
261
  switch (input.model) {
262
+ case "bundle_events": return db.$count(events, buildDrizzleWhere(provider, events, input.where));
175
263
  case "bundles": return db.$count(bundles, buildDrizzleWhere(provider, bundles, input.where));
176
264
  case "bundle_patches": return db.$count(patches, buildDrizzleWhere(provider, patches, input.where));
177
265
  case "releases": return db.$count(releases, buildDrizzleWhere(provider, releases, input.where));
@@ -205,12 +293,12 @@ const createDrizzleCrud = (db, provider) => {
205
293
  limit: input.limit,
206
294
  offset: input.offset
207
295
  })).map(fromStoredBundleRow);
208
- case "bundle_events": return db.query.bundle_events.findMany({
296
+ case "bundle_events": return (await db.query.bundle_events.findMany({
209
297
  where: buildDrizzleWhere(provider, events, input.where),
210
298
  orderBy: toOrderBy(events, input),
211
299
  limit: input.limit,
212
300
  offset: input.offset
213
- });
301
+ })).map(fromStoredBundleEventRow);
214
302
  case "api_keys": return db.query.api_keys.findMany({
215
303
  where: buildDrizzleWhere(provider, apiKeys, input.where),
216
304
  orderBy: toOrderBy(apiKeys, input),
@@ -246,4 +334,4 @@ const createDrizzleCrud = (db, provider) => {
246
334
  };
247
335
  };
248
336
  //#endregion
249
- export { createDrizzleCrud };
337
+ 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}`);
@@ -41,6 +42,7 @@ const createLazyDB = (config) => {
41
42
  return resolvedDB;
42
43
  };
43
44
  return {
45
+ resolve: getDB,
44
46
  _: { fullSchema: parseSchema(config.schema) },
45
47
  $count: async (table, where) => (await getDB()).$count(table, where),
46
48
  delete: (table) => ({ where: (condition) => ({ execute: async () => (await getDB()).delete(table).where(condition).execute() }) }),
@@ -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}`);
@@ -41,6 +42,7 @@ const createLazyDB = (config) => {
41
42
  return resolvedDB;
42
43
  };
43
44
  return {
45
+ resolve: getDB,
44
46
  _: { fullSchema: parseSchema(config.schema) },
45
47
  $count: async (table, where) => (await getDB()).$count(table, where),
46
48
  delete: (table) => ({ where: (condition) => ({ execute: async () => (await getDB()).delete(table).where(condition).execute() }) }),
@@ -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
- return drizzle_orm.sql`${field} glob ${operator === "contains" ? `*${literal}*` : operator === "starts_with" ? `${literal}*` : `*${literal}`}`;
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
- return sql`${field} glob ${operator === "contains" ? `*${literal}*` : operator === "starts_with" ? `${literal}*` : `*${literal}`}`;
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}`;
@@ -1,5 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- require("../_virtual/_rolldown/runtime.cjs");
3
2
  const require_fixedMigrator = require("../db/fixedMigrator.cjs");
4
3
  const require_kyselyCrud = require("./kyselyCrud.cjs");
5
4
  let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
@@ -10,6 +9,7 @@ const createImplementation = (config) => {
10
9
  const relationMode = config.relationMode ?? "foreign-keys";
11
10
  return {
12
11
  ...require_kyselyCrud.createKyselyCrud(db, config.provider, relationMode),
12
+ recordInsights: (input) => db.transaction().execute((transaction) => require_kyselyCrud.recordKyselyInsights(transaction, config.provider, input)),
13
13
  deleteChannel: (input) => db.transaction().execute((transaction) => require_kyselyCrud.createKyselyCrud(transaction, config.provider, relationMode).deleteChannel(input)),
14
14
  create: (input) => db.transaction().execute((transaction) => require_kyselyCrud.createKyselyCrud(transaction, config.provider, relationMode).create(input)),
15
15
  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> {
@@ -1,5 +1,5 @@
1
1
  import { createKyselyMigrator } from "../db/fixedMigrator.mjs";
2
- import { createKyselyCrud } from "./kyselyCrud.mjs";
2
+ import { createKyselyCrud, recordKyselyInsights } from "./kyselyCrud.mjs";
3
3
  import { createDatabasePlugin } from "@hot-updater/plugin-core";
4
4
  import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
5
5
  //#region src/adapters/kysely.ts
@@ -8,6 +8,7 @@ const createImplementation = (config) => {
8
8
  const relationMode = config.relationMode ?? "foreign-keys";
9
9
  return {
10
10
  ...createKyselyCrud(db, config.provider, relationMode),
11
+ recordInsights: (input) => db.transaction().execute((transaction) => recordKyselyInsights(transaction, config.provider, input)),
11
12
  deleteChannel: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).deleteChannel(input)),
12
13
  create: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).create(input)),
13
14
  update: (input) => db.transaction().execute((transaction) => createKyselyCrud(transaction, config.provider, relationMode).update(input)),