@primate/core 0.5.0 → 0.6.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 (297) hide show
  1. package/lib/private/App.d.ts +263 -26
  2. package/lib/private/App.js +42 -14
  3. package/lib/private/Flags.d.ts +8 -4
  4. package/lib/private/Module.d.ts +4 -16
  5. package/lib/private/Module.js +1 -17
  6. package/lib/private/app/EnvSchema.d.ts +5 -0
  7. package/lib/private/app/EnvSchema.js +2 -0
  8. package/lib/private/app/Facade.browser.d.ts +11 -0
  9. package/lib/private/app/Facade.browser.js +19 -0
  10. package/lib/private/app/Facade.d.ts +272 -27
  11. package/lib/private/app/Facade.js +23 -0
  12. package/lib/private/build/client/index.js +8 -3
  13. package/lib/private/build/client/plugin/app-request.d.ts +4 -0
  14. package/lib/private/build/client/plugin/app-request.js +19 -0
  15. package/lib/private/build/client/plugin/view.d.ts +4 -0
  16. package/lib/private/build/client/plugin/view.js +13 -0
  17. package/lib/private/build/hook.d.ts +1 -2
  18. package/lib/private/build/hook.js +21 -16
  19. package/lib/private/build/index.d.ts +2 -1
  20. package/lib/private/build/index.js +20 -21
  21. package/lib/private/build/server/index.js +7 -9
  22. package/lib/private/build/server/plugin/app-request.d.ts +4 -0
  23. package/lib/private/build/server/plugin/app-request.js +19 -0
  24. package/lib/private/build/server/plugin/assets.js +1 -1
  25. package/lib/private/build/server/plugin/live-reload.js +9 -9
  26. package/lib/private/build/server/plugin/native-addons.js +4 -7
  27. package/lib/private/build/server/plugin/route.js +2 -2
  28. package/lib/private/build/server/plugin/store.js +9 -31
  29. package/lib/private/build/server/plugin/stores.js +11 -7
  30. package/lib/private/build/server/plugin/view.js +1 -1
  31. package/lib/private/build/shared/plugin/app-request.d.ts +4 -0
  32. package/lib/private/build/shared/plugin/app-request.js +19 -0
  33. package/lib/private/client/Data.d.ts +3 -2
  34. package/lib/private/{frontend → client}/Render.d.ts +1 -1
  35. package/lib/private/{frontend → client}/ViewResponse.d.ts +1 -1
  36. package/lib/private/client/app.js +1 -2
  37. package/lib/private/client/boot.d.ts +5 -0
  38. package/lib/private/client/boot.js +64 -0
  39. package/lib/private/client/create-form.d.ts +1 -0
  40. package/lib/private/client/create-form.js +19 -20
  41. package/lib/private/client/extract-issues.js +2 -1
  42. package/lib/private/client/http.d.ts +13 -0
  43. package/lib/private/client/http.js +57 -0
  44. package/lib/private/client/index.d.ts +23 -0
  45. package/lib/private/client/index.js +16 -0
  46. package/lib/private/client/navigate.d.ts +13 -0
  47. package/lib/private/client/navigate.js +67 -0
  48. package/lib/private/client/root.d.ts +9 -0
  49. package/lib/private/client/root.js +11 -0
  50. package/lib/private/client/submit.d.ts +2 -0
  51. package/lib/private/client/submit.js +41 -0
  52. package/lib/private/config/index.d.ts +7 -2
  53. package/lib/private/config/index.js +3 -2
  54. package/lib/private/config/schema.d.ts +82 -26
  55. package/lib/private/config/schema.js +17 -4
  56. package/lib/private/cookie.d.ts +12 -6
  57. package/lib/private/db/DB.d.ts +21 -5
  58. package/lib/private/db/DB.js +1 -0
  59. package/lib/private/db/MemoryDB.d.ts +2 -4
  60. package/lib/private/db/MemoryDB.js +40 -22
  61. package/lib/private/db/common.d.ts +7 -0
  62. package/lib/private/db/common.js +31 -0
  63. package/lib/private/db/errors.d.ts +104 -0
  64. package/lib/private/db/errors.js +237 -0
  65. package/lib/private/db/migrate/apply.d.ts +2 -0
  66. package/lib/private/db/migrate/apply.js +32 -0
  67. package/lib/private/db/migrate/bundle.d.ts +3 -0
  68. package/lib/private/db/migrate/bundle.js +22 -0
  69. package/lib/private/db/migrate/create.d.ts +2 -0
  70. package/lib/private/db/migrate/create.js +154 -0
  71. package/lib/private/db/migrate/index.d.ts +10 -0
  72. package/lib/private/db/migrate/index.js +6 -0
  73. package/lib/private/db/migrate/status.d.ts +2 -0
  74. package/lib/private/db/migrate/status.js +38 -0
  75. package/lib/private/db/migrate/store.d.ts +5 -0
  76. package/lib/private/db/migrate/store.js +33 -0
  77. package/lib/private/db/sql.js +3 -3
  78. package/lib/private/db/test.js +461 -95
  79. package/lib/private/errors.d.ts +88 -0
  80. package/lib/private/errors.js +211 -0
  81. package/lib/private/frontend.d.ts +72 -0
  82. package/lib/private/frontend.js +245 -0
  83. package/lib/private/i18n/Formatter.js +2 -2
  84. package/lib/private/i18n/errors.d.ts +16 -0
  85. package/lib/private/i18n/errors.js +27 -0
  86. package/lib/private/i18n/module.d.ts +3 -0
  87. package/lib/private/i18n/module.js +115 -0
  88. package/lib/private/i18n/schema.d.ts +10 -5
  89. package/lib/private/i18n/validate.js +5 -7
  90. package/lib/private/index.d.ts +14 -0
  91. package/lib/private/index.js +2 -0
  92. package/lib/private/log.js +6 -5
  93. package/lib/private/module/Setup.d.ts +21 -0
  94. package/lib/private/module/Setup.js +2 -0
  95. package/lib/private/module/create.d.ts +16 -0
  96. package/lib/private/module/create.js +28 -0
  97. package/lib/private/orm/ExtractSchema.d.ts +9 -0
  98. package/lib/private/orm/ExtractSchema.js +2 -0
  99. package/lib/private/orm/ForeignKey.d.ts +5 -2
  100. package/lib/private/orm/ForeignKey.js +3 -0
  101. package/lib/private/orm/PrimaryKey.d.ts +5 -3
  102. package/lib/private/orm/PrimaryKey.js +9 -6
  103. package/lib/private/orm/StoreInput.d.ts +10 -0
  104. package/lib/private/orm/StoreInput.js +2 -0
  105. package/lib/private/orm/key.d.ts +6 -6
  106. package/lib/private/orm/key.js +7 -3
  107. package/lib/private/orm/parse.d.ts +5 -4
  108. package/lib/private/orm/parse.js +2 -2
  109. package/lib/private/orm/relation.d.ts +2 -2
  110. package/lib/private/orm/{Store.d.ts → store.d.ts} +33 -17
  111. package/lib/private/orm/{Store.js → store.js} +91 -67
  112. package/lib/private/paths.js +3 -3
  113. package/lib/private/request/RequestBag.d.ts +4 -0
  114. package/lib/private/request/RequestBag.js +5 -2
  115. package/lib/private/request/RequestBody.d.ts +6 -9
  116. package/lib/private/request/RequestBody.js +49 -54
  117. package/lib/private/request/RequestFacade.d.ts +3 -8
  118. package/lib/private/request/RequestPublic.d.ts +9 -0
  119. package/lib/private/request/RequestPublic.js +2 -0
  120. package/lib/private/request/RequestView.d.ts +11 -0
  121. package/lib/private/request/RequestView.js +3 -0
  122. package/lib/private/request/handle.d.ts +4 -0
  123. package/lib/private/request/handle.js +18 -0
  124. package/lib/private/request/parse.js +1 -0
  125. package/lib/private/request/route.js +8 -9
  126. package/lib/private/request/router.js +21 -49
  127. package/lib/private/request/storage.d.ts +4 -0
  128. package/lib/private/request/storage.js +5 -0
  129. package/lib/private/response/ResponseFunction.d.ts +1 -1
  130. package/lib/private/response/binary.js +1 -1
  131. package/lib/private/response/error.d.ts +1 -1
  132. package/lib/private/response/error.js +1 -1
  133. package/lib/private/response/json.d.ts +1 -1
  134. package/lib/private/response/json.js +1 -1
  135. package/lib/private/response/redirect.d.ts +5 -5
  136. package/lib/private/response/redirect.js +8 -9
  137. package/lib/private/response/respond.js +9 -7
  138. package/lib/private/response/sse.d.ts +1 -1
  139. package/lib/private/response/sse.js +1 -1
  140. package/lib/private/response/text.d.ts +1 -1
  141. package/lib/private/response/text.js +1 -1
  142. package/lib/private/response/view.d.ts +1 -1
  143. package/lib/private/response/view.js +6 -13
  144. package/lib/private/response/ws.d.ts +1 -1
  145. package/lib/private/route/router.d.ts +3 -3
  146. package/lib/private/route/router.js +7 -10
  147. package/lib/private/serve/App.d.ts +6 -7
  148. package/lib/private/serve/App.js +52 -43
  149. package/lib/private/serve/Init.d.ts +2 -2
  150. package/lib/private/serve/dev-module.d.ts +2 -0
  151. package/lib/private/serve/dev-module.js +34 -0
  152. package/lib/private/serve/hook.d.ts +1 -2
  153. package/lib/private/serve/hook.js +2 -3
  154. package/lib/private/serve/index.d.ts +1 -1
  155. package/lib/private/serve/index.js +32 -2
  156. package/lib/private/server/TAG.d.ts +3 -0
  157. package/lib/private/server/TAG.js +2 -0
  158. package/lib/private/server/index.d.ts +5 -0
  159. package/lib/private/server/index.js +6 -0
  160. package/lib/private/session/SessionHandle.js +2 -1
  161. package/lib/private/session/index.d.ts +1 -1
  162. package/lib/private/session/module.d.ts +3 -0
  163. package/lib/private/session/module.js +114 -0
  164. package/lib/private/session/schema.d.ts +17 -9
  165. package/lib/private/session/schema.js +9 -5
  166. package/lib/private/target/Manager.js +6 -12
  167. package/lib/public/client.d.ts +2 -13
  168. package/lib/public/client.js +1 -9
  169. package/lib/public/db/errors.d.ts +2 -0
  170. package/lib/public/db/errors.js +2 -0
  171. package/lib/public/db/migrate.d.ts +2 -0
  172. package/lib/public/db/migrate.js +2 -0
  173. package/lib/public/db.d.ts +3 -3
  174. package/lib/public/frontend.d.ts +3 -0
  175. package/lib/public/frontend.js +2 -0
  176. package/lib/public/index.d.ts +2 -0
  177. package/lib/public/index.js +2 -0
  178. package/lib/public/orm/store.d.ts +2 -0
  179. package/lib/public/orm/store.js +2 -0
  180. package/lib/public/request/server.d.ts +5 -0
  181. package/lib/public/request/server.js +7 -0
  182. package/lib/public/response.d.ts +4 -4
  183. package/lib/public/server.d.ts +3 -0
  184. package/lib/public/server.js +2 -0
  185. package/package.json +30 -25
  186. package/lib/private/AppError.d.ts +0 -4
  187. package/lib/private/AppError.js +0 -8
  188. package/lib/private/backend/Module.d.ts +0 -18
  189. package/lib/private/backend/Module.js +0 -19
  190. package/lib/private/backend/TAG.d.ts +0 -3
  191. package/lib/private/backend/TAG.js +0 -2
  192. package/lib/private/build/server/plugin/db-default.d.ts +0 -4
  193. package/lib/private/build/server/plugin/db-default.js +0 -45
  194. package/lib/private/build/server/plugin/store-wrap.d.ts +0 -4
  195. package/lib/private/build/server/plugin/store-wrap.js +0 -33
  196. package/lib/private/client/spa/index.d.ts +0 -6
  197. package/lib/private/client/spa/index.js +0 -200
  198. package/lib/private/db/error.d.ts +0 -81
  199. package/lib/private/db/error.js +0 -199
  200. package/lib/private/db/symbol/wrap.d.ts +0 -3
  201. package/lib/private/db/symbol/wrap.js +0 -2
  202. package/lib/private/fail.d.ts +0 -3
  203. package/lib/private/fail.js +0 -5
  204. package/lib/private/frontend/Module.d.ts +0 -62
  205. package/lib/private/frontend/Module.js +0 -255
  206. package/lib/private/i18n/Module.d.ts +0 -16
  207. package/lib/private/i18n/Module.js +0 -133
  208. package/lib/private/module/BuildHook.d.ts +0 -5
  209. package/lib/private/module/BuildHook.js +0 -2
  210. package/lib/private/module/NextBuild.d.ts +0 -5
  211. package/lib/private/module/NextBuild.js +0 -2
  212. package/lib/private/module/NextServe.d.ts +0 -5
  213. package/lib/private/module/NextServe.js +0 -2
  214. package/lib/private/orm/Set.d.ts +0 -11
  215. package/lib/private/orm/Set.js +0 -2
  216. package/lib/private/orm/foreign.d.ts +0 -4
  217. package/lib/private/orm/foreign.js +0 -5
  218. package/lib/private/orm/primary.d.ts +0 -5
  219. package/lib/private/orm/primary.js +0 -5
  220. package/lib/private/orm/types.d.ts +0 -18
  221. package/lib/private/orm/types.js +0 -2
  222. package/lib/private/orm/wrap.d.ts +0 -5
  223. package/lib/private/orm/wrap.js +0 -5
  224. package/lib/private/reducer.d.ts +0 -24
  225. package/lib/private/reducer.js +0 -10
  226. package/lib/private/serve/module/Dev.d.ts +0 -11
  227. package/lib/private/serve/module/Dev.js +0 -32
  228. package/lib/private/serve/module/Handle.d.ts +0 -10
  229. package/lib/private/serve/module/Handle.js +0 -15
  230. package/lib/private/session/SessionModule.d.ts +0 -14
  231. package/lib/private/session/SessionModule.js +0 -122
  232. package/lib/public/App.d.ts +0 -2
  233. package/lib/public/App.js +0 -2
  234. package/lib/public/AppError.d.ts +0 -2
  235. package/lib/public/AppError.js +0 -2
  236. package/lib/public/BuildApp.d.ts +0 -2
  237. package/lib/public/BuildApp.js +0 -2
  238. package/lib/public/BuildHook.d.ts +0 -2
  239. package/lib/public/BuildHook.js +0 -2
  240. package/lib/public/Mode.d.ts +0 -2
  241. package/lib/public/Mode.js +0 -2
  242. package/lib/public/Module.d.ts +0 -2
  243. package/lib/public/Module.js +0 -2
  244. package/lib/public/Next.d.ts +0 -2
  245. package/lib/public/Next.js +0 -2
  246. package/lib/public/NextBuild.d.ts +0 -2
  247. package/lib/public/NextBuild.js +0 -2
  248. package/lib/public/NextHandle.d.ts +0 -2
  249. package/lib/public/NextHandle.js +0 -2
  250. package/lib/public/NextRoute.d.ts +0 -3
  251. package/lib/public/NextRoute.js +0 -2
  252. package/lib/public/NextServe.d.ts +0 -2
  253. package/lib/public/NextServe.js +0 -2
  254. package/lib/public/ServeApp.d.ts +0 -2
  255. package/lib/public/ServeApp.js +0 -2
  256. package/lib/public/Target.d.ts +0 -2
  257. package/lib/public/Target.js +0 -2
  258. package/lib/public/backend/Module.d.ts +0 -2
  259. package/lib/public/backend/Module.js +0 -2
  260. package/lib/public/backend/TAG.d.ts +0 -2
  261. package/lib/public/backend/TAG.js +0 -2
  262. package/lib/public/client/Data.d.ts +0 -2
  263. package/lib/public/client/Data.js +0 -2
  264. package/lib/public/client/spa.d.ts +0 -2
  265. package/lib/public/client/spa.js +0 -2
  266. package/lib/public/db/error.d.ts +0 -2
  267. package/lib/public/db/error.js +0 -2
  268. package/lib/public/fail.d.ts +0 -2
  269. package/lib/public/fail.js +0 -2
  270. package/lib/public/frontend/Module.d.ts +0 -2
  271. package/lib/public/frontend/Module.js +0 -2
  272. package/lib/public/frontend/Publish.d.ts +0 -2
  273. package/lib/public/frontend/Publish.js +0 -2
  274. package/lib/public/frontend/Render.d.ts +0 -2
  275. package/lib/public/frontend/Render.js +0 -2
  276. package/lib/public/frontend/ViewResponse.d.ts +0 -2
  277. package/lib/public/frontend/ViewResponse.js +0 -2
  278. package/lib/public/orm/Store.d.ts +0 -2
  279. package/lib/public/orm/Store.js +0 -2
  280. package/lib/public/orm/wrap.d.ts +0 -2
  281. package/lib/public/orm/wrap.js +0 -2
  282. package/lib/public/request.d.ts +0 -4
  283. package/lib/public/request.js +0 -2
  284. /package/lib/private/{frontend → client}/Publish.d.ts +0 -0
  285. /package/lib/private/{frontend → client}/Publish.js +0 -0
  286. /package/lib/private/{frontend → client}/Render.js +0 -0
  287. /package/lib/private/{frontend → client}/ServerData.d.ts +0 -0
  288. /package/lib/private/{frontend → client}/ServerData.js +0 -0
  289. /package/lib/private/{frontend → client}/ServerView.d.ts +0 -0
  290. /package/lib/private/{frontend → client}/ServerView.js +0 -0
  291. /package/lib/private/{frontend → client}/View.d.ts +0 -0
  292. /package/lib/private/{frontend → client}/View.js +0 -0
  293. /package/lib/private/{frontend → client}/ViewOptions.d.ts +0 -0
  294. /package/lib/private/{frontend → client}/ViewOptions.js +0 -0
  295. /package/lib/private/{frontend → client}/ViewResponse.js +0 -0
  296. /package/lib/private/client/{spa/storage.d.ts → storage.d.ts} +0 -0
  297. /package/lib/private/client/{spa/storage.js → storage.js} +0 -0
