@managemint-solutions/sdk 0.52.0 → 0.54.0

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 (72) hide show
  1. package/README.md +92 -13
  2. package/dist/additional-details/index.d.ts +2 -2
  3. package/dist/additional-details/index.js +6 -10
  4. package/dist/audit/dto.d.ts +3 -8
  5. package/dist/audit/dto.js +7 -48
  6. package/dist/audit/index.d.ts +71 -10
  7. package/dist/audit/index.js +234 -55
  8. package/dist/auth-client/index.d.ts +2 -0
  9. package/dist/auth-client/index.js +12 -0
  10. package/dist/auth.d.ts +21 -0
  11. package/dist/auth.js +47 -3
  12. package/dist/clients/dto.d.ts +5 -1
  13. package/dist/clients/dto.js +12 -1
  14. package/dist/clients/index.d.ts +8 -4
  15. package/dist/clients/index.js +11 -8
  16. package/dist/emulation-handshakes/index.d.ts +13 -0
  17. package/dist/emulation-handshakes/index.js +36 -0
  18. package/dist/errors.js +2 -2
  19. package/dist/index.d.ts +14 -10
  20. package/dist/index.js +23 -4
  21. package/dist/leads/dto.d.ts +5 -1
  22. package/dist/leads/dto.js +12 -1
  23. package/dist/leads/index.d.ts +8 -5
  24. package/dist/leads/index.js +23 -21
  25. package/dist/leave/leave-adjustments.js +1 -0
  26. package/dist/leave/leave-entitlements.d.ts +3 -1
  27. package/dist/leave/leave-entitlements.js +3 -0
  28. package/dist/leave/leave-requests.d.ts +3 -1
  29. package/dist/leave/leave-requests.js +3 -0
  30. package/dist/nest/index.d.ts +26 -1
  31. package/dist/nest/index.js +58 -1
  32. package/dist/notifications/index.d.ts +1 -3
  33. package/dist/organization-payment-methods/index.d.ts +5 -6
  34. package/dist/organization-payment-methods/index.js +4 -17
  35. package/dist/organizations/dto.d.ts +9 -1
  36. package/dist/organizations/dto.js +40 -1
  37. package/dist/organizations/index.d.ts +13 -3
  38. package/dist/organizations/index.js +59 -3
  39. package/dist/permissions/index.d.ts +6 -4
  40. package/dist/permissions/index.js +19 -12
  41. package/dist/projects/dto.d.ts +5 -1
  42. package/dist/projects/dto.js +12 -1
  43. package/dist/projects/index.d.ts +8 -4
  44. package/dist/projects/index.js +11 -8
  45. package/dist/service-client/index.d.ts +39 -1
  46. package/dist/service-client/index.js +89 -2
  47. package/dist/staff/dto.d.ts +14 -0
  48. package/dist/staff/dto.js +63 -0
  49. package/dist/staff/index.d.ts +50 -0
  50. package/dist/staff/index.js +139 -0
  51. package/dist/staff-client.d.ts +37 -0
  52. package/dist/staff-client.js +52 -0
  53. package/dist/tasks/dto.d.ts +5 -1
  54. package/dist/tasks/dto.js +12 -1
  55. package/dist/tasks/index.d.ts +15 -10
  56. package/dist/tasks/index.js +34 -31
  57. package/dist/tenancy.d.ts +13 -0
  58. package/dist/tenancy.js +25 -0
  59. package/dist/timesheets/timesheet-entries.js +1 -0
  60. package/dist/timesheets/timesheets.d.ts +3 -1
  61. package/dist/timesheets/timesheets.js +3 -0
  62. package/dist/user-api-credentials/dto.d.ts +12 -0
  63. package/dist/user-api-credentials/dto.js +56 -0
  64. package/dist/user-api-credentials/index.d.ts +47 -0
  65. package/dist/user-api-credentials/index.js +101 -0
  66. package/dist/users/dto.d.ts +5 -1
  67. package/dist/users/dto.js +13 -2
  68. package/dist/users/index.d.ts +7 -3
  69. package/dist/users/index.js +16 -29
  70. package/dist/validators.d.ts +2 -0
  71. package/dist/validators.js +6 -1
  72. package/package.json +2 -2
@@ -20,6 +20,7 @@ const working_days_1 = require("../leave/working-days");
20
20
  const audit_1 = require("../audit");
21
21
  const errors_1 = require("../errors");
22
22
  const paths_1 = require("../supporting-files/paths");
