ultimabase 0.0.0-stage → 0.1.0

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 (411) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +4 -2
  3. package/dist/access.d.ts +62 -0
  4. package/dist/access.d.ts.map +1 -0
  5. package/dist/access.js +258 -0
  6. package/dist/adapter-errors.d.ts +43 -0
  7. package/dist/adapter-errors.d.ts.map +1 -0
  8. package/dist/adapter-errors.js +72 -0
  9. package/dist/adapter-json.d.ts +20 -0
  10. package/dist/adapter-json.d.ts.map +1 -0
  11. package/dist/adapter-json.js +2 -0
  12. package/dist/adapter-migrations.d.ts +90 -0
  13. package/dist/adapter-migrations.d.ts.map +1 -0
  14. package/dist/adapter-migrations.js +1 -0
  15. package/dist/adapter.d.ts +333 -0
  16. package/dist/adapter.d.ts.map +1 -0
  17. package/dist/adapter.js +5 -0
  18. package/dist/aggregate.d.ts +31 -0
  19. package/dist/aggregate.d.ts.map +1 -0
  20. package/dist/aggregate.js +99 -0
  21. package/dist/app-internals.d.ts +10 -0
  22. package/dist/app-internals.d.ts.map +1 -0
  23. package/dist/app-internals.js +12 -0
  24. package/dist/app-options.d.ts +22 -0
  25. package/dist/app-options.d.ts.map +1 -0
  26. package/dist/app-options.js +3 -0
  27. package/dist/cascade.d.ts +47 -0
  28. package/dist/cascade.d.ts.map +1 -0
  29. package/dist/cascade.js +209 -0
  30. package/dist/cli-config.d.ts +6 -0
  31. package/dist/cli-config.d.ts.map +1 -0
  32. package/dist/cli-config.js +45 -0
  33. package/dist/cli-deploy.d.ts +14 -0
  34. package/dist/cli-deploy.d.ts.map +1 -0
  35. package/dist/cli-deploy.js +193 -0
  36. package/dist/cli-main.d.ts +16 -0
  37. package/dist/cli-main.d.ts.map +1 -0
  38. package/dist/cli-main.js +151 -0
  39. package/dist/cli-migrate.d.ts +20 -0
  40. package/dist/cli-migrate.d.ts.map +1 -0
  41. package/dist/cli-migrate.js +105 -0
  42. package/dist/cli.d.ts +3 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +4 -0
  45. package/dist/complete.d.ts +13 -0
  46. package/dist/complete.d.ts.map +1 -0
  47. package/dist/complete.js +60 -0
  48. package/dist/console-logger.d.ts +3 -0
  49. package/dist/console-logger.d.ts.map +1 -0
  50. package/dist/console-logger.js +62 -0
  51. package/dist/create-many.d.ts +7 -0
  52. package/dist/create-many.d.ts.map +1 -0
  53. package/dist/create-many.js +88 -0
  54. package/dist/decimal.d.ts +23 -0
  55. package/dist/decimal.d.ts.map +1 -0
  56. package/dist/decimal.js +50 -0
  57. package/dist/define-app.d.ts +59 -0
  58. package/dist/define-app.d.ts.map +1 -0
  59. package/dist/define-app.js +5 -0
  60. package/dist/define-enum.d.ts +6 -0
  61. package/dist/define-enum.d.ts.map +1 -0
  62. package/dist/define-enum.js +18 -0
  63. package/dist/define-function.d.ts +25 -0
  64. package/dist/define-function.d.ts.map +1 -0
  65. package/dist/define-function.js +111 -0
  66. package/dist/define-model.d.ts +48 -0
  67. package/dist/define-model.d.ts.map +1 -0
  68. package/dist/define-model.js +85 -0
  69. package/dist/definition.d.ts +179 -0
  70. package/dist/definition.d.ts.map +1 -0
  71. package/dist/definition.js +165 -0
  72. package/dist/delete-many.d.ts +13 -0
  73. package/dist/delete-many.d.ts.map +1 -0
  74. package/dist/delete-many.js +58 -0
  75. package/dist/engine.d.ts +16 -0
  76. package/dist/engine.d.ts.map +1 -0
  77. package/dist/engine.js +174 -0
  78. package/dist/errors.d.ts +50 -0
  79. package/dist/errors.d.ts.map +1 -0
  80. package/dist/errors.js +43 -0
  81. package/dist/exact.d.ts +20 -0
  82. package/dist/exact.d.ts.map +1 -0
  83. package/dist/exact.js +1 -0
  84. package/dist/feed.d.ts +6 -0
  85. package/dist/feed.d.ts.map +1 -0
  86. package/dist/feed.js +33 -0
  87. package/dist/field-codec.d.ts +11 -0
  88. package/dist/field-codec.d.ts.map +1 -0
  89. package/dist/field-codec.js +48 -0
  90. package/dist/field-rules.d.ts +57 -0
  91. package/dist/field-rules.d.ts.map +1 -0
  92. package/dist/field-rules.js +1 -0
  93. package/dist/field-type.d.ts +51 -0
  94. package/dist/field-type.d.ts.map +1 -0
  95. package/dist/field-type.js +106 -0
  96. package/dist/fields.d.ts +295 -0
  97. package/dist/fields.d.ts.map +1 -0
  98. package/dist/fields.js +1 -0
  99. package/dist/function.d.ts +126 -0
  100. package/dist/function.d.ts.map +1 -0
  101. package/dist/function.js +1 -0
  102. package/dist/functions.d.ts +18 -0
  103. package/dist/functions.d.ts.map +1 -0
  104. package/dist/functions.js +99 -0
  105. package/dist/group-by.d.ts +10 -0
  106. package/dist/group-by.d.ts.map +1 -0
  107. package/dist/group-by.js +145 -0
  108. package/dist/group-having.d.ts +8 -0
  109. package/dist/group-having.d.ts.map +1 -0
  110. package/dist/group-having.js +97 -0
  111. package/dist/hooks.d.ts +41 -0
  112. package/dist/hooks.d.ts.map +1 -0
  113. package/dist/hooks.js +149 -0
  114. package/dist/hosts.d.ts +3 -0
  115. package/dist/hosts.d.ts.map +1 -0
  116. package/dist/hosts.js +8 -0
  117. package/dist/identify.d.ts +15 -0
  118. package/dist/identify.d.ts.map +1 -0
  119. package/dist/identify.js +71 -0
  120. package/dist/index.d.ts +25 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +12 -0
  123. package/dist/internal.d.ts +28 -0
  124. package/dist/internal.d.ts.map +1 -0
  125. package/dist/internal.js +39 -0
  126. package/dist/lifecycle.d.ts +21 -0
  127. package/dist/lifecycle.d.ts.map +1 -0
  128. package/dist/lifecycle.js +149 -0
  129. package/dist/list-update.d.ts +12 -0
  130. package/dist/list-update.d.ts.map +1 -0
  131. package/dist/list-update.js +52 -0
  132. package/dist/live.d.ts +37 -0
  133. package/dist/live.d.ts.map +1 -0
  134. package/dist/live.js +139 -0
  135. package/dist/manifest.d.ts +11 -0
  136. package/dist/manifest.d.ts.map +1 -0
  137. package/dist/manifest.js +60 -0
  138. package/dist/memory-aggregate.d.ts +7 -0
  139. package/dist/memory-aggregate.d.ts.map +1 -0
  140. package/dist/memory-aggregate.js +107 -0
  141. package/dist/memory-conditions.d.ts +8 -0
  142. package/dist/memory-conditions.d.ts.map +1 -0
  143. package/dist/memory-conditions.js +82 -0
  144. package/dist/memory-draft.d.ts +34 -0
  145. package/dist/memory-draft.d.ts.map +1 -0
  146. package/dist/memory-draft.js +255 -0
  147. package/dist/memory-json.d.ts +6 -0
  148. package/dist/memory-json.d.ts.map +1 -0
  149. package/dist/memory-json.js +86 -0
  150. package/dist/memory-read.d.ts +45 -0
  151. package/dist/memory-read.d.ts.map +1 -0
  152. package/dist/memory-read.js +244 -0
  153. package/dist/memory-search.d.ts +16 -0
  154. package/dist/memory-search.d.ts.map +1 -0
  155. package/dist/memory-search.js +110 -0
  156. package/dist/memory-values.d.ts +23 -0
  157. package/dist/memory-values.d.ts.map +1 -0
  158. package/dist/memory-values.js +82 -0
  159. package/dist/memory.d.ts +4 -0
  160. package/dist/memory.d.ts.map +1 -0
  161. package/dist/memory.js +157 -0
  162. package/dist/migrate.d.ts +22 -0
  163. package/dist/migrate.d.ts.map +1 -0
  164. package/dist/migrate.js +131 -0
  165. package/dist/model.d.ts +239 -0
  166. package/dist/model.d.ts.map +1 -0
  167. package/dist/model.js +1 -0
  168. package/dist/nested-write.d.ts +64 -0
  169. package/dist/nested-write.d.ts.map +1 -0
  170. package/dist/nested-write.js +274 -0
  171. package/dist/number-update.d.ts +18 -0
  172. package/dist/number-update.d.ts.map +1 -0
  173. package/dist/number-update.js +96 -0
  174. package/dist/plugin-app.d.ts +48 -0
  175. package/dist/plugin-app.d.ts.map +1 -0
  176. package/dist/plugin-app.js +230 -0
  177. package/dist/plugin-code.d.ts +17 -0
  178. package/dist/plugin-code.d.ts.map +1 -0
  179. package/dist/plugin-code.js +125 -0
  180. package/dist/plugin-use.d.ts +22 -0
  181. package/dist/plugin-use.d.ts.map +1 -0
  182. package/dist/plugin-use.js +161 -0
  183. package/dist/plugin.d.ts +357 -0
  184. package/dist/plugin.d.ts.map +1 -0
  185. package/dist/plugin.js +17 -0
  186. package/dist/query-aggregate.d.ts +82 -0
  187. package/dist/query-aggregate.d.ts.map +1 -0
  188. package/dist/query-aggregate.js +1 -0
  189. package/dist/query-args.d.ts +41 -0
  190. package/dist/query-args.d.ts.map +1 -0
  191. package/dist/query-args.js +263 -0
  192. package/dist/query-bulk.d.ts +35 -0
  193. package/dist/query-bulk.d.ts.map +1 -0
  194. package/dist/query-bulk.js +1 -0
  195. package/dist/query-conditions.d.ts +9 -0
  196. package/dist/query-conditions.d.ts.map +1 -0
  197. package/dist/query-conditions.js +46 -0
  198. package/dist/query-context.d.ts +32 -0
  199. package/dist/query-context.d.ts.map +1 -0
  200. package/dist/query-context.js +55 -0
  201. package/dist/query-filter.d.ts +46 -0
  202. package/dist/query-filter.d.ts.map +1 -0
  203. package/dist/query-filter.js +1 -0
  204. package/dist/query-group.d.ts +82 -0
  205. package/dist/query-group.d.ts.map +1 -0
  206. package/dist/query-group.js +1 -0
  207. package/dist/query-json.d.ts +9 -0
  208. package/dist/query-json.d.ts.map +1 -0
  209. package/dist/query-json.js +66 -0
  210. package/dist/query-order.d.ts +15 -0
  211. package/dist/query-order.d.ts.map +1 -0
  212. package/dist/query-order.js +115 -0
  213. package/dist/query-project.d.ts +15 -0
  214. package/dist/query-project.d.ts.map +1 -0
  215. package/dist/query-project.js +45 -0
  216. package/dist/query-search.d.ts +24 -0
  217. package/dist/query-search.d.ts.map +1 -0
  218. package/dist/query-search.js +2 -0
  219. package/dist/query-values.d.ts +28 -0
  220. package/dist/query-values.d.ts.map +1 -0
  221. package/dist/query-values.js +91 -0
  222. package/dist/query-where.d.ts +46 -0
  223. package/dist/query-where.d.ts.map +1 -0
  224. package/dist/query-where.js +200 -0
  225. package/dist/query-write.d.ts +14 -0
  226. package/dist/query-write.d.ts.map +1 -0
  227. package/dist/query-write.js +260 -0
  228. package/dist/query.d.ts +254 -0
  229. package/dist/query.d.ts.map +1 -0
  230. package/dist/query.js +1 -0
  231. package/dist/record.d.ts +257 -0
  232. package/dist/record.d.ts.map +1 -0
  233. package/dist/record.js +1 -0
  234. package/dist/recorder.d.ts +32 -0
  235. package/dist/recorder.d.ts.map +1 -0
  236. package/dist/recorder.js +152 -0
  237. package/dist/relation-write.d.ts +41 -0
  238. package/dist/relation-write.d.ts.map +1 -0
  239. package/dist/relation-write.js +112 -0
  240. package/dist/relations.d.ts +42 -0
  241. package/dist/relations.d.ts.map +1 -0
  242. package/dist/relations.js +119 -0
  243. package/dist/rules.d.ts +97 -0
  244. package/dist/rules.d.ts.map +1 -0
  245. package/dist/rules.js +71 -0
  246. package/dist/running.d.ts +29 -0
  247. package/dist/running.d.ts.map +1 -0
  248. package/dist/running.js +39 -0
  249. package/dist/schema-indexes.d.ts +11 -0
  250. package/dist/schema-indexes.d.ts.map +1 -0
  251. package/dist/schema-indexes.js +59 -0
  252. package/dist/schema-virtuals.d.ts +19 -0
  253. package/dist/schema-virtuals.d.ts.map +1 -0
  254. package/dist/schema-virtuals.js +100 -0
  255. package/dist/schema.d.ts +35 -0
  256. package/dist/schema.d.ts.map +1 -0
  257. package/dist/schema.js +267 -0
  258. package/dist/scope.d.ts +46 -0
  259. package/dist/scope.d.ts.map +1 -0
  260. package/dist/scope.js +82 -0
  261. package/dist/scratch.d.ts +14 -0
  262. package/dist/scratch.d.ts.map +1 -0
  263. package/dist/scratch.js +10 -0
  264. package/dist/serve.d.ts +2 -0
  265. package/dist/serve.d.ts.map +1 -0
  266. package/dist/serve.js +4 -0
  267. package/dist/symbols.d.ts +10 -0
  268. package/dist/symbols.d.ts.map +1 -0
  269. package/dist/symbols.js +1 -0
  270. package/dist/transaction.d.ts +28 -0
  271. package/dist/transaction.d.ts.map +1 -0
  272. package/dist/transaction.js +156 -0
  273. package/dist/types.d.ts +58 -0
  274. package/dist/types.d.ts.map +1 -0
  275. package/dist/types.js +1 -0
  276. package/dist/update-many.d.ts +7 -0
  277. package/dist/update-many.d.ts.map +1 -0
  278. package/dist/update-many.js +182 -0
  279. package/dist/uuid.d.ts +7 -0
  280. package/dist/uuid.d.ts.map +1 -0
  281. package/dist/uuid.js +48 -0
  282. package/dist/validation.d.ts +24 -0
  283. package/dist/validation.d.ts.map +1 -0
  284. package/dist/validation.js +72 -0
  285. package/dist/virtual-read.d.ts +9 -0
  286. package/dist/virtual-read.d.ts.map +1 -0
  287. package/dist/virtual-read.js +145 -0
  288. package/dist/virtual.d.ts +142 -0
  289. package/dist/virtual.d.ts.map +1 -0
  290. package/dist/virtual.js +1 -0
  291. package/dist/write-context.d.ts +46 -0
  292. package/dist/write-context.d.ts.map +1 -0
  293. package/dist/write-context.js +102 -0
  294. package/dist/write-data.d.ts +26 -0
  295. package/dist/write-data.d.ts.map +1 -0
  296. package/dist/write-data.js +144 -0
  297. package/dist/write-plan.d.ts +107 -0
  298. package/dist/write-plan.d.ts.map +1 -0
  299. package/dist/write-plan.js +170 -0
  300. package/dist/write-target.d.ts +17 -0
  301. package/dist/write-target.d.ts.map +1 -0
  302. package/dist/write-target.js +59 -0
  303. package/dist/writes.d.ts +23 -0
  304. package/dist/writes.d.ts.map +1 -0
  305. package/dist/writes.js +246 -0
  306. package/dist/writing.d.ts +10 -0
  307. package/dist/writing.d.ts.map +1 -0
  308. package/dist/writing.js +66 -0
  309. package/package.json +42 -3
  310. package/src/access.ts +329 -0
  311. package/src/adapter-errors.ts +89 -0
  312. package/src/adapter-json.ts +21 -0
  313. package/src/adapter-migrations.ts +98 -0
  314. package/src/adapter.ts +363 -0
  315. package/src/aggregate.ts +136 -0
  316. package/src/app-internals.ts +26 -0
  317. package/src/app-options.ts +24 -0
  318. package/src/cascade.ts +297 -0
  319. package/src/cli-config.ts +45 -0
  320. package/src/cli-deploy.ts +235 -0
  321. package/src/cli-main.ts +165 -0
  322. package/src/cli-migrate.ts +143 -0
  323. package/src/cli.ts +5 -0
  324. package/src/complete.ts +73 -0
  325. package/src/console-logger.ts +87 -0
  326. package/src/create-many.ts +126 -0
  327. package/src/decimal.ts +74 -0
  328. package/src/define-app.ts +108 -0
  329. package/src/define-enum.ts +26 -0
  330. package/src/define-function.ts +188 -0
  331. package/src/define-model.ts +220 -0
  332. package/src/definition.ts +352 -0
  333. package/src/delete-many.ts +76 -0
  334. package/src/engine.ts +281 -0
  335. package/src/errors.ts +97 -0
  336. package/src/exact.ts +49 -0
  337. package/src/feed.ts +39 -0
  338. package/src/field-codec.ts +72 -0
  339. package/src/field-rules.ts +77 -0
  340. package/src/field-type.ts +219 -0
  341. package/src/fields.ts +383 -0
  342. package/src/function.ts +143 -0
  343. package/src/functions.ts +154 -0
  344. package/src/group-by.ts +186 -0
  345. package/src/group-having.ts +143 -0
  346. package/src/hooks.ts +215 -0
  347. package/src/hosts.ts +11 -0
  348. package/src/identify.ts +95 -0
  349. package/src/index.ts +125 -0
  350. package/src/internal.ts +68 -0
  351. package/src/lifecycle.ts +214 -0
  352. package/src/list-update.ts +71 -0
  353. package/src/live.ts +199 -0
  354. package/src/manifest.ts +71 -0
  355. package/src/memory-aggregate.ts +162 -0
  356. package/src/memory-conditions.ts +88 -0
  357. package/src/memory-draft.ts +319 -0
  358. package/src/memory-json.ts +91 -0
  359. package/src/memory-read.ts +311 -0
  360. package/src/memory-search.ts +149 -0
  361. package/src/memory-values.ts +106 -0
  362. package/src/memory.ts +173 -0
  363. package/src/migrate.ts +152 -0
  364. package/src/model.ts +312 -0
  365. package/src/nested-write.ts +390 -0
  366. package/src/number-update.ts +142 -0
  367. package/src/plugin-app.ts +308 -0
  368. package/src/plugin-code.ts +158 -0
  369. package/src/plugin-use.ts +217 -0
  370. package/src/plugin.ts +400 -0
  371. package/src/query-aggregate.ts +96 -0
  372. package/src/query-args.ts +375 -0
  373. package/src/query-bulk.ts +53 -0
  374. package/src/query-conditions.ts +53 -0
  375. package/src/query-context.ts +104 -0
  376. package/src/query-filter.ts +54 -0
  377. package/src/query-group.ts +137 -0
  378. package/src/query-json.ts +90 -0
  379. package/src/query-order.ts +158 -0
  380. package/src/query-project.ts +73 -0
  381. package/src/query-search.ts +31 -0
  382. package/src/query-values.ts +131 -0
  383. package/src/query-where.ts +318 -0
  384. package/src/query-write.ts +360 -0
  385. package/src/query.ts +400 -0
  386. package/src/record.ts +379 -0
  387. package/src/recorder.ts +212 -0
  388. package/src/relation-write.ts +176 -0
  389. package/src/relations.ts +165 -0
  390. package/src/rules.ts +188 -0
  391. package/src/running.ts +62 -0
  392. package/src/schema-indexes.ts +88 -0
  393. package/src/schema-virtuals.ts +134 -0
  394. package/src/schema.ts +367 -0
  395. package/src/scope.ts +123 -0
  396. package/src/scratch.ts +28 -0
  397. package/src/serve.ts +5 -0
  398. package/src/symbols.ts +11 -0
  399. package/src/transaction.ts +211 -0
  400. package/src/types.ts +79 -0
  401. package/src/update-many.ts +268 -0
  402. package/src/uuid.ts +51 -0
  403. package/src/validation.ts +107 -0
  404. package/src/virtual-read.ts +198 -0
  405. package/src/virtual.ts +187 -0
  406. package/src/write-context.ts +170 -0
  407. package/src/write-data.ts +188 -0
  408. package/src/write-plan.ts +273 -0
  409. package/src/write-target.ts +92 -0
  410. package/src/writes.ts +361 -0
  411. package/src/writing.ts +93 -0