@@ -1,7 +1,7 @@
1
- import { Code } from "#db/error";
1
+ import { Code } from "#db/errors";
2
2
  import key from "#orm/key";
3
3
  import relation from "#orm/relation";
4
- import Store from "#orm/Store";
4
+ import store from "#orm/store";
5
5
  import test from "@rcompat/test";
6
6
  import any from "@rcompat/test/any";
7
7
  import p from "pema";
@@ -106,108 +106,147 @@ async function throws(assert, code, fn) {
106
106
  }
107
107
  export default (db) => {
108
108
  test.ended(() => db.close());
109
- const Post = new Store({
110
- id: key.primary(p.string),
111
- title: p.string,
112
- user_id: p.uint,
113
- }, { db, name: "post" });
109
+ const Post = store({
110
+ name: "post",
111
+ db,
112
+ schema: {
113
+ id: key.primary(p.uuid),
114
+ title: p.string,
115
+ user_id: p.uint,
116
+ },
117
+ });
114
118
  Post.update;
115
- const User = new Store({
116
- id: key.primary(p.string),
117
- age: p.u8.optional(),
118
- lastname: p.string.optional(),
119
- name: p.string.default("Donald"),
120
- }, { db: db, name: "user" });
121
- const UserN = new Store({
122
- id: key.primary(p.u32),
123
- age: p.u8.optional(),
124
- lastname: p.string.optional(),
125
- name: p.string.default("Donald"),
126
- }, { db: db, name: "user_n" });
127
- const UserB = new Store({
128
- id: key.primary(p.u128),
129
- age: p.u8.optional(),
130
- lastname: p.string.optional(),
131
- name: p.string.default("Donald"),
132
- }, { db: db, name: "user_b" });
119
+ const User = store({
120
+ name: "user",
121
+ db,
122
+ schema: {
123
+ id: key.primary(p.uuid),
124
+ age: p.u8.optional(),
125
+ lastname: p.string.optional(),
126
+ name: p.string.default("Donald"),
127
+ },
128
+ });
129
+ const UserN = store({
130
+ name: "user_n",
131
+ db,
132
+ schema: {
133
+ id: key.primary(p.u32),
134
+ age: p.u8.optional(),
135
+ lastname: p.string.optional(),
136
+ name: p.string.default("Donald"),
137
+ },
138
+ });
139
+ const UserB = store({
140
+ name: "user_b",
141
+ db,
142
+ schema: {
143
+ id: key.primary(p.u128),
144
+ age: p.u8.optional(),
145
+ lastname: p.string.optional(),
146
+ name: p.string.default("Donald"),
147
+ },
148
+ });
133
149
  const USER_STORES = [User, UserN, UserB];
134
- const Type = new Store({
135
- id: key.primary(p.string),
136
- boolean: p.boolean.optional(),
137
- date: p.date.optional(),
138
- f32: p.f32.optional(),
139
- f64: p.f64.optional(),
140
- i128: p.i128.optional(),
141
- i16: p.i16.optional(),
142
- i32: p.i32.optional(),
143
- i64: p.i64.optional(),
144
- i8: p.i8.optional(),
145
- string: p.string.optional(),
146
- u128: p.u128.optional(),
147
- u16: p.u16.optional(),
148
- u32: p.u32.optional(),
149
- u64: p.u64.optional(),
150
- u8: p.u8.optional(),
151
- }, { db: db, name: "type" });
150
+ const Type = store({
151
+ name: "type",
152
+ db,
153
+ schema: {
154
+ id: key.primary(p.uuid),
155
+ boolean: p.boolean.optional(),
156
+ date: p.date.optional(),
157
+ f32: p.f32.optional(),
158
+ f64: p.f64.optional(),
159
+ i128: p.i128.optional(),
160
+ i16: p.i16.optional(),
161
+ i32: p.i32.optional(),
162
+ i64: p.i64.optional(),
163
+ i8: p.i8.optional(),
164
+ string: p.string.optional(),
165
+ u128: p.u128.optional(),
166
+ u16: p.u16.optional(),
167
+ u32: p.u32.optional(),
168
+ u64: p.u64.optional(),
169
+ u8: p.u8.optional(),
170
+ json: p.json().optional(),
171
+ },
172
+ });
152
173
  // this stresses identifier quoting in CREATE/INSERT/SELECT/UPDATE/DELETE
153
- const Reserved = new Store({
154
- id: key.primary(p.string),
155
- // deliberately reserved-looking column name
156
- order: p.u8.optional(),
157
- name: p.string,
158
- }, { db: db, name: "select" }); // deliberately reserved-like table name
174
+ const Reserved = store({
175
+ // deliberately reserved-like table name
176
+ name: "select",
177
+ db,
178
+ schema: {
179
+ id: key.primary(p.uuid),
180
+ // deliberately reserved-looking column name
181
+ order: p.u8.optional(),
182
+ name: p.string,
183
+ },
184
+ });
159
185
  const AuthorSchema = {
160
- id: key.primary(p.string),
186
+ id: key.primary(p.uuid),
161
187
  name: p.string,
162
188
  };
163
189
  const ArticleSchema = {
164
- id: key.primary(p.string),
190
+ id: key.primary(p.uuid),
165
191
  title: p.string,
166
- author_id: key.foreign(p.string),
192
+ author_id: key.foreign(p.uuid),
167
193
  };
168
194
  const ProfileSchema = {
169
- id: key.primary(p.string),
195
+ id: key.primary(p.uuid),
170
196
  bio: p.string,
171
197
  url: p.url.optional(),
172
- author_id: key.foreign(p.string),
198
+ author_id: key.foreign(p.uuid),
173
199
  };
174
- const Author = new Store(AuthorSchema, {
200
+ const Author = store({
175
201
  db,
176
202
  name: "author",
203
+ schema: AuthorSchema,
177
204
  relations: {
178
205
  articles: relation.many(ArticleSchema, "author_id"),
179
206
  profile: relation.one(ProfileSchema, "author_id"),
180
207
  },
181
208
  });
182
- const Article = new Store(ArticleSchema, {
209
+ /*const AuthorWithJSON = store({
210
+ name: "author_json",
211
+ db,
212
+ schema: {
213
+ id: key.primary(p.uuid),
214
+ name: p.string,
215
+ meta: p.json(p({ views: p.u32, tags: p.array(p.string) })),
216
+ notes: p.json(), // untyped
217
+ },
218
+ });*/
219
+ const Article = store({
183
220
  db,
184
221
  name: "article",
222
+ schema: ArticleSchema,
185
223
  relations: {
186
224
  author: relation.one(AuthorSchema, "author_id", { reverse: true }),
187
225
  },
188
226
  });
189
- const Profile = new Store(ProfileSchema, {
227
+ const Profile = store({
190
228
  db,
191
229
  name: "profile",
230
+ schema: ProfileSchema,
192
231
  relations: {
193
232
  author: relation.one(AuthorSchema, "author_id", { reverse: true }),
194
233
  },
195
234
  });
196
- function $store(label, store, body) {
235
+ function $store(label, s, body) {
197
236
  test.case(label, async (assert) => {
198
- await store.collection.create();
237
+ await s.table.create();
199
238
  try {
200
239
  await body(assert);
201
240
  }
202
241
  finally {
203
- await store.collection.delete();
242
+ await s.table.delete();
204
243
  }
205
244
  });
206
245
  }
207
246
  function $user(label, body) {
208
247
  test.case(label, async (assert) => {
209
248
  for (const S of USER_STORES)
210
- await S.collection.create();
249
+ await S.table.create();
211
250
  try {
212
251
  for (const u of Object.values(USERS)) {
213
252
  for (const S of USER_STORES)
@@ -217,7 +256,7 @@ export default (db) => {
217
256
  }
218
257
  finally {
219
258
  for (const S of USER_STORES)
220
- await S.collection.delete();
259
+ await S.table.delete();
221
260
  }
222
261
  });
223
262
  }
@@ -229,9 +268,9 @@ export default (db) => {
229
268
  }
230
269
  function $rel(label, body) {
231
270
  test.case(`relation: ${label}`, async (assert) => {
232
- await Author.collection.create();
233
- await Article.collection.create();
234
- await Profile.collection.create();
271
+ await Author.table.create();
272
+ await Article.table.create();
273
+ await Profile.table.create();
235
274
  try {
236
275
  const john = await Author.insert({ name: "John" });
237
276
  const bob = await Author.insert({ name: "Bob" });
@@ -257,9 +296,9 @@ export default (db) => {
257
296
  await body(assert);
258
297
  }
259
298
  finally {
260
- await Profile.collection.delete();
261
- await Article.collection.delete();
262
- await Author.collection.delete();
299
+ await Profile.table.delete();
300
+ await Article.table.delete();
301
+ await Author.table.delete();
263
302
  }
264
303
  });
265
304
  }
@@ -309,19 +348,24 @@ export default (db) => {
309
348
  assert(user.id).type();
310
349
  assert(await UserB.has(user.id)).true();
311
350
  });
312
- const ManualUser = new Store({
313
- id: key.primary(p.string, { generate: false }),
314
- name: p.string,
315
- }, { db, name: "manual_user" });
351
+ const ManualUser = store({
352
+ name: "manual_user",
353
+ db,
354
+ schema: {
355
+ id: key.primary(p.uuid, { generate: false }),
356
+ name: p.string,
357
+ },
358
+ });
316
359
  $store("insert: generate=false requires PK", ManualUser, async (assert) => {
317
360
  await throws(assert, Code.pk_required, () => {
318
361
  return ManualUser.insert({ name: "Test" });
319
362
  });
320
363
  });
321
364
  $store("insert: generate=false accepts provided PK", ManualUser, async (assert) => {
322
- const user = await ManualUser.insert({ id: "manual-id", name: "Test" });
323
- assert(user.id).equals("manual-id");
324
- assert(await ManualUser.has("manual-id")).true();
365
+ const id = "4d0996db-bda9-4f95-ad7c-7075b10d4ba6";
366
+ const user = await ManualUser.insert({ id, name: "Test" });
367
+ assert(user.id).equals(id);
368
+ assert(await ManualUser.has(id)).true();
325
369
  });
326
370
  $store("insert: defaults apply", User, async (assert) => {
327
371
  const u = await User.insert({});
@@ -781,6 +825,12 @@ export default (db) => {
781
825
  // returned shape must not contain null
782
826
  assert(got.lastname).undefined();
783
827
  });
828
+ $store("insert: default fields can be omitted", User, async (assert) => {
829
+ // User has name: p.string.default("Donald")
830
+ // should be insertable without providing name
831
+ const user = await User.insert({ age: 30 });
832
+ assert(user.name).equals("Donald");
833
+ });
784
834
  $store("reserved table / column names", Reserved, async (assert) => {
785
835
  const a = await Reserved.insert({ name: "alpha", order: 1 });
786
836
  const b = await Reserved.insert({ name: "beta", order: 2 });
@@ -973,17 +1023,20 @@ export default (db) => {
973
1023
  });
974
1024
  });
975
1025
  $user("get/try: missing id", async (assert) => {
976
- const missing = `missing-${Date.now()}-${Math.random()}`;
1026
+ const missing = "00000000-0000-4000-8000-000000000000";
1027
+ // const missing = `missing-${Date.now()}-${Math.random()}`;
977
1028
  await throws(assert, Code.record_not_found, () => User.get(missing));
978
1029
  assert(await User.try(missing)).undefined();
979
1030
  });
980
1031
  $rel("get/try: missing id (with relations)", async (assert) => {
981
- const missing = `missing-${Date.now()}-${Math.random()}`;
1032
+ //const missing = `missing-${Date.now()}-${Math.random()}`;
1033
+ const missing = "00000000-0000-4000-8000-000000000000";
982
1034
  await throws(assert, Code.record_not_found, () => Article.get(missing, { with: { author: true } }));
983
1035
  assert(await Article.try(missing, { with: { author: true } })).undefined();
984
1036
  });
985
1037
  $rel("get/try: missing id (+ parent)", async (assert) => {
986
- const missing = `missing-${Date.now()}-${Math.random()}`;
1038
+ const missing = "00000000-0000-4000-8000-000000000000";
1039
+ //const missing = `missing-${Date.now()}-${Math.random()}`;
987
1040
  await throws(assert, Code.record_not_found, () => Author.get(missing, { with: { articles: true, profile: true } }));
988
1041
  assert(await Author.try(missing, {
989
1042
  with: { articles: true, profile: true },
@@ -1103,12 +1156,76 @@ export default (db) => {
1103
1156
  const results = await Type.find({
1104
1157
  where: {
1105
1158
  string: "combo",
1106
- u8: { $gte: 150, $ne: 200 }
1159
+ u8: { $gte: 150, $ne: 200 },
1107
1160
  },
1108
1161
  sort: { u8: "asc" },
1109
1162
  });
1110
1163
  assert(results.map(r => r.u8)).equals([150]);
1111
1164
  });
1165
+ $type("json: opaque roundtrip", async (assert) => {
1166
+ const json = { a: 1, b: [true, "x"], c: null };
1167
+ const t = await Type.insert({ json });
1168
+ assert(t.json).equals(json);
1169
+ assert((await Type.get(t.id)).json).equals(json);
1170
+ });
1171
+ $type("json: update", async (assert) => {
1172
+ const t = await Type.insert({ json: { x: 1 } });
1173
+ await Type.update(t.id, { set: { json: { x: 2, y: "hello" } } });
1174
+ assert((await Type.get(t.id)).json).equals({ x: 2, y: "hello" });
1175
+ });
1176
+ $type("json: nested object", async (assert) => {
1177
+ const value = { outer: { inner: { deep: true } } };
1178
+ const t = await Type.insert({ json: value });
1179
+ assert((await Type.get(t.id)).json).equals(value);
1180
+ });
1181
+ $type("json: array at root", async (assert) => {
1182
+ const value = [1, "two", false, null];
1183
+ const t = await Type.insert({ json: value });
1184
+ assert((await Type.get(t.id)).json).equals(value);
1185
+ });
1186
+ $type("json: null value unsets field", async (assert) => {
1187
+ const t = await Type.insert({ json: { x: 1 } });
1188
+ await Type.update(t.id, { set: { json: null } });
1189
+ assert((await Type.get(t.id)).json).undefined();
1190
+ });
1191
+ $type("json: empty object", async (assert) => {
1192
+ const t = await Type.insert({ json: {} });
1193
+ assert((await Type.get(t.id)).json).equals({});
1194
+ });
1195
+ $type("json: empty array", async (assert) => {
1196
+ const t = await Type.insert({ json: [] });
1197
+ assert((await Type.get(t.id)).json).equals([]);
1198
+ });
1199
+ $type("json: primitive string", async (assert) => {
1200
+ const t = await Type.insert({ json: "hello" });
1201
+ assert((await Type.get(t.id)).json).equals("hello");
1202
+ });
1203
+ $type("json: primitive number", async (assert) => {
1204
+ const t = await Type.insert({ json: 42 });
1205
+ assert((await Type.get(t.id)).json).equals(42);
1206
+ });
1207
+ $type("json: primitive float", async (assert) => {
1208
+ const t = await Type.insert({ json: 3.14 });
1209
+ assert((await Type.get(t.id)).json).equals(3.14);
1210
+ });
1211
+ $type("json: primitive boolean true", async (assert) => {
1212
+ const t = await Type.insert({ json: true });
1213
+ assert((await Type.get(t.id)).json).equals(true);
1214
+ });
1215
+ $type("json: primitive boolean false", async (assert) => {
1216
+ const t = await Type.insert({ json: false });
1217
+ assert((await Type.get(t.id)).json).equals(false);
1218
+ });
1219
+ $type("json: null inside object survives roundtrip", async (assert) => {
1220
+ const value = { a: 1, b: null };
1221
+ const t = await Type.insert({ json: value });
1222
+ assert((await Type.get(t.id)).json).equals({ a: 1, b: null });
1223
+ });
1224
+ $type("json: null inside array survives roundtrip", async (assert) => {
1225
+ const value = [1, null, "three"];
1226
+ const t = await Type.insert({ json: value });
1227
+ assert((await Type.get(t.id)).json).equals([1, null, "three"]);
1228
+ });
1112
1229
  $store("where: null matches omitted optional field", User, async (assert) => {
1113
1230
  const u = await User.insert({ name: "NoLast" });
1114
1231
  const rows = await User.find({
@@ -1118,6 +1235,75 @@ export default (db) => {
1118
1235
  assert(rows.length).equals(1);
1119
1236
  assert(rows[0].id).equals(u.id);
1120
1237
  });
1238
+ /*$store("json column: inferred type on insert", AuthorWithJSON, async assert => {
1239
+ const author = await AuthorWithJSON.insert({
1240
+ name: "John",
1241
+ articles: [{ title: "First", published: new Date() }],
1242
+ meta: { views: 0, tags: ["typescript"] },
1243
+ });
1244
+
1245
+ assert(author).type<{
1246
+ id: string;
1247
+ name: string;
1248
+ articles?: { title: string; published: Date }[];
1249
+ meta?: { views: number; tags: string[] };
1250
+ notes?: JSONValue;
1251
+ }>();
1252
+ });
1253
+
1254
+ $store("json column: inferred type on find", AuthorWithJSON, async assert => {
1255
+ const authors = await AuthorWithJSON.find();
1256
+ assert(authors).type<{
1257
+ id: string;
1258
+ name: string;
1259
+ articles?: { title: string; published: Date }[];
1260
+ meta?: { views: number; tags: string[] };
1261
+ notes?: JSONValue;
1262
+ }[]>();
1263
+ });
1264
+
1265
+ $store("json column: inferred type on get", AuthorWithJSON, async assert => {
1266
+ const a = await AuthorWithJSON.insert({
1267
+ name: "John",
1268
+ articles: [{ title: "First", published: new Date() }],
1269
+ meta: { views: 0, tags: ["typescript"] },
1270
+ });
1271
+ const author = await AuthorWithJSON.get(a.id);
1272
+
1273
+ assert(author.articles).type<{ title: string; published: Date }[] | undefined>();
1274
+ assert(author.meta).type<{ views: number; tags: string[] } | undefined>();
1275
+ assert(author.notes).type<JSONValue | undefined>();
1276
+
1277
+ // inner field access fully typed
1278
+ assert(author.articles?.[0].title).type<string | undefined>();
1279
+ assert(author.articles?.[0].published).type<Date | undefined>();
1280
+ });
1281
+
1282
+ $store("json column: roundtrip preserves types", AuthorWithJSON, async assert => {
1283
+ const now = new Date();
1284
+ const a = await AuthorWithJSON.insert({
1285
+ name: "John",
1286
+ articles: [{ title: "First", published: now }],
1287
+ meta: { views: 42, tags: ["ts", "primate"] },
1288
+ });
1289
+
1290
+ const author = await AuthorWithJSON.get(a.id);
1291
+
1292
+ assert(author.articles?.[0].title).equals("First");
1293
+ assert(author.articles?.[0].published?.getTime()).equals(now.getTime());
1294
+ assert(author.meta?.views).equals(42);
1295
+ assert(author.meta?.tags).equals(["ts", "primate"]);
1296
+ });
1297
+
1298
+ $store("json column: nested where is typed", AuthorWithJSON, async assert => {
1299
+ // these should compile
1300
+ await AuthorWithJSON.find({ where: { articles: { title: "First" } } });
1301
+ await AuthorWithJSON.find({ where: { meta: { views: { $gt: 10 } } } });
1302
+ await AuthorWithJSON.find({ where: { meta: { tags: { $like: "%ts%" } } } });
1303
+
1304
+ // $contains always available, untyped
1305
+ await AuthorWithJSON.find({ where: { articles: { $contains: { title: "First" } } } });
1306
+ });*/
1121
1307
  $user("where: null matches unset via update", async (assert) => {
1122
1308
  const [paul] = await User.find({ where: { name: "Paul" } });
1123
1309
  await User.update(paul.id, { set: { lastname: null } });
@@ -1185,9 +1371,10 @@ export default (db) => {
1185
1371
  });
1186
1372
  });
1187
1373
  $rel("one relation returns null when FK missing", async (assert) => {
1374
+ const author_id = "4d0996db-bda9-4f95-ad7c-7075b10d4ba6";
1188
1375
  const orphan = await Article.insert({
1189
1376
  title: "Orphan",
1190
- author_id: "missing-author",
1377
+ author_id,
1191
1378
  });
1192
1379
  const got = await Article.get(orphan.id, { with: { author: true } });
1193
1380
  assert(got.author).null();
@@ -1237,11 +1424,14 @@ export default (db) => {
1237
1424
  });
1238
1425
  });
1239
1426
  $user$("inject invalid identifier (table name)", async (assert) => {
1240
- const BadStore = new Store({
1241
- id: key.primary(p.string),
1242
- }, { db, name: "users; DROP TABLE users" });
1243
- await throws(assert, Code.identifier_invalid, async () => {
1244
- await BadStore.collection.create();
1427
+ await throws(assert, Code.identifier_invalid, () => {
1428
+ store({
1429
+ name: "users; DROP TABLE users",
1430
+ db,
1431
+ schema: {
1432
+ id: key.primary(p.uuid),
1433
+ },
1434
+ });
1245
1435
  });
1246
1436
  });
1247
1437
  $user("find: $like: literal percent sign", async (assert) => {
@@ -1300,31 +1490,33 @@ export default (db) => {
1300
1490
  });
1301
1491
  $rel("with: joined relations decode URL fields (base + rel)", async (assert) => {
1302
1492
  const ParentSchema = {
1303
- id: key.primary(p.string),
1493
+ id: key.primary(p.uuid),
1304
1494
  name: p.string,
1305
1495
  url: p.url.optional(),
1306
1496
  };
1307
1497
  const ChildSchema = {
1308
- id: key.primary(p.string),
1309
- parent_id: key.foreign(p.string),
1498
+ id: key.primary(p.uuid),
1499
+ parent_id: key.foreign(p.uuid),
1310
1500
  url: p.url.optional(),
1311
1501
  };
1312
- const Parent = new Store(ParentSchema, {
1313
- db,
1502
+ const Parent = store({
1314
1503
  name: "j_parent",
1504
+ db,
1505
+ schema: ParentSchema,
1315
1506
  relations: {
1316
1507
  children: relation.many(ChildSchema, "parent_id"),
1317
1508
  },
1318
1509
  });
1319
- const Child = new Store(ChildSchema, {
1510
+ const Child = store({
1320
1511
  db,
1321
1512
  name: "j_child",
1513
+ schema: ChildSchema,
1322
1514
  relations: {
1323
1515
  parent: relation.one(ParentSchema, "parent_id", { reverse: true }),
1324
1516
  },
1325
1517
  });
1326
- await Parent.collection.create();
1327
- await Child.collection.create();
1518
+ await Parent.table.create();
1519
+ await Child.table.create();
1328
1520
  try {
1329
1521
  const p0 = await Parent.insert({
1330
1522
  name: "P0",
@@ -1356,8 +1548,8 @@ export default (db) => {
1356
1548
  assert(c0.url.href).equals("https://example.com/joined");
1357
1549
  }
1358
1550
  finally {
1359
- await Child.collection.delete();
1360
- await Parent.collection.delete();
1551
+ await Child.table.delete();
1552
+ await Parent.table.delete();
1361
1553
  }
1362
1554
  });
1363
1555
  $rel("find: limit applies to parent rows, not joined rows", async (assert) => {
@@ -1380,5 +1572,179 @@ export default (db) => {
1380
1572
  for (const c of BAD_WHERE_COLUMN) {
1381
1573
  bad_where(c.label, () => ({ base: c.base, with: c.with }), c.expected);
1382
1574
  }
1575
+ test.case("store: relation name conflicts with field throws", async (assert) => {
1576
+ await throws(assert, Code.relation_conflicts_with_field, async () => store({
1577
+ name: "conflict",
1578
+ db,
1579
+ schema: {
1580
+ id: key.primary(p.uuid),
1581
+ articles: p.string,
1582
+ },
1583
+ relations: {
1584
+ articles: relation.many(ArticleSchema, "author_id"),
1585
+ },
1586
+ }));
1587
+ });
1588
+ // introspect: returns null for non-existent table
1589
+ test.case("schema: introspect non-existent", async (assert) => {
1590
+ assert(await db.schema.introspect("no_such_table")).null();
1591
+ });
1592
+ // UUID pk (User): wrong JS type
1593
+ $store("pk: get rejects non-string for uuid pk", User, async (assert) => {
1594
+ await throws(assert, Code.pk_invalid, () => User.get(123));
1595
+ });
1596
+ $store("pk: has rejects non-string for uuid pk", User, async (assert) => {
1597
+ await throws(assert, Code.pk_invalid, () => User.has(123));
1598
+ });
1599
+ $store("pk: delete rejects non-string for uuid pk", User, async (assert) => {
1600
+ await throws(assert, Code.pk_invalid, () => User.delete(123));
1601
+ });
1602
+ $store("pk: update rejects non-string for uuid pk", User, async (assert) => {
1603
+ await throws(assert, Code.pk_invalid, () => User.update(123, { set: { name: "x" } }));
1604
+ });
1605
+ // UUID pk (User): valid JS type but malformed UUID
1606
+ $store("pk: get rejects malformed uuid", User, async (assert) => {
1607
+ await throws(assert, Code.pk_invalid, () => User.get("not-a-uuid"));
1608
+ });
1609
+ $store("pk: has rejects malformed uuid", User, async (assert) => {
1610
+ await throws(assert, Code.pk_invalid, () => User.has("not-a-uuid"));
1611
+ });
1612
+ $store("pk: delete rejects malformed uuid", User, async (assert) => {
1613
+ await throws(assert, Code.pk_invalid, () => User.delete("not-a-uuid"));
1614
+ });
1615
+ $store("pk: update rejects malformed uuid", User, async (assert) => {
1616
+ await throws(assert, Code.pk_invalid, () => User.update("not-a-uuid", { set: { name: "x" } }));
1617
+ });
1618
+ // Numeric pk (UserN u32): wrong JS type
1619
+ $store("pk: get rejects string for numeric pk", UserN, async (assert) => {
1620
+ await throws(assert, Code.pk_invalid, () => UserN.get("abc"));
1621
+ });
1622
+ $store("pk: has rejects string for numeric pk", UserN, async (assert) => {
1623
+ await throws(assert, Code.pk_invalid, () => UserN.has("abc"));
1624
+ });
1625
+ $store("pk: delete rejects string for numeric pk", UserN, async (assert) => {
1626
+ await throws(assert, Code.pk_invalid, () => UserN.delete("abc"));
1627
+ });
1628
+ $store("pk: update rejects string for numeric pk", UserN, async (assert) => {
1629
+ await throws(assert, Code.pk_invalid, () => UserN.update("abc", { set: { name: "x" } }));
1630
+ });
1631
+ // Numeric pk (UserN u32): negative value
1632
+ $store("pk: get rejects negative for unsigned pk", UserN, async (assert) => {
1633
+ await throws(assert, Code.pk_invalid, () => UserN.get(-1));
1634
+ });
1635
+ // Bigint pk (UserB u128): wrong JS type
1636
+ $store("pk: get rejects string for bigint pk", UserB, async (assert) => {
1637
+ await throws(assert, Code.pk_invalid, () => UserB.get("abc"));
1638
+ });
1639
+ $store("pk: get rejects negative for unsigned bigint pk", UserB, async (assert) => {
1640
+ await throws(assert, Code.pk_invalid, () => UserB.get(-1n));
1641
+ });
1642
+ // introspect: returns correct types after create
1643
+ $store("schema: introspect after create", User, async (assert) => {
1644
+ // insert a record so MongoDB has something to sample
1645
+ await User.insert({ name: "test", age: 1, lastname: "test" });
1646
+ const types = await db.schema.introspect(User.name, User.pk);
1647
+ assert(types).not.null();
1648
+ if (types !== null) {
1649
+ assert(types.id).includes("uuid");
1650
+ assert(types.name).includes("string");
1651
+ assert(types.age).includes("u8");
1652
+ assert(types.lastname).includes("string");
1653
+ }
1654
+ });
1655
+ // alter: add a field
1656
+ $store("schema: alter add", User, async (assert) => {
1657
+ await db.schema.alter("user", {
1658
+ add: { email: "string" }, drop: [], rename: [],
1659
+ });
1660
+ const MigratedUser = store({
1661
+ name: "user",
1662
+ db,
1663
+ schema: {
1664
+ id: key.primary(p.uuid),
1665
+ age: p.u8.optional(),
1666
+ lastname: p.string.optional(),
1667
+ name: p.string.default("Donald"),
1668
+ email: p.string.email(),
1669
+ },
1670
+ });
1671
+ await MigratedUser.insert({ name: "test", age: 1, email: "test@test.com" });
1672
+ const types = await db.schema.introspect("user");
1673
+ assert(types.email).includes("string");
1674
+ });
1675
+ // alter: drop a field
1676
+ $store("schema: alter drop", User, async (assert) => {
1677
+ await db.schema.alter("user", { add: {}, drop: ["lastname"], rename: [] });
1678
+ const types = await db.schema.introspect("user");
1679
+ assert(types.lastname).undefined();
1680
+ });
1681
+ // alter: rename a field
1682
+ $store("schema: alter rename", User, async (assert) => {
1683
+ await db.schema.alter("user", {
1684
+ add: {}, drop: [], rename: [["lastname", "surname"]],
1685
+ });
1686
+ const MigratedUser = store({
1687
+ name: "user",
1688
+ db,
1689
+ schema: {
1690
+ id: key.primary(p.uuid),
1691
+ age: p.u8.optional(),
1692
+ surname: p.string.optional(),
1693
+ name: p.string.default("Donald"),
1694
+ },
1695
+ });
1696
+ await MigratedUser.insert({ name: "Donald", surname: "Adams" });
1697
+ const types = await db.schema.introspect("user");
1698
+ assert(types.lastname).undefined();
1699
+ assert(types.surname).includes("string");
1700
+ });
1701
+ // alter: combined add + drop
1702
+ $store("schema: alter add and drop", User, async (assert) => {
1703
+ await db.schema.alter("user", {
1704
+ add: { email: "string" }, drop: ["lastname"], rename: [],
1705
+ });
1706
+ const MigratedUser = store({
1707
+ name: "user",
1708
+ db,
1709
+ schema: {
1710
+ id: key.primary(p.uuid),
1711
+ age: p.u8.optional(),
1712
+ name: p.string.default("Donald"),
1713
+ email: p.string.email(),
1714
+ },
1715
+ });
1716
+ await MigratedUser.insert({ name: "Donald", email: "test@test.com" });
1717
+ const types = await db.schema.introspect("user");
1718
+ assert(types.email).includes("string");
1719
+ assert(types.lastname).undefined();
1720
+ });
1721
+ const UUIDTest = store({
1722
+ name: "uuid_test",
1723
+ db,
1724
+ schema: {
1725
+ id: key.primary(p.uuid),
1726
+ uuid: p.uuid,
1727
+ uuid_v4: p.uuid.v4(),
1728
+ uuid_v7: p.uuid.v7(),
1729
+ },
1730
+ });
1731
+ $store("uuid: round-trips uuid column", UUIDTest, async (assert) => {
1732
+ const uuid = "4d0996db-bda9-4f95-ad7c-7075b10d4ba6"; // any valid uuid
1733
+ const uuid_v4 = "7c9e6679-7425-40de-944b-e07fc1f90ae7"; // distinct v4
1734
+ const uuid_v7 = "01932b6e-5a2f-7e4f-9a3b-4f6d2c8b1a0e"; // v7
1735
+ const row = await UUIDTest.insert({ uuid, uuid_v4, uuid_v7 });
1736
+ assert(row.uuid).equals(uuid).type();
1737
+ assert(row.uuid_v4).equals(uuid_v4).type();
1738
+ assert(row.uuid_v7).equals(uuid_v7).type();
1739
+ const fetched = await UUIDTest.get(row.id);
1740
+ assert(fetched.uuid).equals(uuid);
1741
+ assert(fetched.uuid_v4).equals(uuid_v4);
1742
+ assert(fetched.uuid_v7).equals(uuid_v7);
1743
+ });
1744
+ test.case("schema: alter non-existent throws", async (assert) => {
1745
+ await throws(assert, Code.table_not_found, () => db.schema.alter("no_such_table", {
1746
+ add: { email: "string" }, drop: [], rename: [],
1747
+ }));
1748
+ });
1383
1749
  };
1384
1750
  //# sourceMappingURL=test.js.map