@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,5 +1,6 @@
1
1
  import { ValueError } from '@sinclair/typebox/errors';
2
2
  import { IUserContext, IEntity, IQueryOptions, IPagedResult, IModelSpec } from '@loomcore/common/models';
3
+ import type { AppIdType } from '@loomcore/common/types';
3
4
  import { IGenericApiService } from './generic-api-service.interface.js';
4
5
  import { Operation } from '../../databases/operations/operation.js';
5
6
  import { DeleteResult } from '../../databases/models/delete-result.js';
@@ -17,20 +18,20 @@ export declare class GenericApiService<T extends IEntity> implements IGenericApi
17
18
  };
18
19
  validate(doc: any, isPartial?: boolean): ValueError[] | null;
19
20
  validateMany(docs: any[], isPartial?: boolean): ValueError[] | null;
20
- preprocessEntity(userContext: IUserContext, entity: Partial<T>, isCreate: boolean, allowId?: boolean): Promise<Partial<T>>;
21
- postprocessEntity(userContext: IUserContext, entity: T): T;
21
+ preProcessEntity(userContext: IUserContext, entity: Partial<T>, isCreate: boolean, allowId?: boolean): Promise<Partial<T>>;
22
+ postProcessEntity(userContext: IUserContext, entity: T): T;
22
23
  get(userContext: IUserContext, queryOptions?: IQueryOptions): Promise<IPagedResult<T>>;
23
24
  protected prepareQueryOptions(userContext: IUserContext | undefined, queryOptions: IQueryOptions): IQueryOptions;
24
- getById(userContext: IUserContext, id: string): Promise<T>;
25
+ getById(userContext: IUserContext, id: AppIdType): Promise<T>;
25
26
  getCount(userContext: IUserContext): Promise<number>;
26
27
  create(userContext: IUserContext, entity: Partial<T>): Promise<T | null>;
27
28
  createMany(userContext: IUserContext, entities: Partial<T>[]): Promise<T[]>;
28
29
  batchUpdate(userContext: IUserContext, entities: Partial<T>[]): Promise<T[]>;
29
- fullUpdateById(userContext: IUserContext, id: string, entity: T): Promise<T>;
30
- partialUpdateById(userContext: IUserContext, id: string, entity: Partial<T>): Promise<T>;
31
- partialUpdateByIdWithoutPreAndPostProcessing(userContext: IUserContext, id: string, entity: Partial<T>): Promise<T>;
30
+ fullUpdateById(userContext: IUserContext, id: AppIdType, entity: T): Promise<T>;
31
+ partialUpdateById(userContext: IUserContext, id: AppIdType, entity: Partial<T>): Promise<T>;
32
+ partialUpdateByIdWithoutPreAndPostProcessing(userContext: IUserContext, id: AppIdType, entity: Partial<T>): Promise<T>;
32
33
  update(userContext: IUserContext, queryObject: IQueryOptions, entity: Partial<T>): Promise<T[]>;
33
- deleteById(userContext: IUserContext, id: string): Promise<DeleteResult>;
34
+ deleteById(userContext: IUserContext, id: AppIdType): Promise<DeleteResult>;
34
35
  deleteMany(userContext: IUserContext, queryObject: IQueryOptions): Promise<DeleteResult>;
35
36
  find(userContext: IUserContext, queryObject: IQueryOptions): Promise<T[]>;
36
37
  findOne(userContext: IUserContext, queryObject: IQueryOptions): Promise<T | null>;
