@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/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>): Adapter;
492
+ export declare function SQLiteDrizzleAdapter(client: InstanceType<typeof BaseSQLiteDatabase>, tableFn?: SQLiteTableFn<undefined>): CourseBuilderAdapter;
299
493
  //# sourceMappingURL=sqlite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/lib/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,qBAAqB,CAAA;AAElE,OAAO,EACL,kBAAkB,EAIlB,aAAa,EAEd,MAAM,yBAAyB,CAAA;AAIhC,wBAAgB,YAAY,CAAC,WAAW,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDtD;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,OAAO,CA+FT"}
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
- compoundKey: primaryKey(account.provider, account.providerAccountId),
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
- compoundKey: primaryKey(vt.identifier, vt.token),
42
+ pk: primaryKey({ columns: [vt.identifier, vt.token] }),
42
43
  }));
43
- return { users, accounts, sessions, verificationTokens };
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';
@@ -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;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,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"}
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.1",
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
- ): NO_IT_AINT {
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 { Adapter, AdapterAccount, AdapterSession, AdapterUser } from '@auth/core/adapters'
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 { stripUndefined } from './utils.js'
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
- compoundKey: primaryKey(account.provider, account.providerAccountId),
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
- compoundKey: primaryKey(vt.identifier, vt.token),
66
+ pk: primaryKey({ columns: [vt.identifier, vt.token] }),
63
67
  }),
64
68
  )
65
69
 
66
- return { users, accounts, sessions, verificationTokens }
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(client: InstanceType<typeof PgDatabase>, tableFn = defaultPgTableFn): Adapter {
72
- const { users, accounts, sessions, verificationTokens } = createTables(tableFn)
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)