@storecraft/database-sql-base 1.0.12 → 1.0.14
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 +20 -19
- package/migrations.mysql/00003_alter_auth_users.js +1 -0
- package/migrations.postgres/00003_alter_auth_users.js +1 -0
- package/migrations.shared/00003_alter_auth_users.js +37 -0
- package/migrations.sqlite/00003_alter_auth_users.js +1 -0
- package/package.json +1 -1
- package/src/con.auth_users.js +21 -20
- package/src/con.collections.js +123 -22
- package/src/con.customers.js +51 -16
- package/src/con.discounts.js +193 -58
- package/src/con.discounts.utils.js +13 -12
- package/src/con.helpers.json.js +34 -30
- package/src/con.helpers.json.mysql.js +39 -19
- package/src/con.helpers.json.postgres.js +14 -8
- package/src/con.helpers.json.sqlite.js +35 -15
- package/src/con.notifications.js +10 -6
- package/src/con.orders.js +4 -3
- package/src/con.posts.js +6 -6
- package/src/con.products.js +82 -33
- package/src/con.search.js +1 -7
- package/src/con.shared.experiment.js +1 -0
- package/src/con.shared.js +110 -63
- package/src/con.shipping.js +6 -6
- package/src/con.storefronts.js +170 -90
- package/src/con.tags.js +9 -5
- package/src/con.templates.js +3 -1
- package/src/utils.funcs.js +6 -2
- package/src/utils.query.js +24 -20
- package/src/utils.types.d.ts +25 -0
- package/tests/Untitled-1.sqlite3-query +19 -0
- package/tests/sandbox.js +210 -0
- package/types.sql.tables.d.ts +76 -22
- package/src/con.helpers.json.mssql.js +0 -233
- package/tests/sandbox.test.js +0 -73
package/src/con.shared.js
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
* @import { Database } from '../types.sql.tables.js'
|
4
4
|
* @import { ExpressionBuilder, InsertObject } from 'kysely'
|
5
5
|
* @import { SqlDialectType } from '../types.public.js'
|
6
|
+
* @import { QueryableTables } from './utils.types.js'
|
6
7
|
*/
|
7
8
|
import { ExpressionWrapper, InsertQueryBuilder, Kysely, Transaction } from 'kysely'
|
8
9
|
import { jsonArrayFrom, stringArrayFrom } from './con.helpers.json.js'
|
@@ -46,7 +47,7 @@ export const safe_trx = (k) => {
|
|
46
47
|
|
47
48
|
/**
|
48
49
|
* @param {SQL} driver
|
49
|
-
* @param {
|
50
|
+
* @param {QueryableTables} table_name
|
50
51
|
*
|
51
52
|
* @returns {db_crud["count"]}
|
52
53
|
*/
|
@@ -54,16 +55,16 @@ export const count_regular = (driver, table_name) => {
|
|
54
55
|
return async (query) => {
|
55
56
|
|
56
57
|
const result = await driver.client
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
.selectFrom(table_name)
|
59
|
+
.select(
|
60
|
+
(eb) => eb.fn.countAll().as('count')
|
61
|
+
)
|
62
|
+
.where(
|
63
|
+
(eb) => {
|
64
|
+
return query_to_eb(eb, query, table_name);
|
65
|
+
}
|
66
|
+
)
|
67
|
+
.executeTakeFirst();
|
67
68
|
|
68
69
|
return Number(result.count);
|
69
70
|
}
|
@@ -111,50 +112,102 @@ export const where_id_or_handle_table = (id_or_handle) => {
|
|
111
112
|
*/
|
112
113
|
|
113
114
|
/**
|
114
|
-
* helper to
|
115
|
+
* helper to delete entity values from conjunction table.
|
116
|
+
*
|
117
|
+
* Usually in entity tables, the (`value`, `reporter`) pair maps to
|
118
|
+
* (`secondary_entity_id`, `secondary_entity_handle`).
|
119
|
+
*
|
120
|
+
* 1. This is true for all entity tables except of `entity_to_tags_projections`,
|
121
|
+
* `entity_to_search_terms`, `entity_to_media`.
|
122
|
+
* 2. In those other entity tables, usually:
|
123
|
+
* - `value` identifies an entity
|
124
|
+
* - `reporter` handle identifies an entity in tables `products_to_collections`,
|
125
|
+
* `products_to_discounts`, `products_to_variants`, `products_to_related_products`
|
126
|
+
* - `reporter` does not identify an entity in `storefronts_to_other` because it
|
127
|
+
* hosts many resource types (for example, a post has the same handle as a product)
|
128
|
+
* - `reporter` + `context` identifies a secondary identity in `storefronts_to_other`
|
129
|
+
*
|
130
|
+
* Please consult the full documentation about interpretation of the entity
|
131
|
+
* tables in `../types.sql.tables.jd.ts`.
|
132
|
+
*
|
133
|
+
* Consult {@link '../types.sql.tables.jd.ts'} for the list of meaningful entity tables
|
134
|
+
* and their interpretations. and take a look at the database, it is actually
|
135
|
+
* quite simple
|
115
136
|
*
|
116
137
|
* @param {EntityTableKeys} entity_table_name
|
117
138
|
*/
|
118
|
-
export const
|
139
|
+
export const delete_entity_values_by_value_or_reporter_and_context = (
|
140
|
+
entity_table_name
|
141
|
+
) => {
|
119
142
|
/**
|
120
143
|
*
|
121
144
|
* @param {Kysely<Database>} trx
|
122
145
|
* @param {string} value delete by entity value
|
123
146
|
* @param {string} [reporter] delete by reporter
|
147
|
+
* @param {string} [context] delete by reporter + context
|
124
148
|
*/
|
125
|
-
return (trx, value, reporter
|
149
|
+
return (trx, value, reporter, context) => {
|
126
150
|
|
127
151
|
return trx.deleteFrom(entity_table_name).where(
|
128
152
|
eb => eb.or(
|
129
153
|
[
|
130
154
|
value && eb('value', '=', value),
|
131
|
-
reporter && eb(
|
155
|
+
reporter && context && eb.and(
|
156
|
+
[
|
157
|
+
eb('reporter', '=', reporter),
|
158
|
+
eb('context', '=', context),
|
159
|
+
]
|
160
|
+
),
|
161
|
+
reporter && !(context) && eb('reporter', '=', reporter),
|
132
162
|
].filter(Boolean)
|
133
163
|
)
|
134
164
|
).executeTakeFirst();
|
135
165
|
}
|
136
166
|
}
|
137
167
|
|
168
|
+
|
138
169
|
/**
|
139
|
-
* helper to
|
170
|
+
* helper to delete entity values
|
171
|
+
*
|
172
|
+
* 1. either by `entity_id` which always identifies an entity.
|
173
|
+
* 2. or by `entity_handle` which identifies an entity for some entity tables
|
174
|
+
* such as `products_to_collections`, `products_to_discounts`, `products_to_variants`,
|
175
|
+
* `products_to_related_products`, `storefronts_to_other`
|
176
|
+
* 3. or by `entity_handle` + `context` which identifies an entity for some entity tables
|
177
|
+
* such as `entity_to_tags_projections`, `entity_to_search_terms`, `entity_to_media`
|
178
|
+
*
|
179
|
+
* - `entity_handle` by itself does not always identify an entity,
|
180
|
+
* but `entity_handle` + `context` does.
|
181
|
+
*
|
182
|
+
* for example, we may have a product and a collection with the same `entity_handle`
|
183
|
+
* in the `entity_to_tags_projections` table, but they are different entities.
|
184
|
+
* Therefore, if we naively delete by `entity_handle`, we may delete more entities than intended.
|
140
185
|
*
|
141
186
|
* @param {EntityTableKeys} entity_table_name
|
142
187
|
*/
|
143
|
-
export const
|
144
|
-
|
188
|
+
export const delete_entity_values_of_by_entity_id_or_handle_and_context = (
|
189
|
+
entity_table_name
|
190
|
+
) => {
|
145
191
|
/**
|
146
192
|
*
|
147
193
|
* @param {Kysely<Database>} trx
|
148
194
|
* @param {string} entity_id delete by id
|
149
|
-
* @param {string} [entity_handle
|
195
|
+
* @param {string} [entity_handle] delete by handle
|
196
|
+
* @param {string} [context=undefined] the context (another segment technique)
|
150
197
|
*/
|
151
|
-
return (trx, entity_id, entity_handle=undefined) => {
|
198
|
+
return (trx, entity_id, entity_handle=undefined, context=undefined) => {
|
152
199
|
return trx.deleteFrom(entity_table_name).where(
|
153
200
|
eb => eb.or(
|
154
201
|
[
|
155
|
-
eb('entity_id', '=', entity_id),
|
156
|
-
|
157
|
-
|
202
|
+
entity_id && eb('entity_id', '=', entity_id),
|
203
|
+
entity_handle && context && eb.and(
|
204
|
+
[
|
205
|
+
eb('entity_handle', '=', entity_handle),
|
206
|
+
eb('context', '=', context)
|
207
|
+
]
|
208
|
+
),
|
209
|
+
entity_handle && !(context) && eb('entity_handle', '=', entity_handle),
|
210
|
+
].filter(Boolean)
|
158
211
|
)
|
159
212
|
).executeTakeFirst();
|
160
213
|
}
|
@@ -173,23 +226,18 @@ export const insert_entity_array_values_of = (entity_table_name) => {
|
|
173
226
|
* @param {string} [item_handle] whom the tags belong to
|
174
227
|
* @param {boolean} [delete_previous=true] if true and `reporter`,
|
175
228
|
* then will delete by reporter, otherwise by `item_id/item_handle`
|
176
|
-
* @param {string} [reporter=undefined] the reporter of the batch values
|
177
|
-
* (another segment technique)
|
178
229
|
* @param {string} [context=undefined] the context (another segment technique)
|
179
230
|
*/
|
180
|
-
return async (
|
181
|
-
|
231
|
+
return async (
|
232
|
+
trx, values, item_id, item_handle,
|
233
|
+
delete_previous=true,
|
234
|
+
context=undefined
|
235
|
+
) => {
|
182
236
|
|
183
237
|
if(delete_previous) {
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
);
|
188
|
-
} else {
|
189
|
-
await delete_entity_values_of_by_entity_id_or_handle(entity_table_name)(
|
190
|
-
trx, item_id, item_handle
|
191
|
-
);
|
192
|
-
}
|
238
|
+
await delete_entity_values_of_by_entity_id_or_handle_and_context(entity_table_name)(
|
239
|
+
trx, item_id, item_handle, context
|
240
|
+
);
|
193
241
|
}
|
194
242
|
|
195
243
|
if(!values?.length) return Promise.resolve();
|
@@ -199,7 +247,6 @@ export const insert_entity_array_values_of = (entity_table_name) => {
|
|
199
247
|
entity_handle: item_handle,
|
200
248
|
entity_id: item_id,
|
201
249
|
value: t,
|
202
|
-
reporter,
|
203
250
|
context
|
204
251
|
})
|
205
252
|
)
|
@@ -254,7 +301,7 @@ export const insert_entity_array_values_with_delete_of = (entity_table) => {
|
|
254
301
|
*/
|
255
302
|
return (trx, values, item_id, item_handle, context) => {
|
256
303
|
return insert_entity_array_values_of(entity_table)(
|
257
|
-
trx, values, item_id, item_handle, true,
|
304
|
+
trx, values, item_id, item_handle, true, context
|
258
305
|
)
|
259
306
|
};
|
260
307
|
}
|
@@ -263,9 +310,9 @@ export const insert_tags_of = insert_entity_array_values_with_delete_of('entity_
|
|
263
310
|
export const insert_search_of = insert_entity_array_values_with_delete_of('entity_to_search_terms');
|
264
311
|
export const insert_media_of = insert_entity_array_values_with_delete_of('entity_to_media');
|
265
312
|
|
266
|
-
export const delete_tags_of =
|
267
|
-
export const delete_search_of =
|
268
|
-
export const delete_media_of =
|
313
|
+
export const delete_tags_of = delete_entity_values_of_by_entity_id_or_handle_and_context('entity_to_tags_projections');
|
314
|
+
export const delete_search_of = delete_entity_values_of_by_entity_id_or_handle_and_context('entity_to_search_terms');
|
315
|
+
export const delete_media_of = delete_entity_values_of_by_entity_id_or_handle_and_context('entity_to_media');
|
269
316
|
|
270
317
|
|
271
318
|
/**
|
@@ -679,25 +726,25 @@ export const select_values_of_entity_by_entity_id_or_handle =
|
|
679
726
|
.orderBy(`${entity_junction_table}.id`);
|
680
727
|
}
|
681
728
|
|
682
|
-
/**
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
export const select_entity_ids_by_value_or_reporter =
|
691
|
-
(eb, entity_junction_table, value, reporter=undefined) => {
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
}
|
729
|
+
// /**
|
730
|
+
// * select the entity ids which are constrained by value or reporter
|
731
|
+
// *
|
732
|
+
// * @param {ExpressionBuilder<Database>} eb
|
733
|
+
// * @param {EntityTableKeys} entity_junction_table
|
734
|
+
// * @param {string | ExpressionWrapper<Database>} value
|
735
|
+
// * @param {string | ExpressionWrapper<Database>} [reporter]
|
736
|
+
// */
|
737
|
+
// export const select_entity_ids_by_value_or_reporter =
|
738
|
+
// (eb, entity_junction_table, value, reporter=undefined) => {
|
739
|
+
// return eb
|
740
|
+
// .selectFrom(entity_junction_table)
|
741
|
+
// .select(`${entity_junction_table}.entity_id`)
|
742
|
+
// .where(eb2 => eb2.or(
|
743
|
+
// [
|
744
|
+
// eb2(`${entity_junction_table}.value`, '=', value ?? reporter),
|
745
|
+
// eb2(`${entity_junction_table}.reporter`, '=', reporter ?? value),
|
746
|
+
// ]
|
747
|
+
// )
|
748
|
+
// )
|
749
|
+
// .orderBy(`${entity_junction_table}.entity_id`);
|
750
|
+
// }
|
package/src/con.shipping.js
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
*/
|
4
4
|
import { SQL } from '../index.js'
|
5
5
|
import { report_document_media } from './con.images.js'
|
6
|
-
import { count_regular,
|
6
|
+
import { count_regular, delete_entity_values_by_value_or_reporter_and_context,
|
7
7
|
delete_me, delete_media_of, delete_search_of,
|
8
8
|
delete_tags_of, insert_media_of, insert_search_of,
|
9
9
|
insert_tags_of, regular_upsert_me, where_id_or_handle_table,
|
@@ -83,12 +83,12 @@ const remove = (driver) => {
|
|
83
83
|
async (trx) => {
|
84
84
|
|
85
85
|
// entities
|
86
|
-
await
|
87
|
-
await
|
88
|
-
await
|
86
|
+
await delete_tags_of(trx, id_or_handle, id_or_handle, table_name);
|
87
|
+
await delete_search_of(trx, id_or_handle, id_or_handle, table_name);
|
88
|
+
await delete_media_of(trx, id_or_handle, id_or_handle, table_name);
|
89
89
|
// STOREFRONT => SHIPPING
|
90
|
-
await
|
91
|
-
trx, id_or_handle, id_or_handle
|
90
|
+
await delete_entity_values_by_value_or_reporter_and_context('storefronts_to_other')(
|
91
|
+
trx, id_or_handle, id_or_handle, table_name
|
92
92
|
);
|
93
93
|
// delete me
|
94
94
|
await delete_me(trx, table_name, id_or_handle);
|
package/src/con.storefronts.js
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
/**
|
2
2
|
* @import { db_storefronts as db_col } from '@storecraft/core/database'
|
3
|
+
* @import { Database } from '../types.sql.tables.js';
|
3
4
|
*/
|
4
5
|
import { SQL } from '../index.js'
|
6
|
+
import { jsonArrayFrom, stringArrayFrom } from './con.helpers.json.js'
|
5
7
|
import { report_document_media } from './con.images.js'
|
6
|
-
import {
|
8
|
+
import { delete_entity_values_of_by_entity_id_or_handle_and_context,
|
7
9
|
delete_me, delete_media_of, delete_search_of,
|
8
10
|
delete_tags_of, insert_entity_values_of, insert_media_of,
|
9
11
|
insert_search_of, insert_tags_of, storefront_with_collections,
|
@@ -12,7 +14,11 @@ import { delete_entity_values_of_by_entity_id_or_handle,
|
|
12
14
|
regular_upsert_me, where_id_or_handle_table,
|
13
15
|
with_media, with_tags,
|
14
16
|
count_regular,
|
15
|
-
with_search
|
17
|
+
with_search,
|
18
|
+
products_with_collections,
|
19
|
+
products_with_discounts,
|
20
|
+
products_with_variants,
|
21
|
+
products_with_related_products} from './con.shared.js'
|
16
22
|
import { sanitize, sanitize_array } from './utils.funcs.js'
|
17
23
|
import { query_to_eb, query_to_sort } from './utils.query.js'
|
18
24
|
|
@@ -35,8 +41,8 @@ const upsert = (driver) => {
|
|
35
41
|
await report_document_media(driver)(item, trx);
|
36
42
|
// Explicit STOREFRONTS => PRODUCTS / COLLECTIONS / DISCOUNTS / SHIPPING / POSTS
|
37
43
|
// remove all the past connections of this storefront at once
|
38
|
-
await
|
39
|
-
trx, item.id
|
44
|
+
await delete_entity_values_of_by_entity_id_or_handle_and_context('storefronts_to_other')(
|
45
|
+
trx, item.id
|
40
46
|
);
|
41
47
|
if(item.collections) { // add this storefront's new collections connections
|
42
48
|
await insert_entity_values_of('storefronts_to_other')(
|
@@ -115,11 +121,21 @@ const get = (driver) => {
|
|
115
121
|
with_media(eb, id_or_handle, driver.dialectType),
|
116
122
|
with_tags(eb, id_or_handle, driver.dialectType),
|
117
123
|
with_search(eb, id_or_handle, driver.dialectType),
|
118
|
-
expand_collections && storefront_with_collections(
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
124
|
+
expand_collections && storefront_with_collections(
|
125
|
+
eb, id_or_handle, driver.dialectType
|
126
|
+
),
|
127
|
+
expand_products && storefront_with_products(
|
128
|
+
eb, id_or_handle, driver.dialectType
|
129
|
+
),
|
130
|
+
expand_discounts && storefront_with_discounts(
|
131
|
+
eb, id_or_handle, driver.dialectType
|
132
|
+
),
|
133
|
+
expand_shipping && storefront_with_shipping(
|
134
|
+
eb, id_or_handle, driver.dialectType
|
135
|
+
),
|
136
|
+
expand_posts && storefront_with_posts(
|
137
|
+
eb, id_or_handle, driver.dialectType
|
138
|
+
),
|
123
139
|
]
|
124
140
|
.filter(Boolean))
|
125
141
|
.where(where_id_or_handle_table(id_or_handle))
|
@@ -140,11 +156,12 @@ const remove = (driver) => {
|
|
140
156
|
async (trx) => {
|
141
157
|
|
142
158
|
// entities
|
143
|
-
await
|
144
|
-
await
|
145
|
-
await delete_media_of(trx, id_or_handle);
|
159
|
+
await delete_tags_of(trx, id_or_handle, id_or_handle, table_name);
|
160
|
+
await delete_search_of(trx, id_or_handle, id_or_handle, table_name);
|
161
|
+
await delete_media_of(trx, id_or_handle, id_or_handle, table_name);
|
146
162
|
// delete storefront => other
|
147
|
-
|
163
|
+
// this is correct, since `id` or `handle` are both unique for this table
|
164
|
+
await delete_entity_values_of_by_entity_id_or_handle_and_context('storefronts_to_other')(
|
148
165
|
trx, id_or_handle, id_or_handle
|
149
166
|
);
|
150
167
|
// delete me
|
@@ -183,11 +200,21 @@ const list = (driver) => {
|
|
183
200
|
with_media(eb, eb.ref('storefronts.id'), driver.dialectType),
|
184
201
|
with_tags(eb, eb.ref('storefronts.id'), driver.dialectType),
|
185
202
|
with_search(eb, eb.ref('storefronts.id'), driver.dialectType),
|
186
|
-
expand_collections && storefront_with_collections(
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
203
|
+
expand_collections && storefront_with_collections(
|
204
|
+
eb, eb.ref('storefronts.id'), driver.dialectType
|
205
|
+
),
|
206
|
+
expand_products && storefront_with_products(
|
207
|
+
eb, eb.ref('storefronts.id'), driver.dialectType
|
208
|
+
),
|
209
|
+
expand_discounts && storefront_with_discounts(
|
210
|
+
eb, eb.ref('storefronts.id'), driver.dialectType
|
211
|
+
),
|
212
|
+
expand_shipping && storefront_with_shipping(
|
213
|
+
eb, eb.ref('storefronts.id'), driver.dialectType
|
214
|
+
),
|
215
|
+
expand_posts && storefront_with_posts(
|
216
|
+
eb, eb.ref('storefronts.id'), driver.dialectType
|
217
|
+
),
|
191
218
|
].filter(Boolean)
|
192
219
|
)
|
193
220
|
.where(
|
@@ -206,82 +233,139 @@ const list = (driver) => {
|
|
206
233
|
}
|
207
234
|
|
208
235
|
/**
|
209
|
-
* @
|
210
|
-
* @returns {db_col["list_storefront_products"]}
|
236
|
+
* @type {{[K in keyof Database]?: (keyof Database[K])[]}}
|
211
237
|
*/
|
212
|
-
const
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
);
|
220
|
-
return item?.products ?? []
|
238
|
+
const resource_to_props = (
|
239
|
+
{
|
240
|
+
'collections': ['active', 'attributes', 'created_at', 'description', 'handle', 'id', 'published', 'title', 'updated_at'],
|
241
|
+
'discounts': ['active', 'application', 'attributes', 'created_at', 'description', 'handle', 'id', 'info', 'priority', 'published', 'title', 'updated_at'],
|
242
|
+
'products': ['active', 'attributes', 'compare_at_price', 'created_at', 'description', 'handle', 'id', 'isbn', 'parent_handle', 'parent_id', 'price', 'qty', 'title', 'updated_at', 'variant_hint', 'variants_options', 'video'],
|
243
|
+
'shipping_methods': ['active', 'attributes', 'created_at', 'description', 'handle', 'id', 'price', 'title', 'updated_at'],
|
244
|
+
'posts': ['active', 'attributes', 'created_at', 'description', 'handle', 'id', 'text', 'title', 'updated_at'],
|
221
245
|
}
|
222
|
-
|
246
|
+
);
|
223
247
|
|
224
|
-
/**
|
225
|
-
* @param {SQL} driver
|
226
|
-
* @returns {db_col["list_storefront_collections"]}
|
227
|
-
*/
|
228
|
-
const list_storefront_collections = (driver) => {
|
229
|
-
return async (product_id_or_handle) => {
|
230
|
-
// because we load everything (we don't expect storefronts to
|
231
|
-
// promote so many products), therefore we use the simple `get`
|
232
|
-
// method instead of a query
|
233
|
-
const item = await get(driver)(
|
234
|
-
product_id_or_handle, { expand: ['collections'] }
|
235
|
-
);
|
236
|
-
return item?.collections ?? []
|
237
|
-
}
|
238
|
-
}
|
239
|
-
|
240
|
-
/**
|
241
|
-
* @param {SQL} driver
|
242
|
-
* @returns {db_col["list_storefront_discounts"]}
|
243
|
-
*/
|
244
|
-
const list_storefront_discounts = (driver) => {
|
245
|
-
return async (product_id_or_handle) => {
|
246
|
-
// because we load everything (we don't expect storefronts to
|
247
|
-
// promote so many products), therefore we use the simple `get`
|
248
|
-
// method instead of a query
|
249
|
-
const item = await get(driver)(
|
250
|
-
product_id_or_handle, { expand: ['discounts'] }
|
251
|
-
);
|
252
|
-
return item?.discounts ?? []
|
253
|
-
}
|
254
|
-
}
|
255
248
|
|
256
249
|
/**
|
257
250
|
* @param {SQL} driver
|
258
|
-
* @returns {db_col["
|
251
|
+
* @returns {db_col["get_default_auto_generated_storefront"]}
|
259
252
|
*/
|
260
|
-
const
|
261
|
-
return async (
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
const
|
266
|
-
|
253
|
+
const get_default_auto_generated_storefront = (driver) => {
|
254
|
+
return async () => {
|
255
|
+
const client = driver.client;
|
256
|
+
const dialectType = driver.dialectType;
|
257
|
+
const limit = -1;
|
258
|
+
const sf = await client.selectNoFrom(
|
259
|
+
eb => [
|
260
|
+
jsonArrayFrom(
|
261
|
+
eb
|
262
|
+
.selectFrom('collections')
|
263
|
+
.select(resource_to_props.collections)
|
264
|
+
.select(
|
265
|
+
eb => [
|
266
|
+
with_tags(eb, eb.ref('collections.id'), dialectType),
|
267
|
+
with_media(eb, eb.ref('collections.id'), dialectType),
|
268
|
+
]
|
269
|
+
)
|
270
|
+
.where('active', '=', 1)
|
271
|
+
.orderBy(['updated_at desc']),
|
272
|
+
driver.dialectType
|
273
|
+
).as('collections'),
|
274
|
+
|
275
|
+
jsonArrayFrom(
|
276
|
+
eb
|
277
|
+
.selectFrom('products')
|
278
|
+
.select(resource_to_props.products)
|
279
|
+
.select(
|
280
|
+
eb => [
|
281
|
+
with_tags(eb, eb.ref('products.id'), dialectType),
|
282
|
+
with_media(eb, eb.ref('products.id'), dialectType),
|
283
|
+
products_with_collections(eb, eb.ref('products.id'), dialectType),
|
284
|
+
products_with_discounts(eb, eb.ref('products.id'), dialectType),
|
285
|
+
products_with_variants(eb, eb.ref('products.id'), dialectType),
|
286
|
+
products_with_related_products(eb, eb.ref('products.id'), dialectType),
|
287
|
+
]
|
288
|
+
)
|
289
|
+
.where('active', '=', 1)
|
290
|
+
.orderBy(['updated_at desc'])
|
291
|
+
.limit(10),
|
292
|
+
dialectType
|
293
|
+
).as('products'),
|
294
|
+
|
295
|
+
jsonArrayFrom(
|
296
|
+
eb
|
297
|
+
.selectFrom('discounts')
|
298
|
+
.select(resource_to_props.discounts)
|
299
|
+
.select(
|
300
|
+
eb => [
|
301
|
+
with_tags(eb, eb.ref('discounts.id'), dialectType),
|
302
|
+
with_media(eb, eb.ref('discounts.id'), dialectType),
|
303
|
+
]
|
304
|
+
)
|
305
|
+
.where('active', '=', 1)
|
306
|
+
.orderBy(['updated_at desc']),
|
307
|
+
dialectType
|
308
|
+
).as('discounts'),
|
309
|
+
|
310
|
+
jsonArrayFrom(
|
311
|
+
eb
|
312
|
+
.selectFrom('shipping_methods')
|
313
|
+
.select(resource_to_props.shipping_methods)
|
314
|
+
.select(
|
315
|
+
eb => [
|
316
|
+
with_tags(eb, eb.ref('shipping_methods.id'), dialectType),
|
317
|
+
with_media(eb, eb.ref('shipping_methods.id'), dialectType),
|
318
|
+
]
|
319
|
+
)
|
320
|
+
.where('active', '=', 1)
|
321
|
+
.orderBy(['updated_at desc']),
|
322
|
+
dialectType
|
323
|
+
).as('shipping_methods'),
|
324
|
+
|
325
|
+
jsonArrayFrom(
|
326
|
+
eb
|
327
|
+
.selectFrom('posts')
|
328
|
+
.select(resource_to_props.posts)
|
329
|
+
.select(
|
330
|
+
eb => [
|
331
|
+
with_tags(eb, eb.ref('posts.id'), dialectType),
|
332
|
+
with_media(eb, eb.ref('posts.id'), dialectType),
|
333
|
+
]
|
334
|
+
)
|
335
|
+
.where('active', '=', 1)
|
336
|
+
.orderBy(['updated_at desc'])
|
337
|
+
.limit(3),
|
338
|
+
dialectType
|
339
|
+
).as('posts'),
|
340
|
+
|
341
|
+
stringArrayFrom(
|
342
|
+
eb.selectFrom('products')
|
343
|
+
.innerJoin(
|
344
|
+
'entity_to_tags_projections',
|
345
|
+
'entity_to_tags_projections.entity_id',
|
346
|
+
'products.id'
|
347
|
+
)
|
348
|
+
.select('entity_to_tags_projections.value as tag')
|
349
|
+
.groupBy('tag'),
|
350
|
+
dialectType
|
351
|
+
).as('all_used_products_tags')
|
352
|
+
]
|
353
|
+
)
|
354
|
+
.executeTakeFirst();
|
355
|
+
|
356
|
+
const sanitized = sanitize(
|
357
|
+
{
|
358
|
+
active: true,
|
359
|
+
created_at: new Date().toISOString(),
|
360
|
+
handle: 'default-auto-generated-storefront',
|
361
|
+
id: 'default',
|
362
|
+
title: 'Default Auto Generated Storefront',
|
363
|
+
description: 'Default Auto Generated Storefront',
|
364
|
+
...sf
|
365
|
+
}
|
267
366
|
);
|
268
|
-
return item?.posts ?? []
|
269
|
-
}
|
270
|
-
}
|
271
367
|
|
272
|
-
|
273
|
-
* @param {SQL} driver
|
274
|
-
* @returns {db_col["list_storefront_shipping_methods"]}
|
275
|
-
*/
|
276
|
-
const list_storefront_shipping_methods = (driver) => {
|
277
|
-
return async (product_id_or_handle) => {
|
278
|
-
// because we load everything (we don't expect storefronts to
|
279
|
-
// promote so many products), therefore we use the simple `get`
|
280
|
-
// method instead of a query
|
281
|
-
const item = await get(driver)(
|
282
|
-
product_id_or_handle, { expand: ['shipping_methods'] }
|
283
|
-
);
|
284
|
-
return item?.shipping_methods ?? []
|
368
|
+
return sanitized;
|
285
369
|
}
|
286
370
|
}
|
287
371
|
|
@@ -296,12 +380,8 @@ export const impl = (driver) => {
|
|
296
380
|
upsert: upsert(driver),
|
297
381
|
remove: remove(driver),
|
298
382
|
list: list(driver),
|
299
|
-
list_storefront_products: list_storefront_products(driver),
|
300
|
-
list_storefront_collections: list_storefront_collections(driver),
|
301
|
-
list_storefront_discounts: list_storefront_discounts(driver),
|
302
|
-
list_storefront_posts: list_storefront_posts(driver),
|
303
|
-
list_storefront_shipping_methods: list_storefront_shipping_methods(driver),
|
304
383
|
count: count_regular(driver, table_name),
|
384
|
+
get_default_auto_generated_storefront: get_default_auto_generated_storefront(driver),
|
305
385
|
}
|
306
386
|
}
|
307
387
|
|
package/src/con.tags.js
CHANGED
@@ -2,10 +2,11 @@
|
|
2
2
|
* @import { db_tags as db_col } from '@storecraft/core/database'
|
3
3
|
*/
|
4
4
|
import { SQL } from '../index.js'
|
5
|
-
import {
|
5
|
+
import {
|
6
|
+
count_regular, delete_me, delete_search_of, insert_search_of,
|
6
7
|
regular_upsert_me, where_id_or_handle_table,
|
7
|
-
with_media,
|
8
|
-
|
8
|
+
with_media, with_search
|
9
|
+
} from './con.shared.js'
|
9
10
|
import { sanitize, sanitize_array } from './utils.funcs.js'
|
10
11
|
import { query_to_eb, query_to_sort } from './utils.query.js'
|
11
12
|
|
@@ -23,11 +24,14 @@ const upsert = (driver) => {
|
|
23
24
|
async (trx) => {
|
24
25
|
await insert_search_of(trx, search_terms, item.id, item.handle, table_name);
|
25
26
|
await regular_upsert_me(trx, table_name, {
|
27
|
+
active: item.active ? 1 : 0,
|
28
|
+
description: item.description,
|
26
29
|
created_at: item.created_at,
|
27
30
|
updated_at: item.updated_at,
|
28
31
|
id: item.id,
|
29
32
|
handle: item.handle,
|
30
|
-
|
33
|
+
attributes: JSON.stringify(item.attributes),
|
34
|
+
values: JSON.stringify(item.values),
|
31
35
|
});
|
32
36
|
}
|
33
37
|
);
|
@@ -71,7 +75,7 @@ const remove = (driver) => {
|
|
71
75
|
async (trx) => {
|
72
76
|
|
73
77
|
// entities
|
74
|
-
await delete_search_of(trx, id_or_handle);
|
78
|
+
await delete_search_of(trx, id_or_handle, id_or_handle, table_name);
|
75
79
|
// delete me
|
76
80
|
await delete_me(trx, table_name, id_or_handle);
|
77
81
|
}
|