@storecraft/database-sql-base 1.0.10 → 1.0.12

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/index.js CHANGED
@@ -1,3 +1,10 @@
1
+ /**
2
+ * @import { db_driver } from '@storecraft/core/database'
3
+ * @import { Database } from './types.sql.tables.js'
4
+ * @import { Config } from './types.public.js'
5
+ * @import { Dialect } from 'kysely'
6
+ */
7
+
1
8
  import { App } from '@storecraft/core';
2
9
  import { impl as auth_users } from './src/con.auth_users.js';
3
10
  import { impl as collections } from './src/con.collections.js';
@@ -25,15 +32,10 @@ const assert = (b, msg) => {
25
32
  if(!Boolean(b)) throw new Error(msg);
26
33
  }
27
34
 
28
- /**
29
- * @typedef {import('./types.public.d.ts').Config} Config
30
- * @typedef {import('./types.sql.tables.d.ts').Database} Database
31
- * @typedef {import('kysely').Dialect} Dialect
32
- * @typedef {import('@storecraft/core/database').db_driver} db_driver
33
- */
34
35
 
35
36
  /**
36
- * @implements {db_driver}
37
+ * @template {Config} [ConfigType=Config]
38
+ * @implements {db_driver<ConfigType>}
37
39
  */
38
40
  export class SQL {
39
41
 
@@ -43,7 +45,7 @@ export class SQL {
43
45
  /** @type {App<any, any, any>} */
44
46
  #_app;
45
47
 
46
- /** @type {Config} */
48
+ /** @type {ConfigType} */
47
49
  #_config;
48
50
 
49
51
  /** @type {Kysely<Database>} */
@@ -54,7 +56,7 @@ export class SQL {
54
56
 
55
57
  /**
56
58
  *
57
- * @param {Config} [config] config
59
+ * @param {ConfigType} [config] config
58
60
  */
59
61
  constructor(config) {
60
62
  this.#_is_ready = false;
@@ -69,16 +71,6 @@ export class SQL {
69
71
  this.#_config.dialect_type,
70
72
  'No Dialect Type specified !'
71
73
  );
72
-
73
- this.#_client = new Kysely(
74
- {
75
- dialect: this.#_config.dialect,
76
- plugins: [
77
- new ParseJSONResultsPlugin(),
78
- new SanitizePlugin()
79
- ]
80
- }
81
- );
82
74
  }
83
75
 
84
76
  throwIfNotReady() {
@@ -89,13 +81,9 @@ export class SQL {
89
81
  }
90
82
 
91
83
  /**
92
- *
93
- * @param {App<any, any, any>} app
94
- *
95
- *
96
- * @returns {Promise<this>}
84
+ * @type {db_driver["init"]}
97
85
  */
98
- async init(app) {
86
+ init(app) {
99
87
  if(this.isReady)
100
88
  return this;
101
89
 
@@ -144,6 +132,16 @@ export class SQL {
144
132
  }
145
133
 
146
134
  get client() {
135
+ this.#_client = this.#_client ?? new Kysely(
136
+ {
137
+ dialect: this.config.dialect,
138
+ plugins: [
139
+ new ParseJSONResultsPlugin(),
140
+ new SanitizePlugin()
141
+ ]
142
+ }
143
+ );
144
+
147
145
  return this.#_client;
148
146
  }
149
147
 
@@ -0,0 +1 @@
1
+ export * from '../migrations.shared/00002_seed_email_templates.js'
@@ -0,0 +1 @@
1
+ export * from '../migrations.shared/00002_seed_email_templates.js'
@@ -0,0 +1,27 @@
1
+ import { Kysely } from 'kysely'
2
+ import { upsert } from '../src/con.templates.js'
3
+ import { templates } from '@storecraft/core/assets/seed-templates-v2.js';
4
+
5
+ /**
6
+ * @typedef {import('../types.sql.tables.js').Database} Database
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @param {Kysely<Database>} db
12
+ */
13
+ export async function up(db) {
14
+
15
+ for (const template of templates.slice(0)) {
16
+ const result = await upsert(db)(template, template.search);
17
+ if(!result)
18
+ throw new Error('Failed to write a template object')
19
+ }
20
+ }
21
+
22
+ /**
23
+ *
24
+ * @param {Kysely<Database>} db
25
+ */
26
+ export async function down(db) {
27
+ }
@@ -0,0 +1 @@
1
+ export * from '../migrations.shared/00002_seed_email_templates.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storecraft/database-sql-base",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Official SQL Database driver for storecraft",
5
5
  "license": "MIT",
6
6
  "author": "Tomer Shalev (https://github.com/store-craft)",
@@ -1,14 +1,14 @@
1
+ /**
2
+ * @import { db_auth_users as db_col } from '@storecraft/core/database'
3
+ */
1
4
  import { SQL } from '../index.js'
2
- import { sanitize_array } from './utils.funcs.js'
3
- import { count_regular, delete_me, insert_search_of, insert_tags_of, regular_upsert_me,
4
- where_id_or_handle_table,
5
- with_media,
6
- with_tags} from './con.shared.js'
5
+ import { sanitize, sanitize_array } from './utils.funcs.js'
6
+ import {
7
+ count_regular, delete_me, insert_search_of, insert_tags_of,
8
+ regular_upsert_me, where_id_or_handle_table, with_media, with_tags
9
+ } from './con.shared.js'
7
10
  import { query_to_eb, query_to_sort } from './utils.query.js';
8
11
 
9
- /**
10
- * @typedef {import('@storecraft/core/database').db_auth_users} db_col
11
- */
12
12
 
13
13
  export const table_name = 'auth_users';
14
14
 
@@ -60,7 +60,8 @@ const get = (driver) => {
60
60
  .selectFrom(table_name)
61
61
  .selectAll()
62
62
  .where(where_id_or_handle_table(id_or_email))
63
- .executeTakeFirst();
63
+ .executeTakeFirst()
64
+ .then(sanitize);
64
65
  }
65
66
  }
66
67
 
@@ -70,11 +71,12 @@ const get = (driver) => {
70
71
  * @returns {db_col["getByEmail"]}
71
72
  */
72
73
  const getByEmail = (driver) => {
73
- return (email) => {
74
+ return async (email) => {
74
75
  return driver.client
75
76
  .selectFrom('auth_users')
76
77
  .selectAll().where('email', '=', email)
77
- .executeTakeFirst();
78
+ .executeTakeFirst()
79
+ .then(sanitize);
78
80
  }
79
81
  }
80
82
 
@@ -134,13 +136,13 @@ const list = (driver) => {
134
136
  return query_to_eb(eb, query, table_name);
135
137
  }
136
138
  )
137
- .orderBy(query_to_sort(query))
139
+ .orderBy(query_to_sort(query, 'auth_users'))
138
140
  .limit(query.limitToLast ?? query.limit ?? 10)
139
141
  .execute();
140
142
 
141
143
  if(query.limitToLast) items.reverse();
142
144
 
143
- return items;
145
+ return sanitize_array(items);
144
146
  }
145
147
  }
146
148
 
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { db_collections as db_col } from '@storecraft/core/database'
3
+ */
1
4
  import { SQL } from '../index.js'
2
5
  import { report_document_media } from './con.images.js'
3
6
  import { delete_entity_values_by_value_or_reporter, delete_me,
@@ -6,14 +9,12 @@ import { delete_entity_values_by_value_or_reporter, delete_me,
6
9
  select_entity_ids_by_value_or_reporter,
7
10
  regular_upsert_me, where_id_or_handle_table,
8
11
  with_media, with_tags,
9
- count_regular} from './con.shared.js'
10
- import { sanitize_array } from './utils.funcs.js'
12
+ count_regular,
13
+ with_search} from './con.shared.js'
14
+ import { sanitize, sanitize_array } from './utils.funcs.js'
11
15
  import { query_to_eb, query_to_sort } from './utils.query.js'
12
16
 
13
17
 
14
- /**
15
- * @typedef {import('@storecraft/core/database').db_collections} db_col
16
- */
17
18
  export const table_name = 'collections'
18
19
 
19
20
  /**
@@ -61,17 +62,17 @@ const upsert = (driver) => {
61
62
  */
62
63
  const get = (driver) => {
63
64
  return (id_or_handle, options) => {
64
-
65
65
  return driver.client
66
66
  .selectFrom(table_name)
67
67
  .selectAll('collections')
68
68
  .select(eb => [
69
69
  with_tags(eb, eb.ref('collections.id'), driver.dialectType),
70
- with_media(eb, eb.ref('collections.id'), driver.dialectType)
70
+ with_media(eb, eb.ref('collections.id'), driver.dialectType),
71
+ with_search(eb, eb.ref('collections.id'), driver.dialectType)
71
72
  ])
72
73
  .where(where_id_or_handle_table(id_or_handle))
73
- // .compile()
74
- .executeTakeFirst();
74
+ .executeTakeFirst()
75
+ .then(sanitize);
75
76
  }
76
77
  }
77
78
 
@@ -124,13 +125,14 @@ const list = (driver) => {
124
125
  .select(eb => [
125
126
  with_tags(eb, eb.ref('collections.id'), driver.dialectType),
126
127
  with_media(eb, eb.ref('collections.id'), driver.dialectType),
128
+ with_search(eb, eb.ref('collections.id'), driver.dialectType),
127
129
  ])
128
130
  .where(
129
131
  (eb) => {
130
132
  return query_to_eb(eb, query, table_name);
131
133
  }
132
134
  )
133
- .orderBy(query_to_sort(query))
135
+ .orderBy(query_to_sort(query, 'collections'))
134
136
  .limit(query.limitToLast ?? query.limit ?? 10)
135
137
  .execute();
136
138
 
@@ -166,7 +168,7 @@ const list_collection_products = (driver) => {
166
168
  ].filter(Boolean)
167
169
  )
168
170
  )
169
- .orderBy(query_to_sort(query))
171
+ .orderBy(query_to_sort(query, 'products'))
170
172
  .limit(query.limitToLast ?? query.limit ?? 10)
171
173
  .execute();
172
174
 
@@ -1,15 +1,15 @@
1
+ /**
2
+ * @import { db_customers as db_col } from '@storecraft/core/database'
3
+ */
1
4
  import { SQL } from '../index.js'
2
5
  import { report_document_media } from './con.images.js'
3
6
  import { count_regular, delete_me, delete_media_of, delete_search_of,
4
7
  delete_tags_of, insert_media_of, insert_search_of,
5
8
  insert_tags_of, regular_upsert_me, where_id_or_handle_table,
6
- with_media, with_tags} from './con.shared.js'
7
- import { sanitize_array } from './utils.funcs.js'
9
+ with_media, with_search, with_tags} from './con.shared.js'
10
+ import { sanitize, sanitize_array } from './utils.funcs.js'
8
11
  import { query_to_eb, query_to_sort } from './utils.query.js'
