@goodparty_org/sdk 0.1.0 → 1.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.
- package/README.md +11 -1
- package/dist/index.d.mts +17 -9
- package/dist/index.d.ts +17 -9
- package/dist/index.js +93 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,13 @@ const client = await GoodPartyClient.create({
|
|
|
20
20
|
|
|
21
21
|
const user = await client.users.get(1)
|
|
22
22
|
|
|
23
|
-
const users = await client.users.list({
|
|
23
|
+
const users = await client.users.list({ offset: 0, limit: 20 })
|
|
24
|
+
|
|
25
|
+
const filtered = await client.users.list({
|
|
26
|
+
firstName: 'John',
|
|
27
|
+
sortBy: 'createdAt',
|
|
28
|
+
sortOrder: 'desc',
|
|
29
|
+
})
|
|
24
30
|
|
|
25
31
|
await client.users.updatePassword(1, {
|
|
26
32
|
oldPassword: 'old',
|
|
@@ -28,8 +34,12 @@ await client.users.updatePassword(1, {
|
|
|
28
34
|
})
|
|
29
35
|
|
|
30
36
|
await client.users.delete(1)
|
|
37
|
+
|
|
38
|
+
client.destroy()
|
|
31
39
|
```
|
|
32
40
|
|
|
41
|
+
The `destroy()` method cleans up internal token renewal timers. Call it when you are done using the client to prevent leaked timers.
|
|
42
|
+
|
|
33
43
|
All methods throw `SdkError` on failure:
|
|
34
44
|
|
|
35
45
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -6,18 +6,19 @@ declare class SdkError extends Error {
|
|
|
6
6
|
constructor(status: number, message: string, response?: Response);
|
|
7
7
|
}
|
|
8
8
|
type PaginationOptions = {
|
|
9
|
-
|
|
9
|
+
offset?: number;
|
|
10
10
|
limit?: number;
|
|
11
|
+
sortBy?: string;
|
|
12
|
+
sortOrder?: 'asc' | 'desc';
|
|
11
13
|
};
|
|
12
14
|
type PaginationMeta = {
|
|
13
|
-
page: number;
|
|
14
|
-
limit: number;
|
|
15
15
|
total: number;
|
|
16
|
-
|
|
16
|
+
offset: number;
|
|
17
|
+
limit: number;
|
|
17
18
|
};
|
|
18
19
|
type PaginatedList<T> = {
|
|
19
20
|
data: T[];
|
|
20
|
-
|
|
21
|
+
meta: PaginationMeta;
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
declare enum UserRole {
|
|
@@ -59,6 +60,11 @@ type User = {
|
|
|
59
60
|
roles?: UserRole[];
|
|
60
61
|
metaData?: UserMetaData;
|
|
61
62
|
};
|
|
63
|
+
type ListUsersOptions = PaginationOptions & {
|
|
64
|
+
firstName?: string;
|
|
65
|
+
lastName?: string;
|
|
66
|
+
email?: string;
|
|
67
|
+
};
|
|
62
68
|
type UpdatePasswordInput = {
|
|
63
69
|
oldPassword?: string;
|
|
64
70
|
newPassword: string;
|
|
@@ -67,8 +73,8 @@ type UpdatePasswordInput = {
|
|
|
67
73
|
type OfetchRequestBody = FetchOptions<'json'>['body'];
|
|
68
74
|
declare class HttpClient {
|
|
69
75
|
private baseUrl;
|
|
70
|
-
private
|
|
71
|
-
constructor(gpApiRootUrl: string,
|
|
76
|
+
private getToken;
|
|
77
|
+
constructor(gpApiRootUrl: string, getToken: () => Promise<string>);
|
|
72
78
|
request: <T>(path: string, init?: FetchOptions<"json">) => Promise<T>;
|
|
73
79
|
}
|
|
74
80
|
|
|
@@ -82,7 +88,7 @@ declare abstract class BaseResource {
|
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
declare class UsersResource extends BaseResource {
|
|
85
|
-
list: (options?:
|
|
91
|
+
list: (options?: ListUsersOptions) => Promise<PaginatedList<User>>;
|
|
86
92
|
get: (id: number) => Promise<User>;
|
|
87
93
|
delete: (id: number) => Promise<void>;
|
|
88
94
|
updatePassword: (id: number, input: UpdatePasswordInput) => Promise<void>;
|
|
@@ -94,8 +100,10 @@ type GoodPartyClientConfig = {
|
|
|
94
100
|
};
|
|
95
101
|
declare class GoodPartyClient {
|
|
96
102
|
readonly users: UsersResource;
|
|
103
|
+
private clerkService;
|
|
97
104
|
private constructor();
|
|
98
105
|
static create: (config: GoodPartyClientConfig) => Promise<GoodPartyClient>;
|
|
106
|
+
destroy: () => void;
|
|
99
107
|
}
|
|
100
108
|
|
|
101
|
-
export { GoodPartyClient, type GoodPartyClientConfig, type PaginatedList, type PaginationMeta, type PaginationOptions, SdkError, type UpdatePasswordInput, type User, type UserMetaData, UserRole, WhyBrowsing };
|
|
109
|
+
export { GoodPartyClient, type GoodPartyClientConfig, type ListUsersOptions, type PaginatedList, type PaginationMeta, type PaginationOptions, SdkError, type UpdatePasswordInput, type User, type UserMetaData, UserRole, WhyBrowsing };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,18 +6,19 @@ declare class SdkError extends Error {
|
|
|
6
6
|
constructor(status: number, message: string, response?: Response);
|
|
7
7
|
}
|
|
8
8
|
type PaginationOptions = {
|
|
9
|
-
|
|
9
|
+
offset?: number;
|
|
10
10
|
limit?: number;
|
|
11
|
+
sortBy?: string;
|
|
12
|
+
sortOrder?: 'asc' | 'desc';
|
|
11
13
|
};
|
|
12
14
|
type PaginationMeta = {
|
|
13
|
-
page: number;
|
|
14
|
-
limit: number;
|
|
15
15
|
total: number;
|
|
16
|
-
|
|
16
|
+
offset: number;
|
|
17
|
+
limit: number;
|
|
17
18
|
};
|
|
18
19
|
type PaginatedList<T> = {
|
|
19
20
|
data: T[];
|
|
20
|
-
|
|
21
|
+
meta: PaginationMeta;
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
declare enum UserRole {
|
|
@@ -59,6 +60,11 @@ type User = {
|
|
|
59
60
|
roles?: UserRole[];
|
|
60
61
|
metaData?: UserMetaData;
|
|
61
62
|
};
|
|
63
|
+
type ListUsersOptions = PaginationOptions & {
|
|
64
|
+
firstName?: string;
|
|
65
|
+
lastName?: string;
|
|
66
|
+
email?: string;
|
|
67
|
+
};
|
|
62
68
|
type UpdatePasswordInput = {
|
|
63
69
|
oldPassword?: string;
|
|
64
70
|
newPassword: string;
|
|
@@ -67,8 +73,8 @@ type UpdatePasswordInput = {
|
|
|
67
73
|
type OfetchRequestBody = FetchOptions<'json'>['body'];
|
|
68
74
|
declare class HttpClient {
|
|
69
75
|
private baseUrl;
|
|
70
|
-
private
|
|
71
|
-
constructor(gpApiRootUrl: string,
|
|
76
|
+
private getToken;
|
|
77
|
+
constructor(gpApiRootUrl: string, getToken: () => Promise<string>);
|
|
72
78
|
request: <T>(path: string, init?: FetchOptions<"json">) => Promise<T>;
|
|
73
79
|
}
|
|
74
80
|
|
|
@@ -82,7 +88,7 @@ declare abstract class BaseResource {
|
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
declare class UsersResource extends BaseResource {
|
|
85
|
-
list: (options?:
|
|
91
|
+
list: (options?: ListUsersOptions) => Promise<PaginatedList<User>>;
|
|
86
92
|
get: (id: number) => Promise<User>;
|
|
87
93
|
delete: (id: number) => Promise<void>;
|
|
88
94
|
updatePassword: (id: number, input: UpdatePasswordInput) => Promise<void>;
|
|
@@ -94,8 +100,10 @@ type GoodPartyClientConfig = {
|
|
|
94
100
|
};
|
|
95
101
|
declare class GoodPartyClient {
|
|
96
102
|
readonly users: UsersResource;
|
|
103
|
+
private clerkService;
|
|
97
104
|
private constructor();
|
|
98
105
|
static create: (config: GoodPartyClientConfig) => Promise<GoodPartyClient>;
|
|
106
|
+
destroy: () => void;
|
|
99
107
|
}
|
|
100
108
|
|
|
101
|
-
export { GoodPartyClient, type GoodPartyClientConfig, type PaginatedList, type PaginationMeta, type PaginationOptions, SdkError, type UpdatePasswordInput, type User, type UserMetaData, UserRole, WhyBrowsing };
|
|
109
|
+
export { GoodPartyClient, type GoodPartyClientConfig, type ListUsersOptions, type PaginatedList, type PaginationMeta, type PaginationOptions, SdkError, type UpdatePasswordInput, type User, type UserMetaData, UserRole, WhyBrowsing };
|
package/dist/index.js
CHANGED
|
@@ -27,9 +27,6 @@ __export(index_exports, {
|
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(index_exports);
|
|
29
29
|
|
|
30
|
-
// src/GoodPartyClient.ts
|
|
31
|
-
var import_backend = require("@clerk/backend");
|
|
32
|
-
|
|
33
30
|
// src/http/HttpClient.ts
|
|
34
31
|
var import_ofetch = require("ofetch");
|
|
35
32
|
|
|
@@ -48,17 +45,17 @@ var SdkError = class extends Error {
|
|
|
48
45
|
// src/http/HttpClient.ts
|
|
49
46
|
var HttpClient = class {
|
|
50
47
|
baseUrl;
|
|
51
|
-
|
|
52
|
-
constructor(gpApiRootUrl,
|
|
48
|
+
getToken;
|
|
49
|
+
constructor(gpApiRootUrl, getToken) {
|
|
53
50
|
this.baseUrl = gpApiRootUrl;
|
|
54
|
-
this.
|
|
51
|
+
this.getToken = getToken;
|
|
55
52
|
}
|
|
56
53
|
request = async (path, init) => {
|
|
57
54
|
try {
|
|
58
55
|
return await (0, import_ofetch.ofetch)(path, {
|
|
59
56
|
baseURL: this.baseUrl,
|
|
60
57
|
headers: {
|
|
61
|
-
Authorization: `Bearer ${this.
|
|
58
|
+
Authorization: `Bearer ${await this.getToken()}`,
|
|
62
59
|
...init?.headers ?? {}
|
|
63
60
|
},
|
|
64
61
|
...init
|
|
@@ -87,32 +84,62 @@ var BaseResource = class {
|
|
|
87
84
|
|
|
88
85
|
// src/resources/UsersResource.ts
|
|
89
86
|
var UsersResource = class extends BaseResource {
|
|
90
|
-
list =
|
|
91
|
-
const { data, meta: pagination } = await this.getRequest("/users", options);
|
|
92
|
-
return {
|
|
93
|
-
data,
|
|
94
|
-
pagination
|
|
95
|
-
};
|
|
96
|
-
};
|
|
87
|
+
list = (options) => this.getRequest("/users", options);
|
|
97
88
|
get = (id) => this.getRequest(`/users/${id}`);
|
|
98
89
|
delete = (id) => this.deleteRequest(`/users/${id}`);
|
|
99
90
|
updatePassword = (id, input) => this.putRequest(`/users/${id}/password`, input);
|
|
100
91
|
};
|
|
101
92
|
|
|
102
|
-
// src/
|
|
103
|
-
var
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
93
|
+
// src/vendor/clerk/clerk.service.ts
|
|
94
|
+
var import_backend = require("@clerk/backend");
|
|
95
|
+
var TOKEN_RENEWAL_BUFFER_MS = 3e4;
|
|
96
|
+
var ClerkService = class {
|
|
97
|
+
m2mSecret;
|
|
98
|
+
clerkClient;
|
|
99
|
+
cachedToken = null;
|
|
100
|
+
tokenExpiration = null;
|
|
101
|
+
renewalTimer = null;
|
|
102
|
+
pendingTokenPromise = null;
|
|
103
|
+
destroyed = false;
|
|
104
|
+
constructor(m2mSecret) {
|
|
105
|
+
this.m2mSecret = m2mSecret;
|
|
106
|
+
this.clerkClient = (0, import_backend.createClerkClient)({});
|
|
108
107
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
getToken = async () => {
|
|
109
|
+
if (this.cachedToken && this.isTokenValid()) {
|
|
110
|
+
return this.cachedToken;
|
|
111
|
+
}
|
|
112
|
+
if (this.pendingTokenPromise) {
|
|
113
|
+
return this.pendingTokenPromise;
|
|
114
|
+
}
|
|
115
|
+
const promise = this.createAndCacheToken();
|
|
116
|
+
this.pendingTokenPromise = promise;
|
|
117
|
+
try {
|
|
118
|
+
return await promise;
|
|
119
|
+
} finally {
|
|
120
|
+
if (this.pendingTokenPromise === promise) {
|
|
121
|
+
this.pendingTokenPromise = null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
destroy = () => {
|
|
126
|
+
this.destroyed = true;
|
|
127
|
+
if (this.renewalTimer) {
|
|
128
|
+
clearTimeout(this.renewalTimer);
|
|
129
|
+
this.renewalTimer = null;
|
|
130
|
+
}
|
|
131
|
+
this.cachedToken = null;
|
|
132
|
+
this.tokenExpiration = null;
|
|
133
|
+
this.pendingTokenPromise = null;
|
|
134
|
+
};
|
|
135
|
+
isTokenValid = () => {
|
|
136
|
+
if (!this.tokenExpiration) return true;
|
|
137
|
+
return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS;
|
|
138
|
+
};
|
|
139
|
+
createAndCacheToken = async () => {
|
|
113
140
|
try {
|
|
114
|
-
const m2mToken = await clerkClient.m2m.createToken({
|
|
115
|
-
machineSecretKey: m2mSecret
|
|
141
|
+
const m2mToken = await this.clerkClient.m2m.createToken({
|
|
142
|
+
machineSecretKey: this.m2mSecret
|
|
116
143
|
});
|
|
117
144
|
if (!m2mToken.token) {
|
|
118
145
|
throw new SdkError(
|
|
@@ -120,7 +147,11 @@ var GoodPartyClient = class _GoodPartyClient {
|
|
|
120
147
|
"Clerk M2M token creation succeeded but returned no token string"
|
|
121
148
|
);
|
|
122
149
|
}
|
|
123
|
-
|
|
150
|
+
if (this.destroyed) return m2mToken.token;
|
|
151
|
+
this.cachedToken = m2mToken.token;
|
|
152
|
+
this.tokenExpiration = m2mToken.expiration;
|
|
153
|
+
this.scheduleRenewal();
|
|
154
|
+
return this.cachedToken;
|
|
124
155
|
} catch (error) {
|
|
125
156
|
if (error instanceof SdkError) {
|
|
126
157
|
throw error;
|
|
@@ -128,7 +159,41 @@ var GoodPartyClient = class _GoodPartyClient {
|
|
|
128
159
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
129
160
|
throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`);
|
|
130
161
|
}
|
|
131
|
-
|
|
162
|
+
};
|
|
163
|
+
scheduleRenewal = () => {
|
|
164
|
+
if (this.renewalTimer) {
|
|
165
|
+
clearTimeout(this.renewalTimer);
|
|
166
|
+
this.renewalTimer = null;
|
|
167
|
+
}
|
|
168
|
+
if (!this.tokenExpiration) return;
|
|
169
|
+
const timeUntilRenewal = this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS;
|
|
170
|
+
if (timeUntilRenewal <= 0) return;
|
|
171
|
+
this.renewalTimer = setTimeout(() => {
|
|
172
|
+
this.cachedToken = null;
|
|
173
|
+
this.getToken().catch((error) => {
|
|
174
|
+
console.error("Proactive M2M token renewal failed:", error);
|
|
175
|
+
});
|
|
176
|
+
}, timeUntilRenewal);
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// src/GoodPartyClient.ts
|
|
181
|
+
var GoodPartyClient = class _GoodPartyClient {
|
|
182
|
+
users;
|
|
183
|
+
clerkService;
|
|
184
|
+
constructor(clerkService, gpApiRootUrl) {
|
|
185
|
+
this.clerkService = clerkService;
|
|
186
|
+
const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken);
|
|
187
|
+
this.users = new UsersResource(httpClient);
|
|
188
|
+
}
|
|
189
|
+
static create = async (config) => {
|
|
190
|
+
const { m2mSecret, gpApiRootUrl } = config;
|
|
191
|
+
const clerkService = new ClerkService(m2mSecret);
|
|
192
|
+
await clerkService.getToken();
|
|
193
|
+
return new _GoodPartyClient(clerkService, gpApiRootUrl);
|
|
194
|
+
};
|
|
195
|
+
destroy = () => {
|
|
196
|
+
this.clerkService.destroy();
|
|
132
197
|
};
|
|
133
198
|
};
|
|
134
199
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/GoodPartyClient.ts","../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/UsersResource.ts","../src/types/user.ts"],"sourcesContent":["export { GoodPartyClient } from './GoodPartyClient'\nexport type { GoodPartyClientConfig } from './GoodPartyClient'\n\nexport { SdkError } from './types/result'\nexport type {\n PaginationOptions,\n PaginationMeta,\n PaginatedList,\n} from './types/result'\n\nexport type { User, UserMetaData, UpdatePasswordInput } from './types/user'\n\nexport { UserRole, WhyBrowsing } from './types/user'\n","import { createClerkClient } from '@clerk/backend'\nimport { HttpClient } from './http/HttpClient'\nimport { UsersResource } from './resources/UsersResource'\nimport { SdkError } from './types/result'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly users: UsersResource\n\n private constructor(gpApiRootUrl: string, m2mToken: string) {\n const httpClient = new HttpClient(gpApiRootUrl, m2mToken)\n this.users = new UsersResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkClient = createClerkClient({})\n\n let token: string\n try {\n const m2mToken = await clerkClient.m2m.createToken({\n machineSecretKey: m2mSecret,\n })\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n token = m2mToken.token\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n\n return new GoodPartyClient(gpApiRootUrl, token)\n }\n}\n","import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private m2mToken: string\n\n constructor(gpApiRootUrl: string, m2mToken: string) {\n this.baseUrl = gpApiRootUrl\n this.m2mToken = m2mToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${this.m2mToken}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n\nexport type PaginationOptions = {\n page?: number\n limit?: number\n}\n\nexport type PaginationMeta = {\n page: number\n limit: number\n total: number\n totalPages: number\n}\n\nexport type PaginatedList<T> = {\n data: T[]\n pagination: PaginationMeta\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { PaginatedList, PaginationOptions } from '../types/result'\nimport type { UpdatePasswordInput, User } from '../types/user'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n list = async (options?: PaginationOptions): Promise<PaginatedList<User>> => {\n const { data, meta: pagination } = await this.getRequest<{\n data: User[]\n meta: { page: number; limit: number; total: number; totalPages: number }\n }>('/users', options)\n\n return {\n data,\n pagination,\n }\n }\n\n get = (id: number): Promise<User> => this.getRequest<User>(`/users/${id}`)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`/users/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`/users/${id}/password`, input)\n}\n","export enum UserRole {\n admin = 'admin',\n sales = 'sales',\n candidate = 'candidate',\n campaignManager = 'campaignManager',\n demo = 'demo',\n}\n\nexport enum WhyBrowsing {\n considering = 'considering',\n learning = 'learning',\n test = 'test',\n else = 'else',\n}\n\nexport type UserMetaData = {\n customerId?: string\n checkoutSessionId?: string | null\n accountType?: string | null\n lastVisited?: number\n sessionCount?: number\n isDeleted?: boolean\n fsUserId?: string\n whyBrowsing?: WhyBrowsing | null\n hubspotId?: string\n profile_updated_count?: number\n textNotifications?: boolean\n} | null\n\nexport type User = {\n id: number\n firstName: string\n lastName: string\n name?: string | null\n email: string\n phone?: string | null\n zip?: string | null\n avatar?: string | null\n hasPassword: boolean\n roles?: UserRole[]\n metaData?: UserMetaData\n}\n\nexport type UpdatePasswordInput = {\n oldPassword?: string\n newPassword: string\n}\n"],"mappings":"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","names":["UserRole","WhyBrowsing"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/UsersResource.ts","../src/vendor/clerk/clerk.service.ts","../src/GoodPartyClient.ts","../src/types/user.ts"],"sourcesContent":["export { GoodPartyClient } from './GoodPartyClient'\nexport type { GoodPartyClientConfig } from './GoodPartyClient'\n\nexport { SdkError } from './types/result'\nexport type {\n PaginationOptions,\n PaginationMeta,\n PaginatedList,\n} from './types/result'\n\nexport type {\n User,\n UserMetaData,\n ListUsersOptions,\n UpdatePasswordInput,\n} from './types/user'\n\nexport { UserRole, WhyBrowsing } from './types/user'\n","import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private getToken: () => Promise<string>\n\n constructor(gpApiRootUrl: string, getToken: () => Promise<string>) {\n this.baseUrl = gpApiRootUrl\n this.getToken = getToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${await this.getToken()}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n\nexport type PaginationOptions = {\n offset?: number\n limit?: number\n sortBy?: string\n sortOrder?: 'asc' | 'desc'\n}\n\nexport type PaginationMeta = {\n total: number\n offset: number\n limit: number\n}\n\nexport type PaginatedList<T> = {\n data: T[]\n meta: PaginationMeta\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { PaginatedList } from '../types/result'\nimport type { ListUsersOptions, UpdatePasswordInput, User } from '../types/user'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n list = (options?: ListUsersOptions): Promise<PaginatedList<User>> =>\n this.getRequest<PaginatedList<User>>('/users', options)\n\n get = (id: number): Promise<User> => this.getRequest<User>(`/users/${id}`)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`/users/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`/users/${id}/password`, input)\n}\n","import { createClerkClient } from '@clerk/backend'\nimport { SdkError } from '../../types/result'\n\nconst TOKEN_RENEWAL_BUFFER_MS = 30_000\n\nexport class ClerkService {\n private readonly m2mSecret: string\n private readonly clerkClient: ReturnType<typeof createClerkClient>\n private cachedToken: string | null = null\n private tokenExpiration: number | null = null\n private renewalTimer: ReturnType<typeof setTimeout> | null = null\n private pendingTokenPromise: Promise<string> | null = null\n private destroyed = false\n\n constructor(m2mSecret: string) {\n this.m2mSecret = m2mSecret\n this.clerkClient = createClerkClient({})\n }\n\n getToken = async (): Promise<string> => {\n if (this.cachedToken && this.isTokenValid()) {\n return this.cachedToken\n }\n\n if (this.pendingTokenPromise) {\n return this.pendingTokenPromise\n }\n\n const promise = this.createAndCacheToken()\n this.pendingTokenPromise = promise\n\n try {\n return await promise\n } finally {\n if (this.pendingTokenPromise === promise) {\n this.pendingTokenPromise = null\n }\n }\n }\n\n destroy = (): void => {\n this.destroyed = true\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n this.cachedToken = null\n this.tokenExpiration = null\n this.pendingTokenPromise = null\n }\n\n private isTokenValid = (): boolean => {\n if (!this.tokenExpiration) return true\n return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS\n }\n\n private createAndCacheToken = async (): Promise<string> => {\n try {\n const m2mToken = await this.clerkClient.m2m.createToken({\n machineSecretKey: this.m2mSecret,\n })\n\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n\n if (this.destroyed) return m2mToken.token\n\n this.cachedToken = m2mToken.token\n this.tokenExpiration = m2mToken.expiration\n this.scheduleRenewal()\n\n return this.cachedToken\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n }\n\n private scheduleRenewal = (): void => {\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n\n if (!this.tokenExpiration) return\n\n const timeUntilRenewal =\n this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS\n\n if (timeUntilRenewal <= 0) return\n\n this.renewalTimer = setTimeout(() => {\n this.cachedToken = null\n this.getToken().catch((error: unknown) => {\n console.error('Proactive M2M token renewal failed:', error)\n })\n }, timeUntilRenewal)\n }\n}\n","import { HttpClient } from './http/HttpClient'\nimport { UsersResource } from './resources/UsersResource'\nimport { ClerkService } from './vendor/clerk/clerk.service'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly users: UsersResource\n private clerkService: ClerkService\n\n private constructor(clerkService: ClerkService, gpApiRootUrl: string) {\n this.clerkService = clerkService\n const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken)\n this.users = new UsersResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkService = new ClerkService(m2mSecret)\n await clerkService.getToken()\n return new GoodPartyClient(clerkService, gpApiRootUrl)\n }\n\n destroy = (): void => {\n this.clerkService.destroy()\n }\n}\n","import type { PaginationOptions } from './result'\n\nexport enum UserRole {\n admin = 'admin',\n sales = 'sales',\n candidate = 'candidate',\n campaignManager = 'campaignManager',\n demo = 'demo',\n}\n\nexport enum WhyBrowsing {\n considering = 'considering',\n learning = 'learning',\n test = 'test',\n else = 'else',\n}\n\nexport type UserMetaData = {\n customerId?: string\n checkoutSessionId?: string | null\n accountType?: string | null\n lastVisited?: number\n sessionCount?: number\n isDeleted?: boolean\n fsUserId?: string\n whyBrowsing?: WhyBrowsing | null\n hubspotId?: string\n profile_updated_count?: number\n textNotifications?: boolean\n} | null\n\nexport type User = {\n id: number\n firstName: string\n lastName: string\n name?: string | null\n email: string\n phone?: string | null\n zip?: string | null\n avatar?: string | null\n hasPassword: boolean\n roles?: UserRole[]\n metaData?: UserMetaData\n}\n\nexport type ListUsersOptions = PaginationOptions & {\n firstName?: string\n lastName?: string\n email?: string\n}\n\nexport type UpdatePasswordInput = {\n oldPassword?: string\n newPassword: string\n}\n"],"mappings":"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","names":["UserRole","WhyBrowsing"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// src/GoodPartyClient.ts
|
|
2
|
-
import { createClerkClient } from "@clerk/backend";
|
|
3
|
-
|
|
4
1
|
// src/http/HttpClient.ts
|
|
5
2
|
import { ofetch, FetchError } from "ofetch";
|
|
6
3
|
|
|
@@ -19,17 +16,17 @@ var SdkError = class extends Error {
|
|
|
19
16
|
// src/http/HttpClient.ts
|
|
20
17
|
var HttpClient = class {
|
|
21
18
|
baseUrl;
|
|
22
|
-
|
|
23
|
-
constructor(gpApiRootUrl,
|
|
19
|
+
getToken;
|
|
20
|
+
constructor(gpApiRootUrl, getToken) {
|
|
24
21
|
this.baseUrl = gpApiRootUrl;
|
|
25
|
-
this.
|
|
22
|
+
this.getToken = getToken;
|
|
26
23
|
}
|
|
27
24
|
request = async (path, init) => {
|
|
28
25
|
try {
|
|
29
26
|
return await ofetch(path, {
|
|
30
27
|
baseURL: this.baseUrl,
|
|
31
28
|
headers: {
|
|
32
|
-
Authorization: `Bearer ${this.
|
|
29
|
+
Authorization: `Bearer ${await this.getToken()}`,
|
|
33
30
|
...init?.headers ?? {}
|
|
34
31
|
},
|
|
35
32
|
...init
|
|
@@ -58,32 +55,62 @@ var BaseResource = class {
|
|
|
58
55
|
|
|
59
56
|
// src/resources/UsersResource.ts
|
|
60
57
|
var UsersResource = class extends BaseResource {
|
|
61
|
-
list =
|
|
62
|
-
const { data, meta: pagination } = await this.getRequest("/users", options);
|
|
63
|
-
return {
|
|
64
|
-
data,
|
|
65
|
-
pagination
|
|
66
|
-
};
|
|
67
|
-
};
|
|
58
|
+
list = (options) => this.getRequest("/users", options);
|
|
68
59
|
get = (id) => this.getRequest(`/users/${id}`);
|
|
69
60
|
delete = (id) => this.deleteRequest(`/users/${id}`);
|
|
70
61
|
updatePassword = (id, input) => this.putRequest(`/users/${id}/password`, input);
|
|
71
62
|
};
|
|
72
63
|
|
|
73
|
-
// src/
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
// src/vendor/clerk/clerk.service.ts
|
|
65
|
+
import { createClerkClient } from "@clerk/backend";
|
|
66
|
+
var TOKEN_RENEWAL_BUFFER_MS = 3e4;
|
|
67
|
+
var ClerkService = class {
|
|
68
|
+
m2mSecret;
|
|
69
|
+
clerkClient;
|
|
70
|
+
cachedToken = null;
|
|
71
|
+
tokenExpiration = null;
|
|
72
|
+
renewalTimer = null;
|
|
73
|
+
pendingTokenPromise = null;
|
|
74
|
+
destroyed = false;
|
|
75
|
+
constructor(m2mSecret) {
|
|
76
|
+
this.m2mSecret = m2mSecret;
|
|
77
|
+
this.clerkClient = createClerkClient({});
|
|
79
78
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
getToken = async () => {
|
|
80
|
+
if (this.cachedToken && this.isTokenValid()) {
|
|
81
|
+
return this.cachedToken;
|
|
82
|
+
}
|
|
83
|
+
if (this.pendingTokenPromise) {
|
|
84
|
+
return this.pendingTokenPromise;
|
|
85
|
+
}
|
|
86
|
+
const promise = this.createAndCacheToken();
|
|
87
|
+
this.pendingTokenPromise = promise;
|
|
88
|
+
try {
|
|
89
|
+
return await promise;
|
|
90
|
+
} finally {
|
|
91
|
+
if (this.pendingTokenPromise === promise) {
|
|
92
|
+
this.pendingTokenPromise = null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
destroy = () => {
|
|
97
|
+
this.destroyed = true;
|
|
98
|
+
if (this.renewalTimer) {
|
|
99
|
+
clearTimeout(this.renewalTimer);
|
|
100
|
+
this.renewalTimer = null;
|
|
101
|
+
}
|
|
102
|
+
this.cachedToken = null;
|
|
103
|
+
this.tokenExpiration = null;
|
|
104
|
+
this.pendingTokenPromise = null;
|
|
105
|
+
};
|
|
106
|
+
isTokenValid = () => {
|
|
107
|
+
if (!this.tokenExpiration) return true;
|
|
108
|
+
return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS;
|
|
109
|
+
};
|
|
110
|
+
createAndCacheToken = async () => {
|
|
84
111
|
try {
|
|
85
|
-
const m2mToken = await clerkClient.m2m.createToken({
|
|
86
|
-
machineSecretKey: m2mSecret
|
|
112
|
+
const m2mToken = await this.clerkClient.m2m.createToken({
|
|
113
|
+
machineSecretKey: this.m2mSecret
|
|
87
114
|
});
|
|
88
115
|
if (!m2mToken.token) {
|
|
89
116
|
throw new SdkError(
|
|
@@ -91,7 +118,11 @@ var GoodPartyClient = class _GoodPartyClient {
|
|
|
91
118
|
"Clerk M2M token creation succeeded but returned no token string"
|
|
92
119
|
);
|
|
93
120
|
}
|
|
94
|
-
|
|
121
|
+
if (this.destroyed) return m2mToken.token;
|
|
122
|
+
this.cachedToken = m2mToken.token;
|
|
123
|
+
this.tokenExpiration = m2mToken.expiration;
|
|
124
|
+
this.scheduleRenewal();
|
|
125
|
+
return this.cachedToken;
|
|
95
126
|
} catch (error) {
|
|
96
127
|
if (error instanceof SdkError) {
|
|
97
128
|
throw error;
|
|
@@ -99,7 +130,41 @@ var GoodPartyClient = class _GoodPartyClient {
|
|
|
99
130
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
100
131
|
throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`);
|
|
101
132
|
}
|
|
102
|
-
|
|
133
|
+
};
|
|
134
|
+
scheduleRenewal = () => {
|
|
135
|
+
if (this.renewalTimer) {
|
|
136
|
+
clearTimeout(this.renewalTimer);
|
|
137
|
+
this.renewalTimer = null;
|
|
138
|
+
}
|
|
139
|
+
if (!this.tokenExpiration) return;
|
|
140
|
+
const timeUntilRenewal = this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS;
|
|
141
|
+
if (timeUntilRenewal <= 0) return;
|
|
142
|
+
this.renewalTimer = setTimeout(() => {
|
|
143
|
+
this.cachedToken = null;
|
|
144
|
+
this.getToken().catch((error) => {
|
|
145
|
+
console.error("Proactive M2M token renewal failed:", error);
|
|
146
|
+
});
|
|
147
|
+
}, timeUntilRenewal);
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// src/GoodPartyClient.ts
|
|
152
|
+
var GoodPartyClient = class _GoodPartyClient {
|
|
153
|
+
users;
|
|
154
|
+
clerkService;
|
|
155
|
+
constructor(clerkService, gpApiRootUrl) {
|
|
156
|
+
this.clerkService = clerkService;
|
|
157
|
+
const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken);
|
|
158
|
+
this.users = new UsersResource(httpClient);
|
|
159
|
+
}
|
|
160
|
+
static create = async (config) => {
|
|
161
|
+
const { m2mSecret, gpApiRootUrl } = config;
|
|
162
|
+
const clerkService = new ClerkService(m2mSecret);
|
|
163
|
+
await clerkService.getToken();
|
|
164
|
+
return new _GoodPartyClient(clerkService, gpApiRootUrl);
|
|
165
|
+
};
|
|
166
|
+
destroy = () => {
|
|
167
|
+
this.clerkService.destroy();
|
|
103
168
|
};
|
|
104
169
|
};
|
|
105
170
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/GoodPartyClient.ts","../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/UsersResource.ts","../src/types/user.ts"],"sourcesContent":["import { createClerkClient } from '@clerk/backend'\nimport { HttpClient } from './http/HttpClient'\nimport { UsersResource } from './resources/UsersResource'\nimport { SdkError } from './types/result'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly users: UsersResource\n\n private constructor(gpApiRootUrl: string, m2mToken: string) {\n const httpClient = new HttpClient(gpApiRootUrl, m2mToken)\n this.users = new UsersResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkClient = createClerkClient({})\n\n let token: string\n try {\n const m2mToken = await clerkClient.m2m.createToken({\n machineSecretKey: m2mSecret,\n })\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n token = m2mToken.token\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n\n return new GoodPartyClient(gpApiRootUrl, token)\n }\n}\n","import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private m2mToken: string\n\n constructor(gpApiRootUrl: string, m2mToken: string) {\n this.baseUrl = gpApiRootUrl\n this.m2mToken = m2mToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${this.m2mToken}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n\nexport type PaginationOptions = {\n page?: number\n limit?: number\n}\n\nexport type PaginationMeta = {\n page: number\n limit: number\n total: number\n totalPages: number\n}\n\nexport type PaginatedList<T> = {\n data: T[]\n pagination: PaginationMeta\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { PaginatedList, PaginationOptions } from '../types/result'\nimport type { UpdatePasswordInput, User } from '../types/user'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n list = async (options?: PaginationOptions): Promise<PaginatedList<User>> => {\n const { data, meta: pagination } = await this.getRequest<{\n data: User[]\n meta: { page: number; limit: number; total: number; totalPages: number }\n }>('/users', options)\n\n return {\n data,\n pagination,\n }\n }\n\n get = (id: number): Promise<User> => this.getRequest<User>(`/users/${id}`)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`/users/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`/users/${id}/password`, input)\n}\n","export enum UserRole {\n admin = 'admin',\n sales = 'sales',\n candidate = 'candidate',\n campaignManager = 'campaignManager',\n demo = 'demo',\n}\n\nexport enum WhyBrowsing {\n considering = 'considering',\n learning = 'learning',\n test = 'test',\n else = 'else',\n}\n\nexport type UserMetaData = {\n customerId?: string\n checkoutSessionId?: string | null\n accountType?: string | null\n lastVisited?: number\n sessionCount?: number\n isDeleted?: boolean\n fsUserId?: string\n whyBrowsing?: WhyBrowsing | null\n hubspotId?: string\n profile_updated_count?: number\n textNotifications?: boolean\n} | null\n\nexport type User = {\n id: number\n firstName: string\n lastName: string\n name?: string | null\n email: string\n phone?: string | null\n zip?: string | null\n avatar?: string | null\n hasPassword: boolean\n roles?: UserRole[]\n metaData?: UserMetaData\n}\n\nexport type UpdatePasswordInput = {\n oldPassword?: string\n newPassword: string\n}\n"],"mappings":"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","names":["UserRole","WhyBrowsing"]}
|
|
1
|
+
{"version":3,"sources":["../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/UsersResource.ts","../src/vendor/clerk/clerk.service.ts","../src/GoodPartyClient.ts","../src/types/user.ts"],"sourcesContent":["import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private getToken: () => Promise<string>\n\n constructor(gpApiRootUrl: string, getToken: () => Promise<string>) {\n this.baseUrl = gpApiRootUrl\n this.getToken = getToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${await this.getToken()}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n\nexport type PaginationOptions = {\n offset?: number\n limit?: number\n sortBy?: string\n sortOrder?: 'asc' | 'desc'\n}\n\nexport type PaginationMeta = {\n total: number\n offset: number\n limit: number\n}\n\nexport type PaginatedList<T> = {\n data: T[]\n meta: PaginationMeta\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { PaginatedList } from '../types/result'\nimport type { ListUsersOptions, UpdatePasswordInput, User } from '../types/user'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n list = (options?: ListUsersOptions): Promise<PaginatedList<User>> =>\n this.getRequest<PaginatedList<User>>('/users', options)\n\n get = (id: number): Promise<User> => this.getRequest<User>(`/users/${id}`)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`/users/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`/users/${id}/password`, input)\n}\n","import { createClerkClient } from '@clerk/backend'\nimport { SdkError } from '../../types/result'\n\nconst TOKEN_RENEWAL_BUFFER_MS = 30_000\n\nexport class ClerkService {\n private readonly m2mSecret: string\n private readonly clerkClient: ReturnType<typeof createClerkClient>\n private cachedToken: string | null = null\n private tokenExpiration: number | null = null\n private renewalTimer: ReturnType<typeof setTimeout> | null = null\n private pendingTokenPromise: Promise<string> | null = null\n private destroyed = false\n\n constructor(m2mSecret: string) {\n this.m2mSecret = m2mSecret\n this.clerkClient = createClerkClient({})\n }\n\n getToken = async (): Promise<string> => {\n if (this.cachedToken && this.isTokenValid()) {\n return this.cachedToken\n }\n\n if (this.pendingTokenPromise) {\n return this.pendingTokenPromise\n }\n\n const promise = this.createAndCacheToken()\n this.pendingTokenPromise = promise\n\n try {\n return await promise\n } finally {\n if (this.pendingTokenPromise === promise) {\n this.pendingTokenPromise = null\n }\n }\n }\n\n destroy = (): void => {\n this.destroyed = true\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n this.cachedToken = null\n this.tokenExpiration = null\n this.pendingTokenPromise = null\n }\n\n private isTokenValid = (): boolean => {\n if (!this.tokenExpiration) return true\n return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS\n }\n\n private createAndCacheToken = async (): Promise<string> => {\n try {\n const m2mToken = await this.clerkClient.m2m.createToken({\n machineSecretKey: this.m2mSecret,\n })\n\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n\n if (this.destroyed) return m2mToken.token\n\n this.cachedToken = m2mToken.token\n this.tokenExpiration = m2mToken.expiration\n this.scheduleRenewal()\n\n return this.cachedToken\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n }\n\n private scheduleRenewal = (): void => {\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n\n if (!this.tokenExpiration) return\n\n const timeUntilRenewal =\n this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS\n\n if (timeUntilRenewal <= 0) return\n\n this.renewalTimer = setTimeout(() => {\n this.cachedToken = null\n this.getToken().catch((error: unknown) => {\n console.error('Proactive M2M token renewal failed:', error)\n })\n }, timeUntilRenewal)\n }\n}\n","import { HttpClient } from './http/HttpClient'\nimport { UsersResource } from './resources/UsersResource'\nimport { ClerkService } from './vendor/clerk/clerk.service'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly users: UsersResource\n private clerkService: ClerkService\n\n private constructor(clerkService: ClerkService, gpApiRootUrl: string) {\n this.clerkService = clerkService\n const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken)\n this.users = new UsersResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkService = new ClerkService(m2mSecret)\n await clerkService.getToken()\n return new GoodPartyClient(clerkService, gpApiRootUrl)\n }\n\n destroy = (): void => {\n this.clerkService.destroy()\n }\n}\n","import type { PaginationOptions } from './result'\n\nexport enum UserRole {\n admin = 'admin',\n sales = 'sales',\n candidate = 'candidate',\n campaignManager = 'campaignManager',\n demo = 'demo',\n}\n\nexport enum WhyBrowsing {\n considering = 'considering',\n learning = 'learning',\n test = 'test',\n else = 'else',\n}\n\nexport type UserMetaData = {\n customerId?: string\n checkoutSessionId?: string | null\n accountType?: string | null\n lastVisited?: number\n sessionCount?: number\n isDeleted?: boolean\n fsUserId?: string\n whyBrowsing?: WhyBrowsing | null\n hubspotId?: string\n profile_updated_count?: number\n textNotifications?: boolean\n} | null\n\nexport type User = {\n id: number\n firstName: string\n lastName: string\n name?: string | null\n email: string\n phone?: string | null\n zip?: string | null\n avatar?: string | null\n hasPassword: boolean\n roles?: UserRole[]\n metaData?: UserMetaData\n}\n\nexport type ListUsersOptions = PaginationOptions & {\n firstName?: string\n lastName?: string\n email?: string\n}\n\nexport type UpdatePasswordInput = {\n oldPassword?: string\n newPassword: string\n}\n"],"mappings":"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","names":["UserRole","WhyBrowsing"]}
|