@@ -19,7 +19,7 @@ export class GenericApiService {
19
19
  async getAll(userContext) {
20
20
  const { operations } = this.prepareQuery(userContext, {}, []);
21
21
  const entities = await this.database.getAll(operations, this.pluralResourceName);
22
- return entities.map(entity => this.postprocessEntity(userContext, entity));
22
+ return entities.map(entity => this.postProcessEntity(userContext, entity));
23
23
  }
24
24
  prepareQuery(userContext, queryObject, operations) {
25
25
  return { queryObject, operations };
@@ -39,7 +39,7 @@ export class GenericApiService {
39
39
  }
40
40
  return allErrors.length > 0 ? allErrors : null;
41
41
  }
42
- async preprocessEntity(userContext, entity, isCreate, allowId = true) {
42
+ async preProcessEntity(userContext, entity, isCreate, allowId = true) {
43
43
  let preparedEntity = _.clone(entity);
44
44
  stripSenderProvidedSystemProperties(userContext, preparedEntity, allowId);
45
45
  if (this.modelSpec.isAuditable) {
@@ -57,17 +57,17 @@ export class GenericApiService {
57
57
  if (this.modelSpec) {
58
58
  cleanedEntity = this.modelSpec.decode(preparedEntity);
59
59
  }
60
- preparedEntity = this.database.preprocessEntity(cleanedEntity, this.modelSpec.fullSchema);
60
+ preparedEntity = this.database.preProcessEntity(cleanedEntity, this.modelSpec.fullSchema);
61
61
  return preparedEntity;
62
62
  }
63
- postprocessEntity(userContext, entity) {
64
- return this.database.postprocessEntity(entity, this.modelSpec.fullSchema);
63
+ postProcessEntity(userContext, entity) {
64
+ return this.database.postProcessEntity(entity, this.modelSpec.fullSchema);
65
65
  }
66
66
  async get(userContext, queryOptions = { ...DefaultQueryOptions }) {
67
67
  const preparedOptions = this.prepareQueryOptions(userContext, queryOptions);
68
68
  const { operations } = this.prepareQuery(userContext, {}, []);
69
69
  const pagedResult = await this.database.get(operations, preparedOptions, this.modelSpec, this.pluralResourceName);
70
- const transformedEntities = (pagedResult.entities || []).map(entity => this.postprocessEntity(userContext, entity));
70
+ const transformedEntities = (pagedResult.entities || []).map(entity => this.postProcessEntity(userContext, entity));
71
71
  return {
72
72
  ...pagedResult,
73
73
  entities: transformedEntities
@@ -82,7 +82,7 @@ export class GenericApiService {
82
82
  if (!entity) {
83
83
  throw new IdNotFoundError();
84
84
  }
85
- return this.postprocessEntity(userContext, entity);
85
+ return this.postProcessEntity(userContext, entity);
86
86
  }
87
87
  async getCount(userContext) {
88
88
  this.prepareQuery(userContext, {}, []);
@@ -90,20 +90,20 @@ export class GenericApiService {
90
90
  }
91
91
  async create(userContext, entity) {
92
92
  let createdEntity = null;
93
- const preparedEntity = await this.preprocessEntity(userContext, entity, true, true);
93
+ const preparedEntity = await this.preProcessEntity(userContext, entity, true, true);
94
94
  const insertResult = await this.database.create(preparedEntity, this.pluralResourceName);
95
95
  if (insertResult.insertedId) {
96
- createdEntity = this.postprocessEntity(userContext, insertResult.entity);
96
+ createdEntity = this.postProcessEntity(userContext, insertResult.entity);
97
97
  }
98
98
  return createdEntity;
99
99
  }
100
100
  async createMany(userContext, entities) {
101
101
  let createdEntities = [];
102
102
  if (entities.length) {
103
- const preparedEntities = await Promise.all(entities.map(entity => this.preprocessEntity(userContext, entity, true, true)));
103
+ const preparedEntities = await Promise.all(entities.map(entity => this.preProcessEntity(userContext, entity, true, true)));
104
104
  const insertResult = await this.database.createMany(preparedEntities, this.pluralResourceName);
105
105
  if (insertResult.insertedIds) {
106
- createdEntities = insertResult.entities.map(entity => this.postprocessEntity(userContext, entity));
106
+ createdEntities = insertResult.entities.map(entity => this.postProcessEntity(userContext, entity));
107
107
  }
108
108
  }
109
109
  return createdEntities;
@@ -112,10 +112,10 @@ export class GenericApiService {
112
112
  if (!entities || entities.length === 0) {
113
113
  return [];
114
114
  }
115
- const preparedEntities = await Promise.all(entities.map(entity => this.preprocessEntity(userContext, entity, false, true)));
115
+ const preparedEntities = await Promise.all(entities.map(entity => this.preProcessEntity(userContext, entity, false, true)));
116
116
  const { queryObject, operations } = this.prepareQuery(userContext, {}, []);
117
117
  const rawUpdatedEntities = await this.database.batchUpdate(preparedEntities, operations, queryObject, this.pluralResourceName);
118
- const updatedEntities = rawUpdatedEntities.map(entity => this.postprocessEntity(userContext, entity));
118
+ const updatedEntities = rawUpdatedEntities.map(entity => this.postProcessEntity(userContext, entity));
119
119
  return updatedEntities;
120
120
  }
121
121
  async fullUpdateById(userContext, id, entity) {
@@ -128,29 +128,29 @@ export class GenericApiService {
128
128
  _created: existingEntity._created,
129
129
  _createdBy: existingEntity._createdBy,
130
130
  };
131
- const preparedEntity = await this.preprocessEntity(userContext, entity, false, true);
131
+ const preparedEntity = await this.preProcessEntity(userContext, entity, false, true);
132
132
  Object.assign(preparedEntity, auditProperties);
133
133
  const rawUpdatedEntity = await this.database.fullUpdateById(operations, id, preparedEntity, this.pluralResourceName);
134
- const updatedEntity = this.postprocessEntity(userContext, rawUpdatedEntity);
134
+ const updatedEntity = this.postProcessEntity(userContext, rawUpdatedEntity);
135
135
  return updatedEntity;
136
136
  }
137
137
  async partialUpdateById(userContext, id, entity) {
138
138
  const { operations } = this.prepareQuery(userContext, {}, []);
139
- const preparedEntity = await this.preprocessEntity(userContext, entity, false, true);
139
+ const preparedEntity = await this.preProcessEntity(userContext, entity, false, true);
140
140
  const rawUpdatedEntity = await this.database.partialUpdateById(operations, id, preparedEntity, this.pluralResourceName);
141
- const updatedEntity = this.postprocessEntity(userContext, rawUpdatedEntity);
141
+ const updatedEntity = this.postProcessEntity(userContext, rawUpdatedEntity);
142
142
  return updatedEntity;
143
143
  }
144
144
  async partialUpdateByIdWithoutPreAndPostProcessing(userContext, id, entity) {
145
- const preparedEntity = this.database.preprocessEntity(entity, this.modelSpec.fullSchema);
145
+ const preparedEntity = this.database.preProcessEntity(entity, this.modelSpec.fullSchema);
146
146
  const rawUpdatedEntity = await this.database.partialUpdateById([], id, preparedEntity, this.pluralResourceName);
147
- return this.database.postprocessEntity(rawUpdatedEntity, this.modelSpec.fullSchema);
147
+ return this.database.postProcessEntity(rawUpdatedEntity, this.modelSpec.fullSchema);
148
148
  }
149
149
  async update(userContext, queryObject, entity) {
150
150
  const { queryObject: preparedQuery, operations } = this.prepareQuery(userContext, queryObject, []);
151
- const preparedEntity = await this.preprocessEntity(userContext, entity, false, true);
151
+ const preparedEntity = await this.preProcessEntity(userContext, entity, false, true);
152
152
  const rawUpdatedEntities = await this.database.update(preparedQuery, preparedEntity, operations, this.pluralResourceName);
153
- const updatedEntities = rawUpdatedEntities.map(entity => this.postprocessEntity(userContext, entity));
153
+ const updatedEntities = rawUpdatedEntities.map(entity => this.postProcessEntity(userContext, entity));
154
154
  return updatedEntities;
155
155
  }
156
156
  async deleteById(userContext, id) {
@@ -168,11 +168,11 @@ export class GenericApiService {
168
168
  async find(userContext, queryObject) {
169
169
  const { queryObject: preparedQuery, operations } = this.prepareQuery(userContext, queryObject, []);
170
170
  const rawEntities = await this.database.find(preparedQuery, this.pluralResourceName);
171
- return rawEntities.map(entity => this.postprocessEntity(userContext, entity));
171
+ return rawEntities.map(entity => this.postProcessEntity(userContext, entity));
172
172
  }
173
173
  async findOne(userContext, queryObject) {
174
174
  const { queryObject: preparedQuery, operations } = this.prepareQuery(userContext, queryObject, []);
175
175
  const rawEntity = await this.database.findOne(preparedQuery, this.pluralResourceName);
176
- return rawEntity ? this.postprocessEntity(userContext, rawEntity) : null;
176
+ return rawEntity ? this.postProcessEntity(userContext, rawEntity) : null;
177
177
  }
178
178
  }
@@ -9,5 +9,5 @@ export declare class MultiTenantApiService<T extends IEntity> extends GenericApi
9
9
  queryObject: IQueryOptions;
10
10
  operations: Operation[];
11
11
  };
12
- preprocessEntity(userContext: IUserContext, entity: Partial<T>, isCreate: boolean, allowId?: boolean): Promise<Partial<T>>;
12
+ preProcessEntity(userContext: IUserContext, entity: Partial<T>, isCreate: boolean, allowId?: boolean): Promise<Partial<T>>;
13
13
  }
@@ -20,14 +20,14 @@ export class MultiTenantApiService extends GenericApiService {
20
20
  const queryObject = this.tenantDecorator.applyTenantToQuery(userContext, queryOptions, this.pluralResourceName);
21
21
  return { queryObject, operations };
22
22
  }
23
- async preprocessEntity(userContext, entity, isCreate, allowId = false) {
23
+ async preProcessEntity(userContext, entity, isCreate, allowId = false) {
24
24
  if (!config?.app?.isMultiTenant) {
25
- return super.preprocessEntity(userContext, entity, isCreate, allowId);
25
+ return super.preProcessEntity(userContext, entity, isCreate, allowId);
26
26
  }
27
27
  if (!userContext || !userContext.organization?._id) {
28
28
  throw new BadRequestError('A valid userContext was not provided to MultiTenantApiService.prepareEntity');
29
29
  }
30
- const preparedEntity = await super.preprocessEntity(userContext, entity, isCreate, allowId);
30
+ const preparedEntity = await super.preProcessEntity(userContext, entity, isCreate, allowId);
31
31
  if (isCreate && userContext.user._id !== 'system') {
32
32
  preparedEntity._orgId = userContext.organization?._id;
33
33
  }
@@ -1,10 +1,11 @@
1
1
  import { IOrganization, IUserContext } from '@loomcore/common/models';
2
2
  import { IDatabase } from '../databases/models/database.interface.js';
3
3
  import { GenericApiService } from './generic-api-service/generic-api.service.js';
4
+ import { AppIdType } from '@loomcore/common/types';
4
5
  export declare class OrganizationService extends GenericApiService<IOrganization> {
5
6
  constructor(database: IDatabase);
6
- preprocessEntity(userContext: IUserContext, entity: Partial<IOrganization>, isCreate: boolean, allowId?: boolean): Promise<Partial<IOrganization>>;
7
- getAuthTokenByRepoCode(userContext: IUserContext, orgId: string): Promise<string | null>;
8
- validateRepoAuthToken(userContext: IUserContext, orgCode: string, authToken: string): Promise<string | null>;
7
+ preProcessEntity(userContext: IUserContext, entity: Partial<IOrganization>, isCreate: boolean, allowId?: boolean): Promise<Partial<IOrganization>>;
8
+ getAuthTokenByRepoCode(userContext: IUserContext, orgId: AppIdType): Promise<string | null>;
9
+ validateRepoAuthToken(userContext: IUserContext, orgCode: string, authToken: string): Promise<AppIdType | null>;
9
10
  getMetaOrg(userContext: IUserContext): Promise<IOrganization | null>;
10
11
  }
@@ -5,7 +5,7 @@ export class OrganizationService extends GenericApiService {
5
5
  constructor(database) {
6
6
  super(database, 'organizations', 'organization', OrganizationSpec);
7
7
  }
8
- async preprocessEntity(userContext, entity, isCreate, allowId = true) {
8
+ async preProcessEntity(userContext, entity, isCreate, allowId = true) {
9
9
  if (isCreate) {
10
10
  const metaOrg = await this.getMetaOrg(userContext);
11
11
  if (metaOrg && entity.isMetaOrg) {
@@ -15,7 +15,7 @@ export class OrganizationService extends GenericApiService {
15
15
  throw new BadRequestError('User is not authorized to create an organization');
16
16
  }
17
17
  }
18
- const result = await super.preprocessEntity(userContext, entity, isCreate, allowId);
18
+ const result = await super.preProcessEntity(userContext, entity, isCreate, allowId);
19
19
  return result;
20
20
  }
21
21
  async getAuthTokenByRepoCode(userContext, orgId) {
@@ -27,7 +27,7 @@ export class OrganizationService extends GenericApiService {
27
27
  if (!org) {
28
28
  return null;
29
29
  }
30
- const orgId = org.authToken === authToken ? org._id.toString() : null;
30
+ const orgId = org.authToken === authToken ? org._id : null;
31
31
  return orgId;
32
32
  }
33
33
  async getMetaOrg(userContext) {
@@ -1,8 +1,9 @@
1
1
  import { IUser, IUserContext } from '@loomcore/common/models';
2
+ import type { AppIdType } from '@loomcore/common/types';
2
3
  import { MultiTenantApiService } from './index.js';
3
4
  import { IDatabase } from '../databases/models/index.js';
4
5
  export declare class UserService extends MultiTenantApiService<IUser> {
5
6
  constructor(database: IDatabase);
6
- fullUpdateById(userContext: IUserContext, id: string, entity: IUser): Promise<IUser>;
7
- preprocessEntity(userContext: IUserContext, entity: Partial<IUser>, isCreate: boolean, allowId?: boolean): Promise<Partial<IUser>>;
7
+ fullUpdateById(userContext: IUserContext, id: AppIdType, entity: IUser): Promise<IUser>;
8
+ preProcessEntity(userContext: IUserContext, entity: Partial<IUser>, isCreate: boolean, allowId?: boolean): Promise<Partial<IUser>>;
8
9
  }
@@ -9,8 +9,8 @@ export class UserService extends MultiTenantApiService {
9
9
  async fullUpdateById(userContext, id, entity) {
10
10
  throw new ServerError('Cannot full update a user. Either use PATCH or /auth/change-password to update password.');
11
11
  }
12
- async preprocessEntity(userContext, entity, isCreate, allowId = false) {
13
- const preparedEntity = await super.preprocessEntity(userContext, entity, isCreate);
12
+ async preProcessEntity(userContext, entity, isCreate, allowId = false) {
13
+ const preparedEntity = await super.preProcessEntity(userContext, entity, isCreate);
14
14
  if (preparedEntity.email) {
15
15
  preparedEntity.email = preparedEntity.email.toLowerCase();
16
16
  }
@@ -1,7 +1,8 @@
1
+ import { getSystemUserId } from "@loomcore/common/validation";
1
2
  import moment from "moment";
2
3
  export function auditForCreate(userContext, doc) {
3
4
  const now = moment().utc().toDate();
4
- const userId = userContext.user?._id?.toString() ?? 'system';
5
+ const userId = userContext.user?._id ?? getSystemUserId();
5
6
  doc._created = now;
6
7
  doc._createdBy = userId;
7
8
  doc._updated = now;
@@ -1,6 +1,7 @@
1
+ import { getSystemUserId } from "@loomcore/common/validation";
1
2
  import moment from "moment";
2
3
  export function auditForUpdate(userContext, doc) {
3
- const userId = userContext.user?._id?.toString() ?? 'system';
4
+ const userId = userContext.user?._id ?? getSystemUserId();
4
5
  doc._updated = moment().utc().toDate();
5
6
  doc._updatedBy = userId;
6
7
  }
@@ -1,5 +1,6 @@
1
+ import { getSystemUserId } from "@loomcore/common/validation";
1
2
  export function stripSenderProvidedSystemProperties(userContext, entity, allowId = false) {
2
- const isSystemUser = userContext.user?._id === 'system';
3
+ const isSystemUser = userContext.user?._id === getSystemUserId();
3
4
  if (isSystemUser) {
4
5
  return;
5
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.1.53",
3
+ "version": "0.1.57",
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": {
@@ -53,7 +53,7 @@
53
53
  "qs": "^6.14.0"
54
54
  },
55
55
  "peerDependencies": {
56
- "@loomcore/common": "^0.0.32",
56
+ "@loomcore/common": "^0.0.43",
57
57
  "@sinclair/typebox": "0.34.33",
58
58
  "cookie-parser": "^1.4.6",
59
59
  "cors": "^2.8.5",
@@ -1,21 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "../../databases/postgres/migrations/migration.interface.js";
3
- export declare class CreateTestEntitiesTableMigration 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,61 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- export class CreateTestEntitiesTableMigration {
3
- client;
4
- constructor(client) {
5
- this.client = client;
6
- }
7
- index = 100;
8
- async execute() {
9
- const _id = randomUUID().toString();
10
- try {
11
- await this.client.query(`
12
- CREATE TABLE "testEntities" (
13
- "_id" VARCHAR(255) PRIMARY KEY,
14
- "_orgId" VARCHAR(255),
15
- "name" VARCHAR(255) NOT NULL,
16
- "description" TEXT,
17
- "isActive" BOOLEAN,
18
- "tags" TEXT[],
19
- "count" INTEGER,
20
- "_created" TIMESTAMP NOT NULL,
21
- "_createdBy" VARCHAR(255) NOT NULL,
22
- "_updated" TIMESTAMP NOT NULL,
23
- "_updatedBy" VARCHAR(255) NOT NULL,
24
- "_deleted" TIMESTAMP,
25
- "_deletedBy" VARCHAR(255)
26
- )
27
- `);
28
- }
29
- catch (error) {
30
- return { success: false, error: new Error(`Error creating test entities table: ${error.message}`) };
31
- }
32
- try {
33
- await this.client.query(`
34
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${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
- return { success: true, error: null };
41
- }
42
- async revert() {
43
- try {
44
- await this.client.query(`
45
- DROP TABLE test_entities;
46
- `);
47
- }
48
- catch (error) {
49
- return { success: false, error: new Error(`Error dropping test entities table: ${error.message}`) };
50
- }
51
- try {
52
- await this.client.query(`
53
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
54
- `);
55
- }
56
- catch (error) {
57
- return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
58
- }
59
- return { success: true, error: null };
60
- }
61
- }
@@ -1,21 +0,0 @@
1
- import { IMigration } from "../../databases/postgres/migrations/index.js";
2
- import { Client } from "pg";
3
- export declare class CreateCategoriesTableMigration 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,51 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- export class CreateCategoriesTableMigration {
3
- client;
4
- constructor(client) {
5
- this.client = client;
6
- }
7
- index = 101;
8
- async execute() {
9
- const _id = randomUUID().toString();
10
- try {
11
- await this.client.query(`
12
- CREATE TABLE "categories" (
13
- "_id" VARCHAR(255) PRIMARY KEY,
14
- "_orgId" VARCHAR(255),
15
- "name" VARCHAR(255) NOT NULL
16
- )
17
- `);
18
- }
19
- catch (error) {
20
- return { success: false, error: new Error(`Error creating categories table: ${error.message}`) };
21
- }
22
- try {
23
- await this.client.query(`
24
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
25
- `);
26
- }
27
- catch (error) {
28
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
29
- }
30
- return { success: true, error: null };
31
- }
32
- async revert() {
33
- try {
34
- await this.client.query(`
35
- DROP TABLE "categories";
36
- `);
37
- }
38
- catch (error) {
39
- return { success: false, error: new Error(`Error dropping categories table: ${error.message}`) };
40
- }
41
- try {
42
- await this.client.query(`
43
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
44
- `);
45
- }
46
- catch (error) {
47
- return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
48
- }
49
- return { success: true, error: null };
50
- }
51
- }
@@ -1,21 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "../../databases/postgres/migrations/index.js";
3
- export declare class CreateProductsTableMigration 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,60 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- export class CreateProductsTableMigration {
3
- client;
4
- constructor(client) {
5
- this.client = client;
6
- }
7
- index = 102;
8
- async execute() {
9
- const _id = randomUUID().toString();
10
- try {
11
- await this.client.query(`
12
- CREATE TABLE "products" (
13
- "_id" VARCHAR(255) PRIMARY KEY,
14
- "_orgId" VARCHAR(255),
15
- "name" VARCHAR(255) NOT NULL,
16
- "description" TEXT,
17
- "internalNumber" VARCHAR(255),
18
- "categoryId" VARCHAR(255) NOT NULL REFERENCES "categories"("_id"),
19
- "_created" TIMESTAMP NOT NULL,
20
- "_createdBy" VARCHAR(255) NOT NULL,
21
- "_updated" TIMESTAMP NOT NULL,
22
- "_updatedBy" VARCHAR(255) NOT NULL,
23
- "_deleted" TIMESTAMP,
24
- "_deletedBy" VARCHAR(255)
25
- )
26
- `);
27
- }
28
- catch (error) {
29
- return { success: false, error: new Error(`Error creating products table: ${error.message}`) };
30
- }
31
- try {
32
- await this.client.query(`
33
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${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
- return { success: true, error: null };
40
- }
41
- async revert() {
42
- try {
43
- await this.client.query(`
44
- DROP TABLE "products";
45
- `);
46
- }
47
- catch (error) {
48
- return { success: false, error: new Error(`Error dropping products table: ${error.message}`) };
49
- }
50
- try {
51
- await this.client.query(`
52
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
53
- `);
54
- }
55
- catch (error) {
56
- return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
57
- }
58
- return { success: true, error: null };
59
- }
60
- }
@@ -1,21 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "../../databases/postgres/migrations/index.js";
3
- export declare class CreateTestItemsTableMigration 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,59 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- export class CreateTestItemsTableMigration {
3
- client;
4
- constructor(client) {
5
- this.client = client;
6
- }
7
- index = 103;
8
- async execute() {
9
- const _id = randomUUID().toString();
10
- try {
11
- await this.client.query(`
12
- CREATE TABLE "testItems" (
13
- "_id" VARCHAR(255) PRIMARY KEY,
14
- "_orgId" VARCHAR(255),
15
- "name" VARCHAR(255) NOT NULL,
16
- "value" INTEGER,
17
- "eventDate" TIMESTAMP,
18
- "_created" TIMESTAMP NOT NULL,
19
- "_createdBy" VARCHAR(255) NOT NULL,
20
- "_updated" TIMESTAMP NOT NULL,
21
- "_updatedBy" VARCHAR(255) NOT NULL,
22
- "_deleted" TIMESTAMP,
23
- "_deletedBy" VARCHAR(255)
24
- )
25
- `);
26
- }
27
- catch (error) {
28
- return { success: false, error: new Error(`Error creating test items table: ${error.message}`) };
29
- }
30
- try {
31
- await this.client.query(`
32
- Insert into "migrations" ("_id", "index", "hasRun", "reverted") values ('${_id}', ${this.index}, TRUE, FALSE);
33
- `);
34
- }
35
- catch (error) {
36
- return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: ${error.message}`) };
37
- }
38
- return { success: true, error: null };
39
- }
40
- async revert() {
41
- try {
42
- await this.client.query(`
43
- DROP TABLE "testItems";
44
- `);
45
- }
46
- catch (error) {
47
- return { success: false, error: new Error(`Error dropping test items table: ${error.message}`) };
48
- }
49
- try {
50
- await this.client.query(`
51
- Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
52
- `);
53
- }
54
- catch (error) {
55
- return { success: false, error: new Error(`Error updating migration record: ${error.message}`) };
56
- }
57
- return { success: true, error: null };
58
- }
59
- }
@@ -1,3 +0,0 @@
1
- import { Client } from "pg";
2
- import { IMigration } from "../../databases/index.js";
3
- export declare const testMigrations: (client: Client) => IMigration[];