@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,1087 +0,0 @@
1
- import { DateTime } from "luxon";
2
- import { camelCase } from "camel-case";
3
- import { isPromise } from "util/types";
4
- import { validate } from "uuid";
5
- import { Ent, WriteOperation } from "../core/base";
6
- import { Builder } from "../action/action";
7
- import DB, { Dialect } from "../core/db";
8
- import {
9
- DBType,
10
- Field,
11
- FieldMap,
12
- FieldOptions,
13
- ForeignKey,
14
- PolymorphicOptions,
15
- Type,
16
- } from "./schema";
17
- import { __getGlobalSchemaField } from "../core/global_schema";
18
- import { log } from "../core/logger";
19
-
20
- export abstract class BaseField {
21
- name: string;
22
- nullable?: boolean;
23
- storageKey?: string;
24
- serverDefault?: any;
25
- unique?: boolean;
26
- hideFromGraphQL?: boolean;
27
- private?: boolean;
28
- sensitive?: boolean;
29
- graphqlName?: string;
30
- index?: boolean;
31
- foreignKey?: ForeignKey;
32
-
33
- // this should only be set on id fields. if set on other fields, it's currently ignored
34
- polymorphic?: boolean | PolymorphicOptions;
35
- // also adds a _type field
36
- // e.g. owner_id -> owner_type
37
- // other fields
38
-
39
- // fields derived from this one. e.g. polymorphic id fields
40
- // add a _type field
41
- // e.g. a polymorphic user_id field adds a user_type field
42
- // derivedFields?(name: string): FieldMap;
43
- derivedWhenEmbedded?: boolean;
44
-
45
- logValue(val: any): any {
46
- if (this.sensitive) {
47
- // for sensitive things, don't log the actual value
48
- return "*".repeat(`${val}`.length);
49
- }
50
- return val;
51
- }
52
- }
53
-
54
- export class UUIDField extends BaseField implements Field {
55
- type: Type = { dbType: DBType.UUID };
56
-
57
- constructor(private options?: FieldOptions) {
58
- super();
59
-
60
- if (
61
- options?.fieldEdge?.enforceSchema &&
62
- !options.fieldEdge.getLoaderInfoFromSchema
63
- ) {
64
- throw new Error(
65
- `cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`,
66
- );
67
- }
68
- }
69
-
70
- getDerivedFields(fieldName: string): FieldMap {
71
- const polymorphic = this.options?.polymorphic;
72
- if (polymorphic) {
73
- let name = "";
74
- if (fieldName.endsWith("_id")) {
75
- let idx = fieldName.indexOf("_id");
76
- name = fieldName.substring(0, idx) + "_type";
77
- } else if (fieldName.endsWith("ID")) {
78
- let idx = fieldName.indexOf("ID");
79
- name = fieldName.substring(0, idx) + "Type";
80
- } else {
81
- throw new Error(`unsupported id polymorhpic type ${fieldName}`);
82
- }
83
-
84
- let types: string[] | undefined;
85
- let serverDefault: any = undefined;
86
- if (typeof polymorphic === "object") {
87
- serverDefault = polymorphic.serverDefault;
88
- types = polymorphic.types;
89
- }
90
-
91
- // polymorphic field automatically hidden from GraphQL
92
- // can be made visible with custom fields if user wants to change this behavior
93
- // can't be foreignKey so need to make other changes to the field
94
- // intentionally not made private as it doesn't seem like it needs to be hidden
95
-
96
- return {
97
- [name]: PolymorphicStringType({
98
- types: types,
99
- hideFromGraphQL: true,
100
- derivedWhenEmbedded: true,
101
- nullable: this.options?.nullable,
102
- parentFieldToValidate: fieldName,
103
- serverDefault: serverDefault,
104
- }),
105
- };
106
- }
107
- return {};
108
- }
109
-
110
- private isBuilder(val: Builder<Ent> | any): val is Builder<Ent> {
111
- return (val as Builder<Ent>).placeholderID !== undefined;
112
- }
113
-
114
- async valid(val: any) {
115
- if (typeof val === "string" && !validate(val)) {
116
- return false;
117
- }
118
- if (!this.options?.fieldEdge?.enforceSchema) {
119
- return true;
120
- }
121
-
122
- const getLoaderInfo = this.options.fieldEdge.getLoaderInfoFromSchema!;
123
- const loaderInfo = getLoaderInfo(this.options.fieldEdge.schema);
124
- if (!loaderInfo) {
125
- throw new Error(
126
- `couldn't get loaderInfo for ${this.options.fieldEdge.schema}`,
127
- );
128
- }
129
- if (this.isBuilder(val)) {
130
- // if builder, the nodeType of the builder and the nodeType of the loaderInfo should match
131
- return val.nodeType === loaderInfo.nodeType;
132
- }
133
- // TODO we need context here to make sure that we hit local cache
134
-
135
- const row = await loaderInfo.loaderFactory.createLoader().load(val);
136
- return row !== null;
137
- }
138
- }
139
-
140
- export function UUIDType(options?: FieldOptions): UUIDField {
141
- let result = new UUIDField(options);
142
- return Object.assign(result, options);
143
- }
144
-
145
- export interface IntegerOptions extends NumberOptions<number> {}
146
-
147
- export interface NumberOptions<T> extends FieldOptions {
148
- min?: T;
149
- max?: T;
150
- }
151
-
152
- export class NumberField<T> extends BaseField {
153
- // to be overriden as needed
154
- type: Type = { dbType: DBType.Int };
155
-
156
- private validators: { (str: number): boolean }[] = [];
157
- private options: NumberOptions<T> = {};
158
-
159
- constructor(options?: NumberOptions<T>) {
160
- super();
161
- // for legacy callers
162
- this.handleOptions(options || this.options);
163
- }
164
-
165
- getOptions(): NumberOptions<T> {
166
- return this.options;
167
- }
168
-
169
- private handleOptions(options: NumberOptions<T>) {
170
- const params = {
171
- min: this.min,
172
- max: this.max,
173
- };
174
-
175
- for (const k in params) {
176
- const v = options[k];
177
- if (v !== undefined) {
178
- params[k].apply(this, [v]);
179
- }
180
- }
181
- this.options = options;
182
- }
183
-
184
- min(l: T): this {
185
- // @ts-ignore Operator '>=' cannot be applied to types 'number' and 'T'.
186
- return this.validate((val) => val >= l);
187
- }
188
-
189
- max(l: T): this {
190
- // @ts-ignore Operator '<=' cannot be applied to types 'number' and 'T'.
191
- return this.validate((val) => val <= l);
192
- }
193
-
194
- valid(val: any): boolean {
195
- for (const validator of this.validators) {
196
- if (!validator(val)) {
197
- return false;
198
- }
199
- }
200
- return true;
201
- }
202
-
203
- validate(validator: (str: number) => boolean): this {
204
- this.validators.push(validator);
205
- return this;
206
- }
207
- }
208
-
209
- export class IntegerField extends NumberField<number> implements Field {
210
- type: Type = { dbType: DBType.Int };
211
- }
212
-
213
- export function IntegerType(options?: IntegerOptions): IntegerField {
214
- let result = new IntegerField(options);
215
- return Object.assign(result, options);
216
- }
217
-
218
- export class BigIntegerField extends NumberField<BigInt> implements Field {
219
- type: Type = { dbType: DBType.BigInt };
220
- }
221
-
222
- export function BigIntegerType(
223
- options?: NumberOptions<BigInt>,
224
- ): BigIntegerField {
225
- let result = new BigIntegerField(options);
226
- return Object.assign(result, options);
227
- }
228
-
229
- export class FloatField extends NumberField<number> implements Field {
230
- type: Type = { dbType: DBType.Float };
231
- }
232
-
233
- export function FloatType(options?: NumberOptions<number>): FloatField {
234
- let result = new FloatField(options);
235
- return Object.assign(result, options);
236
- }
237
-
238
- export class BooleanField extends BaseField implements Field {
239
- type: Type = { dbType: DBType.Boolean };
240
- }
241
-
242
- export function BooleanType(options?: FieldOptions): BooleanField {
243
- let result = new BooleanField();
244
- return Object.assign(result, options);
245
- }
246
-
247
- export interface StringOptions extends FieldOptions {
248
- minLen?: number;
249
- maxLen?: number;
250
- length?: number;
251
- toLowerCase?: boolean;
252
- toUpperCase?: boolean;
253
- match?: string | RegExp;
254
- doesNotMatch?: string | RegExp;
255
- trim?: boolean;
256
- trimLeft?: boolean;
257
- trimRight?: boolean;
258
- }
259
-
260
- export class StringField extends BaseField implements Field {
261
- type: Type = { dbType: DBType.String };
262
- private validators: { (str: string): boolean }[] = [];
263
- private formatters: { (str: string): string }[] = [];
264
- private options: StringOptions = {};
265
-
266
- constructor(options?: StringOptions) {
267
- super();
268
- // for legacy callers
269
- this.handleOptions(options || {});
270
- }
271
-
272
- getOptions(): StringOptions {
273
- return this.options;
274
- }
275
-
276
- private handleOptions(options: StringOptions) {
277
- const noParams = {
278
- toLowerCase: this.toLowerCase,
279
- toUpperCase: this.toUpperCase,
280
- trim: this.trim,
281
- trimLeft: this.trimLeft,
282
- trimRight: this.trimRight,
283
- };
284
-
285
- const params = {
286
- minLen: this.minLen,
287
- maxLen: this.maxLen,
288
- length: this.length,
289
- match: this.match,
290
- doesNotMatch: this.doesNotMatch,
291
- };
292
-
293
- for (const k in params) {
294
- const v = options[k];
295
- if (v !== undefined) {
296
- params[k].apply(this, [v]);
297
- }
298
- }
299
- for (const k in noParams) {
300
- if (options[k] === true) {
301
- noParams[k].apply(this);
302
- }
303
- }
304
- this.options = options;
305
- }
306
-
307
- minLen(l: number): this {
308
- return this.validate((val) => {
309
- return val.length >= l;
310
- });
311
- }
312
-
313
- maxLen(l: number): this {
314
- return this.validate((val) => val.length <= l);
315
- }
316
-
317
- length(l: number) {
318
- return this.validate((val) => val.length === l);
319
- }
320
-
321
- valid(val: any): boolean {
322
- // TODO play with API more and figure out if I want functions ala below
323
- // or properties ala this
324
- // both doable but which API is better ?
325
- for (const validator of this.validators) {
326
- if (!validator(val)) {
327
- return false;
328
- }
329
- }
330
- return true;
331
- }
332
-
333
- format(val: any): any {
334
- for (const formatter of this.formatters) {
335
- val = formatter(val);
336
- }
337
- return val;
338
- }
339
-
340
- validate(validator: (str: string) => boolean): this {
341
- this.validators.push(validator);
342
- return this;
343
- }
344
-
345
- formatter(formatter: (str: string) => string): this {
346
- this.formatters.push(formatter);
347
- return this;
348
- }
349
-
350
- match(pattern: string | RegExp): this {
351
- return this.validate(function (str: string): boolean {
352
- let r = new RegExp(pattern);
353
- return r.test(str);
354
- });
355
- }
356
-
357
- doesNotMatch(pattern: string | RegExp): this {
358
- return this.validate(function (str: string): boolean {
359
- let r = new RegExp(pattern);
360
- return !r.test(str);
361
- });
362
- }
363
-
364
- toLowerCase(): this {
365
- return this.formatter((str) => str.toLowerCase());
366
- }
367
-
368
- toUpperCase(): this {
369
- return this.formatter((str) => str.toUpperCase());
370
- }
371
-
372
- trim(): this {
373
- return this.formatter((str) => str.trim());
374
- }
375
-
376
- trimLeft(): this {
377
- return this.formatter((str) => str.trimLeft());
378
- }
379
-
380
- trimRight(): this {
381
- return this.formatter((str) => str.trimRight());
382
- }
383
- }
384
-
385
- interface PolymorphicStringOptions extends StringOptions {
386
- parentFieldToValidate: string;
387
- // restrict to just these types...
388
- types?: string[];
389
- }
390
-
391
- export class PolymorphicStringField extends StringField {
392
- private camelCaseVals: string[] | undefined;
393
- constructor(private opts: PolymorphicStringOptions) {
394
- super(opts);
395
- if (opts.types) {
396
- this.camelCaseVals = opts.types.map((v) => camelCase(v));
397
- }
398
- }
399
-
400
- validateWithFullData(val: any, b: Builder<any>): boolean {
401
- const input = b.getInput();
402
- const inputKey =
403
- b.orchestrator.__getOptions().fieldInfo[this.opts.parentFieldToValidate]
404
- .inputKey;
405
-
406
- const v = input[inputKey];
407
-
408
- if (val === null) {
409
- // if this is being set to null, ok if v is also null
410
- return v === null;
411
- }
412
- // if this is not being set, ok if v is not being set
413
- if (val === undefined && b.operation === WriteOperation.Insert) {
414
- return v === undefined;
415
- }
416
- return true;
417
- }
418
-
419
- valid(val: any): boolean {
420
- if (!this.camelCaseVals) {
421
- return true;
422
- }
423
-
424
- let str = camelCase(String(val));
425
- // allow different cases because it could be coming from different clients who don't have strong typing
426
- return this.camelCaseVals.some((value) => value === str);
427
- }
428
-
429
- format(val: any) {
430
- if (!this.camelCaseVals) {
431
- return val;
432
- }
433
-
434
- const converted = camelCase(String(val));
435
-
436
- for (const v of this.camelCaseVals) {
437
- if (v === val) {
438
- return val;
439
- }
440
- if (converted === v) {
441
- return converted;
442
- }
443
- }
444
- return val;
445
- }
446
- }
447
-
448
- function PolymorphicStringType(opts: PolymorphicStringOptions) {
449
- let result = new PolymorphicStringField(opts);
450
- return Object.assign(result, opts);
451
- }
452
-
453
- export function StringType(options?: StringOptions): StringField {
454
- let result = new StringField(options);
455
- const options2 = { ...options };
456
- for (const key in options) {
457
- // key already exists here e.g. the method toLowerCase
458
- if (result[key]) {
459
- delete options2[key];
460
- }
461
- }
462
- return Object.assign(result, options2);
463
- }
464
-
465
- export interface TimestampOptions extends FieldOptions {
466
- withTimezone?: boolean;
467
- }
468
-
469
- export class TimestampField extends BaseField implements Field {
470
- type: Type = { dbType: DBType.Timestamp };
471
- withTimezone?: boolean;
472
-
473
- constructor(options: TimestampOptions) {
474
- super();
475
- if (options.withTimezone) {
476
- this.type = {
477
- dbType: DBType.Timestamptz,
478
- };
479
- }
480
- }
481
-
482
- format(val: Date): any {
483
- let dt: DateTime;
484
- if (typeof val === "string") {
485
- dt = DateTime.fromISO(val);
486
- } else {
487
- dt = DateTime.fromJSDate(val);
488
- }
489
- if (this.withTimezone) {
490
- // send ISO down so that if it's saved in different format e.g. csv and then
491
- // later saved in the db e.g. with COPY, correct value is saved.
492
- return dt.toISO();
493
- }
494
-
495
- // without timezone, make sure to store UTC value...
496
- return dt.toUTC().toISO();
497
- }
498
- }
499
-
500
- export function TimestampType(options?: TimestampOptions): TimestampField {
501
- let result = new TimestampField({ ...options });
502
- return Object.assign(result, options);
503
- }
504
-
505
- export function TimestamptzType(options?: FieldOptions): TimestampField {
506
- let opts: TimestampOptions = { withTimezone: true, ...options };
507
- let result = new TimestampField(opts);
508
- return Object.assign(result, opts);
509
- }
510
-
511
- export interface TimeOptions extends FieldOptions {
512
- withTimezone?: boolean;
513
- precision?: number;
514
- }
515
-
516
- export const leftPad = (val: number): string => {
517
- if (val >= 0) {
518
- if (val < 10) {
519
- return `0${val}`;
520
- }
521
- return val.toString();
522
- }
523
- if (val > -10) {
524
- return `-0${val * -1}`;
525
- }
526
- return val.toString();
527
- };
528
-
529
- export class TimeField extends BaseField implements Field {
530
- type: Type = { dbType: DBType.Time };
531
- withTimezone?: boolean;
532
-
533
- constructor(options?: TimeOptions) {
534
- super();
535
- if (options?.withTimezone) {
536
- this.type = {
537
- dbType: DBType.Timetz,
538
- };
539
- }
540
- }
541
-
542
- format(val: any): any {
543
- // allow database handle it
544
- // https://www.postgresql.org/docs/9.1/datatype-datetime.html#AEN5668
545
- if (!(val instanceof Date)) {
546
- return val;
547
- }
548
- let offset = "";
549
-
550
- if (this.withTimezone) {
551
- // for some reason this API is backwards
552
- let div = (val.getTimezoneOffset() / 60) * -1;
553
-
554
- offset = leftPad(div);
555
- }
556
- let hh = leftPad(val.getHours());
557
- let mm = leftPad(val.getMinutes());
558
- let ss = leftPad(val.getSeconds());
559
- let ms = leftPad(val.getMilliseconds());
560
- if (ms !== "00" && offset) {
561
- return `${hh}:${mm}:${ss}.${ms}${offset}`;
562
- } else {
563
- return `${hh}:${mm}:${ss}`;
564
- }
565
- }
566
- }
567
-
568
- export function TimeType(options?: TimeOptions): TimeField {
569
- let result = new TimeField(options);
570
- return Object.assign(result, options);
571
- }
572
-
573
- export function TimetzType(options?: FieldOptions): TimeField {
574
- let opts: TimestampOptions = {
575
- withTimezone: true,
576
- ...options,
577
- };
578
- let result = new TimeField(opts);
579
- return Object.assign(result, opts);
580
- }
581
-
582
- export class DateField extends BaseField implements Field {
583
- type: Type = { dbType: DBType.Date };
584
-
585
- format(val: any): any {
586
- if (typeof val === "string") {
587
- return val;
588
- }
589
- val = new Date(val);
590
-
591
- let yy = leftPad(val.getFullYear());
592
-
593
- // lol this API
594
- // for some reason this is 0-index
595
- let mm = leftPad(val.getMonth() + 1);
596
- let dd = leftPad(val.getDate());
597
- let ret = `${yy}-${mm}-${dd}`;
598
-
599
- return ret;
600
- }
601
- }
602
-
603
- export function DateType(options?: FieldOptions): DateField {
604
- let result = new DateField();
605
- return Object.assign(result, options);
606
- }
607
-
608
- declare type StringEnumMap = {
609
- [key: string]: string;
610
- };
611
-
612
- /**
613
- * @deprecated use StringEnumOptions
614
- */
615
- export interface EnumOptions extends FieldOptions {
616
- // required when not a reference to a lookup table
617
- // when using a lookup table enum, we should use all caps because we don't have the values to translate back
618
- values?: string[];
619
- // used when we're migrating from old -> new values and want to reuse the values but the values may not be the best keys so this is preferred
620
- // instead of values.
621
- // GRAPHQL will take the key and use it as the value here instead o
622
- map?: StringEnumMap;
623
-
624
- // by default the type is the name as the field
625
- // it's recommended to scope the enum names in scenarios where it makes sense
626
- tsType?: string;
627
- graphQLType?: string;
628
-
629
- createEnumType?: boolean;
630
-
631
- // if set to true, we don't add an `UNKNOWN` or `Unknown` type to deal with invalid|deprecated|old types
632
- // coming from the db.
633
- // GraphQL is strict about old values so we are adding this
634
- disableUnknownType?: boolean;
635
-
636
- // used to flag that this is referencing a global shared enum type.
637
- globalType?: string;
638
- }
639
-
640
- /**
641
- * @deprecated Use StringEnumField
642
- */
643
- export class EnumField extends BaseField implements Field {
644
- type: Type;
645
- private values?: string[];
646
- private map?: StringEnumMap;
647
-
648
- constructor(options: StringEnumOptions) {
649
- super();
650
- this.type = {
651
- // if createEnumType boolean, we create postgres enum otherwise we use a string for it
652
- dbType: options.createEnumType ? DBType.Enum : DBType.StringEnum,
653
- values: options.values,
654
- enumMap: options.map,
655
- type: options.tsType,
656
- graphQLType: options.graphQLType,
657
- disableUnknownType: options.disableUnknownType,
658
- globalType: options.globalType,
659
- };
660
- if (!options.foreignKey) {
661
- if (!options.values && !options.map && !options.globalType) {
662
- throw new Error(
663
- "values, map or globalType required if not look up table enum. Look-up table enum indicated by foreignKey field",
664
- );
665
- }
666
- if (options.values) {
667
- if (!options.values.length) {
668
- throw new Error("need at least one value in enum type");
669
- }
670
- }
671
- if (options.map) {
672
- let count = 0;
673
- for (const _ in options.map) {
674
- count++;
675
- break;
676
- }
677
- if (!count) {
678
- throw new Error("need at least one entry in enum map");
679
- }
680
- }
681
- } else {
682
- if (options.values || options.map || options.globalType) {
683
- throw new Error(
684
- "cannot specify values, map or globalType and foreign key for lookup table enum type",
685
- );
686
- }
687
- if (options.createEnumType) {
688
- throw new Error(
689
- "cannot specify createEnumType without specifying values",
690
- );
691
- }
692
- if (options.tsType) {
693
- throw new Error("cannot specify tsType without specifying values");
694
- }
695
- if (options.graphQLType) {
696
- throw new Error("cannot specify graphQLType without specifying values");
697
- }
698
- }
699
- this.values = options.values;
700
- this.map = options.map;
701
- }
702
-
703
- async valid(val: any): Promise<boolean> {
704
- if (this.type.globalType) {
705
- const f = __getGlobalSchemaField(this.type.globalType);
706
- if (f) {
707
- if (f.valid) {
708
- return f.valid(val);
709
- }
710
- return true;
711
- } else {
712
- log(
713
- "error",
714
- `globalType ${this.type.globalType} not found in global schema`,
715
- );
716
- return false;
717
- }
718
- }
719
-
720
- // lookup table enum and indicated via presence of foreignKey
721
- if (!this.values && !this.map) {
722
- return true;
723
- }
724
- if (this.values) {
725
- let str = String(val);
726
- return this.values.some((value) => value === str);
727
- }
728
-
729
- for (const k in this.map) {
730
- const v = this.map[k];
731
- if (v === val) {
732
- return true;
733
- }
734
- }
735
- return false;
736
- }
737
-
738
- format(val: any): any {
739
- if (this.type.globalType) {
740
- const f = __getGlobalSchemaField(this.type.globalType);
741
- if (f && f.format) {
742
- return f.format(val);
743
- }
744
- return val;
745
- }
746
- return val;
747
- }
748
- }
749
-
750
- export class StringEnumField extends EnumField {}
751
-
752
- export interface PolymorphicStringEnumOptions extends EnumOptions {
753
- parentFieldToValidate: string;
754
- }
755
-
756
- export interface StringEnumOptions extends EnumOptions {}
757
-
758
- export function EnumType(options: StringEnumOptions): EnumField {
759
- let result = new StringEnumField(options);
760
- return Object.assign(result, options);
761
- }
762
-
763
- declare type IntEnumMap = {
764
- [key: string]: number;
765
- };
766
-
767
- export interface IntegerEnumOptions extends FieldOptions {
768
- // used when we're migrating from old -> new values and want to reuse the values but the values may not be the best keys so this is preferred
769
- // instead of values.
770
- // GRAPHQL will take the key and use it as the value here instead o
771
- map?: IntEnumMap;
772
- deprecated?: IntEnumMap;
773
-
774
- // by default the type is the name as the field
775
- // it's recommended to scope the enum names in scenarios where it makes sense
776
- tsType?: string;
777
- graphQLType?: string;
778
-
779
- // if set to true, we don't add an `UNKNOWN` or `Unknown` type to deal with invalid|deprecated|old types
780
- // coming from the db.
781
- // GraphQL is strict about old values so we are adding this
782
- disableUnknownType?: boolean;
783
-
784
- // TODO would be nice for typescript to make tsType and graphQLType required
785
- // when globalType is set
786
- // hard to do that because FieldOptions allows any field so disjoint `|` types don't work
787
- globalType?: string;
788
- }
789
-
790
- export class IntegerEnumField extends BaseField implements Field {
791
- type: Type;
792
- private map: IntEnumMap;
793
-
794
- constructor(options: IntegerEnumOptions) {
795
- super();
796
- this.type = {
797
- dbType: DBType.IntEnum,
798
- intEnumMap: options.map,
799
- type: options.tsType,
800
- graphQLType: options.graphQLType,
801
- deprecatedIntEnumMap: options.deprecated,
802
- disableUnknownType: options.disableUnknownType,
803
- globalType: options.globalType,
804
- };
805
-
806
- if (options.foreignKey) {
807
- throw new Error(`foreignKey on intEnum not supported`);
808
- }
809
-
810
- if (options.globalType) {
811
- if (options.map) {
812
- throw new Error(`cannot specify map and globalType`);
813
- }
814
- this.map = {};
815
- } else {
816
- let count = 0;
817
- for (const _ in options.map) {
818
- count++;
819
- break;
820
- }
821
- if (!count) {
822
- throw new Error("need at least one entry in enum map");
823
- }
824
- if (!options.map) {
825
- throw new Error("map required if not globalType");
826
- }
827
- this.map = options.map!;
828
- }
829
- }
830
-
831
- async valid(val: any): Promise<boolean> {
832
- if (this.type?.globalType) {
833
- const f = __getGlobalSchemaField(this.type.globalType);
834
- if (f) {
835
- if (f.valid) {
836
- return f.valid(val);
837
- }
838
- return true;
839
- } else {
840
- log(
841
- "error",
842
- `globalType ${this.type.globalType} not found in global schema`,
843
- );
844
- return false;
845
- }
846
- }
847
-
848
- // lookup table enum and indicated via presence of foreignKey
849
-
850
- for (const k in this.map) {
851
- const v = this.map[k];
852
- if (v === val || v === parseInt(val)) {
853
- return true;
854
- }
855
- }
856
- return false;
857
- }
858
-
859
- format(val: any): any {
860
- if (this.type.globalType) {
861
- const f = __getGlobalSchemaField(this.type.globalType);
862
- if (f && f.format) {
863
- return f.format(val);
864
- }
865
- }
866
-
867
- return parseInt(val);
868
- }
869
- }
870
-
871
- export function IntegerEnumType(options: IntegerEnumOptions): IntegerEnumField {
872
- let result = new IntegerEnumField(options);
873
- return Object.assign(result, options);
874
- }
875
-
876
- interface ListOptions extends FieldOptions {
877
- disableJSONStringify?: boolean;
878
- }
879
-
880
- export class ListField extends BaseField {
881
- type: Type;
882
- private validators: { (val: any[]): boolean }[] = [];
883
-
884
- constructor(private field: Field, private options?: ListOptions) {
885
- super();
886
- if (field.type.dbType === DBType.List) {
887
- throw new Error(`nested lists not currently supported`);
888
- }
889
- this.type = {
890
- dbType: DBType.List,
891
- listElemType: field.type,
892
- };
893
- Object.assign(this, options);
894
- }
895
-
896
- __getElemField() {
897
- return this.field;
898
- }
899
-
900
- validate(validator: (val: any[]) => boolean): this {
901
- this.validators.push(validator);
902
- return this;
903
- }
904
-
905
- async valid(val: any) {
906
- if (!Array.isArray(val)) {
907
- return false;
908
- }
909
- for (const validator of this.validators) {
910
- if (!validator(val)) {
911
- return false;
912
- }
913
- }
914
- const valid = this.field.valid;
915
- if (!valid) {
916
- return true;
917
- }
918
- const res = valid.apply(this.field, [val[0]]);
919
- if (isPromise(res)) {
920
- const ret = await Promise.all(
921
- val.map(async (v) => await valid.apply(this.field, [v])),
922
- );
923
- return ret.every((v) => v);
924
- }
925
- const ret = val.map((v) => valid.apply(this.field, [v]));
926
- const result = ret.every((v) => v);
927
- return result;
928
- }
929
-
930
- private postgresVal(val: any, jsonType?: boolean) {
931
- if (!jsonType && val === "") {
932
- // support empty strings in list
933
- val = '"' + val + '"';
934
- return val;
935
- }
936
- if (this.options?.disableJSONStringify) {
937
- return val;
938
- }
939
- return JSON.stringify(val);
940
- }
941
-
942
- format(val: any, nested?: boolean): any {
943
- if (!Array.isArray(val)) {
944
- throw new Error(`need an array to format`);
945
- }
946
-
947
- const elemDBType = this.type.listElemType!.dbType;
948
- const jsonType = elemDBType === "JSON" || elemDBType === "JSONB";
949
- // postgres ish doesn't apply when nested
950
- const postgres = !nested && DB.getDialect() === Dialect.Postgres;
951
-
952
- if (nested && !this.field.format) {
953
- return val;
954
- }
955
-
956
- if (!postgres && !this.field.format) {
957
- return JSON.stringify(val);
958
- }
959
-
960
- let ret: any[] = [];
961
- let postgresRet: string = "{";
962
- for (let i = 0; i < val.length; i++) {
963
- let formatted = val[i];
964
- if (this.field.format) {
965
- formatted = this.field.format(val[i], nested);
966
- }
967
-
968
- // postgres supports arrays natively so we
969
- // structure it in the expected format
970
- if (postgres) {
971
- postgresRet += this.postgresVal(formatted, jsonType);
972
- if (i !== val.length - 1) {
973
- postgresRet += ",";
974
- }
975
- } else {
976
- ret[i] = formatted;
977
- }
978
- }
979
- if (postgres) {
980
- return postgresRet + "}";
981
- }
982
- // don't JSON.stringify if nested
983
- if (nested) {
984
- return ret;
985
- }
986
- return JSON.stringify(ret);
987
- }
988
-
989
- minLen(l: number): this {
990
- return this.validate((val: any[]) => val.length >= l);
991
- }
992
-
993
- maxLen(l: number): this {
994
- return this.validate((val: any[]) => val.length <= l);
995
- }
996
-
997
- length(l: number): this {
998
- return this.validate((val: any[]) => val.length === l);
999
- }
1000
-
1001
- // like python's range() function
1002
- // start is where to start and stop is the number to stop (not inclusive in the range)
1003
- range(start: any, stop: any): this {
1004
- return this.validate((val: any[]) => {
1005
- for (const v of val) {
1006
- if (v < start || v >= stop) {
1007
- return false;
1008
- }
1009
- }
1010
- return true;
1011
- });
1012
- }
1013
- }
1014
-
1015
- export function StringListType(options?: StringOptions) {
1016
- return new ListField(StringType(options), options);
1017
- }
1018
-
1019
- export function IntListType(options?: FieldOptions) {
1020
- return new ListField(IntegerType(options), options);
1021
- }
1022
-
1023
- export function IntegerListType(options?: FieldOptions) {
1024
- return new ListField(IntegerType(options), options);
1025
- }
1026
-
1027
- export function FloatListType(options?: FieldOptions) {
1028
- return new ListField(FloatType(options), options);
1029
- }
1030
-
1031
- export function BigIntegerListType(options: FieldOptions) {
1032
- return new ListField(BigIntegerType(options), options);
1033
- }
1034
-
1035
- export function BooleanListType(options?: FieldOptions) {
1036
- return new ListField(BooleanType(options), options);
1037
- }
1038
-
1039
- export function TimestampListType(options: TimestampOptions) {
1040
- return new ListField(TimestampType(options), options);
1041
- }
1042
-
1043
- export function TimestamptzListType(options?: TimestampOptions) {
1044
- return new ListField(TimestamptzType(options), options);
1045
- }
1046
-
1047
- export function TimeListType(options?: TimeOptions) {
1048
- return new ListField(TimeType(options), options);
1049
- }
1050
-
1051
- export function TimetzListType(options: TimeOptions) {
1052
- return new ListField(TimetzType(options), options);
1053
- }
1054
-
1055
- export function DateListType(options?: FieldOptions) {
1056
- return new ListField(DateType(options), options);
1057
- }
1058
-
1059
- export function EnumListType(options: StringEnumOptions) {
1060
- if (options.createEnumType) {
1061
- throw new Error(`createEnumType is currently unsupported in enum list`);
1062
- }
1063
- if (options.foreignKey) {
1064
- throw new Error(`foreignKey is currently unsupported in enum list`);
1065
- }
1066
-
1067
- // not all of these will make sense in a list...
1068
- // can make it work eventually but involves work we're not currently trying to do
1069
- // developer can try to work around it by calling below on their own.
1070
- // unclear what the behavior is
1071
- return new ListField(EnumType(options), options);
1072
- }
1073
-
1074
- export function IntegerEnumListType(options: IntegerEnumOptions) {
1075
- // not all of these will make sense in a list...
1076
- // can make it work eventually but involves work we're not currently trying to do
1077
- // developer can try to work around it by calling below on their own.
1078
- // unclear what the behavior is
1079
- return new ListField(IntegerEnumType(options), options);
1080
- }
1081
-
1082
- export function UUIDListType(options?: FieldOptions) {
1083
- return new ListField(UUIDType(options), {
1084
- ...options,
1085
- disableJSONStringify: true,
1086
- });
1087
- }