@coursebuilder/adapter-drizzle 0.0.1 → 0.0.3
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.d.ts +3 -3
- package/index.d.ts.map +1 -1
- package/lib/mysql.d.ts +1 -1
- package/lib/mysql.d.ts.map +1 -1
- package/lib/mysql.js +56 -0
- package/lib/pg.d.ts +131 -28
- package/lib/pg.d.ts.map +1 -1
- package/lib/pg.js +72 -5
- package/lib/sqlite.d.ts +196 -2
- package/lib/sqlite.d.ts.map +1 -1
- package/lib/sqlite.js +56 -5
- package/lib/utils.d.ts +3 -3
- package/lib/utils.d.ts.map +1 -1
- package/package.json +6 -7
- package/src/index.ts +7 -7
- package/src/lib/mysql.ts +59 -1
- package/src/lib/pg.ts +86 -7
- package/src/lib/sqlite.ts +66 -7
- package/src/lib/utils.ts +3 -3
- package/schema.d.ts +0 -1023
- package/schema.d.ts.map +0 -1
- package/schema.js +0 -318
package/lib/sqlite.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Adapter } from '@auth/core/adapters';
|
|
2
1
|
import { BaseSQLiteDatabase, SQLiteTableFn } from 'drizzle-orm/sqlite-core';
|
|
2
|
+
import { type CourseBuilderAdapter } from '@coursebuilder/core/adapters';
|
|
3
3
|
export declare function createTables(sqliteTable: SQLiteTableFn): {
|
|
4
4
|
users: import("drizzle-orm/sqlite-core/table.js").SQLiteTableWithColumns<{
|
|
5
5
|
name: "user";
|
|
@@ -29,6 +29,18 @@ export declare function createTables(sqliteTable: SQLiteTableFn): {
|
|
|
29
29
|
enumValues: [string, ...string[]];
|
|
30
30
|
baseColumn: never;
|
|
31
31
|
}, object>;
|
|
32
|
+
role: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
33
|
+
name: "role";
|
|
34
|
+
tableName: "user";
|
|
35
|
+
dataType: "string";
|
|
36
|
+
columnType: "SQLiteText";
|
|
37
|
+
data: "user" | "admin";
|
|
38
|
+
driverParam: string;
|
|
39
|
+
notNull: false;
|
|
40
|
+
hasDefault: true;
|
|
41
|
+
enumValues: ["user", "admin"];
|
|
42
|
+
baseColumn: never;
|
|
43
|
+
}, object>;
|
|
32
44
|
email: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
33
45
|
name: "email";
|
|
34
46
|
tableName: "user";
|
|
@@ -293,7 +305,189 @@ export declare function createTables(sqliteTable: SQLiteTableFn): {
|
|
|
293
305
|
};
|
|
294
306
|
dialect: "sqlite";
|
|
295
307
|
}>;
|
|
308
|
+
contentResource: import("drizzle-orm/sqlite-core/table.js").SQLiteTableWithColumns<{
|
|
309
|
+
name: "contentResource";
|
|
310
|
+
schema: undefined;
|
|
311
|
+
columns: {
|
|
312
|
+
id: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
313
|
+
name: "id";
|
|
314
|
+
tableName: "contentResource";
|
|
315
|
+
dataType: "string";
|
|
316
|
+
columnType: "SQLiteText";
|
|
317
|
+
data: string;
|
|
318
|
+
driverParam: string;
|
|
319
|
+
notNull: true;
|
|
320
|
+
hasDefault: false;
|
|
321
|
+
enumValues: [string, ...string[]];
|
|
322
|
+
baseColumn: never;
|
|
323
|
+
}, object>;
|
|
324
|
+
type: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
325
|
+
name: "type";
|
|
326
|
+
tableName: "contentResource";
|
|
327
|
+
dataType: "string";
|
|
328
|
+
columnType: "SQLiteText";
|
|
329
|
+
data: string;
|
|
330
|
+
driverParam: string;
|
|
331
|
+
notNull: true;
|
|
332
|
+
hasDefault: false;
|
|
333
|
+
enumValues: [string, ...string[]];
|
|
334
|
+
baseColumn: never;
|
|
335
|
+
}, object>;
|
|
336
|
+
createdById: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
337
|
+
name: "createdById";
|
|
338
|
+
tableName: "contentResource";
|
|
339
|
+
dataType: "string";
|
|
340
|
+
columnType: "SQLiteText";
|
|
341
|
+
data: string;
|
|
342
|
+
driverParam: string;
|
|
343
|
+
notNull: true;
|
|
344
|
+
hasDefault: false;
|
|
345
|
+
enumValues: [string, ...string[]];
|
|
346
|
+
baseColumn: never;
|
|
347
|
+
}, object>;
|
|
348
|
+
fields: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
349
|
+
name: "metadata";
|
|
350
|
+
tableName: "contentResource";
|
|
351
|
+
dataType: "json";
|
|
352
|
+
columnType: "SQLiteTextJson";
|
|
353
|
+
data: Record<string, any>;
|
|
354
|
+
driverParam: string;
|
|
355
|
+
notNull: false;
|
|
356
|
+
hasDefault: true;
|
|
357
|
+
enumValues: undefined;
|
|
358
|
+
baseColumn: never;
|
|
359
|
+
}, object>;
|
|
360
|
+
createdAt: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
361
|
+
name: "createdAt";
|
|
362
|
+
tableName: "contentResource";
|
|
363
|
+
dataType: "date";
|
|
364
|
+
columnType: "SQLiteTimestamp";
|
|
365
|
+
data: Date;
|
|
366
|
+
driverParam: number;
|
|
367
|
+
notNull: false;
|
|
368
|
+
hasDefault: true;
|
|
369
|
+
enumValues: undefined;
|
|
370
|
+
baseColumn: never;
|
|
371
|
+
}, object>;
|
|
372
|
+
updatedAt: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
373
|
+
name: "updatedAt";
|
|
374
|
+
tableName: "contentResource";
|
|
375
|
+
dataType: "date";
|
|
376
|
+
columnType: "SQLiteTimestamp";
|
|
377
|
+
data: Date;
|
|
378
|
+
driverParam: number;
|
|
379
|
+
notNull: false;
|
|
380
|
+
hasDefault: true;
|
|
381
|
+
enumValues: undefined;
|
|
382
|
+
baseColumn: never;
|
|
383
|
+
}, object>;
|
|
384
|
+
deletedAt: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
385
|
+
name: "deletedAt";
|
|
386
|
+
tableName: "contentResource";
|
|
387
|
+
dataType: "date";
|
|
388
|
+
columnType: "SQLiteTimestamp";
|
|
389
|
+
data: Date;
|
|
390
|
+
driverParam: number;
|
|
391
|
+
notNull: false;
|
|
392
|
+
hasDefault: false;
|
|
393
|
+
enumValues: undefined;
|
|
394
|
+
baseColumn: never;
|
|
395
|
+
}, object>;
|
|
396
|
+
};
|
|
397
|
+
dialect: "sqlite";
|
|
398
|
+
}>;
|
|
399
|
+
contentResourceResource: import("drizzle-orm/sqlite-core/table.js").SQLiteTableWithColumns<{
|
|
400
|
+
name: "contentResourceResource";
|
|
401
|
+
schema: undefined;
|
|
402
|
+
columns: {
|
|
403
|
+
resourceOfId: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
404
|
+
name: "resourceOfId";
|
|
405
|
+
tableName: "contentResourceResource";
|
|
406
|
+
dataType: "string";
|
|
407
|
+
columnType: "SQLiteText";
|
|
408
|
+
data: string;
|
|
409
|
+
driverParam: string;
|
|
410
|
+
notNull: true;
|
|
411
|
+
hasDefault: false;
|
|
412
|
+
enumValues: [string, ...string[]];
|
|
413
|
+
baseColumn: never;
|
|
414
|
+
}, object>;
|
|
415
|
+
resourceId: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
416
|
+
name: "resourceId";
|
|
417
|
+
tableName: "contentResourceResource";
|
|
418
|
+
dataType: "string";
|
|
419
|
+
columnType: "SQLiteText";
|
|
420
|
+
data: string;
|
|
421
|
+
driverParam: string;
|
|
422
|
+
notNull: true;
|
|
423
|
+
hasDefault: false;
|
|
424
|
+
enumValues: [string, ...string[]];
|
|
425
|
+
baseColumn: never;
|
|
426
|
+
}, object>;
|
|
427
|
+
position: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
428
|
+
name: "position";
|
|
429
|
+
tableName: "contentResourceResource";
|
|
430
|
+
dataType: "number";
|
|
431
|
+
columnType: "SQLiteInteger";
|
|
432
|
+
data: number;
|
|
433
|
+
driverParam: number;
|
|
434
|
+
notNull: true;
|
|
435
|
+
hasDefault: true;
|
|
436
|
+
enumValues: undefined;
|
|
437
|
+
baseColumn: never;
|
|
438
|
+
}, object>;
|
|
439
|
+
metadata: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
440
|
+
name: "metadata";
|
|
441
|
+
tableName: "contentResourceResource";
|
|
442
|
+
dataType: "json";
|
|
443
|
+
columnType: "SQLiteTextJson";
|
|
444
|
+
data: Record<string, any>;
|
|
445
|
+
driverParam: string;
|
|
446
|
+
notNull: false;
|
|
447
|
+
hasDefault: true;
|
|
448
|
+
enumValues: undefined;
|
|
449
|
+
baseColumn: never;
|
|
450
|
+
}, object>;
|
|
451
|
+
createdAt: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
452
|
+
name: "createdAt";
|
|
453
|
+
tableName: "contentResourceResource";
|
|
454
|
+
dataType: "date";
|
|
455
|
+
columnType: "SQLiteTimestamp";
|
|
456
|
+
data: Date;
|
|
457
|
+
driverParam: number;
|
|
458
|
+
notNull: false;
|
|
459
|
+
hasDefault: true;
|
|
460
|
+
enumValues: undefined;
|
|
461
|
+
baseColumn: never;
|
|
462
|
+
}, object>;
|
|
463
|
+
updatedAt: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
464
|
+
name: "updatedAt";
|
|
465
|
+
tableName: "contentResourceResource";
|
|
466
|
+
dataType: "date";
|
|
467
|
+
columnType: "SQLiteTimestamp";
|
|
468
|
+
data: Date;
|
|
469
|
+
driverParam: number;
|
|
470
|
+
notNull: false;
|
|
471
|
+
hasDefault: true;
|
|
472
|
+
enumValues: undefined;
|
|
473
|
+
baseColumn: never;
|
|
474
|
+
}, object>;
|
|
475
|
+
deletedAt: import("drizzle-orm/sqlite-core/index.js").SQLiteColumn<{
|
|
476
|
+
name: "deletedAt";
|
|
477
|
+
tableName: "contentResourceResource";
|
|
478
|
+
dataType: "date";
|
|
479
|
+
columnType: "SQLiteTimestamp";
|
|
480
|
+
data: Date;
|
|
481
|
+
driverParam: number;
|
|
482
|
+
notNull: false;
|
|
483
|
+
hasDefault: false;
|
|
484
|
+
enumValues: undefined;
|
|
485
|
+
baseColumn: never;
|
|
486
|
+
}, object>;
|
|
487
|
+
};
|
|
488
|
+
dialect: "sqlite";
|
|
489
|
+
}>;
|
|
296
490
|
};
|
|
297
491
|
export type DefaultSchema = ReturnType<typeof createTables>;
|
|
298
|
-
export declare function SQLiteDrizzleAdapter(client: InstanceType<typeof BaseSQLiteDatabase>, tableFn?: SQLiteTableFn<undefined>):
|
|
492
|
+
export declare function SQLiteDrizzleAdapter(client: InstanceType<typeof BaseSQLiteDatabase>, tableFn?: SQLiteTableFn<undefined>): CourseBuilderAdapter;
|
|
299
493
|
//# sourceMappingURL=sqlite.d.ts.map
|
package/lib/sqlite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/lib/sqlite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/lib/sqlite.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kBAAkB,EAIlB,aAAa,EAEd,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAIxE,wBAAgB,YAAY,CAAC,WAAW,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2FtD;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;AAE3D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,EAC/C,OAAO,2BAAuB,GAC7B,oBAAoB,CAiHtB"}
|
package/lib/sqlite.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { and, eq } from 'drizzle-orm';
|
|
1
|
+
import { and, eq, sql } from 'drizzle-orm';
|
|
2
2
|
import { sqliteTable as defaultSqliteTableFn, integer, primaryKey, text, } from 'drizzle-orm/sqlite-core';
|
|
3
3
|
import { stripUndefined } from './utils.js';
|
|
4
4
|
export function createTables(sqliteTable) {
|
|
5
5
|
const users = sqliteTable('user', {
|
|
6
6
|
id: text('id').notNull().primaryKey(),
|
|
7
7
|
name: text('name'),
|
|
8
|
+
role: text('role', { enum: ['user', 'admin'] }).default('user'),
|
|
8
9
|
email: text('email').notNull(),
|
|
9
10
|
emailVerified: integer('emailVerified', { mode: 'timestamp_ms' }),
|
|
10
11
|
image: text('image'),
|
|
@@ -24,7 +25,7 @@ export function createTables(sqliteTable) {
|
|
|
24
25
|
id_token: text('id_token'),
|
|
25
26
|
session_state: text('session_state'),
|
|
26
27
|
}, (account) => ({
|
|
27
|
-
|
|
28
|
+
pk: primaryKey({ columns: [account.provider, account.providerAccountId] }),
|
|
28
29
|
}));
|
|
29
30
|
const sessions = sqliteTable('session', {
|
|
30
31
|
sessionToken: text('sessionToken').notNull().primaryKey(),
|
|
@@ -38,13 +39,63 @@ export function createTables(sqliteTable) {
|
|
|
38
39
|
token: text('token').notNull(),
|
|
39
40
|
expires: integer('expires', { mode: 'timestamp_ms' }).notNull(),
|
|
40
41
|
}, (vt) => ({
|
|
41
|
-
|
|
42
|
+
pk: primaryKey({ columns: [vt.identifier, vt.token] }),
|
|
42
43
|
}));
|
|
43
|
-
|
|
44
|
+
const contentResource = sqliteTable('contentResource', {
|
|
45
|
+
id: text('id', { length: 255 }).notNull().primaryKey(),
|
|
46
|
+
type: text('type', { length: 255 }).notNull(),
|
|
47
|
+
createdById: text('createdById', { length: 255 }).notNull(),
|
|
48
|
+
fields: text('metadata', { mode: 'json' }).$type().default({}),
|
|
49
|
+
createdAt: integer('createdAt', {
|
|
50
|
+
mode: 'timestamp_ms',
|
|
51
|
+
}).default(sql `CURRENT_TIME`),
|
|
52
|
+
updatedAt: integer('updatedAt', {
|
|
53
|
+
mode: 'timestamp_ms',
|
|
54
|
+
}).default(sql `CURRENT_TIME`),
|
|
55
|
+
deletedAt: integer('deletedAt', {
|
|
56
|
+
mode: 'timestamp_ms',
|
|
57
|
+
}),
|
|
58
|
+
});
|
|
59
|
+
const contentResourceResource = sqliteTable('contentResourceResource', {
|
|
60
|
+
resourceOfId: text('resourceOfId', { length: 255 }).notNull(),
|
|
61
|
+
resourceId: text('resourceId', { length: 255 }).notNull(),
|
|
62
|
+
position: integer('position').notNull().default(0),
|
|
63
|
+
metadata: text('metadata', { mode: 'json' }).$type().default({}),
|
|
64
|
+
createdAt: integer('createdAt', {
|
|
65
|
+
mode: 'timestamp_ms',
|
|
66
|
+
}).default(sql `CURRENT_TIME`),
|
|
67
|
+
updatedAt: integer('updatedAt', {
|
|
68
|
+
mode: 'timestamp_ms',
|
|
69
|
+
}).default(sql `CURRENT_TIME`),
|
|
70
|
+
deletedAt: integer('deletedAt', {
|
|
71
|
+
mode: 'timestamp_ms',
|
|
72
|
+
}),
|
|
73
|
+
}, (crr) => ({
|
|
74
|
+
pk: primaryKey({ columns: [crr.resourceOfId, crr.resourceId] }),
|
|
75
|
+
}));
|
|
76
|
+
return { users, accounts, sessions, verificationTokens, contentResource, contentResourceResource };
|
|
44
77
|
}
|
|
45
78
|
export function SQLiteDrizzleAdapter(client, tableFn = defaultSqliteTableFn) {
|
|
46
|
-
const { users, accounts, sessions, verificationTokens } = createTables(tableFn);
|
|
79
|
+
const { users, accounts, sessions, verificationTokens, contentResource } = createTables(tableFn);
|
|
47
80
|
return {
|
|
81
|
+
async updateContentResourceFields(options) {
|
|
82
|
+
return null;
|
|
83
|
+
},
|
|
84
|
+
async getVideoResource(id) {
|
|
85
|
+
// TODO Implement
|
|
86
|
+
return null;
|
|
87
|
+
},
|
|
88
|
+
async createContentResource(resource) {
|
|
89
|
+
return client
|
|
90
|
+
.insert(contentResource)
|
|
91
|
+
.values({ ...resource, id: crypto.randomUUID() })
|
|
92
|
+
.returning()
|
|
93
|
+
.get();
|
|
94
|
+
},
|
|
95
|
+
async getContentResource(data) {
|
|
96
|
+
const result = await client.select().from(contentResource).where(eq(contentResource.id, data)).get();
|
|
97
|
+
return result ?? null;
|
|
98
|
+
},
|
|
48
99
|
async createUser(data) {
|
|
49
100
|
return client
|
|
50
101
|
.insert(users)
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { MySqlDatabase } from 'drizzle-orm/mysql-core';
|
|
1
|
+
import { type MySqlDatabase } from 'drizzle-orm/mysql-core';
|
|
2
2
|
import type { AnyMySqlTable, MySqlTableFn } from 'drizzle-orm/mysql-core';
|
|
3
|
-
import { PgDatabase } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { type PgDatabase } from 'drizzle-orm/pg-core';
|
|
4
4
|
import type { AnyPgTable, PgTableFn } from 'drizzle-orm/pg-core';
|
|
5
|
-
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
5
|
+
import { type BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
6
6
|
import type { AnySQLiteTable, SQLiteTableFn } from 'drizzle-orm/sqlite-core';
|
|
7
7
|
import type { DefaultSchema as MySqlSchema } from './mysql.js';
|
|
8
8
|
import type { DefaultSchema as PgSchema } from './pg.js';
|
package/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAE5E,OAAO,KAAK,EAAE,aAAa,IAAI,WAAW,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,SAAS,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AAEhE,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;AACtD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AACrD,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAEtE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAClD,EAAE,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACzC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CACtD;AAED,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEnF,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,MAAM,SAAS,gBAAgB,GAC/D,aAAa,CAAC,OAAO,CAAC,GACtB,MAAM,SAAS,aAAa,GAC1B,aAAa,CAAC,IAAI,CAAC,GACnB,MAAM,SAAS,iBAAiB,GAC9B,aAAa,CAAC,QAAQ,CAAC,GACvB,KAAK,CAAA;AAEb,MAAM,MAAM,OAAO,CAAC,MAAM,IAAI,MAAM,SAAS,gBAAgB,GACzD,YAAY,GACZ,MAAM,SAAS,aAAa,GAC1B,SAAS,GACT,MAAM,SAAS,iBAAiB,GAC9B,aAAa,GACb,cAAc,CAAA;AAEtB,KAAK,gBAAgB,CAAC,CAAC,IAAI;KACxB,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;CAC9C,CAAC,MAAM,CAAC,CAAC,CAAA;AAEV,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAItE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coursebuilder/adapter-drizzle",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Drizzle adapter for Course Builder.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"coursebuilder",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@auth/core": "^0.28.0",
|
|
31
|
-
"@coursebuilder/core": "0.0.1",
|
|
32
30
|
"date-fns": "^2.30.0"
|
|
33
31
|
},
|
|
34
32
|
"devDependencies": {
|
|
33
|
+
"@auth/core": "^0.28.0",
|
|
34
|
+
"@coursebuilder/core": "0.0.3",
|
|
35
35
|
"@libsql/client": "0.5.6",
|
|
36
36
|
"@types/better-sqlite3": "7.6.9",
|
|
37
37
|
"@types/uuid": "9.0.8",
|
|
@@ -41,12 +41,11 @@
|
|
|
41
41
|
"mysql2": "^3.6.1",
|
|
42
42
|
"postgres": "^3.3.4"
|
|
43
43
|
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"drizzle-orm": "0.30.x"
|
|
46
|
+
},
|
|
44
47
|
"scripts": {
|
|
45
48
|
"clean": "rm -rf ./dist",
|
|
46
|
-
"test": "pnpm test:mysql && pnpm test:sqlite && pnpm test:pg",
|
|
47
|
-
"test:mysql": "pnpm clean && ./test/mysql/test.sh",
|
|
48
|
-
"test:sqlite": "pnpm clean && ./test/sqlite/test.sh",
|
|
49
|
-
"test:pg": "pnpm clean && ./test/pg/test.sh",
|
|
50
49
|
"build": "tsc",
|
|
51
50
|
"dev": "tsc --watch"
|
|
52
51
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { is } from 'drizzle-orm'
|
|
2
|
-
import { MySqlDatabase, MySqlTableFn } from 'drizzle-orm/mysql-core'
|
|
3
|
-
import { PgDatabase, PgTableFn } from 'drizzle-orm/pg-core'
|
|
4
|
-
import { BaseSQLiteDatabase, SQLiteTableFn } from 'drizzle-orm/sqlite-core'
|
|
2
|
+
import { MySqlDatabase, type MySqlTableFn } from 'drizzle-orm/mysql-core'
|
|
3
|
+
import { PgDatabase, type PgTableFn } from 'drizzle-orm/pg-core'
|
|
4
|
+
import { BaseSQLiteDatabase, type SQLiteTableFn } from 'drizzle-orm/sqlite-core'
|
|
5
|
+
|
|
6
|
+
import { type CourseBuilderAdapter } from '@coursebuilder/core/adapters'
|
|
5
7
|
|
|
6
8
|
import { createTables as createMySqlTables, mySqlDrizzleAdapter } from './lib/mysql.js'
|
|
7
9
|
import { pgDrizzleAdapter } from './lib/pg.js'
|
|
8
10
|
import { SQLiteDrizzleAdapter } from './lib/sqlite.js'
|
|
9
|
-
import { SqlFlavorOptions, TableFn } from './lib/utils.js'
|
|
10
|
-
|
|
11
|
-
type NO_IT_AINT = any
|
|
11
|
+
import { type SqlFlavorOptions, type TableFn } from './lib/utils.js'
|
|
12
12
|
|
|
13
13
|
export function DrizzleAdapter<SqlFlavor extends SqlFlavorOptions>(
|
|
14
14
|
db: SqlFlavor,
|
|
15
15
|
table?: TableFn<SqlFlavor>,
|
|
16
|
-
):
|
|
16
|
+
): CourseBuilderAdapter {
|
|
17
17
|
if (is(db, MySqlDatabase)) {
|
|
18
18
|
return mySqlDrizzleAdapter(db, table as MySqlTableFn)
|
|
19
19
|
} else if (is(db, PgDatabase)) {
|
package/src/lib/mysql.ts
CHANGED
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
varchar,
|
|
16
16
|
} from 'drizzle-orm/mysql-core'
|
|
17
17
|
|
|
18
|
-
import { CourseBuilderAdapter } from '@coursebuilder/core/adapters'
|
|
18
|
+
import { type CourseBuilderAdapter } from '@coursebuilder/core/adapters'
|
|
19
|
+
import { VideoResourceSchema } from '@coursebuilder/core/schemas/video-resource'
|
|
19
20
|
|
|
20
21
|
export function createTables(mySqlTable: MySqlTableFn) {
|
|
21
22
|
const users = mySqlTable('user', {
|
|
@@ -151,6 +152,63 @@ export function mySqlDrizzleAdapter(
|
|
|
151
152
|
const { users, accounts, sessions, verificationTokens, contentResource } = createTables(tableFn)
|
|
152
153
|
|
|
153
154
|
return {
|
|
155
|
+
async updateContentResourceFields(options) {
|
|
156
|
+
const setFields = Object.entries(options.fields)
|
|
157
|
+
.map(([fieldName, fieldValue], index, array) => {
|
|
158
|
+
const comma = index < array.length - 1 ? ',' : ''
|
|
159
|
+
return sql`${fieldName} = ${fieldValue}${comma}`
|
|
160
|
+
})
|
|
161
|
+
.join(' ')
|
|
162
|
+
|
|
163
|
+
const query = sql`
|
|
164
|
+
UPDATE ${contentResource}
|
|
165
|
+
SET ${setFields}
|
|
166
|
+
WHERE
|
|
167
|
+
id = ${options.id};
|
|
168
|
+
`
|
|
169
|
+
return client
|
|
170
|
+
.execute(query)
|
|
171
|
+
.then((_) => {
|
|
172
|
+
return this.getContentResource(options.id)
|
|
173
|
+
})
|
|
174
|
+
.catch((error) => {
|
|
175
|
+
console.error(error)
|
|
176
|
+
throw error
|
|
177
|
+
})
|
|
178
|
+
},
|
|
179
|
+
async getVideoResource(id) {
|
|
180
|
+
if (!id) {
|
|
181
|
+
throw new Error('videoResourceId is required')
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const query = sql`
|
|
185
|
+
SELECT
|
|
186
|
+
id as _id,
|
|
187
|
+
CAST(updatedAt AS DATETIME) as _updatedAt,
|
|
188
|
+
CAST(createdAt AS DATETIME) as _createdAt,
|
|
189
|
+
JSON_EXTRACT (${contentResource.fields}, "$.state") AS state,
|
|
190
|
+
JSON_EXTRACT (${contentResource.fields}, "$.duration") AS duration,
|
|
191
|
+
JSON_EXTRACT (${contentResource.fields}, "$.muxPlaybackId") AS muxPlaybackId,
|
|
192
|
+
JSON_EXTRACT (${contentResource.fields}, "$.muxAssetId") AS muxAssetId,
|
|
193
|
+
JSON_EXTRACT (${contentResource.fields}, "$.transcript") AS transcript
|
|
194
|
+
FROM
|
|
195
|
+
${contentResource}
|
|
196
|
+
WHERE
|
|
197
|
+
type = 'videoResource'
|
|
198
|
+
AND (id = ${id});
|
|
199
|
+
|
|
200
|
+
`
|
|
201
|
+
return client
|
|
202
|
+
.execute(query)
|
|
203
|
+
.then((result: any) => {
|
|
204
|
+
const parsedResource = VideoResourceSchema.safeParse(result.rows[0])
|
|
205
|
+
return parsedResource.success ? parsedResource.data : null
|
|
206
|
+
})
|
|
207
|
+
.catch((error) => {
|
|
208
|
+
console.error(error)
|
|
209
|
+
return error
|
|
210
|
+
})
|
|
211
|
+
},
|
|
154
212
|
async createContentResource(data) {
|
|
155
213
|
const id = crypto.randomUUID()
|
|
156
214
|
|
package/src/lib/pg.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AdapterAccount, AdapterSession, AdapterUser } from '@auth/core/adapters'
|
|
2
2
|
import { and, eq } from 'drizzle-orm'
|
|
3
3
|
import {
|
|
4
4
|
pgTable as defaultPgTableFn,
|
|
5
5
|
integer,
|
|
6
|
+
json,
|
|
6
7
|
PgDatabase,
|
|
8
|
+
pgEnum,
|
|
7
9
|
PgTableFn,
|
|
8
10
|
primaryKey,
|
|
9
11
|
text,
|
|
10
12
|
timestamp,
|
|
13
|
+
varchar,
|
|
11
14
|
} from 'drizzle-orm/pg-core'
|
|
12
15
|
|
|
13
|
-
import {
|
|
16
|
+
import { type CourseBuilderAdapter } from '@coursebuilder/core/adapters'
|
|
14
17
|
|
|
15
18
|
export function createTables(pgTable: PgTableFn) {
|
|
16
19
|
const users = pgTable('user', {
|
|
@@ -18,6 +21,7 @@ export function createTables(pgTable: PgTableFn) {
|
|
|
18
21
|
name: text('name'),
|
|
19
22
|
email: text('email').notNull(),
|
|
20
23
|
emailVerified: timestamp('emailVerified', { mode: 'date' }),
|
|
24
|
+
role: pgEnum('role', ['user', 'admin'])('role').default('user'),
|
|
21
25
|
image: text('image'),
|
|
22
26
|
})
|
|
23
27
|
|
|
@@ -39,7 +43,7 @@ export function createTables(pgTable: PgTableFn) {
|
|
|
39
43
|
session_state: text('session_state'),
|
|
40
44
|
},
|
|
41
45
|
(account) => ({
|
|
42
|
-
|
|
46
|
+
pk: primaryKey({ columns: [account.provider, account.providerAccountId] }),
|
|
43
47
|
}),
|
|
44
48
|
)
|
|
45
49
|
|
|
@@ -59,19 +63,94 @@ export function createTables(pgTable: PgTableFn) {
|
|
|
59
63
|
expires: timestamp('expires', { mode: 'date' }).notNull(),
|
|
60
64
|
},
|
|
61
65
|
(vt) => ({
|
|
62
|
-
|
|
66
|
+
pk: primaryKey({ columns: [vt.identifier, vt.token] }),
|
|
63
67
|
}),
|
|
64
68
|
)
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
const contentResource = pgTable('contentResource', {
|
|
71
|
+
id: varchar('id', { length: 255 }).notNull().primaryKey(),
|
|
72
|
+
type: varchar('type', { length: 255 }).notNull(),
|
|
73
|
+
createdById: varchar('createdById', { length: 255 }).notNull(),
|
|
74
|
+
fields: json('fields').$type<Record<string, any>>().default({}),
|
|
75
|
+
createdAt: timestamp('createdAt', {
|
|
76
|
+
mode: 'date',
|
|
77
|
+
precision: 6,
|
|
78
|
+
withTimezone: true,
|
|
79
|
+
}).defaultNow(),
|
|
80
|
+
updatedAt: timestamp('updatedAt', {
|
|
81
|
+
mode: 'date',
|
|
82
|
+
precision: 6,
|
|
83
|
+
withTimezone: true,
|
|
84
|
+
}).defaultNow(),
|
|
85
|
+
deletedAt: timestamp('deletedAt', {
|
|
86
|
+
mode: 'date',
|
|
87
|
+
precision: 6,
|
|
88
|
+
withTimezone: true,
|
|
89
|
+
}),
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
const contentResourceResource = pgTable(
|
|
93
|
+
'contentResourceResource',
|
|
94
|
+
{
|
|
95
|
+
resourceOfId: varchar('resourceOfId', { length: 255 }).notNull(),
|
|
96
|
+
resourceId: varchar('resourceId', { length: 255 }).notNull(),
|
|
97
|
+
position: integer('position').notNull().default(0),
|
|
98
|
+
metadata: json('fields').$type<Record<string, any>>().default({}),
|
|
99
|
+
createdAt: timestamp('createdAt', {
|
|
100
|
+
mode: 'date',
|
|
101
|
+
precision: 6,
|
|
102
|
+
withTimezone: true,
|
|
103
|
+
}).defaultNow(),
|
|
104
|
+
updatedAt: timestamp('updatedAt', {
|
|
105
|
+
mode: 'date',
|
|
106
|
+
precision: 6,
|
|
107
|
+
withTimezone: true,
|
|
108
|
+
}).defaultNow(),
|
|
109
|
+
deletedAt: timestamp('deletedAt', {
|
|
110
|
+
mode: 'date',
|
|
111
|
+
precision: 6,
|
|
112
|
+
withTimezone: true,
|
|
113
|
+
}),
|
|
114
|
+
},
|
|
115
|
+
(crr) => ({
|
|
116
|
+
pk: primaryKey({ columns: [crr.resourceOfId, crr.resourceId] }),
|
|
117
|
+
}),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return { users, accounts, sessions, verificationTokens, contentResource }
|
|
67
121
|
}
|
|
68
122
|
|
|
69
123
|
export type DefaultSchema = ReturnType<typeof createTables>
|
|
70
124
|
|
|
71
|
-
export function pgDrizzleAdapter(
|
|
72
|
-
|
|
125
|
+
export function pgDrizzleAdapter(
|
|
126
|
+
client: InstanceType<typeof PgDatabase>,
|
|
127
|
+
tableFn = defaultPgTableFn,
|
|
128
|
+
): CourseBuilderAdapter {
|
|
129
|
+
const { users, accounts, sessions, verificationTokens, contentResource } = createTables(tableFn)
|
|
73
130
|
|
|
74
131
|
return {
|
|
132
|
+
async updateContentResourceFields(options) {
|
|
133
|
+
return null
|
|
134
|
+
},
|
|
135
|
+
async getVideoResource(id) {
|
|
136
|
+
// TODO Implement
|
|
137
|
+
return null
|
|
138
|
+
},
|
|
139
|
+
async createContentResource(resource) {
|
|
140
|
+
return client
|
|
141
|
+
.insert(contentResource)
|
|
142
|
+
.values({ ...resource, id: crypto.randomUUID() })
|
|
143
|
+
.returning()
|
|
144
|
+
.then((res) => res[0] ?? null)
|
|
145
|
+
},
|
|
146
|
+
async getContentResource(data) {
|
|
147
|
+
const result = await client
|
|
148
|
+
.select()
|
|
149
|
+
.from(contentResource)
|
|
150
|
+
.where(eq(contentResource.id, data))
|
|
151
|
+
.then((res) => res[0] ?? null)
|
|
152
|
+
return result ?? null
|
|
153
|
+
},
|
|
75
154
|
async createUser(data) {
|
|
76
155
|
return await client
|
|
77
156
|
.insert(users)
|