@hot-updater/server 1.0.0-rc.16 → 1.0.0-rc.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/dist/adapters/drizzle.cjs +5 -5
  2. package/dist/adapters/drizzle.mjs +4 -4
  3. package/dist/adapters/kysely.cjs +3 -3
  4. package/dist/adapters/kysely.mjs +2 -2
  5. package/dist/adapters/mongodb.cjs +3 -3
  6. package/dist/adapters/mongodb.mjs +2 -2
  7. package/dist/adapters/mongodbAdapter.cjs +19 -1
  8. package/dist/adapters/mongodbAdapter.mjs +19 -1
  9. package/dist/adapters/prisma.cjs +5 -5
  10. package/dist/adapters/prisma.mjs +4 -4
  11. package/dist/assembly/assemblePlugins.cjs +47 -28
  12. package/dist/assembly/assemblePlugins.d.cts +3 -7
  13. package/dist/assembly/assemblePlugins.d.mts +3 -7
  14. package/dist/assembly/assemblePlugins.mjs +46 -27
  15. package/dist/assembly/clientPlugins.cjs +86 -0
  16. package/dist/assembly/clientPlugins.d.cts +16 -0
  17. package/dist/assembly/clientPlugins.d.mts +16 -0
  18. package/dist/assembly/clientPlugins.mjs +86 -0
  19. package/dist/assembly/configError.cjs +7 -0
  20. package/dist/assembly/configError.d.cts +7 -0
  21. package/dist/assembly/configError.d.mts +7 -0
  22. package/dist/assembly/configError.mjs +7 -0
  23. package/dist/assembly/databasePlugins.cjs +5 -1
  24. package/dist/assembly/databasePlugins.d.cts +5 -5
  25. package/dist/assembly/databasePlugins.d.mts +5 -5
  26. package/dist/assembly/databasePlugins.mjs +5 -1
  27. package/dist/assembly/pluginCli.cjs +125 -0
  28. package/dist/assembly/pluginCli.d.cts +59 -0
  29. package/dist/assembly/pluginCli.d.mts +59 -0
  30. package/dist/assembly/pluginCli.mjs +121 -0
  31. package/dist/createHotUpdaterCore.cjs +14 -16
  32. package/dist/createHotUpdaterCore.d.cts +10 -3
  33. package/dist/createHotUpdaterCore.d.mts +10 -3
  34. package/dist/createHotUpdaterCore.mjs +11 -13
  35. package/dist/database/aggregateBatching.cjs +626 -0
  36. package/dist/database/aggregateBatching.d.cts +10 -0
  37. package/dist/database/aggregateBatching.d.mts +10 -0
  38. package/dist/database/aggregateBatching.mjs +625 -0
  39. package/dist/{insights/errors.cjs → database/busy.cjs} +2 -15
  40. package/dist/database/busy.d.cts +12 -0
  41. package/dist/database/busy.d.mts +12 -0
  42. package/dist/{insights/errors.mjs → database/busy.mjs} +3 -14
  43. package/dist/database/database.cjs +22 -3
  44. package/dist/database/database.d.cts +15 -2
  45. package/dist/database/database.d.mts +15 -2
  46. package/dist/database/database.mjs +22 -3
  47. package/dist/database/definitions.d.cts +10 -0
  48. package/dist/database/definitions.d.mts +10 -0
  49. package/dist/database/engine.d.cts +2 -1
  50. package/dist/database/engine.d.mts +2 -1
  51. package/dist/database/engineAggregates.cjs +7 -4
  52. package/dist/database/engineAggregates.mjs +8 -5
  53. package/dist/database/engineReads.cjs +5 -3
  54. package/dist/database/engineReads.mjs +6 -4
  55. package/dist/database/engineTransaction.cjs +2 -6
  56. package/dist/database/engineTransaction.mjs +2 -6
  57. package/dist/database/fence.cjs +2 -1
  58. package/dist/database/fence.mjs +2 -1
  59. package/dist/database/index.cjs +17 -8
  60. package/dist/database/index.d.cts +5 -4
  61. package/dist/database/index.d.mts +5 -4
  62. package/dist/database/index.mjs +6 -5
  63. package/dist/database/kv/kvAdapter.cjs +15 -3
  64. package/dist/database/kv/kvAdapter.d.cts +8 -0
  65. package/dist/database/kv/kvAdapter.d.mts +8 -0
  66. package/dist/database/kv/kvAdapter.mjs +16 -4
  67. package/dist/database/resolveSchema.cjs +4 -1
  68. package/dist/database/resolveSchema.d.cts +1 -1
  69. package/dist/database/resolveSchema.d.mts +1 -1
  70. package/dist/database/resolveSchema.mjs +4 -1
  71. package/dist/database/retention.cjs +92 -0
  72. package/dist/database/retention.mjs +90 -0
  73. package/dist/database/schema.cjs +5 -2
  74. package/dist/database/schema.d.cts +30 -1
  75. package/dist/database/schema.d.mts +30 -1
  76. package/dist/database/schema.mjs +5 -2
  77. package/dist/database/sql/sqlAdapter.cjs +8 -0
  78. package/dist/database/sql/sqlAdapter.mjs +9 -1
  79. package/dist/database/sql/sqlSchema.cjs +56 -0
  80. package/dist/database/sql/sqlSchema.mjs +55 -1
  81. package/dist/db/coreDatabase.cjs +85 -0
  82. package/dist/db/coreDatabase.d.cts +57 -0
  83. package/dist/db/coreDatabase.d.mts +57 -0
  84. package/dist/db/coreDatabase.mjs +78 -0
  85. package/dist/db/index.cjs +11 -3
  86. package/dist/db/index.d.cts +7 -3
  87. package/dist/db/index.d.mts +7 -3
  88. package/dist/db/index.mjs +6 -3
  89. package/dist/db/types.d.cts +3 -3
  90. package/dist/db/types.d.mts +3 -3
  91. package/dist/diff.cjs +3 -0
  92. package/dist/diff.d.cts +2 -0
  93. package/dist/diff.d.mts +2 -0
  94. package/dist/diff.mjs +2 -0
  95. package/dist/handler.cjs +2 -14
  96. package/dist/handler.mjs +1 -13
  97. package/dist/handlerReleaseCatalogRoutes.cjs +21 -2
  98. package/dist/handlerReleaseCatalogRoutes.mjs +21 -2
  99. package/dist/index.cjs +2 -6
  100. package/dist/index.d.cts +4 -7
  101. package/dist/index.d.mts +4 -7
  102. package/dist/index.mjs +2 -4
  103. package/dist/package.cjs +1 -1
  104. package/dist/package.mjs +1 -1
  105. package/dist/{apiKeys.cjs → plugins/api-keys/apiKeys.cjs} +1 -1
  106. package/dist/{apiKeys.d.cts → plugins/api-keys/apiKeys.d.cts} +2 -2
  107. package/dist/{apiKeys.d.mts → plugins/api-keys/apiKeys.d.mts} +2 -2
  108. package/dist/{apiKeys.mjs → plugins/api-keys/apiKeys.mjs} +1 -1
  109. package/dist/plugins/api-keys/cli.cjs +115 -0
  110. package/dist/plugins/api-keys/cli.mjs +114 -0
  111. package/dist/plugins/api-keys/index.cjs +9 -6
  112. package/dist/plugins/api-keys/index.d.cts +4 -5
  113. package/dist/plugins/api-keys/index.d.mts +4 -5
  114. package/dist/plugins/api-keys/index.mjs +9 -7
  115. package/dist/plugins/api-keys/model.d.cts +20 -2
  116. package/dist/plugins/api-keys/model.d.mts +20 -2
  117. package/dist/plugins/definePlugin.cjs +1 -1
  118. package/dist/plugins/definePlugin.d.cts +130 -3
  119. package/dist/plugins/definePlugin.d.mts +130 -3
  120. package/dist/plugins/definePlugin.mjs +1 -1
  121. package/dist/plugins/index.cjs +25 -4
  122. package/dist/plugins/index.d.cts +7 -4
  123. package/dist/plugins/index.d.mts +7 -4
  124. package/dist/plugins/index.mjs +6 -4
  125. package/dist/plugins/insights/contract.cjs +193 -0
  126. package/dist/plugins/insights/contract.mjs +189 -0
  127. package/dist/{insights → plugins/insights}/domain.d.cts +60 -15
  128. package/dist/{insights → plugins/insights}/domain.d.mts +60 -15
  129. package/dist/plugins/insights/errors.cjs +15 -0
  130. package/dist/plugins/insights/errors.mjs +14 -0
  131. package/dist/{insights → plugins/insights}/eventInput.cjs +155 -22
  132. package/dist/{insights → plugins/insights}/eventInput.mjs +155 -22
  133. package/dist/plugins/insights/eventRow.cjs +49 -0
  134. package/dist/plugins/insights/eventRow.d.cts +64 -0
  135. package/dist/plugins/insights/eventRow.d.mts +64 -0
  136. package/dist/plugins/insights/eventRow.mjs +47 -0
  137. package/dist/plugins/insights/index.cjs +106 -26
  138. package/dist/plugins/insights/index.d.cts +130 -27
  139. package/dist/plugins/insights/index.d.mts +130 -27
  140. package/dist/plugins/insights/index.mjs +106 -29
  141. package/dist/plugins/insights/model.cjs +2 -2
  142. package/dist/plugins/insights/model.d.cts +1 -1
  143. package/dist/plugins/insights/model.d.mts +1 -1
  144. package/dist/plugins/insights/model.mjs +1 -1
  145. package/dist/plugins/insights/modelTypes.d.cts +176 -0
  146. package/dist/plugins/insights/modelTypes.d.mts +176 -0
  147. package/dist/plugins/insights/overview.cjs +109 -0
  148. package/dist/plugins/insights/overview.d.cts +15 -0
  149. package/dist/plugins/insights/overview.d.mts +15 -0
  150. package/dist/plugins/insights/overview.mjs +107 -0
  151. package/dist/{insights → plugins/insights}/provider.cjs +33 -14
  152. package/dist/{insights → plugins/insights}/provider.d.cts +2 -2
  153. package/dist/{insights → plugins/insights}/provider.d.mts +2 -2
  154. package/dist/{insights → plugins/insights}/provider.mjs +30 -11
  155. package/dist/{insights → plugins/insights}/queryInput.cjs +2 -2
  156. package/dist/{insights → plugins/insights}/queryInput.mjs +2 -2
  157. package/dist/plugins/insights/reads.cjs +298 -88
  158. package/dist/plugins/insights/reads.d.cts +61 -0
  159. package/dist/plugins/insights/reads.d.mts +61 -0
  160. package/dist/plugins/insights/reads.mjs +298 -90
  161. package/dist/plugins/insights/recordEvent.cjs +223 -39
  162. package/dist/plugins/insights/recordEvent.d.cts +9 -4
  163. package/dist/plugins/insights/recordEvent.d.mts +9 -4
  164. package/dist/plugins/insights/recordEvent.mjs +221 -37
  165. package/dist/{insights → plugins/insights}/routes.cjs +3 -30
  166. package/dist/{insights → plugins/insights}/routes.mjs +4 -28
  167. package/dist/plugins/insights/schema.cjs +182 -40
  168. package/dist/plugins/insights/schema.d.cts +446 -6
  169. package/dist/plugins/insights/schema.d.mts +446 -6
  170. package/dist/plugins/insights/schema.mjs +180 -41
  171. package/dist/plugins/insights/testing/eventRow.d.mts +64 -0
  172. package/dist/plugins/insights/testing/expectInsightsIndex.mjs +18 -0
  173. package/dist/plugins/insights/testing/fixtures.d.mts +8 -0
  174. package/dist/plugins/insights/testing/fixtures.mjs +25 -0
  175. package/dist/plugins/insights/testing/index.d.mts +24 -0
  176. package/dist/plugins/insights/testing/index.mjs +25 -0
  177. package/dist/plugins/insights/testing/insightsModelTests.mjs +714 -0
  178. package/dist/plugins/insights/testing/modelTypes.d.mts +176 -0
  179. package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.d.mts +11 -0
  180. package/dist/plugins/insights/testing/setupInsightsHttpTestSuite.mjs +107 -0
  181. package/dist/plugins/insights/testing/setupInsightsModelTestSuite.d.mts +11 -0
  182. package/dist/plugins/insights/testing/setupInsightsModelTestSuite.mjs +31 -0
  183. package/dist/plugins/insights/testing/types.d.mts +26 -0
  184. package/dist/{insights → plugins/insights}/types.d.cts +3 -2
  185. package/dist/{insights → plugins/insights}/types.d.mts +3 -2
  186. package/package.json +18 -7
  187. package/src/adapters/drizzle.conformance.integration.spec.ts +2 -2
  188. package/src/adapters/drizzle.readBudgets.integration.spec.ts +6 -4
  189. package/src/adapters/drizzle.spec.ts +15 -7
  190. package/src/adapters/drizzle.ts +6 -6
  191. package/src/adapters/kysely.conformance.integration.spec.ts +2 -2
  192. package/src/adapters/kysely.readBudgets.integration.spec.ts +4 -2
  193. package/src/adapters/kysely.spec.ts +13 -9
  194. package/src/adapters/kysely.ts +2 -2
  195. package/src/adapters/mongodb.integration.spec.ts +98 -7
  196. package/src/adapters/mongodb.ts +2 -2
  197. package/src/adapters/mongodbAdapter.ts +14 -0
  198. package/src/adapters/prisma.conformance.integration.spec.ts +2 -2
  199. package/src/adapters/prisma.integration.spec.ts +16 -8
  200. package/src/adapters/prisma.readBudgets.integration.spec.ts +5 -2
  201. package/src/adapters/prisma.spec.ts +17 -9
  202. package/src/adapters/prisma.ts +6 -6
  203. package/src/adapters/prismaTestClients.ts +8 -1
  204. package/src/assembly/assemblePlugins.ts +73 -40
  205. package/src/assembly/assembly.spec.ts +63 -11
  206. package/src/assembly/assembly.types.spec.ts +50 -2
  207. package/src/assembly/clientPlugins.ts +113 -0
  208. package/src/assembly/configError.ts +4 -0
  209. package/src/assembly/databasePlugins.ts +11 -5
  210. package/src/assembly/pluginCli.spec.ts +254 -0
  211. package/src/assembly/pluginCli.ts +248 -0
  212. package/src/assembly/{builtInRoutes.spec.ts → pluginRoutes.spec.ts} +10 -37
  213. package/src/createHotUpdaterCore.ts +21 -17
  214. package/src/database/aggregateBatching.spec.ts +577 -0
  215. package/src/database/aggregateBatching.ts +803 -0
  216. package/src/{insights/errors.spec.ts → database/busy.spec.ts} +2 -5
  217. package/src/{insights/errors.ts → database/busy.ts} +1 -13
  218. package/src/database/database.ts +39 -8
  219. package/src/database/definitions.ts +4 -0
  220. package/src/database/engineAggregates.spec.ts +4 -7
  221. package/src/database/engineAggregates.ts +5 -9
  222. package/src/database/engineReads.ts +7 -5
  223. package/src/database/engineTransaction.ts +1 -7
  224. package/src/database/fence.spec.ts +5 -5
  225. package/src/database/fence.ts +4 -0
  226. package/src/database/index.ts +13 -7
  227. package/src/database/kv/kvAdapter.batching.integration.spec.ts +15 -0
  228. package/src/database/kv/kvAdapter.conformance.integration.spec.ts +2 -0
  229. package/src/database/kv/kvAdapter.spec.ts +128 -1
  230. package/src/database/kv/kvAdapter.ts +30 -1
  231. package/src/database/kv/kvTestStore.ts +28 -1
  232. package/src/database/resolveSchema.ts +4 -1
  233. package/src/database/retention.spec.ts +314 -0
  234. package/src/database/retention.ts +129 -0
  235. package/src/database/schema.ts +44 -0
  236. package/src/database/sql/sqlAdapter.integration.spec.ts +4 -7
  237. package/src/database/sql/sqlAdapter.readBudgets.integration.spec.ts +18 -4
  238. package/src/database/sql/sqlAdapter.spec.ts +91 -3
  239. package/src/database/sql/sqlAdapter.ts +20 -0
  240. package/src/database/sql/sqlSchema.ts +81 -0
  241. package/src/databaseTestSuite.spec.ts +9 -4
  242. package/src/db/coreDatabase.ts +153 -0
  243. package/src/db/engineSql.spec.ts +8 -7
  244. package/src/db/index.ts +19 -2
  245. package/src/db/pluginTables.spec.ts +57 -27
  246. package/src/db/types.ts +3 -3
  247. package/src/diff.ts +6 -0
  248. package/src/handler-standalone.integration.spec.ts +2 -3
  249. package/src/handler.ts +1 -32
  250. package/src/handlerReleaseCatalogRoutes.ts +26 -2
  251. package/src/index.ts +0 -10
  252. package/src/{apiKeys.integration.spec.ts → plugins/api-keys/apiKeys.integration.spec.ts} +4 -4
  253. package/src/{apiKeys.spec.ts → plugins/api-keys/apiKeys.spec.ts} +3 -3
  254. package/src/{apiKeys.ts → plugins/api-keys/apiKeys.ts} +1 -1
  255. package/src/plugins/api-keys/apiKeysPlugin.spec.ts +11 -15
  256. package/src/plugins/api-keys/cli.spec.ts +187 -0
  257. package/src/plugins/api-keys/cli.ts +140 -0
  258. package/src/plugins/api-keys/index.ts +48 -41
  259. package/src/plugins/api-keys/model.ts +21 -2
  260. package/src/plugins/definePlugin.ts +144 -2
  261. package/src/plugins/index.ts +20 -2
  262. package/src/plugins/insights/contract.spec.ts +285 -0
  263. package/src/plugins/insights/contract.ts +372 -0
  264. package/src/{insights → plugins/insights}/domain.ts +73 -15
  265. package/src/plugins/insights/errors.ts +11 -0
  266. package/src/{insights → plugins/insights}/eventInput.ts +189 -29
  267. package/src/plugins/insights/eventRow.ts +209 -0
  268. package/src/plugins/insights/index.ts +181 -45
  269. package/src/{insights → plugins/insights}/insights.integration.spec.ts +330 -34
  270. package/src/plugins/insights/insightsRollout.integration.spec.ts +1 -2
  271. package/src/plugins/insights/model.spec.ts +3 -5
  272. package/src/plugins/insights/model.ts +2 -3
  273. package/src/plugins/insights/modelTypes.ts +197 -0
  274. package/src/plugins/insights/overview.spec.ts +64 -0
  275. package/src/plugins/insights/overview.ts +214 -0
  276. package/src/{insights → plugins/insights}/provider.spec.ts +21 -10
  277. package/src/{insights → plugins/insights}/provider.ts +58 -21
  278. package/src/{insights → plugins/insights}/queryInput.ts +2 -2
  279. package/src/plugins/insights/reads.spec.ts +340 -52
  280. package/src/plugins/insights/reads.ts +453 -123
  281. package/src/plugins/insights/recordEvent.spec.ts +474 -20
  282. package/src/plugins/insights/recordEvent.ts +301 -63
  283. package/src/plugins/insights/retention.spec.ts +115 -0
  284. package/src/{insights → plugins/insights}/routes.ts +1 -31
  285. package/src/plugins/insights/schema.ts +356 -176
  286. package/src/plugins/insights/testing/expectInsightsIndex.spec.ts +42 -0
  287. package/src/plugins/insights/testing/expectInsightsIndex.ts +20 -0
  288. package/src/plugins/insights/testing/fixtures.ts +30 -0
  289. package/src/plugins/insights/testing/index.ts +45 -0
  290. package/src/plugins/insights/testing/insightsModelTests.ts +860 -0
  291. package/src/plugins/insights/testing/setupInsightsHttpTestSuite.ts +152 -0
  292. package/src/plugins/insights/testing/setupInsightsModelTestSuite.ts +36 -0
  293. package/src/plugins/insights/testing/types.ts +30 -0
  294. package/src/{insights → plugins/insights}/types.ts +1 -1
  295. package/src/readBudgets.testFixtures.ts +2 -2
  296. package/src/releaseCatalogRoutes.integration.spec.ts +7 -0
  297. package/src/retention.spec.ts +73 -0
  298. package/src/runtime.spec.ts +11 -12
  299. package/src/runtime.testFixtures.ts +7 -2
  300. package/src/testUtilsMutation.integration.spec.ts +2 -1
  301. package/src/testUtilsPackage.integration.spec.ts +7 -3
  302. package/dist/db/builtInDatabase.cjs +0 -104
  303. package/dist/db/builtInDatabase.d.cts +0 -38
  304. package/dist/db/builtInDatabase.d.mts +0 -38
  305. package/dist/db/builtInDatabase.mjs +0 -97
  306. package/dist/plugins/builtIn.cjs +0 -7
  307. package/dist/plugins/builtIn.mjs +0 -6
  308. package/src/db/builtInDatabase.ts +0 -149
  309. package/src/plugins/builtIn.ts +0 -5
