@mitralab.io/platform-sdk 1.0.7 → 1.0.8
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 +115 -66
- package/dist/index.d.mts +27 -508
- package/dist/index.d.ts +27 -508
- package/dist/index.js +147 -184
- package/dist/index.mjs +155 -184
- package/package.json +21 -10
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { encodePathSegment, expectObject } from "@mitralab.io/sdk-core";
|
|
3
|
+
|
|
1
4
|
// src/utils/http-client.ts
|
|
5
|
+
var bearerCredentialPattern = /(Bearer\s+)\S+/gi;
|
|
6
|
+
function redactText(value, currentToken) {
|
|
7
|
+
const withoutBearerCredentials = value.replace(bearerCredentialPattern, "$1[REDACTED]");
|
|
8
|
+
return currentToken ? withoutBearerCredentials.split(currentToken).join("[REDACTED]") : withoutBearerCredentials;
|
|
9
|
+
}
|
|
10
|
+
function redactDetails(value, currentToken) {
|
|
11
|
+
if (typeof value === "string") return redactText(value, currentToken);
|
|
12
|
+
if (Array.isArray(value)) return value.map((item) => redactDetails(item, currentToken));
|
|
13
|
+
if (value && typeof value === "object") {
|
|
14
|
+
return Object.fromEntries(
|
|
15
|
+
Object.entries(value).map(([key, entry]) => [
|
|
16
|
+
redactText(key, currentToken),
|
|
17
|
+
redactDetails(entry, currentToken)
|
|
18
|
+
])
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function asErrorPayload(value) {
|
|
24
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function optionalString(value) {
|
|
28
|
+
return typeof value === "string" ? value : void 0;
|
|
29
|
+
}
|
|
2
30
|
var HttpClient = class {
|
|
3
31
|
baseUrl;
|
|
4
32
|
tokenGetter;
|
|
@@ -62,8 +90,18 @@ var HttpClient = class {
|
|
|
62
90
|
const response = await fetch(url, {
|
|
63
91
|
method,
|
|
64
92
|
headers: requestHeaders,
|
|
65
|
-
body: body ? JSON.stringify(body) : void 0
|
|
93
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
94
|
+
redirect: "manual"
|
|
66
95
|
});
|
|
96
|
+
if (response.redirected || response.type === "opaqueredirect") {
|
|
97
|
+
const error = new MitraApiError(
|
|
98
|
+
"Redirected responses are not allowed",
|
|
99
|
+
response.status,
|
|
100
|
+
"REDIRECT_NOT_ALLOWED"
|
|
101
|
+
);
|
|
102
|
+
this.onError?.(error);
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
67
105
|
if (!response.ok) {
|
|
68
106
|
if (response.status === 401 && !isRetry && this.onUnauthorized) {
|
|
69
107
|
const refreshed = await this.onUnauthorized();
|
|
@@ -72,11 +110,14 @@ var HttpClient = class {
|
|
|
72
110
|
}
|
|
73
111
|
}
|
|
74
112
|
const errorBody = await response.json().catch(() => ({}));
|
|
113
|
+
const errorPayload = asErrorPayload(errorBody);
|
|
114
|
+
const rawMessage = optionalString(errorPayload.message);
|
|
115
|
+
const rawCode = optionalString(errorPayload.error_code);
|
|
75
116
|
const error = new MitraApiError(
|
|
76
|
-
|
|
117
|
+
redactText(rawMessage || `Request failed with status ${response.status}`, token),
|
|
77
118
|
response.status,
|
|
78
|
-
|
|
79
|
-
errorBody
|
|
119
|
+
rawCode === void 0 ? void 0 : redactText(rawCode, token),
|
|
120
|
+
redactDetails(errorBody, token)
|
|
80
121
|
);
|
|
81
122
|
this.onError?.(error);
|
|
82
123
|
throw error;
|
|
@@ -157,22 +198,31 @@ var MitraApiError = class extends Error {
|
|
|
157
198
|
}
|
|
158
199
|
};
|
|
159
200
|
|
|
201
|
+
// src/core-errors.ts
|
|
202
|
+
var coreErrors = {
|
|
203
|
+
configuration: (message) => new MitraApiError(message, 0, "INVALID_CONFIGURATION"),
|
|
204
|
+
invalidResponse: (message) => new MitraApiError(message, 200, "INVALID_RESPONSE")
|
|
205
|
+
};
|
|
206
|
+
|
|
160
207
|
// src/modules/auth.ts
|
|
208
|
+
import { createAuthModule } from "@mitralab.io/sdk-core";
|
|
161
209
|
var AuthModule = class {
|
|
162
210
|
appId;
|
|
163
211
|
_currentUser = null;
|
|
164
|
-
|
|
165
|
-
|
|
212
|
+
#accessToken = null;
|
|
213
|
+
#refreshToken = null;
|
|
166
214
|
refreshPromise = null;
|
|
167
215
|
listeners = /* @__PURE__ */ new Set();
|
|
168
216
|
storageKey;
|
|
169
217
|
publicClient;
|
|
170
218
|
authedClient;
|
|
219
|
+
currentUserApi;
|
|
171
220
|
constructor(appId, iamBaseUrl) {
|
|
172
221
|
this.appId = appId;
|
|
173
222
|
this.storageKey = `mitra_auth_${appId}`;
|
|
174
223
|
this.publicClient = new HttpClient({ baseUrl: iamBaseUrl, getToken: () => null });
|
|
175
|
-
this.authedClient = new HttpClient({ baseUrl: iamBaseUrl, getToken: () => this
|
|
224
|
+
this.authedClient = new HttpClient({ baseUrl: iamBaseUrl, getToken: () => this.#accessToken });
|
|
225
|
+
this.currentUserApi = createAuthModule(this.authedClient, coreErrors);
|
|
176
226
|
this.loadFromStorage();
|
|
177
227
|
}
|
|
178
228
|
/** The currently authenticated user, or null. */
|
|
@@ -181,11 +231,11 @@ var AuthModule = class {
|
|
|
181
231
|
}
|
|
182
232
|
/** The current JWT access token, or null. */
|
|
183
233
|
get accessToken() {
|
|
184
|
-
return this
|
|
234
|
+
return this.#accessToken;
|
|
185
235
|
}
|
|
186
236
|
/** Whether a user is currently authenticated (local check, not server-validated). */
|
|
187
237
|
get isAuthenticated() {
|
|
188
|
-
return this._currentUser !== null && this
|
|
238
|
+
return this._currentUser !== null && this.#accessToken !== null;
|
|
189
239
|
}
|
|
190
240
|
/**
|
|
191
241
|
* Signs in a user with email and password.
|
|
@@ -210,9 +260,9 @@ var AuthModule = class {
|
|
|
210
260
|
"/api/v1/auth/login",
|
|
211
261
|
{ ...credentials, appId: this.appId }
|
|
212
262
|
);
|
|
213
|
-
this
|
|
214
|
-
this
|
|
215
|
-
const user = await this.
|
|
263
|
+
this.#accessToken = tokenResponse.accessToken;
|
|
264
|
+
this.#refreshToken = tokenResponse.refreshToken;
|
|
265
|
+
const user = await this.getCurrentUser();
|
|
216
266
|
this.setAuthState(user, tokenResponse.accessToken, tokenResponse.refreshToken);
|
|
217
267
|
return user;
|
|
218
268
|
}
|
|
@@ -272,7 +322,7 @@ var AuthModule = class {
|
|
|
272
322
|
* ```
|
|
273
323
|
*/
|
|
274
324
|
async refreshSession() {
|
|
275
|
-
if (!this
|
|
325
|
+
if (!this.#refreshToken) return false;
|
|
276
326
|
if (this.refreshPromise) return this.refreshPromise;
|
|
277
327
|
this.refreshPromise = this.doRefresh();
|
|
278
328
|
try {
|
|
@@ -296,9 +346,9 @@ var AuthModule = class {
|
|
|
296
346
|
* ```
|
|
297
347
|
*/
|
|
298
348
|
async me() {
|
|
299
|
-
if (!this
|
|
349
|
+
if (!this.#accessToken) return null;
|
|
300
350
|
try {
|
|
301
|
-
const user = await this.
|
|
351
|
+
const user = await this.getCurrentUser();
|
|
302
352
|
this._currentUser = user;
|
|
303
353
|
this.saveToStorage();
|
|
304
354
|
this.notifyListeners();
|
|
@@ -339,7 +389,7 @@ var AuthModule = class {
|
|
|
339
389
|
* ```
|
|
340
390
|
*/
|
|
341
391
|
setToken(token, saveToStorage = true) {
|
|
342
|
-
this
|
|
392
|
+
this.#accessToken = token;
|
|
343
393
|
if (saveToStorage) {
|
|
344
394
|
this.saveToStorage();
|
|
345
395
|
}
|
|
@@ -390,11 +440,11 @@ var AuthModule = class {
|
|
|
390
440
|
try {
|
|
391
441
|
const tokenResponse = await this.publicClient.post(
|
|
392
442
|
"/api/v1/auth/refresh-token",
|
|
393
|
-
{ refreshToken: this
|
|
443
|
+
{ refreshToken: this.#refreshToken }
|
|
394
444
|
);
|
|
395
|
-
this
|
|
396
|
-
this
|
|
397
|
-
const user = await this.
|
|
445
|
+
this.#accessToken = tokenResponse.accessToken;
|
|
446
|
+
this.#refreshToken = tokenResponse.refreshToken;
|
|
447
|
+
const user = await this.getCurrentUser();
|
|
398
448
|
this.setAuthState(user, tokenResponse.accessToken, tokenResponse.refreshToken);
|
|
399
449
|
return true;
|
|
400
450
|
} catch {
|
|
@@ -404,15 +454,19 @@ var AuthModule = class {
|
|
|
404
454
|
}
|
|
405
455
|
setAuthState(user, token, refreshToken) {
|
|
406
456
|
this._currentUser = user;
|
|
407
|
-
this
|
|
408
|
-
this
|
|
457
|
+
this.#accessToken = token;
|
|
458
|
+
this.#refreshToken = refreshToken;
|
|
409
459
|
this.saveToStorage();
|
|
410
460
|
this.notifyListeners();
|
|
411
461
|
}
|
|
462
|
+
async getCurrentUser() {
|
|
463
|
+
const user = await this.currentUserApi.me();
|
|
464
|
+
return { ...user, tenantId: user.tenant.id };
|
|
465
|
+
}
|
|
412
466
|
clearAuthState() {
|
|
413
467
|
this._currentUser = null;
|
|
414
|
-
this
|
|
415
|
-
this
|
|
468
|
+
this.#accessToken = null;
|
|
469
|
+
this.#refreshToken = null;
|
|
416
470
|
this.removeFromStorage();
|
|
417
471
|
this.notifyListeners();
|
|
418
472
|
}
|
|
@@ -432,8 +486,8 @@ var AuthModule = class {
|
|
|
432
486
|
this.storageKey,
|
|
433
487
|
JSON.stringify({
|
|
434
488
|
user: this._currentUser,
|
|
435
|
-
token: this
|
|
436
|
-
refreshToken: this
|
|
489
|
+
token: this.#accessToken,
|
|
490
|
+
refreshToken: this.#refreshToken
|
|
437
491
|
})
|
|
438
492
|
);
|
|
439
493
|
} catch {
|
|
@@ -446,8 +500,8 @@ var AuthModule = class {
|
|
|
446
500
|
if (stored) {
|
|
447
501
|
const { user, token, refreshToken } = JSON.parse(stored);
|
|
448
502
|
this._currentUser = user;
|
|
449
|
-
this
|
|
450
|
-
this
|
|
503
|
+
this.#accessToken = token;
|
|
504
|
+
this.#refreshToken = refreshToken ?? null;
|
|
451
505
|
}
|
|
452
506
|
} catch {
|
|
453
507
|
this.removeFromStorage();
|
|
@@ -463,208 +517,123 @@ var AuthModule = class {
|
|
|
463
517
|
};
|
|
464
518
|
|
|
465
519
|
// src/modules/entities.ts
|
|
520
|
+
import {
|
|
521
|
+
createEntitiesModule
|
|
522
|
+
} from "@mitralab.io/sdk-core";
|
|
466
523
|
var EntitiesModule = class _EntitiesModule {
|
|
467
|
-
httpClient;
|
|
468
|
-
dataSourceId;
|
|
469
|
-
tableProxies = /* @__PURE__ */ new Map();
|
|
470
524
|
constructor(httpClient, dataSourceId) {
|
|
471
525
|
this.httpClient = httpClient;
|
|
472
|
-
|
|
526
|
+
void dataSourceId;
|
|
527
|
+
this.core = createEntitiesModule(httpClient, coreErrors);
|
|
473
528
|
}
|
|
529
|
+
core;
|
|
474
530
|
static createProxy(httpClient, dataSourceId) {
|
|
475
531
|
const instance = new _EntitiesModule(httpClient, dataSourceId);
|
|
476
532
|
return new Proxy(instance, {
|
|
477
|
-
get
|
|
478
|
-
if (
|
|
479
|
-
return target
|
|
533
|
+
get(target, property, receiver) {
|
|
534
|
+
if (typeof property !== "string" || property in target) {
|
|
535
|
+
return Reflect.get(target, property, receiver);
|
|
480
536
|
}
|
|
481
|
-
return target.getTable(
|
|
537
|
+
return target.getTable(property);
|
|
482
538
|
}
|
|
483
539
|
});
|
|
484
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Preserved for Platform SDK 1.x compatibility.
|
|
543
|
+
* Records now resolve the app from authenticated context instead of a data source path.
|
|
544
|
+
*/
|
|
485
545
|
setDataSourceId(dataSourceId) {
|
|
486
|
-
|
|
487
|
-
this.
|
|
546
|
+
void dataSourceId;
|
|
547
|
+
this.core = createEntitiesModule(this.httpClient, coreErrors);
|
|
488
548
|
}
|
|
489
549
|
getTable(tableName) {
|
|
490
|
-
|
|
491
|
-
this.tableProxies.set(tableName, this.createTableAccessor(tableName));
|
|
492
|
-
}
|
|
493
|
-
return this.tableProxies.get(tableName);
|
|
494
|
-
}
|
|
495
|
-
createTableAccessor(tableName) {
|
|
496
|
-
const basePath = `/api/v1/data-sources/${this.dataSourceId}/tables/${tableName}/records`;
|
|
497
|
-
return {
|
|
498
|
-
list: async (sortOrOptions, limit, skip, fields) => {
|
|
499
|
-
let params;
|
|
500
|
-
if (typeof sortOrOptions === "string" || sortOrOptions === void 0) {
|
|
501
|
-
params = {
|
|
502
|
-
sort: sortOrOptions,
|
|
503
|
-
limit,
|
|
504
|
-
skip,
|
|
505
|
-
fields: fields?.join(",")
|
|
506
|
-
};
|
|
507
|
-
} else {
|
|
508
|
-
params = {
|
|
509
|
-
sort: sortOrOptions.sort,
|
|
510
|
-
limit: sortOrOptions.limit,
|
|
511
|
-
skip: sortOrOptions.skip,
|
|
512
|
-
fields: sortOrOptions.fields?.join(",")
|
|
513
|
-
};
|
|
514
|
-
}
|
|
515
|
-
const response = await this.httpClient.get(basePath, params);
|
|
516
|
-
return response.data;
|
|
517
|
-
},
|
|
518
|
-
filter: async (query, sort, limit, skip, fields) => {
|
|
519
|
-
const params = {
|
|
520
|
-
q: JSON.stringify(query),
|
|
521
|
-
sort,
|
|
522
|
-
limit,
|
|
523
|
-
skip,
|
|
524
|
-
fields: fields?.join(",")
|
|
525
|
-
};
|
|
526
|
-
const response = await this.httpClient.get(basePath, params);
|
|
527
|
-
return response.data;
|
|
528
|
-
},
|
|
529
|
-
get: async (id) => {
|
|
530
|
-
return this.httpClient.get(`${basePath}/${id}`);
|
|
531
|
-
},
|
|
532
|
-
create: async (data) => {
|
|
533
|
-
return this.httpClient.post(basePath, data);
|
|
534
|
-
},
|
|
535
|
-
update: async (id, data) => {
|
|
536
|
-
return this.httpClient.put(`${basePath}/${id}`, data);
|
|
537
|
-
},
|
|
538
|
-
delete: async (id) => {
|
|
539
|
-
return this.httpClient.delete(`${basePath}/${id}`);
|
|
540
|
-
},
|
|
541
|
-
deleteMany: async (query) => {
|
|
542
|
-
return this.httpClient.delete(basePath, {
|
|
543
|
-
q: JSON.stringify(query)
|
|
544
|
-
});
|
|
545
|
-
},
|
|
546
|
-
bulkCreate: async (data) => {
|
|
547
|
-
return this.httpClient.post(`${basePath}/bulk`, data);
|
|
548
|
-
}
|
|
549
|
-
};
|
|
550
|
+
return this.core.getTable(tableName);
|
|
550
551
|
}
|
|
551
552
|
};
|
|
552
553
|
|
|
553
554
|
// src/modules/functions.ts
|
|
555
|
+
import {
|
|
556
|
+
createFunctionsModule
|
|
557
|
+
} from "@mitralab.io/sdk-core";
|
|
554
558
|
var FunctionsModule = class {
|
|
555
|
-
|
|
559
|
+
core;
|
|
556
560
|
constructor(httpClient) {
|
|
557
|
-
this.
|
|
561
|
+
this.core = createFunctionsModule(httpClient, { emptyInput: "omit-body" }, coreErrors);
|
|
558
562
|
}
|
|
559
563
|
/**
|
|
560
|
-
* Executes a
|
|
561
|
-
*
|
|
562
|
-
* Triggers the function's current published version with the provided input.
|
|
563
|
-
*
|
|
564
|
-
* @param functionId - UUID of the function to execute.
|
|
565
|
-
* @param input - Input data to pass to the function.
|
|
566
|
-
* @returns The execution result with status, output, and metadata.
|
|
567
|
-
* @throws {MitraApiError} On function not found (404) or unauthorized (401).
|
|
568
|
-
*
|
|
569
|
-
* @example
|
|
570
|
-
* ```typescript
|
|
571
|
-
* const execution = await mitra.functions.execute('fn-id', { key: 'value' });
|
|
572
|
-
* console.log(execution.status, execution.output);
|
|
573
|
-
* ```
|
|
564
|
+
* Executes a Function using the Platform SDK 1.x server-default invocation semantics.
|
|
565
|
+
* The runtime SDK uses an explicit invocation header instead.
|
|
574
566
|
*/
|
|
575
567
|
async execute(functionId, input) {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
568
|
+
const execution = await this.core.execute(functionId, input);
|
|
569
|
+
if (execution.input === null) {
|
|
570
|
+
throw coreErrors.invalidResponse(
|
|
571
|
+
"Function execution response has an invalid input field"
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
return { ...execution, input: execution.input };
|
|
580
575
|
}
|
|
581
576
|
};
|
|
582
577
|
|
|
583
578
|
// src/modules/integration.ts
|
|
579
|
+
import {
|
|
580
|
+
createIntegrationModule
|
|
581
|
+
} from "@mitralab.io/sdk-core";
|
|
584
582
|
var IntegrationModule = class {
|
|
585
|
-
|
|
583
|
+
core;
|
|
586
584
|
constructor(httpClient) {
|
|
587
|
-
this.
|
|
585
|
+
this.core = createIntegrationModule(httpClient, coreErrors);
|
|
588
586
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
*
|
|
592
|
-
* The resource's endpoint, method, and body are resolved server-side
|
|
593
|
-
* using the provided parameters. Only declared parameters can be passed.
|
|
594
|
-
*
|
|
595
|
-
* @param resourceId - UUID of the integration resource.
|
|
596
|
-
* @param params - Named parameters declared in the resource's params schema.
|
|
597
|
-
* @returns Proxy result with status, headers, body, and execution metadata.
|
|
598
|
-
* @throws {MitraApiError} On resource not found (404) or external API failure.
|
|
599
|
-
*
|
|
600
|
-
* @example
|
|
601
|
-
* ```typescript
|
|
602
|
-
* const result = await mitra.integration.executeResource('resource-id', {
|
|
603
|
-
* descricao: 'Notebook',
|
|
604
|
-
* limit: 10,
|
|
605
|
-
* });
|
|
606
|
-
* console.log(result.body);
|
|
607
|
-
* ```
|
|
608
|
-
*/
|
|
609
|
-
async executeResource(resourceId, params) {
|
|
610
|
-
return this.httpClient.post(
|
|
611
|
-
`/api/v1/proxy/resources/${resourceId}/execute`,
|
|
612
|
-
{ params }
|
|
613
|
-
);
|
|
587
|
+
executeResource(resourceId, params) {
|
|
588
|
+
return this.core.executeResource(resourceId, params);
|
|
614
589
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
*
|
|
618
|
-
* The Mitra server handles authentication and injects credentials automatically.
|
|
619
|
-
* Note: integrations configured with RESOURCE_ONLY mode will block direct proxy access.
|
|
620
|
-
*
|
|
621
|
-
* @param configId - UUID of the integration config.
|
|
622
|
-
* @param request - The HTTP request to proxy (method, endpoint, body, etc.).
|
|
623
|
-
* @returns Proxy result with status, headers, body, and execution metadata.
|
|
624
|
-
* @throws {MitraApiError} On config not found (404) or external API failure.
|
|
625
|
-
*/
|
|
626
|
-
async execute(configId, request) {
|
|
627
|
-
return this.httpClient.post(
|
|
628
|
-
`/api/v1/proxy/template-configs/${configId}/execute`,
|
|
629
|
-
{ ...request, source: "SDK" }
|
|
630
|
-
);
|
|
590
|
+
execute(configId, request) {
|
|
591
|
+
return this.core.execute(configId, request);
|
|
631
592
|
}
|
|
632
593
|
};
|
|
633
594
|
|
|
634
595
|
// src/modules/queries.ts
|
|
596
|
+
import {
|
|
597
|
+
createQueriesModule
|
|
598
|
+
} from "@mitralab.io/sdk-core";
|
|
635
599
|
var QueriesModule = class {
|
|
636
|
-
httpClient;
|
|
637
600
|
dataSourceId = "";
|
|
601
|
+
core;
|
|
638
602
|
constructor(httpClient) {
|
|
639
|
-
this.
|
|
603
|
+
this.core = createQueriesModule(httpClient, () => this.dataSourceId, coreErrors);
|
|
640
604
|
}
|
|
641
|
-
/**
|
|
605
|
+
/** Called by `client.init()` to set the app's resolved data source. */
|
|
642
606
|
setDataSourceId(dataSourceId) {
|
|
643
607
|
this.dataSourceId = dataSourceId;
|
|
644
608
|
}
|
|
645
|
-
/**
|
|
646
|
-
* Executes a named query.
|
|
647
|
-
*
|
|
648
|
-
* @param id - UUID of the custom query.
|
|
649
|
-
* @param parameters - Named parameters for the prepared statement.
|
|
650
|
-
* @returns Query result with rows and affected row count.
|
|
651
|
-
* @throws {MitraApiError} On query not found (404).
|
|
652
|
-
*
|
|
653
|
-
* @example
|
|
654
|
-
* ```typescript
|
|
655
|
-
* const result = await mitra.queries.execute('query-id', { status: 'active' });
|
|
656
|
-
* console.log(`Found ${result.rows.length} rows`);
|
|
657
|
-
* ```
|
|
658
|
-
*/
|
|
659
609
|
async execute(id, parameters) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
{ datasourceId: this.dataSourceId, parameters }
|
|
663
|
-
);
|
|
610
|
+
const result = await this.core.execute(id, parameters);
|
|
611
|
+
return { ...result, affectedRows: result.affectedRows ?? null };
|
|
664
612
|
}
|
|
665
613
|
};
|
|
666
614
|
|
|
667
615
|
// src/client.ts
|
|
616
|
+
function expectAppInfoResponse(value) {
|
|
617
|
+
const response = expectObject(
|
|
618
|
+
value,
|
|
619
|
+
"App info response",
|
|
620
|
+
coreErrors
|
|
621
|
+
);
|
|
622
|
+
if (typeof response.dataSourceId !== "string" || !response.dataSourceId.trim()) {
|
|
623
|
+
throw coreErrors.invalidResponse(
|
|
624
|
+
"App info response has an invalid dataSourceId field"
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
if (typeof response.allowSignup !== "boolean") {
|
|
628
|
+
throw coreErrors.invalidResponse(
|
|
629
|
+
"App info response has an invalid allowSignup field"
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
return {
|
|
633
|
+
dataSourceId: response.dataSourceId,
|
|
634
|
+
allowSignup: response.allowSignup
|
|
635
|
+
};
|
|
636
|
+
}
|
|
668
637
|
function createClient(config) {
|
|
669
638
|
const { appId, apiUrl, onError } = config;
|
|
670
639
|
const iamUrl = `${apiUrl}/iam`;
|
|
@@ -708,8 +677,10 @@ function createClient(config) {
|
|
|
708
677
|
baseUrl: codeStudioUrl,
|
|
709
678
|
getToken: () => null
|
|
710
679
|
});
|
|
711
|
-
const appInfo =
|
|
712
|
-
|
|
680
|
+
const appInfo = expectAppInfoResponse(
|
|
681
|
+
await publicClient.get(
|
|
682
|
+
`/api/v1/apps/${encodePathSegment(appId, "appId", coreErrors)}/info`
|
|
683
|
+
)
|
|
713
684
|
);
|
|
714
685
|
entitiesModule.setDataSourceId(appInfo.dataSourceId);
|
|
715
686
|
queriesModule.setDataSourceId(appInfo.dataSourceId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mitralab.io/platform-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "JavaScript/TypeScript SDK for building apps on the Mitra Platform",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -19,9 +19,12 @@
|
|
|
19
19
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
20
20
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
21
21
|
"lint": "eslint src --ext .ts",
|
|
22
|
-
"
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"test": "vitest run --coverage",
|
|
23
24
|
"test:watch": "vitest",
|
|
24
|
-
"
|
|
25
|
+
"smoke:package": "node scripts/smoke-package.mjs",
|
|
26
|
+
"check": "npm run lint && npm run typecheck && npm test && npm run build && npm run smoke:package",
|
|
27
|
+
"prepublishOnly": "npm run check"
|
|
25
28
|
},
|
|
26
29
|
"keywords": [
|
|
27
30
|
"mitra",
|
|
@@ -42,18 +45,26 @@
|
|
|
42
45
|
"bugs": {
|
|
43
46
|
"url": "https://github.com/mitralab-dev/mitra-platform-sdk/issues"
|
|
44
47
|
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@mitralab.io/sdk-core": "^0.1.0"
|
|
50
|
+
},
|
|
45
51
|
"devDependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
+
"@eslint/js": "^9.39.1",
|
|
53
|
+
"@types/node": "^22.15.0",
|
|
54
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
55
|
+
"eslint": "^9.39.1",
|
|
56
|
+
"globals": "^16.5.0",
|
|
57
|
+
"tsup": "^8.5.1",
|
|
58
|
+
"typescript": "~5.9.3",
|
|
59
|
+
"typescript-eslint": "~8.55.0",
|
|
60
|
+
"vite": "~6.4.3",
|
|
61
|
+
"vitest": "^3.2.4"
|
|
52
62
|
},
|
|
53
63
|
"engines": {
|
|
54
64
|
"node": ">=18.0.0"
|
|
55
65
|
},
|
|
56
66
|
"overrides": {
|
|
57
|
-
"rollup": "^4.59.0"
|
|
67
|
+
"rollup": "^4.59.0",
|
|
68
|
+
"test-exclude": "7.0.1"
|
|
58
69
|
}
|
|
59
70
|
}
|