@managemint-solutions/sdk 0.1.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.
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Constants = void 0;
4
+ exports.Constants = {
5
+ graphql_public: {
6
+ Enums: {},
7
+ },
8
+ public: {
9
+ Enums: {},
10
+ },
11
+ };
12
+ //# sourceMappingURL=database.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.types.js","sourceRoot":"","sources":["../src/database.types.ts"],"names":[],"mappings":";;;AAikFa,QAAA,SAAS,GAAG;IACvB,cAAc,EAAE;QACd,KAAK,EAAE,EAAE;KACV;IACD,MAAM,EAAE;QACN,KAAK,EAAE,EAAE;KACV;CACO,CAAA"}
@@ -0,0 +1,29 @@
1
+ import type { PostgrestError } from '@supabase/supabase-js';
2
+ export type SupabaseClientErrorInit = {
3
+ /** HTTP status the consumer should respond with. */
4
+ status: number;
5
+ /** Error category shown to the client, e.g. 'Database Error'. */
6
+ error: string;
7
+ /** Human-readable message shown to the client. */
8
+ message: string;
9
+ /** Underlying Postgrest/Postgres code, when there is one. */
10
+ code?: string;
11
+ };
12
+ /**
13
+ * Every error the SDK throws. It already carries the HTTP status and the body the
14
+ * consumer sends back to the client (`toResponse()`), so the api needs no mapping.
15
+ */
16
+ export declare class SupabaseClientError extends Error {
17
+ readonly status: number;
18
+ readonly error: string;
19
+ readonly code?: string;
20
+ constructor({ status, error, message, code }: SupabaseClientErrorInit, options?: {
21
+ cause?: unknown;
22
+ });
23
+ toResponse(): {
24
+ error: string;
25
+ message: string;
26
+ };
27
+ }
28
+ /** Converts a raw Postgrest error into the SupabaseClientError the SDK throws. */
29
+ export declare const mapPostgrestError: (error: PostgrestError) => SupabaseClientError;
package/dist/errors.js ADDED
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mapPostgrestError = exports.SupabaseClientError = void 0;
4
+ /**
5
+ * Every error the SDK throws. It already carries the HTTP status and the body the
6
+ * consumer sends back to the client (`toResponse()`), so the api needs no mapping.
7
+ */
8
+ class SupabaseClientError extends Error {
9
+ status;
10
+ error;
11
+ code;
12
+ constructor({ status, error, message, code }, options) {
13
+ super(message, options);
14
+ this.name = 'SupabaseClientError';
15
+ this.status = status;
16
+ this.error = error;
17
+ this.code = code;
18
+ }
19
+ toResponse() {
20
+ return { error: this.error, message: this.message };
21
+ }
22
+ }
23
+ exports.SupabaseClientError = SupabaseClientError;
24
+ const POSTGREST_CODE_TO_HTTP_STATUS = {
25
+ // Group 0 - Connection
26
+ PGRST000: 503,
27
+ PGRST001: 503,
28
+ PGRST002: 503,
29
+ PGRST003: 504,
30
+ // Group 1 - Api Request
31
+ PGRST100: 400,
32
+ PGRST101: 405,
33
+ PGRST102: 400,
34
+ PGRST103: 416,
35
+ PGRST105: 405,
36
+ PGRST106: 406,
37
+ PGRST107: 415,
38
+ PGRST108: 400,
39
+ PGRST109: 400,
40
+ PGRST110: 400,
41
+ PGRST111: 500,
42
+ PGRST112: 500,
43
+ PGRST114: 400,
44
+ PGRST115: 400,
45
+ PGRST116: 406,
46
+ PGRST117: 405,
47
+ PGRST118: 400,
48
+ PGRST119: 400,
49
+ PGRST120: 400,
50
+ PGRST121: 500,
51
+ PGRST122: 400,
52
+ // Group 2 - Schema Cache
53
+ PGRST200: 400,
54
+ PGRST201: 300,
55
+ PGRST202: 404,
56
+ PGRST203: 300,
57
+ PGRST204: 400,
58
+ // Group 3 - JWT
59
+ PGRST300: 500,
60
+ PGRST301: 401,
61
+ PGRST302: 401,
62
+ // Group X - Internal
63
+ PGRSTX00: 500,
64
+ // RLS / raised by is_authenticated_and_authorized()
65
+ 42501: 401,
66
+ 404: 404,
67
+ 400: 400,
68
+ };
69
+ const DETAILS_MESSAGES = {
70
+ 'The result contains 0 rows': 'No records found matching the query.',
71
+ };
72
+ // Raised by public.is_authenticated_and_authorized(): "Unauthorized: Missing required
73
+ // permission <slug>" / "Unauthorized: Module required <module>". New permissions and
74
+ // modules must be added here to get a readable client message.
75
+ const PERMISSION_MESSAGES = {
76
+ create_client: '(Clients - Create)',
77
+ read_client: '(Clients - Read)',
78
+ update_client: '(Clients - Update)',
79
+ delete_client: '(Clients - Delete)',
80
+ read_organizations: '(Organization - Read)',
81
+ create_users: '(Users - Create)',
82
+ read_users: '(Users - Read)',
83
+ update_users: '(Users - Update)',
84
+ delete_users: '(Users - Delete)',
85
+ read_user_permissions: '(User Permissions - Read)',
86
+ update_user_permissions: '(User Permissions - Update)',
87
+ create_clients: '(Clients - Create)',
88
+ read_clients: '(Clients - Read)',
89
+ update_clients: '(Clients - Update)',
90
+ delete_clients: '(Clients - Delete)',
91
+ create_projects: '(Projects - Create)',
92
+ read_projects: '(Projects - Read)',
93
+ update_projects: '(Projects - Update)',
94
+ delete_projects: '(Projects - Delete)',
95
+ create_budgets: '(Budgets - Create)',
96
+ read_budgets: '(Budgets - Read)',
97
+ update_budgets: '(Budgets - Update)',
98
+ delete_budgets: '(Budgets - Delete)',
99
+ create_tasks: '(Tasks - Create)',
100
+ read_tasks: '(Tasks - Read)',
101
+ update_tasks: '(Tasks - Update)',
102
+ delete_tasks: '(Tasks - Delete)',
103
+ read_notifications: '(Notifications - Read)',
104
+ create_notifications: '(Notifications - Create)',
105
+ update_notifications: '(Notifications - Update)',
106
+ delete_notifications: '(Notifications - Delete)',
107
+ create_payments: '(Payments - Create)',
108
+ update_subscriptions: '(Subscriptions - Update)',
109
+ };
110
+ const MODULE_MESSAGES = {
111
+ client: '(CRM)',
112
+ };
113
+ const PERMISSION_PREFIX = 'Unauthorized: Missing required permission ';
114
+ const MODULE_PREFIX = 'Unauthorized: Module required ';
115
+ const readableMessage = (details, message) => {
116
+ if (message.includes(PERMISSION_PREFIX)) {
117
+ return PERMISSION_PREFIX + (PERMISSION_MESSAGES[message.split(PERMISSION_PREFIX)[1]] || '');
118
+ }
119
+ if (message.includes(MODULE_PREFIX)) {
120
+ return MODULE_PREFIX + (MODULE_MESSAGES[message.split(MODULE_PREFIX)[1]] || '');
121
+ }
122
+ return DETAILS_MESSAGES[details] || message;
123
+ };
124
+ /** Converts a raw Postgrest error into the SupabaseClientError the SDK throws. */
125
+ const mapPostgrestError = (error) => new SupabaseClientError({
126
+ status: POSTGREST_CODE_TO_HTTP_STATUS[error.code] || 500,
127
+ error: 'Database Error',
128
+ message: readableMessage(error.details, error.message),
129
+ code: error.code,
130
+ }, { cause: error });
131
+ exports.mapPostgrestError = mapPostgrestError;
132
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from './client';
2
+ export * from './auth';
3
+ export * from './errors';
4
+ export * from './statuses';
5
+ export type { Database, Tables, TablesInsert, TablesUpdate, Json } from './database.types';
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./client"), exports);
18
+ __exportStar(require("./auth"), exports);
19
+ __exportStar(require("./errors"), exports);
20
+ __exportStar(require("./statuses"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,yCAAuB;AACvB,2CAAyB;AACzB,6CAA2B"}
@@ -0,0 +1,9 @@
1
+ import { HttpException } from '@nestjs/common';
2
+ import { SupabaseClientError } from '../errors';
3
+ /**
4
+ * The HttpException Nest should send for an SDK error: same status, and the body is
5
+ * exactly `{ error, message }`. Register this in a global exception filter so
6
+ * services can let SupabaseClientError propagate untouched.
7
+ */
8
+ export declare const toHttpException: (error: SupabaseClientError) => HttpException;
9
+ export declare const SupabaseUserClient: (...dataOrPipes: unknown[]) => ParameterDecorator;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SupabaseUserClient = exports.toHttpException = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const client_1 = require("../client");
6
+ const errors_1 = require("../errors");
7
+ /**
8
+ * The HttpException Nest should send for an SDK error: same status, and the body is
9
+ * exactly `{ error, message }`. Register this in a global exception filter so
10
+ * services can let SupabaseClientError propagate untouched.
11
+ */
12
+ const toHttpException = (error) => new common_1.HttpException(error.toResponse(), error.status, { cause: error });
13
+ exports.toHttpException = toHttpException;
14
+ const getEnvOrThrow = (key) => {
15
+ const value = process.env[key];
16
+ if (!value)
17
+ throw new common_1.InternalServerErrorException(`${key} is not configured`);
18
+ return value;
19
+ };
20
+ const getBearerToken = (request) => {
21
+ const header = request.headers.authorization;
22
+ if (!header)
23
+ throw new common_1.UnauthorizedException('Bearer token is required');
24
+ const [scheme, token] = header.split(' ');
25
+ if (scheme?.toLowerCase() !== 'bearer' || !token) {
26
+ throw new common_1.UnauthorizedException('Authorization header must use Bearer token');
27
+ }
28
+ return token;
29
+ };
30
+ exports.SupabaseUserClient = (0, common_1.createParamDecorator)((_, ctx) => {
31
+ const token = getBearerToken(ctx.switchToHttp().getRequest());
32
+ try {
33
+ return (0, client_1.createSupabaseClient)({
34
+ url: getEnvOrThrow('SUPABASE_URL'),
35
+ key: getEnvOrThrow('SUPABASE_PUBLISHABLE_KEY'),
36
+ accessToken: token,
37
+ });
38
+ }
39
+ catch (error) {
40
+ // Param decorators run outside the exception filters' reach for SDK errors, so
41
+ // the JWT failure is converted here.
42
+ if (error instanceof errors_1.SupabaseClientError)
43
+ throw (0, exports.toHttpException)(error);
44
+ throw error;
45
+ }
46
+ });
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nest/index.ts"],"names":[],"mappings":";;;AAAA,2CAMwB;AAExB,sCAAsE;AACtE,sCAAgD;AAEhD;;;;GAIG;AACI,MAAM,eAAe,GAAG,CAAC,KAA0B,EAAiB,EAAE,CAC3E,IAAI,sBAAa,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AAD3D,QAAA,eAAe,mBAC4C;AAExE,MAAM,aAAa,GAAG,CAAC,GAAgD,EAAU,EAAE;IACjF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,qCAA4B,CAAC,GAAG,GAAG,oBAAoB,CAAC,CAAC;IAC/E,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,OAAgB,EAAU,EAAE;IAClD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,8BAAqB,CAAC,0BAA0B,CAAC,CAAC;IACzE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,MAAM,EAAE,WAAW,EAAE,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACjD,MAAM,IAAI,8BAAqB,CAAC,4CAA4C,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEW,QAAA,kBAAkB,GAAG,IAAA,6BAAoB,EACpD,CAAC,CAAU,EAAE,GAAqB,EAAkB,EAAE;IACpD,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,OAAO,IAAA,6BAAoB,EAAC;YAC1B,GAAG,EAAE,aAAa,CAAC,cAAc,CAAC;YAClC,GAAG,EAAE,aAAa,CAAC,0BAA0B,CAAC;YAC9C,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,+EAA+E;QAC/E,qCAAqC;QACrC,IAAI,KAAK,YAAY,4BAAmB;YAAE,MAAM,IAAA,uBAAe,EAAC,KAAK,CAAC,CAAC;QACvE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CACF,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { AddStatusDto as AddStatusDtoType, GetStatusesDto as GetStatusesDtoType, StatusIdDto as StatusIdDtoType, UpdateStatusDto as UpdateStatusDtoType } from '@managemint-solutions/entities/status/dto';
2
+ import { StatusEntityTypes } from '@managemint-solutions/entities/status/enum';
3
+ import type { TablesInsert } from '../database.types';
4
+ type StatusInsertColumns = Required<Pick<TablesInsert<'statuses'>, 'label' | 'colour'>>;
5
+ export declare class StatusIdDto implements StatusIdDtoType {
6
+ readonly statusId: string;
7
+ }
8
+ export declare class GetStatusesDto implements GetStatusesDtoType {
9
+ readonly entity: StatusEntityTypes;
10
+ }
11
+ export declare class AddStatusDto implements AddStatusDtoType, StatusInsertColumns {
12
+ readonly label: string;
13
+ readonly colour: string;
14
+ readonly entity: StatusEntityTypes;
15
+ }
16
+ export declare class UpdateStatusDto implements UpdateStatusDtoType, StatusInsertColumns {
17
+ readonly label: string;
18
+ readonly colour: string;
19
+ }
20
+ export {};
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.UpdateStatusDto = exports.AddStatusDto = exports.GetStatusesDto = exports.StatusIdDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const enum_1 = require("@managemint-solutions/entities/status/enum");
15
+ class StatusIdDto {
16
+ statusId;
17
+ }
18
+ exports.StatusIdDto = StatusIdDto;
19
+ __decorate([
20
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid status ID format' }),
21
+ __metadata("design:type", String)
22
+ ], StatusIdDto.prototype, "statusId", void 0);
23
+ class GetStatusesDto {
24
+ entity;
25
+ }
26
+ exports.GetStatusesDto = GetStatusesDto;
27
+ __decorate([
28
+ (0, class_validator_1.IsEnum)(enum_1.StatusEntityTypes, { message: 'Invalid entity type' }),
29
+ __metadata("design:type", String)
30
+ ], GetStatusesDto.prototype, "entity", void 0);
31
+ class AddStatusDto {
32
+ label;
33
+ // Colour must be a valid hex code (e.g., #FFFFFF)
34
+ colour;
35
+ // `entity` is the wire name; the SDK maps it to the `entity_type` column.
36
+ entity;
37
+ }
38
+ exports.AddStatusDto = AddStatusDto;
39
+ __decorate([
40
+ (0, class_validator_1.IsString)({ message: 'Invalid label' }),
41
+ (0, class_validator_1.MinLength)(1, { message: 'Label cannot be empty' }),
42
+ (0, class_validator_1.MaxLength)(100, { message: 'Label cannot exceed 100 characters' }),
43
+ __metadata("design:type", String)
44
+ ], AddStatusDto.prototype, "label", void 0);
45
+ __decorate([
46
+ (0, class_validator_1.IsString)({ message: 'Invalid colour format' }),
47
+ (0, class_validator_1.MinLength)(7, { message: 'Colour must be a valid hex code' }),
48
+ (0, class_validator_1.MaxLength)(7, { message: 'Colour must be a valid hex code' }),
49
+ (0, class_validator_1.Matches)(/^#[0-9A-Fa-f]{6}$/, { message: 'Colour must be a valid hex code' }),
50
+ __metadata("design:type", String)
51
+ ], AddStatusDto.prototype, "colour", void 0);
52
+ __decorate([
53
+ (0, class_validator_1.IsEnum)(enum_1.StatusEntityTypes, { message: 'Invalid entity type' }),
54
+ __metadata("design:type", String)
55
+ ], AddStatusDto.prototype, "entity", void 0);
56
+ class UpdateStatusDto {
57
+ label;
58
+ // Colour must be a valid hex code (e.g., #FFFFFF)
59
+ colour;
60
+ }
61
+ exports.UpdateStatusDto = UpdateStatusDto;
62
+ __decorate([
63
+ (0, class_validator_1.IsString)({ message: 'Invalid label' }),
64
+ (0, class_validator_1.MinLength)(1, { message: 'Label cannot be empty' }),
65
+ (0, class_validator_1.MaxLength)(100, { message: 'Label cannot exceed 100 characters' }),
66
+ __metadata("design:type", String)
67
+ ], UpdateStatusDto.prototype, "label", void 0);
68
+ __decorate([
69
+ (0, class_validator_1.IsString)({ message: 'Invalid colour format' }),
70
+ (0, class_validator_1.MinLength)(7, { message: 'Colour must be a valid hex code' }),
71
+ (0, class_validator_1.MaxLength)(7, { message: 'Colour must be a valid hex code' }),
72
+ (0, class_validator_1.Matches)(/^#[0-9A-Fa-f]{6}$/, { message: 'Colour must be a valid hex code' }),
73
+ __metadata("design:type", String)
74
+ ], UpdateStatusDto.prototype, "colour", void 0);
75
+ //# sourceMappingURL=dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dto.js","sourceRoot":"","sources":["../../src/statuses/dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAA0F;AAO1F,qEAA+E;AAQ/E,MAAa,WAAW;IAEb,QAAQ,CAAU;CAC5B;AAHD,kCAGC;AADU;IADR,IAAA,wBAAM,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;;6CAC1B;AAG7B,MAAa,cAAc;IAEhB,MAAM,CAAqB;CACrC;AAHD,wCAGC;AADU;IADR,IAAA,wBAAM,EAAC,wBAAiB,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC;;8CAC1B;AAGtC,MAAa,YAAY;IAId,KAAK,CAAU;IAExB,kDAAkD;IAKzC,MAAM,CAAU;IAEzB,0EAA0E;IAEjE,MAAM,CAAqB;CACrC;AAhBD,oCAgBC;AAZU;IAHR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IACtC,IAAA,2BAAS,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IAClD,IAAA,2BAAS,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC;;2CAC1C;AAOf;IAJR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IAC9C,IAAA,2BAAS,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;IAC5D,IAAA,2BAAS,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;IAC5D,IAAA,yBAAO,EAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;;4CACpD;AAIhB;IADR,IAAA,wBAAM,EAAC,wBAAiB,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC;;4CAC1B;AAGtC,MAAa,eAAe;IAIjB,KAAK,CAAU;IAExB,kDAAkD;IAKzC,MAAM,CAAU;CAC1B;AAZD,0CAYC;AARU;IAHR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IACtC,IAAA,2BAAS,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IAClD,IAAA,2BAAS,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC;;8CAC1C;AAOf;IAJR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IAC9C,IAAA,2BAAS,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;IAC5D,IAAA,2BAAS,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;IAC5D,IAAA,yBAAO,EAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;;+CACpD"}
@@ -0,0 +1,15 @@
1
+ import type { StatusEntity } from '@managemint-solutions/entities/status';
2
+ import type { AddStatusDto, UpdateStatusDto } from '@managemint-solutions/entities/status/dto';
3
+ import { StatusEntityTypes } from '@managemint-solutions/entities/status/enum';
4
+ import type { AuthContext } from '../auth';
5
+ import type { TypedSupabaseClient } from '../client';
6
+ export * from './dto';
7
+ export declare class StatusesResource {
8
+ private readonly supabase;
9
+ private readonly auth;
10
+ constructor(supabase: TypedSupabaseClient, auth: AuthContext);
11
+ list(entity: StatusEntityTypes): Promise<StatusEntity[]>;
12
+ create(input: AddStatusDto): Promise<StatusEntity>;
13
+ update(statusId: string, input: UpdateStatusDto): Promise<StatusEntity>;
14
+ remove(statusId: string): Promise<void>;
15
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.StatusesResource = void 0;
18
+ const errors_1 = require("../errors");
19
+ __exportStar(require("./dto"), exports);
20
+ // The query is typed by the generated Database schema (so the select string is inferred and
21
+ // checked); the public contract is the shared StatusEntity from @managemint-solutions/entities.
22
+ // The only difference between the two is mms_id (generated: string, entities: crypto UUID),
23
+ // which the `as StatusEntity` casts bridge.
24
+ const STATUS_SELECT = 'mms_id, label, colour';
25
+ class StatusesResource {
26
+ supabase;
27
+ auth;
28
+ constructor(supabase, auth) {
29
+ this.supabase = supabase;
30
+ this.auth = auth;
31
+ }
32
+ async list(entity) {
33
+ const { data, error } = await this.supabase
34
+ .from('statuses')
35
+ .select(STATUS_SELECT)
36
+ .eq('organization_id', this.auth.organization_id)
37
+ .eq('entity_type', entity);
38
+ if (error)
39
+ throw (0, errors_1.mapPostgrestError)(error);
40
+ return data;
41
+ }
42
+ async create(input) {
43
+ const { data, error } = await this.supabase
44
+ .from('statuses')
45
+ .insert({
46
+ label: input.label,
47
+ colour: input.colour,
48
+ entity_type: input.entity,
49
+ organization_id: this.auth.organization_id,
50
+ created_by: this.auth.mms_id,
51
+ })
52
+ .select(STATUS_SELECT)
53
+ .single();
54
+ if (error)
55
+ throw (0, errors_1.mapPostgrestError)(error);
56
+ return data;
57
+ }
58
+ async update(statusId, input) {
59
+ const { data, error } = await this.supabase
60
+ .from('statuses')
61
+ .update({
62
+ label: input.label,
63
+ colour: input.colour,
64
+ updated_at: new Date().toISOString(),
65
+ last_updated_by: this.auth.mms_id,
66
+ })
67
+ .eq('mms_id', statusId)
68
+ .eq('organization_id', this.auth.organization_id)
69
+ .select(STATUS_SELECT)
70
+ .single();
71
+ if (error)
72
+ throw (0, errors_1.mapPostgrestError)(error);
73
+ return data;
74
+ }
75
+ async remove(statusId) {
76
+ const { error } = await this.supabase
77
+ .from('statuses')
78
+ .delete()
79
+ .eq('mms_id', statusId)
80
+ .eq('organization_id', this.auth.organization_id);
81
+ if (error)
82
+ throw (0, errors_1.mapPostgrestError)(error);
83
+ }
84
+ }
85
+ exports.StatusesResource = StatusesResource;
86
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/statuses/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAKA,sCAA8C;AAE9C,wCAAsB;AAEtB,4FAA4F;AAC5F,gGAAgG;AAChG,4FAA4F;AAC5F,4CAA4C;AAC5C,MAAM,aAAa,GAAG,uBAAgC,CAAC;AAEvD,MAAa,gBAAgB;IAER;IACA;IAFnB,YACmB,QAA6B,EAC7B,IAAiB;QADjB,aAAQ,GAAR,QAAQ,CAAqB;QAC7B,SAAI,GAAJ,IAAI,CAAa;IACjC,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,MAAyB;QAClC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ;aACxC,IAAI,CAAC,UAAU,CAAC;aAChB,MAAM,CAAC,aAAa,CAAC;aACrB,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC;aAChD,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC7B,IAAI,KAAK;YAAE,MAAM,IAAA,0BAAiB,EAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,IAAsB,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAmB;QAC9B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ;aACxC,IAAI,CAAC,UAAU,CAAC;aAChB,MAAM,CAAC;YACN,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,WAAW,EAAE,KAAK,CAAC,MAAM;YACzB,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe;YAC1C,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;SAC7B,CAAC;aACD,MAAM,CAAC,aAAa,CAAC;aACrB,MAAM,EAAE,CAAC;QACZ,IAAI,KAAK;YAAE,MAAM,IAAA,0BAAiB,EAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,IAAoB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,KAAsB;QACnD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ;aACxC,IAAI,CAAC,UAAU,CAAC;aAChB,MAAM,CAAC;YACN,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;SAClC,CAAC;aACD,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;aACtB,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC;aAChD,MAAM,CAAC,aAAa,CAAC;aACrB,MAAM,EAAE,CAAC;QACZ,IAAI,KAAK;YAAE,MAAM,IAAA,0BAAiB,EAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,IAAoB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ;aAClC,IAAI,CAAC,UAAU,CAAC;aAChB,MAAM,EAAE;aACR,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;aACtB,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,KAAK;YAAE,MAAM,IAAA,0BAAiB,EAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;CACF;AAzDD,4CAyDC"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@managemint-solutions/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Typed Supabase data-access SDK for ManageMint Solutions",
5
+ "license": "UNLICENSED",
6
+ "author": "Scott Bebington <scottbebington@gmail.com>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/ManageMint-Solutions/managemint-solutions-sdk.git"
10
+ },
11
+ "type": "commonjs",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ "./package.json": "./package.json",
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./nest": {
21
+ "types": "./dist/nest/index.d.ts",
22
+ "default": "./dist/nest/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc -p tsconfig.build.json",
30
+ "test": "jest",
31
+ "release": "npm run build && npm publish --access public"
32
+ },
33
+ "jest": {
34
+ "moduleFileExtensions": ["js", "json", "ts"],
35
+ "rootDir": "src",
36
+ "testRegex": ".*\\.spec\\.ts$",
37
+ "transform": {
38
+ "^.+\\.(t|j)s$": "ts-jest"
39
+ },
40
+ "testEnvironment": "node"
41
+ },
42
+ "dependencies": {
43
+ "@managemint-solutions/entities": "^1.1.43"
44
+ },
45
+ "peerDependencies": {
46
+ "@nestjs/common": "^11.0.0",
47
+ "@supabase/supabase-js": "^2.103.0",
48
+ "class-transformer": "^0.5.1",
49
+ "class-validator": "^0.15.0"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "@nestjs/common": {
53
+ "optional": true
54
+ }
55
+ },
56
+ "devDependencies": {
57
+ "@nestjs/common": "^11.0.1",
58
+ "@supabase/supabase-js": "^2.103.3",
59
+ "@types/express": "^5.0.0",
60
+ "@types/jest": "^30.0.0",
61
+ "@types/node": "^22.10.7",
62
+ "class-transformer": "^0.5.1",
63
+ "class-validator": "^0.15.1",
64
+ "jest": "^30.0.0",
65
+ "ts-jest": "^29.2.5",
66
+ "typescript": "^5.7.3"
67
+ }
68
+ }