@meshtrade/api-node 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.
Files changed (44) hide show
  1. package/dist/meshtrade/compliance/client/v1/client_pb.d.ts +17 -9
  2. package/dist/meshtrade/compliance/client/v1/client_pb.js +1 -1
  3. package/dist/meshtrade/compliance/client/v1/service_node_meshts.d.ts +46 -21
  4. package/dist/meshtrade/compliance/client/v1/service_node_meshts.js +98 -56
  5. package/dist/meshtrade/config/index.d.ts +160 -0
  6. package/dist/meshtrade/config/index.js +210 -0
  7. package/dist/meshtrade/iam/api_user/v1/api_user_pb.d.ts +12 -4
  8. package/dist/meshtrade/iam/api_user/v1/api_user_pb.js +1 -1
  9. package/dist/meshtrade/iam/api_user/v1/service_node_meshts.d.ts +46 -21
  10. package/dist/meshtrade/iam/api_user/v1/service_node_meshts.js +149 -65
  11. package/dist/meshtrade/iam/group/v1/group_pb.d.ts +8 -0
  12. package/dist/meshtrade/iam/group/v1/group_pb.js +1 -1
  13. package/dist/meshtrade/iam/group/v1/service_node_meshts.d.ts +46 -21
  14. package/dist/meshtrade/iam/group/v1/service_node_meshts.js +114 -58
  15. package/dist/meshtrade/iam/user/v1/service_node_meshts.d.ts +46 -21
  16. package/dist/meshtrade/iam/user/v1/service_node_meshts.js +141 -64
  17. package/dist/meshtrade/iam/user/v1/user_pb.d.ts +10 -2
  18. package/dist/meshtrade/iam/user/v1/user_pb.js +1 -1
  19. package/dist/meshtrade/{common/connectInterceptors.d.ts → interceptors/index.d.ts} +6 -64
  20. package/dist/meshtrade/{common/connectInterceptors.js → interceptors/index.js} +20 -90
  21. package/dist/meshtrade/ledger/transaction/v1/service_node_meshts.d.ts +46 -21
  22. package/dist/meshtrade/ledger/transaction/v1/service_node_meshts.js +90 -55
  23. package/dist/meshtrade/market_data/price/v1/service_node_meshts.d.ts +46 -21
  24. package/dist/meshtrade/market_data/price/v1/service_node_meshts.js +82 -54
  25. package/dist/meshtrade/reporting/account_report/v1/service_node_meshts.d.ts +46 -21
  26. package/dist/meshtrade/reporting/account_report/v1/service_node_meshts.js +90 -55
  27. package/dist/meshtrade/studio/instrument/v1/instrument_pb.d.ts +8 -0
  28. package/dist/meshtrade/studio/instrument/v1/instrument_pb.js +1 -1
  29. package/dist/meshtrade/trading/limit_order/v1/limit_order_pb.d.ts +16 -8
  30. package/dist/meshtrade/trading/limit_order/v1/limit_order_pb.js +1 -1
  31. package/dist/meshtrade/trading/limit_order/v1/service_node_meshts.d.ts +46 -21
  32. package/dist/meshtrade/trading/limit_order/v1/service_node_meshts.js +133 -63
  33. package/dist/meshtrade/trading/limit_order/v1/service_pb.js +1 -1
  34. package/dist/meshtrade/trading/market_order/v1/service_node_meshts.d.ts +46 -21
  35. package/dist/meshtrade/trading/market_order/v1/service_node_meshts.js +82 -54
  36. package/dist/meshtrade/wallet/account/v1/account_pb.d.ts +8 -0
  37. package/dist/meshtrade/wallet/account/v1/account_pb.js +1 -1
  38. package/dist/meshtrade/wallet/account/v1/service_node_meshts.d.ts +46 -21
  39. package/dist/meshtrade/wallet/account/v1/service_node_meshts.js +149 -65
  40. package/package.json +19 -2
  41. package/dist/meshtrade/common/config.d.ts +0 -50
  42. package/dist/meshtrade/common/config.js +0 -34
  43. package/dist/meshtrade/common/validation.d.ts +0 -62
  44. package/dist/meshtrade/common/validation.js +0 -77
