@storecraft/database-sql-base 1.0.0

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 (49) hide show
  1. package/README.md +126 -0
  2. package/TODO.md +2 -0
  3. package/db-strategy.md +3 -0
  4. package/driver.js +190 -0
  5. package/index.js +3 -0
  6. package/migrate.js +66 -0
  7. package/migrations.mssql/00000_init_tables.js +268 -0
  8. package/migrations.mysql/00000_init_tables.js +372 -0
  9. package/migrations.mysql/00001_seed_email_templates.js +1 -0
  10. package/migrations.postgres/00000_init_tables.js +358 -0
  11. package/migrations.postgres/00001_seed_email_templates.js +1 -0
  12. package/migrations.shared/00001_seed_email_templates.js +260 -0
  13. package/migrations.sqlite/00000_init_tables.js +357 -0
  14. package/migrations.sqlite/00001_seed_email_templates.js +1 -0
  15. package/package.json +47 -0
  16. package/src/con.auth_users.js +159 -0
  17. package/src/con.collections.js +197 -0
  18. package/src/con.customers.js +202 -0
  19. package/src/con.discounts.js +225 -0
  20. package/src/con.discounts.utils.js +180 -0
  21. package/src/con.helpers.json.js +231 -0
  22. package/src/con.helpers.json.mssql.js +233 -0
  23. package/src/con.helpers.json.mysql.js +239 -0
  24. package/src/con.helpers.json.postgres.js +223 -0
  25. package/src/con.helpers.json.sqlite.js +263 -0
  26. package/src/con.images.js +230 -0
  27. package/src/con.notifications.js +149 -0
  28. package/src/con.orders.js +156 -0
  29. package/src/con.posts.js +147 -0
  30. package/src/con.products.js +497 -0
  31. package/src/con.search.js +148 -0
  32. package/src/con.shared.js +616 -0
  33. package/src/con.shipping.js +147 -0
  34. package/src/con.storefronts.js +301 -0
  35. package/src/con.tags.js +120 -0
  36. package/src/con.templates.js +133 -0
  37. package/src/kysely.sanitize.plugin.js +40 -0
  38. package/src/utils.funcs.js +77 -0
  39. package/src/utils.query.js +195 -0
  40. package/tests/query.cursor.test.js +389 -0
  41. package/tests/query.vql.test.js +71 -0
  42. package/tests/runner.mssql-local.test.js +118 -0
  43. package/tests/runner.mysql-local.test.js +101 -0
  44. package/tests/runner.postgres-local.test.js +99 -0
  45. package/tests/runner.sqlite-local.test.js +99 -0
  46. package/tests/sandbox.test.js +71 -0
  47. package/tsconfig.json +21 -0
  48. package/types.public.d.ts +19 -0
  49. package/types.sql.tables.d.ts +247 -0
