@granular-software/sdk 0.4.6 → 0.4.7
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 +18 -12
- package/dist/cli/index.js +10 -9
- package/dist/index.d.mts +36 -11
- package/dist/index.d.ts +36 -11
- package/dist/index.js +87 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,16 +55,16 @@ import { Granular, type ManifestContent } from '@granular-software/sdk';
|
|
|
55
55
|
|
|
56
56
|
const granular = new Granular({ apiKey: process.env.GRANULAR_API_KEY });
|
|
57
57
|
|
|
58
|
-
// 1.
|
|
59
|
-
const
|
|
58
|
+
// 1. Connect to sandbox for one of your app users
|
|
59
|
+
const env = await granular.connect({
|
|
60
|
+
sandbox: 'my-sandbox',
|
|
60
61
|
userId: 'user_123',
|
|
61
62
|
permissions: ['agent'],
|
|
63
|
+
name: 'Jane Doe', // optional
|
|
64
|
+
email: 'jane@example.com', // optional
|
|
62
65
|
});
|
|
63
66
|
|
|
64
|
-
// 2.
|
|
65
|
-
const env = await granular.connect({ sandbox: 'my-sandbox', user });
|
|
66
|
-
|
|
67
|
-
// 3. Define your domain ontology
|
|
67
|
+
// 2. Define your domain ontology
|
|
68
68
|
const manifest: ManifestContent = {
|
|
69
69
|
schemaVersion: 2,
|
|
70
70
|
name: 'my-app',
|
|
@@ -105,7 +105,7 @@ const manifest: ManifestContent = {
|
|
|
105
105
|
|
|
106
106
|
await env.applyManifest(manifest);
|
|
107
107
|
|
|
108
|
-
//
|
|
108
|
+
// 3. Record object instances
|
|
109
109
|
await env.recordObject({
|
|
110
110
|
className: 'customer',
|
|
111
111
|
id: 'cust_42',
|
|
@@ -113,7 +113,7 @@ await env.recordObject({
|
|
|
113
113
|
fields: { name: 'Acme Corp', email: 'billing@acme.com', tier: 'enterprise' },
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
-
//
|
|
116
|
+
// 4. Register live effect handlers for effects already declared in the build manifest
|
|
117
117
|
await granular.registerEffects(env.sandboxId, [
|
|
118
118
|
{
|
|
119
119
|
name: 'get_billing_summary',
|
|
@@ -172,11 +172,11 @@ Effects must be declared ahead of time in the sandbox build manifest with `withE
|
|
|
172
172
|
## Core Flow
|
|
173
173
|
|
|
174
174
|
```
|
|
175
|
-
declare effects in build manifest → connect() → recordObject() → registerEffects() → submitJob()
|
|
175
|
+
declare effects in build manifest → connect({ userId }) → recordObject() → registerEffects() → submitJob()
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
1. **`
|
|
179
|
-
2. **`
|
|
178
|
+
1. **`connect()`** — Connect to a sandbox for a given `userId`, returning an `Environment`
|
|
179
|
+
2. **`recordUser()`** — Optional explicit user upsert when you want the returned `granularId`
|
|
180
180
|
3. **`applyManifest()`** — Define your domain ontology (classes, properties, relationships)
|
|
181
181
|
4. **`recordObject()`** — Create/update instances of your classes with fields and relationships
|
|
182
182
|
5. **`granular.registerEffects()`** — Register sandbox-scoped live handlers for effects declared in the build manifest
|
|
@@ -232,9 +232,15 @@ await env.applyManifest(manifest);
|
|
|
232
232
|
|
|
233
233
|
## Recording Object Instances
|
|
234
234
|
|
|
235
|
-
After defining the ontology, populate it with data:
|
|
235
|
+
After defining the ontology, connect as a user and populate it with data:
|
|
236
236
|
|
|
237
237
|
```typescript
|
|
238
|
+
const env = await granular.connect({
|
|
239
|
+
sandbox: 'library-app',
|
|
240
|
+
userId: 'user_123',
|
|
241
|
+
permissions: ['agent'],
|
|
242
|
+
});
|
|
243
|
+
|
|
238
244
|
const tolkien = await env.recordObject({
|
|
239
245
|
className: 'author',
|
|
240
246
|
id: 'tolkien', // Real-world ID (unique per class)
|
package/dist/cli/index.js
CHANGED
|
@@ -8622,17 +8622,12 @@ const granular = new Granular({`);
|
|
|
8622
8622
|
lines.push(` ...(process.env.GRANULAR_TOKEN ? { token: process.env.GRANULAR_TOKEN } : { apiKey: process.env.GRANULAR_API_KEY! }),`);
|
|
8623
8623
|
lines.push(`});`);
|
|
8624
8624
|
lines.push(`
|
|
8625
|
-
// 1.
|
|
8626
|
-
lines.push(`const user = await granular.recordUser({`);
|
|
8627
|
-
lines.push(` userId: 'user_123', // Your internal ID`);
|
|
8628
|
-
lines.push(` email: 'user@example.com',`);
|
|
8629
|
-
lines.push(` permissions: ['default'], // Permission profile`);
|
|
8630
|
-
lines.push(`});`);
|
|
8631
|
-
lines.push(`
|
|
8632
|
-
// 2. Connect to the sandbox`);
|
|
8625
|
+
// 1. Connect to the sandbox for one of your app users`);
|
|
8633
8626
|
lines.push(`const env = await granular.connect({`);
|
|
8634
8627
|
lines.push(` sandbox: '${sandboxId}',`);
|
|
8635
|
-
lines.push(` user
|
|
8628
|
+
lines.push(` userId: 'user_123', // Your app's user ID`);
|
|
8629
|
+
lines.push(` email: 'user@example.com', // optional`);
|
|
8630
|
+
lines.push(` permissions: ['default'], // Permission profile`);
|
|
8636
8631
|
lines.push(`});`);
|
|
8637
8632
|
lines.push(`
|
|
8638
8633
|
console.log('Connected to:', env.environmentId);`);
|
|
@@ -8643,6 +8638,12 @@ console.log('Connected to:', env.environmentId);`);
|
|
|
8643
8638
|
if (classes.length > 0) {
|
|
8644
8639
|
lines.push(`
|
|
8645
8640
|
\`\`\`typescript`);
|
|
8641
|
+
lines.push(`const env = await granular.connect({`);
|
|
8642
|
+
lines.push(` sandbox: '${sandboxId}',`);
|
|
8643
|
+
lines.push(` userId: 'user_123',`);
|
|
8644
|
+
lines.push(` permissions: ['default'],`);
|
|
8645
|
+
lines.push(`});`);
|
|
8646
|
+
lines.push(``);
|
|
8646
8647
|
for (const cls of classes) {
|
|
8647
8648
|
const exampleFields = {};
|
|
8648
8649
|
for (const [k, v] of Object.entries(cls.fields)) {
|
package/dist/index.d.mts
CHANGED
|
@@ -40,9 +40,13 @@ type GranularAuth = string;
|
|
|
40
40
|
* A user/subject object returned from recordUser()
|
|
41
41
|
*/
|
|
42
42
|
interface User {
|
|
43
|
-
/** Internal
|
|
43
|
+
/** Internal Granular user identifier */
|
|
44
|
+
granularId: string;
|
|
45
|
+
/** External user identifier from your app */
|
|
46
|
+
userId: string;
|
|
47
|
+
/** @deprecated Use `granularId` instead */
|
|
44
48
|
subjectId: string;
|
|
45
|
-
/**
|
|
49
|
+
/** @deprecated Use `userId` instead */
|
|
46
50
|
identityId: string;
|
|
47
51
|
/** User's display name */
|
|
48
52
|
name?: string;
|
|
@@ -68,6 +72,10 @@ interface RecordUserOptions {
|
|
|
68
72
|
* Subject as returned from the API
|
|
69
73
|
*/
|
|
70
74
|
interface Subject {
|
|
75
|
+
/** Internal Granular user identifier */
|
|
76
|
+
granularId: string;
|
|
77
|
+
/** External user identifier from your app */
|
|
78
|
+
userId: string;
|
|
71
79
|
subjectId: string;
|
|
72
80
|
tenantId: string;
|
|
73
81
|
identityId: string;
|
|
@@ -83,8 +91,24 @@ interface Subject {
|
|
|
83
91
|
interface ConnectOptions {
|
|
84
92
|
/** The sandbox name or ID to connect to */
|
|
85
93
|
sandbox: string;
|
|
86
|
-
/**
|
|
87
|
-
|
|
94
|
+
/**
|
|
95
|
+
* External user identifier from your app. This is the primary input for
|
|
96
|
+
* connecting to a sandbox and the only required user field in the common case.
|
|
97
|
+
*/
|
|
98
|
+
userId?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Internal Granular user identifier. Optional fallback when you only know
|
|
101
|
+
* the Granular-side ID for an existing subject.
|
|
102
|
+
*/
|
|
103
|
+
granularId?: string;
|
|
104
|
+
/** Optional display name used when upserting the user */
|
|
105
|
+
name?: string;
|
|
106
|
+
/** Optional email used when upserting the user */
|
|
107
|
+
email?: string;
|
|
108
|
+
/** Permission profile IDs or names to ensure before connecting */
|
|
109
|
+
permissions?: string[];
|
|
110
|
+
/** Backwards-compatible user object returned from recordUser() */
|
|
111
|
+
user?: User;
|
|
88
112
|
/** Optional stable client ID. Defaults to `client_${Date.now()}`. Use a fixed
|
|
89
113
|
* value for long-lived effect hosts so tool catalogs don't accumulate. */
|
|
90
114
|
clientId?: string;
|
|
@@ -274,6 +298,8 @@ interface EffectHandlerContext {
|
|
|
274
298
|
principalId?: string;
|
|
275
299
|
permissionProfileId?: string;
|
|
276
300
|
user: {
|
|
301
|
+
granularId?: string;
|
|
302
|
+
userId?: string;
|
|
277
303
|
subjectId: string;
|
|
278
304
|
identityId?: string;
|
|
279
305
|
principalId?: string;
|
|
@@ -1017,6 +1043,8 @@ declare class Environment extends Session {
|
|
|
1017
1043
|
get sandboxId(): string;
|
|
1018
1044
|
/** The subject ID */
|
|
1019
1045
|
get subjectId(): string;
|
|
1046
|
+
/** Internal Granular user identifier for this environment */
|
|
1047
|
+
get granularId(): string;
|
|
1020
1048
|
/** The permission profile ID */
|
|
1021
1049
|
get permissionProfileId(): string;
|
|
1022
1050
|
/** The GraphQL API endpoint URL */
|
|
@@ -1330,7 +1358,7 @@ declare class Granular {
|
|
|
1330
1358
|
* Records/upserts a user and prepares them for sandbox connections
|
|
1331
1359
|
*
|
|
1332
1360
|
* @param options - User options
|
|
1333
|
-
* @returns The user
|
|
1361
|
+
* @returns The recorded user with both `userId` and `granularId`
|
|
1334
1362
|
*
|
|
1335
1363
|
* @example
|
|
1336
1364
|
* ```typescript
|
|
@@ -1342,6 +1370,7 @@ declare class Granular {
|
|
|
1342
1370
|
* ```
|
|
1343
1371
|
*/
|
|
1344
1372
|
recordUser(options: RecordUserOptions): Promise<User>;
|
|
1373
|
+
private resolveConnectUser;
|
|
1345
1374
|
/**
|
|
1346
1375
|
* Connect to a sandbox and establish a real-time environment session.
|
|
1347
1376
|
*
|
|
@@ -1354,14 +1383,10 @@ declare class Granular {
|
|
|
1354
1383
|
*
|
|
1355
1384
|
* @example
|
|
1356
1385
|
* ```typescript
|
|
1357
|
-
* const user = await granular.recordUser({
|
|
1358
|
-
* userId: 'user_123',
|
|
1359
|
-
* permissions: ['agent'],
|
|
1360
|
-
* });
|
|
1361
|
-
*
|
|
1362
1386
|
* const environment = await granular.connect({
|
|
1363
1387
|
* sandbox: 'my-sandbox',
|
|
1364
|
-
*
|
|
1388
|
+
* userId: 'user_123',
|
|
1389
|
+
* permissions: ['agent'],
|
|
1365
1390
|
* });
|
|
1366
1391
|
*
|
|
1367
1392
|
* await granular.registerEffect('my-sandbox', {
|
package/dist/index.d.ts
CHANGED
|
@@ -40,9 +40,13 @@ type GranularAuth = string;
|
|
|
40
40
|
* A user/subject object returned from recordUser()
|
|
41
41
|
*/
|
|
42
42
|
interface User {
|
|
43
|
-
/** Internal
|
|
43
|
+
/** Internal Granular user identifier */
|
|
44
|
+
granularId: string;
|
|
45
|
+
/** External user identifier from your app */
|
|
46
|
+
userId: string;
|
|
47
|
+
/** @deprecated Use `granularId` instead */
|
|
44
48
|
subjectId: string;
|
|
45
|
-
/**
|
|
49
|
+
/** @deprecated Use `userId` instead */
|
|
46
50
|
identityId: string;
|
|
47
51
|
/** User's display name */
|
|
48
52
|
name?: string;
|
|
@@ -68,6 +72,10 @@ interface RecordUserOptions {
|
|
|
68
72
|
* Subject as returned from the API
|
|
69
73
|
*/
|
|
70
74
|
interface Subject {
|
|
75
|
+
/** Internal Granular user identifier */
|
|
76
|
+
granularId: string;
|
|
77
|
+
/** External user identifier from your app */
|
|
78
|
+
userId: string;
|
|
71
79
|
subjectId: string;
|
|
72
80
|
tenantId: string;
|
|
73
81
|
identityId: string;
|
|
@@ -83,8 +91,24 @@ interface Subject {
|
|
|
83
91
|
interface ConnectOptions {
|
|
84
92
|
/** The sandbox name or ID to connect to */
|
|
85
93
|
sandbox: string;
|
|
86
|
-
/**
|
|
87
|
-
|
|
94
|
+
/**
|
|
95
|
+
* External user identifier from your app. This is the primary input for
|
|
96
|
+
* connecting to a sandbox and the only required user field in the common case.
|
|
97
|
+
*/
|
|
98
|
+
userId?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Internal Granular user identifier. Optional fallback when you only know
|
|
101
|
+
* the Granular-side ID for an existing subject.
|
|
102
|
+
*/
|
|
103
|
+
granularId?: string;
|
|
104
|
+
/** Optional display name used when upserting the user */
|
|
105
|
+
name?: string;
|
|
106
|
+
/** Optional email used when upserting the user */
|
|
107
|
+
email?: string;
|
|
108
|
+
/** Permission profile IDs or names to ensure before connecting */
|
|
109
|
+
permissions?: string[];
|
|
110
|
+
/** Backwards-compatible user object returned from recordUser() */
|
|
111
|
+
user?: User;
|
|
88
112
|
/** Optional stable client ID. Defaults to `client_${Date.now()}`. Use a fixed
|
|
89
113
|
* value for long-lived effect hosts so tool catalogs don't accumulate. */
|
|
90
114
|
clientId?: string;
|
|
@@ -274,6 +298,8 @@ interface EffectHandlerContext {
|
|
|
274
298
|
principalId?: string;
|
|
275
299
|
permissionProfileId?: string;
|
|
276
300
|
user: {
|
|
301
|
+
granularId?: string;
|
|
302
|
+
userId?: string;
|
|
277
303
|
subjectId: string;
|
|
278
304
|
identityId?: string;
|
|
279
305
|
principalId?: string;
|
|
@@ -1017,6 +1043,8 @@ declare class Environment extends Session {
|
|
|
1017
1043
|
get sandboxId(): string;
|
|
1018
1044
|
/** The subject ID */
|
|
1019
1045
|
get subjectId(): string;
|
|
1046
|
+
/** Internal Granular user identifier for this environment */
|
|
1047
|
+
get granularId(): string;
|
|
1020
1048
|
/** The permission profile ID */
|
|
1021
1049
|
get permissionProfileId(): string;
|
|
1022
1050
|
/** The GraphQL API endpoint URL */
|
|
@@ -1330,7 +1358,7 @@ declare class Granular {
|
|
|
1330
1358
|
* Records/upserts a user and prepares them for sandbox connections
|
|
1331
1359
|
*
|
|
1332
1360
|
* @param options - User options
|
|
1333
|
-
* @returns The user
|
|
1361
|
+
* @returns The recorded user with both `userId` and `granularId`
|
|
1334
1362
|
*
|
|
1335
1363
|
* @example
|
|
1336
1364
|
* ```typescript
|
|
@@ -1342,6 +1370,7 @@ declare class Granular {
|
|
|
1342
1370
|
* ```
|
|
1343
1371
|
*/
|
|
1344
1372
|
recordUser(options: RecordUserOptions): Promise<User>;
|
|
1373
|
+
private resolveConnectUser;
|
|
1345
1374
|
/**
|
|
1346
1375
|
* Connect to a sandbox and establish a real-time environment session.
|
|
1347
1376
|
*
|
|
@@ -1354,14 +1383,10 @@ declare class Granular {
|
|
|
1354
1383
|
*
|
|
1355
1384
|
* @example
|
|
1356
1385
|
* ```typescript
|
|
1357
|
-
* const user = await granular.recordUser({
|
|
1358
|
-
* userId: 'user_123',
|
|
1359
|
-
* permissions: ['agent'],
|
|
1360
|
-
* });
|
|
1361
|
-
*
|
|
1362
1386
|
* const environment = await granular.connect({
|
|
1363
1387
|
* sandbox: 'my-sandbox',
|
|
1364
|
-
*
|
|
1388
|
+
* userId: 'user_123',
|
|
1389
|
+
* permissions: ['agent'],
|
|
1365
1390
|
* });
|
|
1366
1391
|
*
|
|
1367
1392
|
* await granular.registerEffect('my-sandbox', {
|
package/dist/index.js
CHANGED
|
@@ -4503,6 +4503,8 @@ var Session = class {
|
|
|
4503
4503
|
environmentId: "",
|
|
4504
4504
|
sessionId: "",
|
|
4505
4505
|
user: {
|
|
4506
|
+
granularId: "",
|
|
4507
|
+
userId: "",
|
|
4506
4508
|
subjectId: ""
|
|
4507
4509
|
}
|
|
4508
4510
|
};
|
|
@@ -5197,6 +5199,29 @@ function normalizeHeapSnapshot(raw) {
|
|
|
5197
5199
|
updatedAt: typeof heap.updatedAt === "number" ? heap.updatedAt : Date.now()
|
|
5198
5200
|
};
|
|
5199
5201
|
}
|
|
5202
|
+
function normalizeSubject(subject) {
|
|
5203
|
+
const granularId = subject.granularId || subject.subjectId;
|
|
5204
|
+
const userId = subject.userId || subject.identityId || granularId;
|
|
5205
|
+
return {
|
|
5206
|
+
...subject,
|
|
5207
|
+
granularId,
|
|
5208
|
+
userId,
|
|
5209
|
+
subjectId: granularId,
|
|
5210
|
+
identityId: subject.identityId || userId
|
|
5211
|
+
};
|
|
5212
|
+
}
|
|
5213
|
+
function normalizeUser(user) {
|
|
5214
|
+
const granularId = user.granularId || user.subjectId;
|
|
5215
|
+
const userId = user.userId || user.identityId || granularId;
|
|
5216
|
+
return {
|
|
5217
|
+
...user,
|
|
5218
|
+
granularId,
|
|
5219
|
+
userId,
|
|
5220
|
+
subjectId: granularId,
|
|
5221
|
+
identityId: user.identityId || userId,
|
|
5222
|
+
permissions: Array.isArray(user.permissions) ? user.permissions : []
|
|
5223
|
+
};
|
|
5224
|
+
}
|
|
5200
5225
|
var Environment = class _Environment extends Session {
|
|
5201
5226
|
envData;
|
|
5202
5227
|
_apiKey;
|
|
@@ -5219,6 +5244,10 @@ var Environment = class _Environment extends Session {
|
|
|
5219
5244
|
get subjectId() {
|
|
5220
5245
|
return this.envData.subjectId;
|
|
5221
5246
|
}
|
|
5247
|
+
/** Internal Granular user identifier for this environment */
|
|
5248
|
+
get granularId() {
|
|
5249
|
+
return this.envData.subjectId;
|
|
5250
|
+
}
|
|
5222
5251
|
/** The permission profile ID */
|
|
5223
5252
|
get permissionProfileId() {
|
|
5224
5253
|
return this.envData.permissionProfileId;
|
|
@@ -6016,7 +6045,7 @@ var Granular = class {
|
|
|
6016
6045
|
* Records/upserts a user and prepares them for sandbox connections
|
|
6017
6046
|
*
|
|
6018
6047
|
* @param options - User options
|
|
6019
|
-
* @returns The user
|
|
6048
|
+
* @returns The recorded user with both `userId` and `granularId`
|
|
6020
6049
|
*
|
|
6021
6050
|
* @example
|
|
6022
6051
|
* ```typescript
|
|
@@ -6028,21 +6057,61 @@ var Granular = class {
|
|
|
6028
6057
|
* ```
|
|
6029
6058
|
*/
|
|
6030
6059
|
async recordUser(options) {
|
|
6031
|
-
const subject = await this.request("/control/subjects", {
|
|
6060
|
+
const subject = normalizeSubject(await this.request("/control/subjects", {
|
|
6032
6061
|
method: "POST",
|
|
6033
6062
|
body: JSON.stringify({
|
|
6034
6063
|
identityId: options.userId,
|
|
6035
6064
|
name: options.name,
|
|
6036
6065
|
email: options.email
|
|
6037
6066
|
})
|
|
6038
|
-
});
|
|
6039
|
-
return {
|
|
6067
|
+
}));
|
|
6068
|
+
return normalizeUser({
|
|
6069
|
+
granularId: subject.granularId,
|
|
6070
|
+
userId: options.userId,
|
|
6040
6071
|
subjectId: subject.subjectId,
|
|
6041
|
-
identityId:
|
|
6042
|
-
name: options.name,
|
|
6043
|
-
email: options.email,
|
|
6072
|
+
identityId: subject.identityId,
|
|
6073
|
+
name: options.name || subject.name || void 0,
|
|
6074
|
+
email: options.email || subject.email || void 0,
|
|
6044
6075
|
permissions: options.permissions || []
|
|
6045
|
-
};
|
|
6076
|
+
});
|
|
6077
|
+
}
|
|
6078
|
+
async resolveConnectUser(options) {
|
|
6079
|
+
if (options.user) {
|
|
6080
|
+
const user = normalizeUser(options.user);
|
|
6081
|
+
return {
|
|
6082
|
+
granularId: user.granularId,
|
|
6083
|
+
userId: user.userId,
|
|
6084
|
+
name: options.name || user.name,
|
|
6085
|
+
email: options.email || user.email,
|
|
6086
|
+
permissions: options.permissions || user.permissions
|
|
6087
|
+
};
|
|
6088
|
+
}
|
|
6089
|
+
if (options.userId) {
|
|
6090
|
+
const user = await this.recordUser({
|
|
6091
|
+
userId: options.userId,
|
|
6092
|
+
name: options.name,
|
|
6093
|
+
email: options.email,
|
|
6094
|
+
permissions: options.permissions
|
|
6095
|
+
});
|
|
6096
|
+
return {
|
|
6097
|
+
granularId: user.granularId,
|
|
6098
|
+
userId: user.userId,
|
|
6099
|
+
name: user.name,
|
|
6100
|
+
email: user.email,
|
|
6101
|
+
permissions: options.permissions || user.permissions
|
|
6102
|
+
};
|
|
6103
|
+
}
|
|
6104
|
+
if (options.granularId) {
|
|
6105
|
+
const subject = await this.subjects.get(options.granularId);
|
|
6106
|
+
return {
|
|
6107
|
+
granularId: subject.granularId,
|
|
6108
|
+
userId: subject.userId,
|
|
6109
|
+
name: options.name || subject.name || void 0,
|
|
6110
|
+
email: options.email || subject.email || void 0,
|
|
6111
|
+
permissions: options.permissions || []
|
|
6112
|
+
};
|
|
6113
|
+
}
|
|
6114
|
+
throw new Error("connect() requires either userId, granularId, or a user object returned by recordUser().");
|
|
6046
6115
|
}
|
|
6047
6116
|
/**
|
|
6048
6117
|
* Connect to a sandbox and establish a real-time environment session.
|
|
@@ -6056,14 +6125,10 @@ var Granular = class {
|
|
|
6056
6125
|
*
|
|
6057
6126
|
* @example
|
|
6058
6127
|
* ```typescript
|
|
6059
|
-
* const user = await granular.recordUser({
|
|
6060
|
-
* userId: 'user_123',
|
|
6061
|
-
* permissions: ['agent'],
|
|
6062
|
-
* });
|
|
6063
|
-
*
|
|
6064
6128
|
* const environment = await granular.connect({
|
|
6065
6129
|
* sandbox: 'my-sandbox',
|
|
6066
|
-
*
|
|
6130
|
+
* userId: 'user_123',
|
|
6131
|
+
* permissions: ['agent'],
|
|
6067
6132
|
* });
|
|
6068
6133
|
*
|
|
6069
6134
|
* await granular.registerEffect('my-sandbox', {
|
|
@@ -6084,13 +6149,14 @@ var Granular = class {
|
|
|
6084
6149
|
*/
|
|
6085
6150
|
async connect(options) {
|
|
6086
6151
|
const clientId = options.clientId || `client_${Date.now()}`;
|
|
6152
|
+
const user = await this.resolveConnectUser(options);
|
|
6087
6153
|
const sandbox = await this.findOrCreateSandbox(options.sandbox);
|
|
6088
|
-
for (const profileName of
|
|
6154
|
+
for (const profileName of user.permissions) {
|
|
6089
6155
|
const profileId = await this.ensurePermissionProfile(sandbox.sandboxId, profileName);
|
|
6090
|
-
await this.ensureAssignment(
|
|
6156
|
+
await this.ensureAssignment(user.granularId, sandbox.sandboxId, profileId);
|
|
6091
6157
|
}
|
|
6092
6158
|
const envData = await this.environments.create(sandbox.sandboxId, {
|
|
6093
|
-
subjectId:
|
|
6159
|
+
subjectId: user.granularId,
|
|
6094
6160
|
permissionProfileId: null
|
|
6095
6161
|
});
|
|
6096
6162
|
await this.activateEnvironment(envData.environmentId);
|
|
@@ -6523,7 +6589,7 @@ var Granular = class {
|
|
|
6523
6589
|
get subjects() {
|
|
6524
6590
|
return {
|
|
6525
6591
|
get: async (subjectId) => {
|
|
6526
|
-
return this.request(`/control/subjects/${subjectId}`);
|
|
6592
|
+
return normalizeSubject(await this.request(`/control/subjects/${subjectId}`));
|
|
6527
6593
|
},
|
|
6528
6594
|
listAssignments: async (subjectId) => {
|
|
6529
6595
|
return this.request(`/control/subjects/${subjectId}/assignments`);
|
|
@@ -6536,17 +6602,17 @@ var Granular = class {
|
|
|
6536
6602
|
get users() {
|
|
6537
6603
|
return {
|
|
6538
6604
|
create: async (data) => {
|
|
6539
|
-
return this.request("/control/subjects", {
|
|
6605
|
+
return normalizeSubject(await this.request("/control/subjects", {
|
|
6540
6606
|
method: "POST",
|
|
6541
6607
|
body: JSON.stringify({
|
|
6542
6608
|
identityId: data.id,
|
|
6543
6609
|
name: data.name,
|
|
6544
6610
|
email: data.email
|
|
6545
6611
|
})
|
|
6546
|
-
});
|
|
6612
|
+
}));
|
|
6547
6613
|
},
|
|
6548
6614
|
get: async (id) => {
|
|
6549
|
-
return this.request(`/control/subjects/${id}`);
|
|
6615
|
+
return normalizeSubject(await this.request(`/control/subjects/${id}`));
|
|
6550
6616
|
}
|
|
6551
6617
|
};
|
|
6552
6618
|
}
|