swcombine-sdk 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.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +404 -0
  3. package/dist/cjs/SWCombine.js +120 -0
  4. package/dist/cjs/SWCombine.js.map +1 -0
  5. package/dist/cjs/auth/OAuthClient.js +195 -0
  6. package/dist/cjs/auth/OAuthClient.js.map +1 -0
  7. package/dist/cjs/auth/TokenManager.js +139 -0
  8. package/dist/cjs/auth/TokenManager.js.map +1 -0
  9. package/dist/cjs/auth/permissions.js +281 -0
  10. package/dist/cjs/auth/permissions.js.map +1 -0
  11. package/dist/cjs/auth/scopes.js +285 -0
  12. package/dist/cjs/auth/scopes.js.map +1 -0
  13. package/dist/cjs/http/HttpClient.js +216 -0
  14. package/dist/cjs/http/HttpClient.js.map +1 -0
  15. package/dist/cjs/http/errors.js +156 -0
  16. package/dist/cjs/http/errors.js.map +1 -0
  17. package/dist/cjs/index.js +48 -0
  18. package/dist/cjs/index.js.map +1 -0
  19. package/dist/cjs/resources/ApiResource.js +44 -0
  20. package/dist/cjs/resources/ApiResource.js.map +1 -0
  21. package/dist/cjs/resources/BaseResource.js +33 -0
  22. package/dist/cjs/resources/BaseResource.js.map +1 -0
  23. package/dist/cjs/resources/CharacterResource.js +178 -0
  24. package/dist/cjs/resources/CharacterResource.js.map +1 -0
  25. package/dist/cjs/resources/DatacardResource.js +42 -0
  26. package/dist/cjs/resources/DatacardResource.js.map +1 -0
  27. package/dist/cjs/resources/EventsResource.js +42 -0
  28. package/dist/cjs/resources/EventsResource.js.map +1 -0
  29. package/dist/cjs/resources/FactionResource.js +162 -0
  30. package/dist/cjs/resources/FactionResource.js.map +1 -0
  31. package/dist/cjs/resources/GalaxyResource.js +184 -0
  32. package/dist/cjs/resources/GalaxyResource.js.map +1 -0
  33. package/dist/cjs/resources/InventoryResource.js +95 -0
  34. package/dist/cjs/resources/InventoryResource.js.map +1 -0
  35. package/dist/cjs/resources/LocationResource.js +20 -0
  36. package/dist/cjs/resources/LocationResource.js.map +1 -0
  37. package/dist/cjs/resources/MarketResource.js +44 -0
  38. package/dist/cjs/resources/MarketResource.js.map +1 -0
  39. package/dist/cjs/resources/NewsResource.js +109 -0
  40. package/dist/cjs/resources/NewsResource.js.map +1 -0
  41. package/dist/cjs/resources/TypesResource.js +75 -0
  42. package/dist/cjs/resources/TypesResource.js.map +1 -0
  43. package/dist/cjs/types/index.js +25 -0
  44. package/dist/cjs/types/index.js.map +1 -0
  45. package/dist/esm/SWCombine.js +116 -0
  46. package/dist/esm/SWCombine.js.map +1 -0
  47. package/dist/esm/auth/OAuthClient.js +188 -0
  48. package/dist/esm/auth/OAuthClient.js.map +1 -0
  49. package/dist/esm/auth/TokenManager.js +135 -0
  50. package/dist/esm/auth/TokenManager.js.map +1 -0
  51. package/dist/esm/auth/permissions.js +275 -0
  52. package/dist/esm/auth/permissions.js.map +1 -0
  53. package/dist/esm/auth/scopes.js +274 -0
  54. package/dist/esm/auth/scopes.js.map +1 -0
  55. package/dist/esm/http/HttpClient.js +209 -0
  56. package/dist/esm/http/HttpClient.js.map +1 -0
  57. package/dist/esm/http/errors.js +152 -0
  58. package/dist/esm/http/errors.js.map +1 -0
  59. package/dist/esm/index.js +15 -0
  60. package/dist/esm/index.js.map +1 -0
  61. package/dist/esm/resources/ApiResource.js +40 -0
  62. package/dist/esm/resources/ApiResource.js.map +1 -0
  63. package/dist/esm/resources/BaseResource.js +29 -0
  64. package/dist/esm/resources/BaseResource.js.map +1 -0
  65. package/dist/esm/resources/CharacterResource.js +168 -0
  66. package/dist/esm/resources/CharacterResource.js.map +1 -0
  67. package/dist/esm/resources/DatacardResource.js +38 -0
  68. package/dist/esm/resources/DatacardResource.js.map +1 -0
  69. package/dist/esm/resources/EventsResource.js +38 -0
  70. package/dist/esm/resources/EventsResource.js.map +1 -0
  71. package/dist/esm/resources/FactionResource.js +153 -0
  72. package/dist/esm/resources/FactionResource.js.map +1 -0
  73. package/dist/esm/resources/GalaxyResource.js +175 -0
  74. package/dist/esm/resources/GalaxyResource.js.map +1 -0
  75. package/dist/esm/resources/InventoryResource.js +90 -0
  76. package/dist/esm/resources/InventoryResource.js.map +1 -0
  77. package/dist/esm/resources/LocationResource.js +16 -0
  78. package/dist/esm/resources/LocationResource.js.map +1 -0
  79. package/dist/esm/resources/MarketResource.js +39 -0
  80. package/dist/esm/resources/MarketResource.js.map +1 -0
  81. package/dist/esm/resources/NewsResource.js +103 -0
  82. package/dist/esm/resources/NewsResource.js.map +1 -0
  83. package/dist/esm/resources/TypesResource.js +69 -0
  84. package/dist/esm/resources/TypesResource.js.map +1 -0
  85. package/dist/esm/types/index.js +22 -0
  86. package/dist/esm/types/index.js.map +1 -0
  87. package/dist/types/SWCombine.d.ts +66 -0
  88. package/dist/types/SWCombine.d.ts.map +1 -0
  89. package/dist/types/auth/OAuthClient.d.ts +48 -0
  90. package/dist/types/auth/OAuthClient.d.ts.map +1 -0
  91. package/dist/types/auth/TokenManager.d.ts +66 -0
  92. package/dist/types/auth/TokenManager.d.ts.map +1 -0
  93. package/dist/types/auth/permissions.d.ts +173 -0
  94. package/dist/types/auth/permissions.d.ts.map +1 -0
  95. package/dist/types/auth/scopes.d.ts +309 -0
  96. package/dist/types/auth/scopes.d.ts.map +1 -0
  97. package/dist/types/http/HttpClient.d.ts +64 -0
  98. package/dist/types/http/HttpClient.d.ts.map +1 -0
  99. package/dist/types/http/errors.d.ts +54 -0
  100. package/dist/types/http/errors.d.ts.map +1 -0
  101. package/dist/types/index.d.ts +11 -0
  102. package/dist/types/index.d.ts.map +1 -0
  103. package/dist/types/resources/ApiResource.d.ts +56 -0
  104. package/dist/types/resources/ApiResource.d.ts.map +1 -0
  105. package/dist/types/resources/BaseResource.d.ts +16 -0
  106. package/dist/types/resources/BaseResource.d.ts.map +1 -0
  107. package/dist/types/resources/CharacterResource.d.ts +151 -0
  108. package/dist/types/resources/CharacterResource.d.ts.map +1 -0
  109. package/dist/types/resources/DatacardResource.d.ts +42 -0
  110. package/dist/types/resources/DatacardResource.d.ts.map +1 -0
  111. package/dist/types/resources/EventsResource.d.ts +34 -0
  112. package/dist/types/resources/EventsResource.d.ts.map +1 -0
  113. package/dist/types/resources/FactionResource.d.ts +166 -0
  114. package/dist/types/resources/FactionResource.d.ts.map +1 -0
  115. package/dist/types/resources/GalaxyResource.d.ts +134 -0
  116. package/dist/types/resources/GalaxyResource.d.ts.map +1 -0
  117. package/dist/types/resources/InventoryResource.d.ts +77 -0
  118. package/dist/types/resources/InventoryResource.d.ts.map +1 -0
  119. package/dist/types/resources/LocationResource.d.ts +18 -0
  120. package/dist/types/resources/LocationResource.d.ts.map +1 -0
  121. package/dist/types/resources/MarketResource.d.ts +34 -0
  122. package/dist/types/resources/MarketResource.d.ts.map +1 -0
  123. package/dist/types/resources/NewsResource.d.ts +54 -0
  124. package/dist/types/resources/NewsResource.d.ts.map +1 -0
  125. package/dist/types/resources/TypesResource.d.ts +72 -0
  126. package/dist/types/resources/TypesResource.d.ts.map +1 -0
  127. package/dist/types/types/index.d.ts +296 -0
  128. package/dist/types/types/index.d.ts.map +1 -0
  129. package/package.json +75 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Main SW Combine SDK client
