@saltcorn/data 1.6.0-alpha.9 → 1.6.0-beta.10

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 (298) hide show
  1. package/dist/base-plugin/actions.d.ts +194 -65
  2. package/dist/base-plugin/actions.d.ts.map +1 -1
  3. package/dist/base-plugin/actions.js +220 -80
  4. package/dist/base-plugin/actions.js.map +1 -1
  5. package/dist/base-plugin/fieldviews.d.ts +1 -0
  6. package/dist/base-plugin/fieldviews.d.ts.map +1 -1
  7. package/dist/base-plugin/fieldviews.js +5 -2
  8. package/dist/base-plugin/fieldviews.js.map +1 -1
  9. package/dist/base-plugin/fileviews.d.ts +6 -0
  10. package/dist/base-plugin/fileviews.d.ts.map +1 -1
  11. package/dist/base-plugin/fileviews.js +14 -0
  12. package/dist/base-plugin/fileviews.js.map +1 -1
  13. package/dist/base-plugin/index.d.ts +220 -70
  14. package/dist/base-plugin/index.d.ts.map +1 -1
  15. package/dist/base-plugin/types.d.ts +26 -11
  16. package/dist/base-plugin/types.d.ts.map +1 -1
  17. package/dist/base-plugin/types.js +47 -13
  18. package/dist/base-plugin/types.js.map +1 -1
  19. package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
  20. package/dist/base-plugin/viewtemplates/edit.js +15 -11
  21. package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
  22. package/dist/base-plugin/viewtemplates/feed.d.ts.map +1 -1
  23. package/dist/base-plugin/viewtemplates/feed.js +1 -1
  24. package/dist/base-plugin/viewtemplates/feed.js.map +1 -1
  25. package/dist/base-plugin/viewtemplates/filter.d.ts.map +1 -1
  26. package/dist/base-plugin/viewtemplates/filter.js +13 -5
  27. package/dist/base-plugin/viewtemplates/filter.js.map +1 -1
  28. package/dist/base-plugin/viewtemplates/list.d.ts +2 -1
  29. package/dist/base-plugin/viewtemplates/list.d.ts.map +1 -1
  30. package/dist/base-plugin/viewtemplates/list.js +20 -2
  31. package/dist/base-plugin/viewtemplates/list.js.map +1 -1
  32. package/dist/base-plugin/viewtemplates/room.d.ts.map +1 -1
  33. package/dist/base-plugin/viewtemplates/room.js +1 -1
  34. package/dist/base-plugin/viewtemplates/room.js.map +1 -1
  35. package/dist/base-plugin/viewtemplates/show.d.ts.map +1 -1
  36. package/dist/base-plugin/viewtemplates/show.js +3 -0
  37. package/dist/base-plugin/viewtemplates/show.js.map +1 -1
  38. package/dist/db/fixtures.d.ts.map +1 -1
  39. package/dist/db/fixtures.js +31 -1
  40. package/dist/db/fixtures.js.map +1 -1
  41. package/dist/db/state.d.ts +9 -3
  42. package/dist/db/state.d.ts.map +1 -1
  43. package/dist/db/state.js +63 -16
  44. package/dist/db/state.js.map +1 -1
  45. package/dist/migrate.d.ts.map +1 -1
  46. package/dist/migrate.js +12 -5
  47. package/dist/migrate.js.map +1 -1
  48. package/dist/migrations/202603101553.d.ts +4 -0
  49. package/dist/migrations/202603101553.d.ts.map +1 -0
  50. package/dist/migrations/202603101553.js +22 -0
  51. package/dist/migrations/202603101553.js.map +1 -0
  52. package/dist/migrations/202604091531.d.ts +2 -0
  53. package/dist/migrations/202604091531.d.ts.map +1 -0
  54. package/dist/migrations/202604091531.js +9 -0
  55. package/dist/migrations/202604091531.js.map +1 -0
  56. package/dist/migrations/202604111200.d.ts +2 -0
  57. package/dist/migrations/202604111200.d.ts.map +1 -0
  58. package/dist/migrations/202604111200.js +15 -0
  59. package/dist/migrations/202604111200.js.map +1 -0
  60. package/dist/migrations/202604141200.d.ts +2 -0
  61. package/dist/migrations/202604141200.d.ts.map +1 -0
  62. package/dist/migrations/202604141200.js +14 -0
  63. package/dist/migrations/202604141200.js.map +1 -0
  64. package/dist/mobile-mocks/node/assert.d.ts +1 -0
  65. package/dist/mobile-mocks/node/assert.d.ts.map +1 -0
  66. package/dist/mobile-mocks/node/assert.js +2 -0
  67. package/dist/mobile-mocks/node/assert.js.map +1 -0
  68. package/dist/mobile-mocks/node/fs/promises.d.ts +1 -0
  69. package/dist/mobile-mocks/node/fs/promises.d.ts.map +1 -1
  70. package/dist/mobile-mocks/node/fs/promises.js +4 -0
  71. package/dist/mobile-mocks/node/fs/promises.js.map +1 -1
  72. package/dist/mobile-mocks/node/fs.d.ts +2 -0
  73. package/dist/mobile-mocks/node/fs.d.ts.map +1 -1
  74. package/dist/mobile-mocks/node/fs.js +36 -0
  75. package/dist/mobile-mocks/node/fs.js.map +1 -1
  76. package/dist/mobile-mocks/npm/npm-registry-fetch.d.ts +3 -0
  77. package/dist/mobile-mocks/npm/npm-registry-fetch.d.ts.map +1 -0
  78. package/dist/mobile-mocks/npm/npm-registry-fetch.js +3 -0
  79. package/dist/mobile-mocks/npm/npm-registry-fetch.js.map +1 -0
  80. package/dist/mobile-mocks/saltcorn/admin-models-tenant.d.ts +1 -0
  81. package/dist/mobile-mocks/saltcorn/admin-models-tenant.d.ts.map +1 -0
  82. package/dist/mobile-mocks/saltcorn/admin-models-tenant.js +2 -0
  83. package/dist/mobile-mocks/saltcorn/admin-models-tenant.js.map +1 -0
  84. package/dist/mobile-mocks/saltcorn/plugins-loader-plugin-installer.d.ts +1 -0
  85. package/dist/mobile-mocks/saltcorn/plugins-loader-plugin-installer.d.ts.map +1 -0
  86. package/dist/mobile-mocks/saltcorn/plugins-loader-plugin-installer.js +2 -0
  87. package/dist/mobile-mocks/saltcorn/plugins-loader-plugin-installer.js.map +1 -0
  88. package/dist/mobile-mocks/saltcorn/plugins-loader-stable-versioning.d.ts +1 -0
  89. package/dist/mobile-mocks/saltcorn/plugins-loader-stable-versioning.d.ts.map +1 -0
  90. package/dist/mobile-mocks/saltcorn/plugins-loader-stable-versioning.js +2 -0
  91. package/dist/mobile-mocks/saltcorn/plugins-loader-stable-versioning.js.map +1 -0
  92. package/dist/models/config.d.ts.map +1 -1
  93. package/dist/models/config.js +46 -1
  94. package/dist/models/config.js.map +1 -1
  95. package/dist/models/discovery.d.ts +14 -0
  96. package/dist/models/discovery.d.ts.map +1 -1
  97. package/dist/models/discovery.js +63 -0
  98. package/dist/models/discovery.js.map +1 -1
  99. package/dist/models/expression.d.ts +8 -5
  100. package/dist/models/expression.d.ts.map +1 -1
  101. package/dist/models/expression.js +77 -28
  102. package/dist/models/expression.js.map +1 -1
  103. package/dist/models/field.d.ts.map +1 -1
  104. package/dist/models/field.js +106 -19
  105. package/dist/models/field.js.map +1 -1
  106. package/dist/models/index.d.ts +13 -3
  107. package/dist/models/index.d.ts.map +1 -1
  108. package/dist/models/index.js +1 -1
  109. package/dist/models/index.js.map +1 -1
  110. package/dist/models/internal/push_message_helper.d.ts.map +1 -1
  111. package/dist/models/internal/push_message_helper.js +5 -2
  112. package/dist/models/internal/push_message_helper.js.map +1 -1
  113. package/dist/models/metadata.d.ts +2 -1
  114. package/dist/models/metadata.d.ts.map +1 -1
  115. package/dist/models/metadata.js +5 -0
  116. package/dist/models/metadata.js.map +1 -1
  117. package/dist/models/page.d.ts +1 -0
  118. package/dist/models/page.d.ts.map +1 -1
  119. package/dist/models/page.js +37 -19
  120. package/dist/models/page.js.map +1 -1
  121. package/dist/models/plugin.d.ts +59 -2
  122. package/dist/models/plugin.d.ts.map +1 -1
  123. package/dist/models/plugin.js +324 -3
  124. package/dist/models/plugin.js.map +1 -1
  125. package/dist/models/scheduler.d.ts.map +1 -1
  126. package/dist/models/scheduler.js +15 -5
  127. package/dist/models/scheduler.js.map +1 -1
  128. package/dist/models/table.d.ts +11 -1
  129. package/dist/models/table.d.ts.map +1 -1
  130. package/dist/models/table.js +344 -127
  131. package/dist/models/table.js.map +1 -1
  132. package/dist/models/trigger.d.ts +3 -1
  133. package/dist/models/trigger.d.ts.map +1 -1
  134. package/dist/models/trigger.js +38 -13
  135. package/dist/models/trigger.js.map +1 -1
  136. package/dist/models/user.d.ts.map +1 -1
  137. package/dist/models/user.js +5 -0
  138. package/dist/models/user.js.map +1 -1
  139. package/dist/models/view.d.ts +1 -0
  140. package/dist/models/view.d.ts.map +1 -1
  141. package/dist/models/view.js +74 -14
  142. package/dist/models/view.js.map +1 -1
  143. package/dist/models/workflow.d.ts.map +1 -1
  144. package/dist/models/workflow.js +6 -0
  145. package/dist/models/workflow.js.map +1 -1
  146. package/dist/models/workflow_run.d.ts.map +1 -1
  147. package/dist/models/workflow_run.js +3 -2
  148. package/dist/models/workflow_run.js.map +1 -1
  149. package/dist/models/workflow_step.d.ts +1 -1
  150. package/dist/models/workflow_step.d.ts.map +1 -1
  151. package/dist/models/workflow_step.js +2 -1
  152. package/dist/models/workflow_step.js.map +1 -1
  153. package/dist/plugin-helper.d.ts +3 -11
  154. package/dist/plugin-helper.d.ts.map +1 -1
  155. package/dist/plugin-helper.js +106 -60
  156. package/dist/plugin-helper.js.map +1 -1
  157. package/dist/standard-menu.d.ts.map +1 -1
  158. package/dist/standard-menu.js +19 -0
  159. package/dist/standard-menu.js.map +1 -1
  160. package/dist/tests/remote_query_helper.js +1 -1
  161. package/dist/tests/remote_query_helper.js.map +1 -1
  162. package/dist/utils.d.ts +15 -0
  163. package/dist/utils.d.ts.map +1 -1
  164. package/dist/utils.js +102 -5
  165. package/dist/utils.js.map +1 -1
  166. package/dist/viewable_fields.d.ts +3 -3
  167. package/dist/viewable_fields.d.ts.map +1 -1
  168. package/dist/viewable_fields.js +60 -16
  169. package/dist/viewable_fields.js.map +1 -1
  170. package/dist/web-mobile-commons.d.ts.map +1 -1
  171. package/dist/web-mobile-commons.js +2 -1
  172. package/dist/web-mobile-commons.js.map +1 -1
  173. package/package.json +12 -9
  174. package/webpack.config.js +12 -0
  175. package/dist/tests/actions.test.d.ts +0 -2
  176. package/dist/tests/actions.test.d.ts.map +0 -1
  177. package/dist/tests/actions.test.js +0 -936
  178. package/dist/tests/actions.test.js.map +0 -1
  179. package/dist/tests/auth.test.d.ts +0 -2
  180. package/dist/tests/auth.test.d.ts.map +0 -1
  181. package/dist/tests/auth.test.js +0 -824
  182. package/dist/tests/auth.test.js.map +0 -1
  183. package/dist/tests/auxtest.test.d.ts +0 -2
  184. package/dist/tests/auxtest.test.d.ts.map +0 -1
  185. package/dist/tests/auxtest.test.js +0 -562
  186. package/dist/tests/auxtest.test.js.map +0 -1
  187. package/dist/tests/base.test.d.ts +0 -2
  188. package/dist/tests/base.test.d.ts.map +0 -1
  189. package/dist/tests/base.test.js +0 -30
  190. package/dist/tests/base.test.js.map +0 -1
  191. package/dist/tests/calc.test.d.ts +0 -2
  192. package/dist/tests/calc.test.d.ts.map +0 -1
  193. package/dist/tests/calc.test.js +0 -1081
  194. package/dist/tests/calc.test.js.map +0 -1
  195. package/dist/tests/composite_pk.test.d.ts +0 -2
  196. package/dist/tests/composite_pk.test.d.ts.map +0 -1
  197. package/dist/tests/composite_pk.test.js +0 -98
  198. package/dist/tests/composite_pk.test.js.map +0 -1
  199. package/dist/tests/config.test.d.ts +0 -2
  200. package/dist/tests/config.test.d.ts.map +0 -1
  201. package/dist/tests/config.test.js +0 -86
  202. package/dist/tests/config.test.js.map +0 -1
  203. package/dist/tests/db.test.d.ts +0 -2
  204. package/dist/tests/db.test.d.ts.map +0 -1
  205. package/dist/tests/db.test.js +0 -178
  206. package/dist/tests/db.test.js.map +0 -1
  207. package/dist/tests/discover.test.d.ts +0 -2
  208. package/dist/tests/discover.test.d.ts.map +0 -1
  209. package/dist/tests/discover.test.js +0 -245
  210. package/dist/tests/discover.test.js.map +0 -1
  211. package/dist/tests/edit.test.d.ts +0 -2
  212. package/dist/tests/edit.test.d.ts.map +0 -1
  213. package/dist/tests/edit.test.js +0 -1161
  214. package/dist/tests/edit.test.js.map +0 -1
  215. package/dist/tests/email.test.d.ts +0 -2
  216. package/dist/tests/email.test.d.ts.map +0 -1
  217. package/dist/tests/email.test.js +0 -255
  218. package/dist/tests/email.test.js.map +0 -1
  219. package/dist/tests/exact_views.test.d.ts +0 -2
  220. package/dist/tests/exact_views.test.d.ts.map +0 -1
  221. package/dist/tests/exact_views.test.js +0 -1363
  222. package/dist/tests/exact_views.test.js.map +0 -1
  223. package/dist/tests/field.test.d.ts +0 -2
  224. package/dist/tests/field.test.d.ts.map +0 -1
  225. package/dist/tests/field.test.js +0 -588
  226. package/dist/tests/field.test.js.map +0 -1
  227. package/dist/tests/fieldviews.test.d.ts +0 -2
  228. package/dist/tests/fieldviews.test.d.ts.map +0 -1
  229. package/dist/tests/fieldviews.test.js +0 -74
  230. package/dist/tests/fieldviews.test.js.map +0 -1
  231. package/dist/tests/file.test.d.ts +0 -2
  232. package/dist/tests/file.test.d.ts.map +0 -1
  233. package/dist/tests/file.test.js +0 -148
  234. package/dist/tests/file.test.js.map +0 -1
  235. package/dist/tests/filter.test.d.ts +0 -2
  236. package/dist/tests/filter.test.d.ts.map +0 -1
  237. package/dist/tests/filter.test.js +0 -496
  238. package/dist/tests/filter.test.js.map +0 -1
  239. package/dist/tests/form.test.d.ts +0 -2
  240. package/dist/tests/form.test.d.ts.map +0 -1
  241. package/dist/tests/form.test.js +0 -264
  242. package/dist/tests/form.test.js.map +0 -1
  243. package/dist/tests/list.test.d.ts +0 -2
  244. package/dist/tests/list.test.d.ts.map +0 -1
  245. package/dist/tests/list.test.js +0 -1037
  246. package/dist/tests/list.test.js.map +0 -1
  247. package/dist/tests/models.test.d.ts +0 -2
  248. package/dist/tests/models.test.d.ts.map +0 -1
  249. package/dist/tests/models.test.js +0 -417
  250. package/dist/tests/models.test.js.map +0 -1
  251. package/dist/tests/page.test.d.ts +0 -2
  252. package/dist/tests/page.test.d.ts.map +0 -1
  253. package/dist/tests/page.test.js +0 -26
  254. package/dist/tests/page.test.js.map +0 -1
  255. package/dist/tests/page_group.test.d.ts +0 -2
  256. package/dist/tests/page_group.test.d.ts.map +0 -1
  257. package/dist/tests/page_group.test.js +0 -51
  258. package/dist/tests/page_group.test.js.map +0 -1
  259. package/dist/tests/plugin.test.d.ts +0 -2
  260. package/dist/tests/plugin.test.d.ts.map +0 -1
  261. package/dist/tests/plugin.test.js +0 -60
  262. package/dist/tests/plugin.test.js.map +0 -1
  263. package/dist/tests/show.test.d.ts +0 -2
  264. package/dist/tests/show.test.d.ts.map +0 -1
  265. package/dist/tests/show.test.js +0 -561
  266. package/dist/tests/show.test.js.map +0 -1
  267. package/dist/tests/state.test.d.ts +0 -2
  268. package/dist/tests/state.test.d.ts.map +0 -1
  269. package/dist/tests/state.test.js +0 -82
  270. package/dist/tests/state.test.js.map +0 -1
  271. package/dist/tests/table.test.d.ts +0 -2
  272. package/dist/tests/table.test.d.ts.map +0 -1
  273. package/dist/tests/table.test.js +0 -2717
  274. package/dist/tests/table.test.js.map +0 -1
  275. package/dist/tests/table_history.test.d.ts +0 -2
  276. package/dist/tests/table_history.test.d.ts.map +0 -1
  277. package/dist/tests/table_history.test.js +0 -413
  278. package/dist/tests/table_history.test.js.map +0 -1
  279. package/dist/tests/tag.test.d.ts +0 -2
  280. package/dist/tests/tag.test.d.ts.map +0 -1
  281. package/dist/tests/tag.test.js +0 -97
  282. package/dist/tests/tag.test.js.map +0 -1
  283. package/dist/tests/user.test.d.ts +0 -2
  284. package/dist/tests/user.test.d.ts.map +0 -1
  285. package/dist/tests/user.test.js +0 -441
  286. package/dist/tests/user.test.js.map +0 -1
  287. package/dist/tests/view.test.d.ts +0 -2
  288. package/dist/tests/view.test.d.ts.map +0 -1
  289. package/dist/tests/view.test.js +0 -699
  290. package/dist/tests/view.test.js.map +0 -1
  291. package/dist/tests/workflow.test.d.ts +0 -2
  292. package/dist/tests/workflow.test.d.ts.map +0 -1
  293. package/dist/tests/workflow.test.js +0 -303
  294. package/dist/tests/workflow.test.js.map +0 -1
  295. package/dist/tests/workflow_run.test.d.ts +0 -2
  296. package/dist/tests/workflow_run.test.d.ts.map +0 -1
  297. package/dist/tests/workflow_run.test.js +0 -922
  298. package/dist/tests/workflow_run.test.js.map +0 -1
