@loomcore/api 0.1.30 → 0.1.32

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.
Files changed (30) hide show
  1. package/dist/__tests__/index.d.ts +1 -1
  2. package/dist/__tests__/index.js +1 -1
  3. package/dist/__tests__/postgres-test-migrations/{001-create-test-entities-table.migration.d.ts → 100-create-test-entities-table.migration.d.ts} +2 -2
  4. package/dist/__tests__/postgres-test-migrations/{001-create-test-entities-table.migration.js → 100-create-test-entities-table.migration.js} +9 -21
  5. package/dist/__tests__/postgres-test-migrations/{002-create-categories-table.migration.d.ts → 101-create-categories-table.migration.d.ts} +2 -2
  6. package/dist/__tests__/postgres-test-migrations/{002-create-categories-table.migration.js → 101-create-categories-table.migration.js} +9 -21
  7. package/dist/__tests__/postgres-test-migrations/{003-create-products-table.migration.d.ts → 102-create-products-table.migration.d.ts} +2 -2
  8. package/dist/__tests__/postgres-test-migrations/{003-create-products-table.migration.js → 102-create-products-table.migration.js} +9 -21
  9. package/dist/__tests__/postgres-test-migrations/{005-create-test-items-table.migration.d.ts → 103-create-test-items-table.migration.d.ts} +2 -2
  10. package/dist/__tests__/postgres-test-migrations/{005-create-test-items-table.migration.js → 103-create-test-items-table.migration.js} +9 -21
  11. package/dist/__tests__/postgres-test-migrations/test-migrations.d.ts +3 -0
  12. package/dist/__tests__/postgres-test-migrations/test-migrations.js +12 -0
  13. package/dist/__tests__/postgres.test-database.js +6 -23
  14. package/dist/controllers/authorizations.controller.d.ts +7 -0
  15. package/dist/controllers/authorizations.controller.js +9 -0
  16. package/dist/controllers/features.controller.d.ts +7 -0
  17. package/dist/controllers/features.controller.js +9 -0
  18. package/dist/controllers/roles.controller.d.ts +7 -0
  19. package/dist/controllers/roles.controller.js +9 -0
  20. package/dist/controllers/user-roles.controller.d.ts +7 -0
  21. package/dist/controllers/user-roles.controller.js +9 -0
  22. package/dist/databases/postgres/migrations/011-create-admin-authorization.migration.js +5 -5
  23. package/dist/databases/postgres/migrations/database-builder.js +5 -2
  24. package/package.json +1 -1
  25. package/dist/__tests__/postgres-test-migrations/run-test-migrations.d.ts +0 -5
  26. package/dist/__tests__/postgres-test-migrations/run-test-migrations.js +0 -21
  27. package/dist/databases/postgres/migrations/setup-for-auth.migration.d.ts +0 -8
  28. package/dist/databases/postgres/migrations/setup-for-auth.migration.js +0 -96
  29. package/dist/databases/postgres/migrations/setup-for-multitenant.migration.d.ts +0 -8
  30. package/dist/databases/postgres/migrations/setup-for-multitenant.migration.js +0 -42
@@ -1,4 +1,4 @@
1
- export * from './postgres-test-migrations/001-create-test-entities-table.migration.js';
1
+ export * from './postgres-test-migrations/100-create-test-entities-table.migration.js';
2
2
  export * from './models/test-entity.model.js';
3
3
  export * from './postgres.test-database.js';
4
4
  export * from './mongo-db.test-database.js';
@@ -1,4 +1,4 @@
1
- export * from './postgres-test-migrations/001-create-test-entities-table.migration.js';
1
+ export * from './postgres-test-migrations/100-create-test-entities-table.migration.js';
2
2
  export * from './models/test-entity.model.js';
3
3
  export * from './postgres.test-database.js';
4
4
  export * from './mongo-db.test-database.js';
@@ -4,14 +4,14 @@ export declare class CreateTestEntitiesTableMigration implements IMigration {
4
4
  private readonly client;
5
5
  constructor(client: Client);
6
6
  index: number;
7
- execute(_orgId?: string): Promise<{
7
+ execute(): Promise<{
8
8
  success: boolean;
9
9
  error: Error;
10
10
  } | {
11
11
  success: boolean;
12
12
  error: null;
13
13
  }>;
14
- revert(_orgId?: string): Promise<{
14
+ revert(): Promise<{
15
15
  success: boolean;
16
16
  error: Error;
17
17
  } | {
@@ -4,8 +4,8 @@ export class CreateTestEntitiesTableMigration {
4
4
  constructor(client) {
5
5
  this.client = client;
6
6
  }
7
- index = 1;
8
- async execute(_orgId) {
7
+ index = 100;
8
+ async execute() {
9
9
  const _id = randomUUID().toString();
10
10
  try {
11
11
  await this.client.query(`
@@ -29,29 +29,17 @@ export class CreateTestEntitiesTableMigration {
29
29
  catch (error) {
30
30
  return { success: false, error: new Error(`Error creating test entities table: ${error.message}`) };
31
31
  }
32
- if (_orgId) {
33
- try {
34
- await this.client.query(`
35
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
36
- `);
37
- }
38
- catch (error) {
39
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
40
- }
41
- }
42
- else {
43
- try {
44
- await this.client.query(`
32
+ try {
33
+ await this.client.query(`
45
34
  Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
46
35
  `);
47
- }
48
- catch (error) {
49
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
50
- }
36
+ }
37
+ catch (error) {
38
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
51
39
  }
52
40
  return { success: true, error: null };
53
41
  }
54
- async revert(_orgId) {
42
+ async revert() {
55
43
  try {
56
44
  await this.client.query(`
57
45
  DROP TABLE test_entities;
@@ -62,7 +50,7 @@ export class CreateTestEntitiesTableMigration {
62
50
  }
63
51
  try {
64
52
  await this.client.query(`
65
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
53
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
66
54
  `);
67
55
  }
68
56
  catch (error) {
@@ -4,14 +4,14 @@ export declare class CreateCategoriesTableMigration implements IMigration {
4
4
  private readonly client;
5
5
  constructor(client: Client);
6
6
  index: number;
7
- execute(_orgId?: string): Promise<{
7
+ execute(): Promise<{
8
8
  success: boolean;
9
9
  error: Error;
10
10
  } | {
11
11
  success: boolean;
12
12
  error: null;
13
13
  }>;
14
- revert(_orgId?: string): Promise<{
14
+ revert(): Promise<{
15
15
  success: boolean;
16
16
  error: Error;
17
17
  } | {
@@ -4,8 +4,8 @@ export class CreateCategoriesTableMigration {
4
4
  constructor(client) {
5
5
  this.client = client;
6
6
  }
7
- index = 2;
8
- async execute(_orgId) {
7
+ index = 101;
8
+ async execute() {
9
9
  const _id = randomUUID().toString();
10
10
  try {
11
11
  await this.client.query(`
@@ -19,29 +19,17 @@ export class CreateCategoriesTableMigration {
19
19
  catch (error) {
20
20
  return { success: false, error: new Error(`Error creating categories table: ${error.message}`) };
21
21
  }
22
- if (_orgId) {
23
- try {
24
- await this.client.query(`
25
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
26
- `);
27
- }
28
- catch (error) {
29
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
30
- }
31
- }
32
- else {
33
- try {
34
- await this.client.query(`
22
+ try {
23
+ await this.client.query(`
35
24
  Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
36
25
  `);
37
- }
38
- catch (error) {
39
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
40
- }
26
+ }
27
+ catch (error) {
28
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
41
29
  }
42
30
  return { success: true, error: null };
43
31
  }
44
- async revert(_orgId) {
32
+ async revert() {
45
33
  try {
46
34
  await this.client.query(`
47
35
  DROP TABLE "categories";
@@ -52,7 +40,7 @@ export class CreateCategoriesTableMigration {
52
40
  }
53
41
  try {
54
42
  await this.client.query(`
55
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
43
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
56
44
  `);
57
45
  }
58
46
  catch (error) {
@@ -4,14 +4,14 @@ export declare class CreateProductsTableMigration implements IMigration {
4
4
  private readonly client;
5
5
  constructor(client: Client);
6
6
  index: number;
7
- execute(_orgId?: string): Promise<{
7
+ execute(): Promise<{
8
8
  success: boolean;
9
9
  error: Error;
10
10
  } | {
11
11
  success: boolean;
12
12
  error: null;
13
13
  }>;
14
- revert(_orgId?: string): Promise<{
14
+ revert(): Promise<{
15
15
  success: boolean;
16
16
  error: Error;
17
17
  } | {
@@ -4,8 +4,8 @@ export class CreateProductsTableMigration {
4
4
  constructor(client) {
5
5
  this.client = client;
6
6
  }
7
- index = 3;
8
- async execute(_orgId) {
7
+ index = 102;
8
+ async execute() {
9
9
  const _id = randomUUID().toString();
10
10
  try {
11
11
  await this.client.query(`
@@ -28,29 +28,17 @@ export class CreateProductsTableMigration {
28
28
  catch (error) {
29
29
  return { success: false, error: new Error(`Error creating products table: ${error.message}`) };
30
30
  }
31
- if (_orgId) {
32
- try {
33
- await this.client.query(`
34
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
35
- `);
36
- }
37
- catch (error) {
38
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
39
- }
40
- }
41
- else {
42
- try {
43
- await this.client.query(`
31
+ try {
32
+ await this.client.query(`
44
33
  Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
45
34
  `);
46
- }
47
- catch (error) {
48
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
49
- }
35
+ }
36
+ catch (error) {
37
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
50
38
  }
51
39
  return { success: true, error: null };
52
40
  }
53
- async revert(_orgId) {
41
+ async revert() {
54
42
  try {
55
43
  await this.client.query(`
56
44
  DROP TABLE "products";
@@ -61,7 +49,7 @@ export class CreateProductsTableMigration {
61
49
  }
62
50
  try {
63
51
  await this.client.query(`
64
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
52
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
65
53
  `);
66
54
  }
67
55
  catch (error) {
@@ -4,14 +4,14 @@ export declare class CreateTestItemsTableMigration implements IMigration {
4
4
  private readonly client;
5
5
  constructor(client: Client);
6
6
  index: number;
7
- execute(_orgId?: string): Promise<{
7
+ execute(): Promise<{
8
8
  success: boolean;
9
9
  error: Error;
10
10
  } | {
11
11
  success: boolean;
12
12
  error: null;
13
13
  }>;
14
- revert(_orgId?: string): Promise<{
14
+ revert(): Promise<{
15
15
  success: boolean;
16
16
  error: Error;
17
17
  } | {
@@ -4,8 +4,8 @@ export class CreateTestItemsTableMigration {
4
4
  constructor(client) {
5
5
  this.client = client;
6
6
  }
7
- index = 5;
8
- async execute(_orgId) {
7
+ index = 103;
8
+ async execute() {
9
9
  const _id = randomUUID().toString();
10
10
  try {
11
11
  await this.client.query(`
@@ -27,29 +27,17 @@ export class CreateTestItemsTableMigration {
27
27
  catch (error) {
28
28
  return { success: false, error: new Error(`Error creating test items table: ${error.message}`) };
29
29
  }
30
- if (_orgId) {
31
- try {
32
- await this.client.query(`
33
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
34
- `);
35
- }
36
- catch (error) {
37
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
38
- }
39
- }
40
- else {
41
- try {
42
- await this.client.query(`
30
+ try {
31
+ await this.client.query(`
43
32
  Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
44
33
  `);
45
- }
46
- catch (error) {
47
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
48
- }
34
+ }
35
+ catch (error) {
36
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
49
37
  }
50
38
  return { success: true, error: null };
51
39
  }
52
- async revert(_orgId) {
40
+ async revert() {
53
41
  try {
54
42
  await this.client.query(`
55
43
  DROP TABLE "testItems";
@@ -60,7 +48,7 @@ export class CreateTestItemsTableMigration {
60
48
  }
61
49
  try {
62
50
  await this.client.query(`
63
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
51
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
64
52
  `);
65
53
  }
66
54
  catch (error) {
@@ -0,0 +1,3 @@
1
+ import { Client } from "pg";
2
+ import { IMigration } from "../../databases/index.js";
3
+ export declare const testMigrations: (client: Client) => IMigration[];
@@ -0,0 +1,12 @@
1
+ import { CreateTestEntitiesTableMigration } from "./100-create-test-entities-table.migration.js";
2
+ import { CreateCategoriesTableMigration } from "./101-create-categories-table.migration.js";
3
+ import { CreateProductsTableMigration } from "./102-create-products-table.migration.js";
4
+ import { CreateTestItemsTableMigration } from "./103-create-test-items-table.migration.js";
5
+ export const testMigrations = (client) => {
6
+ return [
7
+ new CreateTestEntitiesTableMigration(client),
8
+ new CreateCategoriesTableMigration(client),
9
+ new CreateProductsTableMigration(client),
10
+ new CreateTestItemsTableMigration(client),
11
+ ];
12
+ };
@@ -1,13 +1,9 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  import testUtils from './common-test.utils.js';
3
- import { initSystemUserContext } from '../config/base-api-config.js';
4
3
  import { newDb } from "pg-mem";
5
- import { setupDatabaseForMultitenant } from '../databases/postgres/migrations/setup-for-multitenant.migration.js';
6
- import { setupDatabaseForAuth } from '../databases/postgres/migrations/setup-for-auth.migration.js';
7
- import { runTestMigrations } from './postgres-test-migrations/run-test-migrations.js';
4
+ import { testMigrations } from './postgres-test-migrations/test-migrations.js';
8
5
  import { PostgresDatabase } from '../databases/postgres/postgres.database.js';
9
- import { getSystemUserContext } from '@loomcore/common/models';
10
- import { setTestMetaOrgId } from './test-objects.js';
6
+ import { DatabaseBuilder } from '../databases/postgres/migrations/database-builder.js';
11
7
  export class TestPostgresDatabase {
12
8
  database = null;
13
9
  postgresClient = null;
@@ -30,23 +26,10 @@ export class TestPostgresDatabase {
30
26
  const testDatabase = new PostgresDatabase(postgresClient);
31
27
  this.database = testDatabase;
32
28
  this.postgresClient = postgresClient;
33
- const multitenantResult = await setupDatabaseForMultitenant(postgresClient);
34
- let success = multitenantResult.success;
35
- if (!success) {
36
- throw new Error('Failed to setup for multitenant');
37
- }
38
- await initSystemUserContext(this.database);
39
- success = (await setupDatabaseForAuth(postgresClient)).success;
40
- if (!success) {
41
- throw new Error('Failed to setup for auth');
42
- }
43
- const systemUserContext = getSystemUserContext();
44
- if (systemUserContext._orgId) {
45
- setTestMetaOrgId(systemUserContext._orgId);
46
- }
47
- success = (await runTestMigrations(postgresClient, systemUserContext._orgId)).success;
48
- if (!success) {
49
- throw new Error('Failed to run test migrations');
29
+ const builder = new DatabaseBuilder(postgresClient);
30
+ const result = await builder.withMultitenant().withAuth().withMigrations(testMigrations(postgresClient)).build();
31
+ if (!result.success) {
32
+ throw new Error('Failed to setup test database');
50
33
  }
51
34
  testUtils.initialize(testDatabase);
52
35
  await this.createIndexes(postgresClient);
@@ -0,0 +1,7 @@
1
+ import { IAuthorization } from "@loomcore/common/models";
2
+ import { ApiController } from "./api.controller.js";
3
+ import { Application } from "express";
4
+ import { IDatabase } from "../databases/models/index.js";
5
+ export declare class AuthorizationsController extends ApiController<IAuthorization> {
6
+ constructor(app: Application, database: IDatabase);
7
+ }
@@ -0,0 +1,9 @@
1
+ import { AuthorizationModelSpec } from "@loomcore/common/models";
2
+ import { ApiController } from "./api.controller.js";
3
+ import { GenericApiService } from "../services/generic-api-service/generic-api.service.js";
4
+ export class AuthorizationsController extends ApiController {
5
+ constructor(app, database) {
6
+ const authorizationService = new GenericApiService(database, 'authorizations', 'authorization', AuthorizationModelSpec);
7
+ super('authorizations', app, authorizationService, 'authorization', AuthorizationModelSpec);
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ import { IFeature } from "../models/feature.model.js";
2
+ import { ApiController } from "./api.controller.js";
3
+ import { Application } from "express";
4
+ import { IDatabase } from "../databases/models/index.js";
5
+ export declare class FeaturesController extends ApiController<IFeature> {
6
+ constructor(app: Application, database: IDatabase);
7
+ }
@@ -0,0 +1,9 @@
1
+ import { FeatureModelSpec } from "../models/feature.model.js";
2
+ import { ApiController } from "./api.controller.js";
3
+ import { GenericApiService } from "../services/generic-api-service/generic-api.service.js";
4
+ export class FeaturesController extends ApiController {
5
+ constructor(app, database) {
6
+ const featureService = new GenericApiService(database, 'features', 'feature', FeatureModelSpec);
7
+ super('features', app, featureService, 'feature', FeatureModelSpec, FeatureModelSpec);
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ import { IDatabase } from "../databases/models/index.js";
2
+ import { IRole } from "../models/role.model.js";
3
+ import { ApiController } from "./api.controller.js";
4
+ import { Application } from "express";
5
+ export declare class RolesController extends ApiController<IRole> {
6
+ constructor(app: Application, database: IDatabase);
7
+ }
@@ -0,0 +1,9 @@
1
+ import { RoleModelSpec } from "../models/role.model.js";
2
+ import { ApiController } from "./api.controller.js";
3
+ import { GenericApiService } from "../services/generic-api-service/generic-api.service.js";
4
+ export class RolesController extends ApiController {
5
+ constructor(app, database) {
6
+ const roleService = new GenericApiService(database, 'roles', 'role', RoleModelSpec);
7
+ super('roles', app, roleService, 'role', RoleModelSpec, RoleModelSpec);
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ import { ApiController } from "./api.controller.js";
2
+ import { IDatabase } from "../databases/models/index.js";
3
+ import { Application } from "express";
4
+ import { IUserRole } from "../models/user-role.model.js";
5
+ export declare class UserRolesController extends ApiController<IUserRole> {
6
+ constructor(app: Application, database: IDatabase);
7
+ }
@@ -0,0 +1,9 @@
1
+ import { ApiController } from "./api.controller.js";
2
+ import { GenericApiService } from "../services/generic-api-service/generic-api.service.js";
3
+ import { UserRoleModelSpec } from "../models/user-role.model.js";
4
+ export class UserRolesController extends ApiController {
5
+ constructor(app, database) {
6
+ const userRoleService = new GenericApiService(database, 'user-roles', 'user-role', UserRoleModelSpec);
7
+ super('user-roles', app, userRoleService, 'user-role', UserRoleModelSpec, UserRoleModelSpec);
8
+ }
9
+ }
@@ -17,7 +17,7 @@ export class CreateAdminAuthorizationMigration {
17
17
  async execute() {
18
18
  const _id = randomUUID().toString();
19
19
  try {
20
- const metaOrg = await this.organizationService.getMetaOrg(EmptyUserContext).catch(() => null);
20
+ const metaOrg = config.app.isMultiTenant ? await this.organizationService.getMetaOrg(EmptyUserContext) : undefined;
21
21
  if (!config.adminUser?.email) {
22
22
  return { success: false, error: new Error('Create admin authorization: Admin user email not found in config') };
23
23
  }
@@ -30,7 +30,7 @@ export class CreateAdminAuthorizationMigration {
30
30
  const roleResult = await this.client.query(`
31
31
  INSERT INTO "roles" ("_id", "_orgId", "name")
32
32
  VALUES ($1, $2, 'admin')
33
- `, [roleId, metaOrg?._id ?? null]);
33
+ `, [roleId, metaOrg?._id]);
34
34
  if (roleResult.rowCount === 0) {
35
35
  await this.client.query('ROLLBACK');
36
36
  return { success: false, error: new Error('Failed to create admin role') };
@@ -39,7 +39,7 @@ export class CreateAdminAuthorizationMigration {
39
39
  const userRoleResult = await this.client.query(`
40
40
  INSERT INTO "user_roles" ("_id", "_orgId", "_userId", "_roleId", "_created", "_createdBy", "_updated", "_updatedBy")
41
41
  VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
42
- `, [userRoleId, metaOrg?._id ?? null, adminUser?._id, roleId]);
42
+ `, [userRoleId, metaOrg?._id, adminUser?._id, roleId]);
43
43
  if (userRoleResult.rowCount === 0) {
44
44
  await this.client.query('ROLLBACK');
45
45
  return { success: false, error: new Error('Failed to create user role') };
@@ -48,7 +48,7 @@ export class CreateAdminAuthorizationMigration {
48
48
  const featureResult = await this.client.query(`
49
49
  INSERT INTO "features" ("_id", "_orgId", "name")
50
50
  VALUES ($1, $2, 'admin')
51
- `, [featureId, metaOrg?._id ?? null]);
51
+ `, [featureId, metaOrg?._id]);
52
52
  if (featureResult.rowCount === 0) {
53
53
  await this.client.query('ROLLBACK');
54
54
  return { success: false, error: new Error('Failed to create admin feature') };
@@ -60,7 +60,7 @@ export class CreateAdminAuthorizationMigration {
60
60
  "_created", "_createdBy", "_updated", "_updatedBy"
61
61
  )
62
62
  VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
63
- `, [authorizationId, metaOrg?._id ?? null, roleId, featureId]);
63
+ `, [authorizationId, metaOrg?._id, roleId, featureId]);
64
64
  if (authorizationResult.rowCount === 0) {
65
65
  await this.client.query('ROLLBACK');
66
66
  return { success: false, error: new Error('Failed to create admin authorization') };
@@ -1,3 +1,4 @@
1
+ import _ from "lodash";
1
2
  import { CreateMigrationTableMigration } from "./001-create-migrations-table.migration.js";
2
3
  import { CreateUsersTableMigration } from "./003-create-users-table.migration.js";
3
4
  import { CreateAdminUserMigration } from "./006-create-admin-user.migration.js";
@@ -50,11 +51,13 @@ export class DatabaseBuilder {
50
51
  return row.index;
51
52
  });
52
53
  }
53
- const orderedMigrations = this.migrationsToRun.filter((migration) => !runMigrations.includes(migration.index)).sort((migration) => migration.index);
54
+ const orderedMigrations = _.uniqBy(this.migrationsToRun
55
+ .filter((migration) => !runMigrations.includes(migration.index))
56
+ .sort((a, b) => a.index - b.index), 'index');
54
57
  for (const migration of orderedMigrations) {
55
58
  const result = await migration.execute();
56
59
  if (!result.success) {
57
- return result;
60
+ throw result.error;
58
61
  }
59
62
  }
60
63
  return { success: true, error: null };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
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": {
@@ -1,5 +0,0 @@
1
- import { Client } from "pg";
2
- export declare function runTestMigrations(client: Client, _orgId?: string): Promise<{
3
- success: boolean;
4
- error: Error | null;
5
- }>;
@@ -1,21 +0,0 @@
1
- import { CreateTestEntitiesTableMigration } from "./001-create-test-entities-table.migration.js";
2
- import { CreateCategoriesTableMigration } from "./002-create-categories-table.migration.js";
3
- import { CreateProductsTableMigration } from "./003-create-products-table.migration.js";
4
- import { CreateTestItemsTableMigration } from "./005-create-test-items-table.migration.js";
5
- export async function runTestMigrations(client, _orgId) {
6
- const migrations = [
7
- new CreateTestEntitiesTableMigration(client),
8
- new CreateCategoriesTableMigration(client),
9
- new CreateProductsTableMigration(client),
10
- new CreateTestItemsTableMigration(client),
11
- ];
12
- try {
13
- for (const migration of migrations) {
14
- await migration.execute(_orgId);
15
- }
16
- }
17
- catch (error) {
18
- return { success: false, error: error };
19
- }
20
- return { success: true, error: null };
21
- }
@@ -1,8 +0,0 @@
1
- import { Client } from "pg";
2
- export declare function setupDatabaseForAuth(client: Client): Promise<{
3
- success: boolean;
4
- error: Error;
5
- } | {
6
- success: boolean;
7
- error: null;
8
- }>;
@@ -1,96 +0,0 @@
1
- import { CreateRefreshTokenTableMigration } from "./004-create-refresh-tokens-table.migration.js";
2
- import { CreateMigrationTableMigration } from "./001-create-migrations-table.migration.js";
3
- import { CreateUsersTableMigration } from "./003-create-users-table.migration.js";
4
- import { doesTableExist } from "../utils/does-table-exist.util.js";
5
- import { CreateAdminUserMigration } from "./006-create-admin-user.migration.js";
6
- import { CreateUserRolesTableMigration } from "./008-create-user-roles-table.migration.js";
7
- import { CreateRoleTableMigration } from "./007-create-roles-table.migration.js";
8
- import { CreateAuthorizationsTableMigration } from "./010-create-authorizations-table.migration.js";
9
- import { CreateFeaturesTableMigration } from "./009-create-features-table.migration.js";
10
- import { CreateAdminAuthorizationMigration } from "./011-create-admin-authorization.migration.js";
11
- export async function setupDatabaseForAuth(client) {
12
- let runMigrations = [];
13
- if (await doesTableExist(client, 'migrations')) {
14
- const migrations = await client.query(`
15
- SELECT "_id", "index"
16
- FROM migrations
17
- WHERE "hasRun" = TRUE AND "reverted" = FALSE
18
- `);
19
- runMigrations = migrations.rows.map((row) => {
20
- return row.index;
21
- });
22
- }
23
- if (!runMigrations.includes(1)) {
24
- const migration = new CreateMigrationTableMigration(client);
25
- const result = await migration.execute();
26
- if (!result.success) {
27
- console.error('setupDatabaseForAuth: error creating migrations table', result.error);
28
- return result;
29
- }
30
- }
31
- if (!runMigrations.includes(3)) {
32
- const migration = new CreateUsersTableMigration(client);
33
- const result = await migration.execute();
34
- if (!result.success) {
35
- console.error('setupDatabaseForAuth: error creating users table', result.error);
36
- return result;
37
- }
38
- }
39
- if (!runMigrations.includes(4)) {
40
- const migration = new CreateRefreshTokenTableMigration(client);
41
- const result = await migration.execute();
42
- if (!result.success) {
43
- console.error('setupDatabaseForAuth: error creating refresh_tokens table', result.error);
44
- return result;
45
- }
46
- }
47
- if (!runMigrations.includes(6)) {
48
- const migration = new CreateAdminUserMigration(client);
49
- const result = await migration.execute();
50
- if (!result.success) {
51
- console.error('setupDatabaseForAuth: error creating admin user', result.error);
52
- return result;
53
- }
54
- }
55
- if (!runMigrations.includes(7)) {
56
- const migration = new CreateRoleTableMigration(client);
57
- const result = await migration.execute();
58
- if (!result.success) {
59
- console.error('setupDatabaseForAuth: error creating roles table', result.error);
60
- return result;
61
- }
62
- }
63
- if (!runMigrations.includes(8)) {
64
- const migration = new CreateUserRolesTableMigration(client);
65
- const result = await migration.execute();
66
- if (!result.success) {
67
- console.error('setupDatabaseForAuth: error creating user_roles table', result.error);
68
- return result;
69
- }
70
- }
71
- if (!runMigrations.includes(9)) {
72
- const migration = new CreateFeaturesTableMigration(client);
73
- const result = await migration.execute();
74
- if (!result.success) {
75
- console.error('setupDatabaseForAuth: error creating features table', result.error);
76
- return result;
77
- }
78
- }
79
- if (!runMigrations.includes(10)) {
80
- const migration = new CreateAuthorizationsTableMigration(client);
81
- const result = await migration.execute();
82
- if (!result.success) {
83
- console.error('setupDatabaseForAuth: error creating authorizations table', result.error);
84
- return result;
85
- }
86
- }
87
- if (!runMigrations.includes(11)) {
88
- const migration = new CreateAdminAuthorizationMigration(client);
89
- const result = await migration.execute();
90
- if (!result.success) {
91
- console.error('setupDatabaseForAuth: error creating admin authorization', result.error);
92
- return result;
93
- }
94
- }
95
- return { success: true, error: null };
96
- }
@@ -1,8 +0,0 @@
1
- import { Client } from "pg";
2
- export declare function setupDatabaseForMultitenant(client: Client): Promise<{
3
- success: boolean;
4
- error: Error;
5
- } | {
6
- success: boolean;
7
- error: null;
8
- }>;
@@ -1,42 +0,0 @@
1
- import { CreateMigrationTableMigration } from "./001-create-migrations-table.migration.js";
2
- import { CreateOrganizationsTableMigration } from "./002-create-organizations-table.migration.js";
3
- import { doesTableExist } from "../utils/does-table-exist.util.js";
4
- import { CreateMetaOrgMigration } from "./005-create-meta-org.migration.js";
5
- export async function setupDatabaseForMultitenant(client) {
6
- let runMigrations = [];
7
- if (await doesTableExist(client, 'migrations')) {
8
- const migrations = await client.query(`
9
- SELECT "_id", "index"
10
- FROM migrations
11
- WHERE "hasRun" = TRUE AND "reverted" = FALSE
12
- `);
13
- runMigrations = migrations.rows.map((row) => {
14
- return row.index;
15
- });
16
- }
17
- if (!runMigrations.includes(1)) {
18
- const createMigrationTableMigration = new CreateMigrationTableMigration(client);
19
- const result = await createMigrationTableMigration.execute();
20
- if (!result.success) {
21
- console.log('setupDatabaseForMultitenant: error creating migration table', result.error);
22
- return result;
23
- }
24
- }
25
- if (!runMigrations.includes(2)) {
26
- const createOrganizationTableMigration = new CreateOrganizationsTableMigration(client);
27
- const result = await createOrganizationTableMigration.execute();
28
- if (!result.success) {
29
- console.log('setupDatabaseForMultitenant: error creating organizations table', result.error);
30
- return result;
31
- }
32
- }
33
- if (!runMigrations.includes(5)) {
34
- const createMetaOrgMigration = new CreateMetaOrgMigration(client);
35
- const result = await createMetaOrgMigration.execute();
36
- if (!result.success) {
37
- console.log('setupDatabaseForMultitenant: error creating meta org', result.error);
38
- return result;
39
- }
40
- }
41
- return { success: true, error: null };
42
- }