@loomcore/api 0.1.53 → 0.1.57

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 (96) hide show
  1. package/dist/__tests__/common-test.utils.d.ts +8 -2
  2. package/dist/__tests__/common-test.utils.js +50 -16
  3. package/dist/__tests__/index.d.ts +0 -1
  4. package/dist/__tests__/index.js +0 -1
  5. package/dist/__tests__/postgres-test-migrations/postgres-test-schema.d.ts +3 -0
  6. package/dist/__tests__/postgres-test-migrations/postgres-test-schema.js +97 -0
  7. package/dist/__tests__/postgres.test-database.js +9 -8
  8. package/dist/__tests__/setup/vitest-setup.js +15 -0
  9. package/dist/__tests__/test-objects.d.ts +6 -3
  10. package/dist/__tests__/test-objects.js +10 -2
  11. package/dist/controllers/api.controller.d.ts +2 -0
  12. package/dist/controllers/api.controller.js +66 -11
  13. package/dist/databases/migrations/migration-runner.js +6 -6
  14. package/dist/databases/models/database.interface.d.ts +9 -8
  15. package/dist/databases/mongo-db/commands/mongo-delete-by-id.command.d.ts +2 -1
  16. package/dist/databases/mongo-db/commands/mongo-full-updateby-id.command.d.ts +2 -1
  17. package/dist/databases/mongo-db/commands/mongo-partial-update-by-id.command.d.ts +2 -1
  18. package/dist/databases/mongo-db/migrations/{mongo-foundational.d.ts → mongo-initial-schema.d.ts} +1 -1
  19. package/dist/databases/mongo-db/migrations/mongo-initial-schema.js +264 -0
  20. package/dist/databases/mongo-db/mongo-db.database.d.ts +9 -8
  21. package/dist/databases/mongo-db/mongo-db.database.js +2 -2
  22. package/dist/databases/mongo-db/queries/mongo-get-by-id.query.d.ts +2 -1
  23. package/dist/databases/postgres/commands/postgres-batch-update.command.js +1 -1
  24. package/dist/databases/postgres/commands/postgres-create-many.command.d.ts +2 -1
  25. package/dist/databases/postgres/commands/postgres-create-many.command.js +23 -28
  26. package/dist/databases/postgres/commands/postgres-create.command.d.ts +2 -1
  27. package/dist/databases/postgres/commands/postgres-create.command.js +6 -5
  28. package/dist/databases/postgres/commands/postgres-delete-by-id.command.d.ts +2 -1
  29. package/dist/databases/postgres/commands/postgres-full-update-by-id.command.d.ts +2 -1
  30. package/dist/databases/postgres/commands/postgres-partial-update-by-id.command.d.ts +2 -1
  31. package/dist/databases/postgres/migrations/__tests__/test-migration-helper.d.ts +4 -0
  32. package/dist/databases/postgres/migrations/__tests__/test-migration-helper.js +67 -0
  33. package/dist/databases/postgres/migrations/index.d.ts +1 -2
  34. package/dist/databases/postgres/migrations/index.js +1 -2
  35. package/dist/databases/postgres/migrations/{postgres-foundational.d.ts → postgres-initial-schema.d.ts} +1 -1
  36. package/dist/databases/postgres/migrations/postgres-initial-schema.js +436 -0
  37. package/dist/databases/postgres/postgres.database.d.ts +10 -9
  38. package/dist/databases/postgres/postgres.database.js +2 -2
  39. package/dist/databases/postgres/queries/postgres-get-by-id.query.d.ts +2 -1
  40. package/dist/models/refresh-token.model.d.ts +5 -4
  41. package/dist/models/refresh-token.model.js +3 -3
  42. package/dist/services/auth.service.d.ts +3 -2
  43. package/dist/services/auth.service.js +4 -4
  44. package/dist/services/generic-api-service/generic-api-service.interface.d.ts +8 -7
  45. package/dist/services/generic-api-service/generic-api.service.d.ts +8 -7
  46. package/dist/services/generic-api-service/generic-api.service.js +23 -23
  47. package/dist/services/multi-tenant-api.service.d.ts +1 -1
  48. package/dist/services/multi-tenant-api.service.js +3 -3
  49. package/dist/services/organization.service.d.ts +4 -3
  50. package/dist/services/organization.service.js +3 -3
  51. package/dist/services/user.service.d.ts +3 -2
  52. package/dist/services/user.service.js +2 -2
  53. package/dist/services/utils/audit-for-create.util.js +2 -1
  54. package/dist/services/utils/audit-for-update.util.js +2 -1
  55. package/dist/services/utils/strip-sender-provided-system-properties.util.js +2 -1
  56. package/package.json +2 -2
  57. package/dist/__tests__/postgres-test-migrations/100-create-test-entities-table.migration.d.ts +0 -21
  58. package/dist/__tests__/postgres-test-migrations/100-create-test-entities-table.migration.js +0 -61
  59. package/dist/__tests__/postgres-test-migrations/101-create-categories-table.migration.d.ts +0 -21
  60. package/dist/__tests__/postgres-test-migrations/101-create-categories-table.migration.js +0 -51
  61. package/dist/__tests__/postgres-test-migrations/102-create-products-table.migration.d.ts +0 -21
  62. package/dist/__tests__/postgres-test-migrations/102-create-products-table.migration.js +0 -60
  63. package/dist/__tests__/postgres-test-migrations/103-create-test-items-table.migration.d.ts +0 -21
  64. package/dist/__tests__/postgres-test-migrations/103-create-test-items-table.migration.js +0 -59
  65. package/dist/__tests__/postgres-test-migrations/test-migrations.d.ts +0 -3
  66. package/dist/__tests__/postgres-test-migrations/test-migrations.js +0 -12
  67. package/dist/databases/mongo-db/migrations/mongo-foundational.js +0 -30
  68. package/dist/databases/postgres/migrations/001-create-migrations-table.migration.d.ts +0 -21
  69. package/dist/databases/postgres/migrations/001-create-migrations-table.migration.js +0 -51
  70. package/dist/databases/postgres/migrations/002-create-organizations-table.migration.d.ts +0 -21
  71. package/dist/databases/postgres/migrations/002-create-organizations-table.migration.js +0 -76
  72. package/dist/databases/postgres/migrations/003-create-users-table.migration.d.ts +0 -21
  73. package/dist/databases/postgres/migrations/003-create-users-table.migration.js +0 -77
  74. package/dist/databases/postgres/migrations/004-create-refresh-tokens-table.migration.d.ts +0 -21
  75. package/dist/databases/postgres/migrations/004-create-refresh-tokens-table.migration.js +0 -72
  76. package/dist/databases/postgres/migrations/005-create-meta-org.migration.d.ts +0 -22
  77. package/dist/databases/postgres/migrations/005-create-meta-org.migration.js +0 -64
  78. package/dist/databases/postgres/migrations/006-create-admin-user.migration.d.ts +0 -19
  79. package/dist/databases/postgres/migrations/006-create-admin-user.migration.js +0 -52
  80. package/dist/databases/postgres/migrations/007-create-roles-table.migration.d.ts +0 -21
  81. package/dist/databases/postgres/migrations/007-create-roles-table.migration.js +0 -65
  82. package/dist/databases/postgres/migrations/008-create-user-roles-table.migration.d.ts +0 -21
  83. package/dist/databases/postgres/migrations/008-create-user-roles-table.migration.js +0 -75
  84. package/dist/databases/postgres/migrations/009-create-features-table.migration.d.ts +0 -21
  85. package/dist/databases/postgres/migrations/009-create-features-table.migration.js +0 -65
  86. package/dist/databases/postgres/migrations/010-create-authorizations-table.migration.d.ts +0 -21
  87. package/dist/databases/postgres/migrations/010-create-authorizations-table.migration.js +0 -77
  88. package/dist/databases/postgres/migrations/011-create-admin-authorization.migration.d.ts +0 -23
  89. package/dist/databases/postgres/migrations/011-create-admin-authorization.migration.js +0 -130
  90. package/dist/databases/postgres/migrations/database-builder.d.ts +0 -15
  91. package/dist/databases/postgres/migrations/database-builder.interface.d.ts +0 -10
  92. package/dist/databases/postgres/migrations/database-builder.js +0 -65
  93. package/dist/databases/postgres/migrations/migration.interface.d.ts +0 -11
  94. package/dist/databases/postgres/migrations/migration.interface.js +0 -1
  95. package/dist/databases/postgres/migrations/postgres-foundational.js +0 -47
  96. /package/dist/{databases/postgres/migrations/database-builder.interface.js → __tests__/setup/vitest-setup.d.ts} +0 -0
