@snowtop/ent 0.1.0-alpha160-test7 → 0.1.0-alpha160

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 (317) hide show
  1. package/core/query/shared_assoc_test.d.ts +2 -0
  2. package/core/query/shared_assoc_test.js +804 -0
  3. package/core/query/shared_test.d.ts +21 -0
  4. package/core/query/shared_test.js +736 -0
  5. package/graphql/query/shared_assoc_test.d.ts +1 -0
  6. package/graphql/query/shared_assoc_test.js +203 -0
  7. package/package.json +8 -53
  8. package/dist/package.json +0 -64
  9. package/src/action/action.ts +0 -330
  10. package/src/action/executor.ts +0 -453
  11. package/src/action/experimental_action.ts +0 -277
  12. package/src/action/index.ts +0 -31
  13. package/src/action/operations.ts +0 -967
  14. package/src/action/orchestrator.ts +0 -1527
  15. package/src/action/privacy.ts +0 -37
  16. package/src/action/relative_value.ts +0 -242
  17. package/src/action/transaction.ts +0 -38
  18. package/src/auth/auth.ts +0 -77
  19. package/src/auth/index.ts +0 -8
  20. package/src/core/base.ts +0 -367
  21. package/src/core/clause.ts +0 -1065
  22. package/src/core/config.ts +0 -219
  23. package/src/core/const.ts +0 -5
  24. package/src/core/context.ts +0 -135
  25. package/src/core/convert.ts +0 -106
  26. package/src/core/date.ts +0 -23
  27. package/src/core/db.ts +0 -498
  28. package/src/core/ent.ts +0 -1740
  29. package/src/core/global_schema.ts +0 -49
  30. package/src/core/loaders/assoc_count_loader.ts +0 -99
  31. package/src/core/loaders/assoc_edge_loader.ts +0 -250
  32. package/src/core/loaders/index.ts +0 -12
  33. package/src/core/loaders/loader.ts +0 -66
  34. package/src/core/loaders/object_loader.ts +0 -489
  35. package/src/core/loaders/query_loader.ts +0 -314
  36. package/src/core/loaders/raw_count_loader.ts +0 -175
  37. package/src/core/logger.ts +0 -49
  38. package/src/core/privacy.ts +0 -660
  39. package/src/core/query/assoc_query.ts +0 -240
  40. package/src/core/query/custom_clause_query.ts +0 -174
  41. package/src/core/query/custom_query.ts +0 -302
  42. package/src/core/query/index.ts +0 -9
  43. package/src/core/query/query.ts +0 -674
  44. package/src/core/query_impl.ts +0 -32
  45. package/src/core/viewer.ts +0 -52
  46. package/src/ent.code-workspace +0 -73
  47. package/src/graphql/builtins/connection.ts +0 -25
  48. package/src/graphql/builtins/edge.ts +0 -16
  49. package/src/graphql/builtins/node.ts +0 -12
  50. package/src/graphql/graphql.ts +0 -891
  51. package/src/graphql/graphql_field_helpers.ts +0 -221
  52. package/src/graphql/index.ts +0 -42
  53. package/src/graphql/mutations/union.ts +0 -39
  54. package/src/graphql/node_resolver.ts +0 -122
  55. package/src/graphql/query/connection_type.ts +0 -113
  56. package/src/graphql/query/edge_connection.ts +0 -171
  57. package/src/graphql/query/page_info.ts +0 -34
  58. package/src/graphql/query/shared_edge_connection.ts +0 -287
  59. package/src/graphql/scalars/orderby_direction.ts +0 -13
  60. package/src/graphql/scalars/time.ts +0 -38
  61. package/src/imports/dataz/example1/_auth.ts +0 -51
  62. package/src/imports/dataz/example1/_viewer.ts +0 -35
  63. package/src/imports/index.ts +0 -213
  64. package/src/index.ts +0 -145
  65. package/src/parse_schema/parse.ts +0 -585
  66. package/src/schema/base_schema.ts +0 -224
  67. package/src/schema/field.ts +0 -1087
  68. package/src/schema/index.ts +0 -53
  69. package/src/schema/json_field.ts +0 -94
  70. package/src/schema/schema.ts +0 -1028
  71. package/src/schema/struct_field.ts +0 -234
  72. package/src/schema/union_field.ts +0 -105
  73. package/src/scripts/custom_compiler.ts +0 -331
  74. package/src/scripts/custom_graphql.ts +0 -550
  75. package/src/scripts/migrate_v0.1.ts +0 -41
  76. package/src/scripts/move_types.ts +0 -131
  77. package/src/scripts/read_schema.ts +0 -67
  78. package/src/setupPackage.js +0 -42
  79. package/src/testutils/action/complex_schemas.ts +0 -517
  80. package/src/testutils/builder.ts +0 -422
  81. package/src/testutils/context/test_context.ts +0 -25
  82. package/src/testutils/db/fixture.ts +0 -32
  83. package/src/testutils/db/temp_db.ts +0 -941
  84. package/src/testutils/db/value.ts +0 -294
  85. package/src/testutils/db_mock.ts +0 -351
  86. package/src/testutils/db_time_zone.ts +0 -40
  87. package/src/testutils/ent-graphql-tests/index.ts +0 -653
  88. package/src/testutils/fake_comms.ts +0 -50
  89. package/src/testutils/fake_data/const.ts +0 -64
  90. package/src/testutils/fake_data/events_query.ts +0 -145
  91. package/src/testutils/fake_data/fake_contact.ts +0 -150
  92. package/src/testutils/fake_data/fake_event.ts +0 -150
  93. package/src/testutils/fake_data/fake_tag.ts +0 -139
  94. package/src/testutils/fake_data/fake_user.ts +0 -232
  95. package/src/testutils/fake_data/index.ts +0 -1
  96. package/src/testutils/fake_data/internal.ts +0 -8
  97. package/src/testutils/fake_data/tag_query.ts +0 -56
  98. package/src/testutils/fake_data/test_helpers.ts +0 -388
  99. package/src/testutils/fake_data/user_query.ts +0 -524
  100. package/src/testutils/fake_log.ts +0 -52
  101. package/src/testutils/mock_date.ts +0 -10
  102. package/src/testutils/mock_log.ts +0 -39
  103. package/src/testutils/parse_sql.ts +0 -685
  104. package/src/testutils/test_edge_global_schema.ts +0 -49
  105. package/src/testutils/write.ts +0 -70
  106. package/src/tsc/ast.ts +0 -351
  107. package/src/tsc/compilerOptions.ts +0 -85
  108. package/src/tsc/move_generated.ts +0 -191
  109. package/src/tsc/transform.ts +0 -226
  110. package/src/tsc/transform_action.ts +0 -224
  111. package/src/tsc/transform_ent.ts +0 -66
  112. package/src/tsc/transform_schema.ts +0 -546
  113. package/tsconfig.json +0 -20
  114. /package/{dist/action → action}/action.d.ts +0 -0
  115. /package/{dist/action → action}/action.js +0 -0
  116. /package/{dist/action → action}/executor.d.ts +0 -0
  117. /package/{dist/action → action}/executor.js +0 -0
  118. /package/{dist/action → action}/experimental_action.d.ts +0 -0
  119. /package/{dist/action → action}/experimental_action.js +0 -0
  120. /package/{dist/action → action}/index.d.ts +0 -0
  121. /package/{dist/action → action}/index.js +0 -0
  122. /package/{dist/action → action}/operations.d.ts +0 -0
  123. /package/{dist/action → action}/operations.js +0 -0
  124. /package/{dist/action → action}/orchestrator.d.ts +0 -0
  125. /package/{dist/action → action}/orchestrator.js +0 -0
  126. /package/{dist/action → action}/privacy.d.ts +0 -0
  127. /package/{dist/action → action}/privacy.js +0 -0
  128. /package/{dist/action → action}/relative_value.d.ts +0 -0
  129. /package/{dist/action → action}/relative_value.js +0 -0
  130. /package/{dist/action → action}/transaction.d.ts +0 -0
  131. /package/{dist/action → action}/transaction.js +0 -0
  132. /package/{dist/auth → auth}/auth.d.ts +0 -0
  133. /package/{dist/auth → auth}/auth.js +0 -0
  134. /package/{dist/auth → auth}/index.d.ts +0 -0
  135. /package/{dist/auth → auth}/index.js +0 -0
  136. /package/{dist/core → core}/base.d.ts +0 -0
  137. /package/{dist/core → core}/base.js +0 -0
  138. /package/{dist/core → core}/clause.d.ts +0 -0
  139. /package/{dist/core → core}/clause.js +0 -0
  140. /package/{dist/core → core}/config.d.ts +0 -0
  141. /package/{dist/core → core}/config.js +0 -0
  142. /package/{dist/core → core}/const.d.ts +0 -0
  143. /package/{dist/core → core}/const.js +0 -0
  144. /package/{dist/core → core}/context.d.ts +0 -0
  145. /package/{dist/core → core}/context.js +0 -0
  146. /package/{dist/core → core}/convert.d.ts +0 -0
  147. /package/{dist/core → core}/convert.js +0 -0
  148. /package/{dist/core → core}/date.d.ts +0 -0
  149. /package/{dist/core → core}/date.js +0 -0
  150. /package/{dist/core → core}/db.d.ts +0 -0
  151. /package/{dist/core → core}/db.js +0 -0
  152. /package/{dist/core → core}/ent.d.ts +0 -0
  153. /package/{dist/core → core}/ent.js +0 -0
  154. /package/{dist/core → core}/global_schema.d.ts +0 -0
  155. /package/{dist/core → core}/global_schema.js +0 -0
  156. /package/{dist/core → core}/loaders/assoc_count_loader.d.ts +0 -0
  157. /package/{dist/core → core}/loaders/assoc_count_loader.js +0 -0
  158. /package/{dist/core → core}/loaders/assoc_edge_loader.d.ts +0 -0
  159. /package/{dist/core → core}/loaders/assoc_edge_loader.js +0 -0
  160. /package/{dist/core → core}/loaders/index.d.ts +0 -0
  161. /package/{dist/core → core}/loaders/index.js +0 -0
  162. /package/{dist/core → core}/loaders/loader.d.ts +0 -0
  163. /package/{dist/core → core}/loaders/loader.js +0 -0
  164. /package/{dist/core → core}/loaders/object_loader.d.ts +0 -0
  165. /package/{dist/core → core}/loaders/object_loader.js +0 -0
  166. /package/{dist/core → core}/loaders/query_loader.d.ts +0 -0
  167. /package/{dist/core → core}/loaders/query_loader.js +0 -0
  168. /package/{dist/core → core}/loaders/raw_count_loader.d.ts +0 -0
  169. /package/{dist/core → core}/loaders/raw_count_loader.js +0 -0
  170. /package/{dist/core → core}/logger.d.ts +0 -0
  171. /package/{dist/core → core}/logger.js +0 -0
  172. /package/{dist/core → core}/privacy.d.ts +0 -0
  173. /package/{dist/core → core}/privacy.js +0 -0
  174. /package/{dist/core → core}/query/assoc_query.d.ts +0 -0
  175. /package/{dist/core → core}/query/assoc_query.js +0 -0
  176. /package/{dist/core → core}/query/custom_clause_query.d.ts +0 -0
  177. /package/{dist/core → core}/query/custom_clause_query.js +0 -0
  178. /package/{dist/core → core}/query/custom_query.d.ts +0 -0
  179. /package/{dist/core → core}/query/custom_query.js +0 -0
  180. /package/{dist/core → core}/query/index.d.ts +0 -0
  181. /package/{dist/core → core}/query/index.js +0 -0
  182. /package/{dist/core → core}/query/query.d.ts +0 -0
  183. /package/{dist/core → core}/query/query.js +0 -0
  184. /package/{dist/core → core}/query_impl.d.ts +0 -0
  185. /package/{dist/core → core}/query_impl.js +0 -0
  186. /package/{dist/core → core}/viewer.d.ts +0 -0
  187. /package/{dist/core → core}/viewer.js +0 -0
  188. /package/{dist/graphql → graphql}/builtins/connection.d.ts +0 -0
  189. /package/{dist/graphql → graphql}/builtins/connection.js +0 -0
  190. /package/{dist/graphql → graphql}/builtins/edge.d.ts +0 -0
  191. /package/{dist/graphql → graphql}/builtins/edge.js +0 -0
  192. /package/{dist/graphql → graphql}/builtins/node.d.ts +0 -0
  193. /package/{dist/graphql → graphql}/builtins/node.js +0 -0
  194. /package/{dist/graphql → graphql}/graphql.d.ts +0 -0
  195. /package/{dist/graphql → graphql}/graphql.js +0 -0
  196. /package/{dist/graphql → graphql}/graphql_field_helpers.d.ts +0 -0
  197. /package/{dist/graphql → graphql}/graphql_field_helpers.js +0 -0
  198. /package/{dist/graphql → graphql}/index.d.ts +0 -0
  199. /package/{dist/graphql → graphql}/index.js +0 -0
  200. /package/{dist/graphql → graphql}/mutations/union.d.ts +0 -0
  201. /package/{dist/graphql → graphql}/mutations/union.js +0 -0
  202. /package/{dist/graphql → graphql}/node_resolver.d.ts +0 -0
  203. /package/{dist/graphql → graphql}/node_resolver.js +0 -0
  204. /package/{dist/graphql → graphql}/query/connection_type.d.ts +0 -0
  205. /package/{dist/graphql → graphql}/query/connection_type.js +0 -0
  206. /package/{dist/graphql → graphql}/query/edge_connection.d.ts +0 -0
  207. /package/{dist/graphql → graphql}/query/edge_connection.js +0 -0
  208. /package/{dist/graphql → graphql}/query/page_info.d.ts +0 -0
  209. /package/{dist/graphql → graphql}/query/page_info.js +0 -0
  210. /package/{dist/graphql → graphql}/query/shared_edge_connection.d.ts +0 -0
  211. /package/{dist/graphql → graphql}/query/shared_edge_connection.js +0 -0
  212. /package/{dist/graphql → graphql}/scalars/orderby_direction.d.ts +0 -0
  213. /package/{dist/graphql → graphql}/scalars/orderby_direction.js +0 -0
  214. /package/{dist/graphql → graphql}/scalars/time.d.ts +0 -0
  215. /package/{dist/graphql → graphql}/scalars/time.js +0 -0
  216. /package/{dist/imports → imports}/dataz/example1/_auth.d.ts +0 -0
  217. /package/{dist/imports → imports}/dataz/example1/_auth.js +0 -0
  218. /package/{dist/imports → imports}/dataz/example1/_viewer.d.ts +0 -0
  219. /package/{dist/imports → imports}/dataz/example1/_viewer.js +0 -0
  220. /package/{dist/imports → imports}/index.d.ts +0 -0
  221. /package/{dist/imports → imports}/index.js +0 -0
  222. /package/{dist/index.d.ts → index.d.ts} +0 -0
  223. /package/{dist/index.js → index.js} +0 -0
  224. /package/{dist/parse_schema → parse_schema}/parse.d.ts +0 -0
  225. /package/{dist/parse_schema → parse_schema}/parse.js +0 -0
  226. /package/{dist/schema → schema}/base_schema.d.ts +0 -0
  227. /package/{dist/schema → schema}/base_schema.js +0 -0
  228. /package/{dist/schema → schema}/field.d.ts +0 -0
  229. /package/{dist/schema → schema}/field.js +0 -0
  230. /package/{dist/schema → schema}/index.d.ts +0 -0
  231. /package/{dist/schema → schema}/index.js +0 -0
  232. /package/{dist/schema → schema}/json_field.d.ts +0 -0
  233. /package/{dist/schema → schema}/json_field.js +0 -0
  234. /package/{dist/schema → schema}/schema.d.ts +0 -0
  235. /package/{dist/schema → schema}/schema.js +0 -0
  236. /package/{dist/schema → schema}/struct_field.d.ts +0 -0
  237. /package/{dist/schema → schema}/struct_field.js +0 -0
  238. /package/{dist/schema → schema}/union_field.d.ts +0 -0
  239. /package/{dist/schema → schema}/union_field.js +0 -0
  240. /package/{dist/scripts → scripts}/custom_compiler.d.ts +0 -0
  241. /package/{dist/scripts → scripts}/custom_compiler.js +0 -0
  242. /package/{dist/scripts → scripts}/custom_graphql.d.ts +0 -0
  243. /package/{dist/scripts → scripts}/custom_graphql.js +0 -0
  244. /package/{dist/scripts → scripts}/migrate_v0.1.d.ts +0 -0
  245. /package/{dist/scripts → scripts}/migrate_v0.1.js +0 -0
  246. /package/{dist/scripts → scripts}/move_types.d.ts +0 -0
  247. /package/{dist/scripts → scripts}/move_types.js +0 -0
  248. /package/{dist/scripts → scripts}/read_schema.d.ts +0 -0
  249. /package/{dist/scripts → scripts}/read_schema.js +0 -0
  250. /package/{dist/testutils → testutils}/action/complex_schemas.d.ts +0 -0
  251. /package/{dist/testutils → testutils}/action/complex_schemas.js +0 -0
  252. /package/{dist/testutils → testutils}/builder.d.ts +0 -0
  253. /package/{dist/testutils → testutils}/builder.js +0 -0
  254. /package/{dist/testutils → testutils}/context/test_context.d.ts +0 -0
  255. /package/{dist/testutils → testutils}/context/test_context.js +0 -0
  256. /package/{dist/testutils → testutils}/db/fixture.d.ts +0 -0
  257. /package/{dist/testutils → testutils}/db/fixture.js +0 -0
  258. /package/{dist/testutils → testutils}/db/temp_db.d.ts +0 -0
  259. /package/{dist/testutils → testutils}/db/temp_db.js +0 -0
  260. /package/{dist/testutils → testutils}/db/value.d.ts +0 -0
  261. /package/{dist/testutils → testutils}/db/value.js +0 -0
  262. /package/{dist/testutils → testutils}/db_mock.d.ts +0 -0
  263. /package/{dist/testutils → testutils}/db_mock.js +0 -0
  264. /package/{dist/testutils → testutils}/db_time_zone.d.ts +0 -0
  265. /package/{dist/testutils → testutils}/db_time_zone.js +0 -0
  266. /package/{dist/testutils → testutils}/ent-graphql-tests/index.d.ts +0 -0
  267. /package/{dist/testutils → testutils}/ent-graphql-tests/index.js +0 -0
  268. /package/{dist/testutils → testutils}/fake_comms.d.ts +0 -0
  269. /package/{dist/testutils → testutils}/fake_comms.js +0 -0
  270. /package/{dist/testutils → testutils}/fake_data/const.d.ts +0 -0
  271. /package/{dist/testutils → testutils}/fake_data/const.js +0 -0
  272. /package/{dist/testutils → testutils}/fake_data/events_query.d.ts +0 -0
  273. /package/{dist/testutils → testutils}/fake_data/events_query.js +0 -0
  274. /package/{dist/testutils → testutils}/fake_data/fake_contact.d.ts +0 -0
  275. /package/{dist/testutils → testutils}/fake_data/fake_contact.js +0 -0
  276. /package/{dist/testutils → testutils}/fake_data/fake_event.d.ts +0 -0
  277. /package/{dist/testutils → testutils}/fake_data/fake_event.js +0 -0
  278. /package/{dist/testutils → testutils}/fake_data/fake_tag.d.ts +0 -0
  279. /package/{dist/testutils → testutils}/fake_data/fake_tag.js +0 -0
  280. /package/{dist/testutils → testutils}/fake_data/fake_user.d.ts +0 -0
  281. /package/{dist/testutils → testutils}/fake_data/fake_user.js +0 -0
  282. /package/{dist/testutils → testutils}/fake_data/index.d.ts +0 -0
  283. /package/{dist/testutils → testutils}/fake_data/index.js +0 -0
  284. /package/{dist/testutils → testutils}/fake_data/internal.d.ts +0 -0
  285. /package/{dist/testutils → testutils}/fake_data/internal.js +0 -0
  286. /package/{dist/testutils → testutils}/fake_data/tag_query.d.ts +0 -0
  287. /package/{dist/testutils → testutils}/fake_data/tag_query.js +0 -0
  288. /package/{dist/testutils → testutils}/fake_data/test_helpers.d.ts +0 -0
  289. /package/{dist/testutils → testutils}/fake_data/test_helpers.js +0 -0
  290. /package/{dist/testutils → testutils}/fake_data/user_query.d.ts +0 -0
  291. /package/{dist/testutils → testutils}/fake_data/user_query.js +0 -0
  292. /package/{dist/testutils → testutils}/fake_log.d.ts +0 -0
  293. /package/{dist/testutils → testutils}/fake_log.js +0 -0
  294. /package/{dist/testutils → testutils}/mock_date.d.ts +0 -0
  295. /package/{dist/testutils → testutils}/mock_date.js +0 -0
  296. /package/{dist/testutils → testutils}/mock_log.d.ts +0 -0
  297. /package/{dist/testutils → testutils}/mock_log.js +0 -0
  298. /package/{dist/testutils → testutils}/parse_sql.d.ts +0 -0
  299. /package/{dist/testutils → testutils}/parse_sql.js +0 -0
  300. /package/{dist/testutils → testutils}/test_edge_global_schema.d.ts +0 -0
  301. /package/{dist/testutils → testutils}/test_edge_global_schema.js +0 -0
  302. /package/{dist/testutils → testutils}/write.d.ts +0 -0
  303. /package/{dist/testutils → testutils}/write.js +0 -0
  304. /package/{dist/tsc → tsc}/ast.d.ts +0 -0
  305. /package/{dist/tsc → tsc}/ast.js +0 -0
  306. /package/{dist/tsc → tsc}/compilerOptions.d.ts +0 -0
  307. /package/{dist/tsc → tsc}/compilerOptions.js +0 -0
  308. /package/{dist/tsc → tsc}/move_generated.d.ts +0 -0
  309. /package/{dist/tsc → tsc}/move_generated.js +0 -0
  310. /package/{dist/tsc → tsc}/transform.d.ts +0 -0
  311. /package/{dist/tsc → tsc}/transform.js +0 -0
  312. /package/{dist/tsc → tsc}/transform_action.d.ts +0 -0
  313. /package/{dist/tsc → tsc}/transform_action.js +0 -0
  314. /package/{dist/tsc → tsc}/transform_ent.d.ts +0 -0
  315. /package/{dist/tsc → tsc}/transform_ent.js +0 -0
  316. /package/{dist/tsc → tsc}/transform_schema.d.ts +0 -0
  317. /package/{dist/tsc → tsc}/transform_schema.js +0 -0