9
12
 
10
- /**
11
- * @typedef {import('@storecraft/core/database').db_customers} db_col
12
- */
13
13
  export const table_name = 'customers'
14
14
 
15
15
  /**
@@ -64,9 +64,11 @@ const get = (driver) => {
64
64
  .select(eb => [
65
65
  with_media(eb, id, driver.dialectType),
66
66
  with_tags(eb, id, driver.dialectType),
67
+ with_search(eb, id, driver.dialectType),
67
68
  ])
68
69
  .where(where_id_or_handle_table(id))
69
- .executeTakeFirst();
70
+ .executeTakeFirst()
71
+ .then(sanitize);
70
72
  }
71
73
  }
72
74
 
@@ -129,13 +131,14 @@ const list = (driver) => {
129
131
  .select(eb => [
130
132
  with_media(eb, eb.ref('customers.id'), driver.dialectType),
131
133
  with_tags(eb, eb.ref('customers.id'), driver.dialectType),
134
+ with_search(eb, eb.ref('customers.id'), driver.dialectType),
132
135
  ].filter(Boolean))
133
136
  .where(
134
137
  (eb) => {
135
138
  return query_to_eb(eb, query, table_name);
136
139
  }
137
140
  )
138
- .orderBy(query_to_sort(query))
141
+ .orderBy(query_to_sort(query, table_name))
139
142
  .limit(query.limitToLast ?? query.limit ?? 10)
140
143
  .execute();
141
144
 
@@ -174,7 +177,7 @@ const list_customer_orders = (driver) => {
174
177
  ].filter(Boolean)
175
178
  )
176
179
  )
177
- .orderBy(query_to_sort(query))
180
+ .orderBy(query_to_sort(query, 'orders'))
178
181
  .limit(query.limitToLast ?? query.limit ?? 10)
179
182
  .execute();
180
183
 
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { db_discounts as db_col } from '@storecraft/core/database'
3
+ */
1
4
  import { enums } from '@storecraft/core/api'
