@meshtrade/api-web 1.30.2 → 1.32.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/dist/meshtrade/compliance/client/v1/client_pb.d.ts +17 -9
- package/dist/meshtrade/compliance/client/v1/client_pb.js +1 -1
- package/dist/meshtrade/compliance/client/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/compliance/client/v1/service_web_meshts.js +118 -28
- package/dist/meshtrade/config/index.d.ts +160 -0
- package/dist/meshtrade/config/index.js +210 -0
- package/dist/meshtrade/iam/api_user/v1/api_user_pb.d.ts +12 -4
- package/dist/meshtrade/iam/api_user/v1/api_user_pb.js +1 -1
- package/dist/meshtrade/iam/api_user/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/iam/api_user/v1/service_web_meshts.js +167 -35
- package/dist/meshtrade/iam/group/v1/group_pb.d.ts +8 -0
- package/dist/meshtrade/iam/group/v1/group_pb.js +1 -1
- package/dist/meshtrade/iam/group/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/iam/group/v1/service_web_meshts.js +134 -30
- package/dist/meshtrade/iam/user/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/iam/user/v1/service_web_meshts.js +159 -34
- package/dist/meshtrade/iam/user/v1/user_pb.d.ts +10 -2
- package/dist/meshtrade/iam/user/v1/user_pb.js +1 -1
- package/dist/meshtrade/{common/connectInterceptors.d.ts → interceptors/index.d.ts} +23 -17
- package/dist/meshtrade/{common/connectInterceptors.js → interceptors/index.js} +61 -24
- package/dist/meshtrade/ledger/transaction/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/ledger/transaction/v1/service_web_meshts.js +110 -27
- package/dist/meshtrade/market_data/price/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/market_data/price/v1/service_web_meshts.js +102 -26
- package/dist/meshtrade/reporting/account_report/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/reporting/account_report/v1/service_web_meshts.js +110 -27
- package/dist/meshtrade/studio/instrument/v1/instrument_pb.d.ts +8 -0
- package/dist/meshtrade/studio/instrument/v1/instrument_pb.js +1 -1
- package/dist/meshtrade/trading/limit_order/v1/limit_order_pb.d.ts +16 -8
- package/dist/meshtrade/trading/limit_order/v1/limit_order_pb.js +1 -1
- package/dist/meshtrade/trading/limit_order/v1/service_pb.js +1 -1
- package/dist/meshtrade/trading/limit_order/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/trading/limit_order/v1/service_web_meshts.js +151 -33
- package/dist/meshtrade/trading/market_order/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/trading/market_order/v1/service_web_meshts.js +102 -26
- package/dist/meshtrade/wallet/account/v1/account_pb.d.ts +8 -0
- package/dist/meshtrade/wallet/account/v1/account_pb.js +1 -1
- package/dist/meshtrade/wallet/account/v1/service_web_meshts.d.ts +62 -7
- package/dist/meshtrade/wallet/account/v1/service_web_meshts.js +167 -35
- package/package.json +19 -2
- package/dist/meshtrade/common/config.d.ts +0 -7
- package/dist/meshtrade/common/config.js +0 -9
- package/dist/meshtrade/common/validation.d.ts +0 -62
- package/dist/meshtrade/common/validation.js +0 -77
|
@@ -7,28 +7,87 @@ exports.UserServiceWeb = void 0;
|
|
|
7
7
|
const connect_1 = require("@connectrpc/connect");
|
|
8
8
|
const connect_web_1 = require("@connectrpc/connect-web");
|
|
9
9
|
const service_pb_1 = require("./service_pb");
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
10
|
+
const service_pb_2 = require("./service_pb");
|
|
11
|
+
const config_1 = require("../../../config");
|
|
12
|
+
const protovalidate_1 = require("@bufbuild/protovalidate");
|
|
13
|
+
const interceptors_1 = require("../../../interceptors");
|
|
13
14
|
/**
|
|
14
15
|
* Web client for interacting with the meshtrade.iam.user.v1 user v1 API resource service.
|
|
15
|
-
* Uses Connect-ES with gRPC-Web transport for browser-
|
|
16
|
+
* Uses Connect-ES with gRPC-Web transport for browser-based communication.
|
|
17
|
+
*
|
|
18
|
+
* Supports flexible authentication modes using functional options pattern:
|
|
19
|
+
*
|
|
20
|
+
* 1. **No Authentication** (public APIs):
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const client = new UserServiceWeb(
|
|
23
|
+
* WithServerUrl("http://localhost:10000")
|
|
24
|
+
* );
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* 2. **API Key Authentication** (backend services):
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const client = new UserServiceWeb(
|
|
30
|
+
* WithAPIKey("your-api-key"),
|
|
31
|
+
* WithGroup("groups/01ARZ3NDEKTSV4YWVF8F5BH32"),
|
|
32
|
+
* WithServerUrl("https://api.example.com")
|
|
33
|
+
* );
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* 3. **JWT Token Authentication** (Next.js frontend with user session):
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const client = new UserServiceWeb(
|
|
39
|
+
* WithJWTAccessToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."),
|
|
40
|
+
* WithServerUrl("https://api.example.com")
|
|
41
|
+
* );
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* 4. **JWT with Group Context** (user session with specific group):
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const client = new UserServiceWeb(
|
|
47
|
+
* WithJWTAccessToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."),
|
|
48
|
+
* WithGroup("groups/01ARZ3NDEKTSV4YWVF8F5BH32"),
|
|
49
|
+
* WithServerUrl("https://api.example.com")
|
|
50
|
+
* );
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* Available options:
|
|
54
|
+
* - `WithAPIKey(key)` - API key authentication (mutually exclusive with JWT)
|
|
55
|
+
* - `WithJWTAccessToken(token)` - JWT authentication (mutually exclusive with API key)
|
|
56
|
+
* - `WithGroup(group)` - Group context (optional, works with both auth modes)
|
|
57
|
+
* - `WithServerUrl(url)` - Custom server URL (optional, defaults to production)
|
|
16
58
|
*/
|
|
17
59
|
class UserServiceWeb {
|
|
18
60
|
/**
|
|
19
61
|
* Constructs an instance of UserServiceWeb.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
62
|
+
*
|
|
63
|
+
* Uses functional options pattern for flexible configuration:
|
|
64
|
+
* - `WithAPIKey(key)` - API key authentication
|
|
65
|
+
* - `WithJWTAccessToken(token)` - JWT authentication
|
|
66
|
+
* - `WithGroup(group)` - Group context (optional)
|
|
67
|
+
* - `WithServerUrl(url)` - Custom server URL (optional)
|
|
68
|
+
*
|
|
69
|
+
* @param {...ClientOption} opts - Variable number of configuration options
|
|
22
70
|
*/
|
|
23
|
-
constructor(
|
|
24
|
-
|
|
25
|
-
this.
|
|
26
|
-
//
|
|
71
|
+
constructor(...opts) {
|
|
72
|
+
// Build configuration from options
|
|
73
|
+
this._config = (0, config_1.buildConfigFromOptions)(...opts);
|
|
74
|
+
// Initialize validator for request validation
|
|
75
|
+
this._validator = (0, protovalidate_1.createValidator)();
|
|
76
|
+
this._interceptors = [];
|
|
77
|
+
this._interceptors.push((0, interceptors_1.createLoggingInterceptor)());
|
|
78
|
+
if (this._config.apiKey) {
|
|
79
|
+
this._interceptors.push((0, interceptors_1.createApiKeyInterceptor)(this._config.apiKey));
|
|
80
|
+
}
|
|
81
|
+
if (this._config.jwtToken) {
|
|
82
|
+
this._interceptors.push((0, interceptors_1.createJwtInterceptor)(this._config.jwtToken));
|
|
83
|
+
}
|
|
84
|
+
if (this._config.group) {
|
|
85
|
+
this._interceptors.push((0, interceptors_1.createGroupInterceptor)(this._config.group));
|
|
86
|
+
}
|
|
87
|
+
// Create the gRPC-Web transport for browser with interceptors
|
|
27
88
|
const transport = (0, connect_web_1.createGrpcWebTransport)({
|
|
28
89
|
baseUrl: this._config.apiServerURL,
|
|
29
90
|
interceptors: this._interceptors,
|
|
30
|
-
// Enable credentials (cookies) for cross-origin requests
|
|
31
|
-
fetch: (input, init) => globalThis.fetch(input, { ...init, credentials: 'include' }),
|
|
32
91
|
});
|
|
33
92
|
// Construct the Connect-ES client
|
|
34
93
|
this._client = (0, connect_1.createClient)(service_pb_1.UserService, transport);
|
|
@@ -37,26 +96,36 @@ class UserServiceWeb {
|
|
|
37
96
|
* Returns a new client instance configured to send the specified group
|
|
38
97
|
* resource name in the request headers for subsequent API calls.
|
|
39
98
|
*
|
|
99
|
+
* This method creates a new client with the same authentication configuration
|
|
100
|
+
* but with the group context updated to the specified value.
|
|
101
|
+
*
|
|
102
|
+
* **Compatibility**: Works with all authentication modes:
|
|
103
|
+
* - **API key auth**: Creates new client with API key + new group
|
|
104
|
+
* - **JWT auth**: Creates new client with JWT + new group
|
|
105
|
+
* - **No auth**: Creates new client with standalone group interceptor
|
|
106
|
+
*
|
|
40
107
|
* @param {string} group - The operating group context to inject into the request
|
|
41
108
|
* in the format `groups/{ulid}` where {ulid} is a 26-character ULID.
|
|
42
109
|
* Example: 'groups/01ARZ3NDEKTSV4YWVF8F5BH32'
|
|
43
110
|
* @returns {UserServiceWeb} A new, configured instance of the client.
|
|
44
|
-
* @throws {Error} If the group format is invalid
|
|
111
|
+
* @throws {Error} If the group format is invalid
|
|
45
112
|
*/
|
|
46
113
|
withGroup(group) {
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
114
|
+
// Build new options array with existing auth and updated group
|
|
115
|
+
const newOpts = [];
|
|
116
|
+
// Add server URL
|
|
117
|
+
newOpts.push((0, config_1.WithServerUrl)(this._config.apiServerURL));
|
|
118
|
+
// Add authentication (preserve existing mode)
|
|
119
|
+
if (this._config.apiKey) {
|
|
120
|
+
newOpts.push((0, config_1.WithAPIKey)(this._config.apiKey));
|
|
121
|
+
}
|
|
122
|
+
else if (this._config.jwtToken) {
|
|
123
|
+
newOpts.push((0, config_1.WithJWTAccessToken)(this._config.jwtToken));
|
|
124
|
+
}
|
|
125
|
+
// Add the new group
|
|
126
|
+
newOpts.push((0, config_1.WithGroup)(group));
|
|
127
|
+
// Return a new client instance with updated configuration
|
|
128
|
+
return new UserServiceWeb(...newOpts);
|
|
60
129
|
}
|
|
61
130
|
/**
|
|
62
131
|
* Performs assignrolestouser operation on user.
|
|
@@ -65,7 +134,14 @@ class UserServiceWeb {
|
|
|
65
134
|
*/
|
|
66
135
|
assignRolesToUser(request) {
|
|
67
136
|
// Validate request
|
|
68
|
-
(
|
|
137
|
+
const result = this._validator.validate(service_pb_2.AssignRolesToUserRequestSchema, request);
|
|
138
|
+
if (result.kind === "invalid") {
|
|
139
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
140
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
141
|
+
}
|
|
142
|
+
else if (result.kind === "error") {
|
|
143
|
+
throw result.error;
|
|
144
|
+
}
|
|
69
145
|
return this._client.assignRolesToUser(request);
|
|
70
146
|
}
|
|
71
147
|
/**
|
|
@@ -75,7 +151,14 @@ class UserServiceWeb {
|
|
|
75
151
|
*/
|
|
76
152
|
revokeRolesFromUser(request) {
|
|
77
153
|
// Validate request
|
|
78
|
-
(
|
|
154
|
+
const result = this._validator.validate(service_pb_2.RevokeRolesFromUserRequestSchema, request);
|
|
155
|
+
if (result.kind === "invalid") {
|
|
156
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
157
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
158
|
+
}
|
|
159
|
+
else if (result.kind === "error") {
|
|
160
|
+
throw result.error;
|
|
161
|
+
}
|
|
79
162
|
return this._client.revokeRolesFromUser(request);
|
|
80
163
|
}
|
|
81
164
|
/**
|
|
@@ -85,7 +168,14 @@ class UserServiceWeb {
|
|
|
85
168
|
*/
|
|
86
169
|
getUser(request) {
|
|
87
170
|
// Validate request
|
|
88
|
-
(
|
|
171
|
+
const result = this._validator.validate(service_pb_2.GetUserRequestSchema, request);
|
|
172
|
+
if (result.kind === "invalid") {
|
|
173
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
174
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
175
|
+
}
|
|
176
|
+
else if (result.kind === "error") {
|
|
177
|
+
throw result.error;
|
|
178
|
+
}
|
|
89
179
|
return this._client.getUser(request);
|
|
90
180
|
}
|
|
91
181
|
/**
|
|
@@ -95,7 +185,14 @@ class UserServiceWeb {
|
|
|
95
185
|
*/
|
|
96
186
|
getUserByEmail(request) {
|
|
97
187
|
// Validate request
|
|
98
|
-
(
|
|
188
|
+
const result = this._validator.validate(service_pb_2.GetUserByEmailRequestSchema, request);
|
|
189
|
+
if (result.kind === "invalid") {
|
|
190
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
191
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
192
|
+
}
|
|
193
|
+
else if (result.kind === "error") {
|
|
194
|
+
throw result.error;
|
|
195
|
+
}
|
|
99
196
|
return this._client.getUserByEmail(request);
|
|
100
197
|
}
|
|
101
198
|
/**
|
|
@@ -105,7 +202,14 @@ class UserServiceWeb {
|
|
|
105
202
|
*/
|
|
106
203
|
listUsers(request) {
|
|
107
204
|
// Validate request
|
|
108
|
-
(
|
|
205
|
+
const result = this._validator.validate(service_pb_2.ListUsersRequestSchema, request);
|
|
206
|
+
if (result.kind === "invalid") {
|
|
207
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
208
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
209
|
+
}
|
|
210
|
+
else if (result.kind === "error") {
|
|
211
|
+
throw result.error;
|
|
212
|
+
}
|
|
109
213
|
return this._client.listUsers(request);
|
|
110
214
|
}
|
|
111
215
|
/**
|
|
@@ -115,7 +219,14 @@ class UserServiceWeb {
|
|
|
115
219
|
*/
|
|
116
220
|
searchUsers(request) {
|
|
117
221
|
// Validate request
|
|
118
|
-
(
|
|
222
|
+
const result = this._validator.validate(service_pb_2.SearchUsersRequestSchema, request);
|
|
223
|
+
if (result.kind === "invalid") {
|
|
224
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
225
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
226
|
+
}
|
|
227
|
+
else if (result.kind === "error") {
|
|
228
|
+
throw result.error;
|
|
229
|
+
}
|
|
119
230
|
return this._client.searchUsers(request);
|
|
120
231
|
}
|
|
121
232
|
/**
|
|
@@ -125,7 +236,14 @@ class UserServiceWeb {
|
|
|
125
236
|
*/
|
|
126
237
|
createUser(request) {
|
|
127
238
|
// Validate request
|
|
128
|
-
(
|
|
239
|
+
const result = this._validator.validate(service_pb_2.CreateUserRequestSchema, request);
|
|
240
|
+
if (result.kind === "invalid") {
|
|
241
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
242
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
243
|
+
}
|
|
244
|
+
else if (result.kind === "error") {
|
|
245
|
+
throw result.error;
|
|
246
|
+
}
|
|
129
247
|
return this._client.createUser(request);
|
|
130
248
|
}
|
|
131
249
|
/**
|
|
@@ -135,7 +253,14 @@ class UserServiceWeb {
|
|
|
135
253
|
*/
|
|
136
254
|
updateUser(request) {
|
|
137
255
|
// Validate request
|
|
138
|
-
(
|
|
256
|
+
const result = this._validator.validate(service_pb_2.UpdateUserRequestSchema, request);
|
|
257
|
+
if (result.kind === "invalid") {
|
|
258
|
+
const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
|
|
259
|
+
throw new Error(`Validation failed: ${violations}`);
|
|
260
|
+
}
|
|
261
|
+
else if (result.kind === "error") {
|
|
262
|
+
throw result.error;
|
|
263
|
+
}
|
|
139
264
|
return this._client.updateUser(request);
|
|
140
265
|
}
|
|
141
266
|
}
|
|
@@ -33,12 +33,20 @@ export type User = Message<"meshtrade.iam.user.v1.User"> & {
|
|
|
33
33
|
* @generated from field: string owner = 2;
|
|
34
34
|
*/
|
|
35
35
|
owner: string;
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* Ownership hiearchy of groups that have access to this resource in the format groups/{group_id}.
|
|
39
|
+
* System set on creation.
|
|
40
|
+
*
|
|
41
|
+
* @generated from field: repeated string owners = 3;
|
|
42
|
+
*/
|
|
43
|
+
owners: string[];
|
|
36
44
|
/**
|
|
37
45
|
*
|
|
38
46
|
* The unique email address of this user.
|
|
39
47
|
* This field is required on creation and must be a valid email format.
|
|
40
48
|
*
|
|
41
|
-
* @generated from field: string email =
|
|
49
|
+
* @generated from field: string email = 4;
|
|
42
50
|
*/
|
|
43
51
|
email: string;
|
|
44
52
|
/**
|
|
@@ -47,7 +55,7 @@ export type User = Message<"meshtrade.iam.user.v1.User"> & {
|
|
|
47
55
|
* prepended by the name of the group in which they have been assigned that role.
|
|
48
56
|
* e.g. groups/{ULIDv2}/roles/{role}, where role is a value of the meshtrade.iam.role.v1.Role enum.
|
|
49
57
|
*
|
|
50
|
-
* @generated from field: repeated string roles =
|
|
58
|
+
* @generated from field: repeated string roles = 5;
|
|
51
59
|
*/
|
|
52
60
|
roles: string[];
|
|
53
61
|
};
|
|
@@ -9,7 +9,7 @@ const validate_pb_1 = require("../../../../buf/validate/validate_pb");
|
|
|
9
9
|
/**
|
|
10
10
|
* Describes the file meshtrade/iam/user/v1/user.proto.
|
|
11
11
|
*/
|
|
12
|
-
exports.file_meshtrade_iam_user_v1_user = (0, codegenv2_1.fileDesc)("
|
|
12
|
+
exports.file_meshtrade_iam_user_v1_user = (0, codegenv2_1.fileDesc)("CiBtZXNodHJhZGUvaWFtL3VzZXIvdjEvdXNlci5wcm90bxIVbWVzaHRyYWRlLmlhbS51c2VyLnYxItsDCgRVc2VyErQBCgRuYW1lGAEgASgJQqUBukihAboBnQEKFG5hbWUuZm9ybWF0Lm9wdGlvbmFsEjJuYW1lIG11c3QgYmUgZW1wdHkgb3IgaW4gdGhlIGZvcm1hdCB1c2Vycy97VUxJRHYyfRpRc2l6ZSh0aGlzKSA9PSAwIHx8IHRoaXMubWF0Y2hlcygnXnVzZXJzL1swMTIzNDU2Nzg5QUJDREVGR0hKS01OUFFSU1RWV1hZWl17MjZ9JCcpEksKBW93bmVyGAIgASgJQjy6SDnIAQFyNDIvXmdyb3Vwcy9bMDEyMzQ1Njc4OUFCQ0RFRkdISktNTlBRUlNUVldYWVpdezI2fSSYASESTgoGb3duZXJzGAMgAygJQj66SDuSATgiNnI0Mi9eZ3JvdXBzL1swMTIzNDU2Nzg5QUJDREVGR0hKS01OUFFSU1RWV1hZWl17MjZ9JJgBIRIZCgVlbWFpbBgEIAEoCUIKukgHyAEBcgJgARJkCgVyb2xlcxgFIAMoCUJVukhSkgFPIk1ySxAvGDAyRV5ncm91cHMvWzAxMjM0NTY3ODlBQkNERUZHSEpLTU5QUVJTVFZXWFlaXXsyNn0vcm9sZXMvWzEtOV1bMC05XXs2LDd9JEJPChxjby5tZXNodHJhZGUuYXBpLmlhbS51c2VyLnYxWi9naXRodWIuY29tL21lc2h0cmFkZS9hcGkvZ28vaWFtL3VzZXIvdjE7dXNlcl92MWIGcHJvdG8z", [validate_pb_1.file_buf_validate_validate]);
|
|
13
13
|
/**
|
|
14
14
|
* Describes the message meshtrade.iam.user.v1.User.
|
|
15
15
|
* Use `create(UserSchema)` to create a new message.
|
|
@@ -1,23 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Connect-ES interceptors for the Meshtrade API client
|
|
2
|
+
* Connect-ES interceptors for the Meshtrade API client.
|
|
3
3
|
*
|
|
4
4
|
* Provides interceptor utilities for use with @connectrpc/connect clients,
|
|
5
|
-
* including group context injection for
|
|
6
|
-
*
|
|
7
|
-
* ## Authentication in Browser Environments
|
|
8
|
-
*
|
|
9
|
-
* The Web SDK uses browser-native cookie-based authentication via the
|
|
10
|
-
* `credentials: 'include'` fetch option. This automatically sends HTTP-only
|
|
11
|
-
* cookies (like AccessToken) with each request, which is the standard and
|
|
12
|
-
* secure authentication pattern for browser applications.
|
|
13
|
-
*
|
|
14
|
-
* Unlike the Node.js SDK which supports explicit API key and JWT interceptors,
|
|
15
|
-
* the Web SDK relies on the browser's automatic cookie handling. This is why
|
|
16
|
-
* this module only provides group context and logging interceptors - authentication
|
|
17
|
-
* is handled implicitly by the browser's cookie mechanism.
|
|
18
|
-
*
|
|
19
|
-
* For backend/server-side authentication needs, use the Node.js SDK instead
|
|
20
|
-
* (@meshtrade/api-node), which provides explicit API key and JWT token support.
|
|
5
|
+
* including authentication (API key, JWT) and group context injection for
|
|
6
|
+
* multi-tenant operations.
|
|
21
7
|
*/
|
|
22
8
|
import { Interceptor } from "@connectrpc/connect";
|
|
23
9
|
/**
|
|
@@ -54,6 +40,26 @@ import { Interceptor } from "@connectrpc/connect";
|
|
|
54
40
|
export declare function createGroupInterceptor(group: string): Interceptor & {
|
|
55
41
|
groupContext: string;
|
|
56
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* Creates a Connect-ES interceptor that injects API key authentication.
|
|
45
|
+
*
|
|
46
|
+
* @param apiKey - The API key for authentication
|
|
47
|
+
* @returns An interceptor that adds x-api-key header
|
|
48
|
+
* @throws {Error} If apiKey is empty
|
|
49
|
+
*/
|
|
50
|
+
export declare function createApiKeyInterceptor(apiKey: string): Interceptor & {
|
|
51
|
+
apiKeyAuth: true;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Creates a Connect-ES interceptor that injects JWT token authentication.
|
|
55
|
+
*
|
|
56
|
+
* @param jwtToken - The JWT token from the user's session
|
|
57
|
+
* @returns An interceptor that adds AccessToken cookie
|
|
58
|
+
* @throws {Error} If jwtToken is empty
|
|
59
|
+
*/
|
|
60
|
+
export declare function createJwtInterceptor(jwtToken: string): Interceptor & {
|
|
61
|
+
jwtAuth: true;
|
|
62
|
+
};
|
|
57
63
|
/**
|
|
58
64
|
* Creates a logging interceptor that logs all requests and responses.
|
|
59
65
|
* Useful for debugging and development.
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Connect-ES interceptors for the Meshtrade API client
|
|
3
|
+
* Connect-ES interceptors for the Meshtrade API client.
|
|
4
4
|
*
|
|
5
5
|
* Provides interceptor utilities for use with @connectrpc/connect clients,
|
|
6
|
-
* including group context injection for
|
|
7
|
-
*
|
|
8
|
-
* ## Authentication in Browser Environments
|
|
9
|
-
*
|
|
10
|
-
* The Web SDK uses browser-native cookie-based authentication via the
|
|
11
|
-
* `credentials: 'include'` fetch option. This automatically sends HTTP-only
|
|
12
|
-
* cookies (like AccessToken) with each request, which is the standard and
|
|
13
|
-
* secure authentication pattern for browser applications.
|
|
14
|
-
*
|
|
15
|
-
* Unlike the Node.js SDK which supports explicit API key and JWT interceptors,
|
|
16
|
-
* the Web SDK relies on the browser's automatic cookie handling. This is why
|
|
17
|
-
* this module only provides group context and logging interceptors - authentication
|
|
18
|
-
* is handled implicitly by the browser's cookie mechanism.
|
|
19
|
-
*
|
|
20
|
-
* For backend/server-side authentication needs, use the Node.js SDK instead
|
|
21
|
-
* (@meshtrade/api-node), which provides explicit API key and JWT token support.
|
|
6
|
+
* including authentication (API key, JWT) and group context injection for
|
|
7
|
+
* multi-tenant operations.
|
|
22
8
|
*/
|
|
23
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
10
|
exports.createGroupInterceptor = createGroupInterceptor;
|
|
11
|
+
exports.createApiKeyInterceptor = createApiKeyInterceptor;
|
|
12
|
+
exports.createJwtInterceptor = createJwtInterceptor;
|
|
25
13
|
exports.createLoggingInterceptor = createLoggingInterceptor;
|
|
26
|
-
|
|
14
|
+
/**
|
|
15
|
+
* HTTP header names for authentication.
|
|
16
|
+
* Must match the server-side header constants.
|
|
17
|
+
*/
|
|
18
|
+
const API_KEY_HEADER = "x-api-key";
|
|
19
|
+
const GROUP_HEADER = "x-group";
|
|
20
|
+
const COOKIE_HEADER = "cookie";
|
|
21
|
+
const ACCESS_TOKEN_COOKIE_NAME = "AccessToken";
|
|
22
|
+
/**
|
|
23
|
+
* Validates if a resource name follows the groups/{ulid} format.
|
|
24
|
+
*
|
|
25
|
+
* @param resourceName - The resource name string to validate
|
|
26
|
+
* @returns true if the resource name is a valid group resource name, false otherwise
|
|
27
|
+
*/
|
|
28
|
+
function isValidGroupResourceName(resourceName) {
|
|
29
|
+
return /^groups\/[0-9A-Z]{26}$/.test(resourceName);
|
|
30
|
+
}
|
|
27
31
|
/**
|
|
28
32
|
* Creates a Connect-ES interceptor that injects operating group context
|
|
29
33
|
* into API requests by adding an `x-group` header.
|
|
@@ -57,21 +61,54 @@ const validation_1 = require("./validation");
|
|
|
57
61
|
*/
|
|
58
62
|
function createGroupInterceptor(group) {
|
|
59
63
|
// Validate the group resource name format
|
|
60
|
-
if (!
|
|
64
|
+
if (!isValidGroupResourceName(group)) {
|
|
61
65
|
throw new Error(`Invalid group format: "${group}". Group must be in the format "groups/{ulid}" ` +
|
|
62
66
|
`where {ulid} is a 26-character ULID (e.g., "groups/01ARZ3NDEKTSV4YWVF8F5BH32").`);
|
|
63
67
|
}
|
|
64
68
|
// Create the interceptor function
|
|
65
69
|
const interceptor = (next) => async (req) => {
|
|
66
|
-
|
|
67
|
-
req.header.set("x-group", group);
|
|
68
|
-
// Call the next interceptor in the chain
|
|
70
|
+
req.header.set(GROUP_HEADER, group);
|
|
69
71
|
return await next(req);
|
|
70
72
|
};
|
|
71
73
|
// Add a marker property so we can identify group interceptors
|
|
72
74
|
// This is used in the withGroup method to prevent double-setting
|
|
73
75
|
return Object.assign(interceptor, { groupContext: group });
|
|
74
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Creates a Connect-ES interceptor that injects API key authentication.
|
|
79
|
+
*
|
|
80
|
+
* @param apiKey - The API key for authentication
|
|
81
|
+
* @returns An interceptor that adds x-api-key header
|
|
82
|
+
* @throws {Error} If apiKey is empty
|
|
83
|
+
*/
|
|
84
|
+
function createApiKeyInterceptor(apiKey) {
|
|
85
|
+
if (!apiKey || apiKey.trim() === "") {
|
|
86
|
+
throw new Error("API key cannot be empty");
|
|
87
|
+
}
|
|
88
|
+
const interceptor = (next) => async (req) => {
|
|
89
|
+
req.header.set(API_KEY_HEADER, apiKey);
|
|
90
|
+
return await next(req);
|
|
91
|
+
};
|
|
92
|
+
return Object.assign(interceptor, { apiKeyAuth: true });
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Creates a Connect-ES interceptor that injects JWT token authentication.
|
|
96
|
+
*
|
|
97
|
+
* @param jwtToken - The JWT token from the user's session
|
|
98
|
+
* @returns An interceptor that adds AccessToken cookie
|
|
99
|
+
* @throws {Error} If jwtToken is empty
|
|
100
|
+
*/
|
|
101
|
+
function createJwtInterceptor(jwtToken) {
|
|
102
|
+
if (!jwtToken || jwtToken.trim() === "") {
|
|
103
|
+
throw new Error("JWT token cannot be empty");
|
|
104
|
+
}
|
|
105
|
+
const interceptor = (next) => async (req) => {
|
|
106
|
+
const cookieValue = `${ACCESS_TOKEN_COOKIE_NAME}=${jwtToken}`;
|
|
107
|
+
req.header.set(COOKIE_HEADER, cookieValue);
|
|
108
|
+
return await next(req);
|
|
109
|
+
};
|
|
110
|
+
return Object.assign(interceptor, { jwtAuth: true });
|
|
111
|
+
}
|
|
75
112
|
/**
|
|
76
113
|
* Creates a logging interceptor that logs all requests and responses.
|
|
77
114
|
* Useful for debugging and development.
|
|
@@ -96,7 +133,7 @@ function createLoggingInterceptor() {
|
|
|
96
133
|
headers[key] = value;
|
|
97
134
|
});
|
|
98
135
|
// Log the request
|
|
99
|
-
console.
|
|
136
|
+
console.debug(`[Connect] ${req.method.name} request:`, {
|
|
100
137
|
service: req.service.typeName,
|
|
101
138
|
method: req.method.name,
|
|
102
139
|
headers,
|
|
@@ -105,7 +142,7 @@ function createLoggingInterceptor() {
|
|
|
105
142
|
// Call the next interceptor and get the response
|
|
106
143
|
const response = await next(req);
|
|
107
144
|
// Log successful response
|
|
108
|
-
console.
|
|
145
|
+
console.debug(`[Connect] ${req.method.name} response:`, {
|
|
109
146
|
service: req.service.typeName,
|
|
110
147
|
method: req.method.name,
|
|
111
148
|
status: "success",
|
|
@@ -1,29 +1,84 @@
|
|
|
1
|
-
import { Interceptor } from "@connectrpc/connect";
|
|
2
1
|
import { GetTransactionStateRequest, GetTransactionStateResponse, MonitorTransactionStateRequest, MonitorTransactionStateResponse } from "./service_pb";
|
|
3
|
-
import {
|
|
2
|
+
import { ClientOption } from "../../../config";
|
|
4
3
|
/**
|
|
5
4
|
* Web client for interacting with the meshtrade.ledger.transaction.v1 transaction v1 API resource service.
|
|
6
|
-
* Uses Connect-ES with gRPC-Web transport for browser-
|
|
5
|
+
* Uses Connect-ES with gRPC-Web transport for browser-based communication.
|
|
6
|
+
*
|
|
7
|
+
* Supports flexible authentication modes using functional options pattern:
|
|
8
|
+
*
|
|
9
|
+
* 1. **No Authentication** (public APIs):
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const client = new TransactionServiceWeb(
|
|
12
|
+
* WithServerUrl("http://localhost:10000")
|
|
13
|
+
* );
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* 2. **API Key Authentication** (backend services):
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const client = new TransactionServiceWeb(
|
|
19
|
+
* WithAPIKey("your-api-key"),
|
|
20
|
+
* WithGroup("groups/01ARZ3NDEKTSV4YWVF8F5BH32"),
|
|
21
|
+
* WithServerUrl("https://api.example.com")
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* 3. **JWT Token Authentication** (Next.js frontend with user session):
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const client = new TransactionServiceWeb(
|
|
28
|
+
* WithJWTAccessToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."),
|
|
29
|
+
* WithServerUrl("https://api.example.com")
|
|
30
|
+
* );
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* 4. **JWT with Group Context** (user session with specific group):
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const client = new TransactionServiceWeb(
|
|
36
|
+
* WithJWTAccessToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."),
|
|
37
|
+
* WithGroup("groups/01ARZ3NDEKTSV4YWVF8F5BH32"),
|
|
38
|
+
* WithServerUrl("https://api.example.com")
|
|
39
|
+
* );
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* Available options:
|
|
43
|
+
* - `WithAPIKey(key)` - API key authentication (mutually exclusive with JWT)
|
|
44
|
+
* - `WithJWTAccessToken(token)` - JWT authentication (mutually exclusive with API key)
|
|
45
|
+
* - `WithGroup(group)` - Group context (optional, works with both auth modes)
|
|
46
|
+
* - `WithServerUrl(url)` - Custom server URL (optional, defaults to production)
|
|
7
47
|
*/
|
|
8
48
|
export declare class TransactionServiceWeb {
|
|
9
49
|
private _client;
|
|
10
50
|
private readonly _config;
|
|
11
51
|
private readonly _interceptors;
|
|
52
|
+
private readonly _validator;
|
|
12
53
|
/**
|
|
13
54
|
* Constructs an instance of TransactionServiceWeb.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
55
|
+
*
|
|
56
|
+
* Uses functional options pattern for flexible configuration:
|
|
57
|
+
* - `WithAPIKey(key)` - API key authentication
|
|
58
|
+
* - `WithJWTAccessToken(token)` - JWT authentication
|
|
59
|
+
* - `WithGroup(group)` - Group context (optional)
|
|
60
|
+
* - `WithServerUrl(url)` - Custom server URL (optional)
|
|
61
|
+
*
|
|
62
|
+
* @param {...ClientOption} opts - Variable number of configuration options
|
|
16
63
|
*/
|
|
17
|
-
constructor(
|
|
64
|
+
constructor(...opts: ClientOption[]);
|
|
18
65
|
/**
|
|
19
66
|
* Returns a new client instance configured to send the specified group
|
|
20
67
|
* resource name in the request headers for subsequent API calls.
|
|
21
68
|
*
|
|
69
|
+
* This method creates a new client with the same authentication configuration
|
|
70
|
+
* but with the group context updated to the specified value.
|
|
71
|
+
*
|
|
72
|
+
* **Compatibility**: Works with all authentication modes:
|
|
73
|
+
* - **API key auth**: Creates new client with API key + new group
|
|
74
|
+
* - **JWT auth**: Creates new client with JWT + new group
|
|
75
|
+
* - **No auth**: Creates new client with standalone group interceptor
|
|
76
|
+
*
|
|
22
77
|
* @param {string} group - The operating group context to inject into the request
|
|
23
78
|
* in the format `groups/{ulid}` where {ulid} is a 26-character ULID.
|
|
24
79
|
* Example: 'groups/01ARZ3NDEKTSV4YWVF8F5BH32'
|
|
25
80
|
* @returns {TransactionServiceWeb} A new, configured instance of the client.
|
|
26
|
-
* @throws {Error} If the group format is invalid
|
|
81
|
+
* @throws {Error} If the group format is invalid
|
|
27
82
|
*/
|
|
28
83
|
withGroup(group: string): TransactionServiceWeb;
|
|
29
84
|
/**
|