@snowtop/ent 0.1.0-alpha160-test4 → 0.1.0-alpha160-test6

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/dist/package.json +64 -0
  2. package/{scripts → dist/scripts}/custom_compiler.js +0 -0
  3. package/{scripts → dist/scripts}/custom_graphql.js +0 -0
  4. package/package.json +48 -6
  5. package/src/action/action.ts +330 -0
  6. package/src/action/executor.ts +453 -0
  7. package/src/action/experimental_action.ts +277 -0
  8. package/src/action/index.ts +31 -0
  9. package/src/action/operations.ts +967 -0
  10. package/src/action/orchestrator.ts +1527 -0
  11. package/src/action/privacy.ts +37 -0
  12. package/src/action/relative_value.ts +242 -0
  13. package/src/action/transaction.ts +38 -0
  14. package/src/auth/auth.ts +77 -0
  15. package/src/auth/index.ts +8 -0
  16. package/src/core/base.ts +367 -0
  17. package/src/core/clause.ts +1065 -0
  18. package/src/core/config.ts +219 -0
  19. package/src/core/const.ts +5 -0
  20. package/src/core/context.ts +135 -0
  21. package/src/core/convert.ts +106 -0
  22. package/src/core/date.ts +23 -0
  23. package/src/core/db.ts +498 -0
  24. package/src/core/ent.ts +1740 -0
  25. package/src/core/global_schema.ts +49 -0
  26. package/src/core/loaders/assoc_count_loader.ts +99 -0
  27. package/src/core/loaders/assoc_edge_loader.ts +250 -0
  28. package/src/core/loaders/index.ts +12 -0
  29. package/src/core/loaders/loader.ts +66 -0
  30. package/src/core/loaders/object_loader.ts +489 -0
  31. package/src/core/loaders/query_loader.ts +314 -0
  32. package/src/core/loaders/raw_count_loader.ts +175 -0
  33. package/src/core/logger.ts +49 -0
  34. package/src/core/privacy.ts +660 -0
  35. package/src/core/query/assoc_query.ts +240 -0
  36. package/src/core/query/custom_clause_query.ts +174 -0
  37. package/src/core/query/custom_query.ts +302 -0
  38. package/src/core/query/index.ts +9 -0
  39. package/src/core/query/query.ts +674 -0
  40. package/src/core/query_impl.ts +32 -0
  41. package/src/core/viewer.ts +52 -0
  42. package/src/ent.code-workspace +73 -0
  43. package/src/graphql/builtins/connection.ts +25 -0
  44. package/src/graphql/builtins/edge.ts +16 -0
  45. package/src/graphql/builtins/node.ts +12 -0
  46. package/src/graphql/graphql.ts +891 -0
  47. package/src/graphql/graphql_field_helpers.ts +221 -0
  48. package/src/graphql/index.ts +42 -0
  49. package/src/graphql/mutations/union.ts +39 -0
  50. package/src/graphql/node_resolver.ts +122 -0
  51. package/src/graphql/query/connection_type.ts +113 -0
  52. package/src/graphql/query/edge_connection.ts +171 -0
  53. package/src/graphql/query/page_info.ts +34 -0
  54. package/src/graphql/query/shared_edge_connection.ts +287 -0
  55. package/src/graphql/scalars/orderby_direction.ts +13 -0
  56. package/src/graphql/scalars/time.ts +38 -0
  57. package/src/imports/dataz/example1/_auth.ts +51 -0
  58. package/src/imports/dataz/example1/_viewer.ts +35 -0
  59. package/src/imports/index.ts +213 -0
  60. package/src/index.ts +145 -0
  61. package/src/parse_schema/parse.ts +585 -0
  62. package/src/schema/base_schema.ts +224 -0
  63. package/src/schema/field.ts +1087 -0
  64. package/src/schema/index.ts +53 -0
  65. package/src/schema/json_field.ts +94 -0
  66. package/src/schema/schema.ts +1028 -0
  67. package/src/schema/struct_field.ts +234 -0
  68. package/src/schema/union_field.ts +105 -0
  69. package/src/scripts/custom_compiler.ts +331 -0
  70. package/src/scripts/custom_graphql.ts +550 -0
  71. package/src/scripts/migrate_v0.1.ts +41 -0
  72. package/src/scripts/move_types.ts +131 -0
  73. package/src/scripts/read_schema.ts +67 -0
  74. package/src/setupPackage.js +42 -0
  75. package/src/testutils/action/complex_schemas.ts +517 -0
  76. package/src/testutils/builder.ts +422 -0
  77. package/src/testutils/context/test_context.ts +25 -0
  78. package/src/testutils/db/fixture.ts +32 -0
  79. package/src/testutils/db/temp_db.ts +941 -0
  80. package/src/testutils/db/value.ts +294 -0
  81. package/src/testutils/db_mock.ts +351 -0
  82. package/src/testutils/db_time_zone.ts +40 -0
  83. package/src/testutils/ent-graphql-tests/index.ts +653 -0
  84. package/src/testutils/fake_comms.ts +50 -0
  85. package/src/testutils/fake_data/const.ts +64 -0
  86. package/src/testutils/fake_data/events_query.ts +145 -0
  87. package/src/testutils/fake_data/fake_contact.ts +150 -0
  88. package/src/testutils/fake_data/fake_event.ts +150 -0
  89. package/src/testutils/fake_data/fake_tag.ts +139 -0
  90. package/src/testutils/fake_data/fake_user.ts +232 -0
  91. package/src/testutils/fake_data/index.ts +1 -0
  92. package/src/testutils/fake_data/internal.ts +8 -0
  93. package/src/testutils/fake_data/tag_query.ts +56 -0
  94. package/src/testutils/fake_data/test_helpers.ts +388 -0
  95. package/src/testutils/fake_data/user_query.ts +524 -0
  96. package/src/testutils/fake_log.ts +52 -0
  97. package/src/testutils/mock_date.ts +10 -0
  98. package/src/testutils/mock_log.ts +39 -0
  99. package/src/testutils/parse_sql.ts +685 -0
  100. package/src/testutils/test_edge_global_schema.ts +49 -0
  101. package/src/testutils/write.ts +70 -0
  102. package/src/tsc/ast.ts +351 -0
  103. package/src/tsc/compilerOptions.ts +85 -0
  104. package/src/tsc/move_generated.ts +191 -0
  105. package/src/tsc/transform.ts +226 -0
  106. package/src/tsc/transform_action.ts +224 -0
  107. package/src/tsc/transform_ent.ts +66 -0
  108. package/src/tsc/transform_schema.ts +546 -0
  109. package/tsconfig.json +20 -0
  110. package/core/query/shared_assoc_test.d.ts +0 -2
  111. package/core/query/shared_assoc_test.js +0 -804
  112. package/core/query/shared_test.d.ts +0 -21
  113. package/core/query/shared_test.js +0 -736
  114. package/graphql/query/shared_assoc_test.d.ts +0 -1
  115. package/graphql/query/shared_assoc_test.js +0 -203
  116. /package/{action → dist/action}/action.d.ts +0 -0
  117. /package/{action → dist/action}/action.js +0 -0
  118. /package/{action → dist/action}/executor.d.ts +0 -0
  119. /package/{action → dist/action}/executor.js +0 -0
  120. /package/{action → dist/action}/experimental_action.d.ts +0 -0
  121. /package/{action → dist/action}/experimental_action.js +0 -0
  122. /package/{action → dist/action}/index.d.ts +0 -0
  123. /package/{action → dist/action}/index.js +0 -0
  124. /package/{action → dist/action}/operations.d.ts +0 -0
  125. /package/{action → dist/action}/operations.js +0 -0
  126. /package/{action → dist/action}/orchestrator.d.ts +0 -0
  127. /package/{action → dist/action}/orchestrator.js +0 -0
  128. /package/{action → dist/action}/privacy.d.ts +0 -0
  129. /package/{action → dist/action}/privacy.js +0 -0
  130. /package/{action → dist/action}/relative_value.d.ts +0 -0
  131. /package/{action → dist/action}/relative_value.js +0 -0
  132. /package/{action → dist/action}/transaction.d.ts +0 -0
  133. /package/{action → dist/action}/transaction.js +0 -0
  134. /package/{auth → dist/auth}/auth.d.ts +0 -0
  135. /package/{auth → dist/auth}/auth.js +0 -0
  136. /package/{auth → dist/auth}/index.d.ts +0 -0
  137. /package/{auth → dist/auth}/index.js +0 -0
  138. /package/{core → dist/core}/base.d.ts +0 -0
  139. /package/{core → dist/core}/base.js +0 -0
  140. /package/{core → dist/core}/clause.d.ts +0 -0
  141. /package/{core → dist/core}/clause.js +0 -0
  142. /package/{core → dist/core}/config.d.ts +0 -0
  143. /package/{core → dist/core}/config.js +0 -0
  144. /package/{core → dist/core}/const.d.ts +0 -0
  145. /package/{core → dist/core}/const.js +0 -0
  146. /package/{core → dist/core}/context.d.ts +0 -0
  147. /package/{core → dist/core}/context.js +0 -0
  148. /package/{core → dist/core}/convert.d.ts +0 -0
  149. /package/{core → dist/core}/convert.js +0 -0
  150. /package/{core → dist/core}/date.d.ts +0 -0
  151. /package/{core → dist/core}/date.js +0 -0
  152. /package/{core → dist/core}/db.d.ts +0 -0
  153. /package/{core → dist/core}/db.js +0 -0
  154. /package/{core → dist/core}/ent.d.ts +0 -0
  155. /package/{core → dist/core}/ent.js +0 -0
  156. /package/{core → dist/core}/global_schema.d.ts +0 -0
  157. /package/{core → dist/core}/global_schema.js +0 -0
  158. /package/{core → dist/core}/loaders/assoc_count_loader.d.ts +0 -0
  159. /package/{core → dist/core}/loaders/assoc_count_loader.js +0 -0
  160. /package/{core → dist/core}/loaders/assoc_edge_loader.d.ts +0 -0
  161. /package/{core → dist/core}/loaders/assoc_edge_loader.js +0 -0
  162. /package/{core → dist/core}/loaders/index.d.ts +0 -0
  163. /package/{core → dist/core}/loaders/index.js +0 -0
  164. /package/{core → dist/core}/loaders/loader.d.ts +0 -0
  165. /package/{core → dist/core}/loaders/loader.js +0 -0
  166. /package/{core → dist/core}/loaders/object_loader.d.ts +0 -0
  167. /package/{core → dist/core}/loaders/object_loader.js +0 -0
  168. /package/{core → dist/core}/loaders/query_loader.d.ts +0 -0
  169. /package/{core → dist/core}/loaders/query_loader.js +0 -0
  170. /package/{core → dist/core}/loaders/raw_count_loader.d.ts +0 -0
  171. /package/{core → dist/core}/loaders/raw_count_loader.js +0 -0
  172. /package/{core → dist/core}/logger.d.ts +0 -0
  173. /package/{core → dist/core}/logger.js +0 -0
  174. /package/{core → dist/core}/privacy.d.ts +0 -0
  175. /package/{core → dist/core}/privacy.js +0 -0
  176. /package/{core → dist/core}/query/assoc_query.d.ts +0 -0
  177. /package/{core → dist/core}/query/assoc_query.js +0 -0
  178. /package/{core → dist/core}/query/custom_clause_query.d.ts +0 -0
  179. /package/{core → dist/core}/query/custom_clause_query.js +0 -0
  180. /package/{core → dist/core}/query/custom_query.d.ts +0 -0
  181. /package/{core → dist/core}/query/custom_query.js +0 -0
  182. /package/{core → dist/core}/query/index.d.ts +0 -0
  183. /package/{core → dist/core}/query/index.js +0 -0
  184. /package/{core → dist/core}/query/query.d.ts +0 -0
  185. /package/{core → dist/core}/query/query.js +0 -0
  186. /package/{core → dist/core}/query_impl.d.ts +0 -0
  187. /package/{core → dist/core}/query_impl.js +0 -0
  188. /package/{core → dist/core}/viewer.d.ts +0 -0
  189. /package/{core → dist/core}/viewer.js +0 -0
  190. /package/{graphql → dist/graphql}/builtins/connection.d.ts +0 -0
  191. /package/{graphql → dist/graphql}/builtins/connection.js +0 -0
  192. /package/{graphql → dist/graphql}/builtins/edge.d.ts +0 -0
  193. /package/{graphql → dist/graphql}/builtins/edge.js +0 -0
  194. /package/{graphql → dist/graphql}/builtins/node.d.ts +0 -0
  195. /package/{graphql → dist/graphql}/builtins/node.js +0 -0
  196. /package/{graphql → dist/graphql}/graphql.d.ts +0 -0
  197. /package/{graphql → dist/graphql}/graphql.js +0 -0
  198. /package/{graphql → dist/graphql}/graphql_field_helpers.d.ts +0 -0
  199. /package/{graphql → dist/graphql}/graphql_field_helpers.js +0 -0
  200. /package/{graphql → dist/graphql}/index.d.ts +0 -0
  201. /package/{graphql → dist/graphql}/index.js +0 -0
  202. /package/{graphql → dist/graphql}/mutations/union.d.ts +0 -0
  203. /package/{graphql → dist/graphql}/mutations/union.js +0 -0
  204. /package/{graphql → dist/graphql}/node_resolver.d.ts +0 -0
  205. /package/{graphql → dist/graphql}/node_resolver.js +0 -0
  206. /package/{graphql → dist/graphql}/query/connection_type.d.ts +0 -0
  207. /package/{graphql → dist/graphql}/query/connection_type.js +0 -0
  208. /package/{graphql → dist/graphql}/query/edge_connection.d.ts +0 -0
  209. /package/{graphql → dist/graphql}/query/edge_connection.js +0 -0
  210. /package/{graphql → dist/graphql}/query/page_info.d.ts +0 -0
  211. /package/{graphql → dist/graphql}/query/page_info.js +0 -0
  212. /package/{graphql → dist/graphql}/query/shared_edge_connection.d.ts +0 -0
  213. /package/{graphql → dist/graphql}/query/shared_edge_connection.js +0 -0
  214. /package/{graphql → dist/graphql}/scalars/orderby_direction.d.ts +0 -0
  215. /package/{graphql → dist/graphql}/scalars/orderby_direction.js +0 -0
  216. /package/{graphql → dist/graphql}/scalars/time.d.ts +0 -0
  217. /package/{graphql → dist/graphql}/scalars/time.js +0 -0
  218. /package/{imports → dist/imports}/dataz/example1/_auth.d.ts +0 -0
  219. /package/{imports → dist/imports}/dataz/example1/_auth.js +0 -0
  220. /package/{imports → dist/imports}/dataz/example1/_viewer.d.ts +0 -0
  221. /package/{imports → dist/imports}/dataz/example1/_viewer.js +0 -0
  222. /package/{imports → dist/imports}/index.d.ts +0 -0
  223. /package/{imports → dist/imports}/index.js +0 -0
  224. /package/{index.d.ts → dist/index.d.ts} +0 -0
  225. /package/{index.js → dist/index.js} +0 -0
  226. /package/{parse_schema → dist/parse_schema}/parse.d.ts +0 -0
  227. /package/{parse_schema → dist/parse_schema}/parse.js +0 -0
  228. /package/{schema → dist/schema}/base_schema.d.ts +0 -0
  229. /package/{schema → dist/schema}/base_schema.js +0 -0
  230. /package/{schema → dist/schema}/field.d.ts +0 -0
  231. /package/{schema → dist/schema}/field.js +0 -0
  232. /package/{schema → dist/schema}/index.d.ts +0 -0
  233. /package/{schema → dist/schema}/index.js +0 -0
  234. /package/{schema → dist/schema}/json_field.d.ts +0 -0
  235. /package/{schema → dist/schema}/json_field.js +0 -0
  236. /package/{schema → dist/schema}/schema.d.ts +0 -0
  237. /package/{schema → dist/schema}/schema.js +0 -0
  238. /package/{schema → dist/schema}/struct_field.d.ts +0 -0
  239. /package/{schema → dist/schema}/struct_field.js +0 -0
  240. /package/{schema → dist/schema}/union_field.d.ts +0 -0
  241. /package/{schema → dist/schema}/union_field.js +0 -0
  242. /package/{scripts → dist/scripts}/custom_compiler.d.ts +0 -0
  243. /package/{scripts → dist/scripts}/custom_graphql.d.ts +0 -0
  244. /package/{scripts → dist/scripts}/migrate_v0.1.d.ts +0 -0
  245. /package/{scripts → dist/scripts}/migrate_v0.1.js +0 -0
  246. /package/{scripts → dist/scripts}/move_types.d.ts +0 -0
  247. /package/{scripts → dist/scripts}/move_types.js +0 -0
  248. /package/{scripts → dist/scripts}/read_schema.d.ts +0 -0
  249. /package/{scripts → dist/scripts}/read_schema.js +0 -0
  250. /package/{testutils → dist/testutils}/action/complex_schemas.d.ts +0 -0
  251. /package/{testutils → dist/testutils}/action/complex_schemas.js +0 -0
  252. /package/{testutils → dist/testutils}/builder.d.ts +0 -0
  253. /package/{testutils → dist/testutils}/builder.js +0 -0
  254. /package/{testutils → dist/testutils}/context/test_context.d.ts +0 -0
  255. /package/{testutils → dist/testutils}/context/test_context.js +0 -0
  256. /package/{testutils → dist/testutils}/db/fixture.d.ts +0 -0
  257. /package/{testutils → dist/testutils}/db/fixture.js +0 -0
  258. /package/{testutils → dist/testutils}/db/temp_db.d.ts +0 -0
  259. /package/{testutils → dist/testutils}/db/temp_db.js +0 -0
  260. /package/{testutils → dist/testutils}/db/value.d.ts +0 -0
  261. /package/{testutils → dist/testutils}/db/value.js +0 -0
  262. /package/{testutils → dist/testutils}/db_mock.d.ts +0 -0
  263. /package/{testutils → dist/testutils}/db_mock.js +0 -0
  264. /package/{testutils → dist/testutils}/db_time_zone.d.ts +0 -0
  265. /package/{testutils → dist/testutils}/db_time_zone.js +0 -0
  266. /package/{testutils → dist/testutils}/ent-graphql-tests/index.d.ts +0 -0
  267. /package/{testutils → dist/testutils}/ent-graphql-tests/index.js +0 -0
  268. /package/{testutils → dist/testutils}/fake_comms.d.ts +0 -0
  269. /package/{testutils → dist/testutils}/fake_comms.js +0 -0
  270. /package/{testutils → dist/testutils}/fake_data/const.d.ts +0 -0
  271. /package/{testutils → dist/testutils}/fake_data/const.js +0 -0
  272. /package/{testutils → dist/testutils}/fake_data/events_query.d.ts +0 -0
  273. /package/{testutils → dist/testutils}/fake_data/events_query.js +0 -0
  274. /package/{testutils → dist/testutils}/fake_data/fake_contact.d.ts +0 -0
  275. /package/{testutils → dist/testutils}/fake_data/fake_contact.js +0 -0
  276. /package/{testutils → dist/testutils}/fake_data/fake_event.d.ts +0 -0
  277. /package/{testutils → dist/testutils}/fake_data/fake_event.js +0 -0
  278. /package/{testutils → dist/testutils}/fake_data/fake_tag.d.ts +0 -0
  279. /package/{testutils → dist/testutils}/fake_data/fake_tag.js +0 -0
  280. /package/{testutils → dist/testutils}/fake_data/fake_user.d.ts +0 -0
  281. /package/{testutils → dist/testutils}/fake_data/fake_user.js +0 -0
  282. /package/{testutils → dist/testutils}/fake_data/index.d.ts +0 -0
  283. /package/{testutils → dist/testutils}/fake_data/index.js +0 -0
  284. /package/{testutils → dist/testutils}/fake_data/internal.d.ts +0 -0
  285. /package/{testutils → dist/testutils}/fake_data/internal.js +0 -0
  286. /package/{testutils → dist/testutils}/fake_data/tag_query.d.ts +0 -0
  287. /package/{testutils → dist/testutils}/fake_data/tag_query.js +0 -0
  288. /package/{testutils → dist/testutils}/fake_data/test_helpers.d.ts +0 -0
  289. /package/{testutils → dist/testutils}/fake_data/test_helpers.js +0 -0
  290. /package/{testutils → dist/testutils}/fake_data/user_query.d.ts +0 -0
  291. /package/{testutils → dist/testutils}/fake_data/user_query.js +0 -0
  292. /package/{testutils → dist/testutils}/fake_log.d.ts +0 -0
  293. /package/{testutils → dist/testutils}/fake_log.js +0 -0
  294. /package/{testutils → dist/testutils}/mock_date.d.ts +0 -0
  295. /package/{testutils → dist/testutils}/mock_date.js +0 -0
  296. /package/{testutils → dist/testutils}/mock_log.d.ts +0 -0
  297. /package/{testutils → dist/testutils}/mock_log.js +0 -0
  298. /package/{testutils → dist/testutils}/parse_sql.d.ts +0 -0
  299. /package/{testutils → dist/testutils}/parse_sql.js +0 -0
  300. /package/{testutils → dist/testutils}/test_edge_global_schema.d.ts +0 -0
  301. /package/{testutils → dist/testutils}/test_edge_global_schema.js +0 -0
  302. /package/{testutils → dist/testutils}/write.d.ts +0 -0
  303. /package/{testutils → dist/testutils}/write.js +0 -0
  304. /package/{tsc → dist/tsc}/ast.d.ts +0 -0
  305. /package/{tsc → dist/tsc}/ast.js +0 -0
  306. /package/{tsc → dist/tsc}/compilerOptions.d.ts +0 -0
  307. /package/{tsc → dist/tsc}/compilerOptions.js +0 -0
  308. /package/{tsc → dist/tsc}/move_generated.d.ts +0 -0
  309. /package/{tsc → dist/tsc}/move_generated.js +0 -0
  310. /package/{tsc → dist/tsc}/transform.d.ts +0 -0
  311. /package/{tsc → dist/tsc}/transform.js +0 -0
  312. /package/{tsc → dist/tsc}/transform_action.d.ts +0 -0
  313. /package/{tsc → dist/tsc}/transform_action.js +0 -0
  314. /package/{tsc → dist/tsc}/transform_ent.d.ts +0 -0
  315. /package/{tsc → dist/tsc}/transform_ent.js +0 -0
  316. /package/{tsc → dist/tsc}/transform_schema.d.ts +0 -0
  317. /package/{tsc → dist/tsc}/transform_schema.js +0 -0