@@ -0,0 +1,372 @@
1
+ import { CreateTableBuilder, Kysely } from 'kysely'
2
+
3
+ /**
4
+ * @typedef {import('../types.sql.tables.js').Database} Database
5
+ */
6
+
7
+ /**
8
+ * @template {string} TB
9
+ * @template {string} B
10
+ * @param {CreateTableBuilder<TB, B>} tb
11
+ */
12
+ const add_base_columns = tb => {
13
+ return tb
14
+ .addColumn('id', 'varchar(255)', (col) =>
15
+ col.primaryKey()
16
+ )
17
+ .addColumn('handle', 'varchar(255)', (col) => col.unique())
18
+ .addColumn('created_at', 'varchar(32)')
19
+ .addColumn('updated_at', 'varchar(32)')
20
+ .addColumn('attributes', 'json')
21
+ .addColumn('description', 'text')
22
+ .addColumn('active', 'integer')
23
+
24
+ }
25
+
26
+ /**
27
+ * @param {Kysely<Database>} db
28
+ * @param {keyof Database} table_name
29
+ */
30
+ const create_entity_to_value_table = (db, table_name) => {
31
+
32
+ return db.schema
33
+ .createTable(table_name)
34
+ .addColumn('id', 'integer',
35
+ (col) => col.autoIncrement().primaryKey()
36
+ )
37
+ .addColumn('entity_id', 'varchar(100)', col => col.notNull())
38
+ .addColumn('entity_handle', 'varchar(255)')
39
+ .addColumn('value', 'varchar(500)')
40
+ .addColumn('reporter', 'varchar(100)')
41
+ .addColumn('context', 'varchar(100)')
42
+ }
43
+
44
+ /**
45
+ *
46
+ * @param {Kysely<Database>} db
47
+ * @param {keyof Database} table_name
48
+ */
49
+ const create_safe_table = (db, table_name) => {
50
+ return db.schema.createTable(table_name);
51
+ }
52
+
53
+ /**
54
+ *
55
+ * @param {Kysely<Database>} db
56
+ * @param {keyof Database} table_name
57
+ */
58
+ const drop_safe_table = (db, table_name) => {
59
+ return db.schema.dropTable(table_name).execute();
60
+ }
61
+
62
+ /**
63
+ * @param {Kysely<Database>} db
64
+ * @param {keyof Database} table_name
65
+ * @param {boolean} [include_id=true]
66
+ * @param {boolean} [include_handle=true]
67
+ */
68
+ const create_base_indexes = async (db, table_name, include_id=true, include_handle=true) => {
69
+ if(include_id) {
70
+ await db.schema.createIndex(`index_${table_name}_id_updated_at_asc`)
71
+ .on(table_name)
72
+ .columns(['id', 'updated_at asc'])
73
+ .execute();
74
+ await db.schema.createIndex(`index_${table_name}_id_updated_at_desc`)
75
+ .on(table_name)
76
+ .columns(['id', 'updated_at desc'])
77
+ .execute();
78
+ }
79
+
80
+ if(include_handle) {
81
+ await db.schema.createIndex(`index_${table_name}_handle_updated_at_asc`)
82
+ .on(table_name)
83
+ .columns(['handle', 'updated_at asc'])
84
+ .execute();
85
+ await db.schema.createIndex(`index_${table_name}_handle_updated_at_desc`)
86
+ .on(table_name)
87
+ .columns(['handle', 'updated_at desc'])
88
+ .execute();
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @param {Kysely<Database>} db
94
+ * @param {keyof Pick<Database, 'entity_to_media' |
95
+ * 'entity_to_search_terms' | 'entity_to_tags_projections' |
96
+ * 'products_to_collections' | 'products_to_discounts' |
97
+ * 'products_to_variants' | 'storefronts_to_other'>} table_name
98
+ */
99
+ const create_entity_table_indexes = async (db, table_name) => {
100
+ await db.schema.createIndex(`index_${table_name}_entity_id`)
101
+ .on(table_name)
102
+ .column('entity_id')
103
+ .execute();
104
+ await db.schema.createIndex(`index_${table_name}_entity_handle`)
105
+ .on(table_name)
106
+ .column('entity_handle')
107
+ .execute();
108
+ await db.schema.createIndex(`index_${table_name}_value`)
109
+ .on(table_name)
110
+ .column('value')
111
+ .execute();
112
+ await db.schema.createIndex(`index_${table_name}_reporter`)
113
+ .on(table_name)
114
+ .column('reporter')
115
+ .execute();
116
+ await db.schema.createIndex(`index_${table_name}_context`)
117
+ .on(table_name)
118
+ .column('context')
119
+ .execute();
120
+ }
121
+
122
+ /**
123
+ *
124
+ * @param {Kysely<Database>} db
125
+ */
126
+ export async function up(db) {
127
+ // await drop_tables(db);
128
+
129
+ { // auth_users
130
+ let tb = create_safe_table(db, 'auth_users');
131
+ tb = add_base_columns(tb);
132
+ tb = tb
133
+ .addColumn('email', 'varchar(255)', (col) => col.unique())
134
+ .addColumn('password', 'text')
135
+ .addColumn('roles', 'json')
136
+ .addColumn('confirmed_mail', 'integer');
137
+ await tb.execute();
138
+ await create_base_indexes(db, 'auth_users');
139
+ }
140
+
141
+ { // tags
142
+ let tb = create_safe_table(db, 'tags');
143
+ tb = add_base_columns(tb);
144
+ tb = tb.addColumn('values', 'json');
145
+ await tb.execute();
146
+ await create_base_indexes(db, 'tags');
147
+ }
148
+
149
+ { // templates
150
+ let tb = create_safe_table(db, 'templates');
151
+ tb = add_base_columns(tb);
152
+ tb = tb.addColumn('title', 'text');
153
+ tb = tb.addColumn('template', 'text');
154
+ tb = tb.addColumn('reference_example_input', 'json');
155
+ await tb.execute();
156
+ await create_base_indexes(db, 'templates');
157
+ }
158
+
159
+ { // collections
160
+ let tb = create_safe_table(db, 'collections');
161
+ tb = add_base_columns(tb);
162
+ tb = tb
163
+ .addColumn('title', 'text')
164
+ .addColumn('published', 'text')
165
+ await tb.execute();
166
+ await create_base_indexes(db, 'collections');
167
+ }
168
+
169
+ { // products
170
+ let tb = create_safe_table(db, 'products');
171
+ tb = add_base_columns(tb);
172
+ tb = tb
173
+ .addColumn('title', 'text')
174
+ .addColumn('video', 'text')
175
+ .addColumn('price', 'numeric')
176
+ .addColumn('isbn', 'varchar(255)', (col) => col.unique())
177
+ .addColumn('compare_at_price', 'numeric')
178
+ .addColumn('qty', 'integer')
179
+ .addColumn('variants_options', 'json')
180
+ .addColumn('parent_handle', 'varchar(255)')
181
+ .addColumn('parent_id', 'varchar(100)')
182
+ .addColumn('variant_hint', 'json')
183
+ await tb.execute();
184
+ await create_base_indexes(db, 'products');
185
+ }
186
+
187
+ { // products_to_collections
188
+ await create_entity_to_value_table(db, 'products_to_collections').execute();
189
+ await create_entity_table_indexes(db, 'products_to_collections');
190
+ }
191
+
192
+ { // products_to_discounts
193
+ await create_entity_to_value_table(db, 'products_to_discounts').execute();
194
+ await create_entity_table_indexes(db, 'products_to_discounts');
195
+ }
196
+
197
+ { // products_to_variants
198
+ await create_entity_to_value_table(db, 'products_to_variants').execute();
199
+ await create_entity_table_indexes(db, 'products_to_variants');
200
+ }
201
+
202
+ { // products_to_related_products
203
+ await create_entity_to_value_table(db, 'products_to_related_products').execute();
204
+ await create_entity_table_indexes(db, 'products_to_related_products');
205
+ }
206
+
207
+ { // shipping_methods
208
+ let tb = create_safe_table(db, 'shipping_methods');
209
+ tb = add_base_columns(tb);
210
+ tb = tb.addColumn('title', 'text')
211
+ .addColumn('price', 'numeric')
212
+ await tb.execute();
213
+ await create_base_indexes(db, 'shipping_methods');
214
+ }
215
+
216
+ { // posts
217
+ let tb = create_safe_table(db, 'posts');
218
+ tb = add_base_columns(tb);
219
+ tb = tb
220
+ .addColumn('title', 'text')
221
+ .addColumn('text', 'text')
222
+ await tb.execute();
223
+ await create_base_indexes(db, 'posts');
224
+ }
225
+
226
+ { // customers
227
+ let tb = create_safe_table(db, 'customers');
228
+ tb = add_base_columns(tb);
229
+ tb = tb
230
+ .addColumn('email', 'varchar(255)', (col) => col.unique())
231
+ .addColumn('auth_id', 'varchar(255)', (col) => col.unique())
232
+ .addColumn('firstname', 'varchar(255)')
233
+ .addColumn('lastname', 'varchar(255)')
234
+ .addColumn('phone_number', 'varchar(255)')
235
+ .addColumn('address', 'json')
236
+ await tb.execute();
237
+ await create_base_indexes(db, 'customers');
238
+ }
239
+
240
+ { // orders
241
+ let tb = create_safe_table(db, 'orders');
242
+ tb = add_base_columns(tb);
243
+ tb = tb
244
+ .addColumn('contact', 'json')
245
+ .addColumn('address', 'json')
246
+ .addColumn('line_items', 'json')
247
+ .addColumn('notes', 'text')
248
+ .addColumn('shipping_method', 'json')
249
+ .addColumn('status', 'json')
250
+ .addColumn('pricing', 'json')
251
+ .addColumn('validation', 'json')
252
+ .addColumn('payment_gateway', 'json')
253
+ .addColumn('coupons', 'json')
254
+ .addColumn('_customer_id', 'varchar(255)')
255
+ .addColumn('_customer_email', 'varchar(255)')
256
+ .addColumn('_status_payment_id', 'integer')
257
+ .addColumn('_status_checkout_id', 'integer')
258
+ .addColumn('_status_fulfillment_id', 'integer')
259
+
260
+ await tb.execute();
261
+ await create_base_indexes(db, 'orders');
262
+ }
263
+
264
+ { // storefronts
265
+ let tb = create_safe_table(db, 'storefronts');
266
+ tb = add_base_columns(tb);
267
+ tb = tb
268
+ .addColumn('title', 'text')
269
+ .addColumn('video', 'text')
270
+ .addColumn('published', 'text')
271
+ await tb.execute();
272
+ await create_base_indexes(db, 'storefronts');
273
+ }
274
+
275
+ { // storefronts_to_other
276
+ let tb = create_entity_to_value_table(db, 'storefronts_to_other').execute();
277
+ await create_entity_table_indexes(db, 'storefronts_to_other');
278
+ }
279
+
280
+ { // notifications
281
+ let tb = create_safe_table(db, 'notifications');
282
+ tb = add_base_columns(tb);
283
+ tb = tb
284
+ .addColumn('message', 'text')
285
+ .addColumn('author', 'text')
286
+ .addColumn('actions', 'json')
287
+ await tb.execute();
288
+ await create_base_indexes(db, 'notifications', true, false);
289
+ }
290
+
291
+ { // images
292
+ let tb = create_safe_table(db, 'images');
293
+ tb = add_base_columns(tb);
294
+ tb = tb
295
+ .addColumn('name', 'text')
296
+ .addColumn('url', 'text')
297
+ await tb.execute();
298
+ await create_base_indexes(db, 'images');
299
+ }
300
+
301
+ { // discounts
302
+ let tb = create_safe_table(db, 'discounts');
303
+ tb = add_base_columns(tb);
304
+ tb = tb
305
+ .addColumn('title', 'text')
306
+ .addColumn('published', 'text')
307
+ .addColumn('priority', 'integer')
308
+ .addColumn('info', 'json')
309
+ .addColumn('application', 'json')
310
+ .addColumn('_application_id', 'integer')
311
+ .addColumn('_discount_type_id', 'integer')
312
+ await tb.execute();
313
+ await create_base_indexes(db, 'discounts');
314
+ }
315
+
316
+ { // entity_to_tags_projections
317
+ let tb = create_entity_to_value_table(db, 'entity_to_tags_projections').execute();
318
+ await create_entity_table_indexes(db, 'entity_to_tags_projections');
319
+ }
320
+
321
+ { // entity_to_search_terms
322
+ let tb = create_entity_to_value_table(db, 'entity_to_search_terms').execute();
323
+ await create_entity_table_indexes(db, 'entity_to_search_terms');
324
+ }
325
+
326
+ { // entity_to_media
327
+ let tb = create_entity_to_value_table(db, 'entity_to_media').execute();
328
+ await create_entity_table_indexes(db, 'entity_to_media');
329
+ }
330
+
331
+ }
332
+
333
+ /**
334
+ *
335
+ * @param {Kysely<Database>} db
336
+ */
337
+ export async function down(db) {
338
+ await drop_tables(db);
339
+ }
340
+
341
+ /**
342
+ *
343
+ * @param {Kysely<Database>} db
344
+ */
345
+ const drop_tables = async (db) => {
346
+ try {
347
+ await Promise.all([
348
+ drop_safe_table(db, 'auth_users'),
349
+ drop_safe_table(db, 'tags'),
350
+ drop_safe_table(db, 'collections'),
351
+ drop_safe_table(db, 'customers'),
352
+ drop_safe_table(db, 'discounts'),
353
+ drop_safe_table(db, 'images'),
354
+ drop_safe_table(db, 'notifications'),
355
+ drop_safe_table(db, 'orders'),
356
+ drop_safe_table(db, 'posts'),
357
+ drop_safe_table(db, 'shipping_methods'),
358
+ drop_safe_table(db, 'products'),
359
+ drop_safe_table(db, 'products_to_collections'),
360
+ drop_safe_table(db, 'products_to_discounts'),
361
+ drop_safe_table(db, 'products_to_variants'),
362
+ drop_safe_table(db, 'storefronts'),
363
+ drop_safe_table(db, 'storefronts_to_other'),
364
+ drop_safe_table(db, 'entity_to_media'),
365
+ drop_safe_table(db, 'entity_to_search_terms'),
366
+ drop_safe_table(db, 'entity_to_tags_projections'),
367
+ ]);
368
+ } catch (e) {
369
+ console.log(e)
370
+ }
371
+
372
+ }
@@ -0,0 +1 @@
1
+ export * from '../migrations.shared/00001_seed_email_templates.js'