2
5
  import { SQL } from '../index.js'
3
6
  import { discount_to_conjunctions } from './con.discounts.utils.js'
@@ -6,14 +9,12 @@ import { delete_entity_values_by_value_or_reporter,
6
9
  delete_tags_of, insert_media_of, insert_search_of,
7
10
  insert_tags_of, select_entity_ids_by_value_or_reporter, regular_upsert_me, where_id_or_handle_table,
8
11
  with_media, with_tags,
9
- count_regular} from './con.shared.js'
10
- import { sanitize_array } from './utils.funcs.js'
12
+ count_regular,
13
+ with_search} from './con.shared.js'
14
+ import { sanitize, sanitize_array } from './utils.funcs.js'
11
15
  import { query_to_eb, query_to_sort } from './utils.query.js'
12
16
  import { report_document_media } from './con.images.js'
13
17
 
14
- /**
15
- * @typedef {import('@storecraft/core/database').db_discounts} db_col
16
- */
17
18
  export const table_name = 'discounts'
18
19
 
19
20
  /**
@@ -37,6 +38,12 @@ const upsert = (driver) => {
37
38
  // remove all products relation to this discount
38
39
  await delete_entity_values_by_value_or_reporter('products_to_discounts')(
39
40
  trx, item.id, item.handle);
41
+
42
+ await delete_entity_values_by_value_or_reporter('entity_to_search_terms')(
43
+ trx, `discount:${item.id}`);
44
+ await delete_entity_values_by_value_or_reporter('entity_to_search_terms')(
45
+ trx, `discount:${item.handle}`);
46
+
40
47
  if(item.active && item.application.id===enums.DiscountApplicationEnum.Auto.id) {
41
48
  // make connections
42
49
  await trx
@@ -56,6 +63,37 @@ const upsert = (driver) => {
56
63
  )
57
64
  ).execute();
58
65
 
66
+ await trx
67
+ .insertInto('entity_to_search_terms')
68
+ .columns(['entity_handle', 'entity_id', 'value'])
69
+ .expression(eb =>
70
+ eb.selectFrom('products')
71
+ .select(eb => [
72
+ 'handle as entity_handle',
73
+ 'id as entity_id',
74
+ eb.val(`discount:${item.id}`).as('value'),
75
+ ]
76
+ )
77
+ .where(
78
+ eb => eb.and(discount_to_conjunctions(eb, item))
79
+ )
80
+ ).execute();
81
+
82
+ await trx
83
+ .insertInto('entity_to_search_terms')
84
+ .columns(['entity_handle', 'entity_id', 'value'])
85
+ .expression(eb =>
86
+ eb.selectFrom('products')
87
+ .select(eb => [
88
+ 'handle as entity_handle',
89
+ 'id as entity_id',
90
+ eb.val(`discount:${item.handle}`).as('value'),
91
+ ]
92
+ )
93
+ .where(
94
+ eb => eb.and(discount_to_conjunctions(eb, item))
95
+ )
96
+ ).execute();
59
97
  }
60
98
 
61
99
  ///
@@ -100,9 +138,11 @@ const get = (driver) => {
100
138
  .select(eb => [
101
139
  with_media(eb, id_or_handle, driver.dialectType),
102
140
  with_tags(eb, id_or_handle, driver.dialectType),
141
+ with_search(eb, id_or_handle, driver.dialectType),
103
142
  ].filter(Boolean))
104
143
  .where(where_id_or_handle_table(id_or_handle))
105
- .executeTakeFirst();
144
+ .executeTakeFirst()
145
+ .then(sanitize);
106
146
  }
107
147
  }
108
148
 
@@ -156,13 +196,14 @@ const list = (driver) => {
156
196
  .select(eb => [
157
197
  with_media(eb, eb.ref('discounts.id'), driver.dialectType),
158
198
  with_tags(eb, eb.ref('discounts.id'), driver.dialectType),
199
+ with_search(eb, eb.ref('discounts.id'), driver.dialectType),
159
200
  ].filter(Boolean))
160
201
  .where(
161
202
  (eb) => {
162
203
  return query_to_eb(eb, query, table_name);
163
204
  }
164
205
  )
165
- .orderBy(query_to_sort(query))
206
+ .orderBy(query_to_sort(query, table_name))
166
207
  .limit(query.limitToLast ?? query.limit ?? 10)
167
208
  .execute();
168
209
 
@@ -179,6 +220,10 @@ const list = (driver) => {
179
220
  const list_discount_products = (driver) => {
180
221
  return async (handle_or_id, query={}) => {
181
222
 
223
+ // TODO: try to rewrite this with JOIN to products_to_discounts ON products.id=entity_id
224
+ // TODO: and then filter by value==handle_or_id_of_discount
225
+ // TODO: I think it will be better and more memory efficient for the database
226
+ // TODO: becausee right now it loads all the eligible products ids in advance
182
227
  const items = await driver.client
183
228
  .selectFrom('products')
184
229
  .selectAll()
@@ -198,7 +243,7 @@ const list_discount_products = (driver) => {
198
243
  ].filter(Boolean)
199
244
  )
200
245
  )
201
- .orderBy(query_to_sort(query))
246
+ .orderBy(query_to_sort(query, 'products'))
202
247
  .limit(query.limitToLast ?? query.limit ?? 10)
203
248
  .execute();
204
249
 
@@ -1,11 +1,20 @@
1
+ /**
2
+ * @import {
3
+ * DiscountType, FilterValue_p_in_price_range, FilterValue_p_not_in_collections,
4
+ * FilterValue_p_in_collections, FilterValue_p_not_in_tags, FilterValue_p_in_tags,
5
+ * FilterValue_p_in_products, FilterValue_p_not_in_products
6
+ * } from '@storecraft/core/api'
7
+ * @import { Database } from '../types.sql.tables.js'
8
+ * @import { ExpressionBuilder, BinaryOperator } from 'kysely'
9
+ */
1
10
  import { enums } from "@storecraft/core/api";