@@ -9,7 +9,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
9
9
  return (mod && mod.__esModule) ? mod : { "default": mod };
10
10
  };
11
11
  const fetch = require("node-fetch");
12
- const vm = require("vm");
12
+ const { VM } = require("vm2");
13
+ const oldVm = require("vm");
13
14
  const table_1 = __importDefault(require("../models/table"));
14
15
  const eventlog_1 = __importDefault(require("../models/eventlog"));
15
16
  const view_1 = __importDefault(require("../models/view"));
@@ -31,6 +32,7 @@ const db = require("../db");
31
32
  const { isNode, isWeb, ppVal, getFetchProxyOptions } = require("../utils");
32
33
  const { available_languages } = require("../models/config");
33
34
  const MetaData = require("../models/metadata");
35
+ const assert_1 = require("assert");
34
36
  //action use cases: field modify, like/rate (insert join), notify, send row to webhook
35
37
  // todo add translation
36
38
  const consoleInterceptor = (state) => {
@@ -60,11 +62,13 @@ const emit_to_client = (user) => (data, userIds) => {
60
62
  }
61
63
  const safeIds = Array.isArray(userIds)
62
64
  ? userIds
63
- : userIds
64
- ? [userIds]
65
- : user?.id
66
- ? [user.id]
67
- : [];
65
+ : userIds === null
66
+ ? null
67
+ : userIds
68
+ ? [userIds]
69
+ : user?.id
70
+ ? [user.id]
71
+ : [];
68
72
  state.emitDynamicUpdate(db.getTenantSchema(), data, safeIds);
69
73
  };