@@ -80,6 +80,13 @@ const sqlTableShapes = (dialect, tables, tablePrefix = "") => tables.map((table)
80
80
  columns: index.unique ? index.eq : columns
81
81
  }];
82
82
  });
83
+ const retention = table.retention && retentionOrder(table);
84
+ if (retention && !retention.indexed) indexes.push({
85
+ kind: "index",
86
+ name: shortSqlName(`${name}__retention`),
87
+ unique: false,
88
+ columns: retention.columns
89
+ });
83
90
  return {
84
91
  name,
85
92
  columns: table.columns.map((column) => ({
@@ -107,9 +114,58 @@ const createTableStatements = (dialect, tables, tablePrefix = "") => {
107
114
  };
108
115
  return sqlTableShapes(dialect, tables, tablePrefix).flatMap(render);
109
116
  };
117
+ /**
118
+ * The order a prune walks a table's expired rows in, which ends with the
119
+ * key so it is total: the columns of the first index that leads with the
120
+ * retention column, or the key when it does, or else the column and the
121
+ * key, which then need an index of their own (`indexed` false).
122
+ */
123
+ const retentionOrder = (table) => {
124
+ const { column } = table.retention;
125
+ for (const index of table.indexes) {
126
+ const columns = [...index.eq, ...(0, _hot_updater_plugin_core_internal.indexOrderColumns)(table, index)];
127
+ if (!index.unique && !isMultiIndex(table, index) && columns[0] === column) return {
128
+ columns,
129
+ indexed: true
130
+ };
131
+ }
132
+ if (table.key[0] === column) return {
133
+ columns: table.key,
134
+ indexed: true
135
+ };
136
+ return {
137
+ columns: [column, ...table.key.filter((field) => field !== column)],
138
+ indexed: false
139
+ };
140
+ };
141
+ /**
142
+ * The statements that delete up to `limit` expired rows of a table with
143
+ * retention, oldest first in {@link retentionOrder}: its multi-valued index
144
+ * entries, then the rows, which a concurrent write that moved the retention
145
+ * column past `before` keeps. `before` renders the bound each time it
146
+ * appears. MySQL deletes with ORDER BY and LIMIT. Elsewhere the cutoff is
147
+ * the last of the `limit` oldest expired rows in that order, a row value
148
+ * the index ranges over, and the shapes pass Supabase's apply RPC: no IN, no
149
+ * AS, aliases `i` and `b`.
150
+ */
151
+ const pruneStatements = (dialect, table, tablePrefix, limit) => {
152
+ const quote = (name) => quoteSql(dialect, name);
153
+ const name = quote(`${tablePrefix}${table.name}`);
154
+ const at = quote(table.retention.column);
155
+ const order = retentionOrder(table).columns.map(quote);
156
+ const list = (alias, direction = "") => order.map((column) => `${alias}.${column}${direction}`).join(", ");
157
+ const oldest = (before) => `SELECT ${list("i")} FROM ${name} i WHERE i.${at} <= ${before()} ORDER BY ${list("i", " ASC")} LIMIT ${limit}`;
158
+ const doomed = (alias, before) => `${alias}.${at} <= ${before()} AND (${list(alias)}) <= (SELECT ${list("b")} FROM (${oldest(before)}) b ORDER BY ${list("b", " DESC")} LIMIT 1)`;
159
+ const entries = table.indexes.filter((index) => isMultiIndex(table, index)).map((index) => quote(`${tablePrefix}${table.name}__${index.name}`));
160
+ const keyOf = (left, right) => table.key.map((column) => `${left}.${quote(column)} = ${right}.${quote(column)}`).join(" AND ");
161
+ if (dialect === "mysql") return [...entries.map((index) => (before) => `DELETE e FROM ${index} e JOIN (${oldest(before)}) d ON ${keyOf("e", "d")}`), (before) => `DELETE FROM ${name} WHERE ${at} <= ${before()} ORDER BY ${order.join(", ")} LIMIT ${limit}`];
162
+ return [...entries.map((index) => (before) => `DELETE FROM ${index} WHERE EXISTS (SELECT * FROM ${name} b WHERE ${keyOf("b", index)} AND ${doomed("b", before)})`), (before) => `DELETE FROM ${name} WHERE ${doomed(name, before)}`];
163
+ };
110
164
  //#endregion
111
165
  exports.createTableStatements = createTableStatements;
112
166
  exports.isMultiIndex = isMultiIndex;
167
+ exports.pruneStatements = pruneStatements;
113
168
  exports.quoteSql = quoteSql;
169
+ exports.retentionOrder = retentionOrder;
114
170
  exports.shortSqlName = shortSqlName;
115
171
  exports.sqlTableShapes = sqlTableShapes;
@@ -80,6 +80,13 @@ const sqlTableShapes = (dialect, tables, tablePrefix = "") => tables.map((table)
80
80
  columns: index.unique ? index.eq : columns
81
81
  }];
82
82
  });
