@saltcorn/data 0.6.1-beta.2 → 0.6.2-beta.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.
package/package.json CHANGED
@@ -1,21 +1,23 @@
1
1
  {
2
2
  "name": "@saltcorn/data",
3
- "version": "0.6.1-beta.2",
3
+ "version": "0.6.2-beta.1",
4
4
  "description": "Data models for Saltcorn, open-source no-code platform",
5
5
  "homepage": "https://saltcorn.com",
6
6
  "scripts": {
7
- "test": "jest --runInBand"
7
+ "test": "jest --runInBand",
8
+ "tsc": "echo \"Error: no TypeScript support yet\"",
9
+ "clean": "echo \"Error: no TypeScript support yet\""
8
10
  },
9
11
  "author": "Tom Nielsen",
10
12
  "license": "MIT",
11
13
  "main": "index.js",
12
14
  "optionalDependencies": {
13
- "@saltcorn/postgres": "0.6.1-beta.1",
14
- "@saltcorn/sqlite": "0.6.1-beta.1"
15
+ "@saltcorn/postgres": "0.6.2-beta.1",
16
+ "@saltcorn/sqlite": "0.6.2-beta.1"
15
17
  },
16
18
  "dependencies": {
17
- "@saltcorn/markup": "0.6.1-beta.2",
18
- "@saltcorn/db-common": "0.6.1-beta.2",
19
+ "@saltcorn/markup": "0.6.2-beta.1",
20
+ "@saltcorn/db-common": "0.6.2-beta.1",
19
21
  "acorn": "^8.0.3",
20
22
  "adm-zip": "0.5.5",
21
23
  "astring": "^1.4.3",
@@ -47,7 +49,10 @@
47
49
  "jest": "^25.1.0"
48
50
  },
49
51
  "jest": {
50
- "testEnvironment": "node"
52
+ "testEnvironment": "node",
53
+ "moduleNameMapper": {
54
+ "@saltcorn/sqlite/(.*)": "@saltcorn/sqlite/dist/$1"
55
+ }
51
56
  },
52
57
  "publishConfig": {
53
58
  "access": "public"
package/plugin-helper.js CHANGED
@@ -112,16 +112,19 @@ const stateToQueryString = contract(
112
112
  */
113
113
  const calcfldViewOptions = contract(
114
114
  is.fun(
115
- [is.array(is.class("Field")), is.bool],
115
+ [is.array(is.class("Field")), is.str],
116
116
  is.obj({ field_view_options: is.objVals(is.array(is.str)) })
117
117
  ),
118
- (fields, isEdit) => {
119
- var fvs = {};
118
+ (fields, mode) => {
119
+ const isEdit = mode === "edit";
120
+ const isFilter = mode === "filter";
121
+ let fvs = {};
120
122
  const handlesTextStyle = {};
121
123
  fields.forEach((f) => {
122
124
  handlesTextStyle[f.name] = [];
123
125
  if (f.type === "File") {
124
- if (!isEdit) fvs[f.name] = Object.keys(getState().fileviews);
126
+ if (!isEdit && !isFilter)
127
+ fvs[f.name] = Object.keys(getState().fileviews);
125
128
  else fvs[f.name] = ["upload"];
126
129
  } else if (f.type === "Key") {
127
130
  if (isEdit) fvs[f.name] = Object.keys(getState().keyFieldviews);
@@ -129,7 +132,7 @@ const calcfldViewOptions = contract(
129
132
  if (f.reftable && f.reftable.fields) {
130
133
  const { field_view_options } = calcfldViewOptions(
131
134
  f.reftable.fields,
132
- isEdit
135
+ mode
133
136
  );
134
137
  for (const jf of f.reftable.fields) {
135
138
  fvs[`${f.name}.${jf.name}`] = field_view_options[jf.name];
@@ -142,15 +145,20 @@ const calcfldViewOptions = contract(
142
145
  });
143
146
  } else if (f.type && f.type.fieldviews) {
144
147
  const tfvs = Object.entries(f.type.fieldviews).filter(([k, fv]) =>
145
- f.calculated ? !fv.isEdit : !fv.isEdit || isEdit
148
+ f.calculated ? !fv.isEdit : !fv.isEdit || isEdit || isFilter
146
149
  );
147
150
  let tfvs_ordered = [];
148
151
  if (isEdit) {
149
152
  tfvs_ordered = [
150
153
  ...tfvs.filter(([k, fv]) => fv.isEdit),
151
- ...tfvs.filter(([k, fv]) => !fv.isEdit),
154
+ ...tfvs.filter(([k, fv]) => !fv.isEdit && !fv.isFilter),
152
155
  ];
153
- } else tfvs_ordered = tfvs;
156
+ } else if (isFilter) {
157
+ tfvs_ordered = [
158
+ ...tfvs.filter(([k, fv]) => fv.isFilter),
159
+ ...tfvs.filter(([k, fv]) => fv.isEdit),
160
+ ];
161
+ } else tfvs_ordered = tfvs.filter(([k, fv]) => !fv.isFilter);
154
162
  fvs[f.name] = tfvs_ordered.map(([k, fv]) => {
155
163
  if (fv && fv.handlesTextStyle) handlesTextStyle[f.name].push(k);
156
164
  return k;
@@ -323,7 +331,7 @@ const field_picker_fields = contract(
323
331
  }
324
332
  }
325
333
  const fldOptions = fields.map((f) => f.name);
326
- const { field_view_options } = calcfldViewOptions(fields, false);
334
+ const { field_view_options } = calcfldViewOptions(fields, "show");
327
335
  const fieldViewConfigForms = await calcfldViewConfig(fields, false);
328
336
  const fvConfigFields = [];
329
337
  for (const [field_name, fvOptFields] of Object.entries(
@@ -954,6 +962,14 @@ const stateFieldsToWhere = contract(
954
962
  const dfield = fields.find((fld) => fld.name == datefield);
955
963
  if (dfield)
956
964
  addOrCreateList(qstate, datefield, { lt: new Date(v), equal: true });
965
+ } else if (k.startsWith("_gte_")) {
966
+ const datefield = db.sqlsanitize(k.replace("_gte_", ""));
967
+ const dfield = fields.find((fld) => fld.name == datefield);
968
+ if (dfield) addOrCreateList(qstate, datefield, { gt: v, equal: true });
969
+ } else if (k.startsWith("_lte_")) {
970
+ const datefield = db.sqlsanitize(k.replace("_lte_", ""));
971
+ const dfield = fields.find((fld) => fld.name == datefield);
972
+ if (dfield) addOrCreateList(qstate, datefield, { lt: v, equal: true });
957
973
  } else if (
958
974
  field &&
959
975
  field.type.name === "String" &&
@@ -964,7 +980,9 @@ const stateFieldsToWhere = contract(
964
980
  } else if (field && field.type.name === "Bool" && state[k] === "?") {
965
981
  // omit
966
982
  } else if (field && field.type && field.type.read)
967
- qstate[k] = field.type.read(v);
983
+ qstate[k] = Array.isArray(v)
984
+ ? { or: v.map(field.type.read) }
985
+ : field.type.read(v);
968
986
  else if (field) qstate[k] = v;
969
987
  else if (k.includes(".")) {
970
988
  const kpath = k.split(".");
@@ -1124,7 +1142,9 @@ const readState = (state, fields, req) => {
1124
1142
  fields.forEach((f) => {
1125
1143
  const current = state[f.name];
1126
1144
  if (typeof current !== "undefined") {
1127
- if (f.type.read) state[f.name] = f.type.read(current);
1145
+ if (Array.isArray(current) && f.type.read) {
1146
+ state[f.name] = current.map(f.type.read);
1147
+ } else if (f.type.read) state[f.name] = f.type.read(current);
1128
1148
  else if (typeof current === "string" && current.startsWith("Preset:")) {
1129
1149
  const preset = f.presets[current.replace("Preset:", "")];
1130
1150
  state[f.name] = preset(req);
@@ -7,6 +7,7 @@ const {
7
7
  get_expression_function,
8
8
  transform_for_async,
9
9
  expressionValidator,
10
+ jsexprToWhere,
10
11
  } = require("../models/expression");
11
12
 
12
13
  getState().registerPlugin("base", require("../base-plugin"));
@@ -219,3 +220,24 @@ describe("expressions", () => {
219
220
  expect(expressionValidator("2+")).toBe("Unexpected end of input");
220
221
  });
221
222
  });
223
+ describe("jsexprToWhere", () => {
224
+ it("translates equality", () => {
225
+ expect(jsexprToWhere("foo==4")).toEqual({ foo: 4 });
226
+ });
227
+ it("translates equal to col", () => {
228
+ expect(jsexprToWhere("foo==bar").foo.description).toBe("bar");
229
+ });
230
+ it("translates context", () => {
231
+ expect(jsexprToWhere("foo==$bar", { bar: 5 })).toEqual({ foo: 5 });
232
+ });
233
+ it("translates context", () => {
234
+ const w = jsexprToWhere("$father !== null && married_to === $father", {
235
+ father: "1",
236
+ });
237
+ expect(w).toEqual({ married_to: "1", not: { eq: ["1", null] } });
238
+ });
239
+ it("translates context", () => {
240
+ const w = jsexprToWhere("$father !== null && married_to === $father", {});
241
+ expect(w).toEqual({ married_to: null, not: { eq: [null, null] } });
242
+ });
243
+ });