roboto-js 1.8.1 → 1.8.3
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/.last-build +1 -1
- package/dist/cjs/rbt_api.cjs +21 -10
- package/dist/cjs/rbt_object.cjs +10 -8
- package/dist/esm/rbt_api.js +18 -8
- package/dist/esm/rbt_object.js +4 -3
- package/dist/rbt_api.js +19 -8
- package/dist/rbt_object.js +5 -3
- package/examples/sharing-example.js +424 -0
- package/package.json +1 -1
- package/src/rbt_api.js +19 -4
- package/src/rbt_object.js +4 -3
package/.last-build
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2025-10-
|
|
1
|
+
2025-10-09T19:09:24.387Z
|
package/dist/cjs/rbt_api.cjs
CHANGED
|
@@ -1745,6 +1745,7 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
|
|
|
1745
1745
|
status,
|
|
1746
1746
|
message,
|
|
1747
1747
|
output,
|
|
1748
|
+
errorResponse,
|
|
1748
1749
|
_args25 = arguments;
|
|
1749
1750
|
return _regeneratorRuntime().wrap(function _callee25$(_context25) {
|
|
1750
1751
|
while (1) switch (_context25.prev = _context25.next) {
|
|
@@ -1802,18 +1803,28 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
|
|
|
1802
1803
|
case 20:
|
|
1803
1804
|
_context25.prev = 20;
|
|
1804
1805
|
_context25.t0 = _context25["catch"](3);
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
console.error('Error in runTask:', _context25.t0);
|
|
1809
|
-
}
|
|
1810
|
-
return _context25.abrupt("return", {
|
|
1806
|
+
// Standardize error format to match task response object
|
|
1807
|
+
// Support RbtError format with label and message
|
|
1808
|
+
errorResponse = {
|
|
1811
1809
|
ok: false,
|
|
1812
1810
|
jobId: null,
|
|
1813
1811
|
status: 'ERROR',
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1812
|
+
message: _context25.t0.message || _context25.t0.toString() || 'Unknown error',
|
|
1813
|
+
label: _context25.t0.label || _context25.t0.name || 'Error',
|
|
1814
|
+
output: {
|
|
1815
|
+
error: _context25.t0.message,
|
|
1816
|
+
label: _context25.t0.label,
|
|
1817
|
+
stack: _context25.t0.stack,
|
|
1818
|
+
originalError: _context25.t0
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
if (typeof onError === 'function') {
|
|
1822
|
+
onError(errorResponse);
|
|
1823
|
+
} else {
|
|
1824
|
+
console.error('Error in runTask:', errorResponse.message);
|
|
1825
|
+
}
|
|
1826
|
+
return _context25.abrupt("return", errorResponse);
|
|
1827
|
+
case 25:
|
|
1817
1828
|
case "end":
|
|
1818
1829
|
return _context25.stop();
|
|
1819
1830
|
}
|
|
@@ -1917,7 +1928,7 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
|
|
|
1917
1928
|
}
|
|
1918
1929
|
|
|
1919
1930
|
// Provide the current progress to the callback function
|
|
1920
|
-
if (response.status == 'RUNNING') {
|
|
1931
|
+
if (response.status == 'RUNNING' && onProgress) {
|
|
1921
1932
|
onProgress(response);
|
|
1922
1933
|
}
|
|
1923
1934
|
|
package/dist/cjs/rbt_object.cjs
CHANGED
|
@@ -595,14 +595,16 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
|
|
|
595
595
|
publish,
|
|
596
596
|
_options$save2,
|
|
597
597
|
save,
|
|
598
|
+
currentIac,
|
|
598
599
|
iac,
|
|
599
600
|
_args5 = arguments;
|
|
600
601
|
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
601
602
|
while (1) switch (_context5.prev = _context5.next) {
|
|
602
603
|
case 0:
|
|
603
604
|
options = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : {};
|
|
604
|
-
_options$publish = options.publish, publish = _options$publish === void 0 ? true : _options$publish, _options$save2 = options.save, save = _options$save2 === void 0 ? true : _options$save2; // Get current IAC settings
|
|
605
|
-
|
|
605
|
+
_options$publish = options.publish, publish = _options$publish === void 0 ? true : _options$publish, _options$save2 = options.save, save = _options$save2 === void 0 ? true : _options$save2; // Get current IAC settings and create a deep clone to ensure change detection
|
|
606
|
+
currentIac = this.get('iac') || {};
|
|
607
|
+
iac = _lodash["default"].cloneDeep(currentIac); // Initialize readGrants if it doesn't exist
|
|
606
608
|
if (!iac.readGrants) {
|
|
607
609
|
iac.readGrants = {};
|
|
608
610
|
}
|
|
@@ -623,21 +625,21 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
|
|
|
623
625
|
});
|
|
624
626
|
}
|
|
625
627
|
|
|
626
|
-
// Update the object
|
|
628
|
+
// Update the object with the cloned and modified IAC
|
|
627
629
|
this.set('iac', iac);
|
|
628
630
|
|
|
629
631
|
// Save if requested
|
|
630
632
|
if (!save) {
|
|
631
|
-
_context5.next =
|
|
633
|
+
_context5.next = 12;
|
|
632
634
|
break;
|
|
633
635
|
}
|
|
634
|
-
_context5.next =
|
|
636
|
+
_context5.next = 11;
|
|
635
637
|
return this.save();
|
|
636
|
-
case 10:
|
|
637
|
-
return _context5.abrupt("return", _context5.sent);
|
|
638
638
|
case 11:
|
|
639
|
-
return _context5.abrupt("return",
|
|
639
|
+
return _context5.abrupt("return", _context5.sent);
|
|
640
640
|
case 12:
|
|
641
|
+
return _context5.abrupt("return", this);
|
|
642
|
+
case 13:
|
|
641
643
|
case "end":
|
|
642
644
|
return _context5.stop();
|
|
643
645
|
}
|
package/dist/esm/rbt_api.js
CHANGED
|
@@ -1049,17 +1049,27 @@ export default class RbtApi {
|
|
|
1049
1049
|
output
|
|
1050
1050
|
};
|
|
1051
1051
|
} catch (e) {
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
console.error('Error in runTask:', e);
|
|
1056
|
-
}
|
|
1057
|
-
return {
|
|
1052
|
+
// Standardize error format to match task response object
|
|
1053
|
+
// Support RbtError format with label and message
|
|
1054
|
+
const errorResponse = {
|
|
1058
1055
|
ok: false,
|
|
1059
1056
|
jobId: null,
|
|
1060
1057
|
status: 'ERROR',
|
|
1061
|
-
|
|
1058
|
+
message: e.message || e.toString() || 'Unknown error',
|
|
1059
|
+
label: e.label || e.name || 'Error',
|
|
1060
|
+
output: {
|
|
1061
|
+
error: e.message,
|
|
1062
|
+
label: e.label,
|
|
1063
|
+
stack: e.stack,
|
|
1064
|
+
originalError: e
|
|
1065
|
+
}
|
|
1062
1066
|
};
|
|
1067
|
+
if (typeof onError === 'function') {
|
|
1068
|
+
onError(errorResponse);
|
|
1069
|
+
} else {
|
|
1070
|
+
console.error('Error in runTask:', errorResponse.message);
|
|
1071
|
+
}
|
|
1072
|
+
return errorResponse;
|
|
1063
1073
|
}
|
|
1064
1074
|
}
|
|
1065
1075
|
async stopJob(params = {}, callbacks = {}) {
|
|
@@ -1120,7 +1130,7 @@ export default class RbtApi {
|
|
|
1120
1130
|
}
|
|
1121
1131
|
|
|
1122
1132
|
// Provide the current progress to the callback function
|
|
1123
|
-
if (response.status == 'RUNNING') {
|
|
1133
|
+
if (response.status == 'RUNNING' && onProgress) {
|
|
1124
1134
|
onProgress(response);
|
|
1125
1135
|
}
|
|
1126
1136
|
|
package/dist/esm/rbt_object.js
CHANGED
|
@@ -434,8 +434,9 @@ export default class RbtObject {
|
|
|
434
434
|
save = true
|
|
435
435
|
} = options;
|
|
436
436
|
|
|
437
|
-
// Get current IAC settings
|
|
438
|
-
const
|
|
437
|
+
// Get current IAC settings and create a deep clone to ensure change detection
|
|
438
|
+
const currentIac = this.get('iac') || {};
|
|
439
|
+
const iac = _.cloneDeep(currentIac);
|
|
439
440
|
|
|
440
441
|
// Initialize readGrants if it doesn't exist
|
|
441
442
|
if (!iac.readGrants) {
|
|
@@ -456,7 +457,7 @@ export default class RbtObject {
|
|
|
456
457
|
iac.readGrants.users = iac.readGrants.users.filter(userId => userId !== 'public_user');
|
|
457
458
|
}
|
|
458
459
|
|
|
459
|
-
// Update the object
|
|
460
|
+
// Update the object with the cloned and modified IAC
|
|
460
461
|
this.set('iac', iac);
|
|
461
462
|
|
|
462
463
|
// Save if requested
|
package/dist/rbt_api.js
CHANGED
|
@@ -1697,6 +1697,7 @@ var RbtApi = /*#__PURE__*/function () {
|
|
|
1697
1697
|
status,
|
|
1698
1698
|
message,
|
|
1699
1699
|
output,
|
|
1700
|
+
errorResponse,
|
|
1700
1701
|
_args23 = arguments,
|
|
1701
1702
|
_t17;
|
|
1702
1703
|
return _regenerator().w(function (_context23) {
|
|
@@ -1755,17 +1756,27 @@ var RbtApi = /*#__PURE__*/function () {
|
|
|
1755
1756
|
case 5:
|
|
1756
1757
|
_context23.p = 5;
|
|
1757
1758
|
_t17 = _context23.v;
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
console.error('Error in runTask:', _t17);
|
|
1762
|
-
}
|
|
1763
|
-
return _context23.a(2, {
|
|
1759
|
+
// Standardize error format to match task response object
|
|
1760
|
+
// Support RbtError format with label and message
|
|
1761
|
+
errorResponse = {
|
|
1764
1762
|
ok: false,
|
|
1765
1763
|
jobId: null,
|
|
1766
1764
|
status: 'ERROR',
|
|
1767
|
-
|
|
1768
|
-
|
|
1765
|
+
message: _t17.message || _t17.toString() || 'Unknown error',
|
|
1766
|
+
label: _t17.label || _t17.name || 'Error',
|
|
1767
|
+
output: {
|
|
1768
|
+
error: _t17.message,
|
|
1769
|
+
label: _t17.label,
|
|
1770
|
+
stack: _t17.stack,
|
|
1771
|
+
originalError: _t17
|
|
1772
|
+
}
|
|
1773
|
+
};
|
|
1774
|
+
if (typeof onError === 'function') {
|
|
1775
|
+
onError(errorResponse);
|
|
1776
|
+
} else {
|
|
1777
|
+
console.error('Error in runTask:', errorResponse.message);
|
|
1778
|
+
}
|
|
1779
|
+
return _context23.a(2, errorResponse);
|
|
1769
1780
|
}
|
|
1770
1781
|
}, _callee23, this, [[1, 5]]);
|
|
1771
1782
|
}));
|
package/dist/rbt_object.js
CHANGED
|
@@ -583,14 +583,16 @@ var RbtObject = /*#__PURE__*/function () {
|
|
|
583
583
|
publish,
|
|
584
584
|
_options$save2,
|
|
585
585
|
save,
|
|
586
|
+
currentIac,
|
|
586
587
|
iac,
|
|
587
588
|
_args5 = arguments;
|
|
588
589
|
return _regenerator().w(function (_context5) {
|
|
589
590
|
while (1) switch (_context5.n) {
|
|
590
591
|
case 0:
|
|
591
592
|
options = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : {};
|
|
592
|
-
_options$publish = options.publish, publish = _options$publish === void 0 ? true : _options$publish, _options$save2 = options.save, save = _options$save2 === void 0 ? true : _options$save2; // Get current IAC settings
|
|
593
|
-
|
|
593
|
+
_options$publish = options.publish, publish = _options$publish === void 0 ? true : _options$publish, _options$save2 = options.save, save = _options$save2 === void 0 ? true : _options$save2; // Get current IAC settings and create a deep clone to ensure change detection
|
|
594
|
+
currentIac = this.get('iac') || {};
|
|
595
|
+
iac = _.cloneDeep(currentIac); // Initialize readGrants if it doesn't exist
|
|
594
596
|
if (!iac.readGrants) {
|
|
595
597
|
iac.readGrants = {};
|
|
596
598
|
}
|
|
@@ -611,7 +613,7 @@ var RbtObject = /*#__PURE__*/function () {
|
|
|
611
613
|
});
|
|
612
614
|
}
|
|
613
615
|
|
|
614
|
-
// Update the object
|
|
616
|
+
// Update the object with the cloned and modified IAC
|
|
615
617
|
this.set('iac', iac);
|
|
616
618
|
|
|
617
619
|
// Save if requested
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Examples demonstrating object sharing and publishing in roboto-js
|
|
3
|
+
*
|
|
4
|
+
* These examples show how to use the new shareObject() and publishObject() methods
|
|
5
|
+
* to control access to your rbtObjects using the mod-iac system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Import roboto-js
|
|
9
|
+
import Roboto from 'roboto-js';
|
|
10
|
+
|
|
11
|
+
// Initialize roboto instance
|
|
12
|
+
const roboto = new Roboto({
|
|
13
|
+
host: 'your-host.com',
|
|
14
|
+
accessKey: 'your-access-key'
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Wait for authentication
|
|
18
|
+
await roboto.api.loadCurrentUser();
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// EXAMPLE 1: Publishing an Object (Making it Public)
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
async function example1_PublishObject() {
|
|
25
|
+
console.log('\n=== Example 1: Publishing an Object ===\n');
|
|
26
|
+
|
|
27
|
+
// Load an existing object
|
|
28
|
+
const myAgent = await roboto.api.load('<@doc_agent.bot>', 'agent_123');
|
|
29
|
+
|
|
30
|
+
// Check if it's currently published
|
|
31
|
+
console.log('Is published?', myAgent.isPublished());
|
|
32
|
+
|
|
33
|
+
// Publish it (make it publicly accessible)
|
|
34
|
+
await myAgent.publishObject();
|
|
35
|
+
console.log('✓ Agent is now public!');
|
|
36
|
+
|
|
37
|
+
// Verify it's published
|
|
38
|
+
console.log('Is published?', myAgent.isPublished());
|
|
39
|
+
|
|
40
|
+
// Later, you can unpublish it (explicit method)
|
|
41
|
+
await myAgent.unpublishObject();
|
|
42
|
+
console.log('✓ Agent is now private (using unpublishObject)');
|
|
43
|
+
|
|
44
|
+
// Alternative: using publishObject with flag
|
|
45
|
+
// await myAgent.publishObject({ publish: false });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// EXAMPLE 2: Sharing with Specific Users
|
|
50
|
+
// ============================================================================
|
|
51
|
+
|
|
52
|
+
async function example2_ShareWithUsers() {
|
|
53
|
+
console.log('\n=== Example 2: Sharing with Specific Users ===\n');
|
|
54
|
+
|
|
55
|
+
const myDocument = await roboto.api.load('<@doc.document>', 'doc_456');
|
|
56
|
+
|
|
57
|
+
// Share with specific users (read access)
|
|
58
|
+
await myDocument.shareObject({
|
|
59
|
+
userIds: ['user_123', 'user_456', 'user_789']
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
console.log('✓ Document shared with 3 users');
|
|
63
|
+
|
|
64
|
+
// View current permissions
|
|
65
|
+
const permissions = myDocument.getSharing();
|
|
66
|
+
console.log('Read users:', permissions.readGrants.users);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// EXAMPLE 3: Sharing with User Groups
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
async function example3_ShareWithGroups() {
|
|
74
|
+
console.log('\n=== Example 3: Sharing with User Groups ===\n');
|
|
75
|
+
|
|
76
|
+
const myTemplate = await roboto.api.load('<@doc_agent.bot>', 'template_789');
|
|
77
|
+
|
|
78
|
+
// Share with user groups (read access)
|
|
79
|
+
await myTemplate.shareObject({
|
|
80
|
+
groupIds: ['grpRngAccount', 'grpPremiumUsers']
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
console.log('✓ Template shared with 2 user groups');
|
|
84
|
+
|
|
85
|
+
// View permissions
|
|
86
|
+
const permissions = myTemplate.getSharing();
|
|
87
|
+
console.log('Read groups:', permissions.readGrants.userGroups);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// EXAMPLE 4: Granting Write Access
|
|
92
|
+
// ============================================================================
|
|
93
|
+
|
|
94
|
+
async function example4_GrantWriteAccess() {
|
|
95
|
+
console.log('\n=== Example 4: Granting Write Access ===\n');
|
|
96
|
+
|
|
97
|
+
const myProject = await roboto.api.load('<@doc.project>', 'proj_abc');
|
|
98
|
+
|
|
99
|
+
// Share with read access (default)
|
|
100
|
+
await myProject.shareObject({
|
|
101
|
+
groupIds: ['grpViewers']
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Share with write access for editors
|
|
105
|
+
await myProject.shareObject({
|
|
106
|
+
groupIds: ['grpEditors'],
|
|
107
|
+
write: true
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
console.log('✓ Viewers can read, editors can write');
|
|
111
|
+
|
|
112
|
+
// View all permissions
|
|
113
|
+
const permissions = myProject.getSharing();
|
|
114
|
+
console.log('Read groups:', permissions.readGrants.userGroups);
|
|
115
|
+
console.log('Write groups:', permissions.writeGrants.userGroups);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// EXAMPLE 5: Combining Users and Groups
|
|
120
|
+
// ============================================================================
|
|
121
|
+
|
|
122
|
+
async function example5_CombineUsersAndGroups() {
|
|
123
|
+
console.log('\n=== Example 5: Combining Users and Groups ===\n');
|
|
124
|
+
|
|
125
|
+
const myContent = await roboto.api.load('<@doc.content>', 'content_xyz');
|
|
126
|
+
|
|
127
|
+
// Share with both users and groups
|
|
128
|
+
await myContent.shareObject({
|
|
129
|
+
userIds: ['user_special_123'],
|
|
130
|
+
groupIds: ['grpSubscribers', 'grpPremium']
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
console.log('✓ Shared with 1 user and 2 groups');
|
|
134
|
+
|
|
135
|
+
const permissions = myContent.getSharing();
|
|
136
|
+
console.log('Read users:', permissions.readGrants.users);
|
|
137
|
+
console.log('Read groups:', permissions.readGrants.userGroups);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ============================================================================
|
|
141
|
+
// EXAMPLE 6: Replacing vs. Merging Permissions
|
|
142
|
+
// ============================================================================
|
|
143
|
+
|
|
144
|
+
async function example6_ReplaceVsMerge() {
|
|
145
|
+
console.log('\n=== Example 6: Replacing vs. Merging ===\n');
|
|
146
|
+
|
|
147
|
+
const myObject = await roboto.api.load('<@doc.item>', 'item_001');
|
|
148
|
+
|
|
149
|
+
// First share with some users (merges with existing)
|
|
150
|
+
await myObject.shareObject({
|
|
151
|
+
userIds: ['user_a', 'user_b']
|
|
152
|
+
});
|
|
153
|
+
console.log('After merge:', myObject.getSharing().readGrants.users);
|
|
154
|
+
|
|
155
|
+
// Add more users (merges again)
|
|
156
|
+
await myObject.shareObject({
|
|
157
|
+
userIds: ['user_c']
|
|
158
|
+
});
|
|
159
|
+
console.log('After another merge:', myObject.getSharing().readGrants.users);
|
|
160
|
+
|
|
161
|
+
// Replace all permissions
|
|
162
|
+
await myObject.shareObject({
|
|
163
|
+
userIds: ['user_x', 'user_y'],
|
|
164
|
+
replace: true
|
|
165
|
+
});
|
|
166
|
+
console.log('After replace:', myObject.getSharing().readGrants.users);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// EXAMPLE 7: Batch Updates Without Auto-Save
|
|
171
|
+
// ============================================================================
|
|
172
|
+
|
|
173
|
+
async function example7_BatchUpdates() {
|
|
174
|
+
console.log('\n=== Example 7: Batch Updates Without Auto-Save ===\n');
|
|
175
|
+
|
|
176
|
+
const myAgent = await roboto.api.load('<@doc_agent.bot>', 'agent_multi');
|
|
177
|
+
|
|
178
|
+
// Update permissions without saving
|
|
179
|
+
await myAgent.shareObject({
|
|
180
|
+
groupIds: ['grpUsers'],
|
|
181
|
+
save: false
|
|
182
|
+
});
|
|
183
|
+
console.log('✓ Added group (not saved)');
|
|
184
|
+
|
|
185
|
+
// Publish without saving
|
|
186
|
+
await myAgent.publishObject({ save: false });
|
|
187
|
+
console.log('✓ Published (not saved)');
|
|
188
|
+
|
|
189
|
+
// Make other changes
|
|
190
|
+
myAgent.set('configs.title', 'Updated Title');
|
|
191
|
+
console.log('✓ Updated title (not saved)');
|
|
192
|
+
|
|
193
|
+
// Save once with all changes
|
|
194
|
+
await myAgent.save();
|
|
195
|
+
console.log('✓ All changes saved at once!');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// EXAMPLE 8: Tiered Access Control
|
|
200
|
+
// ============================================================================
|
|
201
|
+
|
|
202
|
+
async function example8_TieredAccess() {
|
|
203
|
+
console.log('\n=== Example 8: Tiered Access Control ===\n');
|
|
204
|
+
|
|
205
|
+
const myContent = await roboto.api.load('<@doc.content>', 'content_tiered');
|
|
206
|
+
|
|
207
|
+
// Public can read
|
|
208
|
+
await myContent.publishObject({ save: false });
|
|
209
|
+
|
|
210
|
+
// Editors can write
|
|
211
|
+
await myContent.shareObject({
|
|
212
|
+
groupIds: ['grpEditors'],
|
|
213
|
+
write: true,
|
|
214
|
+
save: false
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Admins can write
|
|
218
|
+
await myContent.shareObject({
|
|
219
|
+
groupIds: ['grpAdmins'],
|
|
220
|
+
write: true,
|
|
221
|
+
save: true
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
console.log('✓ Tiered access configured:');
|
|
225
|
+
console.log(' - Public: read');
|
|
226
|
+
console.log(' - Editors: write');
|
|
227
|
+
console.log(' - Admins: write');
|
|
228
|
+
|
|
229
|
+
const permissions = myContent.getSharing();
|
|
230
|
+
console.log('\nRead users:', permissions.readGrants.users);
|
|
231
|
+
console.log('Write groups:', permissions.writeGrants.userGroups);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ============================================================================
|
|
235
|
+
// EXAMPLE 9: Template Publishing Pattern (like Ringable)
|
|
236
|
+
// ============================================================================
|
|
237
|
+
|
|
238
|
+
async function example9_TemplatePublishing() {
|
|
239
|
+
console.log('\n=== Example 9: Template Publishing Pattern ===\n');
|
|
240
|
+
|
|
241
|
+
const template = await roboto.api.load('<@doc_agent.bot>', 'template_rng');
|
|
242
|
+
|
|
243
|
+
// Function to publish/unpublish a template
|
|
244
|
+
async function setTemplatePublished(agent, isPublished) {
|
|
245
|
+
if (isPublished) {
|
|
246
|
+
// Share with all account users
|
|
247
|
+
await agent.shareObject({
|
|
248
|
+
groupIds: ['grpRngAccount']
|
|
249
|
+
});
|
|
250
|
+
console.log('✓ Template published to all account users');
|
|
251
|
+
} else {
|
|
252
|
+
// Remove the group
|
|
253
|
+
const current = agent.getSharing();
|
|
254
|
+
const remainingGroups = current.readGrants.userGroups
|
|
255
|
+
.filter(g => g !== 'grpRngAccount');
|
|
256
|
+
|
|
257
|
+
await agent.shareObject({
|
|
258
|
+
groupIds: remainingGroups,
|
|
259
|
+
replace: true
|
|
260
|
+
});
|
|
261
|
+
console.log('✓ Template unpublished from account users');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Publish the template
|
|
266
|
+
await setTemplatePublished(template, true);
|
|
267
|
+
|
|
268
|
+
// Later, unpublish it
|
|
269
|
+
await setTemplatePublished(template, false);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ============================================================================
|
|
273
|
+
// EXAMPLE 10: Getting and Inspecting Permissions
|
|
274
|
+
// ============================================================================
|
|
275
|
+
|
|
276
|
+
async function example10_InspectPermissions() {
|
|
277
|
+
console.log('\n=== Example 10: Inspecting Permissions ===\n');
|
|
278
|
+
|
|
279
|
+
const myObject = await roboto.api.load('<@doc.item>', 'item_inspect');
|
|
280
|
+
|
|
281
|
+
// Get all permissions
|
|
282
|
+
const permissions = myObject.getSharing();
|
|
283
|
+
|
|
284
|
+
console.log('Read Permissions:');
|
|
285
|
+
console.log(' Users:', permissions.readGrants.users);
|
|
286
|
+
console.log(' Groups:', permissions.readGrants.userGroups);
|
|
287
|
+
console.log(' Organizations:', permissions.readGrants.organizations);
|
|
288
|
+
|
|
289
|
+
console.log('\nWrite Permissions:');
|
|
290
|
+
console.log(' Users:', permissions.writeGrants.users);
|
|
291
|
+
console.log(' Groups:', permissions.writeGrants.userGroups);
|
|
292
|
+
console.log(' Organizations:', permissions.writeGrants.organizations);
|
|
293
|
+
|
|
294
|
+
// Check if public
|
|
295
|
+
console.log('\nIs Published?', myObject.isPublished());
|
|
296
|
+
|
|
297
|
+
// Get raw IAC data
|
|
298
|
+
const iac = myObject.get('iac');
|
|
299
|
+
console.log('\nRaw IAC data:', JSON.stringify(iac, null, 2));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// ============================================================================
|
|
303
|
+
// EXAMPLE 11: Removing Access with unshareObject
|
|
304
|
+
// ============================================================================
|
|
305
|
+
|
|
306
|
+
async function example11_RemovingAccess() {
|
|
307
|
+
console.log('\n=== Example 11: Removing Access with unshareObject ===\n');
|
|
308
|
+
|
|
309
|
+
const myObject = await roboto.api.load('<@doc.item>', 'item_remove');
|
|
310
|
+
|
|
311
|
+
// Get current permissions
|
|
312
|
+
const current = myObject.getSharing();
|
|
313
|
+
console.log('Current users:', current.readGrants.users);
|
|
314
|
+
console.log('Current groups:', current.readGrants.userGroups);
|
|
315
|
+
|
|
316
|
+
// Remove specific users from read access (easy way)
|
|
317
|
+
await myObject.unshareObject({
|
|
318
|
+
userIds: ['user_123', 'user_456']
|
|
319
|
+
});
|
|
320
|
+
console.log('✓ Removed specific users');
|
|
321
|
+
console.log('Remaining users:', myObject.getSharing().readGrants.users);
|
|
322
|
+
|
|
323
|
+
// Remove specific groups from read access
|
|
324
|
+
await myObject.unshareObject({
|
|
325
|
+
groupIds: ['grpViewers']
|
|
326
|
+
});
|
|
327
|
+
console.log('✓ Removed specific groups');
|
|
328
|
+
console.log('Remaining groups:', myObject.getSharing().readGrants.userGroups);
|
|
329
|
+
|
|
330
|
+
// Remove write access from groups
|
|
331
|
+
await myObject.unshareObject({
|
|
332
|
+
groupIds: ['grpEditors'],
|
|
333
|
+
write: true
|
|
334
|
+
});
|
|
335
|
+
console.log('✓ Removed write access from editors');
|
|
336
|
+
|
|
337
|
+
// Alternative: using replace with shareObject
|
|
338
|
+
const currentAfter = myObject.getSharing();
|
|
339
|
+
const keepUsers = currentAfter.readGrants.users.filter(id => id !== 'user_789');
|
|
340
|
+
await myObject.shareObject({
|
|
341
|
+
userIds: keepUsers,
|
|
342
|
+
replace: true
|
|
343
|
+
});
|
|
344
|
+
console.log('✓ Removed user_789 using replace method');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ============================================================================
|
|
348
|
+
// EXAMPLE 12: Creating and Sharing a New Object
|
|
349
|
+
// ============================================================================
|
|
350
|
+
|
|
351
|
+
async function example12_CreateAndShare() {
|
|
352
|
+
console.log('\n=== Example 12: Creating and Sharing a New Object ===\n');
|
|
353
|
+
|
|
354
|
+
// Create a new object
|
|
355
|
+
const newAgent = await roboto.api.create('<@doc_agent.bot>', {
|
|
356
|
+
configs: {
|
|
357
|
+
title: 'My New Public Agent',
|
|
358
|
+
description: 'This agent will be shared with everyone'
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
console.log('✓ Created new agent:', newAgent.id);
|
|
363
|
+
|
|
364
|
+
// Immediately publish it
|
|
365
|
+
await newAgent.publishObject();
|
|
366
|
+
|
|
367
|
+
console.log('✓ Published new agent');
|
|
368
|
+
console.log('Is published?', newAgent.isPublished());
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ============================================================================
|
|
372
|
+
// Run all examples
|
|
373
|
+
// ============================================================================
|
|
374
|
+
|
|
375
|
+
async function runAllExamples() {
|
|
376
|
+
console.log('╔════════════════════════════════════════════════════════════╗');
|
|
377
|
+
console.log('║ roboto-js Sharing & Publishing Examples ║');
|
|
378
|
+
console.log('╚════════════════════════════════════════════════════════════╝');
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
// Uncomment the examples you want to run:
|
|
382
|
+
|
|
383
|
+
// await example1_PublishObject();
|
|
384
|
+
// await example2_ShareWithUsers();
|
|
385
|
+
// await example3_ShareWithGroups();
|
|
386
|
+
// await example4_GrantWriteAccess();
|
|
387
|
+
// await example5_CombineUsersAndGroups();
|
|
388
|
+
// await example6_ReplaceVsMerge();
|
|
389
|
+
// await example7_BatchUpdates();
|
|
390
|
+
// await example8_TieredAccess();
|
|
391
|
+
// await example9_TemplatePublishing();
|
|
392
|
+
// await example10_InspectPermissions();
|
|
393
|
+
// await example11_RemovingAccess();
|
|
394
|
+
// await example12_CreateAndShare();
|
|
395
|
+
|
|
396
|
+
console.log('\n✓ All examples completed!');
|
|
397
|
+
} catch (error) {
|
|
398
|
+
console.error('\n✗ Error running examples:', error);
|
|
399
|
+
console.error(error.stack);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Run examples if this file is executed directly
|
|
404
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
405
|
+
runAllExamples();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Export examples for use in other files
|
|
409
|
+
export {
|
|
410
|
+
example1_PublishObject,
|
|
411
|
+
example2_ShareWithUsers,
|
|
412
|
+
example3_ShareWithGroups,
|
|
413
|
+
example4_GrantWriteAccess,
|
|
414
|
+
example5_CombineUsersAndGroups,
|
|
415
|
+
example6_ReplaceVsMerge,
|
|
416
|
+
example7_BatchUpdates,
|
|
417
|
+
example8_TieredAccess,
|
|
418
|
+
example9_TemplatePublishing,
|
|
419
|
+
example10_InspectPermissions,
|
|
420
|
+
example11_RemovingAccess,
|
|
421
|
+
example12_CreateAndShare,
|
|
422
|
+
runAllExamples
|
|
423
|
+
};
|
|
424
|
+
|
package/package.json
CHANGED
package/src/rbt_api.js
CHANGED
|
@@ -1098,13 +1098,28 @@ export default class RbtApi {
|
|
|
1098
1098
|
return { ok, jobId, status, message, output };
|
|
1099
1099
|
|
|
1100
1100
|
} catch (e) {
|
|
1101
|
+
// Standardize error format to match task response object
|
|
1102
|
+
// Support RbtError format with label and message
|
|
1103
|
+
const errorResponse = {
|
|
1104
|
+
ok: false,
|
|
1105
|
+
jobId: null,
|
|
1106
|
+
status: 'ERROR',
|
|
1107
|
+
message: e.message || e.toString() || 'Unknown error',
|
|
1108
|
+
label: e.label || e.name || 'Error',
|
|
1109
|
+
output: {
|
|
1110
|
+
error: e.message,
|
|
1111
|
+
label: e.label,
|
|
1112
|
+
stack: e.stack,
|
|
1113
|
+
originalError: e
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1101
1116
|
|
|
1102
1117
|
if (typeof onError === 'function') {
|
|
1103
|
-
onError(
|
|
1118
|
+
onError(errorResponse);
|
|
1104
1119
|
} else {
|
|
1105
|
-
console.error('Error in runTask:',
|
|
1120
|
+
console.error('Error in runTask:', errorResponse.message);
|
|
1106
1121
|
}
|
|
1107
|
-
return
|
|
1122
|
+
return errorResponse;
|
|
1108
1123
|
|
|
1109
1124
|
}
|
|
1110
1125
|
}
|
|
@@ -1163,7 +1178,7 @@ export default class RbtApi {
|
|
|
1163
1178
|
}
|
|
1164
1179
|
|
|
1165
1180
|
// Provide the current progress to the callback function
|
|
1166
|
-
if(response.status == 'RUNNING'){
|
|
1181
|
+
if(response.status == 'RUNNING' && onProgress){
|
|
1167
1182
|
onProgress(response);
|
|
1168
1183
|
}
|
|
1169
1184
|
|
package/src/rbt_object.js
CHANGED
|
@@ -449,8 +449,9 @@ export default class RbtObject{
|
|
|
449
449
|
save = true
|
|
450
450
|
} = options;
|
|
451
451
|
|
|
452
|
-
// Get current IAC settings
|
|
453
|
-
const
|
|
452
|
+
// Get current IAC settings and create a deep clone to ensure change detection
|
|
453
|
+
const currentIac = this.get('iac') || {};
|
|
454
|
+
const iac = _.cloneDeep(currentIac);
|
|
454
455
|
|
|
455
456
|
// Initialize readGrants if it doesn't exist
|
|
456
457
|
if (!iac.readGrants) {
|
|
@@ -472,7 +473,7 @@ export default class RbtObject{
|
|
|
472
473
|
iac.readGrants.users = iac.readGrants.users.filter(userId => userId !== 'public_user');
|
|
473
474
|
}
|
|
474
475
|
|
|
475
|
-
// Update the object
|
|
476
|
+
// Update the object with the cloned and modified IAC
|
|
476
477
|
this.set('iac', iac);
|
|
477
478
|
|
|
478
479
|
// Save if requested
|