83
+ const retention = table.retention && retentionOrder(table);
84
+ if (retention && !retention.indexed) indexes.push({
85
+ kind: "index",
86
+ name: shortSqlName(`${name}__retention`),
87
+ unique: false,
88
+ columns: retention.columns
89
+ });
83
90
  return {
84
91
  name,
85
92
  columns: table.columns.map((column) => ({
@@ -107,5 +114,52 @@ const createTableStatements = (dialect, tables, tablePrefix = "") => {
107
114
  };
108
115
  return sqlTableShapes(dialect, tables, tablePrefix).flatMap(render);
109
116
  };
117
+ /**
118
+ * The order a prune walks a table's expired rows in, which ends with the
119
+ * key so it is total: the columns of the first index that leads with the
120
+ * retention column, or the key when it does, or else the column and the
121
+ * key, which then need an index of their own (`indexed` false).
122
+ */
123
+ const retentionOrder = (table) => {
124
+ const { column } = table.retention;
125
+ for (const index of table.indexes) {
126
+ const columns = [...index.eq, ...indexOrderColumns(table, index)];
127
+ if (!index.unique && !isMultiIndex(table, index) && columns[0] === column) return {
128
+ columns,
129
+ indexed: true
130
+ };
131
+ }
132
+ if (table.key[0] === column) return {
133
+ columns: table.key,
134
+ indexed: true
135
+ };
136
+ return {
137
+ columns: [column, ...table.key.filter((field) => field !== column)],
138
+ indexed: false
139
+ };
140
+ };
141
+ /**
142
+ * The statements that delete up to `limit` expired rows of a table with
143
+ * retention, oldest first in {@link retentionOrder}: its multi-valued index
144
+ * entries, then the rows, which a concurrent write that moved the retention
145
+ * column past `before` keeps. `before` renders the bound each time it
146
+ * appears. MySQL deletes with ORDER BY and LIMIT. Elsewhere the cutoff is
147
+ * the last of the `limit` oldest expired rows in that order, a row value
148
+ * the index ranges over, and the shapes pass Supabase's apply RPC: no IN, no
149
+ * AS, aliases `i` and `b`.
150
+ */
151
+ const pruneStatements = (dialect, table, tablePrefix, limit) => {
152
+ const quote = (name) => quoteSql(dialect, name);
153
+ const name = quote(`${tablePrefix}${table.name}`);
154
+ const at = quote(table.retention.column);
155
+ const order = retentionOrder(table).columns.map(quote);
156
+ const list = (alias, direction = "") => order.map((column) => `${alias}.${column}${direction}`).join(", ");
157
+ const oldest = (before) => `SELECT ${list("i")} FROM ${name} i WHERE i.${at} <= ${before()} ORDER BY ${list("i", " ASC")} LIMIT ${limit}`;
158
+ const doomed = (alias, before) => `${alias}.${at} <= ${before()} AND (${list(alias)}) <= (SELECT ${list("b")} FROM (${oldest(before)}) b ORDER BY ${list("b", " DESC")} LIMIT 1)`;
159
+ const entries = table.indexes.filter((index) => isMultiIndex(table, index)).map((index) => quote(`${tablePrefix}${table.name}__${index.name}`));
160
+ const keyOf = (left, right) => table.key.map((column) => `${left}.${quote(column)} = ${right}.${quote(column)}`).join(" AND ");
161
+ if (dialect === "mysql") return [...entries.map((index) => (before) => `DELETE e FROM ${index} e JOIN (${oldest(before)}) d ON ${keyOf("e", "d")}`), (before) => `DELETE FROM ${name} WHERE ${at} <= ${before()} ORDER BY ${order.join(", ")} LIMIT ${limit}`];
162
+ return [...entries.map((index) => (before) => `DELETE FROM ${index} WHERE EXISTS (SELECT * FROM ${name} b WHERE ${keyOf("b", index)} AND ${doomed("b", before)})`), (before) => `DELETE FROM ${name} WHERE ${doomed(name, before)}`];
163
+ };
110
164
  //#endregion
111
- export { createTableStatements, isMultiIndex, quoteSql, shortSqlName, sqlTableShapes };
165
+ export { createTableStatements, isMultiIndex, pruneStatements, quoteSql, retentionOrder, shortSqlName, sqlTableShapes };
@@ -0,0 +1,85 @@
1
+ const require_resolveSchema = require("../database/resolveSchema.cjs");
2
+ const require_schema = require("../core/schema.cjs");
3
+ const require_fence = require("../database/fence.cjs");
4
+ const require_schemaSettings = require("./schemaSettings.cjs");
5
+ const require_engineMigrator = require("./engineMigrator.cjs");
6
+ //#region src/db/coreDatabase.ts
7
+ /** Core's tables: the tables every provider's tooling creates. */
8
+ const coreSchema = require_resolveSchema.resolveSchema([require_schema.coreModule]);
9
+ /** The settings rows a provider's database is fenced by. */
10
+ const coreSettings = {
11
+ [require_fence.ENGINE_SCHEMA_KEY]: "1",
12
+ "schema.core": require_schema.HOT_UPDATER_SCHEMA_VERSION
13
+ };
14
+ /** What `hot-updater db` creates for a server without plugins. */
15
+ const coreTarget = {
16
+ schema: coreSchema,
17
+ settings: coreSettings
18
+ };
19
+ /** Each plugin's `schema.<id>` settings row. */
20
+ const pluginSettings = (plugins) => Object.fromEntries(plugins.map(({ id, schemaVersion }) => [`schema.${id}`, schemaVersion]));
21
+ /** A plugin's schema as the engine resolves it: prefixed by its id unless it keeps its names. */
22
+ const pluginModule = ({ id, schema, namespace }) => ({
23
+ id,
24
+ schema,
25
+ ...namespace === false ? {} : { namespace: id }
26
+ });
27
+ /**
28
+ * What `hot-updater db` creates for a server's plugins: core's tables, then
29
+ * each plugin's tables with its `schema.<id>` settings row.
30
+ */
31
+ const toolingTargetOf = (plugins) => plugins.length === 0 ? coreTarget : {
32
+ schema: require_resolveSchema.resolveSchema([require_schema.coreModule, ...plugins.map(pluginModule)]),
33
+ settings: {
34
+ ...coreSettings,
35
+ ...pluginSettings(plugins)
36
+ }
37
+ };
38
+ /**
39
+ * Creates core's tables and those of `plugins`, then writes their settings
40
+ * rows: what a provider's setup runs for the plugins its server runs.
41
+ */
42
+ const migrateCoreSchema = (adapter, name, plugins = []) => {
43
+ const { schema, settings } = toolingTargetOf(plugins);
44
+ return require_schemaSettings.migrateSchema(adapter, name, schema.tables, settings);
45
+ };
46
+ /**
47
+ * A provider's database on the storage engine: its adapter behind the schema
48
+ * fence, which checks core's settings rows before the first read or write
49
+ * and names `hot-updater db migrate` when they are missing or stale. When the
50
+ * adapter creates its own tables, `hot-updater db migrate` creates core's
51
+ * tables and the server's plugin tables, then writes their settings rows.
52
+ */
53
+ const createEngineDatabase = ({ name, adapter, onCachedRoutesChange, aggregateBatching }) => {
54
+ const fenced = require_fence.withSchemaFence(adapter, name, coreSettings);
55
+ const createMigrator = ({ schema, settings } = coreTarget) => require_engineMigrator.createEngineMigrator({
56
+ adapterName: name,
57
+ adapter,
58
+ schema,
59
+ settings,
60
+ readSettings: async () => {
61
+ const rows = await require_fence.readSettings(adapter, Object.keys(settings)).catch((error) => {
62
+ if (require_fence.isMissingSchemaError(error)) return [];
63
+ throw error;
64
+ });
65
+ return new Map(rows.flatMap((row) => row === null ? [] : [[String(row.key), row.value]]));
66
+ }
67
+ });
68
+ return {
69
+ name,
70
+ adapter: fenced,
71
+ ...onCachedRoutesChange === void 0 ? {} : { onCachedRoutesChange },
72
+ ...aggregateBatching ? { aggregateBatching } : {},
73
+ ...adapter.dispose === void 0 ? {} : { dispose: () => adapter.dispose() },
74
+ ...adapter.migrations === void 0 ? {} : { createMigrator }
75
+ };
76
+ };
77
+ //#endregion
78
+ exports.coreSchema = coreSchema;
79
+ exports.coreSettings = coreSettings;
80
+ exports.coreTarget = coreTarget;
81
+ exports.createEngineDatabase = createEngineDatabase;
82
+ exports.migrateCoreSchema = migrateCoreSchema;
83
+ exports.pluginModule = pluginModule;
84
+ exports.pluginSettings = pluginSettings;
85
+ exports.toolingTargetOf = toolingTargetOf;
@@ -0,0 +1,57 @@
1
+ import { SchemaSettings } from "../database/fence.cjs";
2
+ import { ModelShape } from "../database/definitions.cjs";
3
+ import { ResolvedSchema } from "../database/resolveSchema.cjs";
4
+ import { ToolingDatabase, ToolingTarget } from "./types.cjs";
5
+ import "../database/index.cjs";
6
+ import { AggregateBatching } from "@hot-updater/plugin-core";
7
+ import { DatabaseAdapter } from "@hot-updater/plugin-core/internal";
8
+ //#region src/db/coreDatabase.d.ts
9
+ /** Core's tables: the tables every provider's tooling creates. */
10
+ declare const coreSchema: ResolvedSchema;
11
+ /** The settings rows a provider's database is fenced by. */
12
+ declare const coreSettings: SchemaSettings;
13
+ /** What `hot-updater db` creates for a server without plugins. */
14
+ declare const coreTarget: ToolingTarget;
15
+ /** A plugin as the tooling reads it: its id, its tables, and their version. */
16
+ interface PluginTables {
17
+ readonly id: string;
18
+ readonly schemaVersion: string;
19
+ readonly schema: Readonly<Record<string, ModelShape>>;
20
+ /** `false` keeps the declared table names instead of prefixing them with the id. */
21
+ readonly namespace?: false;
22
+ }
23
+ /**
24
+ * What `hot-updater db` creates for a server's plugins: core's tables, then
25
+ * each plugin's tables with its `schema.<id>` settings row.
26
+ */
27
+ declare const toolingTargetOf: (plugins: readonly PluginTables[]) => ToolingTarget;
28
+ /**
29
+ * Creates core's tables and those of `plugins`, then writes their settings
30
+ * rows: what a provider's setup runs for the plugins its server runs.
31
+ */
32
+ declare const migrateCoreSchema: (adapter: DatabaseAdapter, name: string, plugins?: readonly PluginTables[]) => Promise<void>;
33
+ interface EngineDatabaseOptions {
34
+ readonly name: string;
35
+ readonly adapter: DatabaseAdapter;
36
+ /**
37
+ * Purges a CDN's copies of the cacheable client routes. Core calls it after
38
+ * a committed write that changes what those routes answer, since only core
39
+ * knows which of its tables they read.
40
+ */
41
+ readonly onCachedRoutesChange?: () => Promise<void>;
42
+ /**
43
+ * Batches aggregates declared `batched`, for stores that bill each write;
44
+ * `false` or absent commits them with each transaction.
45
+ */
46
+ readonly aggregateBatching?: AggregateBatching | false;
47
+ }
48
+ /**
49
+ * A provider's database on the storage engine: its adapter behind the schema
50
+ * fence, which checks core's settings rows before the first read or write
51
+ * and names `hot-updater db migrate` when they are missing or stale. When the
52
+ * adapter creates its own tables, `hot-updater db migrate` creates core's
53
+ * tables and the server's plugin tables, then writes their settings rows.
54
+ */
55
+ declare const createEngineDatabase: ({ name, adapter, onCachedRoutesChange, aggregateBatching }: EngineDatabaseOptions) => ToolingDatabase;
56
+ //#endregion
57
+ export { EngineDatabaseOptions, PluginTables, coreSchema, coreSettings, coreTarget, createEngineDatabase, migrateCoreSchema, toolingTargetOf };
@@ -0,0 +1,57 @@
1
+ import { SchemaSettings } from "../database/fence.mjs";
2
+ import { ModelShape } from "../database/definitions.mjs";
3
+ import { ResolvedSchema } from "../database/resolveSchema.mjs";
4
+ import { ToolingDatabase, ToolingTarget } from "./types.mjs";
5
+ import "../database/index.mjs";
6
+ import { AggregateBatching } from "@hot-updater/plugin-core";
7
+ import { DatabaseAdapter } from "@hot-updater/plugin-core/internal";
8
+ //#region src/db/coreDatabase.d.ts
9
+ /** Core's tables: the tables every provider's tooling creates. */
10
+ declare const coreSchema: ResolvedSchema;
11
+ /** The settings rows a provider's database is fenced by. */
12
+ declare const coreSettings: SchemaSettings;
13
+ /** What `hot-updater db` creates for a server without plugins. */
14
+ declare const coreTarget: ToolingTarget;
15
+ /** A plugin as the tooling reads it: its id, its tables, and their version. */
16
+ interface PluginTables {
17
+ readonly id: string;
18
+ readonly schemaVersion: string;
19
+ readonly schema: Readonly<Record<string, ModelShape>>;
20
+ /** `false` keeps the declared table names instead of prefixing them with the id. */
21
+ readonly namespace?: false;
22
+ }
23
+ /**
24
+ * What `hot-updater db` creates for a server's plugins: core's tables, then
25
+ * each plugin's tables with its `schema.<id>` settings row.
26
+ */
27
+ declare const toolingTargetOf: (plugins: readonly PluginTables[]) => ToolingTarget;
28
+ /**
29
+ * Creates core's tables and those of `plugins`, then writes their settings
30
+ * rows: what a provider's setup runs for the plugins its server runs.
31
+ */
32
+ declare const migrateCoreSchema: (adapter: DatabaseAdapter, name: string, plugins?: readonly PluginTables[]) => Promise<void>;
33
+ interface EngineDatabaseOptions {
34
+ readonly name: string;
35
+ readonly adapter: DatabaseAdapter;
36
+ /**
37
+ * Purges a CDN's copies of the cacheable client routes. Core calls it after
38
+ * a committed write that changes what those routes answer, since only core
39
+ * knows which of its tables they read.
40
+ */
41
+ readonly onCachedRoutesChange?: () => Promise<void>;
42
+ /**
43
+ * Batches aggregates declared `batched`, for stores that bill each write;
44
+ * `false` or absent commits them with each transaction.
45
+ */
46
+ readonly aggregateBatching?: AggregateBatching | false;
47
+ }
48
+ /**
49
+ * A provider's database on the storage engine: its adapter behind the schema
50
+ * fence, which checks core's settings rows before the first read or write
51
+ * and names `hot-updater db migrate` when they are missing or stale. When the
52
+ * adapter creates its own tables, `hot-updater db migrate` creates core's
53
+ * tables and the server's plugin tables, then writes their settings rows.
54
+ */
55
+ declare const createEngineDatabase: ({ name, adapter, onCachedRoutesChange, aggregateBatching }: EngineDatabaseOptions) => ToolingDatabase;
56
+ //#endregion
57
+ export { EngineDatabaseOptions, PluginTables, coreSchema, coreSettings, coreTarget, createEngineDatabase, migrateCoreSchema, toolingTargetOf };
@@ -0,0 +1,78 @@
1
+ import { resolveSchema } from "../database/resolveSchema.mjs";
2
+ import { HOT_UPDATER_SCHEMA_VERSION, coreModule } from "../core/schema.mjs";
3
+ import { ENGINE_SCHEMA_KEY, isMissingSchemaError, readSettings, withSchemaFence } from "../database/fence.mjs";
4
+ import { migrateSchema } from "./schemaSettings.mjs";
5
+ import { createEngineMigrator } from "./engineMigrator.mjs";
6
+ //#region src/db/coreDatabase.ts
7
+ /** Core's tables: the tables every provider's tooling creates. */
8
+ const coreSchema = resolveSchema([coreModule]);
9
+ /** The settings rows a provider's database is fenced by. */
10
+ const coreSettings = {
11
+ [ENGINE_SCHEMA_KEY]: "1",
12
+ "schema.core": HOT_UPDATER_SCHEMA_VERSION
13
+ };
14
+ /** What `hot-updater db` creates for a server without plugins. */
15
+ const coreTarget = {
16
+ schema: coreSchema,
17
+ settings: coreSettings
18
+ };
19
+ /** Each plugin's `schema.<id>` settings row. */
20
+ const pluginSettings = (plugins) => Object.fromEntries(plugins.map(({ id, schemaVersion }) => [`schema.${id}`, schemaVersion]));
21
+ /** A plugin's schema as the engine resolves it: prefixed by its id unless it keeps its names. */
22
+ const pluginModule = ({ id, schema, namespace }) => ({
23
+ id,
24
+ schema,
25
+ ...namespace === false ? {} : { namespace: id }
26
+ });
27
+ /**
28
+ * What `hot-updater db` creates for a server's plugins: core's tables, then
29
+ * each plugin's tables with its `schema.<id>` settings row.
30
+ */
31
+ const toolingTargetOf = (plugins) => plugins.length === 0 ? coreTarget : {
32
+ schema: resolveSchema([coreModule, ...plugins.map(pluginModule)]),
33
+ settings: {
34
+ ...coreSettings,
35
+ ...pluginSettings(plugins)
36
+ }
37
+ };
38
+ /**
39
+ * Creates core's tables and those of `plugins`, then writes their settings
40
+ * rows: what a provider's setup runs for the plugins its server runs.
41
+ */
42
+ const migrateCoreSchema = (adapter, name, plugins = []) => {
43
+ const { schema, settings } = toolingTargetOf(plugins);
44
+ return migrateSchema(adapter, name, schema.tables, settings);
45
+ };
46
+ /**
47
+ * A provider's database on the storage engine: its adapter behind the schema
48
+ * fence, which checks core's settings rows before the first read or write
49
+ * and names `hot-updater db migrate` when they are missing or stale. When the
50
+ * adapter creates its own tables, `hot-updater db migrate` creates core's
51
+ * tables and the server's plugin tables, then writes their settings rows.
52
+ */
53
+ const createEngineDatabase = ({ name, adapter, onCachedRoutesChange, aggregateBatching }) => {
54
+ const fenced = withSchemaFence(adapter, name, coreSettings);
55
+ const createMigrator = ({ schema, settings } = coreTarget) => createEngineMigrator({
56
+ adapterName: name,
57
+ adapter,
58
+ schema,
59
+ settings,
60
+ readSettings: async () => {
61
+ const rows = await readSettings(adapter, Object.keys(settings)).catch((error) => {
62
+ if (isMissingSchemaError(error)) return [];
63
+ throw error;
64
+ });
65
+ return new Map(rows.flatMap((row) => row === null ? [] : [[String(row.key), row.value]]));
66
+ }
67
+ });
68
+ return {
69
+ name,
70
+ adapter: fenced,
71
+ ...onCachedRoutesChange === void 0 ? {} : { onCachedRoutesChange },
72
+ ...aggregateBatching ? { aggregateBatching } : {},
73
+ ...adapter.dispose === void 0 ? {} : { dispose: () => adapter.dispose() },
74
+ ...adapter.migrations === void 0 ? {} : { createMigrator }
75
+ };
76
+ };
77
+ //#endregion
78
+ export { coreSchema, coreSettings, coreTarget, createEngineDatabase, migrateCoreSchema, pluginModule, pluginSettings, toolingTargetOf };
package/dist/db/index.cjs CHANGED
@@ -3,19 +3,22 @@ const require_baseCandidates = require("../core/baseCandidates.cjs");
3
3
  const require_api = require("../core/api.cjs");
4
4
  const require_fence = require("../database/fence.cjs");
5
5
  const require_engineSql = require("./engineSql.cjs");
6
+ const require_clientPlugins = require("../assembly/clientPlugins.cjs");
6
7
  const require_version = require("../version.cjs");
7
8
  const require_createHotUpdaterCore = require("../createHotUpdaterCore.cjs");
8
9
  const require_databasePlugins = require("../assembly/databasePlugins.cjs");
9
- const require_createBundleDiff = require("./createBundleDiff.cjs");
10
+ const require_pluginCli = require("../assembly/pluginCli.cjs");
10
11
  //#region src/db/index.ts
11
12
  const getDBMetadata = (hotUpdater) => {
12
13
  const metadata = require_createHotUpdaterCore.getHotUpdaterCoreMetadata(hotUpdater);
13
14
  if (!metadata) throw new Error("Database tooling requires a hotUpdater instance created by @hot-updater/server.");
14
15
  return metadata;
15
16
  };
17
+ /** A server's plugins as configured, whose commands the CLI adds. */
18
+ const serverPluginsOf = (hotUpdater) => getDBMetadata(hotUpdater).plugins;
16
19
  /** Whether `hot-updater db generate` writes schema files for a server's database. */
17
20
  const generatesSchema = (hotUpdater) => getDBMetadata(hotUpdater).database.generateSchema !== void 0;
18
- /** The migrator for a server's database: its built-in tables and its plugins' tables. */
21
+ /** The migrator for a server's database: core's tables and its plugins' tables. */
19
22
  function createMigrator(hotUpdater) {
20
23
  const { database, target } = getDBMetadata(hotUpdater);
21
24
  if (database.createMigrator === void 0) throw new Error(database.generateSchema === void 0 ? `The ${database.name} database has no migrator; its provider applies the schema.` : `The ${database.name} database applies its schema from migration files: run \`hot-updater db generate\`, then apply the file with the provider's tooling.`);
@@ -30,13 +33,18 @@ function generateSchema(hotUpdater, ...args) {
30
33
  //#endregion
31
34
  exports.HOT_UPDATER_SERVER_VERSION = require_version.HOT_UPDATER_SERVER_VERSION;
32
35
  exports.HotUpdaterSchemaMigrationRequiredError = require_fence.HotUpdaterSchemaMigrationRequiredError;
33
- exports.createBundleDiff = require_createBundleDiff.createBundleDiff;
36
+ exports.clientAuthOf = require_pluginCli.clientAuthOf;
37
+ exports.clientPluginsOf = require_clientPlugins.clientPluginsOf;
34
38
  exports.createDatabaseCoreApi = require_api.createDatabaseCoreApi;
35
39
  exports.createDatabasePluginApis = require_databasePlugins.createDatabasePluginApis;
36
40
  exports.createMeasuredDatabase = require_databasePlugins.createMeasuredDatabase;
37
41
  exports.createMigrator = createMigrator;
42
+ exports.generateClientCredential = require_pluginCli.generateClientCredential;
38
43
  exports.generateEngineSql = require_engineSql.generateEngineSql;
39
44
  exports.generateSchema = generateSchema;
40
45
  exports.generatesSchema = generatesSchema;
46
+ exports.pluginCommandsOf = require_pluginCli.pluginCommandsOf;
47
+ exports.provisionClientCredential = require_pluginCli.provisionClientCredential;
48
+ exports.serverPluginsOf = serverPluginsOf;
41
49
  exports.settingsStatements = require_engineSql.settingsStatements;
42
50
  exports.targetBaseCandidateKey = require_baseCandidates.targetBaseCandidateKey;
@@ -1,19 +1,23 @@
1
1
  import { HotUpdaterSchemaMigrationRequiredError } from "../database/fence.cjs";
2
2
  import { DatabaseTooling, Migrator, SchemaGenerator, ToolingDatabase, ToolingTarget } from "./types.cjs";
3
+ import { AnyHotUpdaterPlugin } from "../plugins/definePlugin.cjs";
3
4
  import { CoreApi, createDatabaseCoreApi } from "../core/api.cjs";
4
5
  import { MeasuredDatabase, MeasuredDatabaseOptions, createDatabasePluginApis, createMeasuredDatabase } from "../assembly/databasePlugins.cjs";
6
+ import { ClientPluginSpec, clientPluginsOf } from "../assembly/clientPlugins.cjs";
7
+ import { ClientAuthSpec, ClientCredentialSpec, PluginCommandEntry, ProvisionedClientCredential, clientAuthOf, generateClientCredential, pluginCommandsOf, provisionClientCredential } from "../assembly/pluginCli.cjs";
5
8
  import { targetBaseCandidateKey } from "../core/baseCandidates.cjs";
6
- import { CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, createBundleDiff } from "./createBundleDiff.cjs";
7
9
  import { EngineSqlOptions, generateEngineSql, settingsStatements } from "./engineSql.cjs";
8
10
  import { HOT_UPDATER_SERVER_VERSION } from "../version.cjs";
9
11
  //#region src/db/index.d.ts
10
12
  type HotUpdaterDBTarget = {
11
13
  readonly adapterName: string;
12
14
  };
15
+ /** A server's plugins as configured, whose commands the CLI adds. */
16
+ declare const serverPluginsOf: (hotUpdater: HotUpdaterDBTarget) => readonly AnyHotUpdaterPlugin[];
13
17
  /** Whether `hot-updater db generate` writes schema files for a server's database. */
14
18
  declare const generatesSchema: (hotUpdater: HotUpdaterDBTarget) => boolean;
15
- /** The migrator for a server's database: its built-in tables and its plugins' tables. */
19
+ /** The migrator for a server's database: core's tables and its plugins' tables. */
16
20
  declare function createMigrator(hotUpdater: HotUpdaterDBTarget): Migrator;
17
21
  declare function generateSchema(hotUpdater: HotUpdaterDBTarget, ...args: Parameters<SchemaGenerator>): ReturnType<SchemaGenerator>;
18
22
  //#endregion
19
- export { type CoreApi, CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, type DatabaseTooling, type EngineSqlOptions, HOT_UPDATER_SERVER_VERSION, HotUpdaterDBTarget, HotUpdaterSchemaMigrationRequiredError, type MeasuredDatabase, type MeasuredDatabaseOptions, type Migrator, type SchemaGenerator, type ToolingDatabase, type ToolingTarget, createBundleDiff, createDatabaseCoreApi, createDatabasePluginApis, createMeasuredDatabase, createMigrator, generateEngineSql, generateSchema, generatesSchema, settingsStatements, targetBaseCandidateKey };
23
+ export { type ClientAuthSpec, type ClientCredentialSpec, type ClientPluginSpec, type CoreApi, type DatabaseTooling, type EngineSqlOptions, HOT_UPDATER_SERVER_VERSION, HotUpdaterDBTarget, HotUpdaterSchemaMigrationRequiredError, type MeasuredDatabase, type MeasuredDatabaseOptions, type Migrator, type PluginCommandEntry, type ProvisionedClientCredential, type SchemaGenerator, type ToolingDatabase, type ToolingTarget, clientAuthOf, clientPluginsOf, createDatabaseCoreApi, createDatabasePluginApis, createMeasuredDatabase, createMigrator, generateClientCredential, generateEngineSql, generateSchema, generatesSchema, pluginCommandsOf, provisionClientCredential, serverPluginsOf, settingsStatements, targetBaseCandidateKey };
@@ -1,19 +1,23 @@
1
1
  import { HotUpdaterSchemaMigrationRequiredError } from "../database/fence.mjs";
2
2
  import { DatabaseTooling, Migrator, SchemaGenerator, ToolingDatabase, ToolingTarget } from "./types.mjs";
3
+ import { AnyHotUpdaterPlugin } from "../plugins/definePlugin.mjs";
3
4
  import { CoreApi, createDatabaseCoreApi } from "../core/api.mjs";
4
5
  import { MeasuredDatabase, MeasuredDatabaseOptions, createDatabasePluginApis, createMeasuredDatabase } from "../assembly/databasePlugins.mjs";
6
+ import { ClientPluginSpec, clientPluginsOf } from "../assembly/clientPlugins.mjs";
7
+ import { ClientAuthSpec, ClientCredentialSpec, PluginCommandEntry, ProvisionedClientCredential, clientAuthOf, generateClientCredential, pluginCommandsOf, provisionClientCredential } from "../assembly/pluginCli.mjs";
5
8
  import { targetBaseCandidateKey } from "../core/baseCandidates.mjs";
6
- import { CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, createBundleDiff } from "./createBundleDiff.mjs";
7
9
  import { EngineSqlOptions, generateEngineSql, settingsStatements } from "./engineSql.mjs";
8
10
  import { HOT_UPDATER_SERVER_VERSION } from "../version.mjs";
9
11
  //#region src/db/index.d.ts
10
12
  type HotUpdaterDBTarget = {
11
13
  readonly adapterName: string;
12
14
  };
15
+ /** A server's plugins as configured, whose commands the CLI adds. */
16
+ declare const serverPluginsOf: (hotUpdater: HotUpdaterDBTarget) => readonly AnyHotUpdaterPlugin[];
13
17
  /** Whether `hot-updater db generate` writes schema files for a server's database. */
14
18
  declare const generatesSchema: (hotUpdater: HotUpdaterDBTarget) => boolean;
15
- /** The migrator for a server's database: its built-in tables and its plugins' tables. */
19
+ /** The migrator for a server's database: core's tables and its plugins' tables. */
16
20
  declare function createMigrator(hotUpdater: HotUpdaterDBTarget): Migrator;
17
21
  declare function generateSchema(hotUpdater: HotUpdaterDBTarget, ...args: Parameters<SchemaGenerator>): ReturnType<SchemaGenerator>;
18
22
  //#endregion
19
- export { type CoreApi, CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, type DatabaseTooling, type EngineSqlOptions, HOT_UPDATER_SERVER_VERSION, HotUpdaterDBTarget, HotUpdaterSchemaMigrationRequiredError, type MeasuredDatabase, type MeasuredDatabaseOptions, type Migrator, type SchemaGenerator, type ToolingDatabase, type ToolingTarget, createBundleDiff, createDatabaseCoreApi, createDatabasePluginApis, createMeasuredDatabase, createMigrator, generateEngineSql, generateSchema, generatesSchema, settingsStatements, targetBaseCandidateKey };
23
+ export { type ClientAuthSpec, type ClientCredentialSpec, type ClientPluginSpec, type CoreApi, type DatabaseTooling, type EngineSqlOptions, HOT_UPDATER_SERVER_VERSION, HotUpdaterDBTarget, HotUpdaterSchemaMigrationRequiredError, type MeasuredDatabase, type MeasuredDatabaseOptions, type Migrator, type PluginCommandEntry, type ProvisionedClientCredential, type SchemaGenerator, type ToolingDatabase, type ToolingTarget, clientAuthOf, clientPluginsOf, createDatabaseCoreApi, createDatabasePluginApis, createMeasuredDatabase, createMigrator, generateClientCredential, generateEngineSql, generateSchema, generatesSchema, pluginCommandsOf, provisionClientCredential, serverPluginsOf, settingsStatements, targetBaseCandidateKey };
package/dist/db/index.mjs CHANGED
@@ -2,19 +2,22 @@ import { targetBaseCandidateKey } from "../core/baseCandidates.mjs";
2
2
  import { createDatabaseCoreApi } from "../core/api.mjs";
3
3
  import { HotUpdaterSchemaMigrationRequiredError } from "../database/fence.mjs";
4
4
  import { generateEngineSql, settingsStatements } from "./engineSql.mjs";
5
+ import { clientPluginsOf } from "../assembly/clientPlugins.mjs";
5
6
  import { HOT_UPDATER_SERVER_VERSION } from "../version.mjs";
6
7
  import { getHotUpdaterCoreMetadata } from "../createHotUpdaterCore.mjs";
7
8
  import { createDatabasePluginApis, createMeasuredDatabase } from "../assembly/databasePlugins.mjs";
8
- import { createBundleDiff } from "./createBundleDiff.mjs";
9
+ import { clientAuthOf, generateClientCredential, pluginCommandsOf, provisionClientCredential } from "../assembly/pluginCli.mjs";
9
10
  //#region src/db/index.ts
10
11
  const getDBMetadata = (hotUpdater) => {
11
12
  const metadata = getHotUpdaterCoreMetadata(hotUpdater);
12
13
  if (!metadata) throw new Error("Database tooling requires a hotUpdater instance created by @hot-updater/server.");
13
14
  return metadata;
14
15
  };
16
+ /** A server's plugins as configured, whose commands the CLI adds. */
17
+ const serverPluginsOf = (hotUpdater) => getDBMetadata(hotUpdater).plugins;
15
18
  /** Whether `hot-updater db generate` writes schema files for a server's database. */
16
19
  const generatesSchema = (hotUpdater) => getDBMetadata(hotUpdater).database.generateSchema !== void 0;
17
- /** The migrator for a server's database: its built-in tables and its plugins' tables. */
20
+ /** The migrator for a server's database: core's tables and its plugins' tables. */
18
21
  function createMigrator(hotUpdater) {
19
22
  const { database, target } = getDBMetadata(hotUpdater);
20
23
  if (database.createMigrator === void 0) throw new Error(database.generateSchema === void 0 ? `The ${database.name} database has no migrator; its provider applies the schema.` : `The ${database.name} database applies its schema from migration files: run \`hot-updater db generate\`, then apply the file with the provider's tooling.`);
@@ -27,4 +30,4 @@ function generateSchema(hotUpdater, ...args) {
27
30
  return database.generateSchema(version, name, target);
28
31
  }
29
32
  //#endregion
30
- export { HOT_UPDATER_SERVER_VERSION, HotUpdaterSchemaMigrationRequiredError, createBundleDiff, createDatabaseCoreApi, createDatabasePluginApis, createMeasuredDatabase, createMigrator, generateEngineSql, generateSchema, generatesSchema, settingsStatements, targetBaseCandidateKey };
33
+ export { HOT_UPDATER_SERVER_VERSION, HotUpdaterSchemaMigrationRequiredError, clientAuthOf, clientPluginsOf, createDatabaseCoreApi, createDatabasePluginApis, createMeasuredDatabase, createMigrator, generateClientCredential, generateEngineSql, generateSchema, generatesSchema, pluginCommandsOf, provisionClientCredential, serverPluginsOf, settingsStatements, targetBaseCandidateKey };
@@ -52,7 +52,7 @@ interface Migrator {
52
52
  }
53
53
  /**
54
54
  * The tables `db migrate` and `db generate` create and the settings rows they
55
- * write: the built-in ones, and each third-party plugin's the server runs.
55
+ * write: core's, and those of each plugin the server runs.
56
56
  */
57
57
  interface ToolingTarget {
58
58
  readonly schema: ResolvedSchema;
@@ -64,8 +64,8 @@ type SchemaGenerator = (version: string | "latest", name?: string, target?: Tool
64
64
  };
65
65
  /**
66
66
  * What `hot-updater db generate` and `db migrate` run for a provider's
67
- * database, beside the database itself. Without a target they cover the
68
- * built-in tables.
67
+ * database, beside the database itself. Without a target they cover core's
68
+ * tables.
69
69
  */
70
70
  interface DatabaseTooling {
71
71
  readonly provider?: ORMProvider;
@@ -52,7 +52,7 @@ interface Migrator {
52
52
  }
53
53
  /**
54
54
  * The tables `db migrate` and `db generate` create and the settings rows they
55
- * write: the built-in ones, and each third-party plugin's the server runs.
55
+ * write: core's, and those of each plugin the server runs.
56
56
  */
57
57
  interface ToolingTarget {
58
58
  readonly schema: ResolvedSchema;
@@ -64,8 +64,8 @@ type SchemaGenerator = (version: string | "latest", name?: string, target?: Tool
64
64
  };
65
65
  /**
66
66
  * What `hot-updater db generate` and `db migrate` run for a provider's
67
- * database, beside the database itself. Without a target they cover the
68
- * built-in tables.
67
+ * database, beside the database itself. Without a target they cover core's
68
+ * tables.
69
69
  */
70
70
  interface DatabaseTooling {
71
71
  readonly provider?: ORMProvider;
package/dist/diff.cjs ADDED
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_createBundleDiff = require("./db/createBundleDiff.cjs");
3
+ exports.createBundleDiff = require_createBundleDiff.createBundleDiff;
@@ -0,0 +1,2 @@
1
+ import { CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, createBundleDiff } from "./db/createBundleDiff.cjs";
2
+ export { CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, createBundleDiff };
@@ -0,0 +1,2 @@
1
+ import { CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, createBundleDiff } from "./db/createBundleDiff.mjs";
2
+ export { CreateBundleDiffDependencies, CreateBundleDiffInput, CreateBundleDiffOptions, createBundleDiff };
package/dist/diff.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { createBundleDiff } from "./db/createBundleDiff.mjs";
2
+ export { createBundleDiff };