@storecraft/database-sql-base 1.0.9 → 1.0.11

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.
@@ -72,9 +72,10 @@ export const query_cursor_to_eb = (eb, c, relation, transformer=(x)=>x) => {
72
72
 
73
73
 
74
74
  /**
75
+ * @template {keyof Database} T
75
76
  * @param {import("kysely").ExpressionBuilder<Database>} eb
76
77
  * @param {import("@storecraft/core/vql").VQL.Node} node
77
- * @param {keyof Database} table_name
78
+ * @param {T} table_name
78
79
  */
79
80
  export const query_vql_node_to_eb = (eb, node, table_name) => {
80
81
  if(node.op==='LEAF') {
@@ -128,12 +129,28 @@ export const query_vql_to_eb = (eb, root, table_name) => {
128
129
  }
129
130
 
130
131
 
132
+ /**
133
+ *
134
+ * @param {[k: string, v: any]} kv
135
+ * @returns {[k: string, v: any]}
136
+ */
137
+ const transform_boolean_to_0_or_1 = (kv) => {
138
+ if(typeof kv[1] === 'boolean') {
139
+ return [
140
+ kv[0],
141
+ kv[1] ? 1 : 0
142
+ ]
143
+ }
144
+ return kv;
145
+ }
146
+
131
147
  /**
132
148
  * Convert an API Query into mongo dialect, also sanitize.
133
149
  *
150
+ * @template {any} [T=any]
134
151
  *
135
152
  * @param {import("kysely").ExpressionBuilder<Database>} eb
136
- * @param {import("@storecraft/core/api").ApiQuery} q
153
+ * @param {import("@storecraft/core/api").ApiQuery<T>} q
137
154
  * @param {keyof Database} table_name
138
155
  *
139
156
  */
@@ -145,15 +162,15 @@ export const query_to_eb = (eb, q={}, table_name) => {
145
162
 
146
163
  // compute index clauses
147
164
  if(q.startAt) {
148
- clauses.push(query_cursor_to_eb(eb, q.startAt, asc ? '>=' : '<='));
165
+ clauses.push(query_cursor_to_eb(eb, q.startAt, asc ? '>=' : '<=', transform_boolean_to_0_or_1));
149
166
  } else if(q.startAfter) {
150
- clauses.push(query_cursor_to_eb(eb, q.startAfter, asc ? '>' : '<'));
167
+ clauses.push(query_cursor_to_eb(eb, q.startAfter, asc ? '>' : '<', transform_boolean_to_0_or_1));
151
168
  }
152
169
 
153
170
  if(q.endAt) {
154
- clauses.push(query_cursor_to_eb(eb, q.endAt, asc ? '<=' : '>='));
171
+ clauses.push(query_cursor_to_eb(eb, q.endAt, asc ? '<=' : '>=', transform_boolean_to_0_or_1));
155
172
  } else if(q.endBefore) {
156
- clauses.push(query_cursor_to_eb(eb, q.endBefore, asc ? '<' : '>'));
173
+ clauses.push(query_cursor_to_eb(eb, q.endBefore, asc ? '<' : '>', transform_boolean_to_0_or_1));
157
174
  }
158
175
 
159
176
  // compute VQL clauses
@@ -174,12 +191,22 @@ const SIGN = {
174
191
  '-1': 'desc'
175
192
  }
176
193
 
194
+ // export type DirectedOrderByStringReference<DB, TB extends keyof DB, O> = `${StringReference<DB, TB> | (keyof O & string)} ${OrderByDirection}`;
195
+
196
+ /**
197
+ * @import {DirectedOrderByStringReference} from './utils.types.js'
198
+ */
199
+ // OE extends OrderByExpression<DB, TB, O>
177
200
  /**
178
201
  * Convert an API Query into mongo dialect, also sanitize.
202
+ * @template {Record<string, any>} [Type=Record<string, any>]
203
+ * @template {keyof Database} [Table=keyof Database]
179
204
  *
180
- * @param {import("@storecraft/core/api").ApiQuery} q
205
+ * @param {import("@storecraft/core/api").ApiQuery<Type>} q
206
+ * @param {Table} table
207
+ * @returns {DirectedOrderByStringReference<Database, Table, Database[Table]>[]}
181
208
  */
182
- export const query_to_sort = (q={}) => {
209
+ export const query_to_sort = (q={}, table) => {
183
210
  // const sort_sign = q.order === 'asc' ? 'asc' : 'desc';
184
211
  // `reverse_sign=-1` means we need to reverse because of `limitToLast`
185
212
  const reverse_sign = (q.limitToLast && !q.limit) ? -1 : 1;
@@ -187,9 +214,11 @@ export const query_to_sort = (q={}) => {
187
214
  const sort_sign = (asc ? 1 : -1) * reverse_sign;
188
215
 
189
216
  // compute sort fields and order
190
- const sort = (q.sortBy?.length ? q.sortBy : ['updated_at', 'id']).map(
217
+ const keys = q.sortBy?.length ? q.sortBy : ['updated_at', 'id'];
218
+ const sort = keys.map(
191
219
  s => `${s} ${SIGN[sort_sign]}`
192
220
  )
193
-
221
+ // it's too complicated to map each ket to table column.
222
+ // kysely was designed to do this in place
194
223
  return sort;
195
224
  }
@@ -0,0 +1,17 @@
1
+ import { StringReference } from "kysely";
2
+
3
+ export type NoActive<T> = T extends {active:number} ? Omit<T, 'active'> & {active: boolean} : T;
4
+ export type ReplaceValues<T, Find extends any=any, ReplaceWith extends any=any> = {
5
+ [K in keyof T]: T[K] extends Find ? ReplaceWith : T[K]
6
+ };
7
+
8
+ export type ReplaceValuesOfKeys<T, Find extends keyof T=keyof T, ReplaceWith extends any=any> = {
9
+ [K in keyof T]: K extends Find ? ReplaceWith : T[K]
10
+ };
11
+
12
+ export type NO<T> = {
13
+ [P in keyof T]: T[P]
14
+ }
15
+
16
+ export type OrderByDirection = 'asc' | 'desc';
17
+ export type DirectedOrderByStringReference<DB, TB extends keyof DB, O> = `${StringReference<DB, TB> | (keyof O & string)} ${OrderByDirection}`;
@@ -240,7 +240,7 @@ export interface DiscountsTable extends Base {
240
240
  /** details and filters of the discount */
241
241
  info: JSONColumnType<DiscountInfo>;
242
242
  /** discount application (automatic and coupons) */
243
- application: JSONColumnType<DiscountApplicationEnum>;
243
+ application: JSONColumnType<DiscountApplicationEnum[keyof DiscountApplicationEnum]>;
244
244
  /** internal usage, the application type id */
245
245
  _application_id: number;
246
246
  /** internal usage, the discount type id */