@@ -7,62 +7,82 @@ exports.UserServiceNode = void 0;
7
7
  const connect_1 = require("@connectrpc/connect");
8
8
  const connect_node_1 = require("@connectrpc/connect-node");
9
9
  const service_pb_1 = require("./service_pb");
10
- const config_1 = require("../../../common/config");
11
- const validation_1 = require("../../../common/validation");
12
- const connectInterceptors_1 = require("../../../common/connectInterceptors");
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
  * Node.js client for interacting with the meshtrade.iam.user.v1 user v1 API resource service.
15
16
  * Uses Connect-ES with gRPC transport for Node.js gRPC communication.
16
17
  *
17
- * Supports three authentication modes:
18
+ * Supports flexible authentication modes using functional options pattern:
18
19
  *
19
20
  * 1. **No Authentication** (public APIs):
20
21
  * ```typescript
21
- * const client = new UserServiceNode({ apiServerURL: "http://localhost:10000" });
22
+ * const client = new UserServiceNode(
23
+ * WithServerUrl("http://localhost:10000")
24
+ * );
22
25
  * ```
23
26
  *
24
27
  * 2. **API Key Authentication** (backend services):
25
28
  * ```typescript
26
- * const client = new UserServiceNode({
27
- * apiServerURL: "https://api.example.com",
28
- * apiKey: "your-api-key",
29
- * group: "groups/01ARZ3NDEKTSV4YWVF8F5BH32"
30
- * });
29
+ * const client = new UserServiceNode(
30
+ * WithAPIKey("your-api-key"),
31
+ * WithGroup("groups/01ARZ3NDEKTSV4YWVF8F5BH32"),
32
+ * WithServerUrl("https://api.example.com")
33
+ * );
31
34
  * ```
32
35
  *
33
36
  * 3. **JWT Token Authentication** (Next.js backend with user session):
34
37
  * ```typescript
35
- * const client = new UserServiceNode({
36
- * apiServerURL: "https://api.example.com",
37
- * jwtToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
38
- * });
38
+ * const client = new UserServiceNode(
39
+ * WithJWTAccessToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."),
40
+ * WithServerUrl("https://api.example.com")
41
+ * );
39
42
  * ```