3
+ */
4
+ import { HttpClient } from './http/HttpClient.js';
5
+ import { OAuthClient } from './auth/OAuthClient.js';
6
+ import { TokenManager } from './auth/TokenManager.js';
7
+ // Import all resource classes
8
+ import { ApiResource } from './resources/ApiResource.js';
9
+ import { CharacterResource } from './resources/CharacterResource.js';
10
+ import { FactionResource } from './resources/FactionResource.js';
11
+ import { GalaxyResource } from './resources/GalaxyResource.js';
12
+ import { InventoryResource } from './resources/InventoryResource.js';
13
+ import { MarketResource } from './resources/MarketResource.js';
14
+ import { NewsResource } from './resources/NewsResource.js';
15
+ import { TypesResource } from './resources/TypesResource.js';
16
+ import { EventsResource } from './resources/EventsResource.js';
17
+ import { LocationResource } from './resources/LocationResource.js';
18
+ import { DatacardResource } from './resources/DatacardResource.js';
19
+ /**
20
+ * Main SW Combine SDK client
21
+ */
22
+ export class SWCombine {
23
+ constructor(config) {
24
+ this.config = config;
25
+ // Initialize token manager
26
+ this.tokenManager = new TokenManager(config.token);
27
+ // Initialize OAuth client
28
+ this.oauthClient = new OAuthClient({
29
+ clientId: config.clientId,
30
+ clientSecret: config.clientSecret,
31
+ redirectUri: config.redirectUri,
32
+ accessType: config.accessType,
33
+ });
34
+ // Set up token refresh callback
35
+ this.tokenManager.setRefreshCallback(async () => {
36
+ const refreshToken = this.tokenManager.getRefreshToken();
37
+ if (!refreshToken) {
38
+ throw new Error('No refresh token available');
39
+ }
40
+ return this.oauthClient.refreshToken(refreshToken);
41
+ });
42
+ // Initialize HTTP client
43
+ this.http = new HttpClient({
44
+ baseURL: config.baseURL,
45
+ timeout: config.timeout,
46
+ maxRetries: config.maxRetries,
47
+ retryDelay: config.retryDelay,
48
+ debug: config.debug,
49
+ }, this.tokenManager);
50
+ // Initialize all resources
51
+ this.api = new ApiResource(this.http);
52
+ this.character = new CharacterResource(this.http);
53
+ this.faction = new FactionResource(this.http);
54
+ this.galaxy = new GalaxyResource(this.http);
55
+ this.inventory = new InventoryResource(this.http);
56
+ this.market = new MarketResource(this.http);
57
+ this.news = new NewsResource(this.http);
58
+ this.types = new TypesResource(this.http);
59
+ this.events = new EventsResource(this.http);
60
+ this.location = new LocationResource(this.http);
61
+ this.datacard = new DatacardResource(this.http);
62
+ // Set up auth operations
63
+ this.auth = {
64
+ getAuthorizationUrl: (options) => {
65
+ return this.oauthClient.getAuthorizationUrl(options);
66
+ },
67
+ handleCallback: async (query) => {
68
+ const result = await this.oauthClient.handleCallback(query);
69
+ if (result.success && result.token) {
70
+ this.tokenManager.setToken(result.token);
71
+ }
72
+ return result;
73
+ },
74
+ revokeToken: async (refreshToken) => {
75
+ return this.oauthClient.revokeToken(refreshToken);
76
+ },
77
+ };
78
+ }
79
+ /**
80
+ * Set the access token
81
+ */
82
+ setToken(token) {
83
+ this.tokenManager.setToken(token);
84
+ }
85
+ /**
86
+ * Get the current token
87
+ */
88
+ getToken() {
89
+ return this.tokenManager.getToken();
90
+ }
91
+ /**
92
+ * Clear the token
93
+ */
94
+ clearToken() {
95
+ this.tokenManager.clear();
96
+ }
97
+ /**
98
+ * Manually refresh the token
99
+ */
100
+ async refreshToken() {
101
+ await this.tokenManager.refreshToken();
102
+ }
103
+ /**
104
+ * Check if token is expired
105
+ */
106
+ isTokenExpired() {
107
+ return this.tokenManager.isExpired();
108
+ }
109
+ /**
110
+ * Check if refresh token is available
111
+ */
112
+ hasRefreshToken() {
113
+ return this.tokenManager.hasRefreshToken();
114
+ }
115
+ }
116
+ //# sourceMappingURL=SWCombine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SWCombine.js","sourceRoot":"","sources":["../../src/SWCombine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * OAuth 2.0 client for SW Combine API
3
+ */
4
+ import axios from 'axios';
5
+ import { GrantType, AccessType, } from '../types/index.js';
6
+ import { SWCError } from '../http/errors.js';
7
+ // OAuth endpoints
8
+ const OAUTH_ENDPOINT_AUTH = 'https://www.swcombine.com/ws/oauth2/auth/';
9
+ const OAUTH_ENDPOINT_TOKEN = 'https://www.swcombine.com/ws/oauth2/token/';
10
+ const OAUTH_ENDPOINT_REVOKE = 'https://www.swcombine.com/ws/oauth2/revoke';
11
+ /**
12
+ * OAuth client for handling authorization flows
13
+ */
14
+ export class OAuthClient {
15
+ constructor(config) {
16
+ this.clientId = config.clientId;
17
+ this.clientSecret = config.clientSecret;
18
+ this.redirectUri = config.redirectUri;
19
+ this.accessType = config.accessType ?? AccessType.Online;
20
+ this.renewPreviouslyGranted = config.renewPreviouslyGranted ?? false;
21
+ }
22
+ /**
23
+ * Get authorization URL for redirecting user
24
+ */
25
+ getAuthorizationUrl(options) {
26
+ if (!this.redirectUri) {
27
+ throw new Error('redirectUri is required for authorization flow');
28
+ }
29
+ const params = {
30
+ response_type: 'code',
31
+ client_id: this.clientId,
32
+ scope: options.scopes.join(' '),
33
+ redirect_uri: this.redirectUri,
34
+ state: options.state,
35
+ access_type: this.accessType,
36
+ };
37
+ // Add optional renewPreviouslyGranted parameter
38
+ if (this.renewPreviouslyGranted) {
39
+ params.renew_previously_granted = 'yes';
40
+ }
41
+ const searchParams = new URLSearchParams(params);
42
+ return `${OAUTH_ENDPOINT_AUTH}?${searchParams.toString()}`;
43
+ }
44
+ /**
45
+ * Handle OAuth callback and exchange code for token
46
+ */
47
+ async handleCallback(query) {
48
+ // Check for error in callback
49
+ if (query.error) {
50
+ return {
51
+ success: false,
52
+ error: query.error_description || query.error,
53
+ state: query.state,
54
+ };
55
+ }
56
+ // Check for authorization code
57
+ if (!query.code) {
58
+ return {
59
+ success: false,
60
+ error: 'No authorization code received',
61
+ state: query.state,
62
+ };
63
+ }
64
+ try {
65
+ // Exchange code for token
66
+ const token = await this.exchangeCodeForToken(query.code);
67
+ return {
68
+ success: true,
69
+ token,
70
+ state: query.state,
71
+ };
72
+ }
73
+ catch (error) {
74
+ return {
75
+ success: false,
76
+ error: error instanceof Error ? error.message : 'Token exchange failed',
77
+ state: query.state,
78
+ };
79
+ }
80
+ }
81
+ /**
82
+ * Exchange authorization code for access token
83
+ */
84
+ async exchangeCodeForToken(code) {
85
+ if (!this.redirectUri) {
86
+ throw new Error('redirectUri is required for token exchange');
87
+ }
88
+ const params = new URLSearchParams({
89
+ code,
90
+ client_id: this.clientId,
91
+ client_secret: this.clientSecret,
92
+ redirect_uri: this.redirectUri,
93
+ grant_type: GrantType.AuthorizationCode,
94
+ access_type: this.accessType,
95
+ });
96
+ try {
97
+ const response = await axios.post(OAUTH_ENDPOINT_TOKEN, params.toString(), {
98
+ headers: {
99
+ 'Content-Type': 'application/x-www-form-urlencoded',
100
+ 'Accept': 'application/json',
101
+ },
102
+ });
103
+ if (response.data.error) {
104
+ throw new SWCError(`Failed to get token: ${response.data.error}`, {
105
+ type: 'auth',
106
+ response: response.data,
107
+ });
108
+ }
109
+ return this.parseTokenResponse(response.data);
110
+ }
111
+ catch (error) {
112
+ if (axios.isAxiosError(error) && error.response) {
113
+ throw SWCError.fromHttpResponse(error.response.status, error.response.data, error.response.headers['x-request-id']);
114
+ }
115
+ throw error;
116
+ }
117
+ }
118
+ /**
119
+ * Refresh access token using refresh token
120
+ */
121
+ async refreshToken(refreshToken) {
122
+ const params = new URLSearchParams({
123
+ refresh_token: refreshToken,
124
+ client_id: this.clientId,
125
+ client_secret: this.clientSecret,
126
+ grant_type: GrantType.RefreshToken,
127
+ });
128
+ try {
129
+ const response = await axios.post(OAUTH_ENDPOINT_TOKEN, params.toString(), {
130
+ headers: {
131
+ 'Content-Type': 'application/x-www-form-urlencoded',
132
+ 'Accept': 'application/json',
133
+ },
134
+ });
135
+ if (response.data.error) {
136
+ throw new SWCError(`Failed to refresh token: ${response.data.error}`, {
137
+ type: 'auth',
138
+ response: response.data,
139
+ });
140
+ }
141
+ return this.parseTokenResponse(response.data);
142
+ }
143
+ catch (error) {
144
+ if (axios.isAxiosError(error) && error.response) {
145
+ throw SWCError.fromHttpResponse(error.response.status, error.response.data, error.response.headers['x-request-id']);
146
+ }
147
+ throw error;
148
+ }
149
+ }
150
+ /**
151
+ * Parse token response from API
152
+ */
153
+ parseTokenResponse(data) {
154
+ const expiresIn = data.expires_in ?? 3600; // Default to 1 hour
155
+ const expiresAt = Date.now() + expiresIn * 1000;
156
+ return {
157
+ accessToken: data.access_token,
158
+ refreshToken: data.refresh_token,
159
+ expiresAt,
160
+ };
161
+ }
162
+ /**
163
+ * Revoke a refresh token
164
+ */
165
+ async revokeToken(refreshToken) {
166
+ const params = new URLSearchParams({
167
+ token: refreshToken,
168
+ client_id: this.clientId,
169
+ });
170
+ try {
171
+ const response = await axios.get(`${OAUTH_ENDPOINT_REVOKE}?${params.toString()}`);
172
+ if (response.status !== 200) {
173
+ throw new SWCError('Failed to revoke token', {
174
+ type: 'auth',
175
+ statusCode: response.status,
176
+ response: response.data,
177
+ });
178
+ }
179
+ }
180
+ catch (error) {
181
+ if (axios.isAxiosError(error) && error.response) {
182
+ throw SWCError.fromHttpResponse(error.response.status, error.response.data, error.response.headers['x-request-id']);
183
+ }
184
+ throw error;
185
+ }
186
+ }
187
+ }
188
+ //# sourceMappingURL=OAuthClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthClient.js","sourceRoot":"","sources":["../../../src/auth/OAuthClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Token management for OAuth tokens
3
+ */
4
+ /**
5
+ * Manages OAuth tokens including expiration and refresh
6
+ */
7
+ export class TokenManager {
8
+ constructor(token, storage) {
9
+ this.token = null;
10
+ if (token) {
11
+ if (typeof token === 'string') {
12
+ // Initialize with just access token (no expiry known)
13
+ this.token = {
14
+ accessToken: token,
15
+ expiresAt: Date.now() + 3600 * 1000, // Assume 1 hour
16
+ };
17
+ }
18
+ else {
19
+ this.token = token;
20
+ }
21
+ }
22
+ this.storage = storage;
23
+ }
24
+ /**
25
+ * Set token
26
+ */
27
+ setToken(token) {
28
+ if (typeof token === 'string') {
29
+ this.token = {
30
+ accessToken: token,
31
+ expiresAt: Date.now() + 3600 * 1000,
32
+ };
33
+ }
34
+ else {
35
+ this.token = token;
36
+ }
37
+ // Save to storage if available
38
+ if (this.storage && this.token) {
39
+ void this.storage.saveToken(this.token);
40
+ }
41
+ }
42
+ /**
43
+ * Get current token
44
+ */
45
+ getToken() {
46
+ return this.token;
47
+ }
48
+ /**
49
+ * Get access token (refreshes if expired)
50
+ */
51
+ async getAccessToken() {
52
+ if (!this.token) {
53
+ return null;
54
+ }
55
+ // Check if token is expired or about to expire (within 5 minutes)
56
+ if (this.shouldRefresh()) {
57
+ await this.refreshToken();
58
+ }
59
+ return this.token?.accessToken ?? null;
60
+ }
61
+ /**
62
+ * Check if token is expired
63
+ */
64
+ isExpired() {
65
+ if (!this.token) {
66
+ return true;
67
+ }
68
+ return Date.now() >= this.token.expiresAt;
69
+ }
70
+ /**
71
+ * Check if token should be refreshed (expired or expiring soon)
72
+ */
73
+ shouldRefresh() {
74
+ if (!this.token) {
75
+ return false;
76
+ }
77
+ // Refresh if expired or expiring within 5 minutes
78
+ const fiveMinutes = 5 * 60 * 1000;
79
+ return Date.now() >= this.token.expiresAt - fiveMinutes;
80
+ }
81
+ /**
82
+ * Check if refresh token is available
83
+ */
84
+ hasRefreshToken() {
85
+ return !!this.token?.refreshToken;
86
+ }
87
+ /**
88
+ * Get refresh token
89
+ */
90
+ getRefreshToken() {
91
+ return this.token?.refreshToken ?? null;
92
+ }
93
+ /**
94
+ * Refresh the access token
95
+ */
96
+ async refreshToken() {
97
+ if (!this.refreshCallback) {
98
+ throw new Error('Token refresh callback not set');
99
+ }
100
+ if (!this.hasRefreshToken()) {
101
+ throw new Error('No refresh token available');
102
+ }
103
+ // Call the refresh callback to get new token
104
+ const newToken = await this.refreshCallback();
105
+ this.setToken(newToken);
106
+ }
107
+ /**
108
+ * Set callback for token refresh
109
+ */
110
+ setRefreshCallback(callback) {
111
+ this.refreshCallback = callback;
112
+ }
113
+ /**
114
+ * Clear token
115
+ */
116
+ clear() {
117
+ this.token = null;
118
+ if (this.storage) {
119
+ void this.storage.clearToken();
120
+ }
121
+ }
122
+ /**
123
+ * Load token from storage
124
+ */
125
+ async loadFromStorage() {
126
+ if (!this.storage) {
127
+ return;
128
+ }
129
+ const token = await this.storage.loadToken();
130
+ if (token) {
131
+ this.token = token;
132
+ }
133
+ }
134
+ }
135
+ //# sourceMappingURL=TokenManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenManager.js","sourceRoot":"","sources":["../../../src/auth/TokenManager.ts"],"names":[],"mappings":"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"}