package/src/plugin.ts ADDED
@@ -0,0 +1,400 @@
1
+ // A plugin is an interface of types and one `definePlugin` (D-57). Its types
2
+ // travel with its values; nothing is declared globally (D-24).
3
+ import type { Logger } from './app-options.ts'
4
+ import type { Enum, FieldBuilders, StandardSchema } from './fields.ts'
5
+ import type { Client, FunctionShape } from './function.ts'
6
+ import type { Identify } from './identify.ts'
7
+ import { pluginEntries, pluginValues } from './definition.ts'
8
+ import { pluginCode } from './plugin-code.ts'
9
+ import type { FieldShape, ModelHooks, ModelShape } from './model.ts'
10
+ import type { Changed, Row, SchemaModel } from './adapter.ts'
11
+ import type { Queries, QueryOptions, UniqueWhere } from './query.ts'
12
+ import type {
13
+ Caller,
14
+ Identity,
15
+ Register,
16
+ UserCallerKeys,
17
+ UserOf,
18
+ } from './rules.ts'
19
+ import type { pluginTypes } from './symbols.ts'
20
+
21
+ /** The keys of a user caller a plugin gives (D-121). */
22
+ type CallerKeys = Partial<UserCallerKeys> & object
23
+
24
+ /**
25
+ * What a plugin adds to the models that use it (D-57). `this['fields']` is
26
+ * the fields of the model that lists the plugin in its `use`, and
27
+ * `this['options']` the options of its entry there.
28
+ */
29
+ export interface PluginTypes {
30
+ /** Its name, the key of its `.with` (D-24). */
31
+ readonly name: string
32
+ readonly fields: unknown
33
+ /** The value of the field whose `.with` holds its field rule. */
34
+ readonly value: unknown
35
+ /** Its entry's options, `softDelete({ ... })` (D-07). */
36
+ readonly options?: object
37
+ /** Its application value's options, `softDeletePlugin({ ... })` (D-24). */
38
+ readonly appOptions?: object
39
+ /** The plugins it needs, by their types (D-16). */
40
+ readonly requires?: PluginTypes
41
+ /** The plugins it uses when installed (D-16). */
42
+ readonly optional?: PluginTypes
43
+ /** What it offers other plugins (D-16). */
44
+ readonly api?: object
45
+ /** The fields it adds to the models that use it (D-07, D-15, D-89). */
46
+ readonly addedFields?: { readonly [field: string]: FieldShape }
47
+ /** Its commands (D-15). */
48
+ readonly commands?: object
49
+ /** Its key of the model's `.with` (D-42); `false` turns it off (D-107). */
50
+ readonly with?: object | false
51
+ /** Its key of a field's `.with`, read with `this['value']` (D-12). */
52
+ readonly fieldWith?: object
53
+ /** Its key of a function's `.with`; `false` stops exposing it (D-27). */
54
+ readonly functionWith?: object | false
55
+ /** Only a query may list it in its `use` (D-154). */
56
+ readonly queryOnly?: true
57
+ }
58
+
59
+ /** A plugin's types for one model's fields. */
60
+ export type ForModel<T, F> = T & { readonly fields: F }
61
+ /** What a plugin's own code sees of a model: the fields it adds. Other
62
+ * fields are the model's, unknown to the plugin (D-57). */
63
+ type Own<T> = T extends { readonly addedFields: infer A }
64
+ ? A
65
+ : // oxlint-disable-next-line typescript/no-generated-empty-object-type -- no fields, not any value
66
+ Record<never, never>
67
+ type EntryOptions<T> = T extends { readonly options: infer O extends object }
68
+ ? O
69
+ : { readonly [option: string]: never }
70
+ type AppOptions<T> = T extends { readonly appOptions: infer O } ? O : never
71
+ type Requires<T> = T extends { readonly requires: infer R extends PluginTypes }
72
+ ? R['name']
73
+ : never
74
+ type Optional<T> = T extends { readonly optional: infer R extends PluginTypes }
75
+ ? R['name']
76
+ : never
77
+ type ApiOf<X> = X extends { readonly api: infer A } ? A : undefined
78
+ type Apis<T> = (T extends { readonly requires: infer R extends PluginTypes }
79
+ ? { readonly [X in R as X['name']]: ApiOf<X> }
80
+ : unknown) &
81
+ (T extends { readonly optional: infer R extends PluginTypes }
82
+ ? { readonly [X in R as X['name']]: ApiOf<X> | undefined }
83
+ : unknown)
84
+
85
+ type Args = { readonly [key: string]: unknown }
86
+ /** A model's queries as a transport calls them, with its client's arguments. */
87
+ export interface ModelQueries {
88
+ findUnique(args: Args, options: QueryOptions): Promise<Row | null>
89
+ findMany(args: Args, options: QueryOptions): Promise<readonly Row[]>
90
+ count(args: Args, options: QueryOptions): Promise<number>
91
+ create(args: Args, options: QueryOptions): Promise<Row>
92
+ update(args: Args, options: QueryOptions): Promise<Row>
93
+ delete(args: Args, options: QueryOptions): Promise<Row>
94
+ }
95
+
96
+ /** A model as transports and tools read it (D-16, D-107). */
97
+ export interface ExposedModel<W = unknown> {
98
+ /** As the adapter receives it (D-73). */
99
+ readonly schema: SchemaModel
100
+ /** The model's `description` and its fields' (D-150). */
101
+ readonly description: string | undefined
102
+ readonly descriptions: { readonly [field: string]: string }
103
+ /** Each field whose values are a `defineEnum` (D-150). */
104
+ readonly enums: { readonly [field: string]: Enum }
105
+ /** `id`, unique fields and unique indexes (D-52). */
106
+ readonly uniques: readonly (readonly string[])[]
107
+ /** Each field with a read rule, `private` when only Master reads it (D-44). */
108
+ readonly readRules: { readonly [field: string]: 'private' | 'rule' }
109
+ /** The fields `create` needs: neither optional nor with a default (D-53). */
110
+ readonly required: readonly string[]
111
+ /** Each `json` field's `validate`, when it is a Standard Schema (D-125). */
112
+ readonly validators: { readonly [field: string]: StandardSchema }
113
+ /** Each plugin field type's field, which a client reads as `toJSON` gives (D-122). */
114
+ readonly fieldTypes: {
115
+ readonly [field: string]: {
116
+ readonly plugin: string
117
+ /** The field type's own options the field took (D-152). */
118
+ readonly options: { readonly [key: string]: unknown }
119
+ readonly toJSON: (value: unknown) => unknown
120
+ /** What `toJSON` gives, if the field type says (D-152). */
121
+ readonly shape: StandardSchema | undefined
122
+ }
123
+ }
124
+ /** Its virtual fields, in their order (D-151). */
125
+ readonly virtuals: readonly ExposedVirtual[]
126
+ /** The plugin's key of the model's `.with`, if it was given. */
127
+ readonly with: W | undefined
128
+ /** Whether the model's `use` lists the plugin's entry. */
129
+ readonly used: boolean
130
+ readonly queries: ModelQueries
131
+ /** `upsert`, which also says whether it created the row (D-142). */
132
+ readonly upsert: (
133
+ args: Args,
134
+ options: QueryOptions,
135
+ ) => Promise<{ readonly row: Row; readonly created: boolean }>
136
+ /** The `defineModel` value, which a plugin's function may return (D-113). */
137
+ readonly model: ModelShape
138
+ }
139
+
140
+ /** A virtual field as transports read it (D-151). */
141
+ export interface ExposedVirtual {
142
+ readonly name: string
143
+ readonly description: string | undefined
144
+ /** A Standard Schema of an object: the field's arguments. */
145
+ readonly input: StandardSchema | undefined
146
+ readonly output: ExposedOutput
147
+ /** In the row without `select`: a value without input. */
148
+ readonly default: boolean
149
+ }
150
+
151
+ /** How an output holds a model or a type (D-109). */
152
+ export type OutputForm = 'one' | 'nullable' | 'list'
153
+
154
+ /** A function's or a type's output, as transports read it (D-109). */
155
+ export type ExposedOutput =
156
+ | { readonly kind: 'schema'; readonly schema: StandardSchema }
157
+ | { readonly kind: 'model'; readonly name: string; readonly form: OutputForm }
158
+ | {
159
+ readonly kind: 'type'
160
+ readonly type: ExposedType
161
+ readonly form: OutputForm
162
+ }
163
+
164
+ /** A `defineType`, its fields in their order (D-109). */
165
+ export interface ExposedType {
166
+ readonly name: string
167
+ readonly description: string | undefined
168
+ readonly fields: ReadonlyMap<string, ExposedOutput>
169
+ }
170
+
171
+ /** A function as transports read it (D-109). */
172
+ export interface ExposedFunction<W = unknown> {
173
+ readonly name: string
174
+ readonly description: string | undefined
175
+ /** The plugin that gives it, `undefined` for the application's (D-113). */
176
+ readonly plugin: string | undefined
177
+ /** A query, which a transport may serve over GET; a mutation otherwise. */
178
+ readonly query: boolean
179
+ /** Whether the function's `use` lists the plugin (D-154). */
180
+ readonly used: boolean
181
+ readonly input: StandardSchema | undefined
182
+ /** `undefined` when it returns nothing. */
183
+ readonly output: ExposedOutput | undefined
184
+ /** The plugin's key of the function's `.with`, if it was given. */
185
+ readonly with: W | undefined
186
+ /** Checks access, validates the input, then runs it for `client` (D-75, D-113). */
187
+ run(input: unknown, options: QueryOptions, client?: Client): Promise<unknown>
188
+ }
189
+
190
+ type WithOf<T> = T extends { readonly with: infer W } ? W : never
191
+ type FunctionWithOf<T> = T extends { readonly functionWith: infer W }
192
+ ? W
193
+ : never
194
+
195
+ /** What the plugin's start and api receive: its application options. */
196
+ export interface PluginContext<T> {
197
+ readonly options: [AppOptions<T>] extends [never]
198
+ ? { readonly [option: string]: never }
199
+ : AppOptions<T>
200
+ readonly plugins: Apis<T>
201
+ readonly logger: Logger
202
+ /** Who sends a request: what a transport runs it as (D-106). */
203
+ readonly identify: Identify
204
+ /**
205
+ * The caller being built stops holding at `at`, as a session that
206
+ * expires: a live read builds it again then (D-154). Outside a caller's
207
+ * construction, it does nothing.
208
+ */
209
+ readonly expires: (at: Date) => void
210
+ /** The application's models, in their order (D-107). */
211
+ readonly models: readonly ExposedModel<WithOf<T>>[]
212
+ /** The application's functions, in their order (D-109). */
213
+ readonly functions: readonly ExposedFunction<FunctionWithOf<T>>[]
214
+ }
215
+
216
+ /** A plugin's entry in a model's `use`, named after the plugin. */
217
+ export interface ModelUse<P extends string, T> {
218
+ readonly plugin: P
219
+ readonly [pluginTypes]: T
220
+ }
221
+
222
+ /** A plugin's value in the application's `plugins`. */
223
+ export interface PluginValue<P extends string, R extends string = never> {
224
+ readonly name: P
225
+ readonly requires?: readonly R[]
226
+ }
227
+
228
+ type HookFacts<F, K extends keyof ModelHooks<F>> = Parameters<
229
+ NonNullable<ModelHooks<F>[K]>
230
+ >[0]
231
+ /**
232
+ * The hooks a plugin runs on every model that uses it (D-15). `command` names
233
+ * the plugin's command the operation was called through, on that model only
234
+ * (D-71).
235
+ */
236
+ export type PluginHooks<F, O, A, C> = {
237
+ readonly [K in keyof ModelHooks<unknown>]?: (
238
+ facts: HookFacts<F, K> &
239
+ PluginModel<F, O, A> & { readonly command: C | undefined },
240
+ ) => ReturnType<NonNullable<ModelHooks<F>[K]>>
241
+ }
242
+ /** `redirect` replaces an operation with another (D-15). */
243
+ export type PluginRedirects<F, O, A> = {
244
+ readonly delete?: (
245
+ facts: {
246
+ readonly caller: Caller
247
+ readonly where: UniqueWhere<F>
248
+ } & PluginModel<F, O, A>,
249
+ ) => Promise<unknown>
250
+ }
251
+
252
+ /** What a model gives a plugin's code. */
253
+ export interface PluginModel<F, O, A> {
254
+ /** The model's name (D-152). */
255
+ readonly name: string
256
+ readonly queries: Queries<F>
257
+ readonly options: O
258
+ readonly plugins: A
259
+ }
260
+
261
+ type CodePart<T, K extends 'commands' | 'addedFields', Out> = T extends {
262
+ readonly [P in K]: object
263
+ }
264
+ ? { readonly [P in K]: Out }
265
+ : { readonly [P in K]?: never }
266
+
267
+ // A plugin without an API may still use the step that builds them, before
268
+ // any start, to call another plugin's API (D-107).
269
+ type ApiPart<T> = T extends { readonly api: object }
270
+ ? { readonly api: (context: PluginContext<T>) => T['api'] }
271
+ : { readonly api?: (context: PluginContext<T>) => void }
272
+
273
+ /** A plugin's package, usually its imported `package.json` (D-57). */
274
+ export interface Manifest {
275
+ readonly name: string
276
+ readonly version: string
277
+ /** The ranges of `ultimabase` and of the plugins it needs. */
278
+ readonly peerDependencies?: { readonly [name: string]: string }
279
+ }
280
+
281
+ type PluginFn<N extends string> = (...args: never[]) => PluginValue<N, string>
282
+ // Each needed plugin's application value under its name (D-16): a missing,
283
+ // an extra or a swapped one is refused.
284
+ type Needs<K extends 'requires' | 'optional', N extends string> = [N] extends [
285
+ never,
286
+ ]
287
+ ? { readonly [P in K]?: never }
288
+ : { readonly [P in K]: { readonly [X in N]: PluginFn<X> } }
289
+
290
+ /** What a plugin's author writes (D-57). */
291
+ export type PluginDefinition<T extends PluginTypes> = {
292
+ readonly name: T['name']
293
+ readonly manifest: Manifest
294
+ /** The hooks it runs on each model that uses it. */
295
+ readonly hooks?: PluginHooks<
296
+ Own<T>,
297
+ EntryOptions<T>,
298
+ Apis<T>,
299
+ keyof ForModel<T, Own<T>>['commands'] & string
300
+ >
301
+ readonly redirect?: PluginRedirects<Own<T>, EntryOptions<T>, Apis<T>>
302
+ /** Runs once when the application starts (D-15). */
303
+ readonly start?: (context: PluginContext<T>) => void | Promise<void>
304
+ /** Runs once when the application stops: close, flush (D-15). */
305
+ readonly stop?: (context: PluginContext<T>) => void | Promise<void>
306
+ /**
307
+ * Who sends a request, or `undefined` when it is not the plugin's; the
308
+ * first plugin to know it wins, after the master key (D-112).
309
+ */
310
+ readonly identify?: (
311
+ request: Request,
312
+ context: PluginContext<T>,
313
+ ) => Promise<Identity | undefined>
314
+ /**
315
+ * The plugin's keys of a user caller, given once per caller the kernel
316
+ * receives, each plugin's in the order of `plugins` (D-121).
317
+ */
318
+ readonly caller?: (
319
+ identity: { readonly kind: 'user'; readonly user: UserOf<Register> },
320
+ context: PluginContext<T>,
321
+ ) => CallerKeys | Promise<CallerKeys>
322
+ /**
323
+ * What each commit changed, on any server: the adapter sends it only when
324
+ * a plugin takes it (D-154).
325
+ */
326
+ readonly changed?: (
327
+ changes: readonly Changed[],
328
+ context: PluginContext<T>,
329
+ ) => void
330
+ /** Changes may have been lost: what `changed` follows is unknown. */
331
+ readonly missed?: (context: PluginContext<T>) => void
332
+ /** Its own models, which no plugin is given (D-110). */
333
+ readonly models?: readonly ModelShape[]
334
+ /** The indexes it adds to each model that uses it (D-52, D-122). */
335
+ readonly addedIndexes?: readonly {
336
+ readonly fields: readonly (keyof Own<T> & string)[]
337
+ readonly unique?: boolean
338
+ /** A trigram index, for `contains` and `mode: 'insensitive'` (D-141). */
339
+ readonly contains?: true
340
+ }[]
341
+ /**
342
+ * Its `defineFunction` values, built once when the application starts and
343
+ * exposed as the application's are (D-113).
344
+ */
345
+ readonly functions?: (
346
+ context: Omit<PluginContext<T>, 'functions'>,
347
+ ) => readonly FunctionShape[]
348
+ } & CodePart<
349
+ T,
350
+ 'commands',
351
+ (
352
+ model: PluginModel<Own<T>, EntryOptions<T>, Apis<T>>,
353
+ ) => ForModel<T, Own<T>>['commands']
354
+ > &
355
+ ApiPart<T> &
356
+ CodePart<
357
+ T,
358
+ 'addedFields',
359
+ (fields: FieldBuilders<never>, options: EntryOptions<T>) => Own<T>
360
+ > &
361
+ Needs<'requires', Requires<T>> &
362
+ Needs<'optional', Optional<T>>
363
+
364
+ /** A plugin's two values (D-24). */
365
+ export interface Plugin<T extends PluginTypes> {
366
+ readonly plugin: (
367
+ options?: AppOptions<T>,
368
+ ) => PluginValue<T['name'], Requires<T>>
369
+ readonly use: PluginEntry<T>
370
+ }
371
+ /** Without options, the entry is the plugin's own types; with them, its
372
+ * types read the options' literal values. */
373
+ export interface PluginEntry<T extends PluginTypes> {
374
+ (): ModelUse<T['name'], T>
375
+ <const O extends EntryOptions<T>>(
376
+ options: O,
377
+ ): ModelUse<T['name'], T & { readonly options: O }>
378
+ }
379
+ /** The type of a plugin's entry function, for its export. */
380
+ export type UseOf<T extends PluginTypes> = Plugin<T>['use']
381
+ /** The type of a plugin's application value function, for its export. */
382
+ export type PluginOf<T extends PluginTypes> = Plugin<T>['plugin']
383
+
384
+ export function definePlugin<T extends PluginTypes>(
385
+ definition: PluginDefinition<T>,
386
+ ): Plugin<T> {
387
+ const code = pluginCode(definition)
388
+ const plugin = (options?: object): PluginValue<string, string> => {
389
+ const value = Object.freeze({ name: code.name, requires: code.requires })
390
+ pluginValues.set(value, { code, options: options ?? {} })
391
+ return value
392
+ }
393
+ const use = (options?: object): object => {
394
+ const entry = Object.freeze({ plugin: code.name, options })
395
+ pluginEntries.set(entry, { code, options: options ?? {} })
396
+ return entry
397
+ }
398
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- the two functions are Plugin<T>'s; their types follow T.
399
+ return { plugin, use } as unknown as Plugin<T>
400
+ }
@@ -0,0 +1,96 @@
1
+ // `aggregate`'s arguments and result (D-143): the result has the keys the
2
+ // arguments ask for, each field typed.
3
+ import type { SortedKeys, Where } from './query.ts'
4
+ import type { StoredValue, SystemFields } from './record.ts'
5
+ import type { calendarDay, fieldType } from './symbols.ts'
6
+
7
+ /** A model's scalars that an aggregate takes: no list, json or plugin field. */
8
+ export type Aggregated<F> = SortedKeys<F> | keyof SystemFields
9
+ export type ValueOf<F, K> = K extends keyof SystemFields
10
+ ? SystemFields[K]
11
+ : K extends keyof F
12
+ ? NonNullable<StoredValue<F[K]>>
13
+ : never
14
+ /** The fields whose values are `V`. */
15
+ export type KeysWith<F, V> = {
16
+ [K in Aggregated<F>]: ValueOf<F, K> extends V ? K : never
17
+ }[Aggregated<F>]
18
+ /** Whether `X` is a decimal field (D-145), filtered and summed as a string. */
19
+ export type IsDecimal<X> = X extends {
20
+ readonly [fieldType]: { readonly options: { readonly precision: number } }
21
+ }
22
+ ? true
23
+ : false
24
+ /** Whether `X` is a string compared in order: a decimal or a day (D-150). */
25
+ export type IsOrdered<X> =
26
+ IsDecimal<X> extends true
27
+ ? true
28
+ : X extends {
29
+ readonly [fieldType]: {
30
+ readonly options: { readonly [calendarDay]: true }
31
+ }
32
+ }
33
+ ? true
34
+ : false
35
+ export type DecimalKeys<F> = {
36
+ [K in Aggregated<F>]: K extends keyof F
37
+ ? IsDecimal<F[K]> extends true
38
+ ? K
39
+ : never
40
+ : never
41
+ }[Aggregated<F>]
42
+ export type Summed<F> = KeysWith<F, number> | DecimalKeys<F>
43
+ type Fields<K extends PropertyKey> = { readonly [P in K]?: true | undefined }
44
+
45
+ export type AggregateArgs<F> = {
46
+ readonly where?: Where<F> | undefined
47
+ readonly _count?:
48
+ | true
49
+ | ({ readonly _all?: true | undefined } & Fields<Aggregated<F>>)
50
+ | undefined
51
+ readonly _sum?: Fields<Summed<F>> | undefined
52
+ readonly _avg?: Fields<Summed<F>> | undefined
53
+ readonly _min?: Fields<KeysWith<F, number | string | Date>> | undefined
54
+ readonly _max?: Fields<KeysWith<F, number | string | Date>> | undefined
55
+ }
56
+
57
+ type Asked<S> = {
58
+ [K in keyof S]: S[K] extends true ? K : never
59
+ }[keyof S]
60
+ /**
61
+ * One value per field `S` names: `null` when no row has one. An average is
62
+ * a number, a sum a number or a decimal's string, a minimum or a maximum
63
+ * the field's value.
64
+ */
65
+ type Values<F, S, As extends 'sum' | 'avg' | 'value'> = {
66
+ readonly [K in Asked<S>]:
67
+ | (As extends 'avg'
68
+ ? number
69
+ : As extends 'sum'
70
+ ? K extends DecimalKeys<F>
71
+ ? string
72
+ : number
73
+ : ValueOf<F, K>)
74
+ | null
75
+ }
76
+
77
+ /** What `aggregate` returns for the arguments `A`. */
78
+ export type Aggregates<F, A> = (A extends { readonly _count: infer C }
79
+ ? C extends true
80
+ ? { readonly _count: number }
81
+ : C extends object
82
+ ? { readonly _count: { readonly [K in Asked<C>]: number } }
83
+ : unknown
84
+ : unknown) &
85
+ (A extends { readonly _sum: infer S extends object }
86
+ ? { readonly _sum: Values<F, S, 'sum'> }
87
+ : unknown) &
88
+ (A extends { readonly _avg: infer S extends object }
89
+ ? { readonly _avg: Values<F, S, 'avg'> }
90
+ : unknown) &
91
+ (A extends { readonly _min: infer S extends object }
92
+ ? { readonly _min: Values<F, S, 'value'> }
93
+ : unknown) &
94
+ (A extends { readonly _max: infer S extends object }
95
+ ? { readonly _max: Values<F, S, 'value'> }
96
+ : unknown)