@saltcorn/data 0.6.1-beta.0 → 0.6.1

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 (60) hide show
  1. package/base-plugin/actions.js +172 -1
  2. package/base-plugin/fieldviews.js +63 -0
  3. package/base-plugin/fileviews.js +41 -0
  4. package/base-plugin/index.js +35 -0
  5. package/base-plugin/types.js +345 -9
  6. package/base-plugin/viewtemplates/edit.js +107 -0
  7. package/base-plugin/viewtemplates/feed.js +46 -0
  8. package/base-plugin/viewtemplates/filter.js +43 -0
  9. package/base-plugin/viewtemplates/list.js +73 -1
  10. package/base-plugin/viewtemplates/listshowlist.js +54 -3
  11. package/base-plugin/viewtemplates/room.js +100 -0
  12. package/base-plugin/viewtemplates/show.js +86 -0
  13. package/base-plugin/viewtemplates/viewable_fields.js +124 -0
  14. package/contracts.js +58 -0
  15. package/db/connect.js +13 -5
  16. package/db/db.test.js +0 -154
  17. package/db/fixtures.js +13 -1
  18. package/db/index.js +42 -3
  19. package/db/reset_schema.js +11 -0
  20. package/db/state.js +105 -36
  21. package/index.js +13 -0
  22. package/migrate.js +4 -1
  23. package/models/backup.js +78 -0
  24. package/models/config.js +113 -22
  25. package/models/crash.js +44 -0
  26. package/models/discovery.js +13 -11
  27. package/models/email.js +17 -0
  28. package/models/eventlog.js +51 -0
  29. package/models/expression.js +49 -1
  30. package/models/field.js +88 -9
  31. package/models/fieldrepeat.js +33 -0
  32. package/models/file.js +23 -4
  33. package/models/form.js +34 -0
  34. package/models/index.js +42 -0
  35. package/models/layout.js +33 -0
  36. package/models/library.js +44 -0
  37. package/models/pack.js +88 -0
  38. package/models/page.js +13 -3
  39. package/models/plugin.js +9 -2
  40. package/models/random.js +36 -0
  41. package/models/role.js +36 -0
  42. package/models/scheduler.js +28 -0
  43. package/models/table.js +34 -15
  44. package/models/table_constraints.js +44 -0
  45. package/models/tenant.js +46 -9
  46. package/models/trigger.js +24 -11
  47. package/models/user.js +33 -8
  48. package/models/view.js +89 -8
  49. package/models/workflow.js +31 -0
  50. package/package.json +7 -5
  51. package/plugin-helper.js +102 -44
  52. package/plugin-testing.js +4 -0
  53. package/tests/exact_views.test.js +5 -5
  54. package/utils.js +4 -0
  55. package/db/internal.js +0 -229
  56. package/db/multi-tenant.js +0 -24
  57. package/db/pg.js +0 -374
  58. package/db/single-tenant.js +0 -8
  59. package/db/sqlite.js +0 -280
  60. package/db/tenants.js +0 -6
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @category saltcorn-data
3
+ * @module base-plugin/viewtemplates/room
4
+ * @subcategory base-plugin
5
+ */
1
6
  const Field = require("../../models/field");
2
7
  const Table = require("../../models/table");
3
8
  const Form = require("../../models/form");
@@ -30,6 +35,11 @@ const { getState } = require("../../db/state");
30
35
  const db = require("../../db");
31
36
  const { getForm, fill_presets } = require("./viewable_fields");
32
37
 
38
+ /**
39
+ *
40
+ * @param {object} req
41
+ * @returns {Workflow}
42
+ */
33
43
  const configuration_workflow = (req) =>
34
44
  new Workflow({
35
45
  steps: [
@@ -160,6 +170,9 @@ const configuration_workflow = (req) =>
160
170
  ],
161
171
  });
162
172
 