@@ -1,21 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "./migration.interface.js";
3
- export declare class CreateUserRolesTableMigration implements IMigration {
4
- private readonly client;
5
- constructor(client: Client);
6
- index: number;
7
- execute(): Promise<{
8
- success: boolean;
9
- error: Error;
10
- } | {
11
- success: boolean;
12
- error: null;
13
- }>;
14
- revert(): Promise<{
15
- success: boolean;
16
- error: Error;
17
- } | {
18
- success: boolean;
19
- error: null;
20
- }>;
21
- }
@@ -1,75 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- import { doesTableExist } from "../utils/does-table-exist.util.js";
3
- import { config } from "../../../config/index.js";
4
- export class CreateUserRolesTableMigration {
5
- client;
6
- constructor(client) {
7
- this.client = client;
8
- }
9
- index = 8;
10
- async execute() {
11
- const _id = randomUUID().toString();
12
- try {
13
- await this.client.query('BEGIN');
14
- const tableExists = await doesTableExist(this.client, 'user_roles');
15
- if (!tableExists) {
16
- const fkConstraint = config.app.isMultiTenant
17
- ? '\n CONSTRAINT "fk_user_roles_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE,'
18
- : '';
19
- await this.client.query(`
20
- CREATE TABLE "user_roles" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "userId" VARCHAR(255) NOT NULL,
24
- "roleId" VARCHAR(255) NOT NULL,
25
- "_created" TIMESTAMP NOT NULL,
26
- "_createdBy" VARCHAR(255) NOT NULL,
27
- "_updated" TIMESTAMP NOT NULL,
28
- "_updatedBy" VARCHAR(255) NOT NULL,
29
- "_deleted" TIMESTAMP,
30
- "_deletedBy" VARCHAR(255),
31
- ${fkConstraint}
32
- CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE,
33
- CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
34
- CONSTRAINT "uk_user_roles" UNIQUE ("_orgId", "userId", "roleId")
35
- )
36
- `);
37
- }
38
- const result = await this.client.query(`
39
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
40
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
41
- `);
42
- if (result.rowCount === 0) {
43
- await this.client.query('ROLLBACK');
44
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
45
- }
46
- await this.client.query('COMMIT');
47
- return { success: true, error: null };
48
- }
49
- catch (error) {
50
- await this.client.query('ROLLBACK');
51
- return { success: false, error: new Error(`Error executing migration ${this.index}: ${error.message}`) };
52
- }
53
- }
54
- async revert() {
55
- try {
56
- await this.client.query('BEGIN');
57
- await this.client.query(`
58
- DROP TABLE "user_roles";
59
- `);
60
- const updateResult = await this.client.query(`
61
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
62
- `);
63
- if (updateResult.rowCount === 0) {
64
- await this.client.query('ROLLBACK');
65
- return { success: false, error: new Error(`Error updating migration record for index ${this.index}: No row returned`) };
66
- }
67
- await this.client.query('COMMIT');
68
- return { success: true, error: null };
69
- }
70
- catch (error) {
71
- await this.client.query('ROLLBACK');
72
- return { success: false, error: new Error(`Error reverting migration ${this.index}: ${error.message}`) };
73
- }
74
- }
75
- }
@@ -1,21 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "./migration.interface.js";
3
- export declare class CreateFeaturesTableMigration implements IMigration {
4
- private readonly client;
5
- constructor(client: Client);
6
- index: number;
7
- execute(): Promise<{
8
- success: boolean;
9
- error: Error;
10
- } | {
11
- success: boolean;
12
- error: null;
13
- }>;
14
- revert(): Promise<{
15
- success: boolean;
16
- error: Error;
17
- } | {
18
- success: boolean;
19
- error: null;
20
- }>;
21
- }
@@ -1,65 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- import { doesTableExist } from "../utils/does-table-exist.util.js";
3
- import { config } from "../../../config/index.js";
4
- export class CreateFeaturesTableMigration {
5
- client;
6
- constructor(client) {
7
- this.client = client;
8
- }
9
- index = 9;
10
- async execute() {
11
- const _id = randomUUID().toString();
12
- try {
13
- await this.client.query('BEGIN');
14
- const tableExists = await doesTableExist(this.client, 'features');
15
- if (!tableExists) {
16
- const fkConstraint = config.app.isMultiTenant
17
- ? ',\n CONSTRAINT "fk_features_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
18
- : '';
19
- await this.client.query(`
20
- CREATE TABLE "features" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "name" VARCHAR(255) NOT NULL,
24
- CONSTRAINT "uk_features" UNIQUE ("_orgId", "name")${fkConstraint}
25
- )
26
- `);
27
- }
28
- const result = await this.client.query(`
29
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
30
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
31
- `);
32
- if (result.rowCount === 0) {
33
- await this.client.query('ROLLBACK');
34
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
35
- }
36
- await this.client.query('COMMIT');
37
- return { success: true, error: null };
38
- }
39
- catch (error) {
40
- await this.client.query('ROLLBACK');
41
- return { success: false, error: new Error(`Error executing migration ${this.index}: ${error.message}`) };
42
- }
43
- }
44
- async revert() {
45
- try {
46
- await this.client.query('BEGIN');
47
- await this.client.query(`
48
- DROP TABLE "features";
49
- `);
50
- const updateResult = await this.client.query(`
51
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
52
- `);
53
- if (updateResult.rowCount === 0) {
54
- await this.client.query('ROLLBACK');
55
- return { success: false, error: new Error(`Error updating migration record for index ${this.index}: No row returned`) };
56
- }
57
- await this.client.query('COMMIT');
58
- return { success: true, error: null };
59
- }
60
- catch (error) {
61
- await this.client.query('ROLLBACK');
62
- return { success: false, error: new Error(`Error reverting migration ${this.index}: ${error.message}`) };
63
- }
64
- }
65
- }
@@ -1,21 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "./migration.interface.js";
3
- export declare class CreateAuthorizationsTableMigration implements IMigration {
4
- private readonly client;
5
- constructor(client: Client);
6
- index: number;
7
- execute(): Promise<{
8
- success: boolean;
9
- error: Error;
10
- } | {
11
- success: boolean;
12
- error: null;
13
- }>;
14
- revert(): Promise<{
15
- success: boolean;
16
- error: Error;
17
- } | {
18
- success: boolean;
19
- error: null;
20
- }>;
21
- }
@@ -1,77 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- import { doesTableExist } from "../utils/does-table-exist.util.js";
3
- import { config } from "../../../config/index.js";
4
- export class CreateAuthorizationsTableMigration {
5
- client;
6
- constructor(client) {
7
- this.client = client;
8
- }
9
- index = 10;
10
- async execute() {
11
- const _id = randomUUID().toString();
12
- try {
13
- await this.client.query('BEGIN');
14
- const tableExists = await doesTableExist(this.client, 'authorizations');
15
- if (!tableExists) {
16
- const fkConstraint = config.app.isMultiTenant
17
- ? ',\n CONSTRAINT "fk_authorizations_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
18
- : '';
19
- await this.client.query(`
20
- CREATE TABLE "authorizations" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "roleId" VARCHAR(255) NOT NULL,
24
- "featureId" VARCHAR(255) NOT NULL,
25
- "startDate" TIMESTAMP,
26
- "endDate" TIMESTAMP,
27
- "config" JSONB,
28
- "_created" TIMESTAMP NOT NULL,
29
- "_createdBy" VARCHAR(255) NOT NULL,
30
- "_updated" TIMESTAMP NOT NULL,
31
- "_updatedBy" VARCHAR(255) NOT NULL,
32
- "_deleted" TIMESTAMP,
33
- "_deletedBy" VARCHAR(255),
34
- CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
35
- CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("featureId") REFERENCES "features"("_id") ON DELETE CASCADE,
36
- CONSTRAINT "uk_authorizations" UNIQUE ("_orgId", "roleId", "featureId")${fkConstraint}
37
- )
38
- `);
39
- }
40
- const result = await this.client.query(`
41
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
42
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
43
- `);
44
- if (result.rowCount === 0) {
45
- await this.client.query('ROLLBACK');
46
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
47
- }
48
- await this.client.query('COMMIT');
49
- return { success: true, error: null };
50
- }
51
- catch (error) {
52
- await this.client.query('ROLLBACK');
53
- return { success: false, error: new Error(`Error executing migration ${this.index}: ${error.message}`) };
54
- }
55
- }
56
- async revert() {
57
- try {
58
- await this.client.query('BEGIN');
59
- await this.client.query(`
60
- DROP TABLE "authorizations";
61
- `);
62
- const updateResult = await this.client.query(`
63
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
64
- `);
65
- if (updateResult.rowCount === 0) {
66
- await this.client.query('ROLLBACK');
67
- return { success: false, error: new Error(`Error updating migration record for index ${this.index}: No row returned`) };
68
- }
69
- await this.client.query('COMMIT');
70
- return { success: true, error: null };
71
- }
72
- catch (error) {
73
- await this.client.query('ROLLBACK');
74
- return { success: false, error: new Error(`Error reverting migration ${this.index}: ${error.message}`) };
75
- }
76
- }
77
- }
@@ -1,23 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "./migration.interface.js";
3
- export declare class CreateAdminAuthorizationMigration implements IMigration {
4
- private readonly client;
5
- constructor(client: Client);
6
- private organizationService;
7
- private authService;
8
- index: number;
9
- execute(): Promise<{
10
- success: boolean;
11
- error: Error;
12
- } | {
13
- success: boolean;
14
- error: null;
15
- }>;
16
- revert(metaOrgId?: string): Promise<{
17
- success: boolean;
18
- error: Error;
19
- } | {
20
- success: boolean;
21
- error: null;
22
- }>;
23
- }
@@ -1,130 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- import { AuthService, OrganizationService } from "../../../services/index.js";
3
- import { PostgresDatabase } from "../index.js";
4
- import { config } from "../../../config/index.js";
5
- import { EmptyUserContext } from "@loomcore/common/models";
6
- export class CreateAdminAuthorizationMigration {
7
- client;
8
- constructor(client) {
9
- this.client = client;
10
- const database = new PostgresDatabase(this.client);
11
- this.organizationService = new OrganizationService(database);
12
- this.authService = new AuthService(database);
13
- }
14
- organizationService;
15
- authService;
16
- index = 11;
17
- async execute() {
18
- const _id = randomUUID().toString();
19
- try {
20
- const metaOrg = config.app.isMultiTenant ? await this.organizationService.getMetaOrg(EmptyUserContext) : undefined;
21
- if (!config.adminUser?.email) {
22
- return { success: false, error: new Error('Create admin authorization: Admin user email not found in config') };
23
- }
24
- const adminUser = await this.authService.getUserByEmail(config.adminUser?.email);
25
- if (!adminUser) {
26
- return { success: false, error: new Error('Create admin authorization: Admin user not found') };
27
- }
28
- await this.client.query('BEGIN');
29
- const roleId = randomUUID().toString();
30
- const roleResult = await this.client.query(`
31
- INSERT INTO "roles" ("_id", "_orgId", "name")
32
- VALUES ($1, $2, 'admin')
33
- `, [roleId, metaOrg?._id]);
34
- if (roleResult.rowCount === 0) {
35
- await this.client.query('ROLLBACK');
36
- return { success: false, error: new Error('Failed to create admin role') };
37
- }
38
- const userRoleId = randomUUID().toString();
39
- const userRoleResult = await this.client.query(`
40
- INSERT INTO "user_roles" ("_id", "_orgId", "userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
41
- VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
42
- `, [userRoleId, metaOrg?._id, adminUser?._id, roleId]);
43
- if (userRoleResult.rowCount === 0) {
44
- await this.client.query('ROLLBACK');
45
- return { success: false, error: new Error('Failed to create user role') };
46
- }
47
- const featureId = randomUUID().toString();
48
- const featureResult = await this.client.query(`
49
- INSERT INTO "features" ("_id", "_orgId", "name")
50
- VALUES ($1, $2, 'admin')
51
- `, [featureId, metaOrg?._id]);
52
- if (featureResult.rowCount === 0) {
53
- await this.client.query('ROLLBACK');
54
- return { success: false, error: new Error('Failed to create admin feature') };
55
- }
56
- const authorizationId = randomUUID().toString();
57
- const authorizationResult = await this.client.query(`
58
- INSERT INTO "authorizations" (
59
- "_id", "_orgId", "roleId", "featureId",
60
- "_created", "_createdBy", "_updated", "_updatedBy"
61
- )
62
- VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
63
- `, [authorizationId, metaOrg?._id, roleId, featureId]);
64
- if (authorizationResult.rowCount === 0) {
65
- await this.client.query('ROLLBACK');
66
- return { success: false, error: new Error('Failed to create admin authorization') };
67
- }
68
- const migrationResult = await this.client.query(`
69
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
70
- VALUES ($1, $2, TRUE, FALSE)
71
- `, [_id, this.index]);
72
- if (migrationResult.rowCount === 0) {
73
- await this.client.query('ROLLBACK');
74
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
75
- }
76
- await this.client.query('COMMIT');
77
- return { success: true, error: null };
78
- }
79
- catch (error) {
80
- await this.client.query('ROLLBACK');
81
- return { success: false, error: new Error(`Error executing migration ${this.index}: ${error.message}`) };
82
- }
83
- }
84
- async revert(metaOrgId) {
85
- try {
86
- await this.client.query('BEGIN');
87
- await this.client.query(`
88
- DELETE FROM "authorizations"
89
- WHERE "_orgId" = $1
90
- AND "_featureId" IN (
91
- SELECT "_id" FROM "features"
92
- WHERE "_orgId" = $1 AND "name" = 'admin'
93
- )
94
- AND "_roleId" IN (
95
- SELECT "_id" FROM "roles"
96
- WHERE "_orgId" = $1 AND "name" = 'admin'
97
- )
98
- `, [metaOrgId]);
99
- await this.client.query(`
100
- DELETE FROM "features"
101
- WHERE "_orgId" = $1 AND "name" = 'admin'
102
- `, [metaOrgId]);
103
- await this.client.query(`
104
- DELETE FROM "user_roles"
105
- WHERE "_orgId" = $1
106
- AND "_roleId" IN (
107
- SELECT "_id" FROM "roles"
108
- WHERE "_orgId" = $1 AND "name" = 'admin'
109
- )
110
- `, [metaOrgId]);
111
- await this.client.query(`
112
- DELETE FROM "roles"
113
- WHERE "_orgId" = $1 AND "name" = 'admin'
114
- `, [metaOrgId]);
115
- const updateResult = await this.client.query(`
116
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = $1
117
- `, [this.index]);
118
- if (updateResult.rowCount === 0) {
119
- await this.client.query('ROLLBACK');
120
- return { success: false, error: new Error(`Error updating migration record for index ${this.index}: No row returned`) };
121
- }
122
- await this.client.query('COMMIT');
123
- return { success: true, error: null };
124
- }
125
- catch (error) {
126
- await this.client.query('ROLLBACK');
127
- return { success: false, error: new Error(`Error reverting migration ${this.index}: ${error.message}`) };
128
- }
129
- }
130
- }
@@ -1,15 +0,0 @@
1
- import { Client } from "pg";
2
- import { IDatabaseBuilder } from "./database-builder.interface.js";
3
- import { IMigration } from "./migration.interface.js";
4
- export declare class DatabaseBuilder implements IDatabaseBuilder {
5
- private client;
6
- private migrationsToRun;
7
- constructor(client: Client);
8
- withAuth(): IDatabaseBuilder;
9
- withMultitenant(): IDatabaseBuilder;
10
- withMigrations(migrations: IMigration[]): IDatabaseBuilder;
11
- build(): Promise<{
12
- success: boolean;
13
- error: Error | null;
14
- }>;
15
- }
@@ -1,10 +0,0 @@
1
- import { IMigration } from "./migration.interface.js";
2
- export interface IDatabaseBuilder {
3
- withAuth(): IDatabaseBuilder;
4
- withMultitenant(): IDatabaseBuilder;
5
- withMigrations(migrations: IMigration[]): IDatabaseBuilder;
6
- build(): Promise<{
7
- success: boolean;
8
- error: Error | null;
9
- }>;
10
- }
@@ -1,65 +0,0 @@
1
- import _ from "lodash";
2
- import { CreateMigrationTableMigration } from "./001-create-migrations-table.migration.js";
3
- import { CreateUsersTableMigration } from "./003-create-users-table.migration.js";
4
- import { CreateAdminUserMigration } from "./006-create-admin-user.migration.js";
5
- import { CreateUserRolesTableMigration } from "./008-create-user-roles-table.migration.js";
6
- import { CreateAuthorizationsTableMigration } from "./010-create-authorizations-table.migration.js";
7
- import { CreateFeaturesTableMigration } from "./009-create-features-table.migration.js";
8
- import { CreateRoleTableMigration } from "./007-create-roles-table.migration.js";
9
- import { CreateRefreshTokenTableMigration } from "./004-create-refresh-tokens-table.migration.js";
10
- import { CreateAdminAuthorizationMigration } from "./011-create-admin-authorization.migration.js";
11
- import { CreateMetaOrgMigration } from "./005-create-meta-org.migration.js";
12
- import { CreateOrganizationsTableMigration } from "./002-create-organizations-table.migration.js";
13
- import { doesTableExist } from "../utils/index.js";
14
- export class DatabaseBuilder {
15
- client;
16
- migrationsToRun = [];
17
- constructor(client) {
18
- this.client = client;
19
- }
20
- withAuth() {
21
- this.migrationsToRun.push(new CreateMigrationTableMigration(this.client));
22
- this.migrationsToRun.push(new CreateUsersTableMigration(this.client));
23
- this.migrationsToRun.push(new CreateRefreshTokenTableMigration(this.client));
24
- this.migrationsToRun.push(new CreateAdminUserMigration(this.client));
25
- this.migrationsToRun.push(new CreateRoleTableMigration(this.client));
26
- this.migrationsToRun.push(new CreateUserRolesTableMigration(this.client));
27
- this.migrationsToRun.push(new CreateFeaturesTableMigration(this.client));
28
- this.migrationsToRun.push(new CreateAuthorizationsTableMigration(this.client));
29
- this.migrationsToRun.push(new CreateAdminAuthorizationMigration(this.client));
30
- return this;
31
- }
32
- withMultitenant() {
33
- this.migrationsToRun.push(new CreateMigrationTableMigration(this.client));
34
- this.migrationsToRun.push(new CreateOrganizationsTableMigration(this.client));
35
- this.migrationsToRun.push(new CreateMetaOrgMigration(this.client));
36
- return this;
37
- }
38
- withMigrations(migrations) {
39
- this.migrationsToRun.push(...migrations);
40
- return this;
41
- }
42
- async build() {
43
- let runMigrations = [];
44
- if (await doesTableExist(this.client, 'migrations')) {
45
- const migrations = await this.client.query(`
46
- SELECT "_id", "index"
47
- FROM migrations
48
- WHERE "hasRun" = TRUE AND "reverted" = FALSE
49
- `);
50
- runMigrations = migrations.rows.map((row) => {
51
- return row.index;
52
- });
53
- }
54
- const orderedMigrations = _.uniqBy(this.migrationsToRun
55
- .filter((migration) => !runMigrations.includes(migration.index))
56
- .sort((a, b) => a.index - b.index), 'index');
57
- for (const migration of orderedMigrations) {
58
- const result = await migration.execute();
59
- if (!result.success) {
60
- throw result.error;
61
- }
62
- }
63
- return { success: true, error: null };
64
- }
65
- }
@@ -1,11 +0,0 @@
1
- export interface IMigration {
2
- index: number;
3
- execute(): Promise<{
4
- success: boolean;
5
- error: Error | null;
6
- }>;
7
- revert(): Promise<{
8
- success: boolean;
9
- error: Error | null;
10
- }>;
11
- }
@@ -1,47 +0,0 @@
1
- export const getPostgresFoundational = (config) => {
2
- const migrations = [];
3
- const isMultiTenant = config.app.isMultiTenant === true;
4
- migrations.push({
5
- name: '00000000000001_base-users',
6
- up: async ({ context: pool }) => {
7
- const orgColumnDef = isMultiTenant ? '_orgId INTEGER,' : '';
8
- const sql = `
9
- CREATE TABLE users (
10
- _id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
11
- ${orgColumnDef}
12
- email VARCHAR(255) NOT NULL UNIQUE,
13
- password VARCHAR(255),
14
- roles TEXT[],
15
- created_at TIMESTAMP DEFAULT NOW(),
16
- updated_at TIMESTAMP DEFAULT NOW()
17
- );
18
- `;
19
- await pool.query(sql);
20
- if (isMultiTenant) {
21
- await pool.query(`CREATE INDEX idx_users_org_id ON users (_orgId);`);
22
- }
23
- },
24
- down: async ({ context: pool }) => {
25
- await pool.query('DROP TABLE IF EXISTS users');
26
- }
27
- });
28
- if (isMultiTenant) {
29
- migrations.push({
30
- name: '00000000000002_base-organizations',
31
- up: async ({ context: pool }) => {
32
- await pool.query(`
33
- CREATE TABLE organizations (
34
- _id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
35
- name VARCHAR(255) NOT NULL,
36
- plan_tier VARCHAR(50) DEFAULT 'free',
37
- created_at TIMESTAMP DEFAULT NOW()
38
- );
39
- `);
40
- },
41
- down: async ({ context: pool }) => {
42
- await pool.query('DROP TABLE IF EXISTS organizations');
43
- }
44
- });
45
- }
46
- return migrations;
47
- };