@storecraft/database-sql-base 1.0.1 → 1.0.2
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 +4 -7
- package/index.js +172 -1
- package/{tsconfig.json → jsconfig.json} +1 -5
- package/migrations.mysql/00000_init_tables.js +9 -9
- package/migrations.shared/00001_seed_email_templates.js +2 -237
- package/package.json +2 -4
- package/src/con.auth_users.js +4 -2
- package/src/con.collections.js +2 -2
- package/src/con.customers.js +2 -2
- package/src/con.discounts.js +3 -3
- package/src/con.discounts.utils.js +11 -11
- package/src/con.images.js +5 -5
- package/src/con.notifications.js +2 -2
- package/src/con.orders.js +2 -2
- package/src/con.posts.js +2 -2
- package/src/con.products.js +5 -5
- package/src/con.search.js +7 -7
- package/src/con.shared.experiment.js +1 -1
- package/src/con.shared.js +43 -9
- package/src/con.shipping.js +2 -2
- package/src/con.storefronts.js +2 -2
- package/src/con.tags.js +2 -2
- package/src/con.templates.js +22 -7
- package/src/utils.query.js +6 -6
- package/tests/runner.mssql-local.test.js +8 -4
- package/tests/runner.mysql-local.test.js +4 -53
- package/tests/runner.postgres-local.test.js +4 -53
- package/tests/runner.sqlite-local.test.js +4 -55
- package/tests/sandbox.test.js +1 -1
- package/types.sql.tables.d.ts +4 -2
- package/driver.js +0 -174
- package/migrations.sqlite/00002_test.js +0 -26
- package/tests/query.cursor.test.js +0 -389
- package/tests/query.vql.test.js +0 -71
package/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<div style="text-align:center">
|
4
4
|
<img src='https://storecraft.app/storecraft-color.svg'
|
5
|
-
width='90%'
|
5
|
+
width='90%' />
|
6
6
|
</div><hr/><br/>
|
7
7
|
|
8
8
|
Official `SQL` driver for `StoreCraft` with the dialects abstracted with `Kysely` or your own drivers.
|
@@ -16,14 +16,11 @@ npm i @storecraft/database-sql-base
|
|
16
16
|
```js
|
17
17
|
import 'dotenv/config';
|
18
18
|
import http from "node:http";
|
19
|
-
import { join } from "node:path";
|
20
|
-
import { homedir } from "node:os";
|
21
|
-
|
22
19
|
import { App } from '@storecraft/core'
|
23
|
-
import { NodePlatform } from '@storecraft/
|
20
|
+
import { NodePlatform } from '@storecraft/core/platform/node';
|
24
21
|
import { SQL } from '@storecraft/database-sql-base'
|
25
22
|
import { migrateToLatest } from '@storecraft/database-sql-base/migrate.js'
|
26
|
-
import { NodeLocalStorage } from '@storecraft/storage
|
23
|
+
import { NodeLocalStorage } from '@storecraft/core/storage/node'
|
27
24
|
|
28
25
|
const app = new App(
|
29
26
|
{
|
@@ -39,7 +36,7 @@ const app = new App(
|
|
39
36
|
dialect_type: 'SQLITE'
|
40
37
|
})
|
41
38
|
)
|
42
|
-
.withStorage(new NodeLocalStorage(
|
39
|
+
.withStorage(new NodeLocalStorage('storage'))
|
43
40
|
|
44
41
|
await app.init();
|
45
42
|
await migrateToLatest(app.db, false);
|
package/index.js
CHANGED
@@ -1,3 +1,174 @@
|
|
1
|
-
|
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';
|
2
18
|
|
3
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.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
|
+
/**
|
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 {App<any, any, any>} app
|
94
|
+
*
|
95
|
+
*
|
96
|
+
* @returns {Promise<this>}
|
97
|
+
*/
|
98
|
+
async init(app) {
|
99
|
+
if(this.isReady)
|
100
|
+
return this;
|
101
|
+
|
102
|
+
this.#_app = app;
|
103
|
+
|
104
|
+
this.#_resources = {
|
105
|
+
auth_users: auth_users(this),
|
106
|
+
collections: collections(this),
|
107
|
+
customers: customers(this),
|
108
|
+
discounts: discounts(this),
|
109
|
+
images: images(this),
|
110
|
+
notifications: notifications(this),
|
111
|
+
orders: orders(this),
|
112
|
+
posts: posts(this),
|
113
|
+
products: products(this),
|
114
|
+
storefronts: storefronts(this),
|
115
|
+
tags: tags(this),
|
116
|
+
shipping_methods: shipping(this),
|
117
|
+
templates: templates(this),
|
118
|
+
search: search(this),
|
119
|
+
}
|
120
|
+
|
121
|
+
this.#_is_ready = true;
|
122
|
+
|
123
|
+
return this;
|
124
|
+
}
|
125
|
+
|
126
|
+
async disconnect() {
|
127
|
+
await this.client.destroy();
|
128
|
+
return true;
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* `database` resources
|
133
|
+
*/
|
134
|
+
get resources () {
|
135
|
+
return this.#_resources;
|
136
|
+
}
|
137
|
+
|
138
|
+
get name() {
|
139
|
+
return this?.config?.db_name ?? 'main';
|
140
|
+
}
|
141
|
+
|
142
|
+
get app() {
|
143
|
+
return this.#_app;
|
144
|
+
}
|
145
|
+
|
146
|
+
get client() {
|
147
|
+
return this.#_client;
|
148
|
+
}
|
149
|
+
|
150
|
+
get config() {
|
151
|
+
return this.#_config;
|
152
|
+
}
|
153
|
+
|
154
|
+
get isReady() {
|
155
|
+
return this.#_is_ready;
|
156
|
+
}
|
157
|
+
|
158
|
+
get dialectType() {
|
159
|
+
return this.#_config.dialect_type;
|
160
|
+
}
|
161
|
+
|
162
|
+
get isSqlite() {
|
163
|
+
return this.dialectType==='SQLITE';
|
164
|
+
}
|
165
|
+
|
166
|
+
get isPostgres() {
|
167
|
+
return this.dialectType==='POSTGRES';
|
168
|
+
}
|
169
|
+
|
170
|
+
get isMysql() {
|
171
|
+
return this.dialectType==='MYSQL';
|
172
|
+
}
|
173
|
+
|
174
|
+
}
|
@@ -1,11 +1,6 @@
|
|
1
1
|
{
|
2
|
-
"compileOnSave": false,
|
3
2
|
"compilerOptions": {
|
4
|
-
"noEmit": true,
|
5
|
-
"allowJs": true,
|
6
3
|
"checkJs": true,
|
7
|
-
"target": "ESNext",
|
8
|
-
"resolveJsonModule": true,
|
9
4
|
"moduleResolution": "NodeNext",
|
10
5
|
"module": "NodeNext",
|
11
6
|
"composite": true,
|
@@ -16,6 +11,7 @@
|
|
16
11
|
"migrations.sqlite/*",
|
17
12
|
"migrations.postgres/*",
|
18
13
|
"migrations.mysql/*",
|
14
|
+
"migrations.shared/*",
|
19
15
|
"tests/*.js"
|
20
16
|
]
|
21
17
|
}
|
@@ -67,22 +67,22 @@ const drop_safe_table = (db, table_name) => {
|
|
67
67
|
*/
|
68
68
|
const create_base_indexes = async (db, table_name, include_id=true, include_handle=true) => {
|
69
69
|
if(include_id) {
|
70
|
-
await db.schema.createIndex(`index_${table_name}_id_updated_at_asc`)
|
70
|
+
await db.schema.createIndex(`index_${table_name}_id_updated_at_asc`)
|
71
71
|
.on(table_name)
|
72
72
|
.columns(['id', 'updated_at asc'])
|
73
73
|
.execute();
|
74
|
-
await db.schema.createIndex(`index_${table_name}_id_updated_at_desc`)
|
74
|
+
await db.schema.createIndex(`index_${table_name}_id_updated_at_desc`)
|
75
75
|
.on(table_name)
|
76
76
|
.columns(['id', 'updated_at desc'])
|
77
77
|
.execute();
|
78
78
|
}
|
79
79
|
|
80
80
|
if(include_handle) {
|
81
|
-
await db.schema.createIndex(`index_${table_name}_handle_updated_at_asc`)
|
81
|
+
await db.schema.createIndex(`index_${table_name}_handle_updated_at_asc`)
|
82
82
|
.on(table_name)
|
83
83
|
.columns(['handle', 'updated_at asc'])
|
84
84
|
.execute();
|
85
|
-
await db.schema.createIndex(`index_${table_name}_handle_updated_at_desc`)
|
85
|
+
await db.schema.createIndex(`index_${table_name}_handle_updated_at_desc`)
|
86
86
|
.on(table_name)
|
87
87
|
.columns(['handle', 'updated_at desc'])
|
88
88
|
.execute();
|
@@ -97,23 +97,23 @@ const create_base_indexes = async (db, table_name, include_id=true, include_hand
|
|
97
97
|
* 'products_to_variants' | 'storefronts_to_other' | 'products_to_related_products'>} table_name
|
98
98
|
*/
|
99
99
|
const create_entity_table_indexes = async (db, table_name) => {
|
100
|
-
await db.schema.createIndex(`index_${table_name}_entity_id`)
|
100
|
+
await db.schema.createIndex(`index_${table_name}_entity_id`)
|
101
101
|
.on(table_name)
|
102
102
|
.column('entity_id')
|
103
103
|
.execute();
|
104
|
-
await db.schema.createIndex(`index_${table_name}_entity_handle`)
|
104
|
+
await db.schema.createIndex(`index_${table_name}_entity_handle`)
|
105
105
|
.on(table_name)
|
106
106
|
.column('entity_handle')
|
107
107
|
.execute();
|
108
|
-
await db.schema.createIndex(`index_${table_name}_value`)
|
108
|
+
await db.schema.createIndex(`index_${table_name}_value`)
|
109
109
|
.on(table_name)
|
110
110
|
.column('value')
|
111
111
|
.execute();
|
112
|
-
await db.schema.createIndex(`index_${table_name}_reporter`)
|
112
|
+
await db.schema.createIndex(`index_${table_name}_reporter`)
|
113
113
|
.on(table_name)
|
114
114
|
.column('reporter')
|
115
115
|
.execute();
|
116
|
-
await db.schema.createIndex(`index_${table_name}_context`)
|
116
|
+
await db.schema.createIndex(`index_${table_name}_context`)
|
117
117
|
.on(table_name)
|
118
118
|
.column('context')
|
119
119
|
.execute();
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Kysely } from 'kysely'
|
2
2
|
import { upsert } from '../src/con.templates.js'
|
3
|
+
import { templates } from '@storecraft/core/assets/seed-templates.js';
|
3
4
|
|
4
5
|
/**
|
5
6
|
* @typedef {import('../types.sql.tables.js').Database} Database
|
@@ -12,7 +13,7 @@ import { upsert } from '../src/con.templates.js'
|
|
12
13
|
export async function up(db) {
|
13
14
|
|
14
15
|
for (const template of templates.slice(0)) {
|
15
|
-
const result = await upsert(db)(template);
|
16
|
+
const result = await upsert(db)(template, template.search);
|
16
17
|
if(!result)
|
17
18
|
throw new Error('Failed to write a template object')
|
18
19
|
}
|
@@ -24,239 +25,3 @@ export async function up(db) {
|
|
24
25
|
*/
|
25
26
|
export async function down(db) {
|
26
27
|
}
|
27
|
-
|
28
|
-
|
29
|
-
const templates = [
|
30
|
-
{
|
31
|
-
"title": "Welcome Customer",
|
32
|
-
"template_html": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns=\"http://www.w3.org/1999/xhtml\" style=\"color-scheme: light dark; supported-color-schemes: light dark;\">\n <head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"x-apple-disable-message-reformatting\" />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <meta name=\"color-scheme\" content=\"light dark\" />\n <meta name=\"supported-color-schemes\" content=\"light dark\" />\n <title></title>\n <style type=\"text/css\" rel=\"stylesheet\" media=\"all\">\n /* Base ------------------------------ */\n \n @import url(\"https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap\");\n body {\n width: 100% !important;\n height: 100%;\n margin: 0;\n -webkit-text-size-adjust: none;\n }\n \n a {\n color: #3869D4;\n }\n \n a img {\n border: none;\n }\n \n td {\n word-break: break-word;\n }\n \n .preheader {\n display: none !important;\n visibility: hidden;\n mso-hide: all;\n font-size: 1px;\n line-height: 1px;\n max-height: 0;\n max-width: 0;\n opacity: 0;\n overflow: hidden;\n }\n /* Type ------------------------------ */\n \n body,\n td,\n th {\n font-family: \"Nunito Sans\", Helvetica, Arial, sans-serif;\n }\n \n h1 {\n margin-top: 0;\n color: #333333;\n font-size: 22px;\n font-weight: bold;\n text-align: left;\n }\n \n h2 {\n margin-top: 0;\n color: #333333;\n font-size: 16px;\n font-weight: bold;\n text-align: left;\n }\n \n h3 {\n margin-top: 0;\n color: #333333;\n font-size: 14px;\n font-weight: bold;\n text-align: left;\n }\n \n td,\n th {\n font-size: 16px;\n }\n \n p,\n ul,\n ol,\n blockquote {\n margin: .4em 0 1.1875em;\n font-size: 16px;\n line-height: 1.625;\n }\n \n p.sub {\n font-size: 13px;\n }\n /* Utilities ------------------------------ */\n \n .align-right {\n text-align: right;\n }\n \n .align-left {\n text-align: left;\n }\n \n .align-center {\n text-align: center;\n }\n \n .u-margin-bottom-none {\n margin-bottom: 0;\n }\n /* Buttons ------------------------------ */\n \n .button {\n background-color: #3869D4;\n border-top: 10px solid #3869D4;\n border-right: 18px solid #3869D4;\n border-bottom: 10px solid #3869D4;\n border-left: 18px solid #3869D4;\n display: inline-block;\n color: #FFF;\n text-decoration: none;\n border-radius: 3px;\n box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);\n -webkit-text-size-adjust: none;\n box-sizing: border-box;\n }\n \n .button--green {\n background-color: #22BC66;\n border-top: 10px solid #22BC66;\n border-right: 18px solid #22BC66;\n border-bottom: 10px solid #22BC66;\n border-left: 18px solid #22BC66;\n }\n \n .button--red {\n background-color: #FF6136;\n border-top: 10px solid #FF6136;\n border-right: 18px solid #FF6136;\n border-bottom: 10px solid #FF6136;\n border-left: 18px solid #FF6136;\n }\n \n @media only screen and (max-width: 500px) {\n .button {\n width: 100% !important;\n text-align: center !important;\n }\n }\n /* Attribute list ------------------------------ */\n \n .attributes {\n margin: 0 0 21px;\n }\n \n .attributes_content {\n background-color: #F4F4F7;\n padding: 16px;\n }\n \n .attributes_item {\n padding: 0;\n }\n /* Related Items ------------------------------ */\n \n .related {\n width: 100%;\n margin: 0;\n padding: 25px 0 0 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n \n .related_item {\n padding: 10px 0;\n color: #CBCCCF;\n font-size: 15px;\n line-height: 18px;\n }\n \n .related_item-title {\n display: block;\n margin: .5em 0 0;\n }\n \n .related_item-thumb {\n display: block;\n padding-bottom: 10px;\n }\n \n .related_heading {\n border-top: 1px solid #CBCCCF;\n text-align: center;\n padding: 25px 0 10px;\n }\n /* Discount Code ------------------------------ */\n \n .discount {\n width: 100%;\n margin: 0;\n padding: 24px;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #F4F4F7;\n border: 2px dashed #CBCCCF;\n }\n \n .discount_heading {\n text-align: center;\n }\n \n .discount_body {\n text-align: center;\n font-size: 15px;\n }\n /* Social Icons ------------------------------ */\n \n .social {\n width: auto;\n }\n \n .social td {\n padding: 0;\n width: auto;\n }\n \n .social_icon {\n height: 20px;\n margin: 0 8px 10px 8px;\n padding: 0;\n }\n /* Data table ------------------------------ */\n \n .purchase {\n width: 100%;\n margin: 0;\n padding: 35px 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n \n .purchase_content {\n width: 100%;\n margin: 0;\n padding: 25px 0 0 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n \n .purchase_item {\n padding: 10px 0;\n color: #51545E;\n font-size: 15px;\n line-height: 18px;\n }\n \n .purchase_heading {\n padding-bottom: 8px;\n border-bottom: 1px solid #EAEAEC;\n }\n \n .purchase_heading p {\n margin: 0;\n color: #85878E;\n font-size: 12px;\n }\n \n .purchase_footer {\n padding-top: 15px;\n border-top: 1px solid #EAEAEC;\n }\n \n .purchase_total {\n margin: 0;\n text-align: right;\n font-weight: bold;\n color: #333333;\n }\n \n .purchase_total--label {\n padding: 0 15px 0 0;\n }\n \n body {\n background-color: #F4F4F7;\n color: #51545E;\n }\n \n p {\n color: #51545E;\n }\n \n p.sub {\n color: #6B6E76;\n }\n \n .email-wrapper {\n width: 100%;\n margin: 0;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #F4F4F7;\n }\n \n .email-content {\n width: 100%;\n margin: 0;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n /* Masthead ----------------------- */\n \n .email-masthead {\n padding: 25px 0;\n text-align: center;\n }\n \n .email-masthead_logo {\n width: 94px;\n }\n \n .email-masthead_name {\n font-size: 16px;\n font-weight: bold;\n color: #A8AAAF;\n text-decoration: none;\n text-shadow: 0 1px 0 white;\n }\n /* Body ------------------------------ */\n \n .email-body {\n width: 100%;\n margin: 0;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #FFFFFF;\n }\n \n .email-body_inner {\n width: 570px;\n margin: 0 auto;\n padding: 0;\n -premailer-width: 570px;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #FFFFFF;\n }\n \n .email-footer {\n width: 570px;\n margin: 0 auto;\n padding: 0;\n -premailer-width: 570px;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n text-align: center;\n }\n \n .email-footer p {\n color: #6B6E76;\n }\n \n .body-action {\n width: 100%;\n margin: 30px auto;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n text-align: center;\n }\n \n .body-sub {\n margin-top: 25px;\n padding-top: 25px;\n border-top: 1px solid #EAEAEC;\n }\n \n .content-cell {\n padding: 35px;\n }\n /*Media Queries ------------------------------ */\n \n @media only screen and (max-width: 600px) {\n .email-body_inner,\n .email-footer {\n width: 100% !important;\n }\n }\n \n @media (prefers-color-scheme: dark) {\n body,\n .email-body,\n .email-body_inner,\n .email-content,\n .email-wrapper,\n .email-masthead,\n .email-footer {\n background-color: #333333 !important;\n color: #FFF !important;\n }\n p,\n ul,\n ol,\n blockquote,\n h1,\n h2,\n h3,\n span,\n .purchase_item {\n color: #FFF !important;\n }\n .attributes_content,\n .discount {\n background-color: #222 !important;\n }\n .email-masthead_name {\n text-shadow: none !important;\n }\n }\n \n :root {\n color-scheme: light dark;\n supported-color-schemes: light dark;\n }\n </style>\n <!--[if mso]>\n <style type=\"text/css\">\n .f-fallback {\n font-family: Arial, sans-serif;\n }\n </style>\n <![endif]-->\n <style type=\"text/css\" rel=\"stylesheet\" media=\"all\">\n body {\n width: 100% !important;\n height: 100%;\n margin: 0;\n -webkit-text-size-adjust: none;\n }\n \n body {\n font-family: \"Nunito Sans\", Helvetica, Arial, sans-serif;\n }\n \n body {\n background-color: #F4F4F7;\n color: #51545E;\n }\n </style>\n </head>\n <body style=\"width: 100% !important; height: 100%; -webkit-text-size-adjust: none; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; background-color: #F4F4F7; color: #51545E; margin: 0;\" bgcolor=\"#F4F4F7\">\n <span class=\"preheader\" style=\"display: none !important; visibility: hidden; mso-hide: all; font-size: 1px; line-height: 1px; max-height: 0; max-width: 0; opacity: 0; overflow: hidden;\">Thanks for signing up with us. We’re thrilled to have you on board.</span>\n <table class=\"email-wrapper\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #F4F4F7; margin: 0; padding: 0;\" bgcolor=\"#F4F4F7\">\n <tr>\n <td align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <table class=\"email-content\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; margin: 0; padding: 0;\">\n <tr>\n <td class=\"email-masthead\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; text-align: center; padding: 25px 0;\" align=\"center\">\n <a href=\"{{info.general_store_website}}\" class=\"f-fallback email-masthead_name\" style=\"color: #A8AAAF; font-size: 16px; font-weight: bold; text-decoration: none; text-shadow: 0 1px 0 white;\">\n {{info.general_store_name}}\n </a>\n </td>\n </tr>\n <!-- Email Body -->\n <tr>\n <td class=\"email-body\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #FFFFFF; margin: 0; padding: 0;\" bgcolor=\"#FFFFFF\">\n <table class=\"email-body_inner\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 570px; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #FFFFFF; margin: 0 auto; padding: 0;\" bgcolor=\"#FFFFFF\">\n <!-- Body content -->\n <tr>\n <td class=\"content-cell\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding: 35px;\">\n <div class=\"f-fallback\">\n <h1 style=\"margin-top: 0; color: #333333; font-size: 22px; font-weight: bold; text-align: left;\" align=\"left\">Welcome, {{customer.firstname}}!</h1>\n <p style=\"font-size: 16px; line-height: 1.625; color: #51545E; margin: .4em 0 1.1875em;\">Thanks for signing up with us. We’re thrilled to have you on board.</p>\n <!-- Action -->\n <table class=\"body-action\" align=\"center\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center; margin: 30px auto; padding: 0;\">\n <tr>\n <td align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <!-- Border based button\n https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design -->\n <table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\">\n <tr>\n <td align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <a href=\"{{info.general_confirm_email_base_url}}/user={{customer.id}}\" class=\"f-fallback button\" target=\"_blank\" style=\"color: #FFF; background-color: #3869D4; display: inline-block; text-decoration: none; border-radius: 3px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16); -webkit-text-size-adjust: none; box-sizing: border-box; border-color: #3869D4; border-style: solid; border-width: 10px 18px;\">Confirm your email</a>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n <p style=\"font-size: 16px; line-height: 1.625; color: #51545E; margin: .4em 0 1.1875em;\">For reference, here's your login information:</p>\n <table class=\"attributes\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"margin: 0 0 21px;\">\n <tr>\n <td class=\"attributes_content\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; background-color: #F4F4F7; padding: 16px;\" bgcolor=\"#F4F4F7\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n <tr>\n <td class=\"attributes_item\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding: 0;\">\n <span class=\"f-fallback\">\n <strong>User ID:</strong> {{customer.id}}\n </span>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n <p style=\"font-size: 16px; line-height: 1.625; color: #51545E; margin: .4em 0 1.1875em;\">Need help, or have any questions ? Simply reply to this email, we'd love to help</p>\n <!-- Sub copy -->\n \n </div>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <table class=\"email-footer\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 570px; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center; margin: 0 auto; padding: 0;\">\n <tr>\n <td class=\"content-cell\" align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding: 35px;\">\n <p class=\"f-fallback sub align-center\" style=\"font-size: 13px; line-height: 1.625; text-align: center; color: #6B6E76; margin: .4em 0 1.1875em;\" align=\"center\">\n {{info.general_store_name}}\n </p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </body>\n</html>",
|
33
|
-
"template_text": "Thanks for signing up with us. \nWe’re thrilled to have you on board.\n\n******************\nWelcome, {{customer.firstname}}!\n******************\n\nThanks for signing up with us. We’re thrilled to \nhave you on board.\n\nConfirm your email here: \n{{ info.general_confirm_email_base_url }}/user={{customer.id}}\n\nFor reference, here's your login information:\n\nUser ID: {{customer.id}}\n\nNeed help, or have any questions ?\nSimply reply to this email, we'd love to help\n\n[{{info.general_store_name}}] ({{info.general_store_website}})\n",
|
34
|
-
"reference_example_input": {
|
35
|
-
"customer": {
|
36
|
-
"email": "john@dow.com",
|
37
|
-
"firstname": "John",
|
38
|
-
"lastname": "Dow",
|
39
|
-
"id": "cus_65f2ae6e8bf30e6cd0ca95fa"
|
40
|
-
},
|
41
|
-
"info": {
|
42
|
-
"general_store_name": "Wush Wush Games",
|
43
|
-
"general_store_website": "https://wush.games/",
|
44
|
-
"general_store_description": "We sell retro video games",
|
45
|
-
"general_confirm_email_base_url": "https://wush.games/confirm-email"
|
46
|
-
}
|
47
|
-
},
|
48
|
-
"handle": "welcome-customer",
|
49
|
-
"id": "template_664afed24eba71b9ee185be4",
|
50
|
-
"created_at": "2024-05-20T07:42:10.436Z",
|
51
|
-
"updated_at": "2024-05-20T09:39:46.492Z",
|
52
|
-
"_relations": {
|
53
|
-
"search": [
|
54
|
-
"handle:welcome-customer",
|
55
|
-
"welcome-customer",
|
56
|
-
"id:template_664afed24eba71b9ee185be4",
|
57
|
-
"template_664afed24eba71b9ee185be4",
|
58
|
-
"664afed24eba71b9ee185be4",
|
59
|
-
"welcome",
|
60
|
-
"customer",
|
61
|
-
"welcome customer"
|
62
|
-
]
|
63
|
-
}
|
64
|
-
},
|
65
|
-
{
|
66
|
-
"title": "Checkout Complete",
|
67
|
-
"template_html": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns=\"http://www.w3.org/1999/xhtml\" style=\"color-scheme: light dark; supported-color-schemes: light dark;\">\n <head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"x-apple-disable-message-reformatting\" />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <meta name=\"color-scheme\" content=\"light dark\" />\n <meta name=\"supported-color-schemes\" content=\"light dark\" />\n <title></title>\n <style type=\"text/css\" rel=\"stylesheet\" media=\"all\">\n /* Base ------------------------------ */\n \n @import url(\"https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap\");\n body {\n width: 100% !important;\n height: 100%;\n margin: 0;\n -webkit-text-size-adjust: none;\n }\n \n a {\n color: #3869D4;\n }\n \n a img {\n border: none;\n }\n \n td {\n word-break: break-word;\n }\n \n .preheader {\n display: none !important;\n visibility: hidden;\n mso-hide: all;\n font-size: 1px;\n line-height: 1px;\n max-height: 0;\n max-width: 0;\n opacity: 0;\n overflow: hidden;\n }\n /* Type ------------------------------ */\n \n body,\n td,\n th {\n font-family: \"Nunito Sans\", Helvetica, Arial, sans-serif;\n }\n \n h1 {\n margin-top: 0;\n color: #333333;\n font-size: 22px;\n font-weight: bold;\n text-align: left;\n }\n \n h2 {\n margin-top: 0;\n color: #333333;\n font-size: 16px;\n font-weight: bold;\n text-align: left;\n }\n \n h3 {\n margin-top: 0;\n color: #333333;\n font-size: 14px;\n font-weight: bold;\n text-align: left;\n }\n \n td,\n th {\n font-size: 16px;\n }\n \n p,\n ul,\n ol,\n blockquote {\n margin: .4em 0 1.1875em;\n font-size: 16px;\n line-height: 1.625;\n }\n \n p.sub {\n font-size: 13px;\n }\n /* Utilities ------------------------------ */\n \n .align-right {\n text-align: right;\n }\n \n .align-left {\n text-align: left;\n }\n \n .align-center {\n text-align: center;\n }\n \n .u-margin-bottom-none {\n margin-bottom: 0;\n }\n /* Buttons ------------------------------ */\n \n .button {\n background-color: #3869D4;\n border-top: 10px solid #3869D4;\n border-right: 18px solid #3869D4;\n border-bottom: 10px solid #3869D4;\n border-left: 18px solid #3869D4;\n display: inline-block;\n color: #FFF;\n text-decoration: none;\n border-radius: 3px;\n box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);\n -webkit-text-size-adjust: none;\n box-sizing: border-box;\n }\n \n .button--green {\n background-color: #22BC66;\n border-top: 10px solid #22BC66;\n border-right: 18px solid #22BC66;\n border-bottom: 10px solid #22BC66;\n border-left: 18px solid #22BC66;\n }\n \n .button--red {\n background-color: #FF6136;\n border-top: 10px solid #FF6136;\n border-right: 18px solid #FF6136;\n border-bottom: 10px solid #FF6136;\n border-left: 18px solid #FF6136;\n }\n \n @media only screen and (max-width: 500px) {\n .button {\n width: 100% !important;\n text-align: center !important;\n }\n }\n /* Attribute list ------------------------------ */\n \n .attributes {\n margin: 0 0 21px;\n }\n \n .attributes_content {\n background-color: #F4F4F7;\n padding: 16px;\n }\n \n .attributes_item {\n padding: 0;\n }\n /* Related Items ------------------------------ */\n \n .related {\n width: 100%;\n margin: 0;\n padding: 25px 0 0 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n \n .related_item {\n padding: 10px 0;\n color: #CBCCCF;\n font-size: 15px;\n line-height: 18px;\n }\n \n .related_item-title {\n display: block;\n margin: .5em 0 0;\n }\n \n .related_item-thumb {\n display: block;\n padding-bottom: 10px;\n }\n \n .related_heading {\n border-top: 1px solid #CBCCCF;\n text-align: center;\n padding: 25px 0 10px;\n }\n /* Discount Code ------------------------------ */\n \n .discount {\n width: 100%;\n margin: 0;\n padding: 24px;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #F4F4F7;\n border: 2px dashed #CBCCCF;\n }\n \n .discount_heading {\n text-align: center;\n }\n \n .discount_body {\n text-align: center;\n font-size: 15px;\n }\n /* Social Icons ------------------------------ */\n \n .social {\n width: auto;\n }\n \n .social td {\n padding: 0;\n width: auto;\n }\n \n .social_icon {\n height: 20px;\n margin: 0 8px 10px 8px;\n padding: 0;\n }\n /* Data table ------------------------------ */\n \n .purchase {\n width: 100%;\n margin: 0;\n padding: 35px 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n \n .purchase_content {\n width: 100%;\n margin: 0;\n padding: 25px 0 0 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n \n .purchase_item {\n padding: 10px 0;\n color: #51545E;\n font-size: 15px;\n line-height: 18px;\n }\n \n .purchase_heading {\n padding-bottom: 8px;\n border-bottom: 1px solid #EAEAEC;\n }\n \n .purchase_heading p {\n margin: 0;\n color: #85878E;\n font-size: 12px;\n }\n \n .purchase_footer {\n padding-top: 15px;\n border-top: 1px solid #EAEAEC;\n }\n \n .purchase_total {\n margin: 0;\n text-align: right;\n font-weight: bold;\n color: #333333;\n }\n \n .purchase_total--label {\n padding: 0 15px 0 0;\n }\n \n body {\n background-color: #F4F4F7;\n color: #51545E;\n }\n \n p {\n color: #51545E;\n }\n \n p.sub {\n color: #6B6E76;\n }\n \n .email-wrapper {\n width: 100%;\n margin: 0;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #F4F4F7;\n }\n \n .email-content {\n width: 100%;\n margin: 0;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n }\n /* Masthead ----------------------- */\n \n .email-masthead {\n padding: 25px 0;\n text-align: center;\n }\n \n .email-masthead_logo {\n width: 94px;\n }\n \n .email-masthead_name {\n font-size: 16px;\n font-weight: bold;\n color: #A8AAAF;\n text-decoration: none;\n text-shadow: 0 1px 0 white;\n }\n /* Body ------------------------------ */\n \n .email-body {\n width: 100%;\n margin: 0;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #FFFFFF;\n }\n \n .email-body_inner {\n width: 570px;\n margin: 0 auto;\n padding: 0;\n -premailer-width: 570px;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n background-color: #FFFFFF;\n }\n \n .email-footer {\n width: 570px;\n margin: 0 auto;\n padding: 0;\n -premailer-width: 570px;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n text-align: center;\n }\n \n .email-footer p {\n color: #6B6E76;\n }\n \n .body-action {\n width: 100%;\n margin: 30px auto;\n padding: 0;\n -premailer-width: 100%;\n -premailer-cellpadding: 0;\n -premailer-cellspacing: 0;\n text-align: center;\n }\n \n .body-sub {\n margin-top: 25px;\n padding-top: 25px;\n border-top: 1px solid #EAEAEC;\n }\n \n .content-cell {\n padding: 35px;\n }\n /*Media Queries ------------------------------ */\n \n @media only screen and (max-width: 600px) {\n .email-body_inner,\n .email-footer {\n width: 100% !important;\n }\n }\n \n @media (prefers-color-scheme: dark) {\n body,\n .email-body,\n .email-body_inner,\n .email-content,\n .email-wrapper,\n .email-masthead,\n .email-footer {\n background-color: #333333 !important;\n color: #FFF !important;\n }\n p,\n ul,\n ol,\n blockquote,\n h1,\n h2,\n h3,\n span,\n .purchase_item {\n color: #FFF !important;\n }\n .attributes_content,\n .discount {\n background-color: #222 !important;\n }\n .email-masthead_name {\n text-shadow: none !important;\n }\n }\n \n :root {\n color-scheme: light dark;\n supported-color-schemes: light dark;\n }\n </style>\n <!--[if mso]>\n <style type=\"text/css\">\n .f-fallback {\n font-family: Arial, sans-serif;\n }\n </style>\n <![endif]-->\n <style type=\"text/css\" rel=\"stylesheet\" media=\"all\">\n body {\n width: 100% !important;\n height: 100%;\n margin: 0;\n -webkit-text-size-adjust: none;\n }\n \n body {\n font-family: \"Nunito Sans\", Helvetica, Arial, sans-serif;\n }\n \n body {\n background-color: #F4F4F7;\n color: #51545E;\n }\n </style>\n </head>\n <body style=\"width: 100% !important; height: 100%; -webkit-text-size-adjust: none; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; background-color: #F4F4F7; color: #51545E; margin: 0;\" bgcolor=\"#F4F4F7\">\n <table class=\"email-wrapper\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #F4F4F7; margin: 0; padding: 0;\" bgcolor=\"#F4F4F7\">\n <tr>\n <td align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <table class=\"email-content\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; margin: 0; padding: 0;\">\n <tr>\n <td class=\"email-masthead\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; text-align: center; padding: 25px 0;\" align=\"center\">\n <a href=\"{{info.general_store_website}}\" class=\"f-fallback email-masthead_name\" style=\"color: #A8AAAF; font-size: 16px; font-weight: bold; text-decoration: none; text-shadow: 0 1px 0 white;\">\n {{info.general_store_name}}\n </a>\n </td>\n </tr>\n <!-- Email Body -->\n <tr>\n <td class=\"email-body\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #FFFFFF; margin: 0; padding: 0;\" bgcolor=\"#FFFFFF\">\n <table class=\"email-body_inner\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 570px; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; background-color: #FFFFFF; margin: 0 auto; padding: 0;\" bgcolor=\"#FFFFFF\">\n <!-- Body content -->\n <tr>\n <td class=\"content-cell\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding: 35px;\">\n <div class=\"f-fallback\">\n <h1 style=\"margin-top: 0; color: #333333; font-size: 22px; font-weight: bold; text-align: left;\" align=\"left\">Hi {{order.contact.firstname}},</h1>\n <p style=\"font-size: 16px; line-height: 1.625; color: #51545E; margin: .4em 0 1.1875em;\">Thank you for your purchase. This email is the receipt for your purchase.</p>\n <table class=\"purchase\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; margin: 0; padding: 0px 0;\">\n <tr>\n <td style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <h3 style=\"margin-top: 0; color: #333333; font-size: 14px; font-weight: bold; text-align: left;\" align=\"left\">{{order.id}}</h3></td>\n \n </tr>\n <tr>\n <td colspan=\"2\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <table class=\"purchase_content\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; margin: 0; padding: 25px 0 0;\">\n <tr>\n <th class=\"purchase_heading\" align=\"left\" style=\"font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-bottom: 8px; border-bottom-width: 1px; border-bottom-color: #EAEAEC; border-bottom-style: solid;\">\n <p class=\"f-fallback\" style=\"font-size: 12px; line-height: 1.625; color: #85878E; margin: 0;\">Description</p>\n </th>\n <th class=\"purchase_heading\" align=\"right\" style=\"font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-bottom: 8px; border-bottom-width: 1px; border-bottom-color: #EAEAEC; border-bottom-style: solid;\">\n <p class=\"f-fallback\" style=\"font-size: 12px; line-height: 1.625; color: #85878E; margin: 0;\">Amount</p>\n </th>\n </tr>\n {{#each order.line_items}}\n <tr>\n <td width=\"80%\" class=\"purchase_item\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 15px; color: #51545E; line-height: 18px; padding: 10px 0;\"><span class=\"f-fallback\">{{data.title}}</span></td>\n <td class=\"align-right\" width=\"20%\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; text-align: right;\" align=\"right\"><span class=\"f-fallback\">{{qty}}</span></td>\n </tr>\n {{/each}}\n <tr>\n <td width=\"80%\" class=\"purchase_footer\" valign=\"middle\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-top: 15px; border-top-width: 1px; border-top-color: #EAEAEC; border-top-style: solid;\">\n <p class=\"f-fallback purchase_total purchase_total--label\" style=\"font-size: 16px; line-height: 1.625; text-align: right; font-weight: bold; color: #333333; margin: 0; padding: 0 15px 0 0;\" align=\"right\">Shipping</p>\n </td>\n <td width=\"20%\" class=\"purchase_footer\" valign=\"middle\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-top: 15px; border-top-width: 1px; border-top-color: #EAEAEC; border-top-style: solid;\">\n <p class=\"f-fallback purchase_total\" style=\"font-size: 16px; line-height: 1.625; text-align: right; font-weight: bold; color: #333333; margin: 0;\" align=\"right\">{{order.shipping_method.price}}</p>\n </td>\n </tr>\n <tr>\n <td width=\"80%\" class=\"purchase_footer\" valign=\"middle\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-top: 15px; border-top-width: 1px; border-top-color: #EAEAEC; border-top-style: solid;\">\n <p class=\"f-fallback purchase_total purchase_total--label\" style=\"font-size: 16px; line-height: 1.625; text-align: right; font-weight: bold; color: #333333; margin: 0; padding: 0 15px 0 0;\" align=\"right\">Subtotal Discounts</p>\n </td>\n <td width=\"20%\" class=\"purchase_footer\" valign=\"middle\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-top: 15px; border-top-width: 1px; border-top-color: #EAEAEC; border-top-style: solid;\">\n <p class=\"f-fallback purchase_total\" style=\"font-size: 16px; line-height: 1.625; text-align: right; font-weight: bold; color: #333333; margin: 0;\" align=\"right\">-{{order.pricing.subtotal_discount}}</p>\n </td>\n </tr>\n <tr>\n <td width=\"80%\" class=\"purchase_footer\" valign=\"middle\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-top: 15px; border-top-width: 1px; border-top-color: #EAEAEC; border-top-style: solid;\">\n <p class=\"f-fallback purchase_total purchase_total--label\" style=\"font-size: 16px; line-height: 1.625; text-align: right; font-weight: bold; color: #333333; margin: 0; padding: 0 15px 0 0;\" align=\"right\">Total</p>\n </td>\n <td width=\"20%\" class=\"purchase_footer\" valign=\"middle\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding-top: 15px; border-top-width: 1px; border-top-color: #EAEAEC; border-top-style: solid;\">\n <p class=\"f-fallback purchase_total\" style=\"font-size: 16px; line-height: 1.625; text-align: right; font-weight: bold; color: #333333; margin: 0;\" align=\"right\">{{order.pricing.total}}</p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n <p style=\"font-size: 16px; line-height: 1.625; color: #51545E; margin: .4em 0 1.1875em;\">If you have any questions about this receipt, simply reply to this email or reach out to our <a href=\"{{info.general_store_support_email}}\" style=\"color: #3869D4;\">support team</a> for help.</p>\n <p style=\"font-size: 16px; line-height: 1.625; color: #51545E; margin: .4em 0 1.1875em;\">Cheers,\n <br />The {{info.general_store_name}} team</p>\n <!-- Action -->\n <table class=\"body-action\" align=\"center\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center; margin: 30px auto; padding: 0;\">\n <tr>\n <td align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <!-- Border based button\n https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design -->\n <table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\">\n <tr>\n <td align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <a href=\"{{action_url}}\" class=\"f-fallback button button--blue\" target=\"_blank\" style=\"color: #FFF; background-color: #3869D4; display: inline-block; text-decoration: none; border-radius: 3px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16); -webkit-text-size-adjust: none; box-sizing: border-box; border-color: #3869D4; border-style: solid; border-width: 10px 18px;\">Download as PDF</a>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n <!-- Sub copy -->\n \n </div>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;\">\n <table class=\"email-footer\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\" style=\"width: 570px; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center; margin: 0 auto; padding: 0;\">\n <tr>\n <td class=\"content-cell\" align=\"center\" style=\"word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding: 35px;\">\n <p class=\"f-fallback sub align-center\" style=\"font-size: 13px; line-height: 1.625; text-align: center; color: #6B6E76; margin: .4em 0 1.1875em;\" align=\"center\">\n {{info.general_store_name}} \n </p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </body>\n</html>",
|
68
|
-
"template_text": "[{{info.general_store_name}}] ({{info.general_store_website}})\n\n************\nHi {{order.contact.firstname}},\n************\n\nThank you for your purchase !!!\n\n\nOrder ID is {{order.id}}\n--------------\n\n{{date}}\n--------\n\nDescription\n\nItems\n{{#each order.line_items}}\n- {{data.title}} x {{qty}}\n{{/each}}\n\nShipping \n{{order.shipping_method.title}}, {{order.shipping_method.price}}\n\nDiscounts\n{{#each order.pricing.evo}}\n- {{discount.title}} - {{total_discount}}\n{{/each}}\n\nTotal\n{{order.pricing.total}}\n\nIf you have any questions about this receipt, simply reply to this \nemail or reach out to our support team ( {{ info.general_store_support_email }} ) for help.\n\nCheers,\nThe {{info.general_store_name}} team\n\n\n{{info.general_store_name}}\n{{info.general_store_website}}",
|
69
|
-
"reference_example_input": {
|
70
|
-
"order": {
|
71
|
-
"contact": {
|
72
|
-
"email": "john@doe.com",
|
73
|
-
"firstname": "John",
|
74
|
-
"phone_number": "000-000-000",
|
75
|
-
"customer_id": "cus_65f2ae6e8bf30e6cd0ca95fa"
|
76
|
-
},
|
77
|
-
"address": {},
|
78
|
-
"status": {
|
79
|
-
"checkout": {
|
80
|
-
"id": 0,
|
81
|
-
"name2": "created",
|
82
|
-
"name": "Created"
|
83
|
-
},
|
84
|
-
"payment": {
|
85
|
-
"id": 1,
|
86
|
-
"name": "Authorized",
|
87
|
-
"name2": "authorized"
|
88
|
-
},
|
89
|
-
"fulfillment": {
|
90
|
-
"id": 0,
|
91
|
-
"name2": "draft",
|
92
|
-
"name": "Draft"
|
93
|
-
}
|
94
|
-
},
|
95
|
-
"pricing": {
|
96
|
-
"evo": [
|
97
|
-
{
|
98
|
-
"quantity_discounted": 0,
|
99
|
-
"quantity_undiscounted": 11,
|
100
|
-
"subtotal": 1100,
|
101
|
-
"total": 1150
|
102
|
-
},
|
103
|
-
{
|
104
|
-
"quantity_discounted": 2,
|
105
|
-
"total_discount": 100,
|
106
|
-
"quantity_undiscounted": 9,
|
107
|
-
"discount": {
|
108
|
-
"active": true,
|
109
|
-
"handle": "discount-bundle-50-off-robot-arms-and-legs-not-recursive",
|
110
|
-
"title": "50% OFF Bundle: robot arms and legs (not recursive)",
|
111
|
-
"priority": 0,
|
112
|
-
"application": {
|
113
|
-
"id": 0,
|
114
|
-
"name": "Automatic",
|
115
|
-
"name2": "automatic"
|
116
|
-
},
|
117
|
-
"info": {
|
118
|
-
"details": {
|
119
|
-
"meta": {
|
120
|
-
"id": 4,
|
121
|
-
"type": "bundle",
|
122
|
-
"name": "Bundle Discount"
|
123
|
-
},
|
124
|
-
"extra": {
|
125
|
-
"fixed": 0,
|
126
|
-
"percent": 50,
|
127
|
-
"recursive": false
|
128
|
-
}
|
129
|
-
},
|
130
|
-
"filters": [
|
131
|
-
{
|
132
|
-
"meta": {
|
133
|
-
"id": 4,
|
134
|
-
"type": "product",
|
135
|
-
"op": "p-in-tags",
|
136
|
-
"name": "Product has Tag"
|
137
|
-
},
|
138
|
-
"value": [
|
139
|
-
"robot_arm"
|
140
|
-
]
|
141
|
-
},
|
142
|
-
{
|
143
|
-
"meta": {
|
144
|
-
"id": 4,
|
145
|
-
"type": "product",
|
146
|
-
"op": "p-in-tags",
|
147
|
-
"name": "Product has Tag"
|
148
|
-
},
|
149
|
-
"value": [
|
150
|
-
"robot_leg"
|
151
|
-
]
|
152
|
-
}
|
153
|
-
]
|
154
|
-
}
|
155
|
-
},
|
156
|
-
"discount_code": "discount-bundle-50-off-robot-arms-and-legs-not-recursive",
|
157
|
-
"subtotal": 1000,
|
158
|
-
"total": 1050
|
159
|
-
}
|
160
|
-
],
|
161
|
-
"shipping_method": {
|
162
|
-
"title": "",
|
163
|
-
"handle": "",
|
164
|
-
"price": 50
|
165
|
-
},
|
166
|
-
"subtotal_discount": 100,
|
167
|
-
"subtotal_undiscounted": 1100,
|
168
|
-
"subtotal": 1000,
|
169
|
-
"total": 1050,
|
170
|
-
"quantity_total": 11,
|
171
|
-
"quantity_discounted": 2,
|
172
|
-
"errors": []
|
173
|
-
},
|
174
|
-
"line_items": [
|
175
|
-
{
|
176
|
-
"id": "robot-leg-white",
|
177
|
-
"qty": 3,
|
178
|
-
"data": {
|
179
|
-
"tags": [
|
180
|
-
"robot_leg"
|
181
|
-
],
|
182
|
-
"qty": 100,
|
183
|
-
"active": true,
|
184
|
-
"title": "Robot Leg White",
|
185
|
-
"price": 100
|
186
|
-
}
|
187
|
-
},
|
188
|
-
{
|
189
|
-
"id": "battery",
|
190
|
-
"qty": 5,
|
191
|
-
"data": {
|
192
|
-
"tags": [
|
193
|
-
"would-not-be-discounted"
|
194
|
-
],
|
195
|
-
"qty": 100,
|
196
|
-
"active": true,
|
197
|
-
"title": "Battery",
|
198
|
-
"price": 100
|
199
|
-
}
|
200
|
-
},
|
201
|
-
{
|
202
|
-
"id": "robot-arm-red",
|
203
|
-
"qty": 2,
|
204
|
-
"data": {
|
205
|
-
"tags": [
|
206
|
-
"robot_arm"
|
207
|
-
],
|
208
|
-
"qty": 100,
|
209
|
-
"active": true,
|
210
|
-
"title": "Robot Arm Red",
|
211
|
-
"price": 100
|
212
|
-
}
|
213
|
-
},
|
214
|
-
{
|
215
|
-
"id": "robot-arm-green",
|
216
|
-
"qty": 1,
|
217
|
-
"data": {
|
218
|
-
"tags": [
|
219
|
-
"robot_arm"
|
220
|
-
],
|
221
|
-
"qty": 100,
|
222
|
-
"active": true,
|
223
|
-
"title": "Robot Arm Green",
|
224
|
-
"price": 100
|
225
|
-
}
|
226
|
-
}
|
227
|
-
],
|
228
|
-
"shipping_method": {
|
229
|
-
"handle": "ship-fast",
|
230
|
-
"title": "ship fast",
|
231
|
-
"price": 50
|
232
|
-
},
|
233
|
-
"id": "order_65d774c6445e4581b9e34c11",
|
234
|
-
"created_at": "2024-02-22T16:22:30.095Z",
|
235
|
-
"updated_at": "2024-02-22T16:22:30.095Z"
|
236
|
-
},
|
237
|
-
"info": {
|
238
|
-
"general_store_name": "Wush Wush Games",
|
239
|
-
"general_store_website": "https://wush.games/",
|
240
|
-
"general_store_description": "We sell retro video games",
|
241
|
-
"general_confirm_email_base_url": "https://wush.games/confirm-email",
|
242
|
-
"general_store_support_email": "support@wush.games"
|
243
|
-
}
|
244
|
-
},
|
245
|
-
"handle": "checkout-complete",
|
246
|
-
"id": "template_664b15174eba71b9ee185be5",
|
247
|
-
"created_at": "2024-05-20T09:17:11.255Z",
|
248
|
-
"updated_at": "2024-05-20T10:43:40.766Z",
|
249
|
-
"_relations": {
|
250
|
-
"search": [
|
251
|
-
"handle:checkout-complete",
|
252
|
-
"checkout-complete",
|
253
|
-
"id:template_664b15174eba71b9ee185be5",
|
254
|
-
"template_664b15174eba71b9ee185be5",
|
255
|
-
"664b15174eba71b9ee185be5",
|
256
|
-
"checkout",
|
257
|
-
"complete",
|
258
|
-
"checkout complete"
|
259
|
-
]
|
260
|
-
}
|
261
|
-
}
|
262
|
-
]
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@storecraft/database-sql-base",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.2",
|
4
4
|
"description": "Official SQL Database driver for storecraft",
|
5
5
|
"license": "MIT",
|
6
6
|
"author": "Tomer Shalev (https://github.com/store-craft)",
|
@@ -8,7 +8,7 @@
|
|
8
8
|
"repository": {
|
9
9
|
"type": "git",
|
10
10
|
"url": "https://github.com/store-craft/storecraft.git",
|
11
|
-
"directory": "packages/database-sql-base"
|
11
|
+
"directory": "packages/databases/database-sql-base"
|
12
12
|
},
|
13
13
|
"keywords": [
|
14
14
|
"commerce",
|
@@ -31,8 +31,6 @@
|
|
31
31
|
"kysely": "^0.27.2"
|
32
32
|
},
|
33
33
|
"devDependencies": {
|
34
|
-
"@storecraft/platforms": "^1.0.0",
|
35
|
-
"@storecraft/test-runner": "^1.0.0",
|
36
34
|
"@types/better-sqlite3": "^7.6.9",
|
37
35
|
"@types/node": "^20.11.0",
|
38
36
|
"@types/pg": "^8.11.2",
|