43
+ *
44
+ * 4. **JWT with Group Context** (user session with specific group):
45
+ * ```typescript
46
+ * const client = new UserServiceNode(
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)
40
58
  */
41
59
  class UserServiceNode {
42
60
  /**
43
61
  * Constructs an instance of UserServiceNode.
44
- * @param {ConfigOpts} [config] - Optional configuration for the client.
45
- * @param {Interceptor[]} [interceptors] - For internal use by `withGroup`.
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
46
70
  */
47
- constructor(config, interceptors) {
48
- this._config = (0, config_1.getConfigFromOpts)(config);
49
- // If interceptors are provided (from withGroup), use them
50
- // Otherwise, create auth interceptors based on config
51
- if (interceptors) {
52
- this._interceptors = interceptors;
53
- }
54
- else {
55
- this._interceptors = [];
56
- // Add authentication interceptor based on configuration
57
- if (this._config.apiKey && this._config.group) {
58
- // API Key authentication mode
59
- this._interceptors.push((0, connectInterceptors_1.createApiKeyInterceptor)(this._config.apiKey, this._config.group));
60
- }
61
- else if (this._config.jwtToken) {
62
- // JWT authentication mode
63
- this._interceptors.push((0, connectInterceptors_1.createJwtInterceptor)(this._config.jwtToken));
64
- }
65
- // If neither is configured, no authentication (public API mode)
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));
66
86
  }
67
87
  // Create the gRPC transport for Node.js with interceptors
68
88
  // Note: gRPC transport uses HTTP/2 by default
@@ -77,35 +97,36 @@ class UserServiceNode {
77
97
  * Returns a new client instance configured to send the specified group
78
98
  * resource name in the request headers for subsequent API calls.
79
99
  *
80
- * **Important**: This method only works with API key authentication.
81
- * - For **API key auth**: Creates a new client with updated group context
82
- * - For **JWT auth**: Throws error (group comes from JWT token claims)
83
- * - For **no auth**: Throws error (group requires authentication)
100
+ * This method creates a new client with the same authentication configuration
101
+ * but with the group context updated to the specified value.
102
+ *
103
+ * **Compatibility**: Works with all authentication modes:
104
+ * - **API key auth**: Creates new client with API key + new group
105
+ * - **JWT auth**: Creates new client with JWT + new group
106
+ * - **No auth**: Creates new client with standalone group interceptor
84
107
  *
85
108
  * @param {string} group - The operating group context to inject into the request
86
109
  * in the format `groups/{ulid}` where {ulid} is a 26-character ULID.
87
110
  * Example: 'groups/01ARZ3NDEKTSV4YWVF8F5BH32'
88
111
  * @returns {UserServiceNode} A new, configured instance of the client.
89
- * @throws {Error} If used with JWT authentication or no authentication
90
112
  * @throws {Error} If the group format is invalid
91
113
  */
92
114
  withGroup(group) {
93
- // Check authentication mode
94
- if (this._config.jwtToken) {
95
- throw new Error("Cannot use withGroup() with JWT authentication. " +
96
- "The group context is determined by the JWT token claims.");
97
- }
98
- if (!this._config.apiKey) {
99
- throw new Error("Cannot use withGroup() without authentication. " +
100
- "Please configure API key authentication to use group context.");
101
- }
102
- // For API key authentication, create new client with updated group
103
- // Replace the existing API key interceptor with one that has the new group
104
- const newInterceptors = [
105
- (0, connectInterceptors_1.createApiKeyInterceptor)(this._config.apiKey, group)
106
- ];
107
- // Return a new client instance with updated group context
108
- return new UserServiceNode(this._config, newInterceptors);
115
+ // Build new options array with existing auth and updated group
116
+ const newOpts = [];
117
+ // Add server URL
118
+ newOpts.push((0, config_1.WithServerUrl)(this._config.apiServerURL));
119
+ // Add authentication (preserve existing mode)
120
+ if (this._config.apiKey) {
121
+ newOpts.push((0, config_1.WithAPIKey)(this._config.apiKey));
122
+ }
123
+ else if (this._config.jwtToken) {
124
+ newOpts.push((0, config_1.WithJWTAccessToken)(this._config.jwtToken));
125
+ }
126
+ // Add the new group
127
+ newOpts.push((0, config_1.WithGroup)(group));
128
+ // Return a new client instance with updated configuration
129
+ return new UserServiceNode(...newOpts);
109
130
  }
110
131
  /**
111
132
  * Performs assignrolestouser operation on user.
@@ -114,7 +135,14 @@ class UserServiceNode {
114
135
  */
115
136
  assignRolesToUser(request) {
116
137
  // Validate request
117
- (0, validation_1.validateRequest)(request);
138
+ const result = this._validator.validate(service_pb_2.AssignRolesToUserRequestSchema, request);
139
+ if (result.kind === "invalid") {
140
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
141
+ throw new Error(`Validation failed: ${violations}`);
142
+ }
143
+ else if (result.kind === "error") {
144
+ throw result.error;
145
+ }
118
146
  return this._client.assignRolesToUser(request);
119
147
  }
120
148
  /**
@@ -124,7 +152,14 @@ class UserServiceNode {
124
152
  */
125
153
  revokeRolesFromUser(request) {
126
154
  // Validate request
127
- (0, validation_1.validateRequest)(request);
155
+ const result = this._validator.validate(service_pb_2.RevokeRolesFromUserRequestSchema, request);
156
+ if (result.kind === "invalid") {
157
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
158
+ throw new Error(`Validation failed: ${violations}`);
159
+ }
160
+ else if (result.kind === "error") {
161
+ throw result.error;
162
+ }
128
163
  return this._client.revokeRolesFromUser(request);
129
164
  }
130
165
  /**
@@ -134,7 +169,14 @@ class UserServiceNode {
134
169
  */
135
170
  getUser(request) {
136
171
  // Validate request
137
- (0, validation_1.validateRequest)(request);
172
+ const result = this._validator.validate(service_pb_2.GetUserRequestSchema, request);
173
+ if (result.kind === "invalid") {
174
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
175
+ throw new Error(`Validation failed: ${violations}`);
176
+ }
177
+ else if (result.kind === "error") {
178
+ throw result.error;
179
+ }
138
180
  return this._client.getUser(request);
139
181
  }
140
182
  /**
@@ -144,7 +186,14 @@ class UserServiceNode {
144
186
  */
145
187
  getUserByEmail(request) {
146
188
  // Validate request
147
- (0, validation_1.validateRequest)(request);
189
+ const result = this._validator.validate(service_pb_2.GetUserByEmailRequestSchema, request);
190
+ if (result.kind === "invalid") {
191
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
192
+ throw new Error(`Validation failed: ${violations}`);
193
+ }
194
+ else if (result.kind === "error") {
195
+ throw result.error;
196
+ }
148
197
  return this._client.getUserByEmail(request);
149
198
  }
150
199
  /**
@@ -154,7 +203,14 @@ class UserServiceNode {
154
203
  */
155
204
  listUsers(request) {
156
205
  // Validate request
157
- (0, validation_1.validateRequest)(request);
206
+ const result = this._validator.validate(service_pb_2.ListUsersRequestSchema, request);
207
+ if (result.kind === "invalid") {
208
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
209
+ throw new Error(`Validation failed: ${violations}`);
210
+ }
211
+ else if (result.kind === "error") {
212
+ throw result.error;
213
+ }
158
214
  return this._client.listUsers(request);
159
215
  }
160
216
  /**
@@ -164,7 +220,14 @@ class UserServiceNode {
164
220
  */
165
221
  searchUsers(request) {
166
222
  // Validate request
167
- (0, validation_1.validateRequest)(request);
223
+ const result = this._validator.validate(service_pb_2.SearchUsersRequestSchema, request);
224
+ if (result.kind === "invalid") {
225
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
226
+ throw new Error(`Validation failed: ${violations}`);
227
+ }
228
+ else if (result.kind === "error") {
229
+ throw result.error;
230
+ }
168
231
  return this._client.searchUsers(request);
169
232
  }
170
233
  /**
@@ -174,7 +237,14 @@ class UserServiceNode {
174
237
  */
175
238
  createUser(request) {
176
239
  // Validate request
177
- (0, validation_1.validateRequest)(request);
240
+ const result = this._validator.validate(service_pb_2.CreateUserRequestSchema, request);
241
+ if (result.kind === "invalid") {
242
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
243
+ throw new Error(`Validation failed: ${violations}`);
244
+ }
245
+ else if (result.kind === "error") {
246
+ throw result.error;
247
+ }
178
248
  return this._client.createUser(request);
179
249
  }
180
250
  /**
@@ -184,7 +254,14 @@ class UserServiceNode {
184
254
  */
185
255
  updateUser(request) {
186
256
  // Validate request
187
- (0, validation_1.validateRequest)(request);
257
+ const result = this._validator.validate(service_pb_2.UpdateUserRequestSchema, request);
258
+ if (result.kind === "invalid") {
259
+ const violations = result.violations.map(v => `${v.field.toString()}: ${v.message}`).join("; ");
260
+ throw new Error(`Validation failed: ${violations}`);
261
+ }
262
+ else if (result.kind === "error") {
263
+ throw result.error;
264
+ }
188
265
  return this._client.updateUser(request);
189
266
  }
190
267
  }
@@ -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 = 3;
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 = 4;
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)("CiBtZXNodHJhZGUvaWFtL3VzZXIvdjEvdXNlci5wcm90bxIVbWVzaHRyYWRlLmlhbS51c2VyLnYxIosDCgRVc2VyErQBCgRuYW1lGAEgASgJQqUBukihAboBnQEKFG5hbWUuZm9ybWF0Lm9wdGlvbmFsEjJuYW1lIG11c3QgYmUgZW1wdHkgb3IgaW4gdGhlIGZvcm1hdCB1c2Vycy97VUxJRHYyfRpRc2l6ZSh0aGlzKSA9PSAwIHx8IHRoaXMubWF0Y2hlcygnXnVzZXJzL1swMTIzNDU2Nzg5QUJDREVGR0hKS01OUFFSU1RWV1hZWl17MjZ9JCcpEksKBW93bmVyGAIgASgJQjy6SDnIAQFyNDIvXmdyb3Vwcy9bMDEyMzQ1Njc4OUFCQ0RFRkdISktNTlBRUlNUVldYWVpdezI2fSSYASESGQoFZW1haWwYAyABKAlCCrpIB8gBAXICYAESZAoFcm9sZXMYBCADKAlCVbpIUpIBTyJNcksQLxgwMkVeZ3JvdXBzL1swMTIzNDU2Nzg5QUJDREVGR0hKS01OUFFSU1RWV1hZWl17MjZ9L3JvbGVzL1sxLTldWzAtOV17Niw3fSRCTwocY28ubWVzaHRyYWRlLmFwaS5pYW0udXNlci52MVovZ2l0aHViLmNvbS9tZXNodHJhZGUvYXBpL2dvL2lhbS91c2VyL3YxO3VzZXJfdjFiBnByb3RvMw", [validate_pb_1.file_buf_validate_validate]);
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.
@@ -41,79 +41,21 @@ export declare function createGroupInterceptor(group: string): Interceptor & {
41
41
  groupContext: string;
42
42
  };
43
43
  /**
44
- * Creates a Connect-ES interceptor that injects API key authentication
45
- * into API requests by adding `x-api-key` and `x-group` headers.
46
- *
47
- * This authentication mode is used for service-to-service communication
48
- * where a backend service authenticates using an API key and operates
49
- * within a specific group context.
50
- *
51
- * Both the API key and group are required and validated. The group must
52
- * follow the resource name format: `groups/{ulid}` where {ulid} is a
53
- * 26-character ULID.
44
+ * Creates a Connect-ES interceptor that injects API key authentication.
54
45
  *
55
46
  * @param apiKey - The API key for authentication
56
- * @param group - The group resource name in format `groups/{ulid}`
57
- * @returns An interceptor function that adds authentication headers to all requests
58
- * @throws {Error} If apiKey is empty or group format is invalid
59
- *
60
- * @example
61
- * ```typescript
62
- * const authInterceptor = createApiKeyInterceptor(
63
- * 'your-api-key',
64
- * 'groups/01ARZ3NDEKTSV4YWVF8F5BH32'
65
- * );
66
- *
67
- * const transport = createGrpcTransport({
68
- * baseUrl: 'https://api.example.com',
69
- * interceptors: [authInterceptor]
70
- * });
71
- * ```
47
+ * @returns An interceptor that adds x-api-key header
48
+ * @throws {Error} If apiKey is empty
72
49
  */
73
- export declare function createApiKeyInterceptor(apiKey: string, group: string): Interceptor & {
50
+ export declare function createApiKeyInterceptor(apiKey: string): Interceptor & {
74
51
  apiKeyAuth: true;
75
- groupContext: string;
76
52
  };
77
53
  /**
78
- * Creates a Connect-ES interceptor that injects JWT token authentication
79
- * into API requests by adding a `Cookie` header with the AccessToken.
80
- *
81
- * This authentication mode is used in Next.js backends where the server
82
- * has access to the user's JWT token from their browser session. The JWT
83
- * is injected as a cookie so the server can extract it in the same way
84
- * it would from a browser request.
85
- *
86
- * The JWT token is added as: `Cookie: AccessToken=<jwt>`
87
- *
88
- * This allows the server-side authentication middleware to extract it as:
89
- * ```go
90
- * if cookieHeader := request.Attributes.Request.Http.Headers["cookie"]; cookieHeader != "" {
91
- * cookies := parseHTTPCookies(cookieHeader)
92
- * for _, cookie := range cookies {
93
- * if cookie.Name == "AccessToken" && cookie.Value != "" {
94
- * authContext.AccessToken = cookie.Value
95
- * break
96
- * }
97
- * }
98
- * }
99
- * ```
54
+ * Creates a Connect-ES interceptor that injects JWT token authentication.
100
55
  *
101
56
  * @param jwtToken - The JWT token from the user's session
102
- * @returns An interceptor function that adds the JWT as a cookie header
57
+ * @returns An interceptor that adds AccessToken cookie
103
58
  * @throws {Error} If jwtToken is empty
104
- *
105
- * @example
106
- * ```typescript
107
- * // In a Next.js API route
108
- * const authInterceptor = createJwtInterceptor(
109
- * 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
110
- * );
111
- *
112
- * const transport = createGrpcTransport({
113
- * baseUrl: 'https://api.example.com',
114
- * interceptors: [authInterceptor]
115
- * });
116
- * ```
117
59
  */
118
60
  export declare function createJwtInterceptor(jwtToken: string): Interceptor & {
119
61
  jwtAuth: true;
@@ -11,7 +11,6 @@ exports.createGroupInterceptor = createGroupInterceptor;
11
11
  exports.createApiKeyInterceptor = createApiKeyInterceptor;
12
12
  exports.createJwtInterceptor = createJwtInterceptor;
13
13
  exports.createLoggingInterceptor = createLoggingInterceptor;
14
- const validation_1 = require("./validation");
15
14
  /**
16
15
  * HTTP header names for authentication.
17
16
  * Must match the server-side header constants.
@@ -20,6 +19,15 @@ const API_KEY_HEADER = "x-api-key";
20
19
  const GROUP_HEADER = "x-group";
21
20
  const COOKIE_HEADER = "cookie";
22
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
+ }
23
31
  /**
24
32
  * Creates a Connect-ES interceptor that injects operating group context
25
33
  * into API requests by adding an `x-group` header.
@@ -53,15 +61,13 @@ const ACCESS_TOKEN_COOKIE_NAME = "AccessToken";
53
61
  */
54
62
  function createGroupInterceptor(group) {
55
63
  // Validate the group resource name format
56
- if (!(0, validation_1.isValidGroupResourceName)(group)) {
64
+ if (!isValidGroupResourceName(group)) {
57
65
  throw new Error(`Invalid group format: "${group}". Group must be in the format "groups/{ulid}" ` +
58
66
  `where {ulid} is a 26-character ULID (e.g., "groups/01ARZ3NDEKTSV4YWVF8F5BH32").`);
59
67
  }
60
68
  // Create the interceptor function
61
69
  const interceptor = (next) => async (req) => {
62
- // Add the x-group header to the request
63
- req.header.set("x-group", group);
64
- // Call the next interceptor in the chain
70
+ req.header.set(GROUP_HEADER, group);
65
71
  return await next(req);
66
72
  };
67
73
  // Add a marker property so we can identify group interceptors
@@ -69,114 +75,38 @@ function createGroupInterceptor(group) {
69
75
  return Object.assign(interceptor, { groupContext: group });
70
76
  }
71
77
  /**
72
- * Creates a Connect-ES interceptor that injects API key authentication
73
- * into API requests by adding `x-api-key` and `x-group` headers.
74
- *
75
- * This authentication mode is used for service-to-service communication
76
- * where a backend service authenticates using an API key and operates
77
- * within a specific group context.
78
- *
79
- * Both the API key and group are required and validated. The group must
80
- * follow the resource name format: `groups/{ulid}` where {ulid} is a
81
- * 26-character ULID.
78
+ * Creates a Connect-ES interceptor that injects API key authentication.
82
79
  *
83
80
  * @param apiKey - The API key for authentication
84
- * @param group - The group resource name in format `groups/{ulid}`
85
- * @returns An interceptor function that adds authentication headers to all requests
86
- * @throws {Error} If apiKey is empty or group format is invalid
87
- *
88
- * @example
89
- * ```typescript
90
- * const authInterceptor = createApiKeyInterceptor(
91
- * 'your-api-key',
92
- * 'groups/01ARZ3NDEKTSV4YWVF8F5BH32'
93
- * );
94
- *
95
- * const transport = createGrpcTransport({
96
- * baseUrl: 'https://api.example.com',
97
- * interceptors: [authInterceptor]
98
- * });
99
- * ```
81
+ * @returns An interceptor that adds x-api-key header
82
+ * @throws {Error} If apiKey is empty
100
83
  */
101
- function createApiKeyInterceptor(apiKey, group) {
102
- // Validate inputs
84
+ function createApiKeyInterceptor(apiKey) {
103
85
  if (!apiKey || apiKey.trim() === "") {
104
86
  throw new Error("API key cannot be empty");
105
87
  }
106
- if (!(0, validation_1.isValidGroupResourceName)(group)) {
107
- throw new Error(`Invalid group format: "${group}". Group must be in the format "groups/{ulid}" ` +
108
- `where {ulid} is a 26-character ULID (e.g., "groups/01ARZ3NDEKTSV4YWVF8F5BH32").`);
109
- }
110
- // Create the interceptor function
111
88
  const interceptor = (next) => async (req) => {
112
- // Add authentication headers to the request
113
89
  req.header.set(API_KEY_HEADER, apiKey);
114
- req.header.set(GROUP_HEADER, group);
115
- // Call the next interceptor in the chain
116
90
  return await next(req);
117
91
  };
118
- // Add marker properties for identification
119
- return Object.assign(interceptor, {
120
- apiKeyAuth: true,
121
- groupContext: group,
122
- });
92
+ return Object.assign(interceptor, { apiKeyAuth: true });
123
93
  }
124
94
  /**
125
- * Creates a Connect-ES interceptor that injects JWT token authentication
126
- * into API requests by adding a `Cookie` header with the AccessToken.
127
- *
128
- * This authentication mode is used in Next.js backends where the server
129
- * has access to the user's JWT token from their browser session. The JWT
130
- * is injected as a cookie so the server can extract it in the same way
131
- * it would from a browser request.
132
- *
133
- * The JWT token is added as: `Cookie: AccessToken=<jwt>`
134
- *
135
- * This allows the server-side authentication middleware to extract it as:
136
- * ```go
137
- * if cookieHeader := request.Attributes.Request.Http.Headers["cookie"]; cookieHeader != "" {
138
- * cookies := parseHTTPCookies(cookieHeader)
139
- * for _, cookie := range cookies {
140
- * if cookie.Name == "AccessToken" && cookie.Value != "" {
141
- * authContext.AccessToken = cookie.Value
142
- * break
143
- * }
144
- * }
145
- * }
146
- * ```
95
+ * Creates a Connect-ES interceptor that injects JWT token authentication.
147
96
  *
148
97
  * @param jwtToken - The JWT token from the user's session
149
- * @returns An interceptor function that adds the JWT as a cookie header
98
+ * @returns An interceptor that adds AccessToken cookie
150
99
  * @throws {Error} If jwtToken is empty
151
- *
152
- * @example
153
- * ```typescript
154
- * // In a Next.js API route
155
- * const authInterceptor = createJwtInterceptor(
156
- * 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
157
- * );
158
- *
159
- * const transport = createGrpcTransport({
160
- * baseUrl: 'https://api.example.com',
161
- * interceptors: [authInterceptor]
162
- * });
163
- * ```
164
100
  */
165
101
  function createJwtInterceptor(jwtToken) {
166
- // Validate input
167
102
  if (!jwtToken || jwtToken.trim() === "") {
168
103
  throw new Error("JWT token cannot be empty");
169
104
  }
170
- // Create the interceptor function
171
105
  const interceptor = (next) => async (req) => {
172
- // Add JWT as a cookie header
173
- // Format: "Cookie: AccessToken=<jwt>"
174
106
  const cookieValue = `${ACCESS_TOKEN_COOKIE_NAME}=${jwtToken}`;
175
107
  req.header.set(COOKIE_HEADER, cookieValue);
176
- // Call the next interceptor in the chain
177
108
  return await next(req);
178
109
  };
179
- // Add marker property for identification
180
110
  return Object.assign(interceptor, { jwtAuth: true });
181
111
  }
182
112
  /**
@@ -203,7 +133,7 @@ function createLoggingInterceptor() {
203
133
  headers[key] = value;
204
134
  });
205
135
  // Log the request
206
- console.log(`[Connect] ${req.method.name} request:`, {
136
+ console.debug(`[Connect] ${req.method.name} request:`, {
207
137
  service: req.service.typeName,
208
138
  method: req.method.name,
209
139
  headers,
@@ -212,7 +142,7 @@ function createLoggingInterceptor() {
212
142
  // Call the next interceptor and get the response
213
143
  const response = await next(req);
214
144
  // Log successful response
215
- console.log(`[Connect] ${req.method.name} response:`, {
145
+ console.debug(`[Connect] ${req.method.name} response:`, {
216
146
  service: req.service.typeName,
217
147
  method: req.method.name,
218
148
  status: "success",