@storecraft/database-turso 1.0.15 → 1.0.17

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 CHANGED
@@ -29,8 +29,8 @@ export class Turso extends SQL {
29
29
  dialect_type: 'SQLITE',
30
30
  dialect: new LibsqlDialect(
31
31
  {
32
+ prefers_batch_over_transactions: true,
32
33
  ...config,
33
- prefers_batch_over_transactions: config.prefers_batch_over_transactions ?? true
34
34
  }
35
35
  ),
36
36
  }
@@ -26,8 +26,12 @@ export class LibsqlDialect {
26
26
  return this.#config;
27
27
  }
28
28
 
29
- createAdapter() { return new kysely.SqliteAdapter(); }
30
- createQueryCompiler() { return new kysely.SqliteQueryCompiler(); }
29
+ createAdapter() {
30
+ return new kysely.SqliteAdapter();
31
+ }
32
+ createQueryCompiler() {
33
+ return new kysely.SqliteQueryCompiler();
34
+ }
31
35
  createDriver() {
32
36
 
33
37
  if (this.#config?.url===undefined) {
@@ -173,9 +177,7 @@ export class LibsqlConnection {
173
177
  }
174
178
 
175
179
  /**
176
- *
177
180
  * @param {kysely.CompiledQuery} compiledQuery
178
- *
179
181
  * @returns {Promise<QueryResult>}
180
182
  */
181
183
  async executeQuery(compiledQuery) {
@@ -193,6 +195,7 @@ export class LibsqlConnection {
193
195
  }
194
196
 
195
197
  async beginTransaction() {
198
+ // console.log('beginTransaction')
196
199
  if(this.config.prefers_batch_over_transactions) {
197
200
  this.isBatch = true;
198
201
  this.batch = [];
package/migrate.js CHANGED
@@ -1,5 +1,123 @@
1
- export { migrateToLatest } from '@storecraft/database-sql-base/migrate.js';
1
+ import { SQL } from "@storecraft/database-sql-base";
2
+ import { AggregateDialect } from "@storecraft/database-sql-base/kysely.aggregate.dialect.js";
3
+ import { get_migrations, prepare_and_bind } from "@storecraft/database-sql-base/migrate.js";
4
+ import { Kysely, Migrator } from "kysely";
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { fileURLToPath } from "node:url";
2
8
 
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
3
11
 
12
+ /**
13
+ *
14
+ * @param {SQL} db_driver
15
+ * @param {boolean} [destroy_db_upon_completion=true]
16
+ */
17
+ export async function migrateToLatest(
18
+ db_driver, destroy_db_upon_completion=true
19
+ ) {
20
+ const db = db_driver?.client;
4
21
 
22
+ if(!db)
23
+ throw new Error('No Kysely client found !!!');
5
24
 
25
+ console.log(
26
+ 'Resolving migrations. This may take 2 minutes ...'
27
+ );
28
+
29
+ const migrations = await get_migrations(db_driver.dialectType);
30
+
31
+ if(!migrations)
32
+ throw new Error('No migrations found !!!');
33
+
34
+ const sorted = Object
35
+ .entries(migrations)
36
+ .sort((a, b) => a[0].localeCompare(b[0]));
37
+
38
+ /** @type {Record<string, import("kysely").Migration>} */
39
+ const rewritten_migrations = {};
40
+
41
+ for (const [name, migration] of sorted) {
42
+ // console.log(`Executing virtual migration "${name}" ...`);
43
+ const up_agg_dialect = new AggregateDialect(
44
+ { dialect: db_driver.config.dialect, }
45
+ );
46
+ const up_agg_kysely = new Kysely(
47
+ { dialect: up_agg_dialect }
48
+ );
49
+ const down_agg_dialect = new AggregateDialect(
50
+ { dialect: db_driver.config.dialect, }
51
+ );
52
+ const down_agg_kysely = new Kysely(
53
+ { dialect: down_agg_dialect }
54
+ );
55
+
56
+ await migration.up(up_agg_kysely);
57
+ await migration.down(down_agg_kysely);
58
+
59
+ // now get the queries
60
+ const queries_up = up_agg_dialect.queries;
61
+ const queries_down = down_agg_dialect.queries;
62
+
63
+ // turso dialect supports transactions and also batch
64
+ // we take adavantage of this
65
+ rewritten_migrations[name] = {
66
+ up: async (db) => {
67
+ await db.transaction().execute(
68
+ async (trx) => {
69
+ for (const query of queries_up) {
70
+ await trx.executeQuery(query)
71
+ }
72
+ }
73
+ );
74
+ },
75
+ down: async (db) => {
76
+ await db.transaction().execute(
77
+ async (trx) => {
78
+ for (const query of queries_down) {
79
+ await trx.executeQuery(query)
80
+ }
81
+ }
82
+ );
83
+ }
84
+ }
85
+ }
86
+
87
+ const migrator = new Migrator(
88
+ {
89
+ db,
90
+ provider: {
91
+ getMigrations: async () => {
92
+ return rewritten_migrations;
93
+ }
94
+ }
95
+ }
96
+ );
97
+
98
+ const { error, results } = await migrator.migrateToLatest();
99
+
100
+ results?.forEach(
101
+ (it) => {
102
+ if (it.status === 'Success') {
103
+ console.log(
104
+ `migration "${it.migrationName}" was executed successfully`
105
+ );
106
+ } else if (it.status === 'Error') {
107
+ console.error(
108
+ `failed to execute migration "${it.migrationName}"`
109
+ );
110
+ }
111
+ }
112
+ );
113
+
114
+ if (error) {
115
+ console.error('failed to migrate')
116
+ console.error(JSON.stringify(error, null, 2))
117
+ process.exit(1)
118
+ }
119
+
120
+ if(destroy_db_upon_completion)
121
+ await db.destroy();
122
+ }
123
+
package/migrate_old.js ADDED
@@ -0,0 +1,5 @@
1
+ export { migrateToLatest } from '@storecraft/database-sql-base/migrate.js';
2
+
3
+
4
+
5
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storecraft/database-turso",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "`Storecraft` database driver for `Turso` (cloud sqlite)",
5
5
  "license": "MIT",
6
6
  "author": "Tomer Shalev (https://github.com/store-craft)",
@@ -11,7 +11,9 @@ export const create_app = async () => {
11
11
  {
12
12
  auth_admins_emails: ['admin@sc.com'],
13
13
  auth_secret_access_token: 'auth_secret_access_token',
14
- auth_secret_refresh_token: 'auth_secret_refresh_token'
14
+ auth_secret_refresh_token: 'auth_secret_refresh_token',
15
+ auth_secret_confirm_email_token: 'auth_secret_confirm_email_token',
16
+ auth_secret_forgot_password_token: 'auth_secret_forgot_password_token',
15
17
  }
16
18
  )
17
19
  .withPlatform(new NodePlatform())
package/tests/sandbox.js CHANGED
@@ -9,7 +9,9 @@ export const test = async () => {
9
9
  {
10
10
  auth_admins_emails: ['admin@sc.com'],
11
11
  auth_secret_access_token: 'auth_secret_access_token',
12
- auth_secret_refresh_token: 'auth_secret_refresh_token'
12
+ auth_secret_refresh_token: 'auth_secret_refresh_token',
13
+ auth_secret_confirm_email_token: 'auth_secret_confirm_email_token',
14
+ auth_secret_forgot_password_token: 'auth_secret_forgot_password_token',
13
15
  }
14
16
  )
15
17
  .withPlatform(new NodePlatform())
@@ -1,33 +0,0 @@
1
-
2
- /**
3
- *
4
- * @param {string} stmt
5
- * @param {any[] | Record<string, any>} params
6
- */
7
- export const prepare_and_bind = (stmt='', params=[]) => {
8
- const params_object = Array.isArray(params) ?
9
- params.reduce((a, v, idx) => ({ ...a, [idx+1]: v}), {}) :
10
- params;
11
-
12
- let current = 0;
13
- let result = ''
14
- let index_run = 1;
15
- for (let m of stmt.matchAll(/\?[0-9]*/g)) {
16
- result += stmt.slice(current, m.index);
17
-
18
- const match_string = m[0];
19
- let index_access = match_string.length > 1 ?
20
- Number(match_string.slice(1)) :
21
- index_run;
22
-
23
- result += "'" + params_object[index_access] + "'";
24
-
25
- current = m.index + m[0].length;
26
- index_run+=1;
27
- }
28
-
29
- result += stmt.slice(current);
30
-
31
- return result;
32
- }
33
-