@alphauspkgs/blue-sdk-ts 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.
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NewAdminClient = NewAdminClient;
4
4
  const admin_pb_1 = require("./admin_pb");
5
5
  const conn_1 = require("../../conn/conn");
6
- function NewAdminClient(...opts) {
7
- const blueapi = new conn_1.BlueAPIService(admin_pb_1.Admin, "blue", opts);
6
+ function NewAdminClient(opt) {
7
+ const blueapi = new conn_1.BlueAPIService(admin_pb_1.Admin, "blue", opt);
8
8
  return blueapi.clientInstance;
9
9
  }
@@ -1,7 +1,7 @@
1
1
  import { Admin } from "./admin_pb";
2
2
  import { BlueAPIService, ConnectOption } from "../../conn/conn";
3
3
 
4
- export function NewAdminClient(...opts: ConnectOption[]) {
5
- const blueapi = new BlueAPIService(Admin, "blue", opts);
4
+ export function NewAdminClient(opt?: ConnectOption) {
5
+ const blueapi = new BlueAPIService(Admin, "blue", opt);
6
6
  return blueapi.clientInstance;
7
7
  }
@@ -3,14 +3,34 @@
3
3
  // @generated from file api/cover/costforecast.proto (package blueapi.api.cover, syntax proto3)
4
4
  /* eslint-disable */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.AwsCostForecastSchema = exports.file_api_cover_costforecast = void 0;
6
+ exports.CostForecastAdjustmentSchema = exports.ExternalAdjustmentSchema = exports.CostForecastDetailsSchema = exports.CostGroupSchema = exports.AwsCostForecastSchema = exports.file_api_cover_costforecast = void 0;
7
7
  const codegenv2_1 = require("@bufbuild/protobuf/codegenv2");
8
8
  /**
9
9
  * Describes the file api/cover/costforecast.proto.
10
10
  */
11
- exports.file_api_cover_costforecast = (0, codegenv2_1.fileDesc)("ChxhcGkvY292ZXIvY29zdGZvcmVjYXN0LnByb3RvEhFibHVlYXBpLmFwaS5jb3ZlciLMAQoPQXdzQ29zdEZvcmVjYXN0EgwKBGRhdGUYASABKAkSDwoHYWNjb3VudBgCIAEoCRITCgtwcm9kdWN0Q29kZRgDIAEoCRIMCgRjb3N0GAQgASgBEhIKCmxvd2VyQm91bmQYBSABKAESEgoKdXBwZXJCb3VuZBgGIAEoARIVCg11bmJsZW5kZWRDb3N0GAcgASgBEhsKE3VuYmxlbmRlZExvd2VyQm91bmQYCCABKAESGwoTdW5ibGVuZGVkVXBwZXJCb3VuZBgJIAEoAUJqCh9jbG91ZC5hbHBoYXVzLmJsdWVhcGkuYXBpLmNvdmVyQhlBcGlDb3ZlckNvc3RGb3JlY2FzdFByb3RvWixnaXRodWIuY29tL2FscGhhdXNsYWJzL2JsdWUtc2RrLWdvL2FwaS9jb3ZlcmIGcHJvdG8z");
11
+ exports.file_api_cover_costforecast = (0, codegenv2_1.fileDesc)("ChxhcGkvY292ZXIvY29zdGZvcmVjYXN0LnByb3RvEhFibHVlYXBpLmFwaS5jb3ZlciLMAQoPQXdzQ29zdEZvcmVjYXN0EgwKBGRhdGUYASABKAkSDwoHYWNjb3VudBgCIAEoCRITCgtwcm9kdWN0Q29kZRgDIAEoCRIMCgRjb3N0GAQgASgBEhIKCmxvd2VyQm91bmQYBSABKAESEgoKdXBwZXJCb3VuZBgGIAEoARIVCg11bmJsZW5kZWRDb3N0GAcgASgBEhsKE3VuYmxlbmRlZExvd2VyQm91bmQYCCABKAESGwoTdW5ibGVuZGVkVXBwZXJCb3VuZBgJIAEoASIlCglDb3N0R3JvdXASCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCSLjAQoTQ29zdEZvcmVjYXN0RGV0YWlscxIKCgJpZBgBIAEoCRIUCgxmb3JlY2FzdE5hbWUYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSLwoJY29zdGdyb3VwGAQgASgLMhwuYmx1ZWFwaS5hcGkuY292ZXIuQ29zdEdyb3VwEhEKCXN0YXJ0RGF0ZRgFIAEoCRIPCgdlbmREYXRlGAYgASgJEhEKCWNyZWF0ZWRCeRgHIAEoCRIUCgxjcmVhdGlvbkRhdGUYCCABKAkSFwoPbGFzdFVwZGF0ZWREYXRlGAkgASgJIoMBChJFeHRlcm5hbEFkanVzdG1lbnQSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRI+CgthZGp1c3RtZW50cxgEIAMoCzIpLmJsdWVhcGkuYXBpLmNvdmVyLkNvc3RGb3JlY2FzdEFkanVzdG1lbnQiOwoWQ29zdEZvcmVjYXN0QWRqdXN0bWVudBINCgVtb250aBgBIAEoCRISCgphZGp1c3RtZW50GAIgASgBQmoKH2Nsb3VkLmFscGhhdXMuYmx1ZWFwaS5hcGkuY292ZXJCGUFwaUNvdmVyQ29zdEZvcmVjYXN0UHJvdG9aLGdpdGh1Yi5jb20vYWxwaGF1c2xhYnMvYmx1ZS1zZGstZ28vYXBpL2NvdmVyYgZwcm90bzM");
12
12
  /**
13
13
  * Describes the message blueapi.api.cover.AwsCostForecast.
14
14
  * Use `create(AwsCostForecastSchema)` to create a new message.
15
15
  */
16
16
  exports.AwsCostForecastSchema = (0, codegenv2_1.messageDesc)(exports.file_api_cover_costforecast, 0);
17
+ /**
18
+ * Describes the message blueapi.api.cover.CostGroup.
19
+ * Use `create(CostGroupSchema)` to create a new message.
20
+ */
21
+ exports.CostGroupSchema = (0, codegenv2_1.messageDesc)(exports.file_api_cover_costforecast, 1);
22
+ /**
23
+ * Describes the message blueapi.api.cover.CostForecastDetails.
24
+ * Use `create(CostForecastDetailsSchema)` to create a new message.
25
+ */
26
+ exports.CostForecastDetailsSchema = (0, codegenv2_1.messageDesc)(exports.file_api_cover_costforecast, 2);
27
+ /**
28
+ * Describes the message blueapi.api.cover.ExternalAdjustment.
29
+ * Use `create(ExternalAdjustmentSchema)` to create a new message.
30
+ */
31
+ exports.ExternalAdjustmentSchema = (0, codegenv2_1.messageDesc)(exports.file_api_cover_costforecast, 3);
32
+ /**
33
+ * Describes the message blueapi.api.cover.CostForecastAdjustment.
34
+ * Use `create(CostForecastAdjustmentSchema)` to create a new message.
35
+ */
36
+ exports.CostForecastAdjustmentSchema = (0, codegenv2_1.messageDesc)(exports.file_api_cover_costforecast, 4);
@@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf";
10
10
  * Describes the file api/cover/costforecast.proto.
11
11
  */
12
12
  export const file_api_cover_costforecast: GenFile = /*@__PURE__*/
13
- fileDesc("ChxhcGkvY292ZXIvY29zdGZvcmVjYXN0LnByb3RvEhFibHVlYXBpLmFwaS5jb3ZlciLMAQoPQXdzQ29zdEZvcmVjYXN0EgwKBGRhdGUYASABKAkSDwoHYWNjb3VudBgCIAEoCRITCgtwcm9kdWN0Q29kZRgDIAEoCRIMCgRjb3N0GAQgASgBEhIKCmxvd2VyQm91bmQYBSABKAESEgoKdXBwZXJCb3VuZBgGIAEoARIVCg11bmJsZW5kZWRDb3N0GAcgASgBEhsKE3VuYmxlbmRlZExvd2VyQm91bmQYCCABKAESGwoTdW5ibGVuZGVkVXBwZXJCb3VuZBgJIAEoAUJqCh9jbG91ZC5hbHBoYXVzLmJsdWVhcGkuYXBpLmNvdmVyQhlBcGlDb3ZlckNvc3RGb3JlY2FzdFByb3RvWixnaXRodWIuY29tL2FscGhhdXNsYWJzL2JsdWUtc2RrLWdvL2FwaS9jb3ZlcmIGcHJvdG8z");
13
+ fileDesc("ChxhcGkvY292ZXIvY29zdGZvcmVjYXN0LnByb3RvEhFibHVlYXBpLmFwaS5jb3ZlciLMAQoPQXdzQ29zdEZvcmVjYXN0EgwKBGRhdGUYASABKAkSDwoHYWNjb3VudBgCIAEoCRITCgtwcm9kdWN0Q29kZRgDIAEoCRIMCgRjb3N0GAQgASgBEhIKCmxvd2VyQm91bmQYBSABKAESEgoKdXBwZXJCb3VuZBgGIAEoARIVCg11bmJsZW5kZWRDb3N0GAcgASgBEhsKE3VuYmxlbmRlZExvd2VyQm91bmQYCCABKAESGwoTdW5ibGVuZGVkVXBwZXJCb3VuZBgJIAEoASIlCglDb3N0R3JvdXASCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCSLjAQoTQ29zdEZvcmVjYXN0RGV0YWlscxIKCgJpZBgBIAEoCRIUCgxmb3JlY2FzdE5hbWUYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSLwoJY29zdGdyb3VwGAQgASgLMhwuYmx1ZWFwaS5hcGkuY292ZXIuQ29zdEdyb3VwEhEKCXN0YXJ0RGF0ZRgFIAEoCRIPCgdlbmREYXRlGAYgASgJEhEKCWNyZWF0ZWRCeRgHIAEoCRIUCgxjcmVhdGlvbkRhdGUYCCABKAkSFwoPbGFzdFVwZGF0ZWREYXRlGAkgASgJIoMBChJFeHRlcm5hbEFkanVzdG1lbnQSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRI+CgthZGp1c3RtZW50cxgEIAMoCzIpLmJsdWVhcGkuYXBpLmNvdmVyLkNvc3RGb3JlY2FzdEFkanVzdG1lbnQiOwoWQ29zdEZvcmVjYXN0QWRqdXN0bWVudBINCgVtb250aBgBIAEoCRISCgphZGp1c3RtZW50GAIgASgBQmoKH2Nsb3VkLmFscGhhdXMuYmx1ZWFwaS5hcGkuY292ZXJCGUFwaUNvdmVyQ29zdEZvcmVjYXN0UHJvdG9aLGdpdGh1Yi5jb20vYWxwaGF1c2xhYnMvYmx1ZS1zZGstZ28vYXBpL2NvdmVyYgZwcm90bzM");
14
14
 
15
15
  /**
16
16
  * @generated from message blueapi.api.cover.AwsCostForecast
@@ -79,3 +79,142 @@ export type AwsCostForecast = Message<"blueapi.api.cover.AwsCostForecast"> & {
79
79
  export const AwsCostForecastSchema: GenMessage<AwsCostForecast> = /*@__PURE__*/
80
80
  messageDesc(file_api_cover_costforecast, 0);
81
81
 
82
+ /**
83
+ * @generated from message blueapi.api.cover.CostGroup
84
+ */
85
+ export type CostGroup = Message<"blueapi.api.cover.CostGroup"> & {
86
+ /**
87
+ * @generated from field: string id = 1;
88
+ */
89
+ id: string;
90
+
91
+ /**
92
+ * cost group name
93
+ *
94
+ * @generated from field: string name = 2;
95
+ */
96
+ name: string;
97
+ };
98
+
99
+ /**
100
+ * Describes the message blueapi.api.cover.CostGroup.
101
+ * Use `create(CostGroupSchema)` to create a new message.
102
+ */
103
+ export const CostGroupSchema: GenMessage<CostGroup> = /*@__PURE__*/
104
+ messageDesc(file_api_cover_costforecast, 1);
105
+
106
+ /**
107
+ * @generated from message blueapi.api.cover.CostForecastDetails
108
+ */
109
+ export type CostForecastDetails = Message<"blueapi.api.cover.CostForecastDetails"> & {
110
+ /**
111
+ * @generated from field: string id = 1;
112
+ */
113
+ id: string;
114
+
115
+ /**
116
+ * @generated from field: string forecastName = 2;
117
+ */
118
+ forecastName: string;
119
+
120
+ /**
121
+ * @generated from field: string description = 3;
122
+ */
123
+ description: string;
124
+
125
+ /**
126
+ * @generated from field: blueapi.api.cover.CostGroup costgroup = 4;
127
+ */
128
+ costgroup?: CostGroup;
129
+
130
+ /**
131
+ * @generated from field: string startDate = 5;
132
+ */
133
+ startDate: string;
134
+
135
+ /**
136
+ * @generated from field: string endDate = 6;
137
+ */
138
+ endDate: string;
139
+
140
+ /**
141
+ * @generated from field: string createdBy = 7;
142
+ */
143
+ createdBy: string;
144
+
145
+ /**
146
+ * @generated from field: string creationDate = 8;
147
+ */
148
+ creationDate: string;
149
+
150
+ /**
151
+ * @generated from field: string lastUpdatedDate = 9;
152
+ */
153
+ lastUpdatedDate: string;
154
+ };
155
+
156
+ /**
157
+ * Describes the message blueapi.api.cover.CostForecastDetails.
158
+ * Use `create(CostForecastDetailsSchema)` to create a new message.
159
+ */
160
+ export const CostForecastDetailsSchema: GenMessage<CostForecastDetails> = /*@__PURE__*/
161
+ messageDesc(file_api_cover_costforecast, 2);
162
+
163
+ /**
164
+ * @generated from message blueapi.api.cover.ExternalAdjustment
165
+ */
166
+ export type ExternalAdjustment = Message<"blueapi.api.cover.ExternalAdjustment"> & {
167
+ /**
168
+ * @generated from field: string id = 1;
169
+ */
170
+ id: string;
171
+
172
+ /**
173
+ * Name of the adjustment
174
+ *
175
+ * @generated from field: string name = 2;
176
+ */
177
+ name: string;
178
+
179
+ /**
180
+ * @generated from field: string description = 3;
181
+ */
182
+ description: string;
183
+
184
+ /**
185
+ * @generated from field: repeated blueapi.api.cover.CostForecastAdjustment adjustments = 4;
186
+ */
187
+ adjustments: CostForecastAdjustment[];
188
+ };
189
+
190
+ /**
191
+ * Describes the message blueapi.api.cover.ExternalAdjustment.
192
+ * Use `create(ExternalAdjustmentSchema)` to create a new message.
193
+ */
194
+ export const ExternalAdjustmentSchema: GenMessage<ExternalAdjustment> = /*@__PURE__*/
195
+ messageDesc(file_api_cover_costforecast, 3);
196
+
197
+ /**
198
+ * @generated from message blueapi.api.cover.CostForecastAdjustment
199
+ */
200
+ export type CostForecastAdjustment = Message<"blueapi.api.cover.CostForecastAdjustment"> & {
201
+ /**
202
+ * For monthly adjustment, format is yyyy-mm.
203
+ *
204
+ * @generated from field: string month = 1;
205
+ */
206
+ month: string;
207
+
208
+ /**
209
+ * @generated from field: double adjustment = 2;
210
+ */
211
+ adjustment: number;
212
+ };
213
+
214
+ /**
215
+ * Describes the message blueapi.api.cover.CostForecastAdjustment.
216
+ * Use `create(CostForecastAdjustmentSchema)` to create a new message.
217
+ */
218
+ export const CostForecastAdjustmentSchema: GenMessage<CostForecastAdjustment> = /*@__PURE__*/
219
+ messageDesc(file_api_cover_costforecast, 4);
220
+
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NewBillingClient = NewBillingClient;
4
4
  const billing_pb_1 = require("./billing_pb");
5
5
  const conn_1 = require("../../conn/conn");
6
- function NewBillingClient(...opts) {
7
- const blueapi = new conn_1.BlueAPIService(billing_pb_1.Billing, "billing", opts);
6
+ function NewBillingClient(opt) {
7
+ const blueapi = new conn_1.BlueAPIService(billing_pb_1.Billing, "billing", opt);
8
8
  return blueapi.clientInstance;
9
9
  }
@@ -1,7 +1,7 @@
1
1
  import { Billing } from "./billing_pb";
2
2
  import { BlueAPIService, ConnectOption } from "../../conn/conn";
3
3
 
4
- export function NewBillingClient(...opts: ConnectOption[]) {
5
- const blueapi = new BlueAPIService(Billing, "billing", opts);
4
+ export function NewBillingClient(opt?: ConnectOption) {
5
+ const blueapi = new BlueAPIService(Billing, "billing", opt);
6
6
  return blueapi.clientInstance;
7
7
  }
package/conn/conn.js CHANGED
@@ -1,23 +1,25 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WithAccessToken = exports.BlueAPIService = void 0;
6
+ exports.BlueCredentials = exports.WithNewBlueCredentials = exports.WithAccessToken = exports.WithDefaultCredentials = exports.BlueAPIService = void 0;
4
7
  const connect_1 = require("@connectrpc/connect");
5
8
  const connect_web_1 = require("@connectrpc/connect-web");
6
9
  const connect_devtools_1 = require("connect-devtools");
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const DEFAULT_BLUE_RPC_HOST = "https://bluerpc.alphaus.cloud:8443";
12
+ const DEFAULT_AUTH_URL = "https://login.alphaus.cloud/ripple/access_token";
7
13
  class BlueAPIService {
8
14
  get clientInstance() {
9
15
  return this.client;
10
16
  }
11
- constructor(service, serviceName, connectOptions = []) {
17
+ constructor(service, serviceName, connectOption = new WithDefaultCredentials()) {
12
18
  this.serviceName = serviceName;
13
- this.host = "https://bluerpc.alphaus.cloud:8443";
14
- if (!connectOptions.length) {
15
- throw new Error("At least one ConnectOption is required");
16
- }
17
19
  const interceptors = [
18
20
  (next) => async (req) => {
19
21
  req.header.set("service-name", this.serviceName);
20
- connectOptions.forEach((option) => option.apply(req.header));
22
+ await connectOption.apply(req.header);
21
23
  return await next(req);
22
24
  },
23
25
  ];
@@ -26,19 +28,96 @@ class BlueAPIService {
26
28
  interceptors.push(connect_devtools_1.devtoolsInterceptor);
27
29
  }
28
30
  const transport = (0, connect_web_1.createGrpcWebTransport)({
29
- baseUrl: this.host,
31
+ baseUrl: connectOption.getHost(),
30
32
  interceptors: interceptors,
31
33
  });
32
34
  this.client = (0, connect_1.createClient)(service, transport);
33
35
  }
34
36
  }
35
37
  exports.BlueAPIService = BlueAPIService;
38
+ class WithDefaultCredentials {
39
+ constructor() {
40
+ this.env = process.env;
41
+ this.clientId =
42
+ this.env.ALPHAUS_CLIENT_ID ||
43
+ this.env.ALPHAUS_RIPPLE_CLIENT_ID ||
44
+ this.env.ALPHAUS_WAVE_CLIENT_ID;
45
+ this.clientSecret =
46
+ this.env.ALPHAUS_CLIENT_SECRET ||
47
+ this.env.ALPHAUS_RIPPLE_CLIENT_SECRET ||
48
+ this.env.ALPHAUS_WAVE_CLIENT_SECRET;
49
+ if (!this.clientId && !this.clientSecret) {
50
+ throw new Error("Missing client ID and client secret");
51
+ }
52
+ }
53
+ getHost() {
54
+ return DEFAULT_BLUE_RPC_HOST;
55
+ }
56
+ async apply(req) {
57
+ // get access token
58
+ const creds = new BlueCredentials({
59
+ clientId: this.clientId,
60
+ clientSecret: this.clientSecret,
61
+ authUrl: this.env.ALPHAUS_AUTH_URL,
62
+ userName: this.env.ALPHAUS_USERNAME,
63
+ password: this.env.ALPHAUS_PASSWORD,
64
+ });
65
+ req.set("Authorization", `Bearer ${await creds.getAccessToken()}`);
66
+ }
67
+ }
68
+ exports.WithDefaultCredentials = WithDefaultCredentials;
36
69
  class WithAccessToken {
37
- constructor(accessToken) {
70
+ constructor(accessToken, host) {
38
71
  this.accessToken = accessToken;
72
+ this.host = host;
73
+ }
74
+ getHost() {
75
+ return this.host || DEFAULT_BLUE_RPC_HOST;
39
76
  }
40
77
  apply(req) {
41
78
  req.set("Authorization", `Bearer ${this.accessToken}`);
79
+ return Promise.resolve();
42
80
  }
43
81
  }
44
82
  exports.WithAccessToken = WithAccessToken;
83
+ class WithNewBlueCredentials {
84
+ constructor(creds) {
85
+ this.creds = creds;
86
+ }
87
+ getHost() {
88
+ return this.creds.input.host || DEFAULT_BLUE_RPC_HOST;
89
+ }
90
+ async apply(req) {
91
+ req.set("Authorization", `Bearer ${await this.creds.getAccessToken()}`);
92
+ }
93
+ }
94
+ exports.WithNewBlueCredentials = WithNewBlueCredentials;
95
+ class BlueCredentials {
96
+ constructor(input) {
97
+ this.input = input;
98
+ }
99
+ isUserPassAuth() {
100
+ return !!(this.input.userName && this.input.password);
101
+ }
102
+ async getAccessToken() {
103
+ const gt = this.isUserPassAuth() ? "password" : "client_credentials";
104
+ const url = this.input.authUrl || DEFAULT_AUTH_URL;
105
+ try {
106
+ const formData = new FormData();
107
+ formData.append("client_id", this.input.clientId);
108
+ formData.append("client_secret", this.input.clientSecret);
109
+ formData.append("grant_type", gt);
110
+ formData.append("scope", "openid");
111
+ if (this.isUserPassAuth()) {
112
+ formData.append("username", this.input.userName);
113
+ formData.append("password", this.input.password);
114
+ }
115
+ const response = await axios_1.default.post(url, formData);
116
+ return response.data.access_token;
117
+ }
118
+ catch (error) {
119
+ throw new Error(`Failed to get access token: ${error}`);
120
+ }
121
+ }
122
+ }
123
+ exports.BlueCredentials = BlueCredentials;
package/conn/conn.ts CHANGED
@@ -2,10 +2,12 @@ import { createClient, Interceptor, type Client } from "@connectrpc/connect";
2
2
  import { createGrpcWebTransport } from "@connectrpc/connect-web";
3
3
  import type { DescService } from "@bufbuild/protobuf";
4
4
  import { devtoolsInterceptor } from "connect-devtools";
5
+ import axios from "axios";
5
6
 
7
+ const DEFAULT_BLUE_RPC_HOST = "https://bluerpc.alphaus.cloud:8443";
8
+ const DEFAULT_AUTH_URL = "https://login.alphaus.cloud/ripple/access_token";
6
9
  export class BlueAPIService<Service extends DescService> {
7
10
  private client: Client<Service>;
8
- private host: string = "https://bluerpc.alphaus.cloud:8443";
9
11
 
10
12
  get clientInstance(): Client<Service> {
11
13
  return this.client;
@@ -14,16 +16,12 @@ export class BlueAPIService<Service extends DescService> {
14
16
  constructor(
15
17
  service: Service,
16
18
  private serviceName: string,
17
- connectOptions: ConnectOption[] = []
19
+ connectOption: ConnectOption = new WithDefaultCredentials()
18
20
  ) {
19
- if (!connectOptions.length) {
20
- throw new Error("At least one ConnectOption is required");
21
- }
22
-
23
21
  const interceptors: Interceptor[] = [
24
22
  (next) => async (req) => {
25
23
  req.header.set("service-name", this.serviceName);
26
- connectOptions.forEach((option) => option.apply(req.header));
24
+ await connectOption.apply(req.header);
27
25
  return await next(req);
28
26
  },
29
27
  ];
@@ -36,22 +34,117 @@ export class BlueAPIService<Service extends DescService> {
36
34
  }
37
35
 
38
36
  const transport = createGrpcWebTransport({
39
- baseUrl: this.host,
37
+ baseUrl: connectOption.getHost(),
40
38
  interceptors: interceptors,
41
39
  });
42
40
 
43
41
  this.client = createClient(service, transport);
44
42
  }
45
43
  }
46
-
47
44
  export interface ConnectOption {
48
- apply(req: Headers): void;
45
+ apply(req: Headers): Promise<void>;
46
+ getHost(): string;
49
47
  }
50
48
 
49
+ export class WithDefaultCredentials implements ConnectOption {
50
+ private readonly clientId?: string;
51
+ private readonly clientSecret?: string;
52
+ private readonly env = process.env;
53
+
54
+ constructor() {
55
+ this.clientId =
56
+ this.env.ALPHAUS_CLIENT_ID ||
57
+ this.env.ALPHAUS_RIPPLE_CLIENT_ID ||
58
+ this.env.ALPHAUS_WAVE_CLIENT_ID;
59
+ this.clientSecret =
60
+ this.env.ALPHAUS_CLIENT_SECRET ||
61
+ this.env.ALPHAUS_RIPPLE_CLIENT_SECRET ||
62
+ this.env.ALPHAUS_WAVE_CLIENT_SECRET;
63
+
64
+ if (!this.clientId && !this.clientSecret) {
65
+ throw new Error("Missing client ID and client secret");
66
+ }
67
+ }
68
+
69
+ getHost(): string {
70
+ return DEFAULT_BLUE_RPC_HOST;
71
+ }
72
+
73
+ async apply(req: Headers): Promise<void> {
74
+ // get access token
75
+ const creds = new BlueCredentials({
76
+ clientId: this.clientId!,
77
+ clientSecret: this.clientSecret!,
78
+ authUrl: this.env.ALPHAUS_AUTH_URL,
79
+ userName: this.env.ALPHAUS_USERNAME,
80
+ password: this.env.ALPHAUS_PASSWORD,
81
+ });
82
+ req.set("Authorization", `Bearer ${await creds.getAccessToken()}`);
83
+ }
84
+ }
51
85
  export class WithAccessToken implements ConnectOption {
52
- constructor(private accessToken: string) {}
86
+ constructor(
87
+ private readonly accessToken: string,
88
+ private readonly host?: string
89
+ ) {}
90
+
91
+ getHost(): string {
92
+ return this.host || DEFAULT_BLUE_RPC_HOST;
93
+ }
53
94
 
54
- apply(req: Headers): void {
95
+ apply(req: Headers): Promise<void> {
55
96
  req.set("Authorization", `Bearer ${this.accessToken}`);
97
+ return Promise.resolve();
56
98
  }
57
99
  }
100
+
101
+ export class WithNewBlueCredentials implements ConnectOption {
102
+ constructor(private creds: BlueCredentials) {}
103
+
104
+ getHost(): string {
105
+ return this.creds.input.host || DEFAULT_BLUE_RPC_HOST;
106
+ }
107
+
108
+ async apply(req: Headers): Promise<void> {
109
+ req.set("Authorization", `Bearer ${await this.creds.getAccessToken()}`);
110
+ }
111
+ }
112
+
113
+ export class BlueCredentials {
114
+ constructor(public readonly input: BlueCredentials.Input) {}
115
+
116
+ private isUserPassAuth(): boolean {
117
+ return !!(this.input.userName && this.input.password);
118
+ }
119
+
120
+ async getAccessToken() {
121
+ const gt = this.isUserPassAuth() ? "password" : "client_credentials";
122
+ const url = this.input.authUrl || DEFAULT_AUTH_URL;
123
+ try {
124
+ const formData = new FormData();
125
+ formData.append("client_id", this.input.clientId);
126
+ formData.append("client_secret", this.input.clientSecret);
127
+ formData.append("grant_type", gt);
128
+ formData.append("scope", "openid");
129
+ if (this.isUserPassAuth()) {
130
+ formData.append("username", this.input.userName!);
131
+ formData.append("password", this.input.password!);
132
+ }
133
+ const response = await axios.post(url, formData);
134
+ return response.data.access_token;
135
+ } catch (error) {
136
+ throw new Error(`Failed to get access token: ${error}`);
137
+ }
138
+ }
139
+ }
140
+
141
+ namespace BlueCredentials {
142
+ export type Input = {
143
+ clientId: string;
144
+ clientSecret: string;
145
+ authUrl?: string;
146
+ userName?: string;
147
+ password?: string;
148
+ host?: string;
149
+ };
150
+ }
package/cost/v1/client.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NewCostClient = NewCostClient;
4
4
  const cost_pb_1 = require("./cost_pb");
5
5
  const conn_1 = require("../../conn/conn");
6
- function NewCostClient(...opts) {
7
- const blueapi = new conn_1.BlueAPIService(cost_pb_1.Cost, "cost", opts);
6
+ function NewCostClient(opt) {
7
+ const blueapi = new conn_1.BlueAPIService(cost_pb_1.Cost, "cost", opt);
8
8
  return blueapi.clientInstance;
9
9
  }
package/cost/v1/client.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Cost } from "./cost_pb";
2
2
  import { BlueAPIService, ConnectOption } from "../../conn/conn";
3
3
 
4
- export function NewCostClient(...opts: ConnectOption[]) {
5
- const blueapi = new BlueAPIService(Cost, "cost", opts);
4
+ export function NewCostClient(opt?: ConnectOption) {
5
+ const blueapi = new BlueAPIService(Cost, "cost", opt);
6
6
  return blueapi.clientInstance;
7
7
  }