@managemint-solutions/sdk 0.25.0 → 0.26.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/README.md +6 -2
- package/dist/projects/dto.d.ts +3 -1
- package/dist/projects/dto.js +22 -3
- package/dist/projects/index.js +9 -0
- package/dist/tasks/dto.d.ts +3 -1
- package/dist/tasks/dto.js +22 -3
- package/dist/tasks/index.js +9 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -144,7 +144,9 @@ const page = await supabase.projects.list({
|
|
|
144
144
|
client_id: clientId, // a UUID, or the base64-JSON option value a select sends
|
|
145
145
|
});
|
|
146
146
|
// `search` matches name/specification; `created_*`, `start_date_*` and `end_date_*` bound the
|
|
147
|
-
// date columns, and `status_id_in` filters by status.
|
|
147
|
+
// date columns, and `status_id_in` filters by status. `status_id_not_in` is the exclusion form —
|
|
148
|
+
// it keeps rows with no status, which `status_id_in` cannot express. `completed` is carried but
|
|
149
|
+
// not acted on here: the api resolves it to status ids against the statuses catalogue first.
|
|
148
150
|
|
|
149
151
|
const project = await supabase.projects.create({
|
|
150
152
|
name: 'Website rebuild',
|
|
@@ -178,7 +180,9 @@ const page = await supabase.tasks.list({
|
|
|
178
180
|
priority_in: [1, 3],
|
|
179
181
|
});
|
|
180
182
|
// `search` matches name/description, and `client_id`, `assigned_to_id`, the date ranges and
|
|
181
|
-
// `status_id_in` narrow it further.
|
|
183
|
+
// `status_id_in` narrow it further. `status_id_not_in` excludes statuses while keeping rows with
|
|
184
|
+
// no status; `completed` is carried but not acted on here — the api resolves it to status ids
|
|
185
|
+
// against the statuses catalogue first.
|
|
182
186
|
|
|
183
187
|
const task = await supabase.tasks.create({
|
|
184
188
|
name: 'Draft the proposal',
|
package/dist/projects/dto.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CreateProjectDto as CreateProjectDtoType, GetProjectsDto as GetProjectsDtoType, ProjectIdDto as ProjectIdDtoType, UpdateProjectDto as UpdateProjectDtoType } from '@managemint-solutions/entities/projects/dto';
|
|
2
|
-
export declare class GetProjectsDto implements Omit<GetProjectsDtoType, 'status_id_in'> {
|
|
2
|
+
export declare class GetProjectsDto implements Omit<GetProjectsDtoType, 'status_id_in' | 'status_id_not_in'> {
|
|
3
3
|
readonly search?: string | null;
|
|
4
4
|
readonly page: number;
|
|
5
5
|
readonly page_size: number;
|
|
@@ -10,6 +10,8 @@ export declare class GetProjectsDto implements Omit<GetProjectsDtoType, 'status_
|
|
|
10
10
|
readonly end_date_after?: string | null;
|
|
11
11
|
readonly end_date_before?: string | null;
|
|
12
12
|
readonly status_id_in?: string[] | null;
|
|
13
|
+
readonly status_id_not_in?: string[] | null;
|
|
14
|
+
readonly completed?: boolean | null;
|
|
13
15
|
readonly client_id?: string | null;
|
|
14
16
|
readonly archive: boolean;
|
|
15
17
|
}
|
package/dist/projects/dto.js
CHANGED
|
@@ -16,9 +16,10 @@ const transforms_1 = require("../transforms");
|
|
|
16
16
|
const validators_1 = require("../validators");
|
|
17
17
|
// class-validator versions of the shared DTO types from @managemint-solutions/entities, so the
|
|
18
18
|
// wire contract cannot drift.
|
|
19
|
-
// `status_id_in`
|
|
20
|
-
// CSV wire
|
|
21
|
-
// `string[] | null` the query builder feeds to `.in('status_id', ...)
|
|
19
|
+
// `status_id_in` and `status_id_not_in` are omitted from the implemented type on purpose: the
|
|
20
|
+
// entities type carries the CSV wire values (`string | null`), while this class carries the
|
|
21
|
+
// `@Transform`-parsed `string[] | null` the query builder feeds to `.in('status_id', ...)` and to
|
|
22
|
+
// the `status_id.is.null,status_id.not.in.(...)` exclusion.
|
|
22
23
|
class GetProjectsDto {
|
|
23
24
|
search;
|
|
24
25
|
page = 1;
|
|
@@ -30,6 +31,10 @@ class GetProjectsDto {
|
|
|
30
31
|
end_date_after;
|
|
31
32
|
end_date_before;
|
|
32
33
|
status_id_in;
|
|
34
|
+
status_id_not_in;
|
|
35
|
+
// Tri-state: true = only completed rows, false = only rows that are not completed, omitted = no
|
|
36
|
+
// completion filter. The api resolves it to status ids before it reaches `list`.
|
|
37
|
+
completed;
|
|
33
38
|
client_id;
|
|
34
39
|
archive = false;
|
|
35
40
|
}
|
|
@@ -99,6 +104,20 @@ __decorate([
|
|
|
99
104
|
(0, class_validator_1.IsUUID)('7', { each: true, message: 'Each status ID must be a valid UUID v7' }),
|
|
100
105
|
__metadata("design:type", Object)
|
|
101
106
|
], GetProjectsDto.prototype, "status_id_in", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
(0, class_validator_1.IsOptional)(),
|
|
109
|
+
(0, validators_1.IsNullable)(),
|
|
110
|
+
(0, class_transformer_1.Transform)(({ value }) => value ? value.split(',').map((id) => id.trim()) : null, { toClassOnly: true }),
|
|
111
|
+
(0, class_validator_1.IsUUID)('7', { each: true, message: 'Each status ID must be a valid UUID v7' }),
|
|
112
|
+
__metadata("design:type", Object)
|
|
113
|
+
], GetProjectsDto.prototype, "status_id_not_in", void 0);
|
|
114
|
+
__decorate([
|
|
115
|
+
(0, class_validator_1.IsOptional)(),
|
|
116
|
+
(0, validators_1.IsNullable)(),
|
|
117
|
+
(0, class_transformer_1.Transform)(({ value }) => value === 'true' ? true : value === 'false' ? false : value, { toClassOnly: true }),
|
|
118
|
+
(0, class_validator_1.IsBoolean)({ message: 'Completed must be true or false' }),
|
|
119
|
+
__metadata("design:type", Object)
|
|
120
|
+
], GetProjectsDto.prototype, "completed", void 0);
|
|
102
121
|
__decorate([
|
|
103
122
|
(0, class_validator_1.IsOptional)(),
|
|
104
123
|
(0, validators_1.IsNullable)(),
|
package/dist/projects/index.js
CHANGED
|
@@ -124,6 +124,15 @@ class ProjectsResource {
|
|
|
124
124
|
if (query.status_id_in && query.status_id_in.length > 0) {
|
|
125
125
|
projectsQuery = projectsQuery.in('status_id', query.status_id_in);
|
|
126
126
|
}
|
|
127
|
+
// Excluding statuses has to be spelled out as "no status OR not one of these": PostgREST can
|
|
128
|
+
// only filter a parent row by an embedded column with `!inner`, which would drop projects that
|
|
129
|
+
// have no status at all — and a project with no status is not complete, so it belongs in the
|
|
130
|
+
// default view. SQL's `NOT IN` drops nulls for the same reason, hence the explicit null arm.
|
|
131
|
+
// The ids are `@IsUUID('7')`-validated by the DTO, so interpolating them is safe. Repeated
|
|
132
|
+
// `or` params are ANDed by PostgREST, so this composes with the search filter above.
|
|
133
|
+
if (query.status_id_not_in && query.status_id_not_in.length > 0) {
|
|
134
|
+
projectsQuery = projectsQuery.or(`status_id.is.null,status_id.not.in.(${query.status_id_not_in.join(',')})`);
|
|
135
|
+
}
|
|
127
136
|
if (query.client_id) {
|
|
128
137
|
projectsQuery = projectsQuery.eq('client_id', query.client_id);
|
|
129
138
|
}
|
package/dist/tasks/dto.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { CreateTaskDto as CreateTaskDtoType, GetTasksDto as GetTasksDtoType
|
|
|
2
2
|
export declare class TaskIdDto implements TaskIdDtoType {
|
|
3
3
|
readonly taskId: string;
|
|
4
4
|
}
|
|
5
|
-
export declare class GetTasksDto implements Omit<GetTasksDtoType, 'status_id_in' | 'priority_in'> {
|
|
5
|
+
export declare class GetTasksDto implements Omit<GetTasksDtoType, 'status_id_in' | 'status_id_not_in' | 'priority_in'> {
|
|
6
6
|
readonly search?: string | null;
|
|
7
7
|
readonly page: number;
|
|
8
8
|
readonly page_size: number;
|
|
@@ -16,6 +16,8 @@ export declare class GetTasksDto implements Omit<GetTasksDtoType, 'status_id_in'
|
|
|
16
16
|
readonly end_date_after?: string | null;
|
|
17
17
|
readonly end_date_before?: string | null;
|
|
18
18
|
readonly status_id_in?: string[] | null;
|
|
19
|
+
readonly status_id_not_in?: string[] | null;
|
|
20
|
+
readonly completed?: boolean | null;
|
|
19
21
|
readonly priority_in?: number[] | null;
|
|
20
22
|
readonly archive: boolean;
|
|
21
23
|
}
|
package/dist/tasks/dto.js
CHANGED
|
@@ -25,9 +25,10 @@ __decorate([
|
|
|
25
25
|
,
|
|
26
26
|
__metadata("design:type", String)
|
|
27
27
|
], TaskIdDto.prototype, "taskId", void 0);
|
|
28
|
-
// `status_id_in` and `priority_in` are omitted from the implemented type on
|
|
29
|
-
// type carries the CSV wire values, while this class carries the
|
|
30
|
-
// query builder feeds to `.in('status_id', ...)` /
|
|
28
|
+
// `status_id_in`, `status_id_not_in` and `priority_in` are omitted from the implemented type on
|
|
29
|
+
// purpose: the entities type carries the CSV wire values, while this class carries the
|
|
30
|
+
// `@Transform`-parsed arrays the query builder feeds to `.in('status_id', ...)` /
|
|
31
|
+
// `.in('priority', ...)` and to the `status_id.is.null,status_id.not.in.(...)` exclusion.
|
|
31
32
|
class GetTasksDto {
|
|
32
33
|
search;
|
|
33
34
|
page = 1;
|
|
@@ -42,6 +43,10 @@ class GetTasksDto {
|
|
|
42
43
|
end_date_after;
|
|
43
44
|
end_date_before;
|
|
44
45
|
status_id_in;
|
|
46
|
+
status_id_not_in;
|
|
47
|
+
// Tri-state: true = only completed rows, false = only rows that are not completed, omitted = no
|
|
48
|
+
// completion filter. The api resolves it to status ids before it reaches `list`.
|
|
49
|
+
completed;
|
|
45
50
|
priority_in;
|
|
46
51
|
archive = false;
|
|
47
52
|
}
|
|
@@ -135,6 +140,20 @@ __decorate([
|
|
|
135
140
|
(0, class_validator_1.IsUUID)('7', { each: true, message: 'Invalid status ID format' }),
|
|
136
141
|
__metadata("design:type", Object)
|
|
137
142
|
], GetTasksDto.prototype, "status_id_in", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
(0, class_validator_1.IsOptional)(),
|
|
145
|
+
(0, validators_1.IsNullable)(),
|
|
146
|
+
(0, class_transformer_1.Transform)(({ value }) => value ? value.split(',').map((id) => id.trim()) : null, { toClassOnly: true }),
|
|
147
|
+
(0, class_validator_1.IsUUID)('7', { each: true, message: 'Invalid status ID format' }),
|
|
148
|
+
__metadata("design:type", Object)
|
|
149
|
+
], GetTasksDto.prototype, "status_id_not_in", void 0);
|
|
150
|
+
__decorate([
|
|
151
|
+
(0, class_validator_1.IsOptional)(),
|
|
152
|
+
(0, validators_1.IsNullable)(),
|
|
153
|
+
(0, class_transformer_1.Transform)(({ value }) => value === 'true' ? true : value === 'false' ? false : value, { toClassOnly: true }),
|
|
154
|
+
(0, class_validator_1.IsBoolean)({ message: 'Completed must be true or false' }),
|
|
155
|
+
__metadata("design:type", Object)
|
|
156
|
+
], GetTasksDto.prototype, "completed", void 0);
|
|
138
157
|
__decorate([
|
|
139
158
|
(0, class_validator_1.IsOptional)(),
|
|
140
159
|
(0, validators_1.IsNullable)(),
|
package/dist/tasks/index.js
CHANGED
|
@@ -133,6 +133,15 @@ class TasksResource {
|
|
|
133
133
|
if (query.status_id_in && query.status_id_in.length > 0) {
|
|
134
134
|
tasksQuery = tasksQuery.in('status_id', query.status_id_in);
|
|
135
135
|
}
|
|
136
|
+
// Excluding statuses has to be spelled out as "no status OR not one of these": PostgREST can
|
|
137
|
+
// only filter a parent row by an embedded column with `!inner`, which would drop tasks that
|
|
138
|
+
// have no status at all — and a task with no status is not complete, so it belongs in the
|
|
139
|
+
// default view. SQL's `NOT IN` drops nulls for the same reason, hence the explicit null arm.
|
|
140
|
+
// The ids are `@IsUUID('7')`-validated by the DTO, so interpolating them is safe. Repeated
|
|
141
|
+
// `or` params are ANDed by PostgREST, so this composes with the search filter above.
|
|
142
|
+
if (query.status_id_not_in && query.status_id_not_in.length > 0) {
|
|
143
|
+
tasksQuery = tasksQuery.or(`status_id.is.null,status_id.not.in.(${query.status_id_not_in.join(',')})`);
|
|
144
|
+
}
|
|
136
145
|
if (query.priority_in && query.priority_in.length > 0) {
|
|
137
146
|
tasksQuery = tasksQuery.in('priority', query.priority_in);
|
|
138
147
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@managemint-solutions/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Typed Supabase data-access SDK for ManageMint Solutions",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "Scott Bebington <scottbebington@gmail.com>",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"testEnvironment": "node"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@managemint-solutions/entities": "^1.
|
|
50
|
+
"@managemint-solutions/entities": "^1.10.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@nestjs/common": "^11.0.0",
|