@managemint-solutions/sdk 0.67.0 → 0.69.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.
- package/dist/additional-details/dto.d.ts +9 -1
- package/dist/additional-details/dto.js +46 -1
- package/dist/additional-details/index.d.ts +8 -0
- package/dist/additional-details/index.js +12 -0
- package/dist/audit/index.d.ts +6 -0
- package/dist/audit/index.js +47 -0
- package/dist/billing/dto.d.ts +8 -0
- package/dist/billing/dto.js +22 -1
- package/dist/configs/dto.d.ts +5 -1
- package/dist/configs/dto.js +10 -1
- package/dist/crons/dto.d.ts +9 -0
- package/dist/crons/dto.js +43 -0
- package/dist/crons/index.d.ts +38 -0
- package/dist/crons/index.js +109 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.js +14 -4
- package/dist/notes/dto.d.ts +9 -1
- package/dist/notes/dto.js +46 -1
- package/dist/notes/index.d.ts +9 -0
- package/dist/notes/index.js +13 -0
- package/dist/organizations/index.js +1 -0
- package/dist/service-client/index.d.ts +10 -0
- package/dist/service-client/index.js +16 -0
- package/dist/staff-client.d.ts +18 -1
- package/dist/staff-client.js +30 -0
- package/dist/statuses/dto.d.ts +9 -1
- package/dist/statuses/dto.js +46 -1
- package/dist/statuses/index.d.ts +7 -2
- package/dist/statuses/index.js +18 -10
- package/dist/supporting-files/dto.d.ts +9 -1
- package/dist/supporting-files/dto.js +46 -1
- package/dist/supporting-files/index.d.ts +5 -0
- package/dist/supporting-files/index.js +9 -0
- package/dist/tenancy.d.ts +12 -0
- package/dist/tenancy.js +22 -1
- package/package.json +2 -2
|
@@ -9,9 +9,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.SupportingFileNamesDto = exports.GetSupportingFilesDto = exports.SupportingFileIdDto = exports.MAX_FILES_PER_UPLOAD = void 0;
|
|
12
|
+
exports.GetAllSupportingFilesDto = exports.SupportingFileNamesDto = exports.GetSupportingFilesDto = exports.SupportingFileIdDto = exports.MAX_FILES_PER_UPLOAD = void 0;
|
|
13
13
|
const class_validator_1 = require("class-validator");
|
|
14
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
15
|
const enum_1 = require("@managemint-solutions/entities/supporting-files/enum");
|
|
16
|
+
const validators_1 = require("../validators");
|
|
15
17
|
// class-validator versions of the shared DTO types from @managemint-solutions/entities.
|
|
16
18
|
// Each class `implements` its entities type so the wire contract cannot drift.
|
|
17
19
|
/** Files accepted in one upload. */
|
|
@@ -51,3 +53,46 @@ __decorate([
|
|
|
51
53
|
(0, class_validator_1.IsNotEmpty)({ each: true, message: 'A file name cannot be empty' }),
|
|
52
54
|
__metadata("design:type", Array)
|
|
53
55
|
], SupportingFileNamesDto.prototype, "names", void 0);
|
|
56
|
+
/** The admin api's GET /supporting-files: every organization's supporting files, a page at a time. */
|
|
57
|
+
class GetAllSupportingFilesDto {
|
|
58
|
+
page = 1;
|
|
59
|
+
page_size = 25;
|
|
60
|
+
organization_id;
|
|
61
|
+
entity_type;
|
|
62
|
+
search;
|
|
63
|
+
}
|
|
64
|
+
exports.GetAllSupportingFilesDto = GetAllSupportingFilesDto;
|
|
65
|
+
__decorate([
|
|
66
|
+
(0, class_validator_1.IsOptional)(),
|
|
67
|
+
(0, class_transformer_1.Transform)(({ value }) => (value ? Number(value) : 1), { toClassOnly: true }),
|
|
68
|
+
(0, class_validator_1.IsNumber)({}, { message: 'Page must be a number' }),
|
|
69
|
+
(0, class_validator_1.Min)(1, { message: 'Page must be at least 1' }),
|
|
70
|
+
__metadata("design:type", Number)
|
|
71
|
+
], GetAllSupportingFilesDto.prototype, "page", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, class_validator_1.IsOptional)(),
|
|
74
|
+
(0, class_transformer_1.Transform)(({ value }) => (value ? Number(value) : 25), { toClassOnly: true }),
|
|
75
|
+
(0, class_validator_1.IsNumber)({}, { message: 'Page size must be a number' }),
|
|
76
|
+
(0, class_validator_1.Min)(1, { message: 'Page size must be at least 1' }),
|
|
77
|
+
(0, class_validator_1.Max)(100, { message: 'Page size cannot exceed 100' }),
|
|
78
|
+
__metadata("design:type", Number)
|
|
79
|
+
], GetAllSupportingFilesDto.prototype, "page_size", void 0);
|
|
80
|
+
__decorate([
|
|
81
|
+
(0, class_validator_1.IsOptional)(),
|
|
82
|
+
(0, validators_1.IsNullable)(),
|
|
83
|
+
(0, class_validator_1.IsUUID)('7', { message: 'Invalid organization ID format' }),
|
|
84
|
+
__metadata("design:type", Object)
|
|
85
|
+
], GetAllSupportingFilesDto.prototype, "organization_id", void 0);
|
|
86
|
+
__decorate([
|
|
87
|
+
(0, class_validator_1.IsOptional)(),
|
|
88
|
+
(0, validators_1.IsNullable)(),
|
|
89
|
+
(0, class_validator_1.IsEnum)(enum_1.SupportingFilesEntityTypes, { message: 'Invalid record type' }),
|
|
90
|
+
__metadata("design:type", Object)
|
|
91
|
+
], GetAllSupportingFilesDto.prototype, "entity_type", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
(0, class_validator_1.IsOptional)(),
|
|
94
|
+
(0, validators_1.IsNullable)(),
|
|
95
|
+
(0, class_validator_1.IsString)({ message: 'Invalid search' }),
|
|
96
|
+
(0, class_validator_1.MaxLength)(200, { message: 'Search cannot exceed 200 characters' }),
|
|
97
|
+
__metadata("design:type", Object)
|
|
98
|
+
], GetAllSupportingFilesDto.prototype, "search", void 0);
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { SupportingFileEntity, SupportingFilePresignedUrl, SupportingFileUploadTarget } from '@managemint-solutions/entities/supporting-files';
|
|
2
|
+
import type { StaffSupportingFileRow } from '@managemint-solutions/entities/supporting-files';
|
|
3
|
+
import type { MmsList } from '@managemint-solutions/entities/common';
|
|
2
4
|
import { SupportingFilesEntityTypes } from '@managemint-solutions/entities/supporting-files/enum';
|
|
3
5
|
import { type AuditResource, type ResourceActor } from '../audit';
|
|
4
6
|
import type { TypedSupabaseClient } from '../client';
|
|
5
7
|
export * from './dto';
|
|
8
|
+
import type { GetAllSupportingFilesDto } from './dto';
|
|
6
9
|
export * from './paths';
|
|
7
10
|
export declare class SupportingFilesResource {
|
|
8
11
|
private readonly supabase;
|
|
@@ -25,6 +28,8 @@ export declare class SupportingFilesResource {
|
|
|
25
28
|
organization_id: string;
|
|
26
29
|
}>;
|
|
27
30
|
list(entity: SupportingFilesEntityTypes, entityId: string): Promise<SupportingFileEntity[]>;
|
|
31
|
+
/** The admin portal's Supporting Files list: every file on a record type in `entityTypes`, newest first. */
|
|
32
|
+
listAll(query: GetAllSupportingFilesDto, entityTypes: string[]): Promise<MmsList<StaffSupportingFileRow>>;
|
|
28
33
|
/**
|
|
29
34
|
* Where the caller puts each file: one signed upload URL per name, in request order, valid
|
|
30
35
|
* for two hours, into the organization's prefix. Storage checks the bucket's INSERT policy
|
|
@@ -21,9 +21,11 @@ const audit_1 = require("../audit");
|
|
|
21
21
|
const errors_1 = require("../errors");
|
|
22
22
|
const won_1 = require("../leads/won");
|
|
23
23
|
const tenancy_1 = require("../tenancy");
|
|
24
|
+
const transforms_1 = require("../transforms");
|
|
24
25
|
const paths_1 = require("./paths");
|
|
25
26
|
__exportStar(require("./dto"), exports);
|
|
26
27
|
__exportStar(require("./paths"), exports);
|
|
28
|
+
const SUPPORTING_FILE_LIST_SELECT = 'mms_id, created_at, name, extension, entity_type, entity_id, created_by:user_profiles!created_by(*), organization:organizations!organization_id(mms_id, name)';
|
|
27
29
|
/** How long a presigned download URL stays valid. */
|
|
28
30
|
const SIGNED_URL_TTL_SECONDS = 300;
|
|
29
31
|
/** Storage calls per file (minting an upload URL, checking an object) run concurrently in batches of this size. */
|
|
@@ -98,6 +100,13 @@ class SupportingFilesResource {
|
|
|
98
100
|
throw (0, errors_1.mapPostgrestError)(error);
|
|
99
101
|
return data;
|
|
100
102
|
}
|
|
103
|
+
/** The admin portal's Supporting Files list: every file on a record type in `entityTypes`, newest first. */
|
|
104
|
+
async listAll(query, entityTypes) {
|
|
105
|
+
const { data, error, count } = await (0, tenancy_1.filterStaffList)(this.supabase.from('supporting_files').select(SUPPORTING_FILE_LIST_SELECT, { count: 'exact' }), query, ['name'], entityTypes).order('created_at', { ascending: false });
|
|
106
|
+
if (error)
|
|
107
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
108
|
+
return (0, transforms_1.toMmsList)(data, query.page, query.page_size, count);
|
|
109
|
+
}
|
|
101
110
|
/**
|
|
102
111
|
* Where the caller puts each file: one signed upload URL per name, in request order, valid
|
|
103
112
|
* for two hours, into the organization's prefix. Storage checks the bucket's INSERT policy
|
package/dist/tenancy.d.ts
CHANGED
|
@@ -11,3 +11,15 @@ export declare const requireOrganization: (actor: {
|
|
|
11
11
|
export declare const withOrganization: (select: string, actor: {
|
|
12
12
|
organization_id: string | null;
|
|
13
13
|
}) => string;
|
|
14
|
+
/**
|
|
15
|
+
* A staff list's page with its filters applied: the organization, the record type, a text search
|
|
16
|
+
* over `searchColumns`, and when given, the record types a row may belong to (those the caller
|
|
17
|
+
* may read). The read spans every organization the caller's policies let it see.
|
|
18
|
+
*/
|
|
19
|
+
export declare const filterStaffList: <Q extends PostgrestFilterBuilder<any, any, any, any, any, any, any>>(query: Q, filters: {
|
|
20
|
+
page: number;
|
|
21
|
+
page_size: number;
|
|
22
|
+
organization_id?: string | null;
|
|
23
|
+
entity_type?: string | null;
|
|
24
|
+
search?: string | null;
|
|
25
|
+
}, searchColumns: readonly string[], entityTypes?: string[]) => Q;
|
package/dist/tenancy.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.withOrganization = exports.requireOrganization = exports.scopeToOrganization = void 0;
|
|
3
|
+
exports.filterStaffList = exports.withOrganization = exports.requireOrganization = exports.scopeToOrganization = void 0;
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
|
+
const transforms_1 = require("./transforms");
|
|
5
6
|
// How a resource scopes itself to the caller's organization. A tenant (`AuthContext`) reads and
|
|
6
7
|
// writes inside their own; staff (`StaffContext`, `organization_id: null`) read across every
|
|
7
8
|
// organization, as their role's policies allow, and write nothing.
|
|
@@ -23,3 +24,23 @@ exports.requireOrganization = requireOrganization;
|
|
|
23
24
|
/** A select, plus the row's organization on a staff read so the row says whose it is. */
|
|
24
25
|
const withOrganization = (select, actor) => actor.organization_id === null ? `${select}, organization:organizations!organization_id(mms_id, name)` : select;
|
|
25
26
|
exports.withOrganization = withOrganization;
|
|
27
|
+
/**
|
|
28
|
+
* A staff list's page with its filters applied: the organization, the record type, a text search
|
|
29
|
+
* over `searchColumns`, and when given, the record types a row may belong to (those the caller
|
|
30
|
+
* may read). The read spans every organization the caller's policies let it see.
|
|
31
|
+
*/
|
|
32
|
+
const filterStaffList = (query, filters, searchColumns, entityTypes) => {
|
|
33
|
+
const from = (filters.page - 1) * filters.page_size;
|
|
34
|
+
let builder = query.range(from, from + filters.page_size - 1);
|
|
35
|
+
if (filters.organization_id)
|
|
36
|
+
builder = builder.eq('organization_id', filters.organization_id);
|
|
37
|
+
if (filters.entity_type)
|
|
38
|
+
builder = builder.eq('entity_type', filters.entity_type);
|
|
39
|
+
if (entityTypes)
|
|
40
|
+
builder = builder.in('entity_type', entityTypes);
|
|
41
|
+
const search = filters.search?.trim();
|
|
42
|
+
if (search)
|
|
43
|
+
builder = builder.or((0, transforms_1.orIlike)(searchColumns, search));
|
|
44
|
+
return builder;
|
|
45
|
+
};
|
|
46
|
+
exports.filterStaffList = filterStaffList;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@managemint-solutions/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.69.0",
|
|
4
4
|
"description": "Typed Supabase data-access SDK for ManageMint Solutions",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "Scott Bebington <scottbebington@gmail.com>",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"testEnvironment": "node"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@managemint-solutions/entities": "^1.
|
|
58
|
+
"@managemint-solutions/entities": "^1.51.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@nestjs/common": "^11.0.0",
|