macbid-ts-api 1.0.0-beta.3 → 1.0.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/MacBid.d.ts CHANGED
@@ -8,6 +8,16 @@ export interface AuthInfo {
8
8
  refresh_token?: string;
9
9
  refresh_token_expiration?: Date;
10
10
  validation_code?: string;
11
+ device_id?: string;
12
+ }
13
+ /** JSON-serializable auth fields safe to persist (no credentials). */
14
+ export interface SerializableAuthState {
15
+ token?: string;
16
+ refresh_token?: string;
17
+ token_expiration?: string;
18
+ refresh_token_expiration?: string;
19
+ user_id?: string;
20
+ device_id?: string;
11
21
  }
12
22
  export interface WatchlistFull {
13
23
  auction_lot_id: number;
@@ -64,9 +74,20 @@ export declare class MacBid {
64
74
  API_ROOT: string;
65
75
  private macbid_session_headers;
66
76
  private auth_info;
67
- private tokenFilePath?;
68
- constructor(auth_info: AuthInfo, tokenFilePath?: string);
69
- authenticate: () => Promise<void>;
77
+ private mergeAuthInfo;
78
+ /** Returns persistable auth state (tokens and device_id). */
79
+ getAuthState: () => SerializableAuthState;
80
+ static serializeAuthState: (authInfo: Partial<AuthInfo>) => SerializableAuthState;
81
+ static parseAuthState: (data: string | SerializableAuthState) => Partial<AuthInfo>;
82
+ private clearLoginSession;
83
+ /** device_id saved without tokens means an SMS was sent and we're waiting for the code. */
84
+ private isAwaiting2FA;
85
+ /**
86
+ * Establish or refresh a session. Pass credentials and any saved tokens / device_id.
87
+ * Omit params on later calls to reuse the current session.
88
+ * Returns persistable auth state; use getAuthState() after API calls that may refresh tokens.
89
+ */
90
+ authenticate: (params?: Partial<AuthInfo>) => Promise<SerializableAuthState>;
70
91
  get: (path: string) => Promise<MacBidApiResponse>;
71
92
  post: (path: string, options?: RequestInit) => Promise<MacBidApiResponse>;
72
93
  /**
@@ -74,12 +95,13 @@ export declare class MacBid {
74
95
  */
75
96
  private check_auth;
76
97
  /**
77
- * Do the login request
78
- * @param email - User email
79
- * @param password - User password
80
- * @param validation_code - Optional validation code. If not provided, will check auth_info.validation_code
98
+ * Validate the access code and get tokens
81
99
  */
82
- login: (email: string, password: string, validation_code?: string) => Promise<boolean>;
100
+ private validateCode;
101
+ /**
102
+ * Do the login request using auth_info fields.
103
+ */
104
+ private login;
83
105
  get_refresh_token_expiration: () => Date;
84
106
  /**
85
107
  * Check if the access token is expired or about to expire (within 5 minutes)
@@ -101,14 +123,6 @@ export declare class MacBid {
101
123
  * Returns the logged in user's favorites, and all of their (visible) attributes.
102
124
  */
103
125
  get_watchlist: () => Promise<WatchlistFull[]>;
104
- /**
105
- * Save tokens to file for persistence across restarts
106
- */
107
- private saveTokens;
108
- /**
109
- * Load tokens from file
110
- */
111
- static loadTokens: (tokenFilePath: string) => Promise<Partial<AuthInfo> | null>;
112
126
  }
113
127
  export default MacBid;
114
128
  //# sourceMappingURL=MacBid.d.ts.map
package/MacBid.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"MacBid.d.ts","sourceRoot":"","sources":["MacBid.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wBAAwB,CAAC,EAAE,IAAI,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,IAAI,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,IAAI,CAAC;IAClB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,mBAAmB,EAAE,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,IAAI,CAAC;IAC1B,cAAc,EAAE,IAAI,CAAC;IACrB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,aAAa,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,WAAW,CAAC;CAC3B;AAED,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED,oBAAY,aAAa;IACvB,OAAO,YAAY;IACnB,OAAO,aAAa;IACpB,OAAO,aAAa;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,QAAQ;IACjD,IAAI,EAAE,MAAM,OAAO,CAAC;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC,CAAC;CACJ;AAED,qBAAa,MAAM;IACV,cAAc,SAAyB;IACvC,QAAQ,SAAiC;IAEhD,OAAO,CAAC,sBAAsB,CAE5B;IACF,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,aAAa,CAAC,CAAS;gBAEnB,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM;IAMhD,YAAY,sBAoCjB;IAEK,GAAG,SAAgB,MAAM,KAAG,QAAQ,iBAAiB,CAAC,CAK3D;IAEK,IAAI,SACH,MAAM,YACF,WAAW,KACpB,QAAQ,iBAAiB,CAAC,CAY3B;IAEF;;OAEG;IACH,OAAO,CAAC,UAAU,CAKhB;IAEF;;;;;OAKG;IACI,KAAK,UACH,MAAM,YACH,MAAM,oBACE,MAAM,KACvB,QAAQ,OAAO,CAAC,CAmEjB;IAEK,4BAA4B,QAAO,IAAI,CAM7C;IAED;;OAEG;IACH,OAAO,CAAC,cAAc,CAOrB;IAED;;OAEG;IACH,OAAO,CAAC,qBAAqB,CAK5B;IAED;;OAEG;IACI,YAAY,QAAa,QAAQ,OAAO,CAAC,CA0D/C;IAED;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAIvB;IAED;;OAEG;IACI,aAAa,QAAa,QAAQ,aAAa,EAAE,CAAC,CAOvD;IAEF;;OAEG;IACH,OAAO,CAAC,UAAU,CAoBhB;IAEF;;OAEG;IACH,OAAc,UAAU,kBAAyB,MAAM,KAAG,QAAQ,QAAQ,QAAQ,CAAC,GAAG,IAAI,CAAC,CAsBzF;CACH;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"MacBid.d.ts","sourceRoot":"","sources":["MacBid.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wBAAwB,CAAC,EAAE,IAAI,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,IAAI,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,IAAI,CAAC;IAClB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,mBAAmB,EAAE,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,IAAI,CAAC;IAC1B,cAAc,EAAE,IAAI,CAAC;IACrB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,aAAa,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,WAAW,CAAC;CAC3B;AAED,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED,oBAAY,aAAa;IACvB,OAAO,YAAY;IACnB,OAAO,aAAa;IACpB,OAAO,aAAa;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,QAAQ;IACjD,IAAI,EAAE,MAAM,OAAO,CAAC;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC,CAAC;CACJ;AAED,qBAAa,MAAM;IACV,cAAc,SAAyB;IACvC,QAAQ,SAAiC;IAEhD,OAAO,CAAC,sBAAsB,CAE5B;IACF,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,aAAa,CAEnB;IAEF,6DAA6D;IACtD,YAAY,QAAO,qBAAqB,CAE7C;IAEF,OAAc,kBAAkB,GAC9B,UAAU,OAAO,CAAC,QAAQ,CAAC,KAC1B,qBAAqB,CAOrB;IAEH,OAAc,cAAc,GAC1B,MAAM,MAAM,GAAG,qBAAqB,KACnC,OAAO,CAAC,QAAQ,CAAC,CAkBlB;IAEF,OAAO,CAAC,iBAAiB,CASvB;IAEF,2FAA2F;IAC3F,OAAO,CAAC,aAAa,CAMnB;IAEF;;;;OAIG;IACI,YAAY,GACjB,SAAS,OAAO,CAAC,QAAQ,CAAC,KACzB,OAAO,CAAC,qBAAqB,CAAC,CA+C/B;IAEK,GAAG,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,iBAAiB,CAAC,CAK3D;IAEK,IAAI,GACT,MAAM,MAAM,EACZ,UAAU,WAAW,KACpB,OAAO,CAAC,iBAAiB,CAAC,CAY3B;IAEF;;OAEG;IACH,OAAO,CAAC,UAAU,CAKhB;IAEF;;OAEG;IACH,OAAO,CAAC,YAAY,CAyElB;IAEF;;OAEG;IACH,OAAO,CAAC,KAAK,CAwDX;IAEK,4BAA4B,QAAO,IAAI,CAM7C;IAED;;OAEG;IACH,OAAO,CAAC,cAAc,CAOrB;IAED;;OAEG;IACH,OAAO,CAAC,qBAAqB,CAK5B;IAED;;OAEG;IACI,YAAY,QAAa,OAAO,CAAC,OAAO,CAAC,CA0D/C;IAED;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAIvB;IAED;;OAEG;IACI,aAAa,QAAa,OAAO,CAAC,aAAa,EAAE,CAAC,CAOvD;CACH;AAED,eAAe,MAAM,CAAC"}
package/MacBid.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import fetch from "node-fetch";
2
- import { promises as fs } from "node:fs";
2
+ import { randomUUID } from "node:crypto";
3
3
  export var AuctionType;
4
4
  (function (AuctionType) {
5
5
  AuctionType["Pallet"] = "pallet";
@@ -17,50 +17,109 @@ export class MacBid {
17
17
  macbid_session_headers = {
18
18
  "Content-Type": "application/json",
19
19
  };
20
- auth_info;
21
- tokenFilePath;
22
- constructor(auth_info, tokenFilePath) {
23
- this.auth_info = auth_info;
24
- this.tokenFilePath = tokenFilePath;
25
- this.authenticate();
26
- }
27
- authenticate = async () => {
28
- if (this.auth_info) {
29
- // If we have a token, use it (will be auto-refreshed if expired)
30
- if (this.auth_info.token) {
31
- this.macbid_session_headers["Authorization"] = this.auth_info
32
- .token;
20
+ auth_info = {};
21
+ mergeAuthInfo = (params) => {
22
+ Object.assign(this.auth_info, params);
23
+ };
24
+ /** Returns persistable auth state (tokens and device_id). */
25
+ getAuthState = () => {
26
+ return MacBid.serializeAuthState(this.auth_info);
27
+ };
28
+ static serializeAuthState = (authInfo) => ({
29
+ token: authInfo.token,
30
+ refresh_token: authInfo.refresh_token,
31
+ token_expiration: authInfo.token_expiration?.toISOString(),
32
+ refresh_token_expiration: authInfo.refresh_token_expiration?.toISOString(),
33
+ user_id: authInfo.user_id,
34
+ device_id: authInfo.device_id,
35
+ });
36
+ static parseAuthState = (data) => {
37
+ const parsed = typeof data === "string"
38
+ ? JSON.parse(data)
39
+ : data;
40
+ return {
41
+ token: parsed.token,
42
+ refresh_token: parsed.refresh_token,
43
+ token_expiration: parsed.token_expiration
44
+ ? new Date(parsed.token_expiration)
45
+ : undefined,
46
+ refresh_token_expiration: parsed.refresh_token_expiration
47
+ ? new Date(parsed.refresh_token_expiration)
48
+ : undefined,
49
+ user_id: parsed.user_id,
50
+ device_id: parsed.device_id,
51
+ };
52
+ };
53
+ clearLoginSession = () => {
54
+ delete this.auth_info.token;
55
+ delete this.auth_info.refresh_token;
56
+ delete this.auth_info.token_expiration;
57
+ delete this.auth_info.refresh_token_expiration;
58
+ delete this.auth_info.user_id;
59
+ delete this.auth_info.device_id;
60
+ delete this.auth_info.validation_code;
61
+ delete this.macbid_session_headers["Authorization"];
62
+ };
63
+ /** device_id saved without tokens means an SMS was sent and we're waiting for the code. */
64
+ isAwaiting2FA = () => {
65
+ return !!(this.auth_info.device_id &&
66
+ !this.auth_info.token &&
67
+ !this.auth_info.refresh_token);
68
+ };
69
+ /**
70
+ * Establish or refresh a session. Pass credentials and any saved tokens / device_id.
71
+ * Omit params on later calls to reuse the current session.
72
+ * Returns persistable auth state; use getAuthState() after API calls that may refresh tokens.
73
+ */
74
+ authenticate = async (params) => {
75
+ if (params) {
76
+ this.mergeAuthInfo(params);
77
+ }
78
+ if (this.auth_info.token) {
79
+ this.macbid_session_headers["Authorization"] = this.auth_info.token;
80
+ if (!this.isTokenExpired()) {
33
81
  console.log("Using existing access token");
34
- // Token will be auto-refreshed by ensureValidToken if needed
35
- return;
82
+ return this.getAuthState();
36
83
  }
37
- // If we have a refresh token but no access token, try to refresh first
38
- if (this.auth_info.refresh_token) {
39
- if (this.isRefreshTokenExpired()) {
40
- console.log("Refresh token has expired, need to login");
84
+ if (this.auth_info.refresh_token && !this.isRefreshTokenExpired()) {
85
+ console.log("Access token expired, refreshing");
86
+ try {
87
+ await this.refreshToken();
88
+ return this.getAuthState();
41
89
  }
42
- else {
43
- console.log("No access token, attempting to refresh using refresh token");
44
- try {
45
- await this.refreshToken();
46
- console.log("Successfully refreshed token");
47
- return;
48
- }
49
- catch (error) {
50
- // If refresh fails, fall through to login
51
- console.warn("Failed to refresh token, attempting login:", error);
52
- }
90
+ catch (error) {
91
+ console.warn("Failed to refresh token, attempting login:", error);
92
+ this.clearLoginSession();
53
93
  }
54
94
  }
55
- // No valid tokens, need to login
56
- if (this.auth_info.email && this.auth_info.password) {
57
- console.log("No valid tokens found, attempting login");
58
- await this.login(this.auth_info.email, this.auth_info.password);
95
+ else {
96
+ this.clearLoginSession();
97
+ }
98
+ }
99
+ else if (this.auth_info.refresh_token) {
100
+ if (this.isRefreshTokenExpired()) {
101
+ console.log("Refresh token has expired, need to login");
102
+ this.clearLoginSession();
59
103
  }
60
104
  else {
61
- throw new Error("Invalid auth_info");
105
+ console.log("No access token, attempting to refresh using refresh token");
106
+ try {
107
+ await this.refreshToken();
108
+ console.log("Successfully refreshed token");
109
+ return this.getAuthState();
110
+ }
111
+ catch (error) {
112
+ console.warn("Failed to refresh token, attempting login:", error);
113
+ this.clearLoginSession();
114
+ }
62
115
  }
63
116
  }
117
+ if (this.auth_info.email && this.auth_info.password) {
118
+ console.log("No valid tokens found, attempting login");
119
+ await this.login();
120
+ return this.getAuthState();
121
+ }
122
+ throw new Error("email and password are required to log in");
64
123
  };
65
124
  get = async (path) => {
66
125
  await this.ensureValidToken();
@@ -91,14 +150,88 @@ export class MacBid {
91
150
  return true;
92
151
  };
93
152
  /**
94
- * Do the login request
95
- * @param email - User email
96
- * @param password - User password
97
- * @param validation_code - Optional validation code. If not provided, will check auth_info.validation_code
153
+ * Validate the access code and get tokens
154
+ */
155
+ validateCode = async (code, device_id) => {
156
+ console.log("Validating code with device_id:", device_id);
157
+ const validation_params = {
158
+ code: code,
159
+ device_id: device_id,
160
+ new_password: "",
161
+ remember_me: false, // Match the browser behavior
162
+ };
163
+ console.log("Sending validation request to /auth/validate-access-code");
164
+ // Use PUT method like the browser does
165
+ const validation_res = await fetch(this.API_ROOT + "/auth/validate-access-code", {
166
+ method: "PUT",
167
+ body: JSON.stringify(validation_params),
168
+ headers: {
169
+ "Content-Type": "application/json",
170
+ },
171
+ });
172
+ const validation_resJson = (await validation_res.json());
173
+ console.log("Validation response status:", validation_res.status);
174
+ const errorMessage = validation_resJson["error"] || validation_resJson["message"] || "";
175
+ const hasError = validation_res.status !== 200 ||
176
+ !!validation_resJson["error"] ||
177
+ (typeof errorMessage === "string" && errorMessage.includes("Missing"));
178
+ if (hasError) {
179
+ console.error("Validation failed:", errorMessage || validation_res.status);
180
+ if (errorMessage.toLowerCase().includes("already verified")) {
181
+ this.clearLoginSession();
182
+ throw new Error("Validation code was already used. Clear saved auth state and authenticate again to request a new code.");
183
+ }
184
+ throw new Error(`Validation failed: ${errorMessage || "Unknown error"}`);
185
+ }
186
+ const access_token = validation_resJson["access_token"];
187
+ const refresh_token = validation_resJson["refresh_token"];
188
+ const user_id = validation_resJson["user_id"];
189
+ const expires = validation_resJson["expires"];
190
+ const expiration_refresh = validation_resJson["expiration_refresh"];
191
+ if (access_token) {
192
+ console.log("Access token received, saving tokens...");
193
+ this.auth_info.token = access_token;
194
+ this.auth_info.user_id = String(user_id);
195
+ this.macbid_session_headers["Authorization"] = this.auth_info.token;
196
+ this.auth_info.token_expiration = new Date(expires * 1000);
197
+ this.auth_info.refresh_token = refresh_token;
198
+ this.auth_info.refresh_token_expiration = new Date(expiration_refresh * 1000);
199
+ delete this.auth_info.validation_code;
200
+ console.log("✓ Login successful");
201
+ return true;
202
+ }
203
+ else {
204
+ console.error("No access token in validation response");
205
+ throw new Error("Login failed: No access token received");
206
+ }
207
+ };
208
+ /**
209
+ * Do the login request using auth_info fields.
98
210
  */
99
- login = async (email, password, validation_code) => {
211
+ login = async () => {
212
+ const email = this.auth_info.email;
213
+ const password = this.auth_info.password;
214
+ if (!email || !password) {
215
+ throw new Error("email and password are required to log in");
216
+ }
217
+ const code = this.auth_info.validation_code;
218
+ if (code) {
219
+ const device_id = this.auth_info.device_id;
220
+ if (!device_id) {
221
+ throw new Error("device_id is required to validate a code");
222
+ }
223
+ console.log("Validation code present, attempting to validate...");
224
+ return await this.validateCode(code, device_id);
225
+ }
226
+ if (this.isAwaiting2FA()) {
227
+ throw new Error("A validation code was already sent for this device_id. Provide validation_code to continue.");
228
+ }
229
+ const device_id = randomUUID();
230
+ this.auth_info.device_id = device_id;
231
+ console.log("Generated new device_id:", device_id);
232
+ console.log("No validation code found, requesting new code...");
100
233
  const login_params = {
101
- device_id: crypto.randomUUID(),
234
+ device_id: device_id,
102
235
  email: email,
103
236
  password: password,
104
237
  ref_code: null,
@@ -108,49 +241,15 @@ export class MacBid {
108
241
  utm_medium: null,
109
242
  utm_source: null,
110
243
  };
111
- // https://api.macdiscount.com/auth/auth-validation
112
244
  const res = await this.post("/auth/auth-validation", {
113
245
  body: JSON.stringify(login_params),
114
246
  });
115
247
  const resJson = await res.json();
116
248
  if (resJson["message"] === "Login validation code sent") {
117
- // Get validation code from parameter, auth_info, or throw error
118
- const code = validation_code ||
119
- this.auth_info.validation_code ||
120
- process.env.MACBID_VALIDATION_CODE;
121
- if (!code) {
122
- throw new Error("Validation code required. Provide it via:\n" +
123
- " 1. login() method parameter: login(email, password, validation_code)\n" +
124
- " 2. AuthInfo.validation_code when creating MacBid instance\n" +
125
- " 3. MACBID_VALIDATION_CODE environment variable");
126
- }
127
- const validation_params = {
128
- code: code,
129
- device_id: login_params.device_id,
130
- new_password: "",
131
- remember_me: true,
132
- };
133
- const validation_res = await this.post("/auth/validate-access-code", {
134
- body: JSON.stringify(validation_params),
135
- });
136
- const validation_resJson = await validation_res.json();
137
- const access_token = validation_resJson["access_token"];
138
- const refresh_token = validation_resJson["refresh_token"];
139
- const user_id = validation_resJson["user_id"];
140
- const expires = validation_resJson["expires"];
141
- const expiration_refresh = validation_resJson["expiration_refresh"];
142
- if (access_token) {
143
- this.auth_info.token = access_token;
144
- this.auth_info.user_id = user_id;
145
- this.macbid_session_headers["Authorization"] = this.auth_info.token;
146
- this.auth_info.token_expiration = new Date(expires * 1000);
147
- this.auth_info.refresh_token = refresh_token;
148
- this.auth_info.refresh_token_expiration = new Date(expiration_refresh * 1000);
149
- await this.saveTokens();
150
- return true;
151
- }
249
+ console.log("✓ Validation code sent");
250
+ throw new Error("Validation code sent. Provide validation_code and authenticate again.");
152
251
  }
153
- console.error(JSON.stringify(resJson, null, 2));
252
+ console.error("Unexpected login response:", JSON.stringify(resJson, null, 2));
154
253
  throw new Error("Login failed");
155
254
  };
156
255
  get_refresh_token_expiration = () => {
@@ -203,9 +302,8 @@ export class MacBid {
203
302
  },
204
303
  });
205
304
  const resJson = (await res.json());
206
- // Check for error response
207
- if (resJson["error"]) {
208
- throw new Error(`Failed to refresh token: ${resJson["error"]}`);
305
+ if (!res.ok || resJson.error) {
306
+ throw new Error(`Failed to refresh token: ${resJson.error || res.status}`);
209
307
  }
210
308
  const access_token = resJson["access_token"];
211
309
  const refresh_token = resJson["refresh_token"];
@@ -222,7 +320,6 @@ export class MacBid {
222
320
  if (expiration_refresh) {
223
321
  this.auth_info.refresh_token_expiration = new Date(expiration_refresh * 1000);
224
322
  }
225
- await this.saveTokens();
226
323
  return true;
227
324
  }
228
325
  else {
@@ -245,49 +342,6 @@ export class MacBid {
245
342
  const res = await this.get(`/auctions/customer/${this.auth_info["user_id"]}/active-auctions`);
246
343
  return (await res.json())["watchlist_full"];
247
344
  };
248
- /**
249
- * Save tokens to file for persistence across restarts
250
- */
251
- saveTokens = async () => {
252
- if (!this.tokenFilePath) {
253
- console.log("No token file path provided, skipping token save");
254
- return;
255
- }
256
- try {
257
- const tokenData = {
258
- token: this.auth_info.token,
259
- refresh_token: this.auth_info.refresh_token,
260
- token_expiration: this.auth_info.token_expiration?.toISOString(),
261
- refresh_token_expiration: this.auth_info.refresh_token_expiration?.toISOString(),
262
- user_id: this.auth_info.user_id,
263
- };
264
- await fs.writeFile(this.tokenFilePath, JSON.stringify(tokenData, null, 2), "utf-8");
265
- console.log("Tokens saved to file:", this.tokenFilePath);
266
- }
267
- catch (error) {
268
- console.warn("Failed to save tokens:", error);
269
- }
270
- };
271
- /**
272
- * Load tokens from file
273
- */
274
- static loadTokens = async (tokenFilePath) => {
275
- try {
276
- const data = await fs.readFile(tokenFilePath, "utf-8");
277
- const tokenData = JSON.parse(data);
278
- return {
279
- token: tokenData.token,
280
- refresh_token: tokenData.refresh_token,
281
- token_expiration: tokenData.token_expiration ? new Date(tokenData.token_expiration) : undefined,
282
- refresh_token_expiration: tokenData.refresh_token_expiration ? new Date(tokenData.refresh_token_expiration) : undefined,
283
- user_id: tokenData.user_id,
284
- };
285
- }
286
- catch (error) {
287
- // File doesn't exist or is invalid, return null
288
- return null;
289
- }
290
- };
291
345
  }
292
346
  export default MacBid;
293
347
  //# sourceMappingURL=MacBid.js.map
package/MacBid.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"MacBid.js","sourceRoot":"","sources":["MacBid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MacBid.js","sourceRoot":"","sources":["MacBid.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "macbid-ts-api",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/pkmnct/macbid-ts-api.git"
@@ -17,35 +17,16 @@
17
17
  "node": ">=16.0.0"
18
18
  },
19
19
  "devDependencies": {
20
- "@types/node-fetch": "^2.6.2",
21
- "@typescript-eslint/eslint-plugin": "^5.61.0",
22
- "@typescript-eslint/parser": "^5.61.0",
23
- "eslint": "^8.44.0",
24
- "eslint-plugin-import": "^2.27.5",
25
- "eslint-plugin-promise": "^6.1.1",
26
- "typescript": "^5.2.2"
27
- },
28
- "eslintConfig": {
29
- "parser": "@typescript-eslint/parser",
30
- "parserOptions": {
31
- "ecmaVersion": 2021,
32
- "sourceType": "module"
33
- },
34
- "extends": [
35
- "eslint:recommended",
36
- "plugin:@typescript-eslint/recommended",
37
- "plugin:promise/recommended",
38
- "plugin:import/recommended",
39
- "plugin:import/typescript"
40
- ],
41
- "plugins": [
42
- "@typescript-eslint",
43
- "promise",
44
- "import"
45
- ]
20
+ "@eslint/js": "^10.0.1",
21
+ "@types/node-fetch": "^2.6.13",
22
+ "eslint": "^10.5.0",
23
+ "eslint-plugin-promise": "^7.3.0",
24
+ "typescript": "^6.0.3",
25
+ "typescript-eslint": "^8.61.1"
46
26
  },
47
27
  "scripts": {
48
28
  "build": "tsc",
29
+ "lint": "eslint .",
49
30
  "prepublish": "npm run build"
50
31
  },
51
32
  "type": "module",
package/readme.md CHANGED
@@ -1 +1,83 @@
1
- # Mac.Bid Typescript API
1
+ # macbid-ts-api
2
+
3
+ Unofficial TypeScript client for the [Mac.Bid](https://www.mac.bid) API.
4
+
5
+ ## Requirements
6
+
7
+ Node.js **>= 16**
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install macbid-ts-api
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import MacBid, { type SerializableAuthState } from "macbid-ts-api";
19
+
20
+ const api = new MacBid();
21
+ let state: SerializableAuthState = {};
22
+
23
+ state = await api.authenticate({
24
+ email: "you@example.com",
25
+ password: "your-password",
26
+ ...state,
27
+ });
28
+
29
+ const watchlist = await api.get_watchlist();
30
+ ```
31
+
32
+ `authenticate()` returns persistable state (tokens and `device_id`, never credentials). Pass it back in on the next call with `...state`.
33
+
34
+ ### Two-factor authentication
35
+
36
+ If SMS verification is required, the first call throws after sending a code. Set `state` from `api.getAuthState()` and call again with the code:
37
+
38
+ ```typescript
39
+ let state: SerializableAuthState = {};
40
+
41
+ try {
42
+ state = await api.authenticate({ email, password, ...state });
43
+ } catch {
44
+ state = api.getAuthState();
45
+ }
46
+
47
+ // User receives SMS, then retry:
48
+ state = await api.authenticate({
49
+ email,
50
+ password,
51
+ validation_code: "123456",
52
+ ...state,
53
+ });
54
+ ```
55
+
56
+ If `device_id` is set but there are no tokens and no `validation_code`, a code was already sent and a new SMS will not be requested.
57
+
58
+ For JSON storage, use `MacBid.serializeAuthState` / `MacBid.parseAuthState`.
59
+
60
+ `AuthInfo` is the type for `authenticate()` params (credentials, `validation_code`, etc.). `SerializableAuthState` is what comes back — safe to persist.
61
+
62
+ ## API
63
+
64
+ | Method | Description |
65
+ |---|---|
66
+ | `authenticate(params?)` | Log in or refresh session; returns persistable state |
67
+ | `get_watchlist()` | Active watchlist items |
68
+ | `get(path)` / `post(path, options?)` | Authenticated API requests |
69
+ | `refreshToken()` | Refresh the access token |
70
+ | `getAuthState()` | Current persistable state |
71
+ | `get_refresh_token_expiration()` | Refresh token expiry |
72
+
73
+ ## Development
74
+
75
+ ```bash
76
+ npm install
77
+ npm run build
78
+ npm run lint
79
+ ```
80
+
81
+ ## License
82
+
83
+ MIT
package/MacBid.ts DELETED
@@ -1,403 +0,0 @@
1
- import fetch, { Response } from "node-fetch";
2
- import { promises as fs } from "node:fs";
3
-
4
- export interface AuthInfo {
5
- email?: string;
6
- password?: string;
7
- token?: string;
8
- token_expiration?: Date;
9
- user_id?: string;
10
- refresh_token?: string;
11
- refresh_token_expiration?: Date;
12
- validation_code?: string;
13
- }
14
-
15
- export interface WatchlistFull {
16
- auction_lot_id: number;
17
- watchlist_date_created: Date;
18
- id: number;
19
- auction_id: number;
20
- closed_date: null;
21
- buyers_assurance_cost: number | null;
22
- expected_close_date: Date;
23
- inventory_id: number;
24
- date_created: Date;
25
- lot_number: string;
26
- listing_url: null;
27
- title: string;
28
- is_open: number;
29
- is_transferrable: number;
30
- total_bids: number;
31
- winning_customer_id: null;
32
- winning_bid_id: null;
33
- winning_bid_amount: number | null;
34
- unique_bidders: number;
35
- product_name: string;
36
- quantity: number;
37
- is_pallet: number;
38
- shipping_height: number | null;
39
- shipping_width: number | null;
40
- shipping_length: number | null;
41
- warehouse_location: string;
42
- shipping_weight: number | null;
43
- case_packed_qty: number | null;
44
- auction_number: string;
45
- retail_price: number;
46
- condition_name: ConditionName;
47
- category: null | string;
48
- image_url: string;
49
- auction_type: AuctionType;
50
- }
51
-
52
- export enum AuctionType {
53
- Pallet = "pallet",
54
- Standard = "standard",
55
- }
56
-
57
- export enum ConditionName {
58
- Damaged = "DAMAGED",
59
- LikeNew = "LIKE NEW",
60
- OpenBox = "OPEN BOX",
61
- }
62
-
63
- export interface MacBidApiResponse extends Response {
64
- json: () => Promise<{
65
- [key: string]: unknown;
66
- }>;
67
- }
68
-
69
- export class MacBid {
70
- public LOGIN_PAGE_URL = "https://www.mac.bid";
71
- public API_ROOT = "https://api.macdiscount.com";
72
-
73
- private macbid_session_headers: { [key: string]: string } = {
74
- "Content-Type": "application/json",
75
- };
76
- private auth_info: AuthInfo;
77
- private tokenFilePath?: string;
78
-
79
- constructor(auth_info: AuthInfo, tokenFilePath?: string) {
80
- this.auth_info = auth_info;
81
- this.tokenFilePath = tokenFilePath;
82
- this.authenticate();
83
- }
84
-
85
- public authenticate = async () => {
86
- if (this.auth_info) {
87
- // If we have a token, use it (will be auto-refreshed if expired)
88
- if (this.auth_info.token) {
89
- this.macbid_session_headers["Authorization"] = this.auth_info
90
- .token as string;
91
- console.log("Using existing access token");
92
- // Token will be auto-refreshed by ensureValidToken if needed
93
- return;
94
- }
95
-
96
- // If we have a refresh token but no access token, try to refresh first
97
- if (this.auth_info.refresh_token) {
98
- if (this.isRefreshTokenExpired()) {
99
- console.log("Refresh token has expired, need to login");
100
- } else {
101
- console.log("No access token, attempting to refresh using refresh token");
102
- try {
103
- await this.refreshToken();
104
- console.log("Successfully refreshed token");
105
- return;
106
- } catch (error) {
107
- // If refresh fails, fall through to login
108
- console.warn("Failed to refresh token, attempting login:", error);
109
- }
110
- }
111
- }
112
-
113
- // No valid tokens, need to login
114
- if (this.auth_info.email && this.auth_info.password) {
115
- console.log("No valid tokens found, attempting login");
116
- await this.login(this.auth_info.email, this.auth_info.password);
117
- } else {
118
- throw new Error("Invalid auth_info");
119
- }
120
- }
121
- };
122
-
123
- public get = async (path: string): Promise<MacBidApiResponse> => {
124
- await this.ensureValidToken();
125
- return (await fetch(this.API_ROOT + path, {
126
- headers: this.macbid_session_headers,
127
- })) as MacBidApiResponse;
128
- };
129
-
130
- public post = async (
131
- path: string,
132
- options?: RequestInit
133
- ): Promise<MacBidApiResponse> => {
134
- // Don't refresh token for auth endpoints
135
- if (!path.includes("/auth/")) {
136
- await this.ensureValidToken();
137
- }
138
- return (await fetch(this.API_ROOT + path, {
139
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
140
- // @ts-ignore
141
- headers: this.macbid_session_headers,
142
- method: "POST",
143
- ...options,
144
- })) as MacBidApiResponse;
145
- };
146
-
147
- /**
148
- * Raise an exception if an endpoint requiring login is called without valid auth
149
- */
150
- private check_auth = (): boolean => {
151
- if (!this.macbid_session_headers["Authorization"]) {
152
- throw new Error("Not authenticated");
153
- }
154
- return true;
155
- };
156
-
157
- /**
158
- * Do the login request
159
- * @param email - User email
160
- * @param password - User password
161
- * @param validation_code - Optional validation code. If not provided, will check auth_info.validation_code
162
- */
163
- public login = async (
164
- email: string,
165
- password: string,
166
- validation_code?: string
167
- ): Promise<boolean> => {
168
- const login_params = {
169
- device_id: crypto.randomUUID(), // TODO: keep this the same to persist sms validation?
170
- email: email,
171
- password: password,
172
- ref_code: null,
173
- ref_r: null,
174
- remember_me: true,
175
- utm_campaign: null,
176
- utm_medium: null,
177
- utm_source: null,
178
- };
179
- // https://api.macdiscount.com/auth/auth-validation
180
- const res = await this.post("/auth/auth-validation", {
181
- body: JSON.stringify(login_params),
182
- });
183
-
184
- const resJson = await res.json();
185
-
186
- if (resJson["message"] === "Login validation code sent") {
187
- // Get validation code from parameter, auth_info, or throw error
188
- const code =
189
- validation_code ||
190
- this.auth_info.validation_code ||
191
- process.env.MACBID_VALIDATION_CODE;
192
-
193
- if (!code) {
194
- throw new Error(
195
- "Validation code required. Provide it via:\n" +
196
- " 1. login() method parameter: login(email, password, validation_code)\n" +
197
- " 2. AuthInfo.validation_code when creating MacBid instance\n" +
198
- " 3. MACBID_VALIDATION_CODE environment variable"
199
- );
200
- }
201
-
202
- const validation_params = {
203
- code: code,
204
- device_id: login_params.device_id,
205
- new_password: "",
206
- remember_me: true,
207
- };
208
-
209
- const validation_res = await this.post("/auth/validate-access-code", {
210
- body: JSON.stringify(validation_params),
211
- });
212
-
213
- const validation_resJson = await validation_res.json();
214
-
215
- const access_token = validation_resJson["access_token"] as string;
216
- const refresh_token = validation_resJson["refresh_token"] as string;
217
- const user_id = validation_resJson["user_id"] as string;
218
- const expires = validation_resJson["expires"] as number;
219
- const expiration_refresh = validation_resJson["expiration_refresh"] as number;
220
-
221
- if (access_token) {
222
- this.auth_info.token = access_token as string;
223
- this.auth_info.user_id = user_id as string;
224
- this.macbid_session_headers["Authorization"] = this.auth_info.token;
225
- this.auth_info.token_expiration = new Date(expires * 1000);
226
- this.auth_info.refresh_token = refresh_token;
227
- this.auth_info.refresh_token_expiration = new Date(expiration_refresh * 1000);
228
- await this.saveTokens();
229
- return true;
230
- }
231
- }
232
- console.error(JSON.stringify(resJson, null, 2));
233
- throw new Error("Login failed");
234
- };
235
-
236
- public get_refresh_token_expiration = (): Date => {
237
- if (this.auth_info.refresh_token_expiration) {
238
- return this.auth_info.refresh_token_expiration;
239
- } else {
240
- throw new Error("Refresh token expiration not set, make sure to login first.");
241
- }
242
- }
243
-
244
- /**
245
- * Check if the access token is expired or about to expire (within 5 minutes)
246
- */
247
- private isTokenExpired = (): boolean => {
248
- if (!this.auth_info.token_expiration) {
249
- return true;
250
- }
251
- // Refresh if token expires within 5 minutes
252
- const bufferTime = 5 * 60 * 1000; // 5 minutes in milliseconds
253
- return Date.now() >= this.auth_info.token_expiration.getTime() - bufferTime;
254
- }
255
-
256
- /**
257
- * Check if the refresh token is expired
258
- */
259
- private isRefreshTokenExpired = (): boolean => {
260
- if (!this.auth_info.refresh_token_expiration) {
261
- return true;
262
- }
263
- return Date.now() >= this.auth_info.refresh_token_expiration.getTime();
264
- }
265
-
266
- /**
267
- * Refresh the access token using the refresh token
268
- */
269
- public refreshToken = async (): Promise<boolean> => {
270
- if (!this.auth_info.refresh_token) {
271
- throw new Error("No refresh token available. Please login again.");
272
- }
273
-
274
- if (this.isRefreshTokenExpired()) {
275
- throw new Error("Refresh token has expired. Please login again.");
276
- }
277
-
278
- const refresh_params = {
279
- refresh_token: this.auth_info.refresh_token,
280
- };
281
-
282
- // Use fetch directly to avoid triggering ensureValidToken and use PUT method
283
- const res = await fetch(this.API_ROOT + "/auth/refresh-token", {
284
- method: "PUT",
285
- body: JSON.stringify(refresh_params),
286
- headers: {
287
- "Content-Type": "application/json",
288
- },
289
- });
290
-
291
- const resJson = (await res.json()) as {
292
- error?: string;
293
- access_token?: string;
294
- refresh_token?: string;
295
- expires?: number;
296
- expiration_refresh?: number;
297
- };
298
-
299
- // Check for error response
300
- if (resJson["error"]) {
301
- throw new Error(`Failed to refresh token: ${resJson["error"]}`);
302
- }
303
-
304
- const access_token = resJson["access_token"] as string;
305
- const refresh_token = resJson["refresh_token"] as string | undefined;
306
- const expires = resJson["expires"] as number;
307
- const expiration_refresh = resJson["expiration_refresh"] as number | undefined;
308
-
309
- if (access_token) {
310
- this.auth_info.token = access_token;
311
- this.macbid_session_headers["Authorization"] = this.auth_info.token;
312
- this.auth_info.token_expiration = new Date(expires * 1000);
313
-
314
- // Update refresh token if a new one is provided
315
- if (refresh_token) {
316
- this.auth_info.refresh_token = refresh_token;
317
- }
318
- if (expiration_refresh) {
319
- this.auth_info.refresh_token_expiration = new Date(expiration_refresh * 1000);
320
- }
321
-
322
- await this.saveTokens();
323
- return true;
324
- } else {
325
- throw new Error("Failed to refresh token: no access token in response");
326
- }
327
- }
328
-
329
- /**
330
- * Ensure the access token is valid, refreshing if necessary
331
- */
332
- private ensureValidToken = async (): Promise<void> => {
333
- if (this.isTokenExpired()) {
334
- await this.refreshToken();
335
- }
336
- }
337
-
338
- /**
339
- * Returns the logged in user's favorites, and all of their (visible) attributes.
340
- */
341
- public get_watchlist = async (): Promise<WatchlistFull[]> => {
342
- this.check_auth();
343
- const res = await this.get(
344
- `/auctions/customer/${this.auth_info["user_id"]}/active-auctions`
345
- );
346
-
347
- return (await res.json())["watchlist_full"] as WatchlistFull[];
348
- };
349
-
350
- /**
351
- * Save tokens to file for persistence across restarts
352
- */
353
- private saveTokens = async (): Promise<void> => {
354
- if (!this.tokenFilePath) {
355
- console.log("No token file path provided, skipping token save");
356
- return;
357
- }
358
-
359
- try {
360
- const tokenData = {
361
- token: this.auth_info.token,
362
- refresh_token: this.auth_info.refresh_token,
363
- token_expiration: this.auth_info.token_expiration?.toISOString(),
364
- refresh_token_expiration: this.auth_info.refresh_token_expiration?.toISOString(),
365
- user_id: this.auth_info.user_id,
366
- };
367
-
368
- await fs.writeFile(this.tokenFilePath, JSON.stringify(tokenData, null, 2), "utf-8");
369
- console.log("Tokens saved to file:", this.tokenFilePath);
370
- } catch (error) {
371
- console.warn("Failed to save tokens:", error);
372
- }
373
- };
374
-
375
- /**
376
- * Load tokens from file
377
- */
378
- public static loadTokens = async (tokenFilePath: string): Promise<Partial<AuthInfo> | null> => {
379
- try {
380
- const data = await fs.readFile(tokenFilePath, "utf-8");
381
- const tokenData = JSON.parse(data) as {
382
- token?: string;
383
- refresh_token?: string;
384
- token_expiration?: string;
385
- refresh_token_expiration?: string;
386
- user_id?: string;
387
- };
388
-
389
- return {
390
- token: tokenData.token,
391
- refresh_token: tokenData.refresh_token,
392
- token_expiration: tokenData.token_expiration ? new Date(tokenData.token_expiration) : undefined,
393
- refresh_token_expiration: tokenData.refresh_token_expiration ? new Date(tokenData.refresh_token_expiration) : undefined,
394
- user_id: tokenData.user_id,
395
- };
396
- } catch (error) {
397
- // File doesn't exist or is invalid, return null
398
- return null;
399
- }
400
- };
401
- }
402
-
403
- export default MacBid;
package/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { default } from "./MacBid.js";
2
- export * from "./MacBid.js";