173
+ /**
174
+ * @returns {object[]}
175
+ */
163
176
  const get_state_fields = () => [
164
177
  {
165
178
  name: "id",
@@ -170,6 +183,23 @@ const get_state_fields = () => [
170
183
  ];
171
184
  const limit = 10;
172
185
 
186
+ /**
187
+ * @param {string} table_id
188
+ * @param {string} viewname
189
+ * @param {object} optsOne
190
+ * @param {string} optsOne.participant_field,
191
+ * @param {string} optsOne.msg_relation
192
+ * @param {*} optsOne.msgsender_field
193
+ * @param {string} optsOne.msgview
194
+ * @param {string} optsOne.msgform
195
+ * @param {string} optsOne.participant_maxread_field
196
+ * @param {object} state
197
+ * @param {object} optsTwo
198
+ * @param {object} optsTwo.req
199
+ * @param {object} optsTwo.res
200
+ * @returns {Promise<div>}
201
+ * @throws {InvalidConfiguration}
202
+ */
173
203
  const run = async (
174
204
  table_id,
175
205
  viewname,
@@ -274,6 +304,18 @@ const run = async (
274
304
  );
275
305
  };
276
306
 
307
+ /**
308
+ * @param {*} table_id
309
+ * @param {*} viewname
310
+ * @param {object} optsOne
311
+ * @param {string} optsOne.participant_field
312
+ * @param {string} optsOne.participant_maxread_field
313
+ * @param {body} body
314
+ * @param {object} optsTwo
315
+ * @param {object} optsTwo.req
316
+ * @param {object} optsTwo.res
317
+ * @returns {Promise<void>}
318
+ */
277
319
  const ack_read = async (
278
320
  table_id,
279
321
  viewname,
@@ -321,6 +363,23 @@ const ack_read = async (
321
363
  },
322
364
  };
323
365
  };
366
+
367
+ /**
368
+ * @param {*} table_id
369
+ * @param {*} viewname
370
+ * @param {object} optsOne.
371
+ * @param {string} optsOne.participant_field
372
+ * @param {string} optsOne.msg_relation
373
+ * @param {*} optsOne.msgsender_field
374
+ * @param {string} optsOne.msgview
375
+ * @param {*} optsOne.msgform
376
+ * @param {*} optsOne.participant_maxread_field
377
+ * @param {object} body
378
+ * @param {object} optsTwo
379
+ * @param {object} optsTwo.req
380
+ * @param {object} optsTwo.res
381
+ * @returns {Promise<object>}
382
+ */
324
383
  const fetch_older_msg = async (
325
384
  table_id,
326
385
  viewname,
@@ -384,6 +443,23 @@ const fetch_older_msg = async (
384
443
  },
385
444
  };
386
445
  };
446
+
447
+ /**
448
+ * @param {*} table_id
449
+ * @param {string} viewname
450
+ * @param {object} optsOne
451
+ * @param {string} optsOne.participant_field
452
+ * @param {string} optsOne.msg_relation
453
+ * @param {*} optsOne.msgsender_field
454
+ * @param {string} optsOne.msgview
455
+ * @param {string} optsOne.msgform
456
+ * @param {string} optsOne.participant_maxread_field
457
+ * @param {*} body
458
+ * @param {object} optsTwo
459
+ * @param {object} optsTwo.req
460
+ * @param {object} optsTwo.res
461
+ * @returns {Promise<object>}
462
+ */
387
463
  const submit_msg_ajax = async (
388
464
  table_id,
389
465
  viewname,
@@ -472,6 +548,18 @@ const submit_msg_ajax = async (
472
548
  }
473
549
  };
474
550
 
551
+ /**
552
+ * @param {*} table_id
553
+ * @param {string} viewname
554
+ * @param {object} opts
555
+ * @param {*} opts.participant_field
556
+ * @param {string} opts.msg_relation,
557
+ * @param {string} opts.msgsender_field,
558
+ * @param {string} opts.msgview,
559
+ * @param {*} opts.msgform,
560
+ * @param {*} opts.participant_maxread_field,
561
+ * @returns {object[]}
562
+ */
475
563
  const virtual_triggers = (
476
564
  table_id,
477
565
  viewname,
@@ -514,14 +602,25 @@ const virtual_triggers = (
514
602
  ];
515
603
  };