package/src/index.ts ADDED
@@ -0,0 +1,145 @@
1
+ export * from "./core/base";
2
+ export {
3
+ loadEnt,
4
+ loadCustomData,
5
+ loadCustomEnts,
6
+ loadCustomCount,
7
+ loadEntX,
8
+ loadEnts,
9
+ CustomQuery,
10
+ loadDerivedEnt,
11
+ loadDerivedEntX,
12
+ loadEntViaKey,
13
+ loadEntXViaKey,
14
+ performRawQuery,
15
+ // even these 3 need to change...
16
+ loadRowX,
17
+ loadRow,
18
+ loadRows,
19
+ AssocEdge,
20
+ AssocEdgeData,
21
+ loadEdgeData,
22
+ loadEdgeDatas,
23
+ loadEdges,
24
+ loadUniqueEdge,
25
+ loadUniqueNode,
26
+ loadRawEdgeCountX,
27
+ loadEdgeForID2,
28
+ loadNodesByEdge,
29
+ getEdgeTypeInGroup,
30
+ } from "./core/ent";
31
+ // TODO should these even be exported from the root?
32
+ export {
33
+ DataOperation,
34
+ EditNodeOptions,
35
+ EditNodeOperation,
36
+ RawQueryOperation,
37
+ EdgeOperation,
38
+ DeleteNodeOperation,
39
+ AssocEdgeInputOptions,
40
+ AssocEdgeInput,
41
+ } from "./action/operations";
42
+ export { setGlobalSchema } from "./core/global_schema";
43
+ import DB from "./core/db";
44
+ export * from "./core/loaders";
45
+ export { DB };
46
+
47
+ // TODO figure out if this should be its own import path e.g. @snowtop/ent/privacy
48
+ export {
49
+ EntPrivacyError,
50
+ AlwaysAllowRule,
51
+ AlwaysDenyRule,
52
+ DenyIfLoggedInRule,
53
+ DenyIfLoggedOutRule,
54
+ AllowIfHasIdentity,
55
+ AllowIfViewerRule,
56
+ AllowIfFuncRule,
57
+ AllowIfViewerIsRule,
58
+ AllowIfViewerIsEntPropertyRule,
59
+ AllowIfEntPropertyIsRule,
60
+ DenyIfEntPropertyIsRule,
61
+ AllowIfViewerEqualsRule,
62
+ DenyIfViewerEqualsRule,
63
+ AllowIfEdgeExistsRule,
64
+ AllowIfViewerInboundEdgeExistsRule,
65
+ AllowIfViewerOutboundEdgeExistsRule,
66
+ DenyIfEdgeExistsRule,
67
+ DenyIfViewerInboundEdgeExistsRule,
68
+ DenyIfViewerOutboundEdgeExistsRule,
69
+ DenyIfEdgeDoesNotExistRule,
70
+ DenyIfViewerInboundEdgeDoesNotExistRule,
71
+ DenyIfViewerOutboundEdgeDoesNotExistRule,
72
+ AllowIfEntIsVisibleRule,
73
+ AllowIfEntIsNotVisibleRule,
74
+ DenyIfEntIsVisibleRule,
75
+ DenyIfEntIsNotVisibleRule,
76
+ AllowIfEntIsVisiblePolicy,
77
+ DenyIfEntIsVisiblePolicy,
78
+ DelayedResultRule,
79
+ applyPrivacyPolicy,
80
+ applyPrivacyPolicyX,
81
+ AlwaysAllowPrivacyPolicy,
82
+ AlwaysDenyPrivacyPolicy,
83
+ AllowIfConditionAppliesRule,
84
+ AllowIfSubPolicyAllowsRule,
85
+ AllowIfViewerPrivacyPolicy,
86
+ AllowIfViewerHasIdentityPrivacyPolicy,
87
+ } from "./core/privacy";
88
+ export * from "./core/query";
89
+ export * from "./core/query_impl";
90
+
91
+ export * from "./schema/";
92
+ import * as q from "./core/clause";
93
+ export { Clause } from "./core/clause";
94
+ const query = {
95
+ Eq: q.Eq,
96
+ NotEq: q.NotEq,
97
+ And: q.And,
98
+ AndOptional: q.AndOptional,
99
+ Or: q.Or,
100
+ OrOptional: q.OrOptional,
101
+ In: q.In,
102
+ UuidIn: q.UuidIn,
103
+ IntegerIn: q.IntegerIn,
104
+ TextIn: q.TextIn,
105
+ DBTypeIn: q.DBTypeIn,
106
+ UuidNotIn: q.UuidNotIn,
107
+ IntegerNotIn: q.IntegerNotIn,
108
+ TextNotIn: q.TextNotIn,
109
+ DBTypeNotIn: q.DBTypeNotIn,
110
+ Greater: q.Greater,
111
+ Less: q.Less,
112
+ GreaterEq: q.GreaterEq,
113
+ LessEq: q.LessEq,
114
+ ArrayEq: q.ArrayEq,
115
+ ArrayNotEq: q.ArrayNotEq,
116
+ PostgresArrayContainsValue: q.PostgresArrayContainsValue,
117
+ PostgresArrayContains: q.PostgresArrayContains,
118
+ PostgresArrayNotContainsValue: q.PostgresArrayNotContainsValue,
119
+ PostgresArrayNotContains: q.PostgresArrayNotContains,
120
+ PostgresArrayOverlaps: q.PostgresArrayOverlaps,
121
+ PostgresArrayNotOverlaps: q.PostgresArrayNotOverlaps,
122
+ JSONPathValuePredicate: q.JSONPathValuePredicate,
123
+ JSONObjectFieldKeyASJSON: q.JSONObjectFieldKeyASJSON,
124
+ JSONObjectFieldKeyAsText: q.JSONObjectFieldKeyAsText,
125
+ TsQuery: q.TsQuery,
126
+ PlainToTsQuery: q.PlainToTsQuery,
127
+ PhraseToTsQuery: q.PhraseToTsQuery,
128
+ WebsearchToTsQuery: q.WebsearchToTsQuery,
129
+ TsVectorColTsQuery: q.TsVectorColTsQuery,
130
+ TsVectorPlainToTsQuery: q.TsVectorPlainToTsQuery,
131
+ TsVectorPhraseToTsQuery: q.TsVectorPhraseToTsQuery,
132
+ TsVectorWebsearchToTsQuery: q.TsVectorWebsearchToTsQuery,
133
+ };
134
+
135
+ export { query };
136
+
137
+ export { RequestContext, ContextCache } from "./core/context";
138
+
139
+ export { IDViewer, LoggedOutViewer, IDViewerOptions } from "./core/viewer";
140
+
141
+ export { loadConfig } from "./core/config";
142
+
143
+ export { setLogLevels } from "./core/logger";
144
+
145
+ export * from "./core/convert";
@@ -0,0 +1,585 @@
1
+ import { cosmiconfigSync } from "cosmiconfig";
2
+ import { PACKAGE } from "../core/const";
3
+ import {
4
+ Pattern,
5
+ Schema,
6
+ Field,
7
+ AssocEdge,
8
+ AssocEdgeGroup,
9
+ Action,
10
+ EdgeAction,
11
+ } from "../schema";
12
+ import {
13
+ ActionField,
14
+ Type,
15
+ FieldMap,
16
+ GlobalSchema,
17
+ TransformReadBetaResult,
18
+ CanViewerDo,
19
+ EdgeGroupAction,
20
+ } from "../schema/schema";
21
+ import { setGlobalSchema } from "../core/global_schema";
22
+
23
+ export async function processFields(
24
+ src: FieldMap | Field[],
25
+ patternName?: string,
26
+ ): Promise<ProcessedField[]> {
27
+ const ret: ProcessedField[] = [];
28
+ let m: FieldMap = {};
29
+ if (Array.isArray(src)) {
30
+ for (const field of src) {
31
+ const name = field.name;
32
+ if (!name) {
33
+ throw new Error(`name is required`);
34
+ }
35
+ m[name] = field;
36
+ }
37
+ } else {
38
+ m = src;
39
+ }
40
+ for (const name in m) {
41
+ const field = m[name];
42
+ //@ts-ignore type and other changed fields with different type in ProcessedField vs Field
43
+ let f: ProcessedField = { ...field, name };
44
+ f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
45
+ f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
46
+ f.hasFieldPrivacy = field.privacyPolicy !== undefined;
47
+ f.hasEditFieldPrivacy = field.editPrivacyPolicy !== undefined;
48
+ if (field.polymorphic) {
49
+ // convert boolean into object
50
+ // we keep boolean as an option to keep API simple
51
+ if (typeof field.polymorphic === "boolean") {
52
+ f.polymorphic = {};
53
+ } else {
54
+ f.polymorphic = field.polymorphic;
55
+ }
56
+ } else {
57
+ delete f.polymorphic;
58
+ }
59
+ if (field.private) {
60
+ // convert boolean into object
61
+ // we keep boolean as an option to keep API simple
62
+ if (typeof field.private === "boolean") {
63
+ f.private = {};
64
+ } else {
65
+ f.private = field.private;
66
+ }
67
+ } else {
68
+ delete f.private;
69
+ }
70
+ // convert string to object to make API consumed by go simple
71
+ if (f.fieldEdge && f.fieldEdge.inverseEdge) {
72
+ if (typeof f.fieldEdge.inverseEdge === "string") {
73
+ f.fieldEdge.inverseEdge = {
74
+ name: f.fieldEdge.inverseEdge,
75
+ };
76
+ }
77
+ }
78
+ if (patternName) {
79
+ f.patternName = patternName;
80
+ }
81
+ if (field.serverDefault !== undefined) {
82
+ f.serverDefault = await transformServerDefault(
83
+ name,
84
+ field,
85
+ field.serverDefault,
86
+ );
87
+ }
88
+
89
+ transformType(field.type);
90
+
91
+ if (field.getDerivedFields) {
92
+ f.derivedFields = await processFields(field.getDerivedFields(name));
93
+ }
94
+ if (field.type.subFields) {
95
+ f.type.subFields = await processFields(field.type.subFields);
96
+ }
97
+ if (field.type.unionFields) {
98
+ f.type.unionFields = await processFields(field.type.unionFields);
99
+ }
100
+ if (
101
+ field.type.listElemType &&
102
+ field.type.listElemType.subFields &&
103
+ // check to avoid ts-ignore below. exists just for tsc
104
+ f.type.listElemType
105
+ ) {
106
+ f.type.listElemType.subFields = await processFields(
107
+ field.type.listElemType.subFields,
108
+ );
109
+ }
110
+ ret.push(f);
111
+ }
112
+ return ret;
113
+ }
114
+
115
+ async function transformServerDefault(name: string, f: Field, value: any) {
116
+ if (f.valid) {
117
+ if (!(await f.valid(value))) {
118
+ throw new Error(`invalid value ${value} passed to field ${name}`);
119
+ }
120
+ }
121
+ if (f.format) {
122
+ value = await f.format(value);
123
+ }
124
+ switch (typeof value) {
125
+ case "boolean":
126
+ case "number":
127
+ case "bigint":
128
+ case "string":
129
+ return `${value}`;
130
+ default:
131
+ throw new Error(`invalid value ${value} passed to field ${name}`);
132
+ }
133
+ }
134
+
135
+ function transformImportType(typ: Type) {
136
+ if (!typ.importType) {
137
+ return;
138
+ }
139
+ typ.importType = {
140
+ ...typ.importType,
141
+ // these 2 needed for forwards compatibility with new go schema
142
+ importPath: typ.importType.path,
143
+ import: typ.importType.type,
144
+ };
145
+ }
146
+
147
+ function transformType(typ: Type | undefined) {
148
+ if (!typ) {
149
+ return;
150
+ }
151
+ transformImportType(typ);
152
+ transformType(typ.listElemType);
153
+ }
154
+
155
+ function processEdges(
156
+ src: AssocEdge[],
157
+ patternName?: string,
158
+ ): ProcessedAssocEdge[] {
159
+ const ret: ProcessedAssocEdge[] = [];
160
+ for (const edge of src) {
161
+ let edge2 = { ...edge } as ProcessedAssocEdge;
162
+ edge2.edgeActions = edge.edgeActions?.map((action) =>
163
+ processAction(action),
164
+ );
165
+ edge2.patternName = patternName;
166
+ ret.push(edge2);
167
+ }
168
+ return ret;
169
+ }
170
+
171
+ function processEdgeGroups(
172
+ processedSchema: ProcessedSchema,
173
+ edgeGroups: AssocEdgeGroup[],
174
+ ) {
175
+ // array-ify this
176
+ for (const group of edgeGroups) {
177
+ if (group.nullStates && !Array.isArray(group.nullStates)) {
178
+ group.nullStates = [group.nullStates];
179
+ }
180
+ let group2 = { ...group } as ProcessedAssocEdgeGroup;
181
+ if (group.edgeAction) {
182
+ group2.edgeAction = processAction(group.edgeAction);
183
+ }
184
+ processedSchema.assocEdgeGroups.push(group2);
185
+ }
186
+ }
187
+
188
+ async function processPattern(
189
+ patterns: patternsDict,
190
+ pattern: Pattern,
191
+ processedSchema: ProcessedSchema,
192
+ ): Promise<TransformFlags> {
193
+ let ret: TransformFlags = {
194
+ ...pattern,
195
+ };
196
+ const name = pattern.name;
197
+ const fields = await processFields(pattern.fields, pattern.name);
198
+ processedSchema.fields.push(...fields);
199
+ if (pattern.edges) {
200
+ const edges = processEdges(pattern.edges, pattern.name);
201
+ processedSchema.assocEdges.push(...edges);
202
+ }
203
+
204
+ // flag transformsSelect
205
+ if (pattern.transformRead) {
206
+ ret.transformsSelect = true;
207
+
208
+ if (pattern.transformReadCodegen_BETA) {
209
+ const r = pattern.transformReadCodegen_BETA();
210
+ if (typeof r === "string") {
211
+ ret.transformsLoaderCodegen = {
212
+ code: r,
213
+ imports: [
214
+ {
215
+ importPath: PACKAGE,
216
+ import: "query",
217
+ },
218
+ ],
219
+ };
220
+ } else {
221
+ ret.transformsLoaderCodegen = r;
222
+ }
223
+ }
224
+ }
225
+
226
+ if (patterns[name] === undefined) {
227
+ // intentionally processing separately and not passing pattern.name
228
+ const edges = processEdges(pattern.edges || []);
229
+ patterns[name] = {
230
+ name: pattern.name,
231
+ assocEdges: edges,
232
+ fields: fields,
233
+ disableMixin: pattern.disableMixin,
234
+ };
235
+ } else {
236
+ // TODO ideally we want to make sure that different patterns don't have the same name
237
+ // can't do a deepEqual check because function calls and therefore different instances in fields
238
+ }
239
+ return ret;
240
+ }
241
+
242
+ enum NullableResult {
243
+ CONTENTS = "contents",
244
+ CONTENTS_AND_LIST = "contentsAndList",
245
+ ITEM = "true", // nullable = true
246
+ }
247
+
248
+ type ProcessedActionField = Omit<ActionField, "nullable"> & {
249
+ nullable?: NullableResult;
250
+ };
251
+
252
+ type ProcessedAssocEdge = Omit<
253
+ AssocEdge,
254
+ "actionOnlyFields" | "edgeActions"
255
+ > & {
256
+ // indicates edge is part of a pattern and should reference that pattern
257
+ // e.g. use pattern's const, pattern edgequery base class etc
258
+ // set via framework
259
+ patternName?: string;
260
+ edgeActions?: OutputAction[];
261
+ };
262
+
263
+ interface TransformFlags {
264
+ // we don't necessary use all of the below but we flag it for now
265
+ // in case we end up using it in the future
266
+ // we only care
267
+ // meaning there needs to be a way to load without transformation
268
+ transformsSelect?: boolean;
269
+ // meaning there needs to be a way to actually delete
270
+ transformsDelete?: boolean;
271
+
272
+ transformsLoaderCodegen?: TransformReadBetaResult;
273
+
274
+ transformsInsert?: boolean;
275
+ transformsUpdate?: boolean;
276
+ }
277
+
278
+ type ProcessedSchema = Omit<
279
+ Schema,
280
+ "edges" | "actions" | "edgeGroups" | "fields"
281
+ > &
282
+ TransformFlags & {
283
+ actions: OutputAction[];
284
+ assocEdges: ProcessedAssocEdge[];
285
+ assocEdgeGroups: ProcessedAssocEdgeGroup[];
286
+ // converting to list for go because we want the order respected
287
+ // and go maps don't support order
288
+
289
+ fields: ProcessedField[];
290
+
291
+ schemaPath?: string;
292
+ patternNames?: string[];
293
+ };
294
+
295
+ type ProcessedAssocEdgeGroup = Omit<AssocEdgeGroup, "edgeAction"> & {
296
+ edgeAction?: OutputAction;
297
+ };
298
+
299
+ type OutputAction = Omit<Action, "actionOnlyFields" | "canViewerDo"> & {
300
+ actionOnlyFields?: ProcessedActionField[];
301
+ canViewerDo?: CanViewerDo;
302
+ };
303
+
304
+ function processAction(
305
+ action: Action | EdgeAction | EdgeGroupAction,
306
+ ): OutputAction {
307
+ const ret = { ...action } as OutputAction;
308
+ if (action.actionOnlyFields !== undefined) {
309
+ let actionOnlyFields: ProcessedActionField[] = action.actionOnlyFields.map(
310
+ (f) => {
311
+ let f2 = f as ProcessedActionField;
312
+ if (!f.nullable) {
313
+ delete f2.nullable;
314
+ return f2;
315
+ }
316
+ if (typeof f.nullable === "boolean") {
317
+ f2.nullable = NullableResult.ITEM;
318
+ } else {
319
+ if (f.nullable === "contentsAndList") {
320
+ f2.nullable = NullableResult.CONTENTS_AND_LIST;
321
+ } else if (f.nullable === "contents") {
322
+ f2.nullable = NullableResult.CONTENTS;
323
+ } else if (f.nullable === "true") {
324
+ // shouldn't happen but ran into weirdness where it did...
325
+ f2.nullable = NullableResult.ITEM;
326
+ }
327
+ }
328
+
329
+ return f2;
330
+ },
331
+ );
332
+ ret.actionOnlyFields = actionOnlyFields;
333
+ }
334
+
335
+ if (action.canViewerDo !== undefined) {
336
+ if (typeof action.canViewerDo !== "object") {
337
+ delete ret.canViewerDo;
338
+ ret.canViewerDo = {};
339
+ }
340
+ }
341
+
342
+ return ret;
343
+ }
344
+
345
+ interface schemasDict {
346
+ [key: string]: ProcessedSchema;
347
+ }
348
+
349
+ interface ProcessedPattern {
350
+ name: string;
351
+ assocEdges: ProcessedAssocEdge[];
352
+ fields: ProcessedField[];
353
+ disableMixin?: boolean;
354
+ }
355
+
356
+ type ProcessedType = Omit<
357
+ Type,
358
+ "subFields" | "listElemType" | "unionFields"
359
+ > & {
360
+ subFields?: ProcessedField[];
361
+ listElemType?: ProcessedType;
362
+ unionFields?: ProcessedField[];
363
+ };
364
+
365
+ export type ProcessedField = Omit<
366
+ Field,
367
+ | "defaultValueOnEdit"
368
+ | "defaultValueOnCreate"
369
+ | "privacyPolicy"
370
+ | "type"
371
+ | "serverDefault"
372
+ > & {
373
+ name: string;
374
+ hasDefaultValueOnCreate?: boolean;
375
+ hasDefaultValueOnEdit?: boolean;
376
+ patternName?: string;
377
+ hasFieldPrivacy?: boolean;
378
+ hasEditFieldPrivacy?: boolean;
379
+ derivedFields?: ProcessedField[];
380
+ type: ProcessedType;
381
+ serverDefault?: string;
382
+ };
383
+
384
+ interface patternsDict {
385
+ [key: string]: ProcessedPattern;
386
+ }
387
+
388
+ interface Result {
389
+ schemas: schemasDict;
390
+ patterns: patternsDict;
391
+ globalSchema?: ProcessedGlobalSchema;
392
+ config?: {
393
+ rome?: RomeConfig;
394
+ };
395
+ }
396
+
397
+ declare type PotentialSchemas = {
398
+ [key: string]: any;
399
+ };
400
+
401
+ interface InputSchema extends Schema {
402
+ schemaPath?: string;
403
+ }
404
+
405
+ export async function parseSchema(
406
+ potentialSchemas: PotentialSchemas,
407
+ globalSchema?: GlobalSchema,
408
+ ): Promise<Result> {
409
+ let schemas: schemasDict = {};
410
+ let patterns: patternsDict = {};
411
+ let parsedGlobalSchema: ProcessedGlobalSchema | undefined;
412
+
413
+ if (globalSchema) {
414
+ parsedGlobalSchema = await parseGlobalSchema(globalSchema);
415
+ // set this so that we can use it, if we're trying to process server default or anything
416
+ // that ends up parsing,validating and formatting fields
417
+ setGlobalSchema(globalSchema);
418
+ }
419
+ for (const key in potentialSchemas) {
420
+ const value = potentialSchemas[key];
421
+ let schema: InputSchema;
422
+ const name = value.constructor.name;
423
+ // named class e.g. new BaseEntSchema
424
+ switch (name) {
425
+ case "Function":
426
+ schema = new value();
427
+ break;
428
+ default:
429
+ // implicit schema or named class
430
+ schema = value;
431
+ }
432
+ let processedSchema: ProcessedSchema = {
433
+ fields: [],
434
+ fieldOverrides: schema.fieldOverrides,
435
+ schemaPath: schema.schemaPath,
436
+ tableName: schema.tableName,
437
+ enumTable: schema.enumTable,
438
+ dbRows: schema.dbRows,
439
+ constraints: schema.constraints,
440
+ indices: schema.indices,
441
+ hideFromGraphQL: schema.hideFromGraphQL,
442
+ actions: schema.actions?.map((action) => processAction(action)) || [],
443
+ assocEdges: [],
444
+ assocEdgeGroups: [],
445
+ customGraphQLInterfaces: schema.customGraphQLInterfaces,
446
+ supportUpsert: schema.supportUpsert,
447
+ showCanViewerSee: schema.showCanViewerSee,
448
+ showCanViewerEdit: schema.showCanViewerEdit,
449
+ };
450
+ // let's put patterns first just so we have id, created_at, updated_at first
451
+ // ¯\_(ツ)_/¯
452
+ let patternNames: string[] = [];
453
+ if (schema.patterns) {
454
+ for (const pattern of schema.patterns) {
455
+ const ret = await processPattern(patterns, pattern, processedSchema);
456
+ patternNames.push(pattern.name);
457
+ if (ret.transformsSelect) {
458
+ if (processedSchema.transformsSelect) {
459
+ throw new Error(
460
+ `can only have one pattern which transforms default querying behavior`,
461
+ );
462
+ }
463
+ processedSchema.transformsSelect = true;
464
+ if (ret.transformsLoaderCodegen) {
465
+ processedSchema.transformsLoaderCodegen =
466
+ ret.transformsLoaderCodegen;
467
+ }
468
+ }
469
+
470
+ if (ret.transformsDelete) {
471
+ if (processedSchema.transformsDelete) {
472
+ throw new Error(
473
+ `can only have one pattern which transforms default deletion behavior`,
474
+ );
475
+ }
476
+ processedSchema.transformsDelete = true;
477
+ }
478
+ }
479
+ }
480
+ const fields = await processFields(schema.fields);
481
+ processedSchema.fields.push(...fields);
482
+ processedSchema.patternNames = patternNames;
483
+ if (schema.edges) {
484
+ const edges = processEdges(schema.edges);
485
+ processedSchema.assocEdges.push(...edges);
486
+ }
487
+ if (schema.edgeGroups) {
488
+ processEdgeGroups(processedSchema, schema.edgeGroups);
489
+ }
490
+
491
+ schemas[key] = processedSchema;
492
+ }
493
+ const rome = translatePrettier();
494
+
495
+ return {
496
+ schemas,
497
+ patterns,
498
+ globalSchema: parsedGlobalSchema,
499
+ config: {
500
+ rome,
501
+ },
502
+ };
503
+ }
504
+
505
+ interface RomeConfig {
506
+ indentStyle?: string;
507
+ lineWidth?: number;
508
+ indentSize?: number;
509
+ quoteStyle?: string;
510
+ quoteProperties?: string;
511
+ trailingComma?: string;
512
+ }
513
+
514
+ function translatePrettier(): RomeConfig | undefined {
515
+ const r = cosmiconfigSync("prettier").search();
516
+ if (!r) {
517
+ return;
518
+ }
519
+ const ret: RomeConfig = {};
520
+ if (r.config.printWidth !== undefined) {
521
+ ret.lineWidth = parseInt(r.config.printWidth);
522
+ }
523
+ if (r.config.useTabs) {
524
+ ret.indentStyle = "tab";
525
+ } else {
526
+ ret.indentStyle = "space";
527
+ }
528
+ if (r.config.tabWidth !== undefined) {
529
+ ret.indentSize = parseInt(r.config.tabWidth);
530
+ }
531
+ if (r.config.singleQuote) {
532
+ ret.quoteStyle = "single";
533
+ } else {
534
+ ret.quoteStyle = "double";
535
+ }
536
+ if (r.config.quoteProps !== undefined) {
537
+ if (r.config.quoteProps === "consistent") {
538
+ // rome doesn't support this
539
+ ret.quoteProperties = "as-needed";
540
+ } else {
541
+ ret.quoteProperties = r.config.quoteProps;
542
+ }
543
+ }
544
+ if (r.config.trailingComma !== undefined) {
545
+ ret.trailingComma = r.config.trailingComma;
546
+ }
547
+ return ret;
548
+ }
549
+
550
+ interface ProcessedGlobalSchema {
551
+ globalEdges: ProcessedAssocEdge[];
552
+ extraEdgeFields: ProcessedField[];
553
+ init?: boolean;
554
+ transformsEdges?: boolean;
555
+ globalFields?: ProcessedField[];
556
+ }
557
+
558
+ async function parseGlobalSchema(
559
+ s: GlobalSchema,
560
+ ): Promise<ProcessedGlobalSchema> {
561
+ const ret: ProcessedGlobalSchema = {
562
+ globalEdges: [],
563
+ extraEdgeFields: [],
564
+ init:
565
+ !!s.extraEdgeFields ||
566
+ s.transformEdgeRead !== undefined ||
567
+ s.transformEdgeWrite !== undefined ||
568
+ s.fields !== undefined,
569
+ transformsEdges: !!s.transformEdgeRead || !!s.transformEdgeWrite,
570
+ };
571
+
572
+ if (s.extraEdgeFields) {
573
+ ret.extraEdgeFields = await processFields(s.extraEdgeFields);
574
+ }
575
+
576
+ if (s.edges) {
577
+ ret.globalEdges = processEdges(s.edges);
578
+ }
579
+
580
+ if (s.fields) {
581
+ ret.globalFields = await processFields(s.fields);
582
+ }
583
+
584
+ return ret;
585
+ }