70
74
  /**
@@ -77,7 +81,23 @@ const emit_to_client = (user) => (data, userIds) => {
77
81
  * @param opts.rest
78
82
  * @returns
79
83
  */
80
- const run_code = async ({ row, table, channel, configuration: { code, run_where }, user, ...rest }) => {
84
+ const run_code = async ({ row, table, channel, configuration, user, ...rest }) => {
85
+ let stripTypes = (s) => s;
86
+ let code;
87
+ try {
88
+ const { stripTypeScriptTypes } = require("module");
89
+ if (stripTypeScriptTypes)
90
+ stripTypes = stripTypeScriptTypes;
91
+ code = stripTypes(`async () =>{${configuration.code}
92
+ }`)
93
+ .replace("async () =>{", "")
94
+ .slice(0, -2);
95
+ }
96
+ catch (e) {
97
+ //console.error("strip error", e);
98
+ code = configuration.code;
99
+ }
100
+ const run_where = configuration.run_where;
81
101
  if (run_where === "Client page")
82
102
  return {
83
103
  eval_js: code,
@@ -139,7 +159,6 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
139
159
  const emitEvent = (eventType, channel, payload) => trigger_1.default.emitEvent(eventType, channel, user, payload);
140
160
  const fetchJSON = async (...args) => await (await fetch(...args)).json();
141
161
  const sysState = getState();
142
- const require = (nm) => sysState.codeNPMmodules[nm];
143
162
  const refreshSystemCache = async (which) => {
144
163
  //this worker
145
164
  if (which)
@@ -156,7 +175,7 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
156
175
  await getState().refresh(false);
157
176
  });
158
177
  };
159
- const f = vm.runInNewContext(`async () => {${code}\n}`, {
178
+ const sandbox = {
160
179
  Table: table_1.default,
161
180
  table,
162
181
  row,
@@ -171,6 +190,7 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
171
190
  fetch,
172
191
  emit_to_client: emit_to_client(user),
173
192
  run_js_code,
193
+ ...(isNode() ? { assert: assert_1.strict } : {}),
174
194
  tryCatchInTransaction: db.tryCatchInTransaction,
175
195
  commitAndBeginNewTransaction: db.commitAndBeginNewTransaction,
176
196
  commitBeginNewTransactionAndRefreshCache: async () => {
@@ -190,7 +210,7 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
190
210
  WorkflowRun: workflow_run_1.default,
191
211
  setTimeout,
192
212
  interpolate,
193
- require,
213
+ require: (nm) => sysState.codeNPMmodules[nm],
194
214
  refreshSystemCache,
195
215
  setConfig: (k, v) => sysState.isFixedConfig(k) ? undefined : sysState.setConfig(k, v),
196
216
  getConfig: (k) => sysState.isFixedConfig(k) ? undefined : sysState.getConfig(k),
@@ -202,8 +222,24 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
202
222
  ...(row || {}),
203
223
  ...getState().eval_context,
204
224
  ...rest,
205
- });
206
- return await f();
225
+ };
226
+ if (isNode()) {
227
+ const vm2 = new VM({ sandbox, eval: false, wasm: false });
228
+ const result = await vm2.run(`(async () => {${code}\n})()`);
229
+ if (result === null || result === undefined || typeof result !== "object")
230
+ return result;
231
+ try {
232
+ return JSON.parse(JSON.stringify(result));
233
+ }
234
+ catch {
235
+ return result;
236
+ }
237
+ }
238
+ else {
239
+ // on mobile, vm2 is not available
240
+ const f = oldVm.runInNewContext(`async () => {${code}\n}`, sandbox);
241
+ return await f();
242
+ }
207
243
  };
208
244
  module.exports = {
209
245
  /**
@@ -243,28 +279,64 @@ module.exports = {
243
279
  * @returns {object[]}
244
280
  */
245
281
  description: "Emit an event",
246
- configFields: () => [
247
- {
248
- name: "eventType",
249
- label: "Event type",
250
- required: true,
251
- input_type: "select",
252
- options: trigger_1.default.when_options,
253
- },
254
- {
255
- name: "channel",
256
- label: "Channel",
257
- type: "String",
258
- fieldview: "textarea",
259
- },
260
- {
261
- name: "payload",
262
- label: "Payload JSON",
263
- sublabel: "Leave blank to use row from table",
264
- type: "String",
265
- fieldview: "textarea",
266
- },
267
- ],
282
+ configFields: async ({ table }) => {
283
+ const evTypes = trigger_1.default.when_options;
284
+ const hasChannel = [];
285
+ const hasTable = [];
286
+ evTypes.forEach((ty) => {
287
+ if (eventlog_1.default.hasChannel(ty))
288
+ hasChannel.push(ty);
289
+ if (eventlog_1.default.hasTable(ty))
290
+ hasTable.push(ty);
291
+ });
292
+ const allTables = await table_1.default.find({}, { cached: true });
293
+ return [
294
+ {
295
+ name: "eventType",
296
+ label: "Event type",
297
+ required: true,
298
+ input_type: "select",
299
+ options: evTypes,
300
+ },
301
+ {
302
+ name: "channel",
303
+ label: "Channel",
304
+ type: "String",
305
+ showIf: { eventType: hasChannel },
306
+ help: {
307
+ topic: "Event channel and payload",
308
+ },
309
+ },
310
+ {
311
+ name: "channel",
312
+ label: "Table",
313
+ type: "String",
314
+ showIf: { eventType: hasTable },
315
+ required: true,
316
+ attributes: { options: allTables.map((t) => t.name) },
317
+ help: {
318
+ topic: "Event channel and payload",
319
+ },
320
+ },
321
+ {
322
+ name: "payload",
323
+ label: "Payload JSON",
324
+ sublabel: `Leave blank to use row from table. <code>user</code> ${table ? `and field variables ` : ""}in scope`,
325
+ input_type: "code",
326
+ attributes: {
327
+ mode: "application/javascript",
328
+ compact: true,
329
+ expression_type: "row",
330
+ table: table?.name,
331
+ nojoins: true,
332
+ user: true,
333
+ },
334
+ help: {
335
+ topic: "Event channel and payload",
336
+ },
337
+ },
338
+ ];
339
+ },
268
340
  /**
269
341
  * @param {object} opts
270
342
  * @param {object} opts.row
@@ -273,7 +345,7 @@ module.exports = {
273
345
  * @returns {Promise<void>}
274
346
  */
275
347
  run: async ({ row, configuration: { eventType, channel, payload }, user, }) => {
276
- return await trigger_1.default.emitEvent(eventType, channel, user, payload ? JSON.parse(payload) : row);
348
+ return await trigger_1.default.emitEvent(eventType, channel, user, payload ? eval_expression(payload, row || {}, user) : row);
277
349
  },
278
350
  namespace: "Control",
279
351
  },
@@ -302,7 +374,7 @@ module.exports = {
302
374
  {
303
375
  name: "where",
304
376
  label: "Where",
305
- sublabel: "Where-expression for subset of rows to loop over",
377
+ sublabel: `Where-expression for subset of rows to loop over. For example: <code>{status: "Active"}</code>`,
306
378
  input_type: "code",
307
379
  attributes: {
308
380
  mode: "application/javascript",
@@ -407,7 +479,7 @@ module.exports = {
407
479
  name: "url",
408
480
  label: "URL",
409
481
  type: "String",
410
- sublabel: "Trigger will call specified URL",
482
+ sublabel: "Trigger will call specified URL. Interpolations <code>{{ }}</code> can be used",
411
483
  },
412
484
  {
413
485
  name: "method",
@@ -419,16 +491,23 @@ module.exports = {
419
491
  {
420
492
  name: "body",
421
493
  label: "JSON body",
422
- sublabel: "Leave blank to use row from table",
423
- type: "String",
424
- fieldview: "textarea",
425
494
  showIf: { method: ["POST", "PUT", "DELETE", "PATCH"] },
495
+ sublabel: `Leave blank to use row from table.${table ? ` <code>user</code> and field variables in scope` : ""}`,
496
+ input_type: "code",
497
+ attributes: {
498
+ mode: "application/javascript",
499
+ compact: true,
500
+ expression_type: "row",
501
+ table: table?.name,
502
+ nojoins: true,
503
+ user: true,
504
+ },
426
505
  },
427
506
  {
428
507
  name: "authorization",
429
508
  label: "Authorization header",
430
509
  type: "String",
431
- sublabel: "For example <code>Bearer xxxx</code>",
510
+ sublabel: "For example <code>Bearer xxxx</code>. Interpolations <code>{{ }}</code> can be used",
432
511
  },
433
512
  ...(field_opts.length
434
513
  ? [
@@ -459,7 +538,7 @@ module.exports = {
459
538
  * @returns {Promise<object>}
460
539
  */
461
540
  run: async ({ row, user, table, configuration: { url, body, authorization, response_field, response_var, method, }, }) => {
462
- let url1 = interpolate(url, row, user, "Webhook URL");
541
+ let url1 = interpolate(url, row || {}, user, "Webhook URL");
463
542
  const fetchOpts = {
464
543
  method: (method || "post").toLowerCase(),
465
544
  headers: { "Content-Type": "application/json" },
@@ -1051,12 +1130,13 @@ module.exports = {
1051
1130
  {
1052
1131
  name: "where",
1053
1132
  label: "Recalculate where",
1054
- sublabel: "Where-expression for subset of rows to recalculate",
1133
+ sublabel: "Where-expression for subset of rows to recalculate. Example: <code>{manager: id}</code>",
1055
1134
  input_type: "code",
1056
1135
  attributes: {
1057
1136
  mode: "application/javascript",
1058
1137
  singleline: true,
1059
1138
  expression_type: "query",
1139
+ ...(table ? { table: table.name } : {}),
1060
1140
  },
1061
1141
  },
1062
1142
  ];
@@ -1101,7 +1181,7 @@ module.exports = {
1101
1181
  * @returns {Promise<object[]>}
1102
1182
  */
1103
1183
  description: "insert a row into any table, using a formula expression",
1104
- configFields: async ({ mode }) => {
1184
+ configFields: async ({ mode, table }) => {
1105
1185
  const tables = await table_1.default.find({}, { cached: true });
1106
1186
  return [
1107
1187
  {
@@ -1115,11 +1195,14 @@ module.exports = {
1115
1195
  name: "row_expr",
1116
1196
  label: "Row expression",
1117
1197
  sublabel: "Expression for JavaScript object or array of objects. Example: <code>{first_name: name.split(' ')[0]}</code>",
1118
- type: "String",
1119
- fieldview: "textarea",
1120
- class: "validate-expression",
1198
+ input_type: "code",
1121
1199
  attributes: {
1122
- spellcheck: false,
1200
+ mode: "application/javascript",
1201
+ compact: true,
1202
+ expression_type: "row",
1203
+ table: table?.name,
1204
+ nojoins: true,
1205
+ user: true,
1123
1206
  },
1124
1207
  },
1125
1208
  ...(mode === "workflow"
@@ -1197,7 +1280,7 @@ module.exports = {
1197
1280
  */
1198
1281
  modify_row: {
1199
1282
  description: "Modify the triggering row",
1200
- configFields: async ({ mode, when_trigger, }) => {
1283
+ configFields: async ({ mode, when_trigger, table, }) => {
1201
1284
  return [
1202
1285
  {
1203
1286
  name: "row_expr",
@@ -1208,6 +1291,9 @@ module.exports = {
1208
1291
  mode: "application/javascript",
1209
1292
  compact: true,
1210
1293
  expression_type: "row",
1294
+ table: table?.name,
1295
+ nojoins: true,
1296
+ user: true,
1211
1297
  },
1212
1298
  },
1213
1299
  ...(mode === "edit" ||
@@ -1298,7 +1384,7 @@ module.exports = {
1298
1384
  * @returns {Promise<object[]>}
1299
1385
  */
1300
1386
  description: "Modify the triggering row",
1301
- configFields: async ({ mode, when_trigger }) => {
1387
+ configFields: async ({ mode, table, when_trigger }) => {
1302
1388
  const tables = await table_1.default.find({}, { cached: true });
1303
1389
  return [
1304
1390
  ...(mode === "workflow"
@@ -1321,10 +1407,15 @@ module.exports = {
1321
1407
  {
1322
1408
  name: "delete_where",
1323
1409
  label: "Delete where",
1324
- type: "String",
1410
+ input_type: "code",
1411
+ attributes: {
1412
+ mode: "application/javascript",
1413
+ singleline: true,
1414
+ expression_type: "query",
1415
+ ...(table ? { table: table.name } : {}),
1416
+ },
1325
1417
  sublabel: "Where expression, ex. <code>{manager: id}</code>",
1326
1418
  required: true,
1327
- class: "validate-expression",
1328
1419
  showIf: mode === "workflow" ? undefined : { delete_triggering_row: false },
1329
1420
  },
1330
1421
  ];
@@ -1337,7 +1428,7 @@ module.exports = {
1337
1428
  await table.deleteRows({ [table.pk_name]: row[table.pk_name] }, user, false, resultCollector);
1338
1429
  return resultCollector;
1339
1430
  }
1340
- const where = eval_expression(delete_where, row || {}, user, "recalculate_stored_fields where");
1431
+ const where = eval_expression(delete_where, row || {}, user, "delete_rows where");
1341
1432
  const tbl = table_1.default.findOne({ name: table_name });
1342
1433
  await tbl.deleteRows(where, user, false, resultCollector);
1343
1434
  return resultCollector;
@@ -1356,7 +1447,7 @@ module.exports = {
1356
1447
  * @returns {Promise<object[]>}
1357
1448
  */
1358
1449
  description: "Navigation action",
1359
- configFields: async () => {
1450
+ configFields: async ({ table }) => {
1360
1451
  const pages = await page_1.default.find({}, { cached: true });
1361
1452
  const views = await view_1.default.find({}, { cached: true });
1362
1453
  return [
@@ -1384,6 +1475,7 @@ module.exports = {
1384
1475
  type: "String",
1385
1476
  required: true,
1386
1477
  showIf: { nav_action: ["Go to URL", "Popup modal"] },
1478
+ sublabel: "Use interpolations <code>{{ }}</code> to access row variables",
1387
1479
  },
1388
1480
  {
1389
1481
  name: "page",
@@ -1402,9 +1494,20 @@ module.exports = {
1402
1494
  {
1403
1495
  name: "state_formula",
1404
1496
  label: "State",
1405
- type: "String",
1406
- class: "validate-expression",
1497
+ input_type: "code",
1498
+ attributes: {
1499
+ mode: "application/javascript",
1500
+ singleline: true,
1501
+ expression_type: "query",
1502
+ ...(table ? { table: table.name } : {}),
1503
+ },
1407
1504
  showIf: { nav_action: ["Go to Page", "Go to View"] },
1505
+ sublabel: `Additional state passed to the page. Example: <code>{id: 5}</code>`,
1506
+ help: {
1507
+ topic: "Extra state formula",
1508
+ context: table ? { srcTable: table.name } : {},
1509
+ dynContext: ["view"],
1510
+ },
1408
1511
  },
1409
1512
  {
1410
1513
  name: "new_tab",
@@ -1515,18 +1618,26 @@ module.exports = {
1515
1618
  {
1516
1619
  name: "form_action",
1517
1620
  label: "Form Action",
1518
- type: "String",
1621
+ input_type: "select",
1519
1622
  required: true,
1520
1623
  attributes: {
1521
- options: [
1522
- "RequestSubmit",
1523
- "Submit",
1524
- "Save",
1525
- "Reset",
1526
- "Submit with Ajax",
1527
- "Ajax Save Form Data",
1528
- ],
1624
+ explainers: {
1625
+ RequestSubmit: "Validate the form, and submit if no errors, or display errors",
1626
+ Submit: "Submit the form, skipping validation",
1627
+ Save: "Save the form contents on the server, stay on the form page",
1628
+ Reset: "Reset the form to the state it was in at page load time",
1629
+ "Submit with Ajax": "Submit the form with Ajax and follow the set destination if there are no errors",
1630
+ "Ajax Save Form Data": "Submit the form with Ajax and close the open popup ",
1631
+ },
1529
1632
  },
1633
+ options: [
1634
+ "RequestSubmit",
1635
+ "Submit",
1636
+ "Save",
1637
+ "Reset",
1638
+ "Submit with Ajax",
1639
+ "Ajax Save Form Data",
1640
+ ],
1530
1641
  },
1531
1642
  ],
1532
1643
  run: async ({ row, table, user, req, configuration: { form_action }, ...rest }) => {
@@ -1648,12 +1759,13 @@ module.exports = {
1648
1759
  label: "Text",
1649
1760
  type: "String",
1650
1761
  required: true,
1762
+ sublabel: "Interpolations <code>{{ }}</code> can be used",
1651
1763
  },
1652
1764
  {
1653
1765
  name: "title",
1654
1766
  label: "Title",
1655
- sublabel: "Optional",
1656
1767
  type: "String",
1768
+ sublabel: "Optional. Interpolations <code>{{ }}</code> can be used",
1657
1769
  },
1658
1770
  {
1659
1771
  name: "remove_delay",
@@ -1745,15 +1857,23 @@ module.exports = {
1745
1857
  table: table?.name || undefined,
1746
1858
  user: has_user,
1747
1859
  workflow: mode === "workflow",
1860
+ nojoins: true,
1748
1861
  },
1749
- class: [
1750
- "validate-statements",
1751
- mode !== "workflow" && "enlarge-in-card",
1752
- ],
1862
+ class: `validate-statements strip-types ${mode !== "workflow" ? "enlarge-in-card" : ""}`,
1753
1863
  validator(s) {
1864
+ let stripTypes = (s) => s;
1865
+ try {
1866
+ const { stripTypeScriptTypes } = require("module");
1867
+ if (stripTypeScriptTypes)
1868
+ stripTypes = stripTypeScriptTypes;
1869
+ }
1870
+ catch (e) {
1871
+ //ignore
1872
+ }
1754
1873
  try {
1755
1874
  let AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
1756
- AsyncFunction(s);
1875
+ AsyncFunction(stripTypes(`async () =>{${s}
1876
+ }`));
1757
1877
  return true;
1758
1878
  }
1759
1879
  catch (e) {
@@ -1894,7 +2014,7 @@ module.exports = {
1894
2014
  const views = await view_1.default.find_table_views_where(table, ({ viewtemplate, viewrow, state_fields }) => viewrow.viewtemplate === "Edit");
1895
2015
  const fldOpts = fields.map((f) => ({
1896
2016
  label: f.name,
1897
- name: f.name,
2017
+ name: `_prefill_${f.name}`,
1898
2018
  default: f.name !== "id",
1899
2019
  type: "Bool",
1900
2020
  }));
@@ -1912,9 +2032,12 @@ module.exports = {
1912
2032
  requireRow: true,
1913
2033
  run: async ({ row, table, configuration: { viewname, ...flds }, user, }) => {
1914
2034
  const qs = Object.entries(flds)
1915
- .map(([k, v]) => v && typeof row[k] !== "undefined"
1916
- ? `${encodeURIComponent(k)}=${encodeURIComponent(row[k])}`
1917
- : false)
2035
+ .map(([prefill_k, v]) => {
2036
+ const k = prefill_k.replace("_prefill_", "");
2037
+ return v && typeof row[k] !== "undefined"
2038
+ ? `${encodeURIComponent(k)}=${encodeURIComponent(row[k])}`
2039
+ : false;
2040
+ })
1918
2041
  .filter((s) => s)
1919
2042
  .join("&");
1920
2043
  return { goto: `/view/${viewname}?${qs}` };
@@ -2126,7 +2249,7 @@ module.exports = {
2126
2249
  },
2127
2250
  reload_embedded_view: {
2128
2251
  description: "Reload an embedded view without full page reload",
2129
- configFields: async () => {
2252
+ configFields: async ({ table }) => {
2130
2253
  const views = await view_1.default.find({});
2131
2254
  return [
2132
2255
  {
@@ -2140,8 +2263,19 @@ module.exports = {
2140
2263
  {
2141
2264
  name: "new_state_fml",
2142
2265
  label: "New state formula",
2143
- type: "String",
2144
- class: "validate-expression",
2266
+ input_type: "code",
2267
+ attributes: {
2268
+ mode: "application/javascript",
2269
+ singleline: true,
2270
+ expression_type: "row",
2271
+ ...(table ? { table: table.name } : {}),
2272
+ },
2273
+ sublabel: `Optional. Updated view state. Example: <code>{id: 5}</code>. Leave blank to keep existing state`,
2274
+ help: {
2275
+ topic: "Extra state formula",
2276
+ context: table ? { srcTable: table.name } : {},
2277
+ dynContext: ["view"],
2278
+ },
2145
2279
  },
2146
2280
  {
2147
2281
  name: "interval",
@@ -2185,7 +2319,7 @@ module.exports = {
2185
2319
  type: "String",
2186
2320
  class: "validate-identifier",
2187
2321
  required: true,
2188
- sublabel: "A valid JavaScript identifier for updating existing progress toasts",
2322
+ sublabel: "A valid JavaScript identifier for updating existing progress toasts. Interpolations <code>{{ }}</code> can be used",
2189
2323
  showIf: { blocking: false },
2190
2324
  },
2191
2325
  {
@@ -2206,12 +2340,14 @@ module.exports = {
2206
2340
  label: "Title",
2207
2341
  type: "String",
2208
2342
  showIf: { close: false },
2343
+ sublabel: "Use interpolations <code>{{ }}</code> to access row variables",
2209
2344
  },
2210
2345
  {
2211
2346
  name: "message",
2212
2347
  label: "Message",
2213
2348
  type: "String",
2214
2349
  showIf: { close: false },
2350
+ sublabel: "Use interpolations <code>{{ }}</code> to access row variables",
2215
2351
  },
2216
2352
  {
2217
2353
  name: "percent",
@@ -2283,27 +2419,31 @@ module.exports = {
2283
2419
  },
2284
2420
  notify_user: {
2285
2421
  description: "Send a notification to a specific user",
2286
- configFields: () => [
2422
+ configFields: ({ table }) => [
2287
2423
  {
2288
2424
  name: "user_spec",
2289
2425
  label: "User where or email",
2290
2426
  type: "String",
2427
+ sublabel: `Valid input: <code>*</code> for all, a valid email address, or a where object, e.g. <code>{department: "Finance"}</code>${table ? ". Row values are in scope for where object." : ""}`,
2291
2428
  },
2292
2429
  {
2293
2430
  name: "title",
2294
2431
  label: "Title",
2295
2432
  required: true,
2296
2433
  type: "String",
2434
+ sublabel: "<code>{{ }}</code> interpolations usable",
2297
2435
  },
2298
2436
  {
2299
2437
  name: "body",
2300
2438
  label: "Body",
2301
2439
  type: "String",
2440
+ sublabel: "<code>{{ }}</code> interpolations usable",
2302
2441
  },
2303
2442
  {
2304
2443
  name: "link",
2305
2444
  label: "Link",
2306
2445
  type: "String",
2446
+ sublabel: "<code>{{ }}</code> interpolations usable",
2307
2447
  },
2308
2448
  ],
2309
2449
  /**