516
604
  module.exports = {
605
+ /** @type {string} */
517
606
  name: "Room",
607
+ /** @type {string} */
518
608
  description: "Real-time space for chat",
519
609
  configuration_workflow,
520
610
  run,
521
611
  get_state_fields,
612
+ /** @type {boolean} */
522
613
  display_state_form: false,
523
614
  routes: { submit_msg_ajax, ack_read, fetch_older_msg },
615
+ /** @type {boolean} */
524
616
  noAutoTest: true,
617
+ /**
618
+ * @param {object} opts
619
+ * @param {object} opts.participant_field
620
+ * @param {string} room_id
621
+ * @param {object} user
622
+ * @returns {Promise<object>}
623
+ */
525
624
  authorize_join: async ({ participant_field }, room_id, user) => {
526
625
  if (!user) return false;
527
626
  const [
@@ -539,6 +638,7 @@ module.exports = {
539
638
  return !!partRow;
540
639
  },
541
640
  virtual_triggers,
641
+ /** @returns {object[]} */
542
642
  getStringsForI18n() {
543
643
  return [];
544
644
  },
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @category saltcorn-data
3
+ * @module base-plugin/viewtemplates/show
4
+ * @subcategory base-plugin
5
+ */
1
6
  const Form = require("../../models/form");
2
7
  const User = require("../../models/user");
3
8
  const Field = require("../../models/field");
@@ -49,6 +54,10 @@ const { get_expression_function } = require("../../models/expression");
49
54
  const { get_base_url } = require("../../models/config");
50
55
  const Library = require("../../models/library");
51
56
 
57
+ /**
58
+ * @param {object} req
59
+ * @returns {Workflow}
60
+ */
52
61
  const configuration_workflow = (req) =>
53
62
  new Workflow({
54
63
  steps: [
@@ -181,6 +190,10 @@ const configuration_workflow = (req) =>
181
190
  },
182
191
  ],
183
192
  });
193
+
194
+ /**
195
+ * @returns {object[]}
196
+ */
184
197
  const get_state_fields = () => [
185
198
  {
186
199
  name: "id",
@@ -190,8 +203,21 @@ const get_state_fields = () => [
190
203
  },
191
204
  ];
192
205
 
206
+ /** @type {function} */
193
207
  const initial_config = initial_config_all_fields(false);
194
208
 
209
+ /**
210
+ * @param {string} table_id
211
+ * @param {string} viewname
212
+ * @param {object} opts
213
+ * @param {object[]} opts.columns
214
+ * @param {object} opts.layout
215
+ * @param {string} [opts.page_title]
216
+ * @param {boolean} opts.page_title_formula
217
+ * @param {object} state
218
+ * @param {object} extra
219
+ * @returns {Promise<string>}
220
+ */
195
221
  const run = async (
196
222
  table_id,
197
223
  viewname,
@@ -216,6 +242,7 @@ const run = async (
216
242
  const { joinFields, aggregations } = picked_fields_to_query(columns, fields);
217
243
  readState(state, fields);
218
244
  const qstate = await stateFieldsToWhere({ fields, state, approximate: true });
245
+ if (Object.keys(qstate).length === 0) return extra.req.__("No row selected");
219
246
  const rows = await tbl.getJoinedRows({
220
247
  where: qstate,
221
248
  joinFields,
@@ -268,6 +295,12 @@ const run = async (
268
295
  return page_title_preamble + rendered;
269
296
  };
270
297
 
298
+ /**
299
+ * @param {object} opts
300
+ * @param {object} opts.layout
301
+ * @param {object[]} opts.fields
302
+ * @returns {Promise<void>}
303
+ */
271
304
  const set_join_fieldviews = async ({ layout, fields }) => {
272
305
  await traverse(layout, {
273
306
  join_field: async (segment) => {
@@ -298,6 +331,16 @@ const set_join_fieldviews = async ({ layout, fields }) => {
298
331
  });
299
332
  };
300
333
 
334
+ /**
335
+ * @param {object} table
336
+ * @param {string} viewname
337
+ * @param {object} opts
338
+ * @param {object[]} opts.columns
339
+ * @param {object} opts.layout
340
+ * @param {object} extra
341
+ * @param {object[]} rows
342
+ * @returns {Promise<string>}
343
+ */
301
344
  const renderRows = async (
302
345
  table,
303
346
  viewname,
@@ -387,6 +430,16 @@ const renderRows = async (
387
430
  });
388
431
  };
389
432
 
433
+ /**
434
+ * @param {number} table_id
435
+ * @param {string} viewname
436
+ * @param {object} opts
437
+ * @param {object[]} opts.columns
438
+ * @param {object} opts.layout
439
+ * @param {object} state
440
+ * @param {object} extra
441
+ * @returns {Promise<object[]>}
442
+ */
390
443
  const runMany = async (
391
444
  table_id,
392
445
  viewname,
@@ -423,6 +476,18 @@ const runMany = async (
423
476
  return rendered.map((html, ix) => ({ html, row: rows[ix] }));
424
477
  };
425
478
 
479
+ /**
480
+ * @param {object} row
481
+ * @param {Field[]} fields
482
+ * @param {Layout} layout0
483
+ * @param {string} viewname
484
+ * @param {Table} table
485
+ * @param {Role} role
486
+ * @param {object} req
487
+ * @param {object} is_owner
488
+ * @throws {Error}
489
+ * @returns {Layout}
490
+ */
426
491
  const render = (row, fields, layout0, viewname, table, role, req, is_owner) => {
427
492
  const evalMaybeExpr = (segment, key, fmlkey) => {
428
493
  if (segment.isFormula && segment.isFormula[fmlkey || key]) {
@@ -560,6 +625,19 @@ const render = (row, fields, layout0, viewname, table, role, req, is_owner) => {
560
625
  is_owner,
561
626
  });
562
627
  };
628
+
629
+ /**
630
+ * @param {number} table_id
631
+ * @param {*} viewname
632
+ * @param {object} opts
633
+ * @param {object[]} opts.columns
634
+ * @param {*} opts.layout
635
+ * @param {*} body
636
+ * @param {object} optsTwo
637
+ * @param {object} optsTwo.req
638
+ * @param {*} optsTwo.res
639
+ * @returns {Promise<object>}
640
+ */
563
641
  const run_action = async (
564
642
  table_id,
565
643
  viewname,
@@ -587,7 +665,9 @@ const run_action = async (
587
665
  };
588
666
 
589
667
  module.exports = {
668
+ /** @type {string} */
590
669
  name: "Show",
670
+ /** @type {string} */
591
671
  description: "Show a single row, with flexible layout",
592
672
  get_state_fields,
593
673
  configuration_workflow,
@@ -595,8 +675,14 @@ module.exports = {
595
675
  runMany,
596
676
  renderRows,
597
677
  initial_config,
678
+ /** @type {boolean} */
598
679
  display_state_form: false,
599
680
  routes: { run_action },
681
+ /**
682
+ * @param {object} opts
683
+ * @param {object} opts.layout
684
+ * @returns {string[]}
685
+ */
600
686
  getStringsForI18n({ layout }) {
601
687
  return getStringsForI18n(layout);
602
688
  },
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @category saltcorn-data
3
+ * @module base-plugin/viewtemplates/viewable_fields
4
+ * @subcategory base-plugin
5
+ */
1
6
  const { post_btn, link } = require("@saltcorn/markup");
2
7
  const { text, a, i } = require("@saltcorn/markup/tags");
3
8
  const { getState } = require("../../db/state");
@@ -11,6 +16,16 @@ const { traverseSync } = require("../../models/layout");
11
16
  const { structuredClone } = require("../../utils");
12
17
  const db = require("../../db");
13
18
 
19
+ /**
20
+ * @function
21
+ * @param {string} viewname
22
+ * @param {Table|object} table
23
+ * @param {string} action_name
24
+ * @param {object} r
25
+ * @param {string} colId missing in contract
26
+ * @param {colIdNm} colIdNm missing in contract
27
+ * @returns {any}
28
+ */
14
29
  const action_url = contract(
15
30
  is.fun([is.str, is_tablely, is.str, is.obj()], is.any),
16
31
  (viewname, table, action_name, r, colId, colIdNm) => {
@@ -26,6 +41,23 @@ const action_url = contract(
26
41
  }
27
42
  );
28
43
 
44
+ /**
45
+ * @param {string} url
46
+ * @param {object} req
47
+ * @param {object} opts
48
+ * @param {string} opts.action_name
49
+ * @param {string} opts.action_label
50
+ * @param {*} opts.confirm
51
+ * @param {*} opts.rndid
52
+ * @param {string} opts.action_style
53
+ * @param {number} opts.action_size
54
+ * @param {*} opts.action_icon
55
+ * @param {string} opts.action_bgcol
56
+ * @param {string} opts.action_bordercol
57
+ * @param {string} opts.action_textcol
58
+ * @param {*} __
59
+ * @returns {object}
60
+ */
29
61
  const action_link = (
30
62
  url,
31
63
  req,
@@ -72,6 +104,12 @@ const action_link = (
72
104
  btnClass: `${action_style || "btn-primary"} ${action_size || ""}`,
73
105
  });
74
106
  };
107
+
108
+ /**
109
+ * @function
110
+ * @param {Field[]} fields
111
+ * @returns {function}
112
+ */
75
113
  const get_view_link_query = contract(
76
114
  is.fun(is.array(is.class("Field")), is.fun(is.obj(), is.str)),
77
115
  (fields) => {
@@ -91,6 +129,17 @@ const get_view_link_query = contract(
91
129
  }
92
130
  );
93
131
 
132
+ /**
133
+ * @function
134
+ * @param {object} opts
135
+ * @param {string} opts.link_text
136
+ * @param {boolean} opts.link_text_formula missing in contract
137
+ * @param {string} [opts.link_url]
138
+ * @param {boolean} opts.link_url_formula
139
+ * @param {boolean} opts.link_target_blank
140
+ * @param {Field[]} fields
141
+ * @returns {object}
142
+ */
94
143
  const make_link = contract(
95
144
  is.fun(
96
145
  [is.obj({ link_text: is.str }), is.array(is.class("Field"))],
@@ -123,6 +172,11 @@ const make_link = contract(
123
172
  };
124
173
  }
125
174
  );
175
+
176
+ /**
177
+ * @param {string} s
178
+ * @returns {object}
179
+ */
126
180
  const parse_view_select = (s) => {
127
181
  const colonSplit = s.split(":");
128
182
  if (colonSplit.length === 1) return { type: "Own", viewname: s };
@@ -143,6 +197,23 @@ const parse_view_select = (s) => {
143
197
  };
144
198
 
145
199
  //todo: use above to simplify code
200
+ /**
201
+ * @function
202
+ * @param {object} opts
203
+ * @param {string} opts.view,
204
+ * @param {object} opts.view_label missing in contract
205
+ * @param {object} opts.in_modal
206
+ * @param {object} opts.view_label_formula
207
+ * @param {string} [opts.link_style = ""]
208
+ * @param {string} [opts.link_size = ""]
209
+ * @param {string} [opts.link_icon = ""]
210
+ * @param {string} [opts.textStyle = ""]
211
+ * @param {string} [opts.link_bgcol]
212
+ * @param {string} [opts.link_bordercol]
213
+ * @param {string} [opts.link_textcol]
214
+ * @param {Field[]} fields
215
+ * @returns {object}
216
+ */
146
217
  const view_linker = contract(
147
218
  is.fun(
148
219
  [is.obj({ view: is.str }), is.array(is.class("Field"))],
@@ -266,12 +337,27 @@ const view_linker = contract(
266
337
  }
267
338
  );
268
339
 
340
+ /**
341
+ * @param {string} nm
342
+ * @returns {boolean}
343
+ */
269
344
  const action_requires_write = (nm) => {
270
345
  if (!nm) return false;
271
346
  if (nm === "Delete") return true;
272
347
  if (nm.startsWith("Toggle")) return true;
273
348
  };
274
349
 
350
+ /**
351
+ * @function
352
+ * @param {string} viewname
353
+ * @param {Table|object} table
354
+ * @param {Fields[]} fields
355
+ * @param {object[]} columns
356
+ * @param {boolean} isShow
357
+ * @param {object} req
358
+ * @param {*} __
359
+ * @returns {object[]}
360
+ */
275
361
  const get_viewable_fields = contract(
276
362
  is.fun(
277
363
  [
@@ -439,6 +525,12 @@ const get_viewable_fields = contract(
439
525
  })
440
526
  .filter((v) => !!v)
441
527
  );
528
+
529
+ /**
530
+ * @param {string} fname
531
+ * @param {object} req
532
+ * @returns {string}
533
+ */
442
534
  const sortlinkForName = (fname, req) => {
443
535
  const { _sortby, _sortdesc } = req.query || {};
444
536
  const desc =
@@ -449,6 +541,14 @@ const sortlinkForName = (fname, req) => {
449
541
  : "true";
450
542
  return `javascript:sortby('${text(fname)}', ${desc})`;
451
543
  };
544
+
545
+ /**
546
+ * @param {object} column
547
+ * @param {object} f
548
+ * @param {object} req
549
+ * @param {*} __
550
+ * @returns {string}
551
+ */
452
552
  const headerLabelForName = (column, f, req, __) => {
453
553
  const label = column.header_label
454
554
  ? text(__(column.header_label))
@@ -462,6 +562,14 @@ const headerLabelForName = (column, f, req, __) => {
462
562
  : i({ class: "fas fa-caret-up" });
463
563
  return label + arrow;
464
564
  };
565
+
566
+ /**
567
+ * @function
568
+ * @param {Field[]} fields
569
+ * @param {object} state
570
+ * @param {boolean} [fuzzyStrings]
571
+ * @returns {object}
572
+ */
465
573
  const splitUniques = contract(
466
574
  is.fun(
467
575
  [is.array(is.class("Field")), is.obj(), is.maybe(is.bool)],
@@ -487,6 +595,16 @@ const splitUniques = contract(
487
595
  return { uniques, nonUniques };
488
596
  }
489
597
  );
598
+
599
+ /**
600
+ * @param {object} table
601
+ * @param {string} viewname
602
+ * @param {object[]} [columns]
603
+ * @param {object} layout0
604
+ * @param {boolean} id
605
+ * @param {object} req
606
+ * @returns {Promise<Form>}
607
+ */
490
608
  const getForm = async (table, viewname, columns, layout0, id, req) => {
491
609
  const fields = await table.getFields();
492
610
 
@@ -556,6 +674,12 @@ const getForm = async (table, viewname, columns, layout0, id, req) => {
556
674
  return form;
557
675
  };
558
676
 
677
+ /**
678
+ * @param {object} table
679
+ * @param {object} req
680
+ * @param {object} fixed
681
+ * @returns {Promise<object>}
682
+ */
559
683
  const fill_presets = async (table, req, fixed) => {
560
684
  const fields = await table.getFields();
561
685
  Object.keys(fixed || {}).forEach((k) => {
package/contracts.js CHANGED
@@ -1,5 +1,12 @@
1
+ /**
2
+ * @category saltcorn-data
3
+ * @module contract
4
+ */
1
5
  const { contract, is } = require("contractis");
2
6
 
7
+ /**
8
+ * @type {function}
9
+ */
3
10
  const fieldlike = is.obj(
4
11
  {
5
12
  name: is.str,
@@ -9,8 +16,14 @@ const fieldlike = is.obj(
9
16
  (o) => o.type || o.input_type
10
17
  );
11
18
 
19
+ /**
20
+ * @type {function}
21
+ */
12
22
  const is_header = is.obj({ script: is.maybe(is.str) });
13
23
 
24
+ /**
25
+ * @type {function}
26
+ */
14
27
  const is_menu_item = is.obj({
15
28
  label: is.str,
16
29
  link: is.maybe(is.str),
@@ -24,6 +37,9 @@ const is_menu_item = is.obj({
24
37
  ),
25
38
  });
26
39
 
40
+ /**
41
+ * @type {function}
42
+ */
27
43
  const is_layout_container = is.or(
28
44
  is.eq(null),
29
45
  is.obj({
@@ -34,6 +50,9 @@ const is_layout_container = is.or(
34
50
  is.obj({})
35
51
  );
36
52
 
53
+ /**
54
+ * @type {function}
55
+ */
37
56
  const is_layout = is.or(
38
57
  is.obj(
39
58
  {
@@ -61,6 +80,9 @@ const is_layout = is.or(
61
80
  is.and(is_layout_container, is.obj({}))
62
81
  );
63
82
 
83
+ /**
84
+ * @type {function}
85
+ */
64
86
  const is_plugin_wrap_arg = is.obj({
65
87
  title: is.str,
66
88
  body: is.or(is.str, is_layout),
@@ -81,6 +103,9 @@ const is_plugin_wrap_arg = is.obj({
81
103
  headers: is.array(is_header),
82
104
  });
83
105
 
106
+ /**
107
+ * @type {function}
108
+ */
84
109
  const is_plugin_authwrap_arg = is.obj({
85
110
  title: is.str,
86
111
  form: is.class("Form"),
@@ -106,8 +131,14 @@ const is_plugin_authwrap_arg = is.obj({
106
131
  }),
107
132
  });
108
133
 
134
+ /**
135
+ * @type {function}
136
+ */
109
137
  const is_plugin_wrap = is.fun(is_plugin_wrap_arg, is.str);
110
138
 
139
+ /**
140
+ * @type {function}
141
+ */
111
142
  const is_plugin_layout = is.obj({
112
143
  wrap: is_plugin_wrap,
113
144
  authWrap: is.maybe(is.fun(is_plugin_authwrap_arg, is.str)),
@@ -115,6 +146,9 @@ const is_plugin_layout = is.obj({
115
146
 
116
147
  const is_attribute = is.obj({ name: is.str, type: is.str, required: is.bool });
117
148
 
149
+ /**
150
+ * @type {function}
151
+ */
118
152
  const is_plugin_type = is.obj({
119
153
  name: is.str,
120
154
  sql_name: is.str,
@@ -138,6 +172,9 @@ const is_plugin_type = is.obj({
138
172
  presets: is.maybe(is.objVals(is.fun([], is.any))),
139
173
  });
140
174
 
175
+ /**
176
+ * @type {function}
177
+ */
141
178
  const is_table_query = is.obj({
142
179
  joinFields: is.maybe(is.objVals(is.obj({ ref: is.str, target: is.str }))),
143
180
  aggregations: is.maybe(
@@ -157,6 +194,9 @@ const is_table_query = is.obj({
157
194
  orderDesc: is.maybe(is.bool),
158
195
  });
159
196
 
197
+ /**
198
+ * @type {function}
199
+ */
160
200
  const is_viewtemplate = is.obj({
161
201
  name: is.str,
162
202
  get_state_fields: is.maybe(
@@ -183,8 +223,16 @@ const is_plugin_function = is.obj({
183
223
  isAsync: is.maybe(is.bool),
184
224
  });
185
225
 
226
+ /**
227
+ *
228
+ * @param {*} a
229
+ * @returns {function}
230
+ */
186
231
  const is_maybe_cfg_fun = (a) => is.or(is.fun(is.obj, a), a, is.undefined);
187
232
 
233
+ /**
234
+ * @type {function}
235
+ */
188
236
  const is_plugin = is.obj({
189
237
  sc_plugin_api_version: is.posint,
190
238
  headers: is_maybe_cfg_fun(is.array(is_header)),
@@ -217,6 +265,9 @@ const is_plugin = is.obj({
217
265
  dependencies: is.maybe(is.array(is.str)),
218
266
  });
219
267
 
268
+ /**
269
+ * @type {function}
270
+ */
220
271
  const is_pack = is.obj({
221
272
  tables: is.array(is.obj({ name: is.str, fields: is.array(fieldlike) })),
222
273
  views: is.array(
@@ -224,6 +275,10 @@ const is_pack = is.obj({
224
275
  ),
225
276
  plugins: is.array(is.obj({ name: is.str, source: is.str, location: is.str })),
226
277
  });
278
+
279
+ /**
280
+ * @type {function}
281
+ */
227
282
  const is_column = is.obj({
228
283
  type: is.one_of([
229
284
  "Action",
@@ -235,6 +290,9 @@ const is_column = is.obj({
235
290
  ]),
236
291
  });
237
292
 
293
+ /**
294
+ * @type {function}
295
+ */
238
296
  const is_tablely = is.or(is.class("Table"), is.obj({ external: is.eq(true) }));
239
297
 
240
298
  module.exports = {