@bardioc/app-sdk 0.4.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/LICENSE +5 -0
- package/README.md +368 -0
- package/assets/fonts/README.md +11 -0
- package/assets/fonts/bardioc-fonts.css +55 -0
- package/assets/fonts/v1/geist-mono-latin-wght-normal.woff2 +0 -0
- package/assets/fonts/v1/nunito-sans-latin-wght-italic.woff2 +0 -0
- package/assets/fonts/v1/nunito-sans-latin-wght-normal.woff2 +0 -0
- package/dist/contract-matrix.d.ts +130 -0
- package/dist/contract-matrix.js +132 -0
- package/dist/dev-auth-proxy-core.d.ts +24 -0
- package/dist/dev-auth-proxy-core.js +59 -0
- package/dist/dev-auth-vite.d.ts +34 -0
- package/dist/dev-auth-vite.js +221 -0
- package/dist/dev-proxy.d.ts +8 -0
- package/dist/dev-proxy.js +40 -0
- package/dist/dev-session-cli.d.ts +34 -0
- package/dist/dev-session-cli.js +125 -0
- package/dist/dev.d.ts +33 -0
- package/dist/dev.js +223 -0
- package/dist/dot-env.d.ts +2 -0
- package/dist/dot-env.js +22 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.js +57 -0
- package/dist/host-bridge.d.ts +3 -0
- package/dist/host-bridge.js +260 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +6 -0
- package/dist/manifest.d.ts +78 -0
- package/dist/manifest.js +169 -0
- package/dist/protocol.d.ts +26 -0
- package/dist/protocol.js +28 -0
- package/dist/react.d.ts +26 -0
- package/dist/react.js +208 -0
- package/dist/transports/graph-transport.d.ts +224 -0
- package/dist/transports/graph-transport.js +584 -0
- package/dist/transports/os-transport.d.ts +189 -0
- package/dist/transports/os-transport.js +444 -0
- package/dist/types.d.ts +343 -0
- package/dist/vite.d.ts +9 -0
- package/dist/vite.js +262 -0
- package/package.json +101 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type { Application, Configuration, CreateMemberInput, CreateUnitInput, FileEntry, InstanceList, OrgMember, OrgStructure, OrgUnit, OsRequestOptions, SdkTransportPayload, UpdateMemberInput, UpdateUnitInput, UserProfile } from '../types.js';
|
|
2
|
+
/** OS transport class providing OS/system operations */
|
|
3
|
+
export declare class OsTransport {
|
|
4
|
+
private readonly _request;
|
|
5
|
+
constructor(_request: <T = unknown>(payload: SdkTransportPayload) => Promise<T>);
|
|
6
|
+
/**
|
|
7
|
+
* User profile operations
|
|
8
|
+
*/
|
|
9
|
+
profile: {
|
|
10
|
+
/**
|
|
11
|
+
* Get current user profile
|
|
12
|
+
*
|
|
13
|
+
* @throws {NetworkError} on HTTP errors
|
|
14
|
+
* @throws {TimeoutError} on request timeout
|
|
15
|
+
*/
|
|
16
|
+
get: () => Promise<UserProfile>;
|
|
17
|
+
/**
|
|
18
|
+
* Get user avatar image
|
|
19
|
+
*
|
|
20
|
+
* @throws {EntityNotFoundError} if avatar doesn't exist
|
|
21
|
+
* @throws {NetworkError} on HTTP errors
|
|
22
|
+
* @throws {TimeoutError} on request timeout
|
|
23
|
+
*/
|
|
24
|
+
getAvatar: () => Promise<Blob>;
|
|
25
|
+
/**
|
|
26
|
+
* Upload user avatar
|
|
27
|
+
*
|
|
28
|
+
* @throws {ValidationError} if image format is invalid
|
|
29
|
+
* @throws {NetworkError} on HTTP errors
|
|
30
|
+
* @throws {TimeoutError} on request timeout
|
|
31
|
+
*/
|
|
32
|
+
setAvatar: (image: Blob) => Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Get accessible instances
|
|
35
|
+
*
|
|
36
|
+
* @throws {NetworkError} on HTTP errors
|
|
37
|
+
* @throws {TimeoutError} on request timeout
|
|
38
|
+
*/
|
|
39
|
+
getInstances: () => Promise<InstanceList>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Organization structure operations
|
|
43
|
+
*/
|
|
44
|
+
organization: {
|
|
45
|
+
/**
|
|
46
|
+
* Get full organization hierarchy
|
|
47
|
+
*
|
|
48
|
+
* @throws {NetworkError} on HTTP errors
|
|
49
|
+
* @throws {TimeoutError} on request timeout
|
|
50
|
+
*/
|
|
51
|
+
getStructure: () => Promise<OrgStructure>;
|
|
52
|
+
/**
|
|
53
|
+
* Create organizational unit
|
|
54
|
+
*
|
|
55
|
+
* @throws {ValidationError} if data is invalid or missing required fields
|
|
56
|
+
* @throws {PermissionError} if user lacks permission to create units
|
|
57
|
+
* @throws {NetworkError} on HTTP errors
|
|
58
|
+
* @throws {TimeoutError} on request timeout
|
|
59
|
+
*/
|
|
60
|
+
createUnit: (data: CreateUnitInput) => Promise<OrgUnit>;
|
|
61
|
+
/**
|
|
62
|
+
* Update organizational unit
|
|
63
|
+
*
|
|
64
|
+
* @throws {EntityNotFoundError} if unit doesn't exist
|
|
65
|
+
* @throws {ValidationError} if data is invalid
|
|
66
|
+
* @throws {PermissionError} if user lacks permission to update unit
|
|
67
|
+
* @throws {NetworkError} on HTTP errors
|
|
68
|
+
* @throws {TimeoutError} on request timeout
|
|
69
|
+
*/
|
|
70
|
+
updateUnit: (id: string, data: UpdateUnitInput) => Promise<OrgUnit>;
|
|
71
|
+
/**
|
|
72
|
+
* Create organization member
|
|
73
|
+
*
|
|
74
|
+
* @throws {ValidationError} if data is invalid or missing required fields
|
|
75
|
+
* @throws {PermissionError} if user lacks permission to create members
|
|
76
|
+
* @throws {NetworkError} on HTTP errors
|
|
77
|
+
* @throws {TimeoutError} on request timeout
|
|
78
|
+
*/
|
|
79
|
+
createMember: (data: CreateMemberInput) => Promise<OrgMember>;
|
|
80
|
+
/**
|
|
81
|
+
* Update organization member
|
|
82
|
+
*
|
|
83
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
84
|
+
* @throws {ValidationError} if data is invalid
|
|
85
|
+
* @throws {PermissionError} if user lacks permission to update member
|
|
86
|
+
* @throws {NetworkError} on HTTP errors
|
|
87
|
+
* @throws {TimeoutError} on request timeout
|
|
88
|
+
*/
|
|
89
|
+
updateMember: (id: string, data: UpdateMemberInput) => Promise<OrgMember>;
|
|
90
|
+
/**
|
|
91
|
+
* Delete organization member
|
|
92
|
+
*
|
|
93
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
94
|
+
* @throws {PermissionError} if user lacks permission to delete member
|
|
95
|
+
* @throws {NetworkError} on HTTP errors
|
|
96
|
+
* @throws {TimeoutError} on request timeout
|
|
97
|
+
*/
|
|
98
|
+
deleteMember: (id: string) => Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Send invitation email to member
|
|
101
|
+
*
|
|
102
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
103
|
+
* @throws {ValidationError} if member email is invalid
|
|
104
|
+
* @throws {NetworkError} on HTTP errors
|
|
105
|
+
* @throws {TimeoutError} on request timeout
|
|
106
|
+
*/
|
|
107
|
+
inviteMember: (id: string) => Promise<void>;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Application management
|
|
111
|
+
*/
|
|
112
|
+
applications: {
|
|
113
|
+
/**
|
|
114
|
+
* List all applications
|
|
115
|
+
*
|
|
116
|
+
* @throws {NetworkError} on HTTP errors
|
|
117
|
+
* @throws {TimeoutError} on request timeout
|
|
118
|
+
*/
|
|
119
|
+
list: () => Promise<Application[]>;
|
|
120
|
+
/**
|
|
121
|
+
* Get application details
|
|
122
|
+
*
|
|
123
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
124
|
+
* @throws {NetworkError} on HTTP errors
|
|
125
|
+
* @throws {TimeoutError} on request timeout
|
|
126
|
+
*/
|
|
127
|
+
get: (appId: string) => Promise<Application>;
|
|
128
|
+
/**
|
|
129
|
+
* Upload application package (zip)
|
|
130
|
+
*
|
|
131
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
132
|
+
* @throws {ValidationError} if file format is invalid
|
|
133
|
+
* @throws {PermissionError} if user lacks permission to upload
|
|
134
|
+
* @throws {NetworkError} on HTTP errors
|
|
135
|
+
* @throws {TimeoutError} on request timeout
|
|
136
|
+
*/
|
|
137
|
+
upload: (appId: string, zipFile: Blob) => Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Download application package
|
|
140
|
+
*
|
|
141
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
142
|
+
* @throws {PermissionError} if user lacks permission to download
|
|
143
|
+
* @throws {NetworkError} on HTTP errors
|
|
144
|
+
* @throws {TimeoutError} on request timeout
|
|
145
|
+
*/
|
|
146
|
+
download: (appId: string) => Promise<Blob>;
|
|
147
|
+
/**
|
|
148
|
+
* List application files
|
|
149
|
+
*
|
|
150
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
151
|
+
* @throws {NetworkError} on HTTP errors
|
|
152
|
+
* @throws {TimeoutError} on request timeout
|
|
153
|
+
*/
|
|
154
|
+
getFiles: (appId: string) => Promise<FileEntry[]>;
|
|
155
|
+
/**
|
|
156
|
+
* Get specific application file
|
|
157
|
+
*
|
|
158
|
+
* @throws {EntityNotFoundError} if application or file doesn't exist
|
|
159
|
+
* @throws {NetworkError} on HTTP errors
|
|
160
|
+
* @throws {TimeoutError} on request timeout
|
|
161
|
+
*/
|
|
162
|
+
getFile: (appId: string, filePath: string) => Promise<string>;
|
|
163
|
+
/**
|
|
164
|
+
* List application configurations
|
|
165
|
+
*
|
|
166
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
167
|
+
* @throws {NetworkError} on HTTP errors
|
|
168
|
+
* @throws {TimeoutError} on request timeout
|
|
169
|
+
*/
|
|
170
|
+
getConfigurations: (appId: string) => Promise<Configuration[]>;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Generic HTTP request for custom OS endpoints
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* const data = await os.request<CustomResponse>({
|
|
177
|
+
* path: '/custom/endpoint',
|
|
178
|
+
* method: 'POST',
|
|
179
|
+
* body: { foo: 'bar' }
|
|
180
|
+
* });
|
|
181
|
+
*
|
|
182
|
+
* @throws {EntityNotFoundError} on 404 errors
|
|
183
|
+
* @throws {ValidationError} on 400 errors
|
|
184
|
+
* @throws {PermissionError} on 403 errors
|
|
185
|
+
* @throws {NetworkError} on HTTP errors
|
|
186
|
+
* @throws {TimeoutError} on request timeout
|
|
187
|
+
*/
|
|
188
|
+
request<T = unknown>(options: OsRequestOptions): Promise<T>;
|
|
189
|
+
}
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { EntityNotFoundError, NetworkError, PermissionError, SdkError, TimeoutError, ValidationError, } from '../errors.js';
|
|
2
|
+
const OS_BASE = '/os';
|
|
3
|
+
// Maps backend errors to typed SDK errors
|
|
4
|
+
function parseOsError(error, operation, context) {
|
|
5
|
+
let statusCode;
|
|
6
|
+
let errorMessage = error.message || 'Unknown error';
|
|
7
|
+
if (error.responsePayload && typeof error.responsePayload === 'object') {
|
|
8
|
+
statusCode = error.responsePayload.status || error.responsePayload.statusCode;
|
|
9
|
+
if (error.responsePayload.message) {
|
|
10
|
+
errorMessage = error.responsePayload.message;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (errorMessage.includes('timed out') || errorMessage.includes('timeout')) {
|
|
14
|
+
return new TimeoutError(operation, 10000);
|
|
15
|
+
}
|
|
16
|
+
if (statusCode) {
|
|
17
|
+
const fullContext = {
|
|
18
|
+
...context,
|
|
19
|
+
operation,
|
|
20
|
+
timestamp: Date.now(),
|
|
21
|
+
statusCode,
|
|
22
|
+
};
|
|
23
|
+
switch (statusCode) {
|
|
24
|
+
case 404:
|
|
25
|
+
return new EntityNotFoundError(context?.id || context?.appId || 'unknown');
|
|
26
|
+
case 400:
|
|
27
|
+
return new ValidationError(errorMessage, context?.field);
|
|
28
|
+
case 403:
|
|
29
|
+
return new PermissionError(errorMessage);
|
|
30
|
+
case 408:
|
|
31
|
+
return new TimeoutError(operation, 10000);
|
|
32
|
+
case 500:
|
|
33
|
+
case 502:
|
|
34
|
+
case 503:
|
|
35
|
+
return new NetworkError(errorMessage, statusCode);
|
|
36
|
+
default:
|
|
37
|
+
if (statusCode >= 400) {
|
|
38
|
+
return new NetworkError(errorMessage, statusCode);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return new SdkError(errorMessage, 'UNKNOWN_ERROR', statusCode, {
|
|
43
|
+
...context,
|
|
44
|
+
operation,
|
|
45
|
+
timestamp: Date.now(),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/** OS transport class providing OS/system operations */
|
|
49
|
+
export class OsTransport {
|
|
50
|
+
_request;
|
|
51
|
+
constructor(_request) {
|
|
52
|
+
this._request = _request;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* User profile operations
|
|
56
|
+
*/
|
|
57
|
+
profile = {
|
|
58
|
+
/**
|
|
59
|
+
* Get current user profile
|
|
60
|
+
*
|
|
61
|
+
* @throws {NetworkError} on HTTP errors
|
|
62
|
+
* @throws {TimeoutError} on request timeout
|
|
63
|
+
*/
|
|
64
|
+
get: async () => {
|
|
65
|
+
try {
|
|
66
|
+
return await this._request({
|
|
67
|
+
path: `${OS_BASE}/me/profile`,
|
|
68
|
+
method: 'GET',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw parseOsError(error, 'os.profile.get');
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Get user avatar image
|
|
77
|
+
*
|
|
78
|
+
* @throws {EntityNotFoundError} if avatar doesn't exist
|
|
79
|
+
* @throws {NetworkError} on HTTP errors
|
|
80
|
+
* @throws {TimeoutError} on request timeout
|
|
81
|
+
*/
|
|
82
|
+
getAvatar: async () => {
|
|
83
|
+
try {
|
|
84
|
+
return await this._request({
|
|
85
|
+
path: `${OS_BASE}/me/avatar`,
|
|
86
|
+
method: 'GET',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
throw parseOsError(error, 'os.profile.getAvatar');
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Upload user avatar
|
|
95
|
+
*
|
|
96
|
+
* @throws {ValidationError} if image format is invalid
|
|
97
|
+
* @throws {NetworkError} on HTTP errors
|
|
98
|
+
* @throws {TimeoutError} on request timeout
|
|
99
|
+
*/
|
|
100
|
+
setAvatar: async (image) => {
|
|
101
|
+
try {
|
|
102
|
+
await this._request({
|
|
103
|
+
path: `${OS_BASE}/me/avatar`,
|
|
104
|
+
method: 'POST',
|
|
105
|
+
body: image,
|
|
106
|
+
contentType: 'application/octet-stream',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw parseOsError(error, 'os.profile.setAvatar');
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* Get accessible instances
|
|
115
|
+
*
|
|
116
|
+
* @throws {NetworkError} on HTTP errors
|
|
117
|
+
* @throws {TimeoutError} on request timeout
|
|
118
|
+
*/
|
|
119
|
+
getInstances: async () => {
|
|
120
|
+
try {
|
|
121
|
+
return await this._request({
|
|
122
|
+
path: `${OS_BASE}/me/instances`,
|
|
123
|
+
method: 'GET',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
throw parseOsError(error, 'os.profile.getInstances');
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Organization structure operations
|
|
133
|
+
*/
|
|
134
|
+
organization = {
|
|
135
|
+
/**
|
|
136
|
+
* Get full organization hierarchy
|
|
137
|
+
*
|
|
138
|
+
* @throws {NetworkError} on HTTP errors
|
|
139
|
+
* @throws {TimeoutError} on request timeout
|
|
140
|
+
*/
|
|
141
|
+
getStructure: async () => {
|
|
142
|
+
try {
|
|
143
|
+
return await this._request({
|
|
144
|
+
path: `${OS_BASE}/organization/structure`,
|
|
145
|
+
method: 'GET',
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
throw parseOsError(error, 'os.organization.getStructure');
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
/**
|
|
153
|
+
* Create organizational unit
|
|
154
|
+
*
|
|
155
|
+
* @throws {ValidationError} if data is invalid or missing required fields
|
|
156
|
+
* @throws {PermissionError} if user lacks permission to create units
|
|
157
|
+
* @throws {NetworkError} on HTTP errors
|
|
158
|
+
* @throws {TimeoutError} on request timeout
|
|
159
|
+
*/
|
|
160
|
+
createUnit: async (data) => {
|
|
161
|
+
try {
|
|
162
|
+
return await this._request({
|
|
163
|
+
path: `${OS_BASE}/organization/units`,
|
|
164
|
+
method: 'POST',
|
|
165
|
+
body: data,
|
|
166
|
+
contentType: 'application/json',
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
throw parseOsError(error, 'os.organization.createUnit', { name: data.name });
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
/**
|
|
174
|
+
* Update organizational unit
|
|
175
|
+
*
|
|
176
|
+
* @throws {EntityNotFoundError} if unit doesn't exist
|
|
177
|
+
* @throws {ValidationError} if data is invalid
|
|
178
|
+
* @throws {PermissionError} if user lacks permission to update unit
|
|
179
|
+
* @throws {NetworkError} on HTTP errors
|
|
180
|
+
* @throws {TimeoutError} on request timeout
|
|
181
|
+
*/
|
|
182
|
+
updateUnit: async (id, data) => {
|
|
183
|
+
try {
|
|
184
|
+
return await this._request({
|
|
185
|
+
path: `${OS_BASE}/organization/units/${encodeURIComponent(id)}`,
|
|
186
|
+
method: 'PATCH',
|
|
187
|
+
body: data,
|
|
188
|
+
contentType: 'application/json',
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
throw parseOsError(error, 'os.organization.updateUnit', { id });
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
/**
|
|
196
|
+
* Create organization member
|
|
197
|
+
*
|
|
198
|
+
* @throws {ValidationError} if data is invalid or missing required fields
|
|
199
|
+
* @throws {PermissionError} if user lacks permission to create members
|
|
200
|
+
* @throws {NetworkError} on HTTP errors
|
|
201
|
+
* @throws {TimeoutError} on request timeout
|
|
202
|
+
*/
|
|
203
|
+
createMember: async (data) => {
|
|
204
|
+
try {
|
|
205
|
+
return await this._request({
|
|
206
|
+
path: `${OS_BASE}/organization/members`,
|
|
207
|
+
method: 'POST',
|
|
208
|
+
body: data,
|
|
209
|
+
contentType: 'application/json',
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
throw parseOsError(error, 'os.organization.createMember', { email: data.mailAddress });
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
/**
|
|
217
|
+
* Update organization member
|
|
218
|
+
*
|
|
219
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
220
|
+
* @throws {ValidationError} if data is invalid
|
|
221
|
+
* @throws {PermissionError} if user lacks permission to update member
|
|
222
|
+
* @throws {NetworkError} on HTTP errors
|
|
223
|
+
* @throws {TimeoutError} on request timeout
|
|
224
|
+
*/
|
|
225
|
+
updateMember: async (id, data) => {
|
|
226
|
+
try {
|
|
227
|
+
return await this._request({
|
|
228
|
+
path: `${OS_BASE}/organization/members/${encodeURIComponent(id)}`,
|
|
229
|
+
method: 'PATCH',
|
|
230
|
+
body: data,
|
|
231
|
+
contentType: 'application/json',
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
throw parseOsError(error, 'os.organization.updateMember', { id });
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
/**
|
|
239
|
+
* Delete organization member
|
|
240
|
+
*
|
|
241
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
242
|
+
* @throws {PermissionError} if user lacks permission to delete member
|
|
243
|
+
* @throws {NetworkError} on HTTP errors
|
|
244
|
+
* @throws {TimeoutError} on request timeout
|
|
245
|
+
*/
|
|
246
|
+
deleteMember: async (id) => {
|
|
247
|
+
try {
|
|
248
|
+
await this._request({
|
|
249
|
+
path: `${OS_BASE}/organization/members/${encodeURIComponent(id)}`,
|
|
250
|
+
method: 'DELETE',
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
throw parseOsError(error, 'os.organization.deleteMember', { id });
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
/**
|
|
258
|
+
* Send invitation email to member
|
|
259
|
+
*
|
|
260
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
261
|
+
* @throws {ValidationError} if member email is invalid
|
|
262
|
+
* @throws {NetworkError} on HTTP errors
|
|
263
|
+
* @throws {TimeoutError} on request timeout
|
|
264
|
+
*/
|
|
265
|
+
inviteMember: async (id) => {
|
|
266
|
+
try {
|
|
267
|
+
await this._request({
|
|
268
|
+
path: `${OS_BASE}/organization/members/${encodeURIComponent(id)}/invite`,
|
|
269
|
+
method: 'POST',
|
|
270
|
+
contentType: 'application/json',
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
throw parseOsError(error, 'os.organization.inviteMember', { id });
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* Application management
|
|
280
|
+
*/
|
|
281
|
+
applications = {
|
|
282
|
+
/**
|
|
283
|
+
* List all applications
|
|
284
|
+
*
|
|
285
|
+
* @throws {NetworkError} on HTTP errors
|
|
286
|
+
* @throws {TimeoutError} on request timeout
|
|
287
|
+
*/
|
|
288
|
+
list: async () => {
|
|
289
|
+
try {
|
|
290
|
+
return await this._request({
|
|
291
|
+
path: `${OS_BASE}/applications`,
|
|
292
|
+
method: 'GET',
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
throw parseOsError(error, 'os.applications.list');
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
/**
|
|
300
|
+
* Get application details
|
|
301
|
+
*
|
|
302
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
303
|
+
* @throws {NetworkError} on HTTP errors
|
|
304
|
+
* @throws {TimeoutError} on request timeout
|
|
305
|
+
*/
|
|
306
|
+
get: async (appId) => {
|
|
307
|
+
try {
|
|
308
|
+
return await this._request({
|
|
309
|
+
path: `${OS_BASE}/applications/${encodeURIComponent(appId)}`,
|
|
310
|
+
method: 'GET',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
throw parseOsError(error, 'os.applications.get', { appId });
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
/**
|
|
318
|
+
* Upload application package (zip)
|
|
319
|
+
*
|
|
320
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
321
|
+
* @throws {ValidationError} if file format is invalid
|
|
322
|
+
* @throws {PermissionError} if user lacks permission to upload
|
|
323
|
+
* @throws {NetworkError} on HTTP errors
|
|
324
|
+
* @throws {TimeoutError} on request timeout
|
|
325
|
+
*/
|
|
326
|
+
upload: async (appId, zipFile) => {
|
|
327
|
+
try {
|
|
328
|
+
await this._request({
|
|
329
|
+
path: `${OS_BASE}/applications/${encodeURIComponent(appId)}/upload`,
|
|
330
|
+
method: 'POST',
|
|
331
|
+
body: zipFile,
|
|
332
|
+
contentType: 'application/zip',
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
throw parseOsError(error, 'os.applications.upload', { appId });
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
/**
|
|
340
|
+
* Download application package
|
|
341
|
+
*
|
|
342
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
343
|
+
* @throws {PermissionError} if user lacks permission to download
|
|
344
|
+
* @throws {NetworkError} on HTTP errors
|
|
345
|
+
* @throws {TimeoutError} on request timeout
|
|
346
|
+
*/
|
|
347
|
+
download: async (appId) => {
|
|
348
|
+
try {
|
|
349
|
+
return await this._request({
|
|
350
|
+
path: `${OS_BASE}/applications/${encodeURIComponent(appId)}/download`,
|
|
351
|
+
method: 'GET',
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
throw parseOsError(error, 'os.applications.download', { appId });
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
/**
|
|
359
|
+
* List application files
|
|
360
|
+
*
|
|
361
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
362
|
+
* @throws {NetworkError} on HTTP errors
|
|
363
|
+
* @throws {TimeoutError} on request timeout
|
|
364
|
+
*/
|
|
365
|
+
getFiles: async (appId) => {
|
|
366
|
+
try {
|
|
367
|
+
return await this._request({
|
|
368
|
+
path: `${OS_BASE}/applications/${encodeURIComponent(appId)}/files`,
|
|
369
|
+
method: 'GET',
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
throw parseOsError(error, 'os.applications.getFiles', { appId });
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
/**
|
|
377
|
+
* Get specific application file
|
|
378
|
+
*
|
|
379
|
+
* @throws {EntityNotFoundError} if application or file doesn't exist
|
|
380
|
+
* @throws {NetworkError} on HTTP errors
|
|
381
|
+
* @throws {TimeoutError} on request timeout
|
|
382
|
+
*/
|
|
383
|
+
getFile: async (appId, filePath) => {
|
|
384
|
+
try {
|
|
385
|
+
return await this._request({
|
|
386
|
+
path: `${OS_BASE}/applications/${encodeURIComponent(appId)}/files/${encodeURIComponent(filePath)}`,
|
|
387
|
+
method: 'GET',
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
catch (error) {
|
|
391
|
+
throw parseOsError(error, 'os.applications.getFile', { appId, filePath });
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
/**
|
|
395
|
+
* List application configurations
|
|
396
|
+
*
|
|
397
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
398
|
+
* @throws {NetworkError} on HTTP errors
|
|
399
|
+
* @throws {TimeoutError} on request timeout
|
|
400
|
+
*/
|
|
401
|
+
getConfigurations: async (appId) => {
|
|
402
|
+
try {
|
|
403
|
+
return await this._request({
|
|
404
|
+
path: `${OS_BASE}/applications/${encodeURIComponent(appId)}/configurations`,
|
|
405
|
+
method: 'GET',
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
throw parseOsError(error, 'os.applications.getConfigurations', { appId });
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* Generic HTTP request for custom OS endpoints
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* const data = await os.request<CustomResponse>({
|
|
418
|
+
* path: '/custom/endpoint',
|
|
419
|
+
* method: 'POST',
|
|
420
|
+
* body: { foo: 'bar' }
|
|
421
|
+
* });
|
|
422
|
+
*
|
|
423
|
+
* @throws {EntityNotFoundError} on 404 errors
|
|
424
|
+
* @throws {ValidationError} on 400 errors
|
|
425
|
+
* @throws {PermissionError} on 403 errors
|
|
426
|
+
* @throws {NetworkError} on HTTP errors
|
|
427
|
+
* @throws {TimeoutError} on request timeout
|
|
428
|
+
*/
|
|
429
|
+
async request(options) {
|
|
430
|
+
try {
|
|
431
|
+
return await this._request({
|
|
432
|
+
path: `${OS_BASE}${options.path}`,
|
|
433
|
+
method: options.method || 'GET',
|
|
434
|
+
body: options.body,
|
|
435
|
+
contentType: options.contentType,
|
|
436
|
+
scopeId: options.scopeId,
|
|
437
|
+
scopePolicy: options.scopePolicy,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
throw parseOsError(error, 'os.request', { path: options.path, method: options.method });
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|