@loomcore/api 0.1.6 → 0.1.8

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 (27) hide show
  1. package/dist/__tests__/postgres-test-migrations/001-create-test-entities-table.migration.d.ts +15 -5
  2. package/dist/__tests__/postgres-test-migrations/001-create-test-entities-table.migration.js +32 -18
  3. package/dist/__tests__/postgres-test-migrations/002-create-categories-table.migration.d.ts +15 -5
  4. package/dist/__tests__/postgres-test-migrations/002-create-categories-table.migration.js +30 -19
  5. package/dist/__tests__/postgres-test-migrations/003-create-products-table.migration.d.ts +15 -5
  6. package/dist/__tests__/postgres-test-migrations/003-create-products-table.migration.js +30 -20
  7. package/dist/__tests__/postgres-test-migrations/004-create-test-users-table.migration.d.ts +15 -5
  8. package/dist/__tests__/postgres-test-migrations/004-create-test-users-table.migration.js +30 -20
  9. package/dist/__tests__/postgres-test-migrations/005-create-test-items-table.migration.d.ts +15 -5
  10. package/dist/__tests__/postgres-test-migrations/005-create-test-items-table.migration.js +34 -13
  11. package/dist/__tests__/postgres-test-migrations/run-test-migrations.d.ts +4 -1
  12. package/dist/__tests__/postgres-test-migrations/run-test-migrations.js +13 -12
  13. package/dist/__tests__/postgres.test-database.js +1 -1
  14. package/dist/databases/postgres/migrations/001-create-migrations-table.migration.d.ts +15 -5
  15. package/dist/databases/postgres/migrations/001-create-migrations-table.migration.js +24 -18
  16. package/dist/databases/postgres/migrations/002-create-organizations-table.migration.d.ts +17 -5
  17. package/dist/databases/postgres/migrations/002-create-organizations-table.migration.js +40 -14
  18. package/dist/databases/postgres/migrations/003-create-users-table.migration.d.ts +15 -5
  19. package/dist/databases/postgres/migrations/003-create-users-table.migration.js +37 -19
  20. package/dist/databases/postgres/migrations/004-create-refresh-token-table.migration.d.ts +16 -6
  21. package/dist/databases/postgres/migrations/004-create-refresh-token-table.migration.js +49 -31
  22. package/dist/databases/postgres/migrations/migration.interface.d.ts +9 -4
  23. package/dist/databases/postgres/migrations/setup-for-auth.migration.d.ts +4 -1
  24. package/dist/databases/postgres/migrations/setup-for-auth.migration.js +11 -10
  25. package/dist/databases/postgres/migrations/setup-for-multitenant.migration.d.ts +4 -1
  26. package/dist/databases/postgres/migrations/setup-for-multitenant.migration.js +10 -9
  27. package/package.json +1 -1
@@ -2,10 +2,20 @@ import { Client } from "pg";
2
2
  import { IMigration } from "../../databases/postgres/migrations/migration.interface.js";
3
3
  export declare class CreateTestEntitiesTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: Error;
