@timbrix/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.
package/dist/index.js ADDED
@@ -0,0 +1,574 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ ApiKeyAuth: () => ApiKeyAuth,
34
+ ApiKeysResource: () => ApiKeysResource,
35
+ AuthResource: () => AuthResource,
36
+ BearerAuth: () => BearerAuth,
37
+ CustomersResource: () => CustomersResource,
38
+ OAuthResource: () => OAuthResource,
39
+ OrganizationsResource: () => OrganizationsResource,
40
+ ProductsResource: () => ProductsResource,
41
+ Timbrix: () => Timbrix,
42
+ UsersResource: () => UsersResource,
43
+ WebhooksResource: () => WebhooksResource
44
+ });
45
+ module.exports = __toCommonJS(index_exports);
46
+
47
+ // src/client.ts
48
+ var import_ky = __toESM(require("ky"));
49
+
50
+ // src/auth/base.ts
51
+ var BearerAuth = class {
52
+ constructor(token) {
53
+ this.token = token;
54
+ }
55
+ getHeaders() {
56
+ return {
57
+ Authorization: `Bearer ${this.token}`
58
+ };
59
+ }
60
+ applyAuth(options) {
61
+ return {
62
+ ...options,
63
+ headers: {
64
+ ...options.headers,
65
+ ...this.getHeaders()
66
+ }
67
+ };
68
+ }
69
+ };
70
+ var ApiKeyAuth = class {
71
+ constructor(apiKey) {
72
+ this.apiKey = apiKey;
73
+ }
74
+ getHeaders() {
75
+ return {
76
+ "X-API-Key": this.apiKey
77
+ };
78
+ }
79
+ applyAuth(options) {
80
+ return {
81
+ ...options,
82
+ headers: {
83
+ ...options.headers,
84
+ ...this.getHeaders()
85
+ }
86
+ };
87
+ }
88
+ };
89
+
90
+ // src/resources/api-keys.ts
91
+ var ApiKeysResource = class {
92
+ constructor(http) {
93
+ this.http = http;
94
+ }
95
+ /**
96
+ * List all API keys for an organization
97
+ */
98
+ async list(organizationId) {
99
+ return this.http.get(`organizations/${organizationId}/api-keys`).json();
100
+ }
101
+ /**
102
+ * Get API key by ID
103
+ */
104
+ async get(organizationId, apiKeyId) {
105
+ return this.http.get(`organizations/${organizationId}/api-keys/${apiKeyId}`).json();
106
+ }
107
+ /**
108
+ * Create a new API key. The plain key is returned only once in the response.
109
+ */
110
+ async create(organizationId, data) {
111
+ return this.http.post(`organizations/${organizationId}/api-keys`, { json: data }).json();
112
+ }
113
+ /**
114
+ * Update API key
115
+ */
116
+ async update(organizationId, apiKeyId, data) {
117
+ return this.http.put(`organizations/${organizationId}/api-keys/${apiKeyId}`, {
118
+ json: data
119
+ }).json();
120
+ }
121
+ /**
122
+ * Delete (revoke) API key
123
+ */
124
+ async delete(organizationId, apiKeyId) {
125
+ await this.http.delete(
126
+ `organizations/${organizationId}/api-keys/${apiKeyId}`
127
+ );
128
+ }
129
+ /**
130
+ * Get API key usage statistics for an organization
131
+ */
132
+ async stats(organizationId) {
133
+ return this.http.get(`organizations/${organizationId}/api-keys/stats`).json();
134
+ }
135
+ /**
136
+ * Validate the currently authenticated API key (uses X-API-Key header)
137
+ */
138
+ async validate() {
139
+ return this.http.post("api-keys/validate").json();
140
+ }
141
+ };
142
+
143
+ // src/resources/auth.ts
144
+ var AuthResource = class {
145
+ constructor(http) {
146
+ this.http = http;
147
+ }
148
+ /**
149
+ * Login with email and password. Returns an access token.
150
+ */
151
+ async login(data) {
152
+ return this.http.post("auth/login", { json: data }).json();
153
+ }
154
+ /**
155
+ * Logout and revoke the current access token.
156
+ */
157
+ async logout() {
158
+ await this.http.post("auth/logout");
159
+ }
160
+ };
161
+
162
+ // src/resources/customers.ts
163
+ var CustomersResource = class {
164
+ constructor(http) {
165
+ this.http = http;
166
+ }
167
+ /**
168
+ * List all customers for an organization
169
+ */
170
+ async list(organizationId) {
171
+ return this.http.get(`organizations/${organizationId}/customers`).json();
172
+ }
173
+ /**
174
+ * Get a customer by ID
175
+ */
176
+ async get(organizationId, customerId) {
177
+ return this.http.get(`organizations/${organizationId}/customers/${customerId}`).json();
178
+ }
179
+ /**
180
+ * Create a new customer
181
+ */
182
+ async create(organizationId, data) {
183
+ return this.http.post(`organizations/${organizationId}/customers`, { json: data }).json();
184
+ }
185
+ /**
186
+ * Update a customer
187
+ */
188
+ async update(organizationId, customerId, data) {
189
+ return this.http.put(`organizations/${organizationId}/customers/${customerId}`, {
190
+ json: data
191
+ }).json();
192
+ }
193
+ /**
194
+ * Delete a customer
195
+ */
196
+ async delete(organizationId, customerId) {
197
+ await this.http.delete(
198
+ `organizations/${organizationId}/customers/${customerId}`
199
+ );
200
+ }
201
+ };
202
+
203
+ // src/resources/oauth.ts
204
+ var OAuthResource = class {
205
+ constructor(http) {
206
+ this.http = http;
207
+ }
208
+ // ─── App Management ─────────────────────────────────────────────────────────
209
+ /**
210
+ * Create a new OAuth application. Client secret is returned only once.
211
+ */
212
+ async createApp(data) {
213
+ return this.http.post("oauth/apps", { json: data }).json();
214
+ }
215
+ /**
216
+ * Get OAuth application by client ID
217
+ */
218
+ async getApp(clientId) {
219
+ return this.http.get(`oauth/apps/${clientId}`).json();
220
+ }
221
+ /**
222
+ * List OAuth applications for an organization
223
+ */
224
+ async listApps(organizationId) {
225
+ return this.http.get(`oauth/apps/organization/${organizationId}`).json();
226
+ }
227
+ /**
228
+ * Update OAuth application
229
+ */
230
+ async updateApp(clientId, data) {
231
+ return this.http.put(`oauth/apps/${clientId}`, { json: data }).json();
232
+ }
233
+ /**
234
+ * Delete OAuth application. All associated tokens will be revoked.
235
+ */
236
+ async deleteApp(clientId) {
237
+ await this.http.delete(`oauth/apps/${clientId}`);
238
+ }
239
+ /**
240
+ * List active tokens for an OAuth application
241
+ */
242
+ async listTokens(clientId) {
243
+ return this.http.get(`oauth/apps/${clientId}/tokens`).json();
244
+ }
245
+ /**
246
+ * Revoke an OAuth token (requires write:oauth-apps scope)
247
+ */
248
+ async revokeToken(tokenId) {
249
+ await this.http.delete(`oauth/token/${tokenId}`);
250
+ }
251
+ // ─── Token Operations ────────────────────────────────────────────────────────
252
+ /**
253
+ * Generate an access token using client credentials flow
254
+ */
255
+ async generateToken(data) {
256
+ return this.http.post("oauth/token", {
257
+ json: {
258
+ grant_type: "client_credentials",
259
+ client_id: data.clientId,
260
+ client_secret: data.clientSecret,
261
+ scope: data.scopes.join(" "),
262
+ user_id: data.userId
263
+ }
264
+ }).json();
265
+ }
266
+ /**
267
+ * Exchange an authorization code for access and refresh tokens
268
+ */
269
+ async exchangeCode(data) {
270
+ return this.http.post("oauth/token/exchange", {
271
+ json: {
272
+ code: data.code,
273
+ clientId: data.clientId,
274
+ clientSecret: data.clientSecret,
275
+ redirectUri: data.redirectUri,
276
+ grantType: "authorization_code",
277
+ codeVerifier: data.codeVerifier
278
+ }
279
+ }).json();
280
+ }
281
+ /**
282
+ * Refresh an access token using a refresh token
283
+ */
284
+ async refreshToken(data) {
285
+ return this.http.post("oauth/token/refresh", {
286
+ json: { refreshToken: data.refreshToken }
287
+ }).json();
288
+ }
289
+ };
290
+
291
+ // src/resources/organizations.ts
292
+ var OrganizationsResource = class {
293
+ constructor(http) {
294
+ this.http = http;
295
+ }
296
+ /**
297
+ * Create a new organization
298
+ */
299
+ async create(data) {
300
+ return this.http.post("organizations", { json: data }).json();
301
+ }
302
+ /**
303
+ * Get organization by ID
304
+ */
305
+ async get(id) {
306
+ return this.http.get(`organizations/${id}`).json();
307
+ }
308
+ /**
309
+ * Update organization (owner only)
310
+ */
311
+ async update(id, data) {
312
+ return this.http.put(`organizations/${id}`, { json: data }).json();
313
+ }
314
+ /**
315
+ * Update organization legal/fiscal data (owner only)
316
+ */
317
+ async updateLegalData(id, data) {
318
+ return this.http.put(`organizations/${id}/legal`, { json: data }).json();
319
+ }
320
+ /**
321
+ * Delete organization (owner only)
322
+ */
323
+ async delete(id) {
324
+ await this.http.delete(`organizations/${id}`);
325
+ }
326
+ /**
327
+ * Get organization members
328
+ */
329
+ async members(id) {
330
+ return this.http.get(`organizations/${id}/members`).json();
331
+ }
332
+ /**
333
+ * Invite a member (owner/admin only)
334
+ */
335
+ async invite(id, data) {
336
+ return this.http.post(`organizations/${id}/members/invite`, { json: data }).json();
337
+ }
338
+ /**
339
+ * Remove a member (owner/admin only)
340
+ */
341
+ async removeMember(id, memberId) {
342
+ await this.http.delete(`organizations/${id}/members/${memberId}`);
343
+ }
344
+ /**
345
+ * Update member role (owner/admin only)
346
+ */
347
+ async updateMemberRole(id, memberId, data) {
348
+ return this.http.put(`organizations/${id}/members/${memberId}/role`, { json: data }).json();
349
+ }
350
+ /**
351
+ * Get pending invitations
352
+ */
353
+ async invites(id) {
354
+ return this.http.get(`organizations/${id}/invites`).json();
355
+ }
356
+ /**
357
+ * Cancel a pending invitation (owner/admin only)
358
+ */
359
+ async cancelInvite(id, inviteId) {
360
+ await this.http.delete(`organizations/${id}/invites/${inviteId}`);
361
+ }
362
+ };
363
+
364
+ // src/resources/products.ts
365
+ var ProductsResource = class {
366
+ constructor(http) {
367
+ this.http = http;
368
+ }
369
+ /**
370
+ * List products for an organization, with optional filters
371
+ */
372
+ async list(organizationId, filters) {
373
+ const searchParams = {};
374
+ if (filters?.description) searchParams.description = filters.description;
375
+ if (filters?.sku) searchParams.sku = filters.sku;
376
+ if (filters?.productKey !== void 0)
377
+ searchParams.productKey = String(filters.productKey);
378
+ return this.http.get(`organizations/${organizationId}/products`, {
379
+ searchParams: Object.keys(searchParams).length > 0 ? searchParams : void 0
380
+ }).json();
381
+ }
382
+ /**
383
+ * Get a product by ID
384
+ */
385
+ async get(organizationId, productId) {
386
+ return this.http.get(`organizations/${organizationId}/products/${productId}`).json();
387
+ }
388
+ /**
389
+ * Create a new product or service
390
+ */
391
+ async create(organizationId, data) {
392
+ return this.http.post(`organizations/${organizationId}/products`, { json: data }).json();
393
+ }
394
+ /**
395
+ * Update a product
396
+ */
397
+ async update(organizationId, productId, data) {
398
+ return this.http.put(`organizations/${organizationId}/products/${productId}`, {
399
+ json: data
400
+ }).json();
401
+ }
402
+ /**
403
+ * Delete a product
404
+ */
405
+ async delete(organizationId, productId) {
406
+ await this.http.delete(
407
+ `organizations/${organizationId}/products/${productId}`
408
+ );
409
+ }
410
+ };
411
+
412
+ // src/resources/users.ts
413
+ var UsersResource = class {
414
+ constructor(http) {
415
+ this.http = http;
416
+ }
417
+ /**
418
+ * Get the currently authenticated user
419
+ */
420
+ async me() {
421
+ return this.http.get("users/me").json();
422
+ }
423
+ /**
424
+ * Get user by ID (requires read:user scope)
425
+ */
426
+ async getById(id) {
427
+ return this.http.get(`users/${id}`).json();
428
+ }
429
+ /**
430
+ * Get organizations for a user (requires read:organization scope)
431
+ */
432
+ async getOrganizations(id) {
433
+ return this.http.get(`users/${id}/organizations`).json();
434
+ }
435
+ /**
436
+ * Get user by email (requires read:user scope)
437
+ */
438
+ async getByEmail(email) {
439
+ return this.http.get(`users/email/${encodeURIComponent(email)}`).json();
440
+ }
441
+ };
442
+
443
+ // src/resources/webhooks.ts
444
+ var WebhooksResource = class {
445
+ constructor(http) {
446
+ this.http = http;
447
+ }
448
+ /**
449
+ * List all webhooks for an organization
450
+ */
451
+ async list(organizationId) {
452
+ return this.http.get(`organizations/${organizationId}/webhooks`).json();
453
+ }
454
+ /**
455
+ * Get webhook by ID
456
+ */
457
+ async get(organizationId, webhookId) {
458
+ return this.http.get(`organizations/${organizationId}/webhooks/${webhookId}`).json();
459
+ }
460
+ /**
461
+ * Create a new webhook
462
+ */
463
+ async create(organizationId, data) {
464
+ return this.http.post(`organizations/${organizationId}/webhooks`, { json: data }).json();
465
+ }
466
+ /**
467
+ * Update webhook
468
+ */
469
+ async update(organizationId, webhookId, data) {
470
+ return this.http.put(`organizations/${organizationId}/webhooks/${webhookId}`, {
471
+ json: data
472
+ }).json();
473
+ }
474
+ /**
475
+ * Delete webhook
476
+ */
477
+ async delete(organizationId, webhookId) {
478
+ await this.http.delete(
479
+ `organizations/${organizationId}/webhooks/${webhookId}`
480
+ );
481
+ }
482
+ /**
483
+ * Get webhook delivery history
484
+ */
485
+ async deliveries(organizationId, webhookId) {
486
+ return this.http.get(`organizations/${organizationId}/webhooks/${webhookId}/deliveries`).json();
487
+ }
488
+ /**
489
+ * Send test webhook
490
+ */
491
+ async test(organizationId, webhookId) {
492
+ return this.http.post(`organizations/${organizationId}/webhooks/${webhookId}/test`).json();
493
+ }
494
+ };
495
+
496
+ // src/client.ts
497
+ var Timbrix = class {
498
+ http;
499
+ authStrategy;
500
+ auth;
501
+ organizations;
502
+ webhooks;
503
+ apiKeys;
504
+ users;
505
+ customers;
506
+ oauth;
507
+ products;
508
+ constructor(config = {}) {
509
+ const baseUrl = config.baseUrl || "http://localhost:3001/api";
510
+ if (config.bearerToken) {
511
+ this.authStrategy = new BearerAuth(config.bearerToken);
512
+ } else if (config.apiKey) {
513
+ this.authStrategy = new ApiKeyAuth(config.apiKey);
514
+ }
515
+ this.http = import_ky.default.create({
516
+ prefixUrl: baseUrl,
517
+ headers: {
518
+ "Content-Type": "application/json"
519
+ },
520
+ hooks: {
521
+ beforeRequest: [
522
+ (request) => {
523
+ if (this.authStrategy) {
524
+ const authHeaders = this.authStrategy.getHeaders();
525
+ Object.entries(authHeaders).forEach(([key, value]) => {
526
+ request.headers.set(key, value);
527
+ });
528
+ }
529
+ }
530
+ ]
531
+ }
532
+ });
533
+ this.auth = new AuthResource(this.http);
534
+ this.organizations = new OrganizationsResource(this.http);
535
+ this.webhooks = new WebhooksResource(this.http);
536
+ this.apiKeys = new ApiKeysResource(this.http);
537
+ this.users = new UsersResource(this.http);
538
+ this.customers = new CustomersResource(this.http);
539
+ this.oauth = new OAuthResource(this.http);
540
+ this.products = new ProductsResource(this.http);
541
+ }
542
+ /**
543
+ * Update authentication strategy (useful for CLI when token changes)
544
+ */
545
+ setAuth(bearerToken, apiKey) {
546
+ if (bearerToken) {
547
+ this.authStrategy = new BearerAuth(bearerToken);
548
+ } else if (apiKey) {
549
+ this.authStrategy = new ApiKeyAuth(apiKey);
550
+ } else {
551
+ this.authStrategy = void 0;
552
+ }
553
+ }
554
+ /**
555
+ * Make a custom request
556
+ */
557
+ async request(url, options) {
558
+ return this.http(url, options).json();
559
+ }
560
+ };
561
+ // Annotate the CommonJS export names for ESM import in node:
562
+ 0 && (module.exports = {
563
+ ApiKeyAuth,
564
+ ApiKeysResource,
565
+ AuthResource,
566
+ BearerAuth,
567
+ CustomersResource,
568
+ OAuthResource,
569
+ OrganizationsResource,
570
+ ProductsResource,
571
+ Timbrix,
572
+ UsersResource,
573
+ WebhooksResource
574
+ });