23
+ const tenancy_1 = require("../tenancy");
23
24
  const transforms_1 = require("../transforms");
24
25
  const paths_2 = require("./paths");
25
26
  __exportStar(require("./dto"), exports);
@@ -33,10 +34,13 @@ class UsersResource {
33
34
  supabase;
34
35
  auth;
35
36
  table;
37
+ /** This record's history - its own rows and the rows that hang off it. */
38
+ audit;
36
39
  constructor(supabase, auth, audit) {
37
40
  this.supabase = supabase;
38
41
  this.auth = auth;
39
42
  this.table = (0, audit_1.auditedTable)(supabase, auth, audit, USERS_TABLE);
43
+ this.audit = new audit_1.EntityAuditTrail(supabase, auth, enum_1.AuditTrailEntityType.USER);
40
44
  }
41
45
  async list(query) {
42
46
  const page = query.page;
@@ -45,12 +49,14 @@ class UsersResource {
45
49
  const trimmedSearch = query.search?.trim();
46
50
  // `order`/`range` return `this`, so the builder stays a filter builder and the conditional
47
51
  // filters below can be reassigned onto it without a cast.
48
- let usersQuery = this.supabase
52
+ let usersQuery = (0, tenancy_1.scopeToOrganization)(this.supabase
49
53
  .from('users')
50
- .select(USER_LIST_SELECT, { count: 'estimated' })
51
- .eq('organization_id', this.auth.organization_id)
54
+ .select((0, tenancy_1.withOrganization)(USER_LIST_SELECT, this.auth), { count: 'estimated' }), this.auth)
52
55
  .order('created_at', { ascending: false })
53
56
  .range(offset, offset + pageSize - 1);
57
+ if (query.organization_id) {
58
+ usersQuery = usersQuery.eq('organization_id', query.organization_id);
59
+ }
54
60
  // No filter shows everyone: inactive users must stay reachable so they can
55
61
  // be reactivated from their detail page.
56
62
  if (query.active_in && query.active_in.length > 0) {
@@ -69,12 +75,7 @@ class UsersResource {
69
75
  return (0, transforms_1.toMmsList)(data, page, pageSize, count);
70
76
  }
71
77
  async getRow(userId) {
72
- const { data, error } = await this.supabase
73
- .from('users')
74
- .select('*')
75
- .eq('mms_id', userId)
76
- .eq('organization_id', this.auth.organization_id)
77
- .single();
78
+ const { data, error } = await (0, tenancy_1.scopeToOrganization)(this.supabase.from('users').select('*').eq('mms_id', userId), this.auth).single();
78
79
  if (error)
79
80
  throw (0, errors_1.mapPostgrestError)(error);
80
81
  return (0, audit_1.withoutInternalId)(data);
@@ -103,11 +104,7 @@ class UsersResource {
103
104
  * `active` is not consulted: a deactivated report's history stays visible to their manager.
104
105
  */
105
106
  async idsManagedBy(managerId) {
106
- const { data, error } = await this.supabase
107
- .from('users')
108
- .select('mms_id')
109
- .eq('organization_id', this.auth.organization_id)
110
- .or(`manager_id.eq.${managerId},secondary_manager_id.eq.${managerId}`);
107
+ const { data, error } = await (0, tenancy_1.scopeToOrganization)(this.supabase.from('users').select('mms_id'), this.auth).or(`manager_id.eq.${managerId},secondary_manager_id.eq.${managerId}`);
111
108
  if (error)
112
109
  throw (0, errors_1.mapPostgrestError)(error);
113
110
  return (data ?? []).map((row) => row.mms_id);
@@ -117,10 +114,9 @@ class UsersResource {
117
114
  * are timestamps), and the working week. Everyone in the organization, or just `userIds`.
118
115
  */
119
116
  async employment(userIds) {
120
- let employmentQuery = this.supabase
117
+ let employmentQuery = (0, tenancy_1.scopeToOrganization)(this.supabase
121
118
  .from('users')
122
- .select('mms_id, name, surname, email, profile_image, active, start_date, end_date, working_days')
123
- .eq('organization_id', this.auth.organization_id);
119
+ .select('mms_id, name, surname, email, profile_image, active, start_date, end_date, working_days'), this.auth);
124
120
  if (userIds) {
125
121
  employmentQuery = employmentQuery.in('mms_id', userIds);
126
122
  }
@@ -135,22 +131,13 @@ class UsersResource {
135
131
  }
136
132
  /** Seats in use. Counts rows rather than fetching them. */
137
133
  async activeCount() {
138
- const { count, error } = await this.supabase
139
- .from('users')
140
- .select('mms_id', { count: 'exact', head: true })
141
- .eq('organization_id', this.auth.organization_id)
142
- .eq('active', true);
134
+ const { count, error } = await (0, tenancy_1.scopeToOrganization)(this.supabase.from('users').select('mms_id', { count: 'exact', head: true }), this.auth).eq('active', true);
143
135
  if (error)
144
136
  throw (0, errors_1.mapPostgrestError)(error);
145
137
  return count ?? 0;
146
138
  }
147
139
  async isActive(userId) {
148
- const { data, error } = await this.supabase
149
- .from('users')
150
- .select('active')
151
- .eq('mms_id', userId)
152
- .eq('organization_id', this.auth.organization_id)
153
- .single();
140
+ const { data, error } = await (0, tenancy_1.scopeToOrganization)(this.supabase.from('users').select('active').eq('mms_id', userId), this.auth).single();
154
141
  if (error)
155
142
  throw (0, errors_1.mapPostgrestError)(error);
156
143
  return data.active;
@@ -176,7 +163,7 @@ class UsersResource {
176
163
  */
177
164
  async setProfileImage(userId, file) {
178
165
  const { name, extension } = (0, paths_1.splitFileName)((0, paths_1.sanitizeFileName)(file.name));
179
- const path = (0, paths_2.profileImagePath)(this.auth.organization_id, userId, name, extension);
166
+ const path = (0, paths_2.profileImagePath)((0, tenancy_1.requireOrganization)(this.auth), userId, name, extension);
180
167
  const previous = (0, paths_2.profileImageObjectPath)((await this.getRow(userId)).profile_image);
181
168
  const { error } = await this.supabase.storage
182
169
  .from(paths_2.PROFILE_PICTURES_BUCKET)
@@ -17,6 +17,8 @@ export declare const isClockTime: (value: unknown, allowEndOfDay?: boolean) => v
17
17
  export declare const IsClockTime: ({ allowEndOfDay, ...options }?: ValidationOptions & {
18
18
  allowEndOfDay?: boolean;
19
19
  }) => PropertyDecorator;
20
+ /** The password rules every GoTrue account is held to: a tenant user's and a staff member's. */
21
+ export declare const MatchesPasswordRules: () => PropertyDecorator;
20
22
  export declare function IsNullable(validationOptions?: ValidationOptions): PropertyDecorator;
21
23
  /**
22
24
  * An empty string from a cleared form field means "none". It becomes null before validation,
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.IsClockTime = exports.isClockTime = exports.IsCalendarDate = exports.isCalendarDate = void 0;
9
+ exports.MatchesPasswordRules = exports.IsClockTime = exports.isClockTime = exports.IsCalendarDate = exports.isCalendarDate = void 0;
10
10
  exports.IsNullable = IsNullable;
11
11
  exports.EmptyToNull = EmptyToNull;
12
12
  const class_validator_1 = require("class-validator");
@@ -56,6 +56,11 @@ ClockTimeConstraint = __decorate([
56
56
  */
57
57
  const IsClockTime = ({ allowEndOfDay = false, ...options } = {}) => (0, class_validator_1.Validate)(ClockTimeConstraint, [allowEndOfDay], options);
58
58
  exports.IsClockTime = IsClockTime;
59
+ /** The password rules every GoTrue account is held to: a tenant user's and a staff member's. */
60
+ const MatchesPasswordRules = () => (0, class_validator_1.Matches)(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#$%^&*])/, {
61
+ message: 'Password must contain at least 1 uppercase letter, 1 lowercase letter, 1 number, and 1 special character (!@#$%^&*)',
62
+ });
63
+ exports.MatchesPasswordRules = MatchesPasswordRules;
59
64
  function IsNullable(validationOptions) {
60
65
  return (0, class_validator_1.ValidateIf)((_object, value) => value !== null, validationOptions);
61
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@managemint-solutions/sdk",
3
- "version": "0.52.0",
3
+ "version": "0.54.0",
4
4
  "description": "Typed Supabase data-access SDK for ManageMint Solutions",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Scott Bebington <scottbebington@gmail.com>",
@@ -51,7 +51,7 @@
51
51
  "testEnvironment": "node"
52
52
  },
53
53
  "dependencies": {
54
- "@managemint-solutions/entities": "^1.34.0"
54
+ "@managemint-solutions/entities": "^1.36.0"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "@nestjs/common": "^11.0.0",