@loomcore/api 0.1.13 → 0.1.15

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.
@@ -6,7 +6,7 @@ export declare class TestMongoDatabase implements ITestDatabase {
6
6
  private mongoDb;
7
7
  private database;
8
8
  private initPromise;
9
- init(databaseName: string): Promise<IDatabase>;
9
+ init(): Promise<IDatabase>;
10
10
  getRandomId(): string;
11
11
  private _performInit;
12
12
  private createIndexes;
@@ -9,17 +9,17 @@ export class TestMongoDatabase {
9
9
  mongoDb = null;
10
10
  database = null;
11
11
  initPromise = null;
12
- async init(databaseName) {
12
+ async init() {
13
13
  if (this.initPromise) {
14
14
  return this.initPromise;
15
15
  }
16
- this.initPromise = this._performInit(databaseName);
16
+ this.initPromise = this._performInit();
17
17
  return this.initPromise;
18
18
  }
19
19
  getRandomId() {
20
20
  return new ObjectId().toString();
21
21
  }
22
- async _performInit(databaseName) {
22
+ async _performInit() {
23
23
  if (!this.database) {
24
24
  this.mongoServer = await MongoMemoryServer.create({
25
25
  instance: {
@@ -4,7 +4,7 @@ export declare class TestPostgresDatabase implements ITestDatabase {
4
4
  private database;
5
5
  private postgresClient;
6
6
  private initPromise;
7
- init(databaseName: string): Promise<IDatabase>;
7
+ init(adminUsername?: string, adminPassword?: string): Promise<IDatabase>;
8
8
  getRandomId(): string;
9
9
  private _performInit;
10
10
  private createIndexes;
@@ -11,17 +11,17 @@ export class TestPostgresDatabase {
11
11
  database = null;
12
12
  postgresClient = null;
13
13
  initPromise = null;
14
- async init(databaseName) {
14
+ async init(adminUsername, adminPassword) {
15
15
  if (this.initPromise) {
16
16
  return this.initPromise;
17
17
  }
18
- this.initPromise = this._performInit(databaseName);
18
+ this.initPromise = this._performInit(adminUsername, adminPassword);
19
19
  return this.initPromise;
20
20
  }
21
21
  getRandomId() {
22
22
  return randomUUID();
23
23
  }
24
- async _performInit(databaseName) {
24
+ async _performInit(adminUsername, adminPassword) {
25
25
  if (!this.database) {
26
26
  const { Client } = newDb().adapters.createPg();
27
27
  const postgresClient = new Client();
@@ -33,7 +33,7 @@ export class TestPostgresDatabase {
33
33
  if (!success) {
34
34
  throw new Error('Failed to setup for multitenant');
35
35
  }
36
- success = (await setupDatabaseForAuth(postgresClient, testOrg._id)).success;
36
+ success = (await setupDatabaseForAuth(postgresClient, adminUsername || 'admin', adminPassword || 'password', testOrg._id)).success;
37
37
  if (!success) {
38
38
  throw new Error('Failed to setup for auth');
39
39
  }
@@ -1,6 +1,6 @@
1
1
  import { IDatabase } from "../databases/models/index.js";
2
2
  export type ITestDatabase = {
3
- init(databaseName: string): Promise<IDatabase>;
3
+ init(adminUsername?: string, adminPassword?: string): Promise<IDatabase>;
4
4
  getRandomId(): string;
5
5
  clearCollections(): Promise<void>;
6
6
  cleanup(): Promise<void>;
@@ -61,12 +61,12 @@ export class TestExpressApp {
61
61
  if (useMongoDb) {
62
62
  const testMongoDb = new TestMongoDatabase();
63
63
  this.testDatabase = testMongoDb;
64
- this.database = await testMongoDb.init(this.databaseName);
64
+ this.database = await testMongoDb.init();
65
65
  }
66
66
  else {
67
67
  const testPostgresDb = new TestPostgresDatabase();
68
68
  this.testDatabase = testPostgresDb;
69
- this.database = await testPostgresDb.init(this.databaseName);
69
+ this.database = await testPostgresDb.init('admin', 'password');
70
70
  }
71
71
  }
72
72
  if (!this.app) {
@@ -19,10 +19,7 @@ export class CreateMigrationTableMigration {
19
19
  `);
20
20
  }
21
21
  catch (error) {
22
- if (error.code === '42P07' || error.data?.error?.includes('already exists')) {
23
- console.log(`Migrations table already exists`);
24
- }
25
- else {
22
+ if (error.code !== '42P07' && !error.data?.error?.includes('already exists')) {
26
23
  return { success: false, error: new Error(`Error creating migrations table: ${error.message}`) };
27
24
  }
28
25
  }
@@ -0,0 +1,20 @@
1
+ import { Client } from "pg";
2
+ import { IMigration } from "../index.js";
3
+ export declare class CreateAdminUserMigration implements IMigration {
4
+ private readonly client;
5
+ private readonly adminEmail;
6
+ private readonly adminPassword;
7
+ constructor(client: Client, adminEmail: string, adminPassword: string);
8
+ index: number;
9
+ execute(_orgId?: string): Promise<{
10
+ success: boolean;
11
+ error: Error;
12
+ } | {
13
+ success: boolean;
14
+ error: null;
15
+ }>;
16
+ revert(_orgId?: string): Promise<{
17
+ success: boolean;
18
+ error: Error | null;
19
+ }>;
20
+ }
@@ -0,0 +1,53 @@
1
+ import { PostgresDatabase } from "../index.js";
2
+ import { randomUUID } from "crypto";
3
+ import { UserService } from "../../../services/user.service.js";
4
+ import { getSystemUserContext, initializeSystemUserContext } from "@loomcore/common/models";
5
+ export class CreateAdminUserMigration {
6
+ client;
7
+ adminEmail;
8
+ adminPassword;
9
+ constructor(client, adminEmail, adminPassword) {
10
+ this.client = client;
11
+ this.adminEmail = adminEmail;
12
+ this.adminPassword = adminPassword;
13
+ }
14
+ index = 6;
15
+ async execute(_orgId) {
16
+ const _id = randomUUID().toString();
17
+ try {
18
+ const database = new PostgresDatabase(this.client);
19
+ const userService = new UserService(database);
20
+ initializeSystemUserContext(this.adminEmail, _orgId);
21
+ const systemUserContext = getSystemUserContext();
22
+ const adminUser = await userService.create(systemUserContext, {
23
+ _id: _id,
24
+ _orgId: _orgId,
25
+ email: this.adminEmail,
26
+ password: this.adminPassword,
27
+ firstName: 'Admin',
28
+ lastName: 'User',
29
+ displayName: 'Admin User',
30
+ roles: ['admin'],
31
+ });
32
+ }
33
+ catch (error) {
34
+ return { success: false, error: new Error(`Error creating admin user: ${error.message}`) };
35
+ }
36
+ try {
37
+ const result = await this.client.query(`
38
+ INSERT INTO "migrations" ("_id", "_orgId", "index", "hasRun", "reverted")
39
+ VALUES ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
40
+ `);
41
+ if (result.rowCount === 0) {
42
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
43
+ }
44
+ }
45
+ catch (error) {
46
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
47
+ }
48
+ return { success: true, error: null };
49
+ }
50
+ async revert(_orgId) {
51
+ throw new Error('Not implemented');
52
+ }
53
+ }
@@ -1,5 +1,5 @@
1
1
  import { Client } from "pg";
2
- export declare function setupDatabaseForAuth(client: Client, _orgId?: string): Promise<{
2
+ export declare function setupDatabaseForAuth(client: Client, adminUsername: string, adminPassword: string, _orgId?: string): Promise<{
3
3
  success: boolean;
4
4
  error: Error | null;
5
5
  }>;
@@ -2,7 +2,8 @@ import { CreateRefreshTokenTableMigration } from "./004-create-refresh-tokens-ta
2
2
  import { CreateMigrationTableMigration } from "./001-create-migrations-table.migration.js";
3
3
  import { CreateUsersTableMigration } from "./003-create-users-table.migration.js";
4
4
  import { doesTableExist } from "../utils/does-table-exist.util.js";
5
- export async function setupDatabaseForAuth(client, _orgId) {
5
+ import { CreateAdminUserMigration } from "./006-create-admin-user.migration.js";
6
+ export async function setupDatabaseForAuth(client, adminUsername, adminPassword, _orgId) {
6
7
  let runMigrations = [];
7
8
  if (await doesTableExist(client, 'migrations')) {
8
9
  const migrations = await client.query(`
@@ -21,6 +22,8 @@ export async function setupDatabaseForAuth(client, _orgId) {
21
22
  migrationsToRun.push(new CreateUsersTableMigration(client));
22
23
  if (!runMigrations.includes(4))
23
24
  migrationsToRun.push(new CreateRefreshTokenTableMigration(client));
25
+ if (!runMigrations.includes(6))
26
+ migrationsToRun.push(new CreateAdminUserMigration(client, adminUsername, adminPassword));
24
27
  for (const migration of migrationsToRun) {
25
28
  await migration.execute(_orgId);
26
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "private": false,
5
5
  "description": "Loom Core Api - An opinionated Node.js api using Typescript, Express, and MongoDb or PostgreSQL",
6
6
  "scripts": {