@bardioc/app-sdk 1.0.2 → 1.0.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/README.md +2 -0
- package/dist/api/request.d.ts +4 -4
- package/dist/contract-matrix.d.ts +148 -0
- package/dist/contract-matrix.js +150 -0
- package/dist/contract.d.ts +16 -16
- 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-idb.d.ts +4 -4
- package/dist/dev-session-cli.d.ts +34 -0
- package/dist/dev-session-cli.js +125 -0
- package/dist/host-bridge.d.ts +3 -0
- package/dist/host-bridge.js +318 -0
- package/dist/react.js +3 -2
- package/dist/transports/backend-transport.d.ts +24 -0
- package/dist/transports/backend-transport.js +54 -0
- package/dist/transports/graph-transport.d.ts +241 -0
- package/dist/transports/graph-transport.js +616 -0
- package/dist/transports/os-transport.d.ts +190 -0
- package/dist/transports/os-transport.js +444 -0
- package/dist/vite.js +25 -11
- package/package.json +4 -4
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import type { Application, Configuration, CreateMemberInput, CreateUnitInput, FileEntry, InstanceList, OrgMember, OrgStructure, OrgUnit, OsRequestOptions, SdkTransportPayload, UpdateMemberInput, UpdateUnitInput, UserProfile } from '../types.js';
|
|
2
|
+
export declare function parseOsError(error: any, operation: string, context?: Record<string, unknown>): Error;
|
|
3
|
+
/** OS transport class providing OS/system operations */
|
|
4
|
+
export declare class OsTransport {
|
|
5
|
+
private readonly _request;
|
|
6
|
+
constructor(_request: <T = unknown>(payload: SdkTransportPayload) => Promise<T>);
|
|
7
|
+
/**
|
|
8
|
+
* User profile operations
|
|
9
|
+
*/
|
|
10
|
+
profile: {
|
|
11
|
+
/**
|
|
12
|
+
* Get current user profile
|
|
13
|
+
*
|
|
14
|
+
* @throws {NetworkError} on HTTP errors
|
|
15
|
+
* @throws {TimeoutError} on request timeout
|
|
16
|
+
*/
|
|
17
|
+
get: () => Promise<UserProfile>;
|
|
18
|
+
/**
|
|
19
|
+
* Get user avatar image
|
|
20
|
+
*
|
|
21
|
+
* @throws {EntityNotFoundError} if avatar doesn't exist
|
|
22
|
+
* @throws {NetworkError} on HTTP errors
|
|
23
|
+
* @throws {TimeoutError} on request timeout
|
|
24
|
+
*/
|
|
25
|
+
getAvatar: () => Promise<Blob>;
|
|
26
|
+
/**
|
|
27
|
+
* Upload user avatar
|
|
28
|
+
*
|
|
29
|
+
* @throws {ValidationError} if image format is invalid
|
|
30
|
+
* @throws {NetworkError} on HTTP errors
|
|
31
|
+
* @throws {TimeoutError} on request timeout
|
|
32
|
+
*/
|
|
33
|
+
setAvatar: (image: Blob) => Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Get accessible instances
|
|
36
|
+
*
|
|
37
|
+
* @throws {NetworkError} on HTTP errors
|
|
38
|
+
* @throws {TimeoutError} on request timeout
|
|
39
|
+
*/
|
|
40
|
+
getInstances: () => Promise<InstanceList>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Organization structure operations
|
|
44
|
+
*/
|
|
45
|
+
organization: {
|
|
46
|
+
/**
|
|
47
|
+
* Get full organization hierarchy
|
|
48
|
+
*
|
|
49
|
+
* @throws {NetworkError} on HTTP errors
|
|
50
|
+
* @throws {TimeoutError} on request timeout
|
|
51
|
+
*/
|
|
52
|
+
getStructure: () => Promise<OrgStructure>;
|
|
53
|
+
/**
|
|
54
|
+
* Create organizational unit
|
|
55
|
+
*
|
|
56
|
+
* @throws {ValidationError} if data is invalid or missing required fields
|
|
57
|
+
* @throws {PermissionError} if user lacks permission to create units
|
|
58
|
+
* @throws {NetworkError} on HTTP errors
|
|
59
|
+
* @throws {TimeoutError} on request timeout
|
|
60
|
+
*/
|
|
61
|
+
createUnit: (data: CreateUnitInput) => Promise<OrgUnit>;
|
|
62
|
+
/**
|
|
63
|
+
* Update organizational unit
|
|
64
|
+
*
|
|
65
|
+
* @throws {EntityNotFoundError} if unit doesn't exist
|
|
66
|
+
* @throws {ValidationError} if data is invalid
|
|
67
|
+
* @throws {PermissionError} if user lacks permission to update unit
|
|
68
|
+
* @throws {NetworkError} on HTTP errors
|
|
69
|
+
* @throws {TimeoutError} on request timeout
|
|
70
|
+
*/
|
|
71
|
+
updateUnit: (id: string, data: UpdateUnitInput) => Promise<OrgUnit>;
|
|
72
|
+
/**
|
|
73
|
+
* Create organization member
|
|
74
|
+
*
|
|
75
|
+
* @throws {ValidationError} if data is invalid or missing required fields
|
|
76
|
+
* @throws {PermissionError} if user lacks permission to create members
|
|
77
|
+
* @throws {NetworkError} on HTTP errors
|
|
78
|
+
* @throws {TimeoutError} on request timeout
|
|
79
|
+
*/
|
|
80
|
+
createMember: (data: CreateMemberInput) => Promise<OrgMember>;
|
|
81
|
+
/**
|
|
82
|
+
* Update organization member
|
|
83
|
+
*
|
|
84
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
85
|
+
* @throws {ValidationError} if data is invalid
|
|
86
|
+
* @throws {PermissionError} if user lacks permission to update member
|
|
87
|
+
* @throws {NetworkError} on HTTP errors
|
|
88
|
+
* @throws {TimeoutError} on request timeout
|
|
89
|
+
*/
|
|
90
|
+
updateMember: (id: string, data: UpdateMemberInput) => Promise<OrgMember>;
|
|
91
|
+
/**
|
|
92
|
+
* Delete organization member
|
|
93
|
+
*
|
|
94
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
95
|
+
* @throws {PermissionError} if user lacks permission to delete member
|
|
96
|
+
* @throws {NetworkError} on HTTP errors
|
|
97
|
+
* @throws {TimeoutError} on request timeout
|
|
98
|
+
*/
|
|
99
|
+
deleteMember: (id: string) => Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Send invitation email to member
|
|
102
|
+
*
|
|
103
|
+
* @throws {EntityNotFoundError} if member doesn't exist
|
|
104
|
+
* @throws {ValidationError} if member email is invalid
|
|
105
|
+
* @throws {NetworkError} on HTTP errors
|
|
106
|
+
* @throws {TimeoutError} on request timeout
|
|
107
|
+
*/
|
|
108
|
+
inviteMember: (id: string) => Promise<void>;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Application management
|
|
112
|
+
*/
|
|
113
|
+
applications: {
|
|
114
|
+
/**
|
|
115
|
+
* List all applications
|
|
116
|
+
*
|
|
117
|
+
* @throws {NetworkError} on HTTP errors
|
|
118
|
+
* @throws {TimeoutError} on request timeout
|
|
119
|
+
*/
|
|
120
|
+
list: () => Promise<Application[]>;
|
|
121
|
+
/**
|
|
122
|
+
* Get application details
|
|
123
|
+
*
|
|
124
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
125
|
+
* @throws {NetworkError} on HTTP errors
|
|
126
|
+
* @throws {TimeoutError} on request timeout
|
|
127
|
+
*/
|
|
128
|
+
get: (appId: string) => Promise<Application>;
|
|
129
|
+
/**
|
|
130
|
+
* Upload application package (zip)
|
|
131
|
+
*
|
|
132
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
133
|
+
* @throws {ValidationError} if file format is invalid
|
|
134
|
+
* @throws {PermissionError} if user lacks permission to upload
|
|
135
|
+
* @throws {NetworkError} on HTTP errors
|
|
136
|
+
* @throws {TimeoutError} on request timeout
|
|
137
|
+
*/
|
|
138
|
+
upload: (appId: string, zipFile: Blob) => Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Download application package
|
|
141
|
+
*
|
|
142
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
143
|
+
* @throws {PermissionError} if user lacks permission to download
|
|
144
|
+
* @throws {NetworkError} on HTTP errors
|
|
145
|
+
* @throws {TimeoutError} on request timeout
|
|
146
|
+
*/
|
|
147
|
+
download: (appId: string) => Promise<Blob>;
|
|
148
|
+
/**
|
|
149
|
+
* List application files
|
|
150
|
+
*
|
|
151
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
152
|
+
* @throws {NetworkError} on HTTP errors
|
|
153
|
+
* @throws {TimeoutError} on request timeout
|
|
154
|
+
*/
|
|
155
|
+
getFiles: (appId: string) => Promise<FileEntry[]>;
|
|
156
|
+
/**
|
|
157
|
+
* Get specific application file
|
|
158
|
+
*
|
|
159
|
+
* @throws {EntityNotFoundError} if application or file doesn't exist
|
|
160
|
+
* @throws {NetworkError} on HTTP errors
|
|
161
|
+
* @throws {TimeoutError} on request timeout
|
|
162
|
+
*/
|
|
163
|
+
getFile: (appId: string, filePath: string) => Promise<string>;
|
|
164
|
+
/**
|
|
165
|
+
* List application configurations
|
|
166
|
+
*
|
|
167
|
+
* @throws {EntityNotFoundError} if application doesn't exist
|
|
168
|
+
* @throws {NetworkError} on HTTP errors
|
|
169
|
+
* @throws {TimeoutError} on request timeout
|
|
170
|
+
*/
|
|
171
|
+
getConfigurations: (appId: string) => Promise<Configuration[]>;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Generic HTTP request for custom OS endpoints
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* const data = await os.request<CustomResponse>({
|
|
178
|
+
* path: '/custom/endpoint',
|
|
179
|
+
* method: 'POST',
|
|
180
|
+
* body: { foo: 'bar' }
|
|
181
|
+
* });
|
|
182
|
+
*
|
|
183
|
+
* @throws {EntityNotFoundError} on 404 errors
|
|
184
|
+
* @throws {ValidationError} on 400 errors
|
|
185
|
+
* @throws {PermissionError} on 403 errors
|
|
186
|
+
* @throws {NetworkError} on HTTP errors
|
|
187
|
+
* @throws {TimeoutError} on request timeout
|
|
188
|
+
*/
|
|
189
|
+
request<T = unknown>(options: OsRequestOptions): Promise<T>;
|
|
190
|
+
}
|
|
@@ -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
|
+
export 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
|
+
}
|
package/dist/vite.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
3
3
|
import { resolve, sep } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { resolveDevAuthEnv } from './dev-auth-env.js';
|
|
6
|
-
import { createDevAuthProxyHandler } from './dev-proxy.js';
|
|
6
|
+
import { createDevAuthProxyHandler, sendJson } from './dev-proxy.js';
|
|
7
7
|
import { MANIFEST_FILENAME, validateManifest } from './manifest.js';
|
|
8
8
|
function devProxy(opts) {
|
|
9
9
|
const { port } = opts;
|
|
@@ -26,7 +26,13 @@ function devProxy(opts) {
|
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
console.log(`[bardioc] Dev server ready: http://localhost:${port}`);
|
|
29
|
-
|
|
29
|
+
const env = resolveDevAuthEnv({
|
|
30
|
+
envDir: server.config.envDir ?? server.config.root,
|
|
31
|
+
mode: server.config.mode,
|
|
32
|
+
});
|
|
33
|
+
if (!env.devSecret || !env.apiBaseUrl) {
|
|
34
|
+
console.log(`[bardioc] For standalone dev auth, set DEV_SECRET and API_BASE_URL in .env.`);
|
|
35
|
+
}
|
|
30
36
|
console.log(`[bardioc] App Name: ${opts.appName || manifest.id}`);
|
|
31
37
|
console.log(`[bardioc] URL: http://localhost:${port}`);
|
|
32
38
|
});
|
|
@@ -136,20 +142,23 @@ export function bardiocDevAuth(options) {
|
|
|
136
142
|
envDir: server.config.envDir ?? server.config.root,
|
|
137
143
|
mode: server.config.mode,
|
|
138
144
|
});
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
if (env.devSecret && env.apiBaseUrl) {
|
|
146
|
+
proxyOptions = {
|
|
147
|
+
apiBaseUrl: env.apiBaseUrl,
|
|
148
|
+
devSecret: env.devSecret,
|
|
149
|
+
};
|
|
142
150
|
}
|
|
143
|
-
proxyOptions = {
|
|
144
|
-
apiBaseUrl: env.apiBaseUrl,
|
|
145
|
-
devSecret: env.devSecret,
|
|
146
|
-
};
|
|
147
151
|
}
|
|
148
|
-
const handler = createDevAuthProxyHandler(proxyOptions);
|
|
152
|
+
const handler = proxyOptions ? createDevAuthProxyHandler(proxyOptions) : null;
|
|
149
153
|
const basePath = server.config.base.endsWith('/')
|
|
150
154
|
? server.config.base.slice(0, -1)
|
|
151
155
|
: server.config.base;
|
|
152
|
-
|
|
156
|
+
if (proxyOptions) {
|
|
157
|
+
server.config.logger.info(`[bardioc-dev-auth] proxying /rest/* → ${proxyOptions.apiBaseUrl} for appName="${options.appName}"`);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
server.config.logger.warn(`[bardioc-dev-auth] DEV_SECRET and API_BASE_URL are required for dev auth — disabled for appName="${options.appName}".`);
|
|
161
|
+
}
|
|
153
162
|
server.middlewares.use(async (req, res, next) => {
|
|
154
163
|
const originalUrl = req.url ?? '';
|
|
155
164
|
const parsed = new URL(originalUrl, 'http://localhost');
|
|
@@ -161,6 +170,11 @@ export function bardiocDevAuth(options) {
|
|
|
161
170
|
next();
|
|
162
171
|
return;
|
|
163
172
|
}
|
|
173
|
+
// Answer instead of falling through: Vite's SPA fallback would serve index.html as a 200.
|
|
174
|
+
if (!handler) {
|
|
175
|
+
sendJson(res, 503, { error: 'dev_auth_disabled' });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
164
178
|
try {
|
|
165
179
|
req.url = `${routePath}${parsed.search}`;
|
|
166
180
|
await handler(req, res);
|