@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
package/models/form.js CHANGED
@@ -1,8 +1,22 @@
1
+ /**
2
+ * Role Database Access Layer
3
+ * @category saltcorn-data
4
+ * @module models/form
5
+ * @subcategory models
6
+ */
1
7
  const { contract, is } = require("contractis");
2
8
  const db = require("../db");
3
9
  const Field = require("./field");
4
10
 
11
+ /**
12
+ * Form Class
13
+ * @category saltcorn-data
14
+ */
5
15
  class Form {
16
+ /**
17
+ * Constructor
18
+ * @param o
19
+ */
6
20
  constructor(o) {
7
21
  this.fields = o.fields.map((f) =>
8
22
  f.constructor.name === Object.name ? new Field(f) : f
@@ -32,6 +46,10 @@ class Form {
32
46
  if (o.validate) this.validate(o.validate);
33
47
  contract.class(this);
34
48
  }
49
+
50
+ /**
51
+ * @param {object} ks
52
+ */
35
53
  hidden(...ks) {
36
54
  ks.forEach((k) => {
37
55
  !this.fields.map((f) => f.name).includes(k) &&
@@ -43,12 +61,19 @@ class Form {
43
61
  );
44
62
  });
45
63
  }
64
+
65
+ /**
66
+ * @param {boolean} [force_allow_none = false]
67
+ */
46
68
  async fill_fkey_options(force_allow_none = false) {
47
69
  for (const f of this.fields) {
48
70
  await f.fill_fkey_options(force_allow_none);
49
71
  }
50
72
  }
51
73
 
74
+ /**
75
+ * @returns {Promise<object>}
76
+ */
52
77
  async generate() {
53
78
  var r = {};
54
79
 
@@ -60,6 +85,10 @@ class Form {
60
85
  }
61
86
  return r;
62
87
  }
88
+
89
+ /**
90
+ * @type {string}
91
+ */
63
92
  get errorSummary() {
64
93
  let strs = [];
65
94
  Object.entries(this.errors).forEach(([k, v]) => {
@@ -67,6 +96,11 @@ class Form {
67
96
  });
68
97
  return strs.join("; ");
69
98
  }
99
+
100
+ /**
101
+ * @param {*} v
102
+ * @returns {object}
103
+ */
70
104
  validate(v) {
71
105
  this.hasErrors = false;
72
106
  this.errors = {};
@@ -0,0 +1,42 @@
1
+ // for the jsdoc documentation
2
+ /**
3
+ * @category saltcorn-data
4
+ * @subcategory models
5
+ * @module models/index
6
+ */
7
+
8
+ /**
9
+ * All files in the models module.
10
+ * @namespace models_overview
11
+ * @property {module:models/backup} backup
12
+ * @property {module:models/config} config
13
+ * @property {module:models/crash} crash
14
+ * @property {module:models/discovery} discovery
15
+ * @property {module:models/email} email
16
+ * @property {module:models/eventlog} eventlog
17
+ * @property {module:models/expression} expression
18
+ * @property {module:models/field} field
19
+ * @property {module:models/fieldrepeat} fieldrepeat
20
+ * @property {module:models/file} file
21
+ * @property {module:models/form} form
22
+ * @property {module:models/layout} layout
23
+ * @property {module:models/library} library
24
+ * @property {module:models/pack} pack
25
+ * @property {module:models/page} page
26
+ * @property {module:models/plugin} plugin
27
+ * @property {module:models/random} random
28
+ * @property {module:models/role} role
29
+ * @property {module:models/scheduler} scheduler
30
+ * @property {module:models/table_constraints} table_constraints
31
+ * @property {module:models/table} table
32
+ * @property {module:models/tenant} tenant
33
+ * @property {module:models/trigger} trigger
34
+ * @property {module:models/user} user
35
+ * @property {module:models/view} view
36
+ * @property {module:models/workflow} workflow
37
+ *
38
+ *
39
+ * @category saltcorn-data
40
+ * @subcategory models
41
+ */
42
+
package/models/layout.js CHANGED
@@ -1,5 +1,15 @@
1
+ /**
2
+ * @category saltcorn-data
3
+ * @module models/layout
4
+ * @subcategory models
5
+ */
1
6
  const { getState } = require("../db/state");
2
7
 
8
+ /**
9
+ * @param {object} layout
10
+ * @param {object[]} visitors
11
+ * @returns {void}
12
+ */
3
13
  const traverseSync = (layout, visitors) => {
4
14
  const go = (segment) => {
5
15
  if (!segment) return;
@@ -26,6 +36,11 @@ const traverseSync = (layout, visitors) => {
26
36
  go(layout);
27
37
  };
28
38
 
39
+ /**
40
+ * @param {object} layout
41
+ * @param {object[]} visitors
42
+ * @returns {Promise<void>}
43
+ */
29
44
  const traverse = async (layout, visitors) => {
30
45
  const go = async (segment) => {
31
46
  if (!segment) return;
@@ -53,8 +68,17 @@ const traverse = async (layout, visitors) => {
53
68
  await go(layout);
54
69
  };
55
70
 
71
+ /**
72
+ * @param {object} layout
73
+ * @param {*} f
74
+ * @returns {void}
75
+ */
56
76
  const eachView = (layout, f) => traverse(layout, { view: f });
57
77
 
78
+ /**
79
+ * @param {object} layout
80
+ * @returns {Promise<object[]>}
81
+ */
58
82
  const getViews = async (layout) => {
59
83
  const views = [];
60
84
  await eachView(layout, (segment) => {
@@ -62,6 +86,11 @@ const getViews = async (layout) => {
62
86
  });
63
87
  return views;
64
88
  };
89
+
90
+ /**
91
+ * @param {object} layout
92
+ * @returns {string[]}
93
+ */
65
94
  const getStringsForI18n = (layout) => {
66
95
  const strings = [];
67
96
  traverseSync(layout, {
@@ -82,6 +111,10 @@ const getStringsForI18n = (layout) => {
82
111
  return strings;
83
112
  };
84
113
 
114
+ /**
115
+ * @param {object} layout
116
+ * @param {object} locale
117
+ */
85
118
  const translateLayout = (layout, locale) => {
86
119
  const appState = getState()
87
120
  const __ = (s) => appState.i18n.__({ phrase: s, locale }) || s;
package/models/library.js CHANGED
@@ -1,8 +1,22 @@
1
+ /**
2
+ * Library Database Access Layer
3
+ * @category saltcorn-data
4
+ * @module models/library
5
+ * @subcategory models
6
+ */
1
7
  const db = require("../db");
2
8
  const { contract, is } = require("contractis");
3
9
  const { traverseSync } = require("./layout");
4
10
 
11
+ /**
12
+ * Library Class
13
+ * @category saltcorn-data
14
+ */
5
15
  class Library {
16
+ /**
17
+ * Library constructor
18
+ * @param {object} o
19
+ */
6
20
  constructor(o) {
7
21
  this.id = o.id;
8
22
  this.name = o.name;
@@ -10,6 +24,10 @@ class Library {
10
24
  this.layout =
11
25
  typeof o.layout === "string" ? JSON.parse(o.layout) : o.layout;
12
26
  }
27
+
28
+ /**
29
+ * @param {object} lib_in
30
+ */
13
31
  static async create(lib_in) {
14
32
  const lib = new Library(lib_in);
15
33
  await db.insert("_sc_library", {
@@ -18,19 +36,38 @@ class Library {
18
36
  layout: lib.layout,
19
37
  });
20
38
  }
39
+
40
+ /**
41
+ * @type {...*}
42
+ */
21
43
  get toJson() {
22
44
  const { id, ...rest } = this;
23
45
  return rest;
24
46
  }
47
+
48
+ /**
49
+ * @param {*} where
50
+ * @param {*} selectopts
51
+ * @returns {Library[]}
52
+ */
25
53
  static async find(where, selectopts) {
26
54
  const us = await db.select("_sc_library", where, selectopts);
27
55
  return us.map((u) => new Library(u));
28
56
  }
57
+
58
+ /**
59
+ * @param {*} where
60
+ * @returns {Library}
61
+ */
29
62
  static async findOne(where) {
30
63
  const u = await db.selectMaybeOne("_sc_library", where);
31
64
  return u ? new Library(u) : u;
32
65
  }
33
66
 
67
+ /**
68
+ * @param {*} what
69
+ * @returns {object}
70
+ */
34
71
  suitableFor(what) {
35
72
  let notPage, notShow, notEdit, notFilter;
36
73
  if (!this.layout) return false;
@@ -78,11 +115,18 @@ class Library {
78
115
  }[what];
79
116
  }
80
117
 
118
+ /**
119
+ * @returns {Promise<void>}
120
+ */
81
121
  async delete() {
82
122
  const schema = db.getTenantSchemaPrefix();
83
123
  await db.query(`delete FROM ${schema}_sc_library WHERE id = $1`, [this.id]);
84
124
  }
85
125
 
126
+ /**
127
+ * @param {*} row
128
+ * @returns {Promise<void>}
129
+ */
86
130
  async update(row) {
87
131
  await db.update("_sc_library", row, this.id);
88
132
  }
package/models/pack.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @category saltcorn-data
3
+ * @module models/pack
4
+ * @subcategory models
5
+ */
1
6
  const Table = require("./table");
2
7
  const db = require("../db");
3
8
  const View = require("./view");
@@ -16,6 +21,11 @@ const Library = require("./library");
16
21
 
17
22
  const pack_fun = is.fun(is.str, is.promise(is.obj()));
18
23
 
24
+ /**
25
+ * @function
26
+ * @param {string} name
27
+ * @returns {Promise<object>}
28
+ */
19
29
  const table_pack = contract(pack_fun, async (name) => {
20
30
  const table = await Table.findOne({ name });
21
31
  const fields = await table.getFields();
@@ -40,6 +50,11 @@ const table_pack = contract(pack_fun, async (name) => {
40
50
  };
41
51
  });
42
52
 
53
+ /**
54
+ * @function
55
+ * @param {string} name
56
+ * @returns {Promise<object>}
57
+ */
43
58
  const view_pack = contract(pack_fun, async (name) => {
44
59
  const view = await View.findOne({ name });
45
60
  const table = await Table.findOne({ id: view.table_id });
@@ -55,6 +70,11 @@ const view_pack = contract(pack_fun, async (name) => {
55
70
  };
56
71
  });
57
72
 
73
+ /**
74
+ * @function
75
+ * @param {string} name
76
+ * @returns {Promise<object>}
77
+ */
58
78
  const plugin_pack = contract(pack_fun, async (name) => {
59
79
  const Plugin = require("./plugin");
60
80
  const plugin = await Plugin.findOne({ name });
@@ -67,6 +87,12 @@ const plugin_pack = contract(pack_fun, async (name) => {
67
87
  deploy_private_key: plugin.deploy_private_key,
68
88
  };
69
89
  });
90
+
91
+ /**
92
+ * @function
93
+ * @param {string} name
94
+ * @returns {Promise<object>}
95
+ */
70
96
  const page_pack = contract(pack_fun, async (name) => {
71
97
  const page = await Page.findOne({ name });
72
98
  const root_page_for_roles = await page.is_root_page_for_roles();
@@ -81,17 +107,41 @@ const page_pack = contract(pack_fun, async (name) => {
81
107
  root_page_for_roles,
82
108
  };
83
109
  });
110
+
111
+ /**
112
+ * @function
113
+ * @param {string} name
114
+ * @returns {Promise<object>}
115
+ */
84
116
  const library_pack = contract(pack_fun, async (name) => {
85
117
  const lib = await Library.findOne({ name });
86
118
  return lib.toJson;
87
119
  });
120
+
121
+ /**
122
+ * @function
123
+ * @param {string} name
124
+ * @returns {Promise<object>}
125
+ */
88
126
  const trigger_pack = contract(pack_fun, async (name) => {
89
127
  const trig = await Trigger.findOne({ name });
90
128
  return trig.toJson;
91
129
  });
130
+
131
+ /**
132
+ * @function
133
+ * @param {string} role
134
+ * @returns {Promise<object>}
135
+ */
92
136
  const role_pack = contract(pack_fun, async (role) => {
93
137
  return await Role.findOne({ role });
94
138
  });
139
+
140
+ /**
141
+ * @function
142
+ * @param {string} pack
143
+ * @returns {Promise<boolean|object>}
144
+ */
95
145
  const can_install_pack = contract(
96
146
  is.fun(
97
147
  is_pack,
@@ -147,6 +197,12 @@ const can_install_pack = contract(
147
197
  }
148
198
  );
149
199
 
200
+ /**
201
+ * @function
202
+ * @param {string} pack
203
+ * @param {string} name
204
+ * @returns {Promise<void>}
205
+ */
150
206
  const uninstall_pack = contract(
151
207
  is.fun([is_pack, is.str], is.promise(is.undefined)),
152
208
  async (pack, name) => {
@@ -188,6 +244,11 @@ const uninstall_pack = contract(
188
244
  }
189
245
  );
190
246
 
247
+ /**
248
+ * @function
249
+ * @param {object} item
250
+ * @returns {Promise<void>}
251
+ */
191
252
  const add_to_menu = contract(
192
253
  is.fun(
193
254
  is.obj({ label: is.str, type: is.one_of(["View", "Page"]) }),
@@ -200,6 +261,14 @@ const add_to_menu = contract(
200
261
  }
201
262
  );
202
263
 
264
+ /**
265
+ * @function
266
+ * @param {string} pack
267
+ * @param {string} [name]
268
+ * @param {function} loadAndSaveNewPlugin
269
+ * @param {boolean} [bare_tables = false]
270
+ * @returns {Promise<void>}
271
+ */
203
272
  const install_pack = contract(
204
273
  is.fun(
205
274
  [is_pack, is.maybe(is.str), is.fun(is_plugin, is.undefined)],
@@ -305,6 +374,12 @@ const install_pack = contract(
305
374
  }
306
375
  );
307
376
 
377
+ /**
378
+ * @function
379
+ * @param {Date} date
380
+ * @param {string} [hours = 24]
381
+ * @returns {boolean}
382
+ */
308
383
  const is_stale = contract(
309
384
  is.fun([is.or(is.class("Date"), is.str), is.maybe(is.posint)], is.bool),
310
385
  (date, hours = 24) => {
@@ -314,6 +389,10 @@ const is_stale = contract(
314
389
  }
315
390
  );
316
391
 
392
+ /**
393
+ * @function
394
+ * @returns {object[]}
395
+ */
317
396
  const fetch_available_packs = contract(
318
397
  is.fun([], is.promise(is.array(is.obj({ name: is.str })))),
319
398
  async () => {
@@ -332,6 +411,10 @@ const fetch_available_packs = contract(
332
411
  }
333
412
  );
334
413
 
414
+ /**
415
+ * @function
416
+ * @returns {Promise<object[]>}
417
+ */
335
418
  const fetch_available_packs_from_store = contract(
336
419
  is.fun([], is.promise(is.array(is.obj({ name: is.str })))),
337
420
  async () => {
@@ -345,6 +428,11 @@ const fetch_available_packs_from_store = contract(
345
428
  }
346
429
  );
347
430
 
431
+ /**
432
+ * @function
433
+ * @param {string} name
434
+ * @returns {Promise<object|null>}
435
+ */
348
436
  const fetch_pack_by_name = contract(
349
437
  is.fun(
350
438
  is.str,
package/models/page.js CHANGED
@@ -1,7 +1,9 @@
1
1
  /**
2
- * Page Data Access Layer
2
+ * Page Database Access Layer
3
+ * @category saltcorn-data
4
+ * @module models/page
5
+ * @subcategory models
3
6
  */
4
-
5
7
  const db = require("../db");
6
8
  const { contract, is } = require("contractis");
7
9
  const View = require("./view");
@@ -26,8 +28,12 @@ const {
26
28
 
27
29
  /**
28
30
  * Page Class
31
+ * @category saltcorn-data
29
32
  */
30
33
  class Page {
34
+ /**
35
+ * @param {object} o
36
+ */
31
37
  constructor(o) {
32
38
  this.name = o.name;
33
39
  this.title = o.title;
@@ -50,6 +56,10 @@ class Page {
50
56
  * @returns {Promise<*>}
51
57
  */
52
58
  static async find(where, selectopts = { orderBy: "name", nocase: true }) {
59
+ if (selectopts.cached) {
60
+ const { getState } = require("../db/state");
61
+ return getState().pages.map((t) => new Page(t));
62
+ }
53
63
  const db_flds = await db.select("_sc_pages", where, selectopts);
54
64
  return db_flds.map((dbf) => new Page(dbf));
55
65
  }
@@ -136,7 +146,7 @@ class Page {
136
146
 
137
147
  /**
138
148
  * get menu label for page
139
- * @returns {*|undefined}
149
+ * @type {string|undefined}
140
150
  */
141
151
  get menu_label() {
142
152
  const { getState } = require("../db/state");
package/models/plugin.js CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Plugin Database Access Layer
3
+ * @category saltcorn-data
4
+ * @module models/plugin
5
+ * @subcategory models
6
+ */
1
7
  const db = require("../db");
2
8
  const { contract, is } = require("contractis");
3
9
  const View = require("./view");
@@ -7,11 +13,12 @@ const { stringToJSON } = require("../utils");
7
13
 
8
14
  /**
9
15
  * Plugin Class
16
+ * @category saltcorn-data
10
17
  */
11
18
  class Plugin {
12
19
  /**
13
20
  * Plugin constructor
14
- * @param o
21
+ * @param {object} o
15
22
  */
16
23
  constructor(o) {
17
24
  this.id = o.id ? +o.id : o.id;
@@ -99,7 +106,7 @@ class Plugin {
99
106
 
100
107
  /**
101
108
  * List of views relay on this plugin
102
- * @returns {Promise<*[]|*>}
109
+ * @returns {Promise<View[]>}
103
110
  */
104
111
  async dependant_views() {
105
112
  const views = await View.find({});
package/models/random.js CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * View Database Access Layer
3
+ * @category saltcorn-data
4
+ * @module models/random
5
+ * @subcategory models
6
+ */
1
7
  const View = require("./view");
2
8
  const Field = require("./field");
3
9
  const Table = require("./table");
@@ -7,6 +13,10 @@ const { initial_config_all_fields } = require("../plugin-helper");
7
13
  const { contract, is } = require("contractis");
8
14
  const db = require("../db");
9
15
 
16
+ /**
17
+ * @param {object} [opts = {}]
18
+ * @returns {Promise<Table>}
19
+ */
10
20
  const random_table = async (opts = {}) => {
11
21
  const name = is
12
22
  .and(
@@ -41,6 +51,10 @@ const random_table = async (opts = {}) => {
41
51
  return table;
42
52
  };
43
53
 
54
+ /**
55
+ * @param {Table} table
56
+ * @returns {Promise<*>}
57
+ */
44
58
  const fill_table_row = async (table) => {
45
59
  const fields = await table.getFields();
46
60
  const row = {};
@@ -51,6 +65,13 @@ const fill_table_row = async (table) => {
51
65
  //console.log(fields, row);
52
66
  await table.tryInsertRow(row);
53
67
  };
68
+
69
+ /**
70
+ * @param {string} type
71
+ * @param {string[]} existing_fields
72
+ * @throws {Error}
73
+ * @returns {string}
74
+ */
54
75
  const random_expression = (type, existing_fields) => {
55
76
  const numField = existing_fields.find((f) =>
56
77
  ["Integer", "Float"].includes(f.type)
@@ -69,6 +90,12 @@ const random_expression = (type, existing_fields) => {
69
90
  throw new Error("random_expression: unknown type " + type);
70
91
  }
71
92
  };
93
+
94
+ /**
95
+ * @param {string[]} existing_field_names
96
+ * @param {Table} table
97
+ * @returns {Promise<Field>}
98
+ */
72
99
  const random_field = async (existing_field_names, table) => {
73
100
  const tables = await Table.find({});
74
101
  const tables_with_data = [];
@@ -144,6 +171,11 @@ const random_field = async (existing_field_names, table) => {
144
171
  return f;
145
172
  };
146
173
 
174
+ /**
175
+ * @param {Table} table
176
+ * @param {string} viewtemplate
177
+ * @returns {Promise<View>}
178
+ */
147
179
  const initial_view = async (table, viewtemplate) => {
148
180
  const configuration = await initial_config_all_fields(
149
181
  viewtemplate === "Edit"
@@ -160,6 +192,10 @@ const initial_view = async (table, viewtemplate) => {
160
192
  return view;
161
193
  };
162
194
 
195
+ /**
196
+ * @param {Table} table
197
+ * @returns {Promise<object[]>}
198
+ */
163
199
  const all_views = async (table) => {
164
200
  const list = await initial_view(table, "List");
165
201
  const edit = await initial_view(table, "Edit");
package/models/role.js CHANGED
@@ -1,11 +1,30 @@
1
+ /**
2
+ * Role Database Access Layer
3
+ * @category saltcorn-data
4
+ * @module models/role
5
+ * @subcategory models
6
+ */
1
7
  const db = require("../db");
2
8
  const { contract, is } = require("contractis");
9
+ /**
10
+ * Role class
11
+ * @category saltcorn-data
12
+ */
3
13
  class Role {
14
+ /**
15
+ * Role constructor
16
+ * @param {object} o
17
+ */
4
18
  constructor(o) {
5
19
  this.id = o.id;
6
20
  this.role = o.role;
7
21
  contract.class(this);
8
22
  }
23
+
24
+ /**
25
+ * @param {*} uo
26
+ * @returns {Role}
27
+ */
9
28
  static async create(uo) {
10
29
  const u = new Role(uo);
11
30
 
@@ -18,20 +37,37 @@ class Role {
18
37
  return u;
19
38
  }
20
39
 
40
+ /**
41
+ * @param {*} where
42
+ * @param {*} selectopts
43
+ * @returns {Promise<Role[]>}
44
+ */
21
45
  static async find(where, selectopts) {
22
46
  const us = await db.select("_sc_roles", where, selectopts);
23
47
  return us.map((u) => new Role(u));
24
48
  }
49
+
50
+ /**
51
+ * @param {*} where
52
+ * @returns {Promise<Role>}
53
+ */
25
54
  static async findOne(where) {
26
55
  const u = await db.selectMaybeOne("_sc_roles", where);
27
56
  return u ? new Role(u) : u;
28
57
  }
29
58
 
59
+ /**
60
+ * @returns {Promise<void>}
61
+ */
30
62
  async delete() {
31
63
  const schema = db.getTenantSchemaPrefix();
32
64
  await db.query(`delete FROM ${schema}_sc_roles WHERE id = $1`, [this.id]);
33
65
  }
34
66
 
67
+ /**
68
+ * @param {*} row
69
+ * @returns {Promise<void>}
70
+ */
35
71
  async update(row) {
36
72
  await db.update("_sc_roles", row, this.id);
37
73
  }