2
11
 
3
- /** @param {import("@storecraft/core/api").DiscountType} d */
12
+ /** @param {DiscountType} d */
4
13
  const is_order_discount = d => {
5
14
  return (d.info.details.meta.id===enums.DiscountMetaEnum.order.id);
6
15
  }
7
16
 
8
- /** @param {import("@storecraft/core/api").DiscountType} d */
17
+ /** @param {DiscountType} d */
9
18
  const is_automatic_discount = d => {
10
19
  return (d.application.id===enums.DiscountApplicationEnum.Auto.id);
11
20
  }
@@ -14,10 +23,9 @@ const extract_abs_number = v => {
14
23
  return v && !isNaN(v) && v!==Infinity && Math.abs(v);
15
24
  }
16
25
  /**
17
- * @typedef {import("../index.js").Database} Database
18
- * @param {import("kysely").ExpressionBuilder<Database, 'products'>} eb
26
+ * @param {ExpressionBuilder<Database, 'products'>} eb
19
27
  * @param {keyof Pick<Database, 'entity_to_tags_projections' | 'products_to_collections'>} table
20
- * @param {import("kysely").BinaryOperator} op
28
+ * @param {BinaryOperator} op
21
29
  * @param {string[]} value
22
30
  */
23
31
  const eb_in = (eb, table, op, value) => {
@@ -42,8 +50,8 @@ const eb_in = (eb, table, op, value) => {
42
50
  /**
43
51
  * create a mongodb conjunctions clauses from discount, intended
44
52
  * for filtering.
45
- * @param {import("kysely").ExpressionBuilder<Database, 'products'>} eb
46
- * @param {import("@storecraft/core/api").DiscountType} d
53
+ * @param {ExpressionBuilder<Database, 'products'>} eb
54
+ * @param {DiscountType} d
47
55
  */
48
56
  export const discount_to_conjunctions = (eb, d) => {
49
57
  // discount has to be product discount + automatic + active + has filters
@@ -66,8 +74,10 @@ export const discount_to_conjunctions = (eb, d) => {
66
74
  break;
67
75
  case enums.FilterMetaEnum.p_in_products.op:
68
76
  {
69
- /** @type {import("@storecraft/core/api").FilterValue_p_in_products} */
70
- const cast = Array.isArray(filter?.value) ? filter.value : [];
77
+
78
+ const cast = /** @type {FilterValue_p_in_products} */ (
79
+ Array.isArray(filter?.value) ? filter.value : []
80
+ );
71
81
 
72
82
  conjunctions.push(
73
83
  eb(
@@ -79,8 +89,10 @@ export const discount_to_conjunctions = (eb, d) => {
79
89
  break;
80
90
  case enums.FilterMetaEnum.p_not_in_products.op:
81
91
  {
82
- /** @type {import("@storecraft/core/api").FilterValue_p_not_in_products} */
83
- const cast = Array.isArray(filter?.value) ? filter.value : [];
92
+
93
+ const cast = /** @type {FilterValue_p_not_in_products} */ (
94
+ Array.isArray(filter?.value) ? filter.value : []
95
+ );
84
96
 
85
97
  conjunctions.push(
86
98
  eb(
@@ -92,8 +104,10 @@ export const discount_to_conjunctions = (eb, d) => {
92
104
  break;
93
105
  case enums.FilterMetaEnum.p_in_tags.op:
94
106
  {
95
- /** @type {import("@storecraft/core/api").FilterValue_p_in_tags} */
96
- const cast = Array.isArray(filter?.value) ? filter.value : [];
107
+
108
+ const cast = /** @type {FilterValue_p_in_tags} */(
109
+ Array.isArray(filter?.value) ? filter.value : []
110
+ );
97
111
 
98
112
  conjunctions.push(
99
113
  eb_in(
@@ -105,8 +119,9 @@ export const discount_to_conjunctions = (eb, d) => {
105
119
  break;
106
120
  case enums.FilterMetaEnum.p_not_in_tags.op:
107
121
  {
108
- /** @type {import("@storecraft/core/api").FilterValue_p_not_in_tags} */
109
- const cast = Array.isArray(filter?.value) ? filter.value : [];
122
+ const cast = /** @type {FilterValue_p_not_in_tags} */ (
123
+ Array.isArray(filter?.value) ? filter.value : []
124
+ );
110
125
 
111
126
  conjunctions.push(
112
127
  eb.not(
@@ -120,8 +135,9 @@ export const discount_to_conjunctions = (eb, d) => {
120
135
  break;
121
136
  case enums.FilterMetaEnum.p_in_collections.op:
122
137
  {
123
- /** @type {import("@storecraft/core/api").FilterValue_p_in_collections} */
124
- const cast = Array.isArray(filter?.value) ? filter.value : [];
138
+ const cast = /** @type {FilterValue_p_in_collections} */ (
139
+ Array.isArray(filter?.value) ? filter.value : []
140
+ );
125
141
 
126
142
  // PROBLEM: we only have ids, but use handles in the filters
127
143
  conjunctions.push(
@@ -134,8 +150,9 @@ export const discount_to_conjunctions = (eb, d) => {
134
150
  break;
135
151
  case enums.FilterMetaEnum.p_not_in_collections.op:
136
152
  {
137
- /** @type {import("@storecraft/core/api").FilterValue_p_not_in_collections} */
138
- const cast = Array.isArray(filter?.value) ? filter.value : [];
153
+ const cast = /** @type {FilterValue_p_not_in_collections} */ (
154
+ Array.isArray(filter?.value) ? filter.value : []
155
+ );
139
156
 
140
157
  conjunctions.push(
141
158
  eb.not(
@@ -149,12 +166,13 @@ export const discount_to_conjunctions = (eb, d) => {
149
166
  break;
150
167
  case enums.FilterMetaEnum.p_in_price_range.op:
151
168
  {
152
- /** @type {import("@storecraft/core/api").FilterValue_p_in_price_range} */
153
- const cast = {
154
- from: 0,
155
- to: Number.POSITIVE_INFINITY,
156
- ...(filter?.value ?? {}),
157
- };
169
+ const cast = /** @type {FilterValue_p_in_price_range} */ (
170
+ {
171
+ from: 0,
172
+ to: Number.POSITIVE_INFINITY,
173
+ ...(filter?.value ?? {}),
174
+ }
175
+ );
158
176
 
159
177
  const from = extract_abs_number(cast.from);
160
178
  const to = extract_abs_number(cast.to);
@@ -140,8 +140,8 @@ export function jsonArrayFrom(expr, sql_type) {
140
140
  return pg_jsonArrayFrom(expr);
141
141
  case 'MYSQL':
142
142
  return mysql_jsonArrayFrom(expr);
143
- case 'MSSQL':
144
- return mssql_jsonArrayFrom(expr);
143
+ // case 'MSSQL':
144
+ // return mssql_jsonArrayFrom(expr);
145
145
  default:
146
146
  throw new Error(`sql_type=${sql_type} NOT SUPPORTED !`);
147
147
  }
@@ -171,7 +171,6 @@ export function jsonArrayFrom(expr, sql_type) {
171
171
  * @template O
172
172
  * @param {import('./con.helpers.json.js').SelectQueryBuilderExpression<O>} expr
173
173
  * @param {import('../types.public.d.ts').SqlDialectType} sql_type
174
- * @returns {import('kysely').RawBuilder<import('kysely').Simplify<O>[]>}
175
174
  */
176
175
  export function stringArrayFrom(expr, sql_type) {
177
176
  switch(sql_type) {
@@ -181,13 +180,14 @@ export function stringArrayFrom(expr, sql_type) {
181
180
  return pg_stringArrayFrom(expr);
182
181
  case 'MYSQL':
183
182
  return mysql_stringArrayFrom(expr);
184
- case 'MSSQL':
185
- return mssql_stringArrayFrom(expr);
183
+ // case 'MSSQL':
184
+ // return mssql_stringArrayFrom(expr);
186
185
  default:
187
186
  throw new Error(`sql_type=${sql_type} NOT SUPPORTED !`);
188
187
  }
189
188
  }
190
189
 
190
+
191
191
  /**
192
192
  * ### Examples
193
193
  *
@@ -223,8 +223,8 @@ export function jsonObjectFrom(expr, sql_type) {
223
223
  return pg_jsonObjectFrom(expr);
224
224
  case 'MYSQL':
225
225
  return mysql_jsonObjectFrom(expr);
226
- case 'MSSQL':
227
- return mssql_jsonObjectFrom(expr);
226
+ // case 'MSSQL':
227
+ // return mssql_jsonObjectFrom(expr);
228
228
  default:
229
229
  throw new Error(`sql_type=${sql_type} NOT SUPPORTED !`);
230
230
  }
@@ -106,7 +106,7 @@ export function mysql_jsonArrayFrom(expr) {
106
106
  * ```
107
107
  * @template O
108
108
  * @param {import('./con.helpers.json.js').SelectQueryBuilderExpression<O>} expr
109
- * @returns {import('kysely').RawBuilder<import('kysely').Simplify<O>[]>}
109
+ * @returns {import('kysely').RawBuilder<string[]>}
110
110
  */
111
111
  export function mysql_stringArrayFrom(expr) {
112
112
  const arg = extract_first_selection(expr, 'agg');
@@ -51,7 +51,7 @@ import { extract_first_selection } from './con.helpers.json.js';
51
51
  * ```
52
52
  * @template O
53
53
  * @param {import('./con.helpers.json.js').SelectQueryBuilderExpression<O>} expr
54
- * @returns {import('kysely').RawBuilder<import('kysely').Simplify<O>[]>}
54
+ * @returns {import('kysely').RawBuilder<string[]>}
55
55
  */
56
56
  export function pg_stringArrayFrom(expr) {
57
57
  const arg = extract_first_selection(expr, 'agg');
@@ -114,7 +114,7 @@ export function sqlite_jsonArrayFrom(expr) {
114
114
  * ```
115
115
  * @template O
116
116
  * @param {import('./con.helpers.json.js').SelectQueryBuilderExpression<O>} expr
117
- * @returns {import('kysely').RawBuilder<import('kysely').Simplify<O>[]>}
117
+ * @returns {import('kysely').RawBuilder<string[]>}
118
118
  */
119
119
  export function sqlite_stringArrayFrom(expr) {
120
120
  const arg = extract_first_selection(expr, 'agg');