@@ -1,967 +0,0 @@
1
- import { Queryer, SyncQueryer } from "../core/db";
2
- import {
3
- Viewer,
4
- Ent,
5
- ID,
6
- Data,
7
- DataOptions,
8
- EditRowOptions,
9
- LoadEntOptions,
10
- Context,
11
- CreateRowOptions,
12
- } from "../core/base";
13
- import { Executor } from "../action/action";
14
- import * as clause from "../core/clause";
15
- import { WriteOperation, Builder } from "../action";
16
- import { ObjectLoader } from "../core/loaders";
17
- import {
18
- getStorageKey,
19
- SQLStatementOperation,
20
- TransformedEdgeUpdateOperation,
21
- } from "../schema/schema";
22
- import { __getGlobalSchema } from "../core/global_schema";
23
- import {
24
- AssocEdgeData,
25
- buildQuery,
26
- createRow,
27
- createRowSync,
28
- deleteRows,
29
- deleteRowsSync,
30
- editRow,
31
- editRowSync,
32
- loadEdgeData,
33
- logQuery,
34
- parameterizedQueryOptions,
35
- } from "../core/ent";
36
-
37
- export interface UpdatedOperation {
38
- operation: WriteOperation;
39
- builder: Builder<any>;
40
- }
41
-
42
- // PS: anytime this is updated, need to update ConditionalOperation
43
- export interface DataOperation<T extends Ent = Ent> {
44
- // builder associated with the operation
45
- builder: Builder<T>;
46
- // any data that needs to be fetched before the write should be fetched here
47
- // because of how SQLite works, we can't use asynchronous fetches during the write
48
- // so we batch up fetching to be done beforehand here
49
- preFetch?(queryer: Queryer, context?: Context): Promise<void>;
50
-
51
- // performWriteSync is called for SQLITE and APIs that don't support asynchronous writes
52
- performWriteSync(queryer: SyncQueryer, context?: Context): void;
53
- performWrite(queryer: Queryer, context?: Context): Promise<void>;
54
-
55
- placeholderID?: ID;
56
- returnedRow?(): Data | null; // optional to get the raw row
57
- createdEnt?(viewer: Viewer): T | null; // optional to indicate the ent that was created
58
-
59
- // optional to indicate that the operation should not be performed. used for conditional changesets/operations
60
- shortCircuit?(executor: Executor): boolean;
61
- updatedOperation?(): UpdatedOperation | null;
62
- resolve?(executor: Executor): void; //throws?
63
-
64
- // any data that needs to be fetched asynchronously post write|post transaction
65
- postFetch?(queryer: Queryer, context?: Context): Promise<void>;
66
- }
67
-
68
- export class DeleteNodeOperation implements DataOperation {
69
- constructor(
70
- private id: ID,
71
- public readonly builder: Builder<Ent>,
72
- private options: DataOptions,
73
- ) {}
74
-
75
- async performWrite(queryer: Queryer, context?: Context): Promise<void> {
76
- let options = {
77
- ...this.options,
78
- context,
79
- };
80
- return deleteRows(queryer, options, clause.Eq("id", this.id));
81
- }
82
-
83
- performWriteSync(queryer: SyncQueryer, context?: Context): void {
84
- let options = {
85
- ...this.options,
86
- context,
87
- };
88
- return deleteRowsSync(queryer, options, clause.Eq("id", this.id));
89
- }
90
- }
91
-
92
- export class RawQueryOperation<
93
- TEnt extends Ent<TViewer>,
94
- TViewer extends Viewer = Viewer,
95
- > implements DataOperation<TEnt>
96
- {
97
- constructor(
98
- public builder: Builder<TEnt, TViewer>,
99
- private queries: (string | parameterizedQueryOptions)[],
100
- ) {}
101
-
102
- async performWrite(queryer: Queryer, context?: Context): Promise<void> {
103
- for (const q of this.queries) {
104
- if (typeof q === "string") {
105
- logQuery(q, []);
106
- await queryer.query(q);
107
- } else {
108
- logQuery(q.query, q.logValues || []);
109
- await queryer.query(q.query, q.values);
110
- }
111
- }
112
- }
113
-
114
- performWriteSync(queryer: SyncQueryer, context?: Context): void {
115
- for (const q of this.queries) {
116
- if (typeof q === "string") {
117
- logQuery(q, []);
118
- queryer.execSync(q);
119
- } else {
120
- logQuery(q.query, q.logValues || []);
121
- queryer.execSync(q.query, q.values);
122
- }
123
- }
124
- }
125
- }
126
-
127
- export interface EditNodeOptions<T extends Ent> extends EditRowOptions {
128
- fieldsToResolve: string[];
129
- loadEntOptions: LoadEntOptions<T>;
130
- key: string;
131
- onConflict?: CreateRowOptions["onConflict"];
132
- builder: Builder<T>;
133
- }
134
-
135
- export class EditNodeOperation<T extends Ent> implements DataOperation {
136
- private row: Data | null = null;
137
- placeholderID?: ID | undefined;
138
- private updatedOp: UpdatedOperation | null = null;
139
- public builder: Builder<T>;
140
- private resolved = false;
141
-
142
- constructor(
143
- public options: EditNodeOptions<T>,
144
- private existingEnt: Ent | null = null,
145
- ) {
146
- this.builder = options.builder;
147
- this.placeholderID = options.builder.placeholderID;
148
- }
149
-
150
- resolve<T extends Ent>(executor: Executor): void {
151
- if (!this.options.fieldsToResolve.length) {
152
- return;
153
- }
154
-
155
- if (this.resolved) {
156
- throw new Error(`already resolved ${this.placeholderID}`);
157
- }
158
-
159
- let fields = this.options.fields;
160
- this.options.fieldsToResolve.forEach((fieldName) => {
161
- let value: Builder<T> | null = fields[fieldName];
162
- if (!value) {
163
- throw new Error(
164
- `trying to resolve field ${fieldName} but not a valid field`,
165
- );
166
- }
167
- let ent = executor.resolveValue(value.placeholderID);
168
- if (!ent) {
169
- throw new Error(
170
- `couldn't resolve field \`${fieldName}\` with value ${value.placeholderID}`,
171
- );
172
- }
173
- fields[fieldName] = ent.id;
174
- });
175
- this.options.fields = fields;
176
- this.resolved = true;
177
- }
178
-
179
- private hasData(data: Data) {
180
- for (const _k in data) {
181
- return true;
182
- }
183
- return false;
184
- }
185
-
186
- private buildOnConflictQuery(options: EditNodeOptions<T>) {
187
- // assumes onConflict has been checked already...
188
- const clauses: clause.Clause[] = [];
189
- for (const col of this.options.onConflict!.onConflictCols) {
190
- clauses.push(clause.Eq(col, options.fields[col]));
191
- }
192
- const cls = clause.AndOptional(...clauses);
193
- const query = this.buildReloadQuery(options, cls);
194
- return { cls, query };
195
- }
196
-
197
- async performWrite(queryer: Queryer, context?: Context) {
198
- let options = {
199
- ...this.options,
200
- context,
201
- };
202
- if (this.existingEnt) {
203
- if (this.hasData(options.fields)) {
204
- // even this with returning * may not always work if transformed...
205
- // we can have a transformed flag to see if it should be returned?
206
- this.row = await editRow(queryer, options, "RETURNING *");
207
- } else {
208
- // @ts-ignore
209
- this.row = this.existingEnt["data"];
210
- }
211
- } else {
212
- // TODO: eventually, when we officially support auto-increment ids. need to make sure/test that this works
213
- // https://github.com/lolopinto/ent/issues/1431
214
-
215
- this.row = await createRow(queryer, options, "RETURNING *");
216
- const key = this.options.key;
217
-
218
- if (this.row && this.row[key] !== this.options.fields[key]) {
219
- this.updatedOp = {
220
- builder: this.options.builder,
221
- operation: WriteOperation.Edit,
222
- };
223
- }
224
- if (
225
- this.row === null &&
226
- this.options.onConflict &&
227
- !this.options.onConflict.updateCols?.length
228
- ) {
229
- // no row returned and on conflict, do nothing, have to fetch the conflict row back...
230
- const { cls, query } = this.buildOnConflictQuery(options);
231
-
232
- logQuery(query, cls.logValues());
233
- const res = await queryer.query(query, cls.values());
234
- this.row = res.rows[0];
235
- this.updatedOp = {
236
- builder: this.options.builder,
237
- operation: WriteOperation.Edit,
238
- };
239
- }
240
- }
241
- }
242
-
243
- private buildReloadQuery(options: EditNodeOptions<T>, cls: clause.Clause) {
244
- // TODO this isn't always an ObjectLoader. should throw or figure out a way to get query
245
- // and run this on its own...
246
- const loader = this.options.loadEntOptions.loaderFactory.createLoader(
247
- options.context,
248
- ) as ObjectLoader<T>;
249
- const opts = loader.getOptions();
250
- if (opts.clause) {
251
- let optionClause: clause.Clause | undefined;
252
- if (typeof opts.clause === "function") {
253
- optionClause = opts.clause();
254
- } else {
255
- optionClause = opts.clause;
256
- }
257
- if (optionClause) {
258
- cls = clause.And(cls, optionClause);
259
- }
260
- }
261
-
262
- const query = buildQuery({
263
- fields: opts.fields.length ? opts.fields : ["*"],
264
- tableName: options.tableName,
265
- clause: cls,
266
- });
267
- return query;
268
- }
269
-
270
- private reloadRow(queryer: SyncQueryer, id: ID, options: EditNodeOptions<T>) {
271
- const query = this.buildReloadQuery(options, clause.Eq(options.key, id));
272
-
273
- // special case log here because we're not going through any of the normal
274
- // methods here because those are async and this is sync
275
- // this is the only place we're doing this so only handling here
276
- logQuery(query, [id]);
277
- const r = queryer.querySync(query, [id]);
278
- if (r.rows.length === 1) {
279
- this.row = r.rows[0];
280
- }
281
- }
282
-
283
- performWriteSync(queryer: SyncQueryer, context?: Context): void {
284
- let options = {
285
- ...this.options,
286
- context,
287
- };
288
-
289
- if (this.existingEnt) {
290
- if (this.hasData(this.options.fields)) {
291
- editRowSync(queryer, options, "RETURNING *");
292
- this.reloadRow(queryer, this.existingEnt.id, options);
293
- } else {
294
- // @ts-ignore
295
- this.row = this.existingEnt["data"];
296
- }
297
- } else {
298
- createRowSync(queryer, options, "RETURNING *");
299
- const id = options.fields[options.key];
300
- this.reloadRow(queryer, id, options);
301
- const key = this.options.key;
302
-
303
- if (this.row && this.row[key] !== this.options.fields[key]) {
304
- this.updatedOp = {
305
- builder: this.options.builder,
306
- operation: WriteOperation.Edit,
307
- };
308
- }
309
- // if we can't find the id, try and load the on conflict row
310
- // no returning * with sqlite and have to assume the row was created more often than not
311
-
312
- // there's a world in which we combine into one query if on-conflict
313
- // seems like it's safer not to and sqlite (only sync client we currently have) is fast enough
314
- // (single-process) that it's fine to do two queries
315
-
316
- // we wanna do this in both on conflict do nothing or on conflict update
317
- if (this.row === null && this.options.onConflict) {
318
- const { cls, query } = this.buildOnConflictQuery(options);
319
-
320
- // special case log here because we're not going through any of the normal
321
- // methods here because those are async and this is sync
322
- // this is the only place we're doing this so only handling here
323
- logQuery(query, cls.logValues());
324
- const r = queryer.querySync(query, cls.values());
325
- if (r.rows.length === 1) {
326
- this.row = r.rows[0];
327
- }
328
- this.updatedOp = {
329
- builder: this.options.builder,
330
- operation: WriteOperation.Edit,
331
- };
332
- }
333
- }
334
- }
335
-
336
- returnedRow(): Data | null {
337
- return this.row;
338
- }
339
-
340
- createdEnt(viewer: Viewer): T | null {
341
- if (!this.row) {
342
- return null;
343
- }
344
- return new this.options.loadEntOptions.ent(viewer, this.row);
345
- }
346
-
347
- updatedOperation(): UpdatedOperation | null {
348
- return this.updatedOp;
349
- }
350
- }
351
-
352
- interface EdgeOperationOptions {
353
- operation: WriteOperation;
354
- id1Placeholder?: boolean;
355
- id2Placeholder?: boolean;
356
- dataPlaceholder?: boolean;
357
- }
358
-
359
- export interface AssocEdgeInputOptions extends AssocEdgeOptions {
360
- time?: Date;
361
- data?: string | Builder<Ent>;
362
- }
363
-
364
- export interface AssocEdgeOptions {
365
- // if passed. indicates that it's conditional on the current builder's operator not changing
366
- // e.g. if an upsert is being done, and the builder changes from insert to update,
367
- // then the edge write should not be done if this is true
368
- conditional?: boolean;
369
-
370
- // if passed and we have global tranformWrite options on edges, it disables the tranformations
371
- // e.g. if we have edge soft delete enabled, this exists to delete the edge without soft deleting
372
- disableTransformations?: boolean;
373
- }
374
-
375
- export interface AssocEdgeInput extends AssocEdgeInputOptions {
376
- id1: ID;
377
- id1Type: string;
378
- edgeType: string;
379
- id2: ID;
380
- id2Type: string;
381
- }
382
-
383
- export class EdgeOperation implements DataOperation {
384
- private edgeData: AssocEdgeData | undefined;
385
- private constructor(
386
- public builder: Builder<any>,
387
- public edgeInput: AssocEdgeInput,
388
- private options: EdgeOperationOptions,
389
- ) {}
390
-
391
- async preFetch(queryer: Queryer, context?: Context): Promise<void> {
392
- let edgeData = await loadEdgeData(this.edgeInput.edgeType);
393
- if (!edgeData) {
394
- throw new Error(`error loading edge data for ${this.edgeInput.edgeType}`);
395
- }
396
- this.edgeData = edgeData;
397
- }
398
-
399
- async performWrite(queryer: Queryer, context?: Context): Promise<void> {
400
- if (!this.edgeData) {
401
- throw new Error(
402
- `error fetching edgeData for type ${this.edgeInput.edgeType}`,
403
- );
404
- }
405
- switch (this.options.operation) {
406
- case WriteOperation.Delete:
407
- return this.performDeleteWrite(
408
- queryer,
409
- this.edgeData,
410
- this.edgeInput,
411
- context,
412
- );
413
- case WriteOperation.Insert:
414
- case WriteOperation.Edit:
415
- return this.performInsertWrite(
416
- queryer,
417
- this.edgeData,
418
- this.edgeInput,
419
- context,
420
- );
421
- }
422
- }
423
-
424
- performWriteSync(queryer: SyncQueryer, context?: Context): void {
425
- if (!this.edgeData) {
426
- throw new Error(
427
- `error fetching edgeData for type ${this.edgeInput.edgeType}`,
428
- );
429
- }
430
- switch (this.options.operation) {
431
- case WriteOperation.Delete:
432
- return this.performDeleteWriteSync(
433
- queryer,
434
- this.edgeData,
435
- this.edgeInput,
436
- context,
437
- );
438
- case WriteOperation.Insert:
439
- case WriteOperation.Edit:
440
- return this.performInsertWriteSync(
441
- queryer,
442
- this.edgeData,
443
- this.edgeInput,
444
- context,
445
- );
446
- }
447
- }
448
-
449
- private getDeleteRowParams(
450
- edgeData: AssocEdgeData,
451
- edge: AssocEdgeInput,
452
- context?: Context,
453
- ) {
454
- let transformed: TransformedEdgeUpdateOperation | null = null;
455
- let op = SQLStatementOperation.Delete;
456
- let updateData: Data | null = null;
457
-
458
- const transformedEdgeWrite = __getGlobalSchema()?.transformEdgeWrite;
459
- if (transformedEdgeWrite && !edge.disableTransformations) {
460
- transformed = transformedEdgeWrite({
461
- op: SQLStatementOperation.Delete,
462
- edge,
463
- });
464
- if (transformed) {
465
- op = transformed.op;
466
- if (transformed.op === SQLStatementOperation.Insert) {
467
- throw new Error(`cannot currently transform a delete into an insert`);
468
- }
469
- if (transformed.op === SQLStatementOperation.Update) {
470
- if (!transformed.data) {
471
- throw new Error(
472
- `cannot transform a delete into an update without providing data`,
473
- );
474
- }
475
- updateData = transformed.data;
476
- }
477
- }
478
- }
479
-
480
- return {
481
- op,
482
- updateData,
483
- options: {
484
- tableName: edgeData.edgeTable,
485
- context,
486
- },
487
- clause: clause.And(
488
- clause.Eq("id1", edge.id1),
489
- clause.Eq("id2", edge.id2),
490
- clause.Eq("edge_type", edge.edgeType),
491
- ),
492
- };
493
- }
494
-
495
- private async performDeleteWrite(
496
- q: Queryer,
497
- edgeData: AssocEdgeData,
498
- edge: AssocEdgeInput,
499
- context?: Context,
500
- ): Promise<void> {
501
- const params = this.getDeleteRowParams(edgeData, edge, context);
502
- if (params.op === SQLStatementOperation.Delete) {
503
- return deleteRows(q, params.options, params.clause);
504
- } else {
505
- if (params.op !== SQLStatementOperation.Update) {
506
- throw new Error(`invalid operation ${params.op}`);
507
- }
508
- await editRow(q, {
509
- tableName: params.options.tableName,
510
- whereClause: params.clause,
511
- fields: params.updateData!,
512
- fieldsToLog: params.updateData!,
513
- });
514
- }
515
- }
516
-
517
- private performDeleteWriteSync(
518
- q: SyncQueryer,
519
- edgeData: AssocEdgeData,
520
- edge: AssocEdgeInput,
521
- context?: Context,
522
- ): void {
523
- const params = this.getDeleteRowParams(edgeData, edge, context);
524
- if (params.op === SQLStatementOperation.Delete) {
525
- return deleteRowsSync(q, params.options, params.clause);
526
- } else {
527
- if (params.op !== SQLStatementOperation.Update) {
528
- throw new Error(`invalid operation ${params.op}`);
529
- }
530
- editRowSync(q, {
531
- tableName: params.options.tableName,
532
- whereClause: params.clause,
533
- fields: params.updateData!,
534
- });
535
- }
536
- }
537
-
538
- private getInsertRowParams(
539
- edgeData: AssocEdgeData,
540
- edge: AssocEdgeInput,
541
- context?: Context,
542
- ): [CreateRowOptions, string] {
543
- const fields: Data = {
544
- id1: edge.id1,
545
- id2: edge.id2,
546
- id1_type: edge.id1Type,
547
- id2_type: edge.id2Type,
548
- edge_type: edge.edgeType,
549
- data: edge.data || null,
550
- };
551
- if (edge.time) {
552
- fields["time"] = edge.time.toISOString();
553
- } else {
554
- // todo make this a schema field like what we do in generated base files...
555
- // maybe when actions exist?
556
- fields["time"] = new Date().toISOString();
557
- }
558
-
559
- const onConflictFields = ["data"];
560
-
561
- const extraEdgeFields = __getGlobalSchema()?.extraEdgeFields;
562
- if (extraEdgeFields) {
563
- for (const name in extraEdgeFields) {
564
- const f = extraEdgeFields[name];
565
- if (f.defaultValueOnCreate) {
566
- const storageKey = getStorageKey(f, name);
567
- fields[storageKey] = f.defaultValueOnCreate(this.builder, {});
568
- // onconflict make sure we override the default values
569
- // e.g. setting deleted_at = null for soft delete
570
- onConflictFields.push(storageKey);
571
- }
572
- }
573
- }
574
-
575
- let transformed: TransformedEdgeUpdateOperation | null = null;
576
- const transformEdgeWrite = __getGlobalSchema()?.transformEdgeWrite;
577
- if (transformEdgeWrite && !edge.disableTransformations) {
578
- transformed = transformEdgeWrite({
579
- op: SQLStatementOperation.Insert,
580
- edge,
581
- });
582
- if (transformed) {
583
- throw new Error(`transforming an insert edge not currently supported`);
584
- }
585
- }
586
-
587
- return [
588
- {
589
- tableName: edgeData.edgeTable,
590
- fields: fields,
591
- fieldsToLog: fields,
592
- context,
593
- },
594
- `ON CONFLICT(id1, edge_type, id2) DO UPDATE SET ${onConflictFields
595
- .map((f) => `${f} = EXCLUDED.${f}`)
596
- .join(", ")}`,
597
- ];
598
- }
599
-
600
- private async performInsertWrite(
601
- q: Queryer,
602
- edgeData: AssocEdgeData,
603
- edge: AssocEdgeInput,
604
- context?: Context,
605
- ): Promise<void> {
606
- const [options, suffix] = this.getInsertRowParams(edgeData, edge, context);
607
-
608
- await createRow(q, options, suffix);
609
- }
610
-
611
- private performInsertWriteSync(
612
- q: SyncQueryer,
613
- edgeData: AssocEdgeData,
614
- edge: AssocEdgeInput,
615
- context?: Context,
616
- ): void {
617
- const [options, suffix] = this.getInsertRowParams(edgeData, edge, context);
618
-
619
- createRowSync(q, options, suffix);
620
- }
621
-
622
- private resolveImpl(
623
- executor: Executor,
624
- placeholder: ID,
625
- desc: string,
626
- ): [ID, string] {
627
- let ent = executor.resolveValue(placeholder);
628
- if (!ent) {
629
- throw new Error(
630
- `could not resolve placeholder value ${placeholder} for ${desc} for edge ${this.edgeInput.edgeType}`,
631
- );
632
- }
633
- if (ent.id === undefined) {
634
- throw new Error(`id of resolved ent is not defined`);
635
- }
636
- return [ent.id, ent.nodeType];
637
- }
638
-
639
- resolve(executor: Executor): void {
640
- if (this.options.id1Placeholder) {
641
- [this.edgeInput.id1, this.edgeInput.id1Type] = this.resolveImpl(
642
- executor,
643
- this.edgeInput.id1,
644
- "id1",
645
- );
646
- }
647
- if (this.options.id2Placeholder) {
648
- [this.edgeInput.id2, this.edgeInput.id2Type] = this.resolveImpl(
649
- executor,
650
- this.edgeInput.id2,
651
- "id2",
652
- );
653
- }
654
- if (this.options.dataPlaceholder) {
655
- if (!this.edgeInput.data) {
656
- throw new Error(`data placeholder set but edgeInput data undefined`);
657
- }
658
- let [data, _] = this.resolveImpl(
659
- executor,
660
- this.edgeInput.data.toString(),
661
- "data",
662
- );
663
- this.edgeInput.data = data.toString();
664
- }
665
- }
666
-
667
- symmetricEdge(): EdgeOperation {
668
- return new EdgeOperation(
669
- this.builder,
670
- {
671
- id1: this.edgeInput.id2,
672
- id1Type: this.edgeInput.id2Type,
673
- id2: this.edgeInput.id1,
674
- id2Type: this.edgeInput.id1Type,
675
- edgeType: this.edgeInput.edgeType,
676
- time: this.edgeInput.time,
677
- data: this.edgeInput.data,
678
- disableTransformations: this.edgeInput.disableTransformations,
679
- },
680
- {
681
- operation: this.options.operation,
682
- id1Placeholder: this.options.id2Placeholder,
683
- id2Placeholder: this.options.id1Placeholder,
684
- dataPlaceholder: this.options.dataPlaceholder,
685
- },
686
- );
687
- }
688
-
689
- inverseEdge(edgeData: AssocEdgeData): EdgeOperation {
690
- return new EdgeOperation(
691
- this.builder,
692
- {
693
- id1: this.edgeInput.id2,
694
- id1Type: this.edgeInput.id2Type,
695
- id2: this.edgeInput.id1,
696
- id2Type: this.edgeInput.id1Type,
697
- edgeType: edgeData.inverseEdgeType!,
698
- time: this.edgeInput.time,
699
- data: this.edgeInput.data,
700
- disableTransformations: this.edgeInput.disableTransformations,
701
- },
702
- {
703
- operation: this.options.operation,
704
- id1Placeholder: this.options.id2Placeholder,
705
- id2Placeholder: this.options.id1Placeholder,
706
- dataPlaceholder: this.options.dataPlaceholder,
707
- },
708
- );
709
- }
710
-
711
- private static resolveIDs<T extends Ent, T2 extends Ent>(
712
- srcBuilder: Builder<T>, // id1
713
- destID: Builder<T2> | ID, // id2 ( and then you flip it)
714
- ): [ID, string, boolean, ID, boolean] {
715
- let destIDVal: ID;
716
- let destPlaceholder = false;
717
- if (this.isBuilder(destID)) {
718
- destIDVal = destID.placeholderID;
719
- destPlaceholder = true;
720
- } else {
721
- destIDVal = destID;
722
- }
723
- let srcIDVal: ID;
724
- let srcType: string;
725
-
726
- let srcPlaceholder = false;
727
- if (srcBuilder.existingEnt) {
728
- srcIDVal = srcBuilder.existingEnt.id;
729
- srcType = srcBuilder.existingEnt.nodeType;
730
- } else {
731
- srcPlaceholder = true;
732
- // get placeholder.
733
- srcIDVal = srcBuilder.placeholderID;
734
- // expected to be filled later
735
- srcType = "";
736
- }
737
-
738
- return [srcIDVal, srcType, srcPlaceholder, destIDVal, destPlaceholder];
739
- }
740
-
741
- private static isBuilder(val: Builder<Ent> | any): val is Builder<Ent> {
742
- return (val as Builder<Ent>).placeholderID !== undefined;
743
- }
744
-
745
- private static resolveData(
746
- data?: Builder<Ent> | string,
747
- ): [string | undefined, boolean] {
748
- if (!data) {
749
- return [undefined, false];
750
- }
751
-
752
- if (this.isBuilder(data)) {
753
- return [data.placeholderID.toString(), true];
754
- }
755
-
756
- return [data, false];
757
- }
758
-
759
- static inboundEdge<T extends Ent, T2 extends Ent>(
760
- builder: Builder<T>,
761
- edgeType: string,
762
- id1: Builder<T2> | ID,
763
- nodeType: string,
764
- options?: AssocEdgeInputOptions,
765
- ): EdgeOperation {
766
- let [id2Val, id2Type, id2Placeholder, id1Val, id1Placeholder] =
767
- EdgeOperation.resolveIDs(builder, id1);
768
- let [data, dataPlaceholder] = EdgeOperation.resolveData(options?.data);
769
- const edge: AssocEdgeInput = {
770
- id1: id1Val,
771
- edgeType: edgeType,
772
- id2: id2Val,
773
- id2Type: id2Type,
774
- id1Type: nodeType,
775
- ...options,
776
- };
777
- if (data) {
778
- edge.data = data;
779
- }
780
-
781
- return new EdgeOperation(builder, edge, {
782
- operation: WriteOperation.Insert,
783
- id2Placeholder,
784
- id1Placeholder,
785
- dataPlaceholder,
786
- });
787
- }
788
-
789
- static outboundEdge<T extends Ent, T2 extends Ent>(
790
- builder: Builder<T>,
791
- edgeType: string,
792
- id2: Builder<T2> | ID,
793
- nodeType: string,
794
- options?: AssocEdgeInputOptions,
795
- ): EdgeOperation {
796
- let [id1Val, id1Type, id1Placeholder, id2Val, id2Placeholder] =
797
- EdgeOperation.resolveIDs(builder, id2);
798
- let [data, dataPlaceholder] = EdgeOperation.resolveData(options?.data);
799
-
800
- const edge: AssocEdgeInput = {
801
- id1: id1Val,
802
- edgeType: edgeType,
803
- id2: id2Val,
804
- id2Type: nodeType,
805
- id1Type: id1Type,
806
- ...options,
807
- };
808
- if (data) {
809
- edge.data = data;
810
- }
811
-
812
- return new EdgeOperation(builder, edge, {
813
- operation: WriteOperation.Insert,
814
- id1Placeholder,
815
- id2Placeholder,
816
- dataPlaceholder,
817
- });
818
- }
819
-
820
- static removeInboundEdge<T extends Ent>(
821
- builder: Builder<T>,
822
- edgeType: string,
823
- id1: ID,
824
- options?: AssocEdgeInputOptions,
825
- ): EdgeOperation {
826
- if (!builder.existingEnt) {
827
- throw new Error("cannot remove an edge from a non-existing ent");
828
- }
829
- const edge: AssocEdgeInput = {
830
- id1: id1,
831
- edgeType: edgeType,
832
- id2: builder.existingEnt!.id,
833
- id2Type: "", // these 2 shouldn't matter
834
- id1Type: "",
835
- disableTransformations: options?.disableTransformations,
836
- };
837
- return new EdgeOperation(builder, edge, {
838
- operation: WriteOperation.Delete,
839
- });
840
- }
841
-
842
- static removeOutboundEdge<T extends Ent>(
843
- builder: Builder<T>,
844
- edgeType: string,
845
- id2: ID,
846
- options?: AssocEdgeInputOptions,
847
- ): EdgeOperation {
848
- if (!builder.existingEnt) {
849
- throw new Error("cannot remove an edge from a non-existing ent");
850
- }
851
- const edge: AssocEdgeInput = {
852
- id2: id2,
853
- edgeType: edgeType,
854
- id1: builder.existingEnt!.id,
855
- id2Type: "", // these 2 shouldn't matter
856
- id1Type: "",
857
- disableTransformations: options?.disableTransformations,
858
- };
859
- return new EdgeOperation(builder, edge, {
860
- operation: WriteOperation.Delete,
861
- });
862
- }
863
- }
864
-
865
- export class ConditionalOperation<T extends Ent = Ent>
866
- implements DataOperation<T>
867
- {
868
- placeholderID?: ID | undefined;
869
- protected shortCircuited = false;
870
- public readonly builder: Builder<T>;
871
-
872
- constructor(
873
- protected op: DataOperation<T>,
874
- private conditionalBuilder: Builder<any>,
875
- ) {
876
- this.builder = op.builder;
877
- this.placeholderID = op.placeholderID;
878
- }
879
-
880
- shortCircuit(executor: Executor): boolean {
881
- this.shortCircuited = executor.builderOpChanged(this.conditionalBuilder);
882
- return this.shortCircuited;
883
- }
884
-
885
- async preFetch(
886
- queryer: Queryer,
887
- context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
888
- ): Promise<void> {
889
- if (this.op.preFetch) {
890
- return this.op.preFetch(queryer, context);
891
- }
892
- }
893
-
894
- performWriteSync(
895
- queryer: SyncQueryer,
896
- context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
897
- ): void {
898
- this.op.performWriteSync(queryer, context);
899
- }
900
-
901
- performWrite(
902
- queryer: Queryer,
903
- context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
904
- ): Promise<void> {
905
- return this.op.performWrite(queryer, context);
906
- }
907
-
908
- returnedRow(): Data | null {
909
- if (this.op.returnedRow) {
910
- return this.op.returnedRow();
911
- }
912
- return null;
913
- }
914
-
915
- updatedOperation(): UpdatedOperation | null {
916
- if (this.op.updatedOperation) {
917
- return this.op.updatedOperation();
918
- }
919
- return null;
920
- }
921
-
922
- resolve(executor: Executor): void {
923
- if (this.op.resolve) {
924
- return this.op.resolve(executor);
925
- }
926
- }
927
-
928
- async postFetch(
929
- queryer: Queryer,
930
- context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
931
- ): Promise<void> {
932
- if (this.op.postFetch) {
933
- return this.op.postFetch(queryer, context);
934
- }
935
- }
936
- }
937
-
938
- // separate because we need to implement createdEnt and we manually run those before edge/other operations in executors
939
- export class ConditionalNodeOperation<
940
- T extends Ent,
941
- > extends ConditionalOperation<T> {
942
- createdEnt(viewer: Viewer): T | null {
943
- if (this.op.createdEnt) {
944
- return this.op.createdEnt(viewer);
945
- }
946
- return null;
947
- }
948
-
949
- updatedOperation(): UpdatedOperation | null {
950
- if (!this.op.updatedOperation) {
951
- return null;
952
- }
953
- const ret = this.op.updatedOperation();
954
- if (ret !== null) {
955
- return ret;
956
- }
957
- if (!this.shortCircuited) {
958
- return null;
959
- }
960
- // hack. if this short circuited, claim that this updated as an edit and it should invalidate other builders
961
- // this API needs to change or EditNodeOperation needs to be used instead of this...
962
- return {
963
- operation: WriteOperation.Edit,
964
- builder: this.builder,
965
- };
966
- }
967
- }