@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.
- package/README.md +126 -0
- package/TODO.md +2 -0
- package/db-strategy.md +3 -0
- package/driver.js +190 -0
- package/index.js +3 -0
- package/migrate.js +66 -0
- package/migrations.mssql/00000_init_tables.js +268 -0
- package/migrations.mysql/00000_init_tables.js +372 -0
- package/migrations.mysql/00001_seed_email_templates.js +1 -0
- package/migrations.postgres/00000_init_tables.js +358 -0
- package/migrations.postgres/00001_seed_email_templates.js +1 -0
- package/migrations.shared/00001_seed_email_templates.js +260 -0
- package/migrations.sqlite/00000_init_tables.js +357 -0
- package/migrations.sqlite/00001_seed_email_templates.js +1 -0
- package/package.json +47 -0
- package/src/con.auth_users.js +159 -0
- package/src/con.collections.js +197 -0
- package/src/con.customers.js +202 -0
- package/src/con.discounts.js +225 -0
- package/src/con.discounts.utils.js +180 -0
- package/src/con.helpers.json.js +231 -0
- package/src/con.helpers.json.mssql.js +233 -0
- package/src/con.helpers.json.mysql.js +239 -0
- package/src/con.helpers.json.postgres.js +223 -0
- package/src/con.helpers.json.sqlite.js +263 -0
- package/src/con.images.js +230 -0
- package/src/con.notifications.js +149 -0
- package/src/con.orders.js +156 -0
- package/src/con.posts.js +147 -0
- package/src/con.products.js +497 -0
- package/src/con.search.js +148 -0
- package/src/con.shared.js +616 -0
- package/src/con.shipping.js +147 -0
- package/src/con.storefronts.js +301 -0
- package/src/con.tags.js +120 -0
- package/src/con.templates.js +133 -0
- package/src/kysely.sanitize.plugin.js +40 -0
- package/src/utils.funcs.js +77 -0
- package/src/utils.query.js +195 -0
- package/tests/query.cursor.test.js +389 -0
- package/tests/query.vql.test.js +71 -0
- package/tests/runner.mssql-local.test.js +118 -0
- package/tests/runner.mysql-local.test.js +101 -0
- package/tests/runner.postgres-local.test.js +99 -0
- package/tests/runner.sqlite-local.test.js +99 -0
- package/tests/sandbox.test.js +71 -0
- package/tsconfig.json +21 -0
- package/types.public.d.ts +19 -0
- package/types.sql.tables.d.ts +247 -0
package/README.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# Storecraft `SQL` driver
|
2
|
+
|
3
|
+
Official `SQL` driver for `StoreCraft` with the dialects abstracted with `Kysely` or your own drivers.
|
4
|
+
|
5
|
+
## usage
|
6
|
+
|
7
|
+
```js
|
8
|
+
import 'dotenv/config';
|
9
|
+
import http from "node:http";
|
10
|
+
import { join } from "node:path";
|
11
|
+
import { homedir } from "node:os";
|
12
|
+
|
13
|
+
import { App } from '@storecraft/core'
|
14
|
+
import { NodePlatform } from '@storecraft/platform-node'
|
15
|
+
import { MongoDB } from '@storecraft/database-mongodb-node'
|
16
|
+
import { NodeLocalStorage } from '@storecraft/storage-node-local'
|
17
|
+
|
18
|
+
let app = new App(
|
19
|
+
new NodePlatform(),
|
20
|
+
new MongoDB({ db_name: 'prod', url: '<MONGO-URL>'}),
|
21
|
+
new NodeLocalStorage(join(homedir(), 'tomer'))
|
22
|
+
);
|
23
|
+
|
24
|
+
await app.init();
|
25
|
+
|
26
|
+
const server = http.createServer(app.handler).listen(
|
27
|
+
8000,
|
28
|
+
() => {
|
29
|
+
console.log(`Server is running on http://localhost:8000`);
|
30
|
+
}
|
31
|
+
);
|
32
|
+
|
33
|
+
```
|
34
|
+
|
35
|
+
## Testing Locally
|
36
|
+
|
37
|
+
### **SQLite**
|
38
|
+
1. Simply `runner.sqlite-local.test.js`
|
39
|
+
```bash
|
40
|
+
npm run test:sqlite
|
41
|
+
```
|
42
|
+
|
43
|
+
### **Postgres**
|
44
|
+
1. First setup a `postgres` server
|
45
|
+
```bash
|
46
|
+
docker pull postgres
|
47
|
+
docker run --name some-postgres -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=admin \
|
48
|
+
-e PGDATA=/var/lib/postgresql/data/pgdata \
|
49
|
+
-v $(pwd):/var/lib/postgresql/data \
|
50
|
+
-p 5432:5432 -d postgres
|
51
|
+
```
|
52
|
+
|
53
|
+
2. create Environment
|
54
|
+
create `.env` file with
|
55
|
+
```bash
|
56
|
+
POSTGRES_USER='user'
|
57
|
+
POSTGRES_PASSWORD='password'
|
58
|
+
POSTGRES_PORT=5432
|
59
|
+
POSTGRES_HOST='localhost'
|
60
|
+
```
|
61
|
+
|
62
|
+
3. Run `runner.postgres-local.test.js`
|
63
|
+
```bash
|
64
|
+
npm run test:postgres
|
65
|
+
```
|
66
|
+
|
67
|
+
### **MySQL**
|
68
|
+
1. First setup a `mysql` server
|
69
|
+
```zsh
|
70
|
+
docker pull mysql
|
71
|
+
docker run --name mysql \
|
72
|
+
-v $(pwd):/etc/mysql/conf.d \
|
73
|
+
-v /my/own/datadir:/var/lib/mysql \
|
74
|
+
-e MYSQL_ROOT_PASSWORD=admin -e MYSQL_ROOT_HOST=localhost \
|
75
|
+
-e MYSQL_DATABASE=main -e MYSQL_USER=admin -e MYSQL_PASSWORD=admin \
|
76
|
+
-p 8080:3306 -d mysql
|
77
|
+
```
|
78
|
+
|
79
|
+
2. create Environment
|
80
|
+
create `.env` file with
|
81
|
+
```bash
|
82
|
+
MYSQL_USER='root'
|
83
|
+
MYSQL_ROOT_PASSWORD='password'
|
84
|
+
MYSQL_PORT=8080
|
85
|
+
MYSQL_HOST='localhost'
|
86
|
+
```
|
87
|
+
|
88
|
+
3. Run `runner.mysql-local.test.js`
|
89
|
+
```bash
|
90
|
+
npm run test:mysql
|
91
|
+
```
|
92
|
+
|
93
|
+
### **MSSQL** (Currently NOT SUPPORTED, waiting for votes on that one)
|
94
|
+
Work in progress, i will probably not continue with this.
|
95
|
+
|
96
|
+
1. First setup a `mysql` server
|
97
|
+
```zsh
|
98
|
+
docker pull mcr.microsoft.com/mssql/server
|
99
|
+
# use this For OSX with M1 chips
|
100
|
+
docker pull mcr.microsoft.com/azure-sql-edge:latest
|
101
|
+
docker run --name some-mssql \
|
102
|
+
-e ACCEPT_EULA=Y -e MSSQL_SA_PASSWORD='Abcd1234!?' \
|
103
|
+
-v $(pwd):/var/opt/mssql \
|
104
|
+
-p 1433:1433 \
|
105
|
+
-d mcr.microsoft.com/azure-sql-edge:latest
|
106
|
+
|
107
|
+
```
|
108
|
+
|
109
|
+
2. create Environment
|
110
|
+
create `.env` file with
|
111
|
+
```bash
|
112
|
+
MYSQL_USER='root'
|
113
|
+
MYSQL_ROOT_PASSWORD='password'
|
114
|
+
MYSQL_PORT=8080
|
115
|
+
MYSQL_HOST='localhost'
|
116
|
+
```
|
117
|
+
|
118
|
+
3. Run `runner.mysql-local.test.js`
|
119
|
+
```bash
|
120
|
+
npm run test:mysql
|
121
|
+
```
|
122
|
+
|
123
|
+
|
124
|
+
```text
|
125
|
+
Author: Tomer Shalev <tomer.shalev@gmail.com>
|
126
|
+
```
|
package/TODO.md
ADDED
package/db-strategy.md
ADDED
package/driver.js
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
import { App } from '@storecraft/core';
|
2
|
+
import { impl as auth_users } from './src/con.auth_users.js';
|
3
|
+
import { impl as collections } from './src/con.collections.js';
|
4
|
+
import { impl as customers } from './src/con.customers.js';
|
5
|
+
import { impl as discounts } from './src/con.discounts.js';
|
6
|
+
import { impl as images } from './src/con.images.js';
|
7
|
+
import { impl as notifications } from './src/con.notifications.js';
|
8
|
+
import { impl as orders } from './src/con.orders.js';
|
9
|
+
import { impl as posts } from './src/con.posts.js';
|
10
|
+
import { impl as products } from './src/con.products.js';
|
11
|
+
import { impl as shipping } from './src/con.shipping.js';
|
12
|
+
import { impl as storefronts } from './src/con.storefronts.js';
|
13
|
+
import { impl as tags } from './src/con.tags.js';
|
14
|
+
import { impl as templates } from './src/con.templates.js';
|
15
|
+
import { impl as search } from './src/con.search.js';
|
16
|
+
import { Kysely, ParseJSONResultsPlugin } from 'kysely'
|
17
|
+
import { SanitizePlugin } from './src/kysely.sanitize.plugin.js';
|
18
|
+
|
19
|
+
|
20
|
+
/**
|
21
|
+
* @param {any} b
|
22
|
+
* @param {string} msg
|
23
|
+
*/
|
24
|
+
const assert = (b, msg) => {
|
25
|
+
if(!Boolean(b)) throw new Error(msg);
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* @typedef {import('./types.public.js').Config} Config
|
30
|
+
* @typedef {import('./types.sql.tables.js').Database} Database
|
31
|
+
* @typedef {import('kysely').Dialect} Dialect
|
32
|
+
* @typedef {import('@storecraft/core/v-database').db_driver} db_driver
|
33
|
+
*/
|
34
|
+
|
35
|
+
/**
|
36
|
+
* @implements {db_driver}
|
37
|
+
*/
|
38
|
+
export class SQL {
|
39
|
+
|
40
|
+
/** @type {boolean} */
|
41
|
+
#_is_ready;
|
42
|
+
|
43
|
+
/** @type {App<any, any, any>} */
|
44
|
+
#_app;
|
45
|
+
|
46
|
+
/** @type {Config} */
|
47
|
+
#_config;
|
48
|
+
|
49
|
+
/** @type {Kysely<Database>} */
|
50
|
+
#_client;
|
51
|
+
|
52
|
+
/** @type {db_driver["resources"]} */
|
53
|
+
#_resources;
|
54
|
+
|
55
|
+
/**
|
56
|
+
*
|
57
|
+
* @param {Config} [config] config
|
58
|
+
*/
|
59
|
+
constructor(config) {
|
60
|
+
this.#_is_ready = false;
|
61
|
+
this.#_config = config;
|
62
|
+
|
63
|
+
assert(
|
64
|
+
this.#_config.dialect,
|
65
|
+
'No Dialect found !'
|
66
|
+
);
|
67
|
+
|
68
|
+
assert(
|
69
|
+
this.#_config.dialect_type,
|
70
|
+
'No Dialect Type specified !'
|
71
|
+
);
|
72
|
+
|
73
|
+
this.#_client = new Kysely(
|
74
|
+
{
|
75
|
+
dialect: this.#_config.dialect,
|
76
|
+
plugins: [
|
77
|
+
new ParseJSONResultsPlugin(),
|
78
|
+
new SanitizePlugin()
|
79
|
+
]
|
80
|
+
}
|
81
|
+
);
|
82
|
+
}
|
83
|
+
|
84
|
+
throwIfNotReady() {
|
85
|
+
assert(
|
86
|
+
this.isReady,
|
87
|
+
'Database not ready !!! you need to `.init()` it'
|
88
|
+
);
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
*
|
93
|
+
* @param {boolean} [destroy_db_upon_completion=false]
|
94
|
+
*/
|
95
|
+
async migrateToLatest(destroy_db_upon_completion=false) {
|
96
|
+
this.throwIfNotReady();
|
97
|
+
|
98
|
+
const { migrateToLatest } = await import('./migrate.js');
|
99
|
+
|
100
|
+
await migrateToLatest(this, destroy_db_upon_completion);
|
101
|
+
};
|
102
|
+
|
103
|
+
/**
|
104
|
+
*
|
105
|
+
* @param {App<any, any, any>} app
|
106
|
+
*
|
107
|
+
*
|
108
|
+
* @returns {Promise<this>}
|
109
|
+
*/
|
110
|
+
async init(app) {
|
111
|
+
if(this.isReady)
|
112
|
+
return this;
|
113
|
+
|
114
|
+
this.#_app = app;
|
115
|
+
|
116
|
+
this.#_resources = {
|
117
|
+
auth_users: auth_users(this),
|
118
|
+
collections: collections(this),
|
119
|
+
customers: customers(this),
|
120
|
+
discounts: discounts(this),
|
121
|
+
images: images(this),
|
122
|
+
notifications: notifications(this),
|
123
|
+
orders: orders(this),
|
124
|
+
posts: posts(this),
|
125
|
+
products: products(this),
|
126
|
+
storefronts: storefronts(this),
|
127
|
+
tags: tags(this),
|
128
|
+
shipping_methods: shipping(this),
|
129
|
+
templates: templates(this),
|
130
|
+
search: search(this),
|
131
|
+
}
|
132
|
+
|
133
|
+
this.#_is_ready = true;
|
134
|
+
|
135
|
+
return this;
|
136
|
+
}
|
137
|
+
|
138
|
+
async disconnect() {
|
139
|
+
await this.client.destroy();
|
140
|
+
return true;
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* `database` resources
|
145
|
+
*/
|
146
|
+
get resources () {
|
147
|
+
return this.#_resources;
|
148
|
+
}
|
149
|
+
|
150
|
+
get name () {
|
151
|
+
return 'main';
|
152
|
+
}
|
153
|
+
|
154
|
+
get app() {
|
155
|
+
return this.#_app;
|
156
|
+
}
|
157
|
+
|
158
|
+
get client() {
|
159
|
+
return this.#_client;
|
160
|
+
}
|
161
|
+
|
162
|
+
get config() {
|
163
|
+
return this.#_config;
|
164
|
+
}
|
165
|
+
|
166
|
+
get isReady() {
|
167
|
+
return this.#_is_ready;
|
168
|
+
}
|
169
|
+
|
170
|
+
get dialectType() {
|
171
|
+
return this.#_config.dialect_type;
|
172
|
+
}
|
173
|
+
|
174
|
+
get isSqlite() {
|
175
|
+
return this.dialectType==='SQLITE';
|
176
|
+
}
|
177
|
+
|
178
|
+
get isPostgres() {
|
179
|
+
return this.dialectType==='POSTGRES';
|
180
|
+
}
|
181
|
+
|
182
|
+
get isMysql() {
|
183
|
+
return this.dialectType==='MYSQL';
|
184
|
+
}
|
185
|
+
|
186
|
+
get isMssql() {
|
187
|
+
return this.dialectType==='MSSQL';
|
188
|
+
}
|
189
|
+
|
190
|
+
}
|
package/index.js
ADDED
package/migrate.js
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
2
|
+
import * as path from 'path'
|
3
|
+
import { promises as fs } from 'fs'
|
4
|
+
import {
|
5
|
+
Migrator,
|
6
|
+
FileMigrationProvider,
|
7
|
+
} from 'kysely'
|
8
|
+
import { SQL } from "./index.js";
|
9
|
+
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
11
|
+
const __dirname = path.dirname(__filename);
|
12
|
+
|
13
|
+
export const current = {
|
14
|
+
driver: undefined
|
15
|
+
}
|
16
|
+
|
17
|
+
/**
|
18
|
+
*
|
19
|
+
* @param {SQL} db_driver
|
20
|
+
* @param {boolean} [destroy_db_upon_completion=true]
|
21
|
+
*/
|
22
|
+
export async function migrateToLatest(db_driver, destroy_db_upon_completion=true) {
|
23
|
+
if(!db_driver?.client)
|
24
|
+
throw new Error('No Kysely client found !!!');
|
25
|
+
|
26
|
+
console.log('Resolving migrations')
|
27
|
+
|
28
|
+
let db = db_driver.client;
|
29
|
+
|
30
|
+
current.driver = db_driver;
|
31
|
+
|
32
|
+
const migrator = new Migrator({
|
33
|
+
db,
|
34
|
+
provider: new FileMigrationProvider({
|
35
|
+
fs,
|
36
|
+
path,
|
37
|
+
migrationFolder: path.join(
|
38
|
+
__dirname,
|
39
|
+
`migrations.${db_driver.dialectType.toLowerCase()}`
|
40
|
+
),
|
41
|
+
}),
|
42
|
+
})
|
43
|
+
|
44
|
+
const { error, results } = await migrator.migrateToLatest();
|
45
|
+
|
46
|
+
results?.forEach((it) => {
|
47
|
+
if (it.status === 'Success') {
|
48
|
+
console.log(
|
49
|
+
`migration "${it.migrationName}" was executed successfully`
|
50
|
+
);
|
51
|
+
} else if (it.status === 'Error') {
|
52
|
+
console.error(
|
53
|
+
`failed to execute migration "${it.migrationName}"`
|
54
|
+
);
|
55
|
+
}
|
56
|
+
})
|
57
|
+
|
58
|
+
if (error) {
|
59
|
+
console.error('failed to migrate')
|
60
|
+
console.error(error)
|
61
|
+
process.exit(1)
|
62
|
+
}
|
63
|
+
|
64
|
+
if(destroy_db_upon_completion)
|
65
|
+
await db.destroy()
|
66
|
+
}
|
@@ -0,0 +1,268 @@
|
|
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(256)', (col) =>
|
15
|
+
col.primaryKey()
|
16
|
+
)
|
17
|
+
.addColumn('handle', 'VARCHAR(256)', (col) => col.unique())
|
18
|
+
.addColumn('created_at', 'text')
|
19
|
+
.addColumn('updated_at', 'text')
|
20
|
+
.addColumn('attributes', 'VARCHAR(MAX)')
|
21
|
+
.addColumn('description', 'text')
|
22
|
+
.addColumn('active', 'integer')
|
23
|
+
}
|
24
|
+
|
25
|
+
/**
|
26
|
+
* @param {Kysely<Database>} db
|
27
|
+
* @param {keyof Database} table_name
|
28
|
+
*/
|
29
|
+
const create_entity_to_value_table = (db, table_name) => {
|
30
|
+
|
31
|
+
return db.schema
|
32
|
+
.createTable(table_name)
|
33
|
+
.addColumn('id', 'integer',
|
34
|
+
(col) => col.autoIncrement().primaryKey()
|
35
|
+
)
|
36
|
+
.addColumn('entity_id', 'VARCHAR(256)', col => col.notNull())
|
37
|
+
.addColumn('entity_handle', 'VARCHAR(256)')
|
38
|
+
.addColumn('value', 'VARCHAR(256)')
|
39
|
+
.addColumn('reporter', 'VARCHAR(256)')
|
40
|
+
.addColumn('context', 'VARCHAR(256)')
|
41
|
+
}
|
42
|
+
|
43
|
+
/**
|
44
|
+
*
|
45
|
+
* @param {Kysely<Database>} db
|
46
|
+
* @param {keyof Database} table_name
|
47
|
+
*/
|
48
|
+
const create_safe_table = (db, table_name) => {
|
49
|
+
return db.schema.createTable(table_name);
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
*
|
54
|
+
* @param {Kysely<Database>} db
|
55
|
+
* @param {keyof Database} table_name
|
56
|
+
*/
|
57
|
+
const drop_safe_table = (db, table_name) => {
|
58
|
+
return db.schema.dropTable(table_name).execute();
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
*
|
63
|
+
* @param {Kysely<Database>} db
|
64
|
+
*/
|
65
|
+
export async function up(db) {
|
66
|
+
{ // auth_users
|
67
|
+
let tb = create_safe_table(db, 'auth_users');
|
68
|
+
tb = add_base_columns(tb);
|
69
|
+
tb = tb
|
70
|
+
.addColumn('email', 'VARCHAR(256)', (col) => col.unique())
|
71
|
+
.addColumn('password', 'text')
|
72
|
+
.addColumn('roles', 'VARCHAR(MAX)')
|
73
|
+
.addColumn('confirmed_mail', 'integer');
|
74
|
+
await tb.execute();
|
75
|
+
}
|
76
|
+
|
77
|
+
{ // tags
|
78
|
+
let tb = create_safe_table(db, 'tags');
|
79
|
+
tb = add_base_columns(tb);
|
80
|
+
tb = tb.addColumn('values', 'VARCHAR(MAX)');
|
81
|
+
await tb.execute();
|
82
|
+
}
|
83
|
+
|
84
|
+
{ // collections
|
85
|
+
let tb = create_safe_table(db, 'collections');
|
86
|
+
tb = add_base_columns(tb);
|
87
|
+
tb = tb
|
88
|
+
.addColumn('title', 'text')
|
89
|
+
.addColumn('published', 'text')
|
90
|
+
await tb.execute();
|
91
|
+
}
|
92
|
+
|
93
|
+
{ // products
|
94
|
+
let tb = create_safe_table(db, 'products');
|
95
|
+
tb = add_base_columns(tb);
|
96
|
+
tb = tb
|
97
|
+
.addColumn('title', 'text')
|
98
|
+
.addColumn('video', 'text')
|
99
|
+
.addColumn('price', 'numeric')
|
100
|
+
.addColumn('compare_at_price', 'numeric')
|
101
|
+
.addColumn('qty', 'integer')
|
102
|
+
.addColumn('variants_options', 'VARCHAR(MAX)')
|
103
|
+
.addColumn('parent_handle', 'text')
|
104
|
+
.addColumn('parent_id', 'text')
|
105
|
+
.addColumn('variant_hint', 'VARCHAR(MAX)')
|
106
|
+
await tb.execute();
|
107
|
+
}
|
108
|
+
|
109
|
+
{ // products_to_collections
|
110
|
+
let tb = create_entity_to_value_table(db, 'products_to_collections')
|
111
|
+
await tb.execute();
|
112
|
+
}
|
113
|
+
|
114
|
+
{ // products_to_discounts
|
115
|
+
let tb = create_entity_to_value_table(db, 'products_to_discounts')
|
116
|
+
await tb.execute();
|
117
|
+
}
|
118
|
+
|
119
|
+
{ // products_to_variants
|
120
|
+
let tb = create_entity_to_value_table(db, 'products_to_variants')
|
121
|
+
await tb.execute();
|
122
|
+
}
|
123
|
+
|
124
|
+
{ // shipping_methods
|
125
|
+
let tb = create_safe_table(db, 'shipping_methods');
|
126
|
+
tb = add_base_columns(tb);
|
127
|
+
tb = tb.addColumn('title', 'text')
|
128
|
+
.addColumn('price', 'numeric')
|
129
|
+
await tb.execute();
|
130
|
+
}
|
131
|
+
|
132
|
+
{ // posts
|
133
|
+
let tb = create_safe_table(db, 'posts');
|
134
|
+
tb = add_base_columns(tb);
|
135
|
+
tb = tb
|
136
|
+
.addColumn('title', 'text')
|
137
|
+
.addColumn('text', 'text')
|
138
|
+
await tb.execute();
|
139
|
+
}
|
140
|
+
|
141
|
+
{ // customers
|
142
|
+
let tb = create_safe_table(db, 'customers');
|
143
|
+
tb = add_base_columns(tb);
|
144
|
+
tb = tb
|
145
|
+
.addColumn('email', 'VARCHAR(256)', (col) => col.unique())
|
146
|
+
.addColumn('auth_id', 'VARCHAR(256)', (col) => col.unique())
|
147
|
+
.addColumn('firstname', 'text')
|
148
|
+
.addColumn('lastname', 'text')
|
149
|
+
.addColumn('phone_number', 'text')
|
150
|
+
.addColumn('address', 'VARCHAR(MAX)')
|
151
|
+
await tb.execute();
|
152
|
+
}
|
153
|
+
|
154
|
+
{ // orders
|
155
|
+
let tb = create_safe_table(db, 'orders');
|
156
|
+
tb = add_base_columns(tb);
|
157
|
+
tb = tb
|
158
|
+
.addColumn('contact', 'VARCHAR(MAX)')
|
159
|
+
.addColumn('address', 'VARCHAR(MAX)')
|
160
|
+
.addColumn('line_items', 'VARCHAR(MAX)')
|
161
|
+
.addColumn('notes', 'text')
|
162
|
+
.addColumn('shipping_method', 'VARCHAR(MAX)')
|
163
|
+
.addColumn('status', 'VARCHAR(MAX)')
|
164
|
+
.addColumn('pricing', 'VARCHAR(MAX)')
|
165
|
+
.addColumn('validation', 'VARCHAR(MAX)')
|
166
|
+
.addColumn('payment_gateway', 'VARCHAR(MAX)')
|
167
|
+
.addColumn('coupons', 'VARCHAR(MAX)')
|
168
|
+
.addColumn('_customer_id', 'text')
|
169
|
+
.addColumn('_customer_email', 'text')
|
170
|
+
.addColumn('_status_payment_id', 'integer')
|
171
|
+
.addColumn('_status_checkout_id', 'integer')
|
172
|
+
.addColumn('_status_fulfillment_id', 'integer')
|
173
|
+
|
174
|
+
await tb.execute();
|
175
|
+
}
|
176
|
+
|
177
|
+
{ // storefronts
|
178
|
+
let tb = create_safe_table(db, 'storefronts');
|
179
|
+
tb = add_base_columns(tb);
|
180
|
+
tb = tb
|
181
|
+
.addColumn('title', 'text')
|
182
|
+
.addColumn('video', 'text')
|
183
|
+
.addColumn('published', 'text')
|
184
|
+
await tb.execute();
|
185
|
+
}
|
186
|
+
|
187
|
+
{ // storefronts_to_other
|
188
|
+
let tb = create_entity_to_value_table(db, 'storefronts_to_other')
|
189
|
+
await tb.execute();
|
190
|
+
}
|
191
|
+
|
192
|
+
{ // notifications
|
193
|
+
let tb = create_safe_table(db, 'notifications');
|
194
|
+
tb = add_base_columns(tb);
|
195
|
+
tb = tb
|
196
|
+
.addColumn('message', 'text')
|
197
|
+
.addColumn('author', 'text')
|
198
|
+
.addColumn('actions', 'VARCHAR(MAX)')
|
199
|
+
await tb.execute();
|
200
|
+
}
|
201
|
+
|
202
|
+
{ // images
|
203
|
+
let tb = create_safe_table(db, 'images');
|
204
|
+
tb = add_base_columns(tb);
|
205
|
+
tb = tb
|
206
|
+
.addColumn('name', 'text')
|
207
|
+
.addColumn('url', 'text')
|
208
|
+
await tb.execute();
|
209
|
+
}
|
210
|
+
|
211
|
+
{ // discounts
|
212
|
+
let tb = create_safe_table(db, 'discounts');
|
213
|
+
tb = add_base_columns(tb);
|
214
|
+
tb = tb
|
215
|
+
.addColumn('title', 'text')
|
216
|
+
.addColumn('published', 'text')
|
217
|
+
.addColumn('priority', 'integer')
|
218
|
+
.addColumn('info', 'json')
|
219
|
+
.addColumn('application', 'VARCHAR(MAX)')
|
220
|
+
.addColumn('_application_id', 'integer')
|
221
|
+
.addColumn('_discount_type_id', 'integer')
|
222
|
+
await tb.execute();
|
223
|
+
}
|
224
|
+
|
225
|
+
{ // entity_to_tags_projections
|
226
|
+
let tb = create_entity_to_value_table(db, 'entity_to_tags_projections')
|
227
|
+
await tb.execute();
|
228
|
+
}
|
229
|
+
|
230
|
+
{ // entity_to_search_terms
|
231
|
+
let tb = create_entity_to_value_table(db, 'entity_to_search_terms')
|
232
|
+
await tb.execute();
|
233
|
+
}
|
234
|
+
|
235
|
+
{ // entity_to_media
|
236
|
+
let tb = create_entity_to_value_table(db, 'entity_to_media')
|
237
|
+
await tb.execute();
|
238
|
+
}
|
239
|
+
|
240
|
+
}
|
241
|
+
|
242
|
+
/**
|
243
|
+
*
|
244
|
+
* @param {Kysely<Database>} db
|
245
|
+
*/
|
246
|
+
export async function down(db) {
|
247
|
+
await Promise.all([
|
248
|
+
drop_safe_table(db, 'auth_users'),
|
249
|
+
drop_safe_table(db, 'tags'),
|
250
|
+
drop_safe_table(db, 'collections'),
|
251
|
+
drop_safe_table(db, 'customers'),
|
252
|
+
drop_safe_table(db, 'discounts'),
|
253
|
+
drop_safe_table(db, 'images'),
|
254
|
+
drop_safe_table(db, 'notifications'),
|
255
|
+
drop_safe_table(db, 'orders'),
|
256
|
+
drop_safe_table(db, 'posts'),
|
257
|
+
drop_safe_table(db, 'shipping_methods'),
|
258
|
+
drop_safe_table(db, 'products'),
|
259
|
+
drop_safe_table(db, 'products_to_collections'),
|
260
|
+
drop_safe_table(db, 'products_to_discounts'),
|
261
|
+
drop_safe_table(db, 'products_to_variants'),
|
262
|
+
drop_safe_table(db, 'storefronts'),
|
263
|
+
drop_safe_table(db, 'storefronts_to_other'),
|
264
|
+
drop_safe_table(db, 'entity_to_media'),
|
265
|
+
drop_safe_table(db, 'entity_to_search_terms'),
|
266
|
+
drop_safe_table(db, 'entity_to_tags_projections'),
|
267
|
+
]);
|
268
|
+
}
|