@managemint-solutions/sdk 0.6.0 → 0.8.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 CHANGED
@@ -15,7 +15,9 @@ are peer dependencies — the request DTOs (`AddStatusDto`, `UpdateStatusDto`, `
15
15
  `AdditionalDetailsIdDto`, `GetAdditionalDetailsDto`, `AddNoteDto`, `NoteIdDto`,
16
16
  `GetNotesDto`, `SupportingFileIdDto`, `GetSupportingFilesDto`, `GetClientsDto`, `ClientIdDto`,
17
17
  `CreateClientDto`, `UpdateClientDto`, `GetProjectsDto`, `ProjectIdDto`, `CreateProjectDto`,
18
- `UpdateProjectDto`, `GetTasksDto`, `TaskIdDto`, `CreateTaskDto`, `UpdateTaskDto`) ship with their class-validator
18
+ `UpdateProjectDto`, `GetTasksDto`, `TaskIdDto`, `CreateTaskDto`, `UpdateTaskDto`, `SignInDto`,
19
+ `ExchangeRefreshTokenDto`, `SendPasswordResetEmailDto`, `ExchangeTokenHashDto`,
20
+ `ResetPasswordDto`) ship with their class-validator
19
21
  decorators so consumers validate against
20
22
  the same rules the SDK's input types describe. `@nestjs/common` (^11) is an optional peer
21
23
  dependency, needed only for the `@managemint-solutions/sdk/nest` subpath.
@@ -196,13 +198,78 @@ The client decodes `{ mms_id, organization_id }` from the JWT itself and scopes
196
198
  by `organization_id`. `supabase.supabase` is the raw `@supabase/supabase-js` client
197
199
  (`TypedSupabaseClient`) — the escape hatch for queries not yet covered by a resource.
198
200
 
201
+ ## Auth
202
+
203
+ `SupabaseClient` needs the caller's JWT, which the auth flows are there to produce — so sign-in,
204
+ refresh and the password-reset exchanges live on a separate `SupabaseAuthClient`, built from the
205
+ publishable key alone.
206
+
207
+ ```ts
208
+ import { createSupabaseAuthClient } from '@managemint-solutions/sdk';
209
+
210
+ const auth = createSupabaseAuthClient({
211
+ url: process.env.SUPABASE_URL!,
212
+ key: process.env.SUPABASE_PUBLISHABLE_KEY!, // no caller token — these callers are logged out
213
+ });
214
+
215
+ const { access_token, refresh_token } = await auth.signIn({ email, password });
216
+ await auth.refreshSession({ refresh_token });
217
+ await auth.signOut();
218
+
219
+ // The redirect URL is passed in; the SDK reads no environment variables.
220
+ await auth.sendPasswordResetEmail({ email }, `${process.env.FRONTEND_URL}/reset-password`);
221
+ await auth.exchangeRecoveryToken({ token_hash }); // recovery link → tokens
222
+ await auth.exchangeConfirmToken({ token_hash }); // signup confirmation link → tokens
223
+ await auth.resetPassword({ password, access_token, refresh_token });
224
+ ```
225
+
226
+ `signIn` also stamps `users.last_logged_in` for the user who just signed in, on a throwaway
227
+ client carrying the fresh access token; a failed stamp never fails the login. `signOut` is a
228
+ no-op server-side — the client holds no session — and is kept for parity with the api endpoint
229
+ it replaces. `auth.supabase` is the raw `@supabase/supabase-js` client.
230
+
231
+ ```ts
232
+ import { SupabasePublicClient } from '@managemint-solutions/sdk/nest';
233
+ import { SignInDto, SupabaseAuthClient } from '@managemint-solutions/sdk';
234
+
235
+ @Controller('auth')
236
+ export class AuthController {
237
+ @Post('sign-in')
238
+ signIn(@SupabasePublicClient() auth: SupabaseAuthClient, @Body() body: SignInDto) {
239
+ return auth.signIn(body);
240
+ }
241
+ }
242
+ ```
243
+
244
+ ## Pricebooks
245
+
246
+ The price catalog (`pricebooks`, `pricebook_modules`, `billing_modules`) is readable by `anon`
247
+ by design — an unauthenticated signup prices against it — so `pricebooks` hangs off the same
248
+ bearer-less `SupabaseAuthClient` as the auth flows, takes no auth context and scopes by nothing.
249
+
250
+ ```ts
251
+ import { monthlyTotalMinor } from '@managemint-solutions/sdk';
252
+ import type { PricebookWithModules } from '@managemint-solutions/entities/modules';
253
+
254
+ const pricebook: PricebookWithModules = await auth.pricebooks.getActive();
255
+ await auth.pricebooks.getById(pricebookId); // e.g. the pricebook an organization is pinned to
256
+
257
+ // What the selected modules cost per month, in minor units. A module the pricebook does not
258
+ // price throws a 400 `Pricing Error`.
259
+ const total = monthlyTotalMinor(pricebook, ['CRM'], seatCount);
260
+ ```
261
+
262
+ Each pricebook comes back with its `modules` flattened to `PricedModule`s (the `pricebook_modules`
263
+ row joined with its `billing_modules` catalog entry). Exactly one pricebook is active at a time.
264
+
199
265
  ## Errors
200
266
 
201
267
  Every error the SDK throws is a `SupabaseClientError` carrying the HTTP `status` to respond
202
268
  with and the client-facing body, `toResponse()` → `{ error, message }`. Postgrest/Postgres
203
269
  errors are translated by `mapPostgrestError` (Postgrest code → status, RLS permission and
204
270
  module denials → readable messages), Storage errors by `mapStorageError` (the storage error's
205
- own HTTP status, or 500 when it has none); JWT problems are `401 Authentication Error`. Consumers
271
+ own HTTP status, or 500 when it has none), Supabase Auth errors by `mapAuthError` (same rule,
272
+ `Authentication Error`); JWT problems are `401 Authentication Error`. Consumers
206
273
  return these as-is instead of mapping database errors themselves.
207
274
 
208
275
  ## NestJS
@@ -0,0 +1,19 @@
1
+ import type { ExchangeRefreshTokenDto as ExchangeRefreshTokenDtoType, ExchangeTokenHashDto as ExchangeTokenHashDtoType, loginDto as LoginDtoType, ResetPasswordDto as ResetPasswordDtoType, SendPasswordResetEmailDto as SendPasswordResetEmailDtoType } from '@managemint-solutions/entities/auth/dto';
2
+ export declare class SignInDto implements LoginDtoType {
3
+ readonly email: string;
4
+ readonly password: string;
5
+ }
6
+ export declare class ExchangeRefreshTokenDto implements ExchangeRefreshTokenDtoType {
7
+ readonly refresh_token: string;
8
+ }
9
+ export declare class SendPasswordResetEmailDto implements SendPasswordResetEmailDtoType {
10
+ readonly email: string;
11
+ }
12
+ export declare class ExchangeTokenHashDto implements ExchangeTokenHashDtoType {
13
+ readonly token_hash: string;
14
+ }
15
+ export declare class ResetPasswordDto implements ResetPasswordDtoType {
16
+ readonly password: string;
17
+ readonly access_token: string;
18
+ readonly refresh_token: string;
19
+ }
@@ -0,0 +1,72 @@
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.ResetPasswordDto = exports.ExchangeTokenHashDto = exports.SendPasswordResetEmailDto = exports.ExchangeRefreshTokenDto = exports.SignInDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ // class-validator versions of the shared DTO types from @managemint-solutions/entities.
15
+ // Each class `implements` its entities type so the wire contract cannot drift.
16
+ // The entities type is spelled `loginDto` (lowercase); the class keeps the `SignInDto` name.
17
+ class SignInDto {
18
+ email;
19
+ password;
20
+ }
21
+ exports.SignInDto = SignInDto;
22
+ __decorate([
23
+ (0, class_validator_1.IsEmail)({}, { message: 'Email is required' }),
24
+ __metadata("design:type", String)
25
+ ], SignInDto.prototype, "email", void 0);
26
+ __decorate([
27
+ (0, class_validator_1.IsString)({ message: 'Password is required' }),
28
+ __metadata("design:type", String)
29
+ ], SignInDto.prototype, "password", void 0);
30
+ class ExchangeRefreshTokenDto {
31
+ refresh_token;
32
+ }
33
+ exports.ExchangeRefreshTokenDto = ExchangeRefreshTokenDto;
34
+ __decorate([
35
+ (0, class_validator_1.IsString)({ message: 'Refresh token is required' }),
36
+ __metadata("design:type", String)
37
+ ], ExchangeRefreshTokenDto.prototype, "refresh_token", void 0);
38
+ class SendPasswordResetEmailDto {
39
+ email;
40
+ }
41
+ exports.SendPasswordResetEmailDto = SendPasswordResetEmailDto;
42
+ __decorate([
43
+ (0, class_validator_1.IsEmail)({}, { message: 'Email is required' }),
44
+ __metadata("design:type", String)
45
+ ], SendPasswordResetEmailDto.prototype, "email", void 0);
46
+ class ExchangeTokenHashDto {
47
+ token_hash;
48
+ }
49
+ exports.ExchangeTokenHashDto = ExchangeTokenHashDto;
50
+ __decorate([
51
+ (0, class_validator_1.IsString)({ message: 'Token hash is required' }),
52
+ __metadata("design:type", String)
53
+ ], ExchangeTokenHashDto.prototype, "token_hash", void 0);
54
+ class ResetPasswordDto {
55
+ password;
56
+ access_token;
57
+ refresh_token;
58
+ }
59
+ exports.ResetPasswordDto = ResetPasswordDto;
60
+ __decorate([
61
+ (0, class_validator_1.IsString)({ message: 'Password is required' }),
62
+ __metadata("design:type", String)
63
+ ], ResetPasswordDto.prototype, "password", void 0);
64
+ __decorate([
65
+ (0, class_validator_1.IsString)({ message: 'Access token is required' }),
66
+ __metadata("design:type", String)
67
+ ], ResetPasswordDto.prototype, "access_token", void 0);
68
+ __decorate([
69
+ (0, class_validator_1.IsString)({ message: 'Refresh token is required' }),
70
+ __metadata("design:type", String)
71
+ ], ResetPasswordDto.prototype, "refresh_token", void 0);
72
+ //# sourceMappingURL=dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dto.js","sourceRoot":"","sources":["../../src/auth-client/dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAoD;AASpD,wFAAwF;AACxF,+EAA+E;AAE/E,6FAA6F;AAC7F,MAAa,SAAS;IAEX,KAAK,CAAU;IAGf,QAAQ,CAAU;CAC5B;AAND,8BAMC;AAJU;IADR,IAAA,yBAAO,EAAC,EAAE,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;;wCACtB;AAGf;IADR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;;2CACnB;AAG7B,MAAa,uBAAuB;IAEzB,aAAa,CAAU;CACjC;AAHD,0DAGC;AADU;IADR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC;;8DACnB;AAGlC,MAAa,yBAAyB;IAE3B,KAAK,CAAU;CACzB;AAHD,8DAGC;AADU;IADR,IAAA,yBAAO,EAAC,EAAE,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;;wDACtB;AAG1B,MAAa,oBAAoB;IAEtB,UAAU,CAAU;CAC9B;AAHD,oDAGC;AADU;IADR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;;wDACnB;AAG/B,MAAa,gBAAgB;IAElB,QAAQ,CAAU;IAGlB,YAAY,CAAU;IAGtB,aAAa,CAAU;CACjC;AATD,4CASC;AAPU;IADR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;;kDACnB;AAGlB;IADR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;;sDACnB;AAGtB;IADR,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC;;uDACnB"}
@@ -0,0 +1,41 @@
1
+ import { type SupabaseClient as SupabaseJsClient } from '@supabase/supabase-js';
2
+ import type { ExchangeTokenResponse, LoginResponse } from '@managemint-solutions/entities/auth';
3
+ import type { ExchangeRefreshTokenDto, ExchangeTokenHashDto, loginDto, ResetPasswordDto, SendPasswordResetEmailDto } from '@managemint-solutions/entities/auth/dto';
4
+ import { PricebooksResource } from '../pricebooks';
5
+ export * from './dto';
6
+ export type SupabaseAuthClientConfig = {
7
+ url: string;
8
+ key: string;
9
+ };
10
+ /**
11
+ * The client for callers that do not have a JWT yet: the auth flows, and the public catalog
12
+ * (`pricebooks`) an unauthenticated signup prices against. `SupabaseClient` needs the caller's
13
+ * token to build its RLS context, so sign-in, refresh and the password-reset exchanges live on
14
+ * this separate client, built from the publishable key alone.
15
+ */
16
+ export declare class SupabaseAuthClient {
17
+ private readonly config;
18
+ readonly supabase: SupabaseJsClient;
19
+ readonly pricebooks: PricebooksResource;
20
+ constructor(config: SupabaseAuthClientConfig);
21
+ signIn(input: loginDto): Promise<LoginResponse>;
22
+ refreshSession(input: ExchangeRefreshTokenDto): Promise<ExchangeTokenResponse>;
23
+ /**
24
+ * Parity with the api: this client never holds a session (`persistSession` is off), so
25
+ * server-side there is nothing to revoke and the call is a no-op. Kept as the api had it.
26
+ */
27
+ signOut(): Promise<void>;
28
+ /** `redirectTo` is passed in — the SDK reads no environment variables. */
29
+ sendPasswordResetEmail(input: SendPasswordResetEmailDto, redirectTo: string): Promise<void>;
30
+ exchangeRecoveryToken(input: ExchangeTokenHashDto): Promise<ExchangeTokenResponse>;
31
+ exchangeConfirmToken(input: ExchangeTokenHashDto): Promise<ExchangeTokenResponse>;
32
+ resetPassword(input: ResetPasswordDto): Promise<void>;
33
+ /**
34
+ * Stamps `users.last_logged_in` as the user who just signed in — the users UPDATE policy
35
+ * allows `auth.uid() = mms_id`, so the write goes through a throwaway client carrying the
36
+ * fresh access token rather than this session-less one. Parity with the api: the result is
37
+ * ignored, a failed stamp must not fail the login.
38
+ */
39
+ private stampLastLoggedIn;
40
+ }
41
+ export declare const createSupabaseAuthClient: (config: SupabaseAuthClientConfig) => SupabaseAuthClient;
@@ -0,0 +1,139 @@
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.createSupabaseAuthClient = exports.SupabaseAuthClient = void 0;
18
+ const supabase_js_1 = require("@supabase/supabase-js");
19
+ const errors_1 = require("../errors");
20
+ const pricebooks_1 = require("../pricebooks");
21
+ __exportStar(require("./dto"), exports);
22
+ // The api's "no session/user returned" NotFoundException, as an SDK error.
23
+ const noSession = (message) => new errors_1.SupabaseClientError({ status: 404, error: 'Authentication Error', message });
24
+ const toTokens = (session) => ({
25
+ access_token: session.access_token,
26
+ refresh_token: session.refresh_token,
27
+ });
28
+ /**
29
+ * The client for callers that do not have a JWT yet: the auth flows, and the public catalog
30
+ * (`pricebooks`) an unauthenticated signup prices against. `SupabaseClient` needs the caller's
31
+ * token to build its RLS context, so sign-in, refresh and the password-reset exchanges live on
32
+ * this separate client, built from the publishable key alone.
33
+ */
34
+ class SupabaseAuthClient {
35
+ config;
36
+ supabase; // escape hatch for flows not covered by a method
37
+ pricebooks;
38
+ constructor(config) {
39
+ this.config = config;
40
+ this.supabase = (0, supabase_js_1.createClient)(config.url, config.key, {
41
+ // Server-side and stateless: nothing is stored, refreshed or read out of a URL.
42
+ auth: { persistSession: false, autoRefreshToken: false, detectSessionInUrl: false },
43
+ });
44
+ this.pricebooks = new pricebooks_1.PricebooksResource(this.supabase);
45
+ }
46
+ async signIn(input) {
47
+ const { data, error } = await this.supabase.auth.signInWithPassword({
48
+ email: input.email,
49
+ password: input.password,
50
+ });
51
+ if (error)
52
+ throw (0, errors_1.mapAuthError)(error);
53
+ if (!data.session || !data.user) {
54
+ throw noSession('Authentication failed: No session or user data returned');
55
+ }
56
+ await this.stampLastLoggedIn(data.session.access_token, data.user.id);
57
+ return toTokens(data.session);
58
+ }
59
+ async refreshSession(input) {
60
+ const { data, error } = await this.supabase.auth.refreshSession({
61
+ refresh_token: input.refresh_token,
62
+ });
63
+ if (error)
64
+ throw (0, errors_1.mapAuthError)(error);
65
+ if (!data.session)
66
+ throw noSession('Token exchange failed: No session data returned');
67
+ return toTokens(data.session);
68
+ }
69
+ /**
70
+ * Parity with the api: this client never holds a session (`persistSession` is off), so
71
+ * server-side there is nothing to revoke and the call is a no-op. Kept as the api had it.
72
+ */
73
+ async signOut() {
74
+ const { error } = await this.supabase.auth.signOut();
75
+ if (error)
76
+ throw (0, errors_1.mapAuthError)(error);
77
+ }
78
+ /** `redirectTo` is passed in — the SDK reads no environment variables. */
79
+ async sendPasswordResetEmail(input, redirectTo) {
80
+ const { error } = await this.supabase.auth.resetPasswordForEmail(input.email, { redirectTo });
81
+ if (error)
82
+ throw (0, errors_1.mapAuthError)(error);
83
+ }
84
+ async exchangeRecoveryToken(input) {
85
+ const { data, error } = await this.supabase.auth.verifyOtp({
86
+ type: 'recovery',
87
+ token_hash: input.token_hash,
88
+ });
89
+ if (error)
90
+ throw (0, errors_1.mapAuthError)(error);
91
+ if (!data.session)
92
+ throw noSession('Token exchange failed: No session data returned');
93
+ return toTokens(data.session);
94
+ }
95
+ async exchangeConfirmToken(input) {
96
+ const { data, error } = await this.supabase.auth.verifyOtp({
97
+ type: 'signup',
98
+ token_hash: input.token_hash,
99
+ });
100
+ if (error)
101
+ throw (0, errors_1.mapAuthError)(error);
102
+ if (!data.session)
103
+ throw noSession('Token exchange failed: No session data returned');
104
+ return toTokens(data.session);
105
+ }
106
+ async resetPassword(input) {
107
+ const { error: sessionError } = await this.supabase.auth.setSession({
108
+ access_token: input.access_token,
109
+ refresh_token: input.refresh_token,
110
+ });
111
+ if (sessionError)
112
+ throw (0, errors_1.mapAuthError)(sessionError);
113
+ const { error: updateError } = await this.supabase.auth.updateUser({
114
+ password: input.password,
115
+ });
116
+ if (updateError)
117
+ throw (0, errors_1.mapAuthError)(updateError);
118
+ }
119
+ /**
120
+ * Stamps `users.last_logged_in` as the user who just signed in — the users UPDATE policy
121
+ * allows `auth.uid() = mms_id`, so the write goes through a throwaway client carrying the
122
+ * fresh access token rather than this session-less one. Parity with the api: the result is
123
+ * ignored, a failed stamp must not fail the login.
124
+ */
125
+ async stampLastLoggedIn(accessToken, userId) {
126
+ const asUser = (0, supabase_js_1.createClient)(this.config.url, this.config.key, {
127
+ global: { headers: { Authorization: `Bearer ${accessToken}` } },
128
+ auth: { persistSession: false, autoRefreshToken: false },
129
+ });
130
+ await asUser
131
+ .from('users')
132
+ .update({ last_logged_in: new Date().toISOString() })
133
+ .eq('mms_id', userId);
134
+ }
135
+ }
136
+ exports.SupabaseAuthClient = SupabaseAuthClient;
137
+ const createSupabaseAuthClient = (config) => new SupabaseAuthClient(config);
138
+ exports.createSupabaseAuthClient = createSupabaseAuthClient;
139
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth-client/index.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { StorageError } from '@supabase/storage-js';
2
- import type { PostgrestError } from '@supabase/supabase-js';
2
+ import type { AuthError, PostgrestError } from '@supabase/supabase-js';
3
3
  export type SupabaseClientErrorInit = {
4
4
  /** HTTP status the consumer should respond with. */
5
5
  status: number;
@@ -34,3 +34,9 @@ export declare const mapPostgrestError: (error: PostgrestError) => SupabaseClien
34
34
  * network/unknown failures have none, hence the 500 fallback.
35
35
  */
36
36
  export declare const mapStorageError: (error: StorageError, message?: string) => SupabaseClientError;
37
+ /**
38
+ * Converts a Supabase Auth (GoTrue) error into the SupabaseClientError the SDK throws — the
39
+ * SDK-side equivalent of the api's `throwAuthErrorResponse`. `AuthError.status` is the HTTP
40
+ * status GoTrue answered with; network/unknown failures carry none, hence the 500 fallback.
41
+ */
42
+ export declare const mapAuthError: (error: AuthError) => SupabaseClientError;
package/dist/errors.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapStorageError = exports.mapPostgrestError = exports.SupabaseClientError = void 0;
3
+ exports.mapAuthError = exports.mapStorageError = exports.mapPostgrestError = exports.SupabaseClientError = void 0;
4
4
  /**
5
5
  * Every error the SDK throws. It already carries the HTTP status and the body the
6
6
  * consumer sends back to the client (`toResponse()`), so the api needs no mapping.
@@ -140,4 +140,15 @@ const mapStorageError = (error, message = error.message) => new SupabaseClientEr
140
140
  message,
141
141
  }, { cause: error });
142
142
  exports.mapStorageError = mapStorageError;
143
+ /**
144
+ * Converts a Supabase Auth (GoTrue) error into the SupabaseClientError the SDK throws — the
145
+ * SDK-side equivalent of the api's `throwAuthErrorResponse`. `AuthError.status` is the HTTP
146
+ * status GoTrue answered with; network/unknown failures carry none, hence the 500 fallback.
147
+ */
148
+ const mapAuthError = (error) => new SupabaseClientError({
149
+ status: error.status ?? 500,
150
+ error: 'Authentication Error',
151
+ message: error.message,
152
+ }, { cause: error });
153
+ exports.mapAuthError = mapAuthError;
143
154
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './client';
2
2
  export * from './auth';
3
+ export * from './auth-client';
3
4
  export * from './errors';
4
5
  export * from './validators';
5
6
  export * from './transforms';
@@ -10,3 +11,4 @@ export * from './supporting-files';
10
11
  export * from './clients';
11
12
  export * from './projects';
12
13
  export * from './tasks';
14
+ export * from './pricebooks';
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./client"), exports);
18
18
  __exportStar(require("./auth"), exports);
19
+ __exportStar(require("./auth-client"), exports);
19
20
  __exportStar(require("./errors"), exports);
20
21
  __exportStar(require("./validators"), exports);
21
22
  __exportStar(require("./transforms"), exports);
@@ -26,4 +27,5 @@ __exportStar(require("./supporting-files"), exports);
26
27
  __exportStar(require("./clients"), exports);
27
28
  __exportStar(require("./projects"), exports);
28
29
  __exportStar(require("./tasks"), exports);
30
+ __exportStar(require("./pricebooks"), exports);
29
31
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,yCAAuB;AACvB,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,6CAA2B;AAC3B,uDAAqC;AACrC,0CAAwB;AACxB,qDAAmC;AACnC,4CAA0B;AAC1B,6CAA2B;AAC3B,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,yCAAuB;AACvB,gDAA8B;AAC9B,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,6CAA2B;AAC3B,uDAAqC;AACrC,0CAAwB;AACxB,qDAAmC;AACnC,4CAA0B;AAC1B,6CAA2B;AAC3B,0CAAwB;AACxB,+CAA6B"}
@@ -7,3 +7,8 @@ import { SupabaseClientError } from '../errors';
7
7
  */
8
8
  export declare const toHttpException: (error: SupabaseClientError) => HttpException;
9
9
  export declare const SupabaseUserClient: (...dataOrPipes: unknown[]) => ParameterDecorator;
10
+ /**
11
+ * A `SupabaseAuthClient` for routes a logged-out caller hits (sign-in, refresh, password
12
+ * reset) — built from the publishable key alone, with no bearer token involved.
13
+ */
14
+ export declare const SupabasePublicClient: (...dataOrPipes: any[]) => ParameterDecorator;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SupabaseUserClient = exports.toHttpException = void 0;
3
+ exports.SupabasePublicClient = exports.SupabaseUserClient = exports.toHttpException = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
+ const auth_client_1 = require("../auth-client");
5
6
  const client_1 = require("../client");
6
7
  const errors_1 = require("../errors");
7
8
  /**
@@ -44,4 +45,12 @@ exports.SupabaseUserClient = (0, common_1.createParamDecorator)((_, ctx) => {
44
45
  throw error;
45
46
  }
46
47
  });
48
+ /**
49
+ * A `SupabaseAuthClient` for routes a logged-out caller hits (sign-in, refresh, password
50
+ * reset) — built from the publishable key alone, with no bearer token involved.
51
+ */
52
+ exports.SupabasePublicClient = (0, common_1.createParamDecorator)(() => (0, auth_client_1.createSupabaseAuthClient)({
53
+ url: getEnvOrThrow('SUPABASE_URL'),
54
+ key: getEnvOrThrow('SUPABASE_PUBLISHABLE_KEY'),
55
+ }));
47
56
  //# sourceMappingURL=index.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nest/index.ts"],"names":[],"mappings":";;;AAAA,2CAMwB;AAExB,gDAAmF;AACnF,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;AAEF;;;GAGG;AACU,QAAA,oBAAoB,GAAG,IAAA,6BAAoB,EACtD,GAAuB,EAAE,CACvB,IAAA,sCAAwB,EAAC;IACvB,GAAG,EAAE,aAAa,CAAC,cAAc,CAAC;IAClC,GAAG,EAAE,aAAa,CAAC,0BAA0B,CAAC;CAC/C,CAAC,CACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { SupabaseClient as SupabaseJsClient } from '@supabase/supabase-js';
2
+ import type { PricebookWithModules } from '@managemint-solutions/entities/modules';
3
+ /**
4
+ * The public price catalog. `pricebooks`, `pricebook_modules` and `billing_modules` are readable
5
+ * by `anon` by design — unauthenticated signup prices against them — so this resource takes no
6
+ * auth context and scopes by nothing.
7
+ */
8
+ export declare class PricebooksResource {
9
+ private readonly supabase;
10
+ constructor(supabase: SupabaseJsClient);
11
+ getActive(): Promise<PricebookWithModules>;
12
+ getById(pricebookId: string): Promise<PricebookWithModules>;
13
+ }
14
+ /**
15
+ * What the given modules cost per month, in minor units: every module's unit price summed and
16
+ * multiplied by the seat count. A module the pricebook does not price is a 400 — the caller
17
+ * asked for something that cannot be billed.
18
+ */
19
+ export declare const monthlyTotalMinor: (pricebook: PricebookWithModules, moduleKeys: string[], seatCount: number) => number;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.monthlyTotalMinor = exports.PricebooksResource = void 0;
4
+ const errors_1 = require("../errors");
5
+ // The public contract is PricebookWithModules from @managemint-solutions/entities; the row
6
+ // types below only declare the shape this select string produces (the columns are defined in
7
+ // the api's supabase/migrations).
8
+ const PRICEBOOK_SELECT = `
9
+ mms_id,
10
+ name,
11
+ description,
12
+ active,
13
+ pricebook_modules (
14
+ module_id,
15
+ unit_amount_minor,
16
+ currency,
17
+ billing_modules (
18
+ module_key
19
+ )
20
+ )
21
+ `;
22
+ // A pricebook_modules row whose catalog entry did not come back leaves `module_key` undefined —
23
+ // the cast keeps the mapping honest about that rather than inventing a key.
24
+ const toPricebookWithModules = (row) => ({
25
+ mms_id: row.mms_id,
26
+ name: row.name,
27
+ active: row.active,
28
+ description: row.description,
29
+ modules: (row.pricebook_modules || []).map((pricedModule) => ({
30
+ module_id: pricedModule.module_id,
31
+ module_key: pricedModule.billing_modules?.module_key,
32
+ unit_amount_minor: pricedModule.unit_amount_minor,
33
+ currency: pricedModule.currency,
34
+ })),
35
+ });
36
+ /**
37
+ * The public price catalog. `pricebooks`, `pricebook_modules` and `billing_modules` are readable
38
+ * by `anon` by design — unauthenticated signup prices against them — so this resource takes no
39
+ * auth context and scopes by nothing.
40
+ */
41
+ class PricebooksResource {
42
+ supabase;
43
+ constructor(supabase) {
44
+ this.supabase = supabase;
45
+ }
46
+ async getActive() {
47
+ const { data, error } = await this.supabase
48
+ .from('pricebooks')
49
+ .select(PRICEBOOK_SELECT)
50
+ .eq('active', true)
51
+ .single();
52
+ if (error)
53
+ throw (0, errors_1.mapPostgrestError)(error);
54
+ return toPricebookWithModules(data);
55
+ }
56
+ async getById(pricebookId) {
57
+ const { data, error } = await this.supabase
58
+ .from('pricebooks')
59
+ .select(PRICEBOOK_SELECT)
60
+ .eq('mms_id', pricebookId)
61
+ .single();
62
+ if (error)
63
+ throw (0, errors_1.mapPostgrestError)(error);
64
+ return toPricebookWithModules(data);
65
+ }
66
+ }
67
+ exports.PricebooksResource = PricebooksResource;
68
+ /**
69
+ * What the given modules cost per month, in minor units: every module's unit price summed and
70
+ * multiplied by the seat count. A module the pricebook does not price is a 400 — the caller
71
+ * asked for something that cannot be billed.
72
+ */
73
+ const monthlyTotalMinor = (pricebook, moduleKeys, seatCount) => {
74
+ const total = moduleKeys.reduce((sum, moduleKey) => {
75
+ const pricedModule = pricebook.modules.find((module) => module.module_key === moduleKey);
76
+ if (!pricedModule) {
77
+ throw new errors_1.SupabaseClientError({
78
+ status: 400,
79
+ error: 'Pricing Error',
80
+ message: `Module ${moduleKey} is not priced by pricebook ${pricebook.name}`,
81
+ });
82
+ }
83
+ return sum + pricedModule.unit_amount_minor;
84
+ }, 0);
85
+ return total * seatCount;
86
+ };
87
+ exports.monthlyTotalMinor = monthlyTotalMinor;
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pricebooks/index.ts"],"names":[],"mappings":";;;AAEA,sCAAmE;AAEnE,2FAA2F;AAC3F,6FAA6F;AAC7F,kCAAkC;AAClC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;CAaf,CAAC;AAoBX,gGAAgG;AAChG,4EAA4E;AAC5E,MAAM,sBAAsB,GAAG,CAAC,GAAiB,EAAwB,EAAE,CAAC,CAAC;IAC3E,MAAM,EAAE,GAAG,CAAC,MAAM;IAClB,IAAI,EAAE,GAAG,CAAC,IAAI;IACd,MAAM,EAAE,GAAG,CAAC,MAAM;IAClB,WAAW,EAAE,GAAG,CAAC,WAAW;IAC5B,OAAO,EAAE,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC5D,SAAS,EAAE,YAAY,CAAC,SAAS;QACjC,UAAU,EAAE,YAAY,CAAC,eAAe,EAAE,UAAU;QACpD,iBAAiB,EAAE,YAAY,CAAC,iBAAiB;QACjD,QAAQ,EAAE,YAAY,CAAC,QAAQ;KAChC,CAAC,CAAmB;CACtB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAa,kBAAkB;IACA;IAA7B,YAA6B,QAA0B;QAA1B,aAAQ,GAAR,QAAQ,CAAkB;IAAG,CAAC;IAE3D,KAAK,CAAC,SAAS;QACb,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ;aACxC,IAAI,CAAC,YAAY,CAAC;aAClB,MAAM,CAAC,gBAAgB,CAAC;aACxB,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC;aAClB,MAAM,EAAE,CAAC;QACZ,IAAI,KAAK;YAAE,MAAM,IAAA,0BAAiB,EAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,sBAAsB,CAAC,IAA+B,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ;aACxC,IAAI,CAAC,YAAY,CAAC;aAClB,MAAM,CAAC,gBAAgB,CAAC;aACxB,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC;aACzB,MAAM,EAAE,CAAC;QACZ,IAAI,KAAK;YAAE,MAAM,IAAA,0BAAiB,EAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,sBAAsB,CAAC,IAA+B,CAAC,CAAC;IACjE,CAAC;CACF;AAtBD,gDAsBC;AAED;;;;GAIG;AACI,MAAM,iBAAiB,GAAG,CAC/B,SAA+B,EAC/B,UAAoB,EACpB,SAAiB,EACT,EAAE;IACV,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE;QACjD,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC;QAEzF,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,4BAAmB,CAAC;gBAC5B,MAAM,EAAE,GAAG;gBACX,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,UAAU,SAAS,+BAA+B,SAAS,CAAC,IAAI,EAAE;aAC5E,CAAC,CAAC;QACL,CAAC;QAED,OAAO,GAAG,GAAG,YAAY,CAAC,iBAAiB,CAAC;IAC9C,CAAC,EAAE,CAAC,CAAC,CAAC;IAEN,OAAO,KAAK,GAAG,SAAS,CAAC;AAC3B,CAAC,CAAC;AApBW,QAAA,iBAAiB,qBAoB5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@managemint-solutions/sdk",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Typed Supabase data-access SDK for ManageMint Solutions",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Scott Bebington <scottbebington@gmail.com>",