10
+ } | {
11
+ success: boolean;
12
+ error: null;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,14 +1,12 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateTestEntitiesTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 1;
10
- _id = randomUUID().toString();
11
- async execute() {
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
12
10
  try {
13
11
  await this.client.query(`
14
12
  CREATE TABLE "testEntities" (
@@ -27,33 +25,49 @@ export class CreateTestEntitiesTableMigration {
27
25
  "_deletedBy" VARCHAR(255)
28
26
  )
29
27
  `);
30
- if (this.orgId) {
28
+ }
29
+ catch (error) {
30
+ return { success: false, error: new Error(`Error creating test entities table: ${error.message}`) };
31
+ }
32
+ if (_orgId) {
33
+ try {
31
34
  await this.client.query(`
32
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
35
+ Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
33
36
  `);
34
37
  }
35
- else {
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 {
36
44
  await this.client.query(`
37
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${this._id}', ${this.index}, TRUE, FALSE);
45
+ Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
38
46
  `);
39
47
  }
40
- return true;
41
- }
42
- catch (error) {
43
- console.error('Error creating test entities table:', error);
44
- return false;
48
+ catch (error) {
49
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
50
+ }
45
51
  }
52
+ return { success: true, error: null };
46
53
  }
47
- async revert() {
54
+ async revert(_orgId) {
48
55
  try {
49
56
  await this.client.query(`
50
57
  DROP TABLE test_entities;
51
58
  `);
52
59
  }
53
60
  catch (error) {
54
- console.error('Error reverting test entities table:', error);
55
- return false;
61
+ return { success: false, error: new Error(`Error dropping test entities table: ${error.message}`) };
62
+ }
63
+ try {
64
+ await this.client.query(`
65
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
66
+ `);
67
+ }
68
+ catch (error) {
69
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
56
70
  }
57
- return true;
71
+ return { success: true, error: null };
58
72
  }
59
73
  }
@@ -2,10 +2,20 @@ import { IMigration } from "../../databases/postgres/migrations/index.js";
2
2
  import { Client } from "pg";
3
3
  export declare class CreateCategoriesTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: Error;
10
+ } | {
11
+ success: boolean;
12
+ error: null;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,14 +1,12 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateCategoriesTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 2;
10
- _id = randomUUID().toString();
11
- async execute() {
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
12
10
  try {
13
11
  await this.client.query(`
14
12
  CREATE TABLE "categories" (
@@ -17,36 +15,49 @@ export class CreateCategoriesTableMigration {
17
15
  "name" VARCHAR(255) NOT NULL
18
16
  )
19
17
  `);
20
- if (this.orgId) {
18
+ }
19
+ catch (error) {
20
+ return { success: false, error: new Error(`Error creating categories table: ${error.message}`) };
21
+ }
22
+ if (_orgId) {
23
+ try {
21
24
  await this.client.query(`
22
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
25
+ Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
23
26
  `);
24
27
  }
25
- else {
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 {
26
34
  await this.client.query(`
27
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${this._id}', ${this.index}, TRUE, FALSE);
35
+ Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
28
36
  `);
29
37
  }
30
- return true;
31
- }
32
- catch (error) {
33
- console.error('Error creating categories table:', error);
34
- return false;
38
+ catch (error) {
39
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
40
+ }
35
41
  }
42
+ return { success: true, error: null };
36
43
  }
37
- async revert() {
44
+ async revert(_orgId) {
38
45
  try {
39
46
  await this.client.query(`
40
47
  DROP TABLE "categories";
41
48
  `);
49
+ }
50
+ catch (error) {
51
+ return { success: false, error: new Error(`Error dropping categories table: ${error.message}`) };
52
+ }
53
+ try {
42
54
  await this.client.query(`
43
- Update "migrations" SET "reverted" = TRUE WHERE "_id" = '${this._id}';
55
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
44
56
  `);
45
57
  }
46
58
  catch (error) {
47
- console.error('Error reverting categories table:', error);
48
- return false;
59
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
49
60
  }
50
- return true;
61
+ return { success: true, error: null };
51
62
  }
52
63
  }
@@ -2,10 +2,20 @@ import { Client } from "pg";
2
2
  import { IMigration } from "../../databases/postgres/migrations/index.js";
3
3
  export declare class CreateProductsTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: Error;
10
+ } | {
11
+ success: boolean;
12
+ error: null;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,14 +1,12 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateProductsTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 3;
10
- _id = randomUUID().toString();
11
- async execute() {
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
12
10
  try {
13
11
  await this.client.query(`
14
12
  CREATE TABLE "products" (
@@ -26,37 +24,49 @@ export class CreateProductsTableMigration {
26
24
  "_deletedBy" VARCHAR(255)
27
25
  )
28
26
  `);
29
- if (this.orgId) {
27
+ }
28
+ catch (error) {
29
+ return { success: false, error: new Error(`Error creating products table: ${error.message}`) };
30
+ }
31
+ if (_orgId) {
32
+ try {
30
33
  await this.client.query(`
31
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
34
+ Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
32
35
  `);
33
36
  }
34
- else {
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 {
35
43
  await this.client.query(`
36
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${this._id}', ${this.index}, TRUE, FALSE);
44
+ Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
37
45
  `);
38
46
  }
39
- return true;
40
- }
41
- catch (error) {
42
- console.error('Error creating products table:', error);
43
- return false;
47
+ catch (error) {
48
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
49
+ }
44
50
  }
45
- return true;
51
+ return { success: true, error: null };
46
52
  }
47
- async revert() {
53
+ async revert(_orgId) {
48
54
  try {
49
55
  await this.client.query(`
50
56
  DROP TABLE "products";
51
57
  `);
58
+ }
59
+ catch (error) {
60
+ return { success: false, error: new Error(`Error dropping products table: ${error.message}`) };
61
+ }
62
+ try {
52
63
  await this.client.query(`
53
- Update "migrations" SET "reverted" = TRUE WHERE "_id" = '${this._id}';
64
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
54
65
  `);
55
66
  }
56
67
  catch (error) {
57
- console.error('Error reverting products table:', error);
58
- return false;
68
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
59
69
  }
60
- return true;
70
+ return { success: true, error: null };
61
71
  }
62
72
  }
@@ -2,10 +2,20 @@ import { Client } from "pg";
2
2
  import { IMigration } from "../../databases/postgres/migrations/index.js";
3
3
  export declare class CreateTestUsersTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: Error;
10
+ } | {
11
+ success: boolean;
12
+ error: null;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,14 +1,12 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateTestUsersTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 4;
10
- _id = randomUUID().toString();
11
- async execute() {
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
12
10
  try {
13
11
  await this.client.query(`
14
12
  CREATE TABLE "testUsers" (
@@ -30,37 +28,49 @@ export class CreateTestUsersTableMigration {
30
28
  "_deletedBy" VARCHAR(255)
31
29
  )
32
30
  `);
33
- if (this.orgId) {
31
+ }
32
+ catch (error) {
33
+ return { success: false, error: new Error(`Error creating test users table: ${error.message}`) };
34
+ }
35
+ if (_orgId) {
36
+ try {
34
37
  await this.client.query(`
35
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
38
+ Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
36
39
  `);
37
40
  }
38
- else {
41
+ catch (error) {
42
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
43
+ }
44
+ }
45
+ else {
46
+ try {
39
47
  await this.client.query(`
40
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${this._id}', ${this.index}, TRUE, FALSE);
48
+ Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
41
49
  `);
42
50
  }
43
- return true;
44
- }
45
- catch (error) {
46
- console.error('Error creating test users table:', error);
47
- return false;
51
+ catch (error) {
52
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
53
+ }
48
54
  }
49
- return true;
55
+ return { success: true, error: null };
50
56
  }
51
- async revert() {
57
+ async revert(_orgId) {
52
58
  try {
53
59
  await this.client.query(`
54
60
  DROP TABLE "testUsers";
55
61
  `);
56
62
  }
57
63
  catch (error) {
64
+ return { success: false, error: new Error(`Error dropping test users table: ${error.message}`) };
65
+ }
66
+ try {
58
67
  await this.client.query(`
59
- Update "migrations" SET "reverted" = TRUE WHERE "_id" = '${this._id}';
68
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
60
69
  `);
61
- console.error('Error reverting test users table:', error);
62
- return false;
63
70
  }
64
- return true;
71
+ catch (error) {
72
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
73
+ }
74
+ return { success: true, error: null };
65
75
  }
66
76
  }
@@ -2,10 +2,20 @@ import { Client } from "pg";
2
2
  import { IMigration } from "../../databases/postgres/migrations/index.js";
3
3
  export declare class CreateTestItemsTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: Error;
10
+ } | {
11
+ success: boolean;
12
+ error: null;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,14 +1,12 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateTestItemsTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 5;
10
- _id = randomUUID().toString();
11
- async execute() {
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
12
10
  try {
13
11
  await this.client.query(`
14
12
  CREATE TABLE "testItems" (
@@ -27,24 +25,47 @@ export class CreateTestItemsTableMigration {
27
25
  `);
28
26
  }
29
27
  catch (error) {
30
- console.error('Error creating test items table:', error);
31
- return false;
28
+ return { success: false, error: new Error(`Error creating test items table: ${error.message}`) };
32
29
  }
33
- return true;
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(`
43
+ Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
44
+ `);
45
+ }
46
+ catch (error) {
47
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
48
+ }
49
+ }
50
+ return { success: true, error: null };
34
51
  }
35
- async revert() {
52
+ async revert(_orgId) {
36
53
  try {
37
54
  await this.client.query(`
38
55
  DROP TABLE "testItems";
39
56
  `);
40
57
  }
41
58
  catch (error) {
59
+ return { success: false, error: new Error(`Error dropping test items table: ${error.message}`) };
60
+ }
61
+ try {
42
62
  await this.client.query(`
43
- Update "migrations" SET "reverted" = TRUE WHERE "_id" = '${this._id}';
63
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
44
64
  `);
45
- console.error('Error reverting test items table:', error);
46
- return false;
47
65
  }
48
- return true;
66
+ catch (error) {
67
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
68
+ }
69
+ return { success: true, error: null };
49
70
  }
50
71
  }
@@ -1,2 +1,5 @@
1
1
  import { Client } from "pg";
2
- export declare function runTestMigrations(client: Client, orgId?: string): Promise<boolean>;
2
+ export declare function runTestMigrations(client: Client, _orgId?: string): Promise<{
3
+ success: boolean;
4
+ error: Error | null;
5
+ }>;
@@ -3,20 +3,21 @@ import { CreateCategoriesTableMigration } from "./002-create-categories-table.mi
3
3
  import { CreateProductsTableMigration } from "./003-create-products-table.migration.js";
4
4
  import { CreateTestUsersTableMigration } from "./004-create-test-users-table.migration.js";
5
5
  import { CreateTestItemsTableMigration } from "./005-create-test-items-table.migration.js";
6
- export async function runTestMigrations(client, orgId) {
6
+ export async function runTestMigrations(client, _orgId) {
7
7
  const migrations = [
8
- new CreateTestEntitiesTableMigration(client, orgId),
9
- new CreateCategoriesTableMigration(client, orgId),
10
- new CreateProductsTableMigration(client, orgId),
11
- new CreateTestUsersTableMigration(client, orgId),
12
- new CreateTestItemsTableMigration(client, orgId),
8
+ new CreateTestEntitiesTableMigration(client),
9
+ new CreateCategoriesTableMigration(client),
10
+ new CreateProductsTableMigration(client),
11
+ new CreateTestUsersTableMigration(client),
12
+ new CreateTestItemsTableMigration(client),
13
13
  ];
14
- let success = true;
15
- for (const migration of migrations) {
16
- success = await migration.execute();
17
- if (!success) {
18
- return false;
14
+ try {
15
+ for (const migration of migrations) {
16
+ await migration.execute(_orgId);
19
17
  }
20
18
  }
21
- return success;
19
+ catch (error) {
20
+ return { success: false, error: error };
21
+ }
22
+ return { success: true, error: null };
22
23
  }
@@ -29,7 +29,7 @@ export class TestPostgresDatabase {
29
29
  const testDatabase = new PostgresDatabase(postgresClient);
30
30
  this.database = testDatabase;
31
31
  this.postgresClient = postgresClient;
32
- let success = await setupDatabaseForMultitenant(postgresClient, testOrg._id);
32
+ let success = await setupDatabaseForMultitenant(postgresClient, 'Test Org', 'test-org');
33
33
  if (!success) {
34
34
  throw new Error('Failed to setup for multitenant');
35
35
  }
@@ -2,10 +2,20 @@ import { Client } from "pg";
2
2
  import { IMigration } from "./migration.interface.js";
3
3
  export declare class CreateMigrationTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: null;
10
+ } | {
11
+ success: boolean;
12
+ error: Error;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,15 +1,12 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  export class CreateMigrationTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 1;
10
- _id = randomUUID().toString();
11
- async execute() {
12
- let alreadyRun = false;
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
13
10
  try {
14
11
  await this.client.query(`
15
12
  CREATE TABLE "migrations" (
@@ -22,31 +19,40 @@ export class CreateMigrationTableMigration {
22
19
  `);
23
20
  }
24
21
  catch (error) {
25
- if (error.data.error.includes('already exists')) {
26
- alreadyRun = true;
22
+ if (error.code === '42P07' || error.data?.error?.includes('already exists')) {
23
+ return { success: true, error: null };
27
24
  }
28
25
  else {
29
- throw error;
26
+ return { success: false, error: new Error(`Error creating migrations table: ${error.message}`) };
30
27
  }
31
28
  }
32
- if (!alreadyRun) {
33
- if (this.orgId) {
29
+ try {
30
+ if (_orgId) {
34
31
  await this.client.query(`
35
- INSERT INTO "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") VALUES ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
36
- `);
32
+ INSERT INTO "migrations" ("_id", "_orgId", "index", "hasRun", "reverted")
33
+ VALUES ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);`);
37
34
  }
38
35
  else {
39
36
  await this.client.query(`
40
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted") VALUES ('${this._id}', ${this.index}, TRUE, FALSE);
37
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
38
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
41
39
  `);
42
40
  }
43
41
  }
44
- return true;
42
+ catch (error) {
43
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
44
+ }
45
+ return { success: true, error: null };
45
46
  }
46
- async revert() {
47
- await this.client.query(`
47
+ async revert(_orgId) {
48
+ try {
49
+ await this.client.query(`
48
50
  DROP TABLE "migrations";
49
51
  `);
50
- return true;
52
+ }
53
+ catch (error) {
54
+ return { success: false, error: new Error(`Error reverting migration ${this.index} from migrations table: ${error.message}`) };
55
+ }
56
+ return { success: true, error: null };
51
57
  }
52
58
  }
@@ -2,10 +2,22 @@ import { Client } from "pg";
2
2
  import { IMigration } from "./migration.interface.js";
3
3
  export declare class CreateOrganizationTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId;
6
- constructor(client: Client, orgId: string);
5
+ private readonly orgName;
6
+ private readonly orgCode;
7
+ constructor(client: Client, orgName: string, orgCode: string);
7
8
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
9
+ execute(_orgId?: string): Promise<{
10
+ success: boolean;
11
+ error: null;
12
+ } | {
13
+ success: boolean;
14
+ error: Error;
15
+ }>;
16
+ revert(_orgId?: string): Promise<{
17
+ success: boolean;
18
+ error: Error;
19
+ } | {
20
+ success: boolean;
21
+ error: null;
22
+ }>;
11
23
  }
@@ -1,14 +1,17 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateOrganizationTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ orgName;
5
+ orgCode;
6
+ constructor(client, orgName, orgCode) {
6
7
  this.client = client;
7
- this.orgId = orgId;
8
+ this.orgName = orgName;
9
+ this.orgCode = orgCode;
8
10
  }
9
11
  index = 2;
10
- _id = randomUUID().toString();
11
- async execute() {
12
+ async execute(_orgId) {
13
+ const _id = randomUUID().toString();
14
+ const _orgIdToUse = _orgId || randomUUID().toString();
12
15
  try {
13
16
  await this.client.query(`
14
17
  CREATE TABLE "organizations" (
@@ -27,29 +30,52 @@ export class CreateOrganizationTableMigration {
27
30
  "_deletedBy" VARCHAR(255)
28
31
  )
29
32
  `);
33
+ }
34
+ catch (error) {
35
+ if (error.code === '42P07' || error.data?.error?.includes('already exists')) {
36
+ return { success: true, error: null };
37
+ }
38
+ else {
39
+ return { success: false, error: new Error(`Error creating organization table: ${error.message}`) };
40
+ }
41
+ }
42
+ try {
43
+ await this.client.query(`
44
+ INSERT INTO "organizations" ("_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
45
+ VALUES ('${_orgIdToUse}', '${this.orgName}', '${this.orgCode}', 1, true, NOW(), 'system', NOW(), 'system');
46
+ `);
47
+ }
48
+ catch (error) {
49
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
50
+ }
51
+ try {
30
52
  await this.client.query(`
31
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
53
+ INSERT INTO "migrations" ("_id", "_orgId", "index", "hasRun", "reverted")
54
+ VALUES ('${_id}', '${_orgIdToUse}', ${this.index}, TRUE, FALSE);
32
55
  `);
33
- return true;
34
56
  }
35
57
  catch (error) {
36
- console.error('Error creating organization table:', error);
37
- return false;
58
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
38
59
  }
60
+ return { success: true, error: null };
39
61
  }
40
- async revert() {
62
+ async revert(_orgId) {
41
63
  try {
42
64
  await this.client.query(`
43
65
  DROP TABLE "organizations";
44
66
  `);
67
+ }
68
+ catch (error) {
69
+ return { success: false, error: new Error(`Error dropping organizations table: ${error.message}`) };
70
+ }
71
+ try {
45
72
  await this.client.query(`
46
- Update "migrations" SET "reverted" = TRUE WHERE "_id" = '${this._id}';
73
+ Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
47
74
  `);
48
75
  }
49
76
  catch (error) {
50
- console.error('Error reverting organization table:', error);
51
- return false;
77
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
52
78
  }
53
- return true;
79
+ return { success: true, error: null };
54
80
  }
55
81
  }
@@ -2,10 +2,20 @@ import { Client } from "pg";
2
2
  import { IMigration } from "./migration.interface.js";
3
3
  export declare class CreateUsersTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: null;
10
+ } | {
11
+ success: boolean;
12
+ error: Error;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,14 +1,12 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateUsersTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 3;
10
- _id = randomUUID().toString();
11
- async execute() {
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
12
10
  try {
13
11
  await this.client.query(`
14
12
  CREATE TABLE "users" (
@@ -30,36 +28,56 @@ export class CreateUsersTableMigration {
30
28
  "_deletedBy" VARCHAR(255)
31
29
  )
32
30
  `);
33
- if (this.orgId) {
34
- await this.client.query(`
35
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
36
- `);
31
+ }
32
+ catch (error) {
33
+ if (error.code === '42P07' || error.data?.error?.includes('already exists')) {
34
+ return { success: true, error: null };
37
35
  }
38
36
  else {
37
+ return { success: false, error: new Error(`Error creating users table: ${error.message}`) };
38
+ }
39
+ }
40
+ if (_orgId) {
41
+ try {
39
42
  await this.client.query(`
40
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${this._id}', ${this.index}, TRUE, FALSE);
43
+ INSERT INTO "migrations" ("_id", "_orgId", "index", "hasRun", "reverted")
44
+ VALUES ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
41
45
  `);
42
46
  }
47
+ catch (error) {
48
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
49
+ }
43
50
  }
44
- catch (error) {
45
- console.error('Error creating users table:', error);
46
- return false;
51
+ else {
52
+ try {
53
+ await this.client.query(`
54
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
55
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
56
+ `);
57
+ }
58
+ catch (error) {
59
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
60
+ }
47
61
  }
48
- return true;
62
+ return { success: true, error: null };
49
63
  }
50
- async revert() {
64
+ async revert(_orgId) {
51
65
  try {
52
66
  await this.client.query(`
53
67
  DROP TABLE "users";
54
68
  `);
69
+ }
70
+ catch (error) {
71
+ return { success: false, error: new Error(`Error dropping users table: ${error.message}`) };
72
+ }
73
+ try {
55
74
  await this.client.query(`
56
- Update "migrations" SET "reverted" = TRUE WHERE "_id" = '${this._id}';
75
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
57
76
  `);
58
77
  }
59
78
  catch (error) {
60
- console.error('Error reverting users table:', error);
61
- return false;
79
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
62
80
  }
63
- return true;
81
+ return { success: true, error: null };
64
82
  }
65
83
  }
@@ -1,11 +1,21 @@
1
1
  import { Client } from "pg";
2
- import { IMigration } from "./index.js";
2
+ import { IMigration } from "./migration.interface.js";
3
3
  export declare class CreateRefreshTokenTableMigration implements IMigration {
4
4
  private readonly client;
5
- private readonly orgId?;
6
- constructor(client: Client, orgId?: string | undefined);
5
+ constructor(client: Client);
7
6
  index: number;
8
- _id: string;
9
- execute(): Promise<boolean>;
10
- revert(): Promise<boolean>;
7
+ execute(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: null;
10
+ } | {
11
+ success: boolean;
12
+ error: Error;
13
+ }>;
14
+ revert(_orgId?: string): Promise<{
15
+ success: boolean;
16
+ error: Error;
17
+ } | {
18
+ success: boolean;
19
+ error: null;
20
+ }>;
11
21
  }
@@ -1,57 +1,75 @@
1
1
  import { randomUUID } from "crypto";
2
2
  export class CreateRefreshTokenTableMigration {
3
3
  client;
4
- orgId;
5
- constructor(client, orgId) {
4
+ constructor(client) {
6
5
  this.client = client;
7
- this.orgId = orgId;
8
6
  }
9
7
  index = 4;
10
- _id = randomUUID().toString();
11
- async execute() {
8
+ async execute(_orgId) {
9
+ const _id = randomUUID().toString();
12
10
  try {
13
11
  await this.client.query(`
14
- CREATE TABLE "refreshTokens" (
15
- "_id" VARCHAR(255) PRIMARY KEY,
16
- "_orgId" VARCHAR(255),
17
- "token" VARCHAR(255) NOT NULL,
18
- "deviceId" VARCHAR(255) NOT NULL,
19
- "userId" VARCHAR(255) NOT NULL,
20
- "expiresOn" BIGINT NOT NULL,
21
- "created" TIMESTAMP NOT NULL,
22
- "createdBy" VARCHAR(255) NOT NULL
23
- )
24
- `);
25
- if (this.orgId) {
26
- await this.client.query(`
27
- Insert into "migrations" ("_id", "_orgId", "index", "hasRun", "reverted") values ('${this._id}', '${this.orgId}', ${this.index}, TRUE, FALSE);
28
- `);
12
+ CREATE TABLE "refreshTokens" (
13
+ "_id" VARCHAR(255) PRIMARY KEY,
14
+ "_orgId" VARCHAR(255),
15
+ "token" VARCHAR(255) NOT NULL,
16
+ "deviceId" VARCHAR(255) NOT NULL,
17
+ "userId" VARCHAR(255) NOT NULL,
18
+ "expiresOn" BIGINT NOT NULL,
19
+ "created" TIMESTAMP NOT NULL,
20
+ "createdBy" VARCHAR(255) NOT NULL
21
+ )
22
+ `);
23
+ }
24
+ catch (error) {
25
+ if (error.code === '42P07' || error.data?.error?.includes('already exists')) {
26
+ return { success: true, error: null };
29
27
  }
30
28
  else {
29
+ return { success: false, error: new Error(`Error creating refresh token table: ${error.message}`) };
30
+ }
31
+ }
32
+ if (_orgId) {
33
+ try {
31
34
  await this.client.query(`
32
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${this._id}', ${this.index}, TRUE, FALSE);
35
+ INSERT INTO "migrations" ("_id", "_orgId", "index", "hasRun", "reverted")
36
+ VALUES ('${_id}', '${_orgId}', ${this.index}, TRUE, FALSE);
33
37
  `);
34
38
  }
35
- return true;
39
+ catch (error) {
40
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
41
+ }
36
42
  }
37
- catch (error) {
38
- console.error('Error creating refresh token table:', error);
39
- return false;
43
+ else {
44
+ try {
45
+ await this.client.query(`
46
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
47
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
48
+ `);
49
+ }
50
+ catch (error) {
51
+ return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
52
+ }
40
53
  }
54
+ return { success: true, error: null };
41
55
  }
42
- async revert() {
56
+ async revert(_orgId) {
43
57
  try {
44
58
  await this.client.query(`
45
- DROP TABLE "refresh_tokens";
59
+ DROP TABLE "refreshTokens";
46
60
  `);
61
+ }
62
+ catch (error) {
63
+ return { success: false, error: new Error(`Error dropping refresh token table: ${error.message}`) };
64
+ }
65
+ try {
47
66
  await this.client.query(`
48
- Update "migrations" SET "reverted" = TRUE WHERE "_id" = '${this._id}';
67
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}' AND "_orgId" = '${_orgId}';
49
68
  `);
50
- return true;
51
69
  }
52
70
  catch (error) {
53
- console.error('Error reverting refresh token table:', error);
54
- return false;
71
+ return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
55
72
  }
73
+ return { success: true, error: null };
56
74
  }
57
75
  }
@@ -1,6 +1,11 @@
1
- import { IEntity } from "@loomcore/common/models";
2
- export interface IMigration extends IEntity {
1
+ export interface IMigration {
3
2
  index: number;
4
- execute(): Promise<boolean>;
5
- revert(): Promise<boolean>;
3
+ execute(_orgId?: string): Promise<{
4
+ success: boolean;
5
+ error: Error | null;
6
+ }>;
7
+ revert(_orgId?: string): Promise<{
8
+ success: boolean;
9
+ error: Error | null;
10
+ }>;
6
11
  }
@@ -1,2 +1,5 @@
1
1
  import { Client } from "pg";
2
- export declare function setupDatabaseForAuth(client: Client, orgId?: string): Promise<boolean>;
2
+ export declare function setupDatabaseForAuth(client: Client, _orgId?: string): Promise<{
3
+ success: boolean;
4
+ error: Error | null;
5
+ }>;
@@ -1,18 +1,19 @@
1
1
  import { CreateRefreshTokenTableMigration } from "./004-create-refresh-token-table.migration.js";
2
2
  import { CreateMigrationTableMigration } from "./001-create-migrations-table.migration.js";
3
3
  import { CreateUsersTableMigration } from "./003-create-users-table.migration.js";
4
- export async function setupDatabaseForAuth(client, orgId) {
4
+ export async function setupDatabaseForAuth(client, _orgId) {
5
5
  const migrations = [
6
- new CreateMigrationTableMigration(client, orgId),
7
- new CreateUsersTableMigration(client, orgId),
8
- new CreateRefreshTokenTableMigration(client, orgId),
6
+ new CreateMigrationTableMigration(client),
7
+ new CreateUsersTableMigration(client),
8
+ new CreateRefreshTokenTableMigration(client),
9
9
  ];
10
- let success = true;
11
- for (const migration of migrations) {
12
- success = await migration.execute();
13
- if (!success) {
14
- return false;
10
+ try {
11
+ for (const migration of migrations) {
12
+ await migration.execute(_orgId);
15
13
  }
16
14
  }
17
- return success;
15
+ catch (error) {
16
+ return { success: false, error: error };
17
+ }
18
+ return { success: true, error: null };
18
19
  }
@@ -1,2 +1,5 @@
1
1
  import { Client } from "pg";
2
- export declare function setupDatabaseForMultitenant(client: Client, orgId: string): Promise<boolean>;
2
+ export declare function setupDatabaseForMultitenant(client: Client, orgName: string, orgCode: string): Promise<{
3
+ success: boolean;
4
+ error: Error | null;
5
+ }>;
@@ -1,16 +1,17 @@
1
1
  import { CreateMigrationTableMigration } from "./001-create-migrations-table.migration.js";
2
2
  import { CreateOrganizationTableMigration } from "./002-create-organizations-table.migration.js";
3
- export async function setupDatabaseForMultitenant(client, orgId) {
3
+ export async function setupDatabaseForMultitenant(client, orgName, orgCode) {
4
4
  const migrations = [
5
- new CreateMigrationTableMigration(client, orgId),
6
- new CreateOrganizationTableMigration(client, orgId),
5
+ new CreateMigrationTableMigration(client),
6
+ new CreateOrganizationTableMigration(client, orgName, orgCode),
7
7
  ];
8
- let success = true;
9
- for (const migration of migrations) {
10
- success = await migration.execute();
11
- if (!success) {
12
- return false;
8
+ try {
9
+ for (const migration of migrations) {
10
+ await migration.execute();
13
11
  }
14
12
  }
15
- return success;
13
+ catch (error) {
14
+ return { success: false, error: error };
15
+ }
16
+ return { success: true